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