@ctxprotocol/sdk 0.8.4 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -5
- package/dist/client/index.cjs +48 -50
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +143 -10
- package/dist/client/index.d.ts +143 -10
- package/dist/client/index.js +48 -50
- package/dist/client/index.js.map +1 -1
- package/dist/index.cjs +48 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +48 -50
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -342,7 +342,7 @@ var Query = class {
|
|
|
342
342
|
* Run an agentic query and wait for the full response.
|
|
343
343
|
*
|
|
344
344
|
* The server discovers relevant tools (or uses the ones you specify),
|
|
345
|
-
* executes the
|
|
345
|
+
* executes the discovery-first pipeline (up to 100 MCP calls per tool),
|
|
346
346
|
* and returns an AI-synthesized answer. Payment is settled after
|
|
347
347
|
* successful execution via deferred settlement.
|
|
348
348
|
*
|
|
@@ -371,48 +371,25 @@ var Query = class {
|
|
|
371
371
|
*/
|
|
372
372
|
async run(options) {
|
|
373
373
|
const opts = typeof options === "string" ? { query: options } : options;
|
|
374
|
-
|
|
375
|
-
const
|
|
376
|
-
"
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
queryDepth: opts.queryDepth,
|
|
388
|
-
stream: false
|
|
389
|
-
})
|
|
374
|
+
let terminalError;
|
|
375
|
+
for await (const event of this.stream(opts)) {
|
|
376
|
+
if (event.type === "error") {
|
|
377
|
+
terminalError = {
|
|
378
|
+
error: event.error,
|
|
379
|
+
...event.code ? { code: event.code } : {},
|
|
380
|
+
...event.scope ? { scope: event.scope } : {},
|
|
381
|
+
...event.reasonCode ? { reasonCode: event.reasonCode } : {}
|
|
382
|
+
};
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
if (event.type === "done") {
|
|
386
|
+
return event.result;
|
|
390
387
|
}
|
|
391
|
-
);
|
|
392
|
-
if ("error" in response) {
|
|
393
|
-
throw new ContextError(
|
|
394
|
-
response.error,
|
|
395
|
-
response.code,
|
|
396
|
-
void 0,
|
|
397
|
-
response.helpUrl
|
|
398
|
-
);
|
|
399
388
|
}
|
|
400
|
-
if (
|
|
401
|
-
|
|
402
|
-
toolsUsed: response.toolsUsed,
|
|
403
|
-
durationMs: response.durationMs
|
|
404
|
-
}) : void 0);
|
|
405
|
-
return {
|
|
406
|
-
response: response.response,
|
|
407
|
-
toolsUsed: response.toolsUsed,
|
|
408
|
-
cost: response.cost,
|
|
409
|
-
durationMs: response.durationMs,
|
|
410
|
-
data: response.data,
|
|
411
|
-
dataUrl: response.dataUrl,
|
|
412
|
-
developerTrace
|
|
413
|
-
};
|
|
389
|
+
if (terminalError) {
|
|
390
|
+
throw new ContextError(terminalError.error, terminalError.code);
|
|
414
391
|
}
|
|
415
|
-
throw new ContextError("
|
|
392
|
+
throw new ContextError("Streaming query ended before done event");
|
|
416
393
|
}
|
|
417
394
|
/**
|
|
418
395
|
* Run an agentic query with streaming. Returns an async iterable that
|
|
@@ -422,6 +399,7 @@ var Query = class {
|
|
|
422
399
|
* - `tool-status` — A tool started executing or changed status
|
|
423
400
|
* - `text-delta` — A chunk of the AI response text
|
|
424
401
|
* - `developer-trace` — Runtime trace metadata (when includeDeveloperTrace=true)
|
|
402
|
+
* - `error` — A structured query/runtime error emitted before stream completion
|
|
425
403
|
* - `done` — The full response is complete (includes final `QueryResult`)
|
|
426
404
|
*
|
|
427
405
|
* @param options - Query options or a plain string question
|
|
@@ -443,6 +421,9 @@ var Query = class {
|
|
|
443
421
|
* case "done":
|
|
444
422
|
* console.log("\nCost:", event.result.cost.totalCostUsd);
|
|
445
423
|
* break;
|
|
424
|
+
* case "error":
|
|
425
|
+
* console.error("Stream error:", event.error);
|
|
426
|
+
* break;
|
|
446
427
|
* }
|
|
447
428
|
* }
|
|
448
429
|
* ```
|
|
@@ -461,6 +442,7 @@ var Query = class {
|
|
|
461
442
|
includeDataUrl: opts.includeDataUrl,
|
|
462
443
|
includeDeveloperTrace: opts.includeDeveloperTrace,
|
|
463
444
|
queryDepth: opts.queryDepth,
|
|
445
|
+
debugScoutDeepMode: opts.debugScoutDeepMode,
|
|
464
446
|
stream: true
|
|
465
447
|
})
|
|
466
448
|
});
|
|
@@ -498,10 +480,13 @@ var Query = class {
|
|
|
498
480
|
event.result.developerTrace
|
|
499
481
|
);
|
|
500
482
|
if (!mergedTrace && opts.includeDeveloperTrace) {
|
|
501
|
-
mergedTrace = this.buildSyntheticTraceFromStreamStatus({
|
|
483
|
+
mergedTrace = statusTimeline.length > 0 ? this.buildSyntheticTraceFromStreamStatus({
|
|
502
484
|
statusTimeline,
|
|
503
485
|
toolsUsed: event.result.toolsUsed,
|
|
504
486
|
durationMs: event.result.durationMs
|
|
487
|
+
}) : this.buildSyntheticTraceFromRunResult({
|
|
488
|
+
toolsUsed: event.result.toolsUsed,
|
|
489
|
+
durationMs: event.result.durationMs
|
|
505
490
|
});
|
|
506
491
|
}
|
|
507
492
|
if (mergedTrace) {
|
|
@@ -618,30 +603,34 @@ var ContextClient = class {
|
|
|
618
603
|
*
|
|
619
604
|
* @internal
|
|
620
605
|
*/
|
|
621
|
-
async _fetch(endpoint, options = {}) {
|
|
606
|
+
async _fetch(endpoint, options = {}, fetchOptions) {
|
|
622
607
|
if (this._closed) {
|
|
623
608
|
throw new ContextError("Client has been closed");
|
|
624
609
|
}
|
|
625
610
|
const url = `${this.baseUrl}${endpoint}`;
|
|
626
611
|
const maxRetries = 3;
|
|
627
612
|
const timeoutMs = this.requestTimeoutMs;
|
|
613
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
614
|
+
const requestHeaders = new Headers(options.headers);
|
|
615
|
+
const canRetryRequest = fetchOptions?.retry === false ? false : method === "GET" || method === "HEAD" || method === "OPTIONS" || requestHeaders.has("Idempotency-Key");
|
|
628
616
|
let lastError;
|
|
629
617
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
630
618
|
const controller = new AbortController();
|
|
631
619
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
620
|
+
const mergedHeaders = new Headers(requestHeaders);
|
|
621
|
+
if (!mergedHeaders.has("Content-Type")) {
|
|
622
|
+
mergedHeaders.set("Content-Type", "application/json");
|
|
623
|
+
}
|
|
624
|
+
mergedHeaders.set("Authorization", `Bearer ${this.apiKey}`);
|
|
632
625
|
try {
|
|
633
626
|
const response = await fetch(url, {
|
|
634
627
|
...options,
|
|
635
628
|
signal: controller.signal,
|
|
636
|
-
headers:
|
|
637
|
-
"Content-Type": "application/json",
|
|
638
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
639
|
-
...options.headers
|
|
640
|
-
}
|
|
629
|
+
headers: mergedHeaders
|
|
641
630
|
});
|
|
642
631
|
clearTimeout(timeout);
|
|
643
632
|
if (!response.ok) {
|
|
644
|
-
if (response.status >= 500 && attempt < maxRetries) {
|
|
633
|
+
if (response.status >= 500 && canRetryRequest && attempt < maxRetries) {
|
|
645
634
|
const delay = Math.min(1e3 * 2 ** attempt, 1e4);
|
|
646
635
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
647
636
|
continue;
|
|
@@ -660,7 +649,16 @@ var ContextClient = class {
|
|
|
660
649
|
}
|
|
661
650
|
throw new ContextError(errorMessage, errorCode, response.status, helpUrl);
|
|
662
651
|
}
|
|
663
|
-
|
|
652
|
+
try {
|
|
653
|
+
return await response.json();
|
|
654
|
+
} catch (error) {
|
|
655
|
+
const parseError = error instanceof Error ? error : new Error(String(error));
|
|
656
|
+
throw new ContextError(
|
|
657
|
+
`Failed to parse JSON response: ${parseError.message}`,
|
|
658
|
+
void 0,
|
|
659
|
+
response.status
|
|
660
|
+
);
|
|
661
|
+
}
|
|
664
662
|
} catch (error) {
|
|
665
663
|
clearTimeout(timeout);
|
|
666
664
|
if (error instanceof ContextError) {
|
|
@@ -668,7 +666,7 @@ var ContextClient = class {
|
|
|
668
666
|
}
|
|
669
667
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
670
668
|
const isRetryable = lastError.name === "AbortError" || lastError.message.includes("fetch failed") || lastError.message.includes("ECONNRESET") || lastError.message.includes("ETIMEDOUT");
|
|
671
|
-
if (isRetryable && attempt < maxRetries) {
|
|
669
|
+
if (isRetryable && canRetryRequest && attempt < maxRetries) {
|
|
672
670
|
const delay = Math.min(1e3 * 2 ** attempt, 1e4);
|
|
673
671
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
674
672
|
continue;
|