Compare commits

..

2 Commits

Author SHA1 Message Date
Michal
22d8e13390 fix(smoke): match the _resultId format the pipeline actually emits
Some checks failed
CI/CD / typecheck (pull_request) Successful in 1m23s
CI/CD / lint (pull_request) Successful in 2m19s
CI/CD / test (pull_request) Successful in 1m41s
CI/CD / smoke (pull_request) Failing after 2m6s
CI/CD / build (pull_request) Successful in 2m22s
CI/CD / publish (pull_request) Has been skipped
The drill-down checks matched /_resultId:\s*(\S+)/ — the legacy paginator's
JSON spelling. The content pipeline writes _resultId="pm-abc", so the regex
found nothing: "Has _resultId for drill-down" reported a false failure on
every run, and the drill-down tests that used the same regex to extract an id
skipped themselves as "not large enough for section-split". Both were
invisible in a green suite.

One shared extractResultId() in the smoke harness now accepts either
spelling and returns the bare id, so the ad-hoc character strip on the
captured group goes away too. proxy-pipeline's check block reports 21/21
instead of 20 with a phantom failure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JQr5Z9gYrqBQXTGBBuemZ2
2026-09-05 18:03:56 +01:00
b5d0234d0b Merge pull request #129: drill-down required params
Some checks failed
CI/CD / typecheck (push) Successful in 1m22s
CI/CD / lint (push) Successful in 2m13s
CI/CD / test (push) Has started running
CI/CD / smoke (push) Has been cancelled
CI/CD / build (push) Has been cancelled
CI/CD / publish (push) Has been cancelled
2026-09-05 16:59:46 +00:00
3 changed files with 25 additions and 17 deletions

View File

@@ -261,6 +261,21 @@ export async function isMcplocalRunning(): Promise<boolean> {
}
}
/**
* Pull the drill-down id out of a paginated result or TOC.
*
* The instruction is written `_resultId="pm-abc"`, while the legacy paginator
* emits it as JSON (`"_resultId": "pm-abc"`). A regex matching only the JSON
* form silently found nothing in the current format, so drill-down checks
* either reported a false failure or skipped themselves as "not large enough
* for section-split" — both invisible in a green run. Accept either spelling
* and return the bare id.
*/
export function extractResultId(text: string): string | null {
const match = /_resultId"?\s*[:=]\s*"?(pm-[a-zA-Z0-9]+)/.exec(text);
return match?.[1] ?? null;
}
/**
* Run an mcpctl CLI command and return stdout.
*/

View File

@@ -7,7 +7,7 @@
* Requires: mcplocal running on localhost:3200, mcpd at https://mcpctl.ad.itaz.eu
*/
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { SmokeMcpSession, isMcplocalRunning } from './mcp-client.js';
import { SmokeMcpSession, isMcplocalRunning, extractResultId } from './mcp-client.js';
const PROJECT_NAME = 'smoke-data';
@@ -90,9 +90,8 @@ describe('Smoke: Prompt section drill-down', () => {
console.log(` TOC preview: ${text.slice(0, 200)}...`);
// Extract _resultId
const match = /_resultId:\s*(pm-[a-z0-9]+)/.exec(text);
if (match) {
const resultId = match[1];
const resultId = extractResultId(text);
if (resultId !== null) {
// Extract first section id from TOC
const sectionMatch = /\[([^\]]+)\]/.exec(text);
if (sectionMatch) {

View File

@@ -17,7 +17,7 @@
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { writeFile, mkdir, rm } from 'node:fs/promises';
import { join, resolve } from 'node:path';
import { SmokeMcpSession, isMcplocalRunning, mcpctl } from './mcp-client.js';
import { SmokeMcpSession, isMcplocalRunning, mcpctl, extractResultId } from './mcp-client.js';
import { ChatReporter } from './reporter.js';
const PROJECT_NAME = 'smoke-data';
@@ -286,8 +286,7 @@ describe('Smoke: ProxyModel pipeline', () => {
chat.check('Response is manageable size', text.length, (v) => v < 20_000);
if (text.includes('_resultId')) {
const match = text.match(/_resultId:\s*(\S+)/);
chat.check('_resultId is present', !!match, (v) => v === true);
chat.check('_resultId is present', extractResultId(text) !== null, (v) => v === true);
} else {
chat.info('Content small enough — no pagination needed');
}
@@ -307,14 +306,12 @@ describe('Smoke: ProxyModel pipeline', () => {
});
const text = result.content[0]?.text ?? '';
const match = text.match(/_resultId:\s*(\S+)/);
if (!match) {
const resultId = extractResultId(text);
if (resultId === null) {
chat.info('Content not large enough for pagination — skip drill-down');
return;
}
const resultId = match[1]!.replace(/[^a-zA-Z0-9-]/g, '');
const sectionResult = await chat.callTool('smoke-aws-docs_read_documentation', {
url: 'https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html',
_resultId: resultId,
@@ -401,8 +398,7 @@ describe('Smoke: ProxyModel pipeline', () => {
chat.check('Response is manageable size', text.length, (v) => v < 20_000);
if (text.includes('_resultId')) {
const match = text.match(/_resultId:\s*(\S+)/);
chat.check('Has _resultId for drill-down', !!match, (v) => v === true);
chat.check('Has _resultId for drill-down', extractResultId(text) !== null, (v) => v === true);
}
}, 60_000);
@@ -420,14 +416,12 @@ describe('Smoke: ProxyModel pipeline', () => {
});
const text = result.content[0]?.text ?? '';
const match = text.match(/_resultId:\s*(\S+)/);
if (!match) {
const resultId = extractResultId(text);
if (resultId === null) {
chat.info('Content not large enough for section-split');
return;
}
const resultId = match[1]!.replace(/[^a-zA-Z0-9-]/g, '');
const sectionResult = await chat.callTool('smoke-aws-docs_read_documentation', {
url: 'https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html',
_resultId: resultId,