@ctxprotocol/sdk 0.8.3 → 0.8.4
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 +13 -1
- package/dist/client/index.cjs +167 -3
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +79 -2
- package/dist/client/index.d.ts +79 -2
- package/dist/client/index.js +167 -3
- package/dist/client/index.js.map +1 -1
- package/dist/index.cjs +167 -3
- 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 +167 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -228,6 +228,114 @@ var Query = class {
|
|
|
228
228
|
constructor(client) {
|
|
229
229
|
this.client = client;
|
|
230
230
|
}
|
|
231
|
+
buildSyntheticTraceFromRunResult(params) {
|
|
232
|
+
const timeline = params.toolsUsed.map((tool, index) => ({
|
|
233
|
+
stepType: "tool-call",
|
|
234
|
+
event: "tool-call",
|
|
235
|
+
status: "success",
|
|
236
|
+
timestampMs: index,
|
|
237
|
+
tool: {
|
|
238
|
+
id: tool.id,
|
|
239
|
+
name: tool.name
|
|
240
|
+
},
|
|
241
|
+
metadata: {
|
|
242
|
+
skillCalls: tool.skillCalls,
|
|
243
|
+
synthetic: true
|
|
244
|
+
}
|
|
245
|
+
}));
|
|
246
|
+
const toolCalls = params.toolsUsed.reduce(
|
|
247
|
+
(sum, tool) => sum + Math.max(tool.skillCalls, 0),
|
|
248
|
+
0
|
|
249
|
+
);
|
|
250
|
+
return {
|
|
251
|
+
summary: {
|
|
252
|
+
toolCalls,
|
|
253
|
+
retryCount: 0,
|
|
254
|
+
selfHealCount: 0,
|
|
255
|
+
fallbackCount: 0,
|
|
256
|
+
failureCount: 0,
|
|
257
|
+
recoveryCount: 0,
|
|
258
|
+
completionChecks: 0,
|
|
259
|
+
loopCount: 0
|
|
260
|
+
},
|
|
261
|
+
timeline,
|
|
262
|
+
source: "sdk-fallback",
|
|
263
|
+
synthetic: true,
|
|
264
|
+
reason: "backend_trace_missing",
|
|
265
|
+
durationMs: params.durationMs
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
buildSyntheticTraceFromStreamStatus(params) {
|
|
269
|
+
const timeline = params.statusTimeline.map((entry, index) => ({
|
|
270
|
+
stepType: "tool-status",
|
|
271
|
+
event: "tool-status",
|
|
272
|
+
status: entry.status,
|
|
273
|
+
timestampMs: index,
|
|
274
|
+
tool: entry.tool.name || entry.tool.id ? {
|
|
275
|
+
id: entry.tool.id || void 0,
|
|
276
|
+
name: entry.tool.name || void 0
|
|
277
|
+
} : void 0,
|
|
278
|
+
metadata: { synthetic: true }
|
|
279
|
+
}));
|
|
280
|
+
const toolCallsFromUsage = params.toolsUsed.reduce(
|
|
281
|
+
(sum, tool) => sum + Math.max(tool.skillCalls, 0),
|
|
282
|
+
0
|
|
283
|
+
);
|
|
284
|
+
const toolCallsFromStatus = params.statusTimeline.filter(
|
|
285
|
+
(entry) => entry.status === "tool-complete"
|
|
286
|
+
).length;
|
|
287
|
+
const toolCalls = toolCallsFromUsage > 0 ? toolCallsFromUsage : toolCallsFromStatus;
|
|
288
|
+
const retryCount = params.statusTimeline.filter(
|
|
289
|
+
(entry) => /(retry|fix|reflect|recover)/i.test(entry.status)
|
|
290
|
+
).length;
|
|
291
|
+
const completionChecks = params.statusTimeline.filter(
|
|
292
|
+
(entry) => /complet/i.test(entry.status)
|
|
293
|
+
).length;
|
|
294
|
+
return {
|
|
295
|
+
summary: {
|
|
296
|
+
toolCalls,
|
|
297
|
+
retryCount,
|
|
298
|
+
selfHealCount: retryCount,
|
|
299
|
+
fallbackCount: 0,
|
|
300
|
+
failureCount: 0,
|
|
301
|
+
recoveryCount: 0,
|
|
302
|
+
completionChecks,
|
|
303
|
+
loopCount: retryCount
|
|
304
|
+
},
|
|
305
|
+
timeline,
|
|
306
|
+
source: "sdk-fallback",
|
|
307
|
+
synthetic: true,
|
|
308
|
+
reason: "backend_trace_missing",
|
|
309
|
+
durationMs: params.durationMs
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
mergeDeveloperTrace(first, second) {
|
|
313
|
+
if (!first) return second;
|
|
314
|
+
if (!second) return first;
|
|
315
|
+
const firstTimeline = Array.isArray(first.timeline) ? first.timeline : [];
|
|
316
|
+
const secondTimeline = Array.isArray(second.timeline) ? second.timeline : [];
|
|
317
|
+
const mergedTimeline = [...firstTimeline, ...secondTimeline];
|
|
318
|
+
return {
|
|
319
|
+
...first,
|
|
320
|
+
...second,
|
|
321
|
+
summary: {
|
|
322
|
+
...typeof first.summary === "object" && first.summary ? first.summary : {},
|
|
323
|
+
...typeof second.summary === "object" && second.summary ? second.summary : {}
|
|
324
|
+
},
|
|
325
|
+
...mergedTimeline.length > 0 ? { timeline: mergedTimeline } : {}
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
parseStreamEvent(rawData) {
|
|
329
|
+
const parsed = JSON.parse(rawData);
|
|
330
|
+
if (!parsed || typeof parsed !== "object") {
|
|
331
|
+
return void 0;
|
|
332
|
+
}
|
|
333
|
+
const event = parsed;
|
|
334
|
+
if (typeof event.type !== "string") {
|
|
335
|
+
return void 0;
|
|
336
|
+
}
|
|
337
|
+
return event;
|
|
338
|
+
}
|
|
231
339
|
/**
|
|
232
340
|
* Run an agentic query and wait for the full response.
|
|
233
341
|
*
|
|
@@ -273,6 +381,7 @@ var Query = class {
|
|
|
273
381
|
modelId: opts.modelId,
|
|
274
382
|
includeData: opts.includeData,
|
|
275
383
|
includeDataUrl: opts.includeDataUrl,
|
|
384
|
+
includeDeveloperTrace: opts.includeDeveloperTrace,
|
|
276
385
|
queryDepth: opts.queryDepth,
|
|
277
386
|
stream: false
|
|
278
387
|
})
|
|
@@ -287,13 +396,18 @@ var Query = class {
|
|
|
287
396
|
);
|
|
288
397
|
}
|
|
289
398
|
if (response.success) {
|
|
399
|
+
const developerTrace = response.developerTrace ?? (opts.includeDeveloperTrace ? this.buildSyntheticTraceFromRunResult({
|
|
400
|
+
toolsUsed: response.toolsUsed,
|
|
401
|
+
durationMs: response.durationMs
|
|
402
|
+
}) : void 0);
|
|
290
403
|
return {
|
|
291
404
|
response: response.response,
|
|
292
405
|
toolsUsed: response.toolsUsed,
|
|
293
406
|
cost: response.cost,
|
|
294
407
|
durationMs: response.durationMs,
|
|
295
408
|
data: response.data,
|
|
296
|
-
dataUrl: response.dataUrl
|
|
409
|
+
dataUrl: response.dataUrl,
|
|
410
|
+
developerTrace
|
|
297
411
|
};
|
|
298
412
|
}
|
|
299
413
|
throw new ContextError("Unexpected response format from query API");
|
|
@@ -305,6 +419,7 @@ var Query = class {
|
|
|
305
419
|
* Event types:
|
|
306
420
|
* - `tool-status` — A tool started executing or changed status
|
|
307
421
|
* - `text-delta` — A chunk of the AI response text
|
|
422
|
+
* - `developer-trace` — Runtime trace metadata (when includeDeveloperTrace=true)
|
|
308
423
|
* - `done` — The full response is complete (includes final `QueryResult`)
|
|
309
424
|
*
|
|
310
425
|
* @param options - Query options or a plain string question
|
|
@@ -320,6 +435,9 @@ var Query = class {
|
|
|
320
435
|
* case "text-delta":
|
|
321
436
|
* process.stdout.write(event.delta);
|
|
322
437
|
* break;
|
|
438
|
+
* case "developer-trace":
|
|
439
|
+
* console.log("Trace summary:", event.trace.summary);
|
|
440
|
+
* break;
|
|
323
441
|
* case "done":
|
|
324
442
|
* console.log("\nCost:", event.result.cost.totalCostUsd);
|
|
325
443
|
* break;
|
|
@@ -339,6 +457,7 @@ var Query = class {
|
|
|
339
457
|
modelId: opts.modelId,
|
|
340
458
|
includeData: opts.includeData,
|
|
341
459
|
includeDataUrl: opts.includeDataUrl,
|
|
460
|
+
includeDeveloperTrace: opts.includeDeveloperTrace,
|
|
342
461
|
queryDepth: opts.queryDepth,
|
|
343
462
|
stream: true
|
|
344
463
|
})
|
|
@@ -350,6 +469,45 @@ var Query = class {
|
|
|
350
469
|
const reader = body.getReader();
|
|
351
470
|
const decoder = new TextDecoder();
|
|
352
471
|
let buffer = "";
|
|
472
|
+
let aggregatedTrace;
|
|
473
|
+
const statusTimeline = [];
|
|
474
|
+
const parseAndHydrateEvent = (rawData) => {
|
|
475
|
+
const event = this.parseStreamEvent(rawData);
|
|
476
|
+
if (!event) {
|
|
477
|
+
return void 0;
|
|
478
|
+
}
|
|
479
|
+
if (event.type === "developer-trace") {
|
|
480
|
+
aggregatedTrace = this.mergeDeveloperTrace(aggregatedTrace, event.trace);
|
|
481
|
+
return event;
|
|
482
|
+
}
|
|
483
|
+
if (event.type === "tool-status") {
|
|
484
|
+
statusTimeline.push({
|
|
485
|
+
status: event.status,
|
|
486
|
+
tool: {
|
|
487
|
+
id: event.tool.id,
|
|
488
|
+
name: event.tool.name
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
return event;
|
|
492
|
+
}
|
|
493
|
+
if (event.type === "done") {
|
|
494
|
+
let mergedTrace = this.mergeDeveloperTrace(
|
|
495
|
+
aggregatedTrace,
|
|
496
|
+
event.result.developerTrace
|
|
497
|
+
);
|
|
498
|
+
if (!mergedTrace && opts.includeDeveloperTrace) {
|
|
499
|
+
mergedTrace = this.buildSyntheticTraceFromStreamStatus({
|
|
500
|
+
statusTimeline,
|
|
501
|
+
toolsUsed: event.result.toolsUsed,
|
|
502
|
+
durationMs: event.result.durationMs
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
if (mergedTrace) {
|
|
506
|
+
event.result.developerTrace = mergedTrace;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
return event;
|
|
510
|
+
};
|
|
353
511
|
try {
|
|
354
512
|
while (true) {
|
|
355
513
|
const { done, value } = await reader.read();
|
|
@@ -363,7 +521,10 @@ var Query = class {
|
|
|
363
521
|
const data = trimmed.slice(6);
|
|
364
522
|
if (data === "[DONE]") return;
|
|
365
523
|
try {
|
|
366
|
-
|
|
524
|
+
const event = parseAndHydrateEvent(data);
|
|
525
|
+
if (event) {
|
|
526
|
+
yield event;
|
|
527
|
+
}
|
|
367
528
|
} catch {
|
|
368
529
|
}
|
|
369
530
|
}
|
|
@@ -373,7 +534,10 @@ var Query = class {
|
|
|
373
534
|
const data = buffer.trim().slice(6);
|
|
374
535
|
if (data !== "[DONE]") {
|
|
375
536
|
try {
|
|
376
|
-
|
|
537
|
+
const event = parseAndHydrateEvent(data);
|
|
538
|
+
if (event) {
|
|
539
|
+
yield event;
|
|
540
|
+
}
|
|
377
541
|
} catch {
|
|
378
542
|
}
|
|
379
543
|
}
|