@ctxprotocol/sdk 0.9.0 → 0.11.0
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 +25 -9
- package/dist/client/index.cjs +136 -8
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +35 -629
- package/dist/client/index.d.ts +35 -629
- package/dist/client/index.js +135 -9
- package/dist/client/index.js.map +1 -1
- package/dist/contrib/search/index.cjs +703 -0
- package/dist/contrib/search/index.cjs.map +1 -0
- package/dist/contrib/search/index.d.cts +33 -0
- package/dist/contrib/search/index.d.ts +33 -0
- package/dist/contrib/search/index.js +690 -0
- package/dist/contrib/search/index.js.map +1 -0
- package/dist/index.cjs +135 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +135 -9
- package/dist/index.js.map +1 -1
- package/dist/types-DRbq-FA6.d.cts +1180 -0
- package/dist/types-DRbq-FA6.d.ts +1180 -0
- package/package.json +11 -1
package/README.md
CHANGED
|
@@ -96,16 +96,19 @@ const result = await client.tools.execute({
|
|
|
96
96
|
console.log(result.session); // methodPrice, spent, remaining, maxSpend, ...
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
**Query mode** gives you
|
|
99
|
+
**Query mode** gives you a managed librarian contract — the server runs a discovery-first planner contract (`discover/probe -> plan-from-evidence -> execute -> bounded fallback`) with model-aware context budgeting and can return plain answers or structured evidence packages for one flat fee:
|
|
100
100
|
```typescript
|
|
101
101
|
const answer = await client.query.run({
|
|
102
102
|
query: "What are the top whale movements on Base?",
|
|
103
|
-
|
|
103
|
+
answerModelId: "glm-model", // optional: choose the final synthesis model
|
|
104
|
+
responseShape: "answer_with_evidence", // optional: answer | answer_with_evidence | evidence_only
|
|
104
105
|
queryDepth: "deep", // optional: fast | auto | deep
|
|
105
106
|
includeDataUrl: true, // optional: persist full execution data to blob
|
|
106
107
|
includeDeveloperTrace: true, // optional: include machine-readable runtime trace
|
|
107
108
|
});
|
|
108
|
-
console.log(answer.response); //
|
|
109
|
+
console.log(answer.response); // response text or summary
|
|
110
|
+
console.log(answer.summary); // short machine-friendly summary
|
|
111
|
+
console.log(answer.evidence); // structured evidence package
|
|
109
112
|
console.log(answer.toolsUsed); // Which tools were used
|
|
110
113
|
console.log(answer.cost); // Cost breakdown
|
|
111
114
|
console.log(answer.dataUrl); // Optional blob URL with full data
|
|
@@ -114,6 +117,16 @@ console.log(answer.developerTrace?.diagnostics?.selection); // lane + scout prob
|
|
|
114
117
|
console.log(answer.orchestrationMetrics); // high-level first-pass / rediscovery metrics
|
|
115
118
|
```
|
|
116
119
|
|
|
120
|
+
`responseShape` options:
|
|
121
|
+
|
|
122
|
+
- `answer`: backward-compatible prose answer
|
|
123
|
+
- `answer_with_evidence`: prose plus `summary`, `evidence`, `artifacts`, `freshness`, `confidence`, `usage`, `outcome`, and `controller`
|
|
124
|
+
- `evidence_only`: machine-friendly summary plus the same evidence package for downstream agents
|
|
125
|
+
|
|
126
|
+
Premium wedge answers can also expose `evidence.marketIntelligence`, `view.rows`, `view.columns`, and the top-level controller fields `stopReason`, `issueClass`, and `actionsTaken`.
|
|
127
|
+
|
|
128
|
+
The first-party chat app uses the same Query contract and defaults to `answer_with_evidence`.
|
|
129
|
+
|
|
117
130
|
> Mixed listings are first-class: one listing can expose methods to both surfaces. Methods without `_meta.pricing.executeUsd` remain query-only until priced.
|
|
118
131
|
>
|
|
119
132
|
> Compatibility: SDK/API payload fields such as `price` and `pricePerQuery` are retained for backward compatibility. In Query mode, they represent listing-level **price per response turn**.
|
|
@@ -128,8 +141,11 @@ const client = new ContextClient({
|
|
|
128
141
|
apiKey: "sk_live_...",
|
|
129
142
|
});
|
|
130
143
|
|
|
131
|
-
// Pay-per-response: Ask a question, get a
|
|
132
|
-
const answer = await client.query.run(
|
|
144
|
+
// Pay-per-response: Ask a question, get a managed answer package
|
|
145
|
+
const answer = await client.query.run({
|
|
146
|
+
query: "What are the top whale movements on Base?",
|
|
147
|
+
responseShape: "answer_with_evidence",
|
|
148
|
+
});
|
|
133
149
|
console.log(answer.response);
|
|
134
150
|
|
|
135
151
|
// Execute surface: require explicit execute pricing
|
|
@@ -402,7 +418,7 @@ const closed = await client.tools.closeSession("sess_123");
|
|
|
402
418
|
|
|
403
419
|
#### `client.query.run(options)`
|
|
404
420
|
|
|
405
|
-
Run an agentic query. The server applies discovery-first orchestration (`discover/probe -> plan-from-evidence -> execute -> bounded fallback`) with up to 100 MCP calls per response turn, then returns
|
|
421
|
+
Run an agentic query. The server applies discovery-first orchestration (`discover/probe -> plan-from-evidence -> execute -> bounded fallback`) with up to 100 MCP calls per response turn, then returns the selected Query response contract (`answer`, `answer_with_evidence`, or `evidence_only`).
|
|
406
422
|
|
|
407
423
|
`queryDepth` controls orchestration depth:
|
|
408
424
|
- `fast`: lower-latency path for simple lookups.
|
|
@@ -422,14 +438,14 @@ const answer = await client.query.run("What are the top whale movements on Base?
|
|
|
422
438
|
const answer = await client.query.run({
|
|
423
439
|
query: "Analyze whale activity on Base",
|
|
424
440
|
tools: ["tool-uuid-1", "tool-uuid-2"], // optional — auto-discover if omitted
|
|
425
|
-
|
|
441
|
+
answerModelId: "kimi-model-thinking", // optional final synthesis model
|
|
426
442
|
queryDepth: "auto", // optional: fast | auto | deep
|
|
427
443
|
includeData: true, // optional: include execution data inline
|
|
428
444
|
includeDataUrl: true, // optional: include blob URL for full data
|
|
429
445
|
includeDeveloperTrace: true, // optional: include Developer Mode trace
|
|
430
446
|
});
|
|
431
447
|
|
|
432
|
-
console.log(answer.response); //
|
|
448
|
+
console.log(answer.response); // response text or summary
|
|
433
449
|
console.log(answer.toolsUsed); // [{ id, name, skillCalls }]
|
|
434
450
|
console.log(answer.cost); // { modelCostUsd, toolCostUsd, totalCostUsd }
|
|
435
451
|
console.log(answer.durationMs); // Total time
|
|
@@ -564,7 +580,7 @@ interface ExecutionResult<T = unknown> {
|
|
|
564
580
|
|
|
565
581
|
```typescript
|
|
566
582
|
interface QueryResult {
|
|
567
|
-
response: string; //
|
|
583
|
+
response: string; // response text or summary
|
|
568
584
|
toolsUsed: QueryToolUsage[]; // Tools used: { id, name, skillCalls }
|
|
569
585
|
cost: QueryCost; // { modelCostUsd, toolCostUsd, totalCostUsd }
|
|
570
586
|
durationMs: number;
|
package/dist/client/index.cjs
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/client/types.ts
|
|
4
|
+
var ALLOWED_TOOL_CATEGORIES = [
|
|
5
|
+
"Crypto & DeFi",
|
|
6
|
+
"Financial Markets",
|
|
7
|
+
"Business & Sales",
|
|
8
|
+
"Marketing & SEO",
|
|
9
|
+
"Legal & Regulatory",
|
|
10
|
+
"Real World",
|
|
11
|
+
"Developer Tools",
|
|
12
|
+
"Research & Academia",
|
|
13
|
+
"Utility",
|
|
14
|
+
"Other"
|
|
15
|
+
];
|
|
4
16
|
var ContextError = class _ContextError extends Error {
|
|
5
17
|
constructor(message, code, statusCode, helpUrl) {
|
|
6
18
|
super(message);
|
|
@@ -12,6 +24,57 @@ var ContextError = class _ContextError extends Error {
|
|
|
12
24
|
}
|
|
13
25
|
};
|
|
14
26
|
|
|
27
|
+
// src/client/resources/developer.ts
|
|
28
|
+
var Developer = class {
|
|
29
|
+
constructor(client) {
|
|
30
|
+
this.client = client;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Update a tool listing's metadata (name, description, category).
|
|
34
|
+
*
|
|
35
|
+
* Requires an API key belonging to the tool's owner.
|
|
36
|
+
*
|
|
37
|
+
* @param toolId - The UUID of the tool to update
|
|
38
|
+
* @param updates - Fields to update (at least one required)
|
|
39
|
+
* @returns The updated tool metadata
|
|
40
|
+
*
|
|
41
|
+
* @throws {ContextError} If authentication fails or the caller does not own the tool
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const updated = await client.developer.updateTool("tool-uuid", {
|
|
46
|
+
* description: "Updated description with better showcase prompts",
|
|
47
|
+
* category: "crypto",
|
|
48
|
+
* });
|
|
49
|
+
* console.log(updated.updatedAt);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
async updateTool(toolId, updates) {
|
|
53
|
+
if (!toolId) {
|
|
54
|
+
throw new ContextError("toolId is required");
|
|
55
|
+
}
|
|
56
|
+
if (updates.name === void 0 && updates.description === void 0 && updates.category === void 0) {
|
|
57
|
+
throw new ContextError(
|
|
58
|
+
"At least one field required: name, description, or category"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
if (updates.category !== void 0 && updates.category !== null && !ALLOWED_TOOL_CATEGORIES.includes(updates.category)) {
|
|
62
|
+
throw new ContextError(
|
|
63
|
+
`category must be one of: ${ALLOWED_TOOL_CATEGORIES.join(", ")}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
const encodedToolId = encodeURIComponent(toolId);
|
|
67
|
+
return this.client._fetch(
|
|
68
|
+
`/api/v1/tools/${encodedToolId}`,
|
|
69
|
+
{
|
|
70
|
+
method: "PATCH",
|
|
71
|
+
body: JSON.stringify(updates)
|
|
72
|
+
},
|
|
73
|
+
{ retry: false }
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
15
78
|
// src/client/resources/discovery.ts
|
|
16
79
|
var Discovery = class {
|
|
17
80
|
constructor(client) {
|
|
@@ -236,6 +299,47 @@ var Query = class {
|
|
|
236
299
|
constructor(client) {
|
|
237
300
|
this.client = client;
|
|
238
301
|
}
|
|
302
|
+
normalizeResult(result) {
|
|
303
|
+
const candidate = result;
|
|
304
|
+
if (candidate.outcomeType === "clarification_required" && "clarification" in candidate && candidate.clarification) {
|
|
305
|
+
return candidate;
|
|
306
|
+
}
|
|
307
|
+
if (candidate.outcomeType === "capability_miss" && "capabilityMiss" in candidate && candidate.capabilityMiss) {
|
|
308
|
+
return candidate;
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
...candidate,
|
|
312
|
+
outcomeType: "answer"
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
buildPolicyErrorEvent(params) {
|
|
316
|
+
if (params.clarificationPolicy !== "error") {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (params.result.outcomeType === "clarification_required") {
|
|
320
|
+
return {
|
|
321
|
+
type: "error",
|
|
322
|
+
error: params.result.response,
|
|
323
|
+
code: "clarification_required",
|
|
324
|
+
reasonCode: "clarification_required",
|
|
325
|
+
outcomeType: "clarification_required",
|
|
326
|
+
clarification: params.result.clarification,
|
|
327
|
+
querySession: params.result.querySession
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
if (params.result.outcomeType === "capability_miss") {
|
|
331
|
+
return {
|
|
332
|
+
type: "error",
|
|
333
|
+
error: params.result.response,
|
|
334
|
+
code: "capability_miss",
|
|
335
|
+
reasonCode: "capability_miss",
|
|
336
|
+
outcomeType: "capability_miss",
|
|
337
|
+
capabilityMiss: params.result.capabilityMiss,
|
|
338
|
+
querySession: params.result.querySession
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
return void 0;
|
|
342
|
+
}
|
|
239
343
|
buildSyntheticTraceFromRunResult(params) {
|
|
240
344
|
const timeline = params.toolsUsed.map((tool, index) => ({
|
|
241
345
|
stepType: "tool-call",
|
|
@@ -378,6 +482,7 @@ var Query = class {
|
|
|
378
482
|
async run(options) {
|
|
379
483
|
const opts = typeof options === "string" ? { query: options } : options;
|
|
380
484
|
let terminalError;
|
|
485
|
+
let finalResult;
|
|
381
486
|
for await (const event of this.stream(opts)) {
|
|
382
487
|
if (event.type === "error") {
|
|
383
488
|
terminalError = {
|
|
@@ -389,9 +494,12 @@ var Query = class {
|
|
|
389
494
|
continue;
|
|
390
495
|
}
|
|
391
496
|
if (event.type === "done") {
|
|
392
|
-
|
|
497
|
+
finalResult = event.result;
|
|
393
498
|
}
|
|
394
499
|
}
|
|
500
|
+
if (finalResult) {
|
|
501
|
+
return finalResult;
|
|
502
|
+
}
|
|
395
503
|
if (terminalError) {
|
|
396
504
|
throw new ContextError(terminalError.error, terminalError.code);
|
|
397
505
|
}
|
|
@@ -443,7 +551,11 @@ var Query = class {
|
|
|
443
551
|
body: JSON.stringify({
|
|
444
552
|
query: opts.query,
|
|
445
553
|
tools: opts.tools,
|
|
446
|
-
|
|
554
|
+
resumeFrom: opts.resumeFrom,
|
|
555
|
+
forkFrom: opts.forkFrom,
|
|
556
|
+
clarificationPolicy: opts.clarificationPolicy,
|
|
557
|
+
answerModelId: opts.answerModelId,
|
|
558
|
+
responseShape: opts.responseShape,
|
|
447
559
|
includeData: opts.includeData,
|
|
448
560
|
includeDataUrl: opts.includeDataUrl,
|
|
449
561
|
includeDeveloperTrace: opts.includeDeveloperTrace,
|
|
@@ -481,22 +593,31 @@ var Query = class {
|
|
|
481
593
|
return event;
|
|
482
594
|
}
|
|
483
595
|
if (event.type === "done") {
|
|
596
|
+
const normalizedResult = this.normalizeResult(event.result);
|
|
484
597
|
let mergedTrace = this.mergeDeveloperTrace(
|
|
485
598
|
aggregatedTrace,
|
|
486
|
-
|
|
599
|
+
normalizedResult.developerTrace
|
|
487
600
|
);
|
|
488
601
|
if (!mergedTrace && opts.includeDeveloperTrace) {
|
|
489
602
|
mergedTrace = statusTimeline.length > 0 ? this.buildSyntheticTraceFromStreamStatus({
|
|
490
603
|
statusTimeline,
|
|
491
|
-
toolsUsed:
|
|
492
|
-
durationMs:
|
|
604
|
+
toolsUsed: normalizedResult.toolsUsed,
|
|
605
|
+
durationMs: normalizedResult.durationMs
|
|
493
606
|
}) : this.buildSyntheticTraceFromRunResult({
|
|
494
|
-
toolsUsed:
|
|
495
|
-
durationMs:
|
|
607
|
+
toolsUsed: normalizedResult.toolsUsed,
|
|
608
|
+
durationMs: normalizedResult.durationMs
|
|
496
609
|
});
|
|
497
610
|
}
|
|
498
611
|
if (mergedTrace) {
|
|
499
|
-
|
|
612
|
+
normalizedResult.developerTrace = mergedTrace;
|
|
613
|
+
}
|
|
614
|
+
event.result = normalizedResult;
|
|
615
|
+
const policyErrorEvent = this.buildPolicyErrorEvent({
|
|
616
|
+
result: normalizedResult,
|
|
617
|
+
clarificationPolicy: opts.clarificationPolicy
|
|
618
|
+
});
|
|
619
|
+
if (policyErrorEvent) {
|
|
620
|
+
return policyErrorEvent;
|
|
500
621
|
}
|
|
501
622
|
}
|
|
502
623
|
return event;
|
|
@@ -551,6 +672,10 @@ var ContextClient = class {
|
|
|
551
672
|
requestTimeoutMs;
|
|
552
673
|
streamTimeoutMs;
|
|
553
674
|
_closed = false;
|
|
675
|
+
/**
|
|
676
|
+
* Developer resource for managing tool listings (contributor/developer concerns).
|
|
677
|
+
*/
|
|
678
|
+
developer;
|
|
554
679
|
/**
|
|
555
680
|
* Discovery resource for searching tools
|
|
556
681
|
*/
|
|
@@ -592,6 +717,7 @@ var ContextClient = class {
|
|
|
592
717
|
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
593
718
|
this.requestTimeoutMs = requestTimeoutMs;
|
|
594
719
|
this.streamTimeoutMs = streamTimeoutMs;
|
|
720
|
+
this.developer = new Developer(this);
|
|
595
721
|
this.discovery = new Discovery(this);
|
|
596
722
|
this.tools = new Tools(this);
|
|
597
723
|
this.query = new Query(this);
|
|
@@ -750,8 +876,10 @@ var ContextClient = class {
|
|
|
750
876
|
}
|
|
751
877
|
};
|
|
752
878
|
|
|
879
|
+
exports.ALLOWED_TOOL_CATEGORIES = ALLOWED_TOOL_CATEGORIES;
|
|
753
880
|
exports.ContextClient = ContextClient;
|
|
754
881
|
exports.ContextError = ContextError;
|
|
882
|
+
exports.Developer = Developer;
|
|
755
883
|
exports.Discovery = Discovery;
|
|
756
884
|
exports.Query = Query;
|
|
757
885
|
exports.Tools = Tools;
|