@tangle-network/agent-interface 0.26.1 → 0.27.1
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/dist/agent-candidate-compat.d.ts +1918 -0
- package/dist/agent-candidate-compat.js +340 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +2 -0
- package/dist/plan.d.ts +126 -0
- package/dist/plan.js +77 -0
- package/package.json +1 -1
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backward-compatibility surface for the candidate outcome and receipt exports
|
|
3
|
+
* that were renamed or collapsed when the candidate contract was unified.
|
|
4
|
+
*
|
|
5
|
+
* Every symbol here is deprecated and exists only so published consumers that
|
|
6
|
+
* still import the pre-unification names keep resolving at ESM import time.
|
|
7
|
+
* Prefer the current names; these will be removed in a future major.
|
|
8
|
+
*
|
|
9
|
+
* Two shapes of compat live in this module:
|
|
10
|
+
* - Pure renames (shape-identical to a current export) are re-exported as
|
|
11
|
+
* deprecated aliases and remain reference-equal to their new counterpart.
|
|
12
|
+
* - Symbols whose shape changed (a different `schemaVersion` literal, a
|
|
13
|
+
* restructured field, or a union that no longer exists) are re-declared here
|
|
14
|
+
* verbatim from the last release that published them, so old data still
|
|
15
|
+
* parses against the old name instead of silently binding to a newer shape.
|
|
16
|
+
*/
|
|
17
|
+
import { z } from "zod";
|
|
18
|
+
import { agentCandidateModelSettlementCallSchema, agentCandidateModelSettlementEvidenceSchema, agentCandidateModelSettlementMaterialSchema, agentCandidateBenchmarkResultEvidenceSchema, agentCandidateFixedSpendSchema, agentCandidateTaskOutcomeEvidenceSchema, } from "./agent-candidate-outcome-schema.js";
|
|
19
|
+
import { agentCandidateResolvedModelSchema } from "./agent-candidate-execution-plan-schema.js";
|
|
20
|
+
import { agentCandidateSpendSchema } from "./agent-candidate-lineage-schema.js";
|
|
21
|
+
import { agentCandidateMemoryReceiptSchema, agentCandidateTerminationSchema, agentCandidateTraceEvidenceSchema, } from "./agent-candidate-receipt-schema.js";
|
|
22
|
+
import { isCanonicalJsonValue, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated Renamed to {@link agentCandidateModelSettlementCallSchema}.
|
|
25
|
+
* Reference-equal to the current export.
|
|
26
|
+
*/
|
|
27
|
+
export const agentCandidateModelSettlementCallV2Schema = agentCandidateModelSettlementCallSchema;
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated Renamed to {@link agentCandidateModelSettlementMaterialSchema}.
|
|
30
|
+
* Reference-equal to the current export.
|
|
31
|
+
*/
|
|
32
|
+
export const agentCandidateModelSettlementMaterialV2Schema = agentCandidateModelSettlementMaterialSchema;
|
|
33
|
+
// -----------------------------------------------------------------------------
|
|
34
|
+
// Re-added schemas.
|
|
35
|
+
// -----------------------------------------------------------------------------
|
|
36
|
+
const safeCountSchema = z
|
|
37
|
+
.number()
|
|
38
|
+
.int()
|
|
39
|
+
.nonnegative()
|
|
40
|
+
.refine(Number.isSafeInteger, "value must be a nonnegative safe integer");
|
|
41
|
+
const boundedIdentifierSchema = z.string().min(1).max(256);
|
|
42
|
+
/**
|
|
43
|
+
* @deprecated The run receipt no longer carries a standalone model-usage block.
|
|
44
|
+
* Restored `resolved`/`usage` schema for consumers of the V1/V2 run receipt.
|
|
45
|
+
*/
|
|
46
|
+
export const agentCandidateModelUsageSchema = z
|
|
47
|
+
.object({
|
|
48
|
+
resolved: agentCandidateResolvedModelSchema,
|
|
49
|
+
usage: agentCandidateSpendSchema,
|
|
50
|
+
})
|
|
51
|
+
.strict();
|
|
52
|
+
/**
|
|
53
|
+
* Restored per-call aggregate and canonical-value checks shared by the V1
|
|
54
|
+
* settlement material. Mirrors the current internal refinement but tolerates
|
|
55
|
+
* the pre-router call shape that omits `generationId`.
|
|
56
|
+
*/
|
|
57
|
+
function refineLegacyModelSettlementMaterial(material, ctx) {
|
|
58
|
+
const callIds = new Set();
|
|
59
|
+
const traceSpanIds = new Set();
|
|
60
|
+
const totals = {
|
|
61
|
+
inputTokens: 0,
|
|
62
|
+
outputTokens: 0,
|
|
63
|
+
cachedInputTokens: 0,
|
|
64
|
+
reasoningTokens: 0,
|
|
65
|
+
modelCalls: material.calls.length,
|
|
66
|
+
costUsdNanos: 0,
|
|
67
|
+
};
|
|
68
|
+
for (const [index, call] of material.calls.entries()) {
|
|
69
|
+
if (callIds.has(call.callId)) {
|
|
70
|
+
ctx.addIssue({
|
|
71
|
+
code: "custom",
|
|
72
|
+
path: ["calls", index, "callId"],
|
|
73
|
+
message: "model settlement call ids must be unique",
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
callIds.add(call.callId);
|
|
77
|
+
if (traceSpanIds.has(call.traceSpanId)) {
|
|
78
|
+
ctx.addIssue({
|
|
79
|
+
code: "custom",
|
|
80
|
+
path: ["calls", index, "traceSpanId"],
|
|
81
|
+
message: "model settlement trace span ids must be unique",
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
traceSpanIds.add(call.traceSpanId);
|
|
85
|
+
if (call.model !== material.resolved.model) {
|
|
86
|
+
ctx.addIssue({
|
|
87
|
+
code: "custom",
|
|
88
|
+
path: ["calls", index, "model"],
|
|
89
|
+
message: "settled call model must match the resolved single model",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
for (const field of [
|
|
93
|
+
"inputTokens",
|
|
94
|
+
"outputTokens",
|
|
95
|
+
"cachedInputTokens",
|
|
96
|
+
"reasoningTokens",
|
|
97
|
+
"costUsdNanos",
|
|
98
|
+
]) {
|
|
99
|
+
const sum = totals[field] + call[field];
|
|
100
|
+
if (!Number.isSafeInteger(sum)) {
|
|
101
|
+
ctx.addIssue({
|
|
102
|
+
code: "custom",
|
|
103
|
+
path: ["calls", index, field],
|
|
104
|
+
message: `model settlement ${field} total exceeds safe integer range`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
totals[field] = sum;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (!sameFixedSpend(totals, material.usage)) {
|
|
113
|
+
ctx.addIssue({
|
|
114
|
+
code: "custom",
|
|
115
|
+
path: ["usage"],
|
|
116
|
+
message: "model settlement usage must equal the exact per-call aggregate",
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (!isCanonicalJsonValue(material)) {
|
|
120
|
+
ctx.addIssue({
|
|
121
|
+
code: "custom",
|
|
122
|
+
message: "model settlement material must contain only RFC 8785 JSON values",
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const legacyModelSettlementCallV1Schema = z
|
|
127
|
+
.object({
|
|
128
|
+
callId: boundedIdentifierSchema,
|
|
129
|
+
traceSpanId: boundedIdentifierSchema,
|
|
130
|
+
model: boundedIdentifierSchema,
|
|
131
|
+
inputTokens: safeCountSchema,
|
|
132
|
+
outputTokens: safeCountSchema,
|
|
133
|
+
cachedInputTokens: safeCountSchema,
|
|
134
|
+
reasoningTokens: safeCountSchema,
|
|
135
|
+
costUsdNanos: safeCountSchema,
|
|
136
|
+
})
|
|
137
|
+
.strict();
|
|
138
|
+
/**
|
|
139
|
+
* @deprecated The settlement material collapsed to
|
|
140
|
+
* {@link agentCandidateModelSettlementMaterialSchema} (`schemaVersion: 2`).
|
|
141
|
+
* Restored `schemaVersion: 1` parser for the pre-router base call shape.
|
|
142
|
+
*/
|
|
143
|
+
export const agentCandidateModelSettlementMaterialV1Schema = z
|
|
144
|
+
.object({
|
|
145
|
+
schemaVersion: z.literal(1),
|
|
146
|
+
kind: z.literal("agent-candidate-model-settlement-material"),
|
|
147
|
+
executionPlanDigest: sha256DigestSchema,
|
|
148
|
+
preparationId: boundedIdentifierSchema,
|
|
149
|
+
grantDigest: sha256DigestSchema,
|
|
150
|
+
closed: z.literal(true),
|
|
151
|
+
resolved: agentCandidateResolvedModelSchema,
|
|
152
|
+
usage: agentCandidateFixedSpendSchema,
|
|
153
|
+
calls: z.array(legacyModelSettlementCallV1Schema),
|
|
154
|
+
})
|
|
155
|
+
.strict()
|
|
156
|
+
.superRefine(refineLegacyModelSettlementMaterial);
|
|
157
|
+
/**
|
|
158
|
+
* @deprecated The run receipt collapsed to
|
|
159
|
+
* {@link agentCandidateRunReceiptSchema} (`schemaVersion: 3`). Restored
|
|
160
|
+
* `schemaVersion: 1` parser with aggregate usage accounting.
|
|
161
|
+
*/
|
|
162
|
+
export const agentCandidateRunReceiptV1Schema = z
|
|
163
|
+
.object({
|
|
164
|
+
schemaVersion: z.literal(1),
|
|
165
|
+
kind: z.literal("agent-candidate-run"),
|
|
166
|
+
digestAlgorithm: z.literal("rfc8785-sha256"),
|
|
167
|
+
bundleDigest: sha256DigestSchema,
|
|
168
|
+
materializationReceiptDigest: sha256DigestSchema,
|
|
169
|
+
executionPlanDigest: sha256DigestSchema,
|
|
170
|
+
memory: agentCandidateMemoryReceiptSchema,
|
|
171
|
+
usage: agentCandidateSpendSchema,
|
|
172
|
+
modelUsage: agentCandidateModelUsageSchema,
|
|
173
|
+
trace: agentCandidateTraceEvidenceSchema,
|
|
174
|
+
termination: agentCandidateTerminationSchema,
|
|
175
|
+
digest: sha256DigestSchema,
|
|
176
|
+
})
|
|
177
|
+
.strict()
|
|
178
|
+
.superRefine((receipt, ctx) => {
|
|
179
|
+
const usageMatchesModel = receipt.usage.costUsd === receipt.modelUsage.usage.costUsd &&
|
|
180
|
+
receipt.usage.inputTokens === receipt.modelUsage.usage.inputTokens &&
|
|
181
|
+
receipt.usage.outputTokens === receipt.modelUsage.usage.outputTokens &&
|
|
182
|
+
receipt.usage.cachedInputTokens ===
|
|
183
|
+
receipt.modelUsage.usage.cachedInputTokens &&
|
|
184
|
+
receipt.usage.modelCalls === receipt.modelUsage.usage.modelCalls;
|
|
185
|
+
if (!usageMatchesModel) {
|
|
186
|
+
ctx.addIssue({
|
|
187
|
+
code: "custom",
|
|
188
|
+
path: ["modelUsage", "usage"],
|
|
189
|
+
message: "single-model usage must equal aggregate protected usage",
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (receipt.trace.modelCallCount !== receipt.modelUsage.usage.modelCalls) {
|
|
193
|
+
ctx.addIssue({
|
|
194
|
+
code: "custom",
|
|
195
|
+
path: ["trace", "modelCallCount"],
|
|
196
|
+
message: "trace model-call count must match protected single-model usage",
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (!isCanonicalJsonValue(receipt)) {
|
|
200
|
+
ctx.addIssue({
|
|
201
|
+
code: "custom",
|
|
202
|
+
message: "run receipt must contain only RFC 8785 JSON values",
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
function legacyUsageMatchesFixed(legacy, fixed) {
|
|
207
|
+
return (legacy.costUsd === fixed.costUsdNanos / 1_000_000_000 &&
|
|
208
|
+
legacy.inputTokens === fixed.inputTokens &&
|
|
209
|
+
legacy.outputTokens === fixed.outputTokens &&
|
|
210
|
+
(legacy.cachedInputTokens ?? 0) === fixed.cachedInputTokens &&
|
|
211
|
+
legacy.modelCalls === fixed.modelCalls);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* @deprecated The run receipt collapsed to
|
|
215
|
+
* {@link agentCandidateRunReceiptSchema} (`schemaVersion: 3`). Restored
|
|
216
|
+
* `schemaVersion: 2` parser. Its evidence members bind the current settlement,
|
|
217
|
+
* task-outcome, and benchmark-result schemas.
|
|
218
|
+
*/
|
|
219
|
+
export const agentCandidateRunReceiptV2Schema = z
|
|
220
|
+
.object({
|
|
221
|
+
schemaVersion: z.literal(2),
|
|
222
|
+
kind: z.literal("agent-candidate-run"),
|
|
223
|
+
digestAlgorithm: z.literal("rfc8785-sha256"),
|
|
224
|
+
bundleDigest: sha256DigestSchema,
|
|
225
|
+
materializationReceiptDigest: sha256DigestSchema,
|
|
226
|
+
executionPlanDigest: sha256DigestSchema,
|
|
227
|
+
memory: agentCandidateMemoryReceiptSchema,
|
|
228
|
+
usage: agentCandidateSpendSchema,
|
|
229
|
+
modelUsage: agentCandidateModelUsageSchema,
|
|
230
|
+
trace: agentCandidateTraceEvidenceSchema,
|
|
231
|
+
termination: agentCandidateTerminationSchema,
|
|
232
|
+
fixedUsage: agentCandidateFixedSpendSchema,
|
|
233
|
+
modelSettlement: agentCandidateModelSettlementEvidenceSchema,
|
|
234
|
+
taskOutcome: agentCandidateTaskOutcomeEvidenceSchema,
|
|
235
|
+
benchmarkResult: agentCandidateBenchmarkResultEvidenceSchema,
|
|
236
|
+
digest: sha256DigestSchema,
|
|
237
|
+
})
|
|
238
|
+
.strict()
|
|
239
|
+
.superRefine((receipt, ctx) => {
|
|
240
|
+
const legacyUsageMatchesModel = receipt.usage.costUsd === receipt.modelUsage.usage.costUsd &&
|
|
241
|
+
receipt.usage.inputTokens === receipt.modelUsage.usage.inputTokens &&
|
|
242
|
+
receipt.usage.outputTokens === receipt.modelUsage.usage.outputTokens &&
|
|
243
|
+
receipt.usage.cachedInputTokens ===
|
|
244
|
+
receipt.modelUsage.usage.cachedInputTokens &&
|
|
245
|
+
receipt.usage.modelCalls === receipt.modelUsage.usage.modelCalls;
|
|
246
|
+
if (!legacyUsageMatchesModel) {
|
|
247
|
+
ctx.addIssue({
|
|
248
|
+
code: "custom",
|
|
249
|
+
path: ["modelUsage", "usage"],
|
|
250
|
+
message: "single-model usage must equal aggregate protected usage",
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (!legacyUsageMatchesFixed(receipt.usage, receipt.fixedUsage)) {
|
|
254
|
+
ctx.addIssue({
|
|
255
|
+
code: "custom",
|
|
256
|
+
path: ["fixedUsage"],
|
|
257
|
+
message: "fixed usage must exactly preserve the legacy usage totals",
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
if (!sameFixedSpend(receipt.fixedUsage, receipt.modelSettlement.material.usage)) {
|
|
261
|
+
ctx.addIssue({
|
|
262
|
+
code: "custom",
|
|
263
|
+
path: ["modelSettlement", "material", "usage"],
|
|
264
|
+
message: "model settlement aggregate must equal fixed run usage",
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
if (JSON.stringify(receipt.modelUsage.resolved) !==
|
|
268
|
+
JSON.stringify(receipt.modelSettlement.material.resolved)) {
|
|
269
|
+
ctx.addIssue({
|
|
270
|
+
code: "custom",
|
|
271
|
+
path: ["modelSettlement", "material", "resolved"],
|
|
272
|
+
message: "model settlement must bind the run's resolved model",
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
if (receipt.modelSettlement.material.executionPlanDigest !==
|
|
276
|
+
receipt.executionPlanDigest) {
|
|
277
|
+
ctx.addIssue({
|
|
278
|
+
code: "custom",
|
|
279
|
+
path: ["modelSettlement", "material", "executionPlanDigest"],
|
|
280
|
+
message: "model settlement must bind the executed plan",
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
if (receipt.trace.modelCallCount !== receipt.fixedUsage.modelCalls) {
|
|
284
|
+
ctx.addIssue({
|
|
285
|
+
code: "custom",
|
|
286
|
+
path: ["trace", "modelCallCount"],
|
|
287
|
+
message: "trace model-call count must match fixed run usage",
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
if (receipt.taskOutcome.material.executionPlanDigest !==
|
|
291
|
+
receipt.executionPlanDigest) {
|
|
292
|
+
ctx.addIssue({
|
|
293
|
+
code: "custom",
|
|
294
|
+
path: ["taskOutcome", "material", "executionPlanDigest"],
|
|
295
|
+
message: "task outcome must bind the executed plan",
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
if (receipt.benchmarkResult.material.executionPlanDigest !==
|
|
299
|
+
receipt.executionPlanDigest) {
|
|
300
|
+
ctx.addIssue({
|
|
301
|
+
code: "custom",
|
|
302
|
+
path: ["benchmarkResult", "material", "executionPlanDigest"],
|
|
303
|
+
message: "benchmark result must bind the executed plan",
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
if (receipt.benchmarkResult.material.taskOutcomeDigest !==
|
|
307
|
+
receipt.taskOutcome.digest) {
|
|
308
|
+
ctx.addIssue({
|
|
309
|
+
code: "custom",
|
|
310
|
+
path: ["benchmarkResult", "material", "taskOutcomeDigest"],
|
|
311
|
+
message: "benchmark result must bind the exact task outcome",
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
if (!isCanonicalJsonValue(receipt)) {
|
|
315
|
+
ctx.addIssue({
|
|
316
|
+
code: "custom",
|
|
317
|
+
message: "run receipt must contain only RFC 8785 JSON values",
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
/**
|
|
322
|
+
* @deprecated The run receipt generations collapsed into a single current
|
|
323
|
+
* schema. Restored union parser for consumers that accepted both generations.
|
|
324
|
+
*/
|
|
325
|
+
export const agentCandidateRunReceiptAnyVersionSchema = z.union([
|
|
326
|
+
agentCandidateRunReceiptV1Schema,
|
|
327
|
+
agentCandidateRunReceiptV2Schema,
|
|
328
|
+
]);
|
|
329
|
+
/**
|
|
330
|
+
* @deprecated No longer exported from the outcome module. Restored spend-equality
|
|
331
|
+
* helper for consumers that compared fixed-point usage totals.
|
|
332
|
+
*/
|
|
333
|
+
export function sameFixedSpend(left, right) {
|
|
334
|
+
return (left.inputTokens === right.inputTokens &&
|
|
335
|
+
left.outputTokens === right.outputTokens &&
|
|
336
|
+
left.cachedInputTokens === right.cachedInputTokens &&
|
|
337
|
+
left.reasoningTokens === right.reasoningTokens &&
|
|
338
|
+
left.modelCalls === right.modelCalls &&
|
|
339
|
+
left.costUsdNanos === right.costUsdNanos);
|
|
340
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* This package defines the contract between the sidecar and provider implementations.
|
|
6
6
|
*/
|
|
7
7
|
import type { InteractionRequest, InteractionResponse } from "./interaction.js";
|
|
8
|
+
import type { AgentExecutionOutcome, DurablePlan, PlanContinuation, SdkPlanHost } from "./plan.js";
|
|
8
9
|
export type * from "./environment-provider.js";
|
|
10
|
+
export * from "./plan.js";
|
|
9
11
|
export type BackendCapabilities = {
|
|
10
12
|
streaming: boolean;
|
|
11
13
|
toolUse: boolean;
|
|
@@ -218,6 +220,11 @@ export type StreamEvent = MessagePartUpdatedEvent | {
|
|
|
218
220
|
type: "interaction.cancel";
|
|
219
221
|
id: string;
|
|
220
222
|
reason?: string;
|
|
223
|
+
}
|
|
224
|
+
/** A durable plan was committed. This event is observational, not a live ask. */
|
|
225
|
+
| {
|
|
226
|
+
type: "plan.submitted";
|
|
227
|
+
plan: DurablePlan;
|
|
221
228
|
};
|
|
222
229
|
export type ToolInvocation = {
|
|
223
230
|
toolName: string;
|
|
@@ -267,8 +274,11 @@ export type AgentExecutionInput = {
|
|
|
267
274
|
* client-initiated retries of the same intent.
|
|
268
275
|
*/
|
|
269
276
|
turnId?: string;
|
|
277
|
+
/** Server-owned continuation of a previously committed plan decision. */
|
|
278
|
+
planContinuation?: PlanContinuation;
|
|
270
279
|
};
|
|
271
280
|
export type AgentExecutionResult = {
|
|
281
|
+
outcome: AgentExecutionOutcome;
|
|
272
282
|
text: string;
|
|
273
283
|
toolInvocations: ToolInvocation[];
|
|
274
284
|
reasoning?: string[];
|
|
@@ -491,6 +501,7 @@ export interface SdkTraceContext {
|
|
|
491
501
|
export type SdkHostServices = {
|
|
492
502
|
memoryHost: SdkMemoryHost;
|
|
493
503
|
toolHost: SdkToolHost;
|
|
504
|
+
planHost: SdkPlanHost;
|
|
494
505
|
recorder: SdkRecorder;
|
|
495
506
|
providerConfig: ProviderConfig;
|
|
496
507
|
traceContext?: SdkTraceContext;
|
|
@@ -603,6 +614,7 @@ export * from "./interaction.js";
|
|
|
603
614
|
export * from "./agent-candidate.js";
|
|
604
615
|
export * from "./agent-candidate-schema.js";
|
|
605
616
|
export * from "./agent-candidate-promotion-schema.js";
|
|
617
|
+
export * from "./agent-candidate-compat.js";
|
|
606
618
|
export * from "./agent-profile.js";
|
|
607
619
|
export * from "./profile-diff.js";
|
|
608
620
|
export * from "./harness.js";
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Shared types and interfaces for SDK provider adapters.
|
|
5
5
|
* This package defines the contract between the sidecar and provider implementations.
|
|
6
6
|
*/
|
|
7
|
+
export * from "./plan.js";
|
|
7
8
|
/** Helper to check part type */
|
|
8
9
|
export function isTextPart(part) {
|
|
9
10
|
return part.type === "text";
|
|
@@ -126,6 +127,7 @@ export * from "./interaction.js";
|
|
|
126
127
|
export * from "./agent-candidate.js";
|
|
127
128
|
export * from "./agent-candidate-schema.js";
|
|
128
129
|
export * from "./agent-candidate-promotion-schema.js";
|
|
130
|
+
export * from "./agent-candidate-compat.js";
|
|
129
131
|
export * from "./agent-profile.js";
|
|
130
132
|
export * from "./profile-diff.js";
|
|
131
133
|
export * from "./harness.js";
|
package/dist/plan.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Harnesses with an enforceable durable-plan continuation contract. */
|
|
3
|
+
export declare const PlanProviderKindSchema: z.ZodEnum<{
|
|
4
|
+
"claude-code": "claude-code";
|
|
5
|
+
codex: "codex";
|
|
6
|
+
opencode: "opencode";
|
|
7
|
+
}>;
|
|
8
|
+
export type PlanProviderKind = z.infer<typeof PlanProviderKindSchema>;
|
|
9
|
+
/**
|
|
10
|
+
* Credential-free provider correlation committed with the plan. This union is
|
|
11
|
+
* deliberately closed: adding plan support for another harness requires an
|
|
12
|
+
* explicit resume contract instead of smuggling opaque metadata through.
|
|
13
|
+
*/
|
|
14
|
+
export declare const PlanProviderStateSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
15
|
+
kind: z.ZodLiteral<"claude-code">;
|
|
16
|
+
version: z.ZodLiteral<1>;
|
|
17
|
+
nativeSessionId: z.ZodString;
|
|
18
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
19
|
+
kind: z.ZodLiteral<"codex">;
|
|
20
|
+
version: z.ZodLiteral<1>;
|
|
21
|
+
threadId: z.ZodString;
|
|
22
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
23
|
+
kind: z.ZodLiteral<"opencode">;
|
|
24
|
+
version: z.ZodLiteral<1>;
|
|
25
|
+
}, z.core.$strict>], "kind">;
|
|
26
|
+
export type PlanProviderState = z.infer<typeof PlanProviderStateSchema>;
|
|
27
|
+
/**
|
|
28
|
+
* A plan committed by the runtime before the planning turn is allowed to end.
|
|
29
|
+
* The full body is part of the contract so consumers never reconstruct it from
|
|
30
|
+
* rendered chat text.
|
|
31
|
+
*/
|
|
32
|
+
export declare const DurablePlanSchema: z.ZodObject<{
|
|
33
|
+
id: z.ZodString;
|
|
34
|
+
revision: z.ZodNumber;
|
|
35
|
+
title: z.ZodOptional<z.ZodString>;
|
|
36
|
+
body: z.ZodString;
|
|
37
|
+
submittedAt: z.ZodString;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
export type DurablePlan = z.infer<typeof DurablePlanSchema>;
|
|
40
|
+
/** Provider-originated data required to commit a plan exactly once. */
|
|
41
|
+
export declare const PlanSubmissionSchema: z.ZodObject<{
|
|
42
|
+
title: z.ZodOptional<z.ZodString>;
|
|
43
|
+
body: z.ZodString;
|
|
44
|
+
sourceToolCallId: z.ZodString;
|
|
45
|
+
providerState: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
46
|
+
kind: z.ZodLiteral<"claude-code">;
|
|
47
|
+
version: z.ZodLiteral<1>;
|
|
48
|
+
nativeSessionId: z.ZodString;
|
|
49
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
50
|
+
kind: z.ZodLiteral<"codex">;
|
|
51
|
+
version: z.ZodLiteral<1>;
|
|
52
|
+
threadId: z.ZodString;
|
|
53
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
54
|
+
kind: z.ZodLiteral<"opencode">;
|
|
55
|
+
version: z.ZodLiteral<1>;
|
|
56
|
+
}, z.core.$strict>], "kind">;
|
|
57
|
+
}, z.core.$strict>;
|
|
58
|
+
export type PlanSubmission = z.infer<typeof PlanSubmissionSchema>;
|
|
59
|
+
/** The human verdict that starts the next turn. */
|
|
60
|
+
export declare const PlanDecisionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
61
|
+
outcome: z.ZodLiteral<"approved">;
|
|
62
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
63
|
+
outcome: z.ZodLiteral<"rejected">;
|
|
64
|
+
feedback: z.ZodString;
|
|
65
|
+
}, z.core.$strict>], "outcome">;
|
|
66
|
+
export type PlanDecision = z.infer<typeof PlanDecisionSchema>;
|
|
67
|
+
/**
|
|
68
|
+
* Typed server-originated continuation. Adapters consume this instead of
|
|
69
|
+
* inferring approval from a free-form user message.
|
|
70
|
+
*/
|
|
71
|
+
export declare const PlanContinuationSchema: z.ZodObject<{
|
|
72
|
+
version: z.ZodLiteral<1>;
|
|
73
|
+
plan: z.ZodObject<{
|
|
74
|
+
id: z.ZodString;
|
|
75
|
+
revision: z.ZodNumber;
|
|
76
|
+
title: z.ZodOptional<z.ZodString>;
|
|
77
|
+
body: z.ZodString;
|
|
78
|
+
submittedAt: z.ZodString;
|
|
79
|
+
}, z.core.$strict>;
|
|
80
|
+
sourceToolCallId: z.ZodString;
|
|
81
|
+
decision: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
82
|
+
outcome: z.ZodLiteral<"approved">;
|
|
83
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
84
|
+
outcome: z.ZodLiteral<"rejected">;
|
|
85
|
+
feedback: z.ZodString;
|
|
86
|
+
}, z.core.$strict>], "outcome">;
|
|
87
|
+
providerState: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
88
|
+
kind: z.ZodLiteral<"claude-code">;
|
|
89
|
+
version: z.ZodLiteral<1>;
|
|
90
|
+
nativeSessionId: z.ZodString;
|
|
91
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
92
|
+
kind: z.ZodLiteral<"codex">;
|
|
93
|
+
version: z.ZodLiteral<1>;
|
|
94
|
+
threadId: z.ZodString;
|
|
95
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
96
|
+
kind: z.ZodLiteral<"opencode">;
|
|
97
|
+
version: z.ZodLiteral<1>;
|
|
98
|
+
}, z.core.$strict>], "kind">;
|
|
99
|
+
}, z.core.$strict>;
|
|
100
|
+
export type PlanContinuation = z.infer<typeof PlanContinuationSchema>;
|
|
101
|
+
/** Terminal meaning of a successfully completed adapter invocation. */
|
|
102
|
+
export declare const AgentExecutionOutcomeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
103
|
+
type: z.ZodLiteral<"completed">;
|
|
104
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
105
|
+
type: z.ZodLiteral<"awaiting_plan_decision">;
|
|
106
|
+
plan: z.ZodObject<{
|
|
107
|
+
id: z.ZodString;
|
|
108
|
+
revision: z.ZodNumber;
|
|
109
|
+
title: z.ZodOptional<z.ZodString>;
|
|
110
|
+
body: z.ZodString;
|
|
111
|
+
submittedAt: z.ZodString;
|
|
112
|
+
}, z.core.$strict>;
|
|
113
|
+
}, z.core.$strict>], "type">;
|
|
114
|
+
export type AgentExecutionOutcome = z.infer<typeof AgentExecutionOutcomeSchema>;
|
|
115
|
+
/**
|
|
116
|
+
* Per-turn host command used by providers to commit a plan. Implementations
|
|
117
|
+
* bind project, host-session, and turn identity outside provider-controlled
|
|
118
|
+
* input and must resolve only after the durable write commits.
|
|
119
|
+
*/
|
|
120
|
+
export interface SdkPlanHost {
|
|
121
|
+
submit(submission: PlanSubmission): Promise<DurablePlan>;
|
|
122
|
+
/** Publish a committed plan only after the provider turn has terminalized. */
|
|
123
|
+
confirm(planId: string): Promise<void>;
|
|
124
|
+
/** Compensate a committed plan when provider terminalization cannot be proven. */
|
|
125
|
+
withdraw(planId: string, reason: string): Promise<void>;
|
|
126
|
+
}
|
package/dist/plan.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Harnesses with an enforceable durable-plan continuation contract. */
|
|
3
|
+
export const PlanProviderKindSchema = z.enum([
|
|
4
|
+
"claude-code",
|
|
5
|
+
"codex",
|
|
6
|
+
"opencode",
|
|
7
|
+
]);
|
|
8
|
+
/**
|
|
9
|
+
* Credential-free provider correlation committed with the plan. This union is
|
|
10
|
+
* deliberately closed: adding plan support for another harness requires an
|
|
11
|
+
* explicit resume contract instead of smuggling opaque metadata through.
|
|
12
|
+
*/
|
|
13
|
+
export const PlanProviderStateSchema = z.discriminatedUnion("kind", [
|
|
14
|
+
z.object({
|
|
15
|
+
kind: z.literal("claude-code"),
|
|
16
|
+
version: z.literal(1),
|
|
17
|
+
nativeSessionId: z.string().min(1),
|
|
18
|
+
}).strict(),
|
|
19
|
+
z.object({
|
|
20
|
+
kind: z.literal("codex"),
|
|
21
|
+
version: z.literal(1),
|
|
22
|
+
threadId: z.string().min(1),
|
|
23
|
+
}).strict(),
|
|
24
|
+
z.object({
|
|
25
|
+
kind: z.literal("opencode"),
|
|
26
|
+
version: z.literal(1),
|
|
27
|
+
}).strict(),
|
|
28
|
+
]);
|
|
29
|
+
/**
|
|
30
|
+
* A plan committed by the runtime before the planning turn is allowed to end.
|
|
31
|
+
* The full body is part of the contract so consumers never reconstruct it from
|
|
32
|
+
* rendered chat text.
|
|
33
|
+
*/
|
|
34
|
+
export const DurablePlanSchema = z.object({
|
|
35
|
+
id: z.string().min(1),
|
|
36
|
+
revision: z.number().int().positive(),
|
|
37
|
+
title: z.string().trim().min(1).optional(),
|
|
38
|
+
body: z.string().trim().min(1),
|
|
39
|
+
submittedAt: z.string().datetime({ offset: true }),
|
|
40
|
+
}).strict();
|
|
41
|
+
/** Provider-originated data required to commit a plan exactly once. */
|
|
42
|
+
export const PlanSubmissionSchema = z.object({
|
|
43
|
+
title: z.string().trim().min(1).optional(),
|
|
44
|
+
body: z.string().trim().min(1),
|
|
45
|
+
/** Stable provider tool-call identity reused when a lost acknowledgement retries. */
|
|
46
|
+
sourceToolCallId: z.string().min(1),
|
|
47
|
+
/** Credential-free correlation required to resume the deferred turn. */
|
|
48
|
+
providerState: PlanProviderStateSchema,
|
|
49
|
+
}).strict();
|
|
50
|
+
/** The human verdict that starts the next turn. */
|
|
51
|
+
export const PlanDecisionSchema = z.discriminatedUnion("outcome", [
|
|
52
|
+
z.object({ outcome: z.literal("approved") }).strict(),
|
|
53
|
+
z.object({
|
|
54
|
+
outcome: z.literal("rejected"),
|
|
55
|
+
feedback: z.string().trim().min(1),
|
|
56
|
+
}).strict(),
|
|
57
|
+
]);
|
|
58
|
+
/**
|
|
59
|
+
* Typed server-originated continuation. Adapters consume this instead of
|
|
60
|
+
* inferring approval from a free-form user message.
|
|
61
|
+
*/
|
|
62
|
+
export const PlanContinuationSchema = z.object({
|
|
63
|
+
version: z.literal(1),
|
|
64
|
+
plan: DurablePlanSchema,
|
|
65
|
+
sourceToolCallId: z.string().min(1),
|
|
66
|
+
decision: PlanDecisionSchema,
|
|
67
|
+
/** Exact payload previously committed with the plan submission. */
|
|
68
|
+
providerState: PlanProviderStateSchema,
|
|
69
|
+
}).strict();
|
|
70
|
+
/** Terminal meaning of a successfully completed adapter invocation. */
|
|
71
|
+
export const AgentExecutionOutcomeSchema = z.discriminatedUnion("type", [
|
|
72
|
+
z.object({ type: z.literal("completed") }).strict(),
|
|
73
|
+
z.object({
|
|
74
|
+
type: z.literal("awaiting_plan_decision"),
|
|
75
|
+
plan: DurablePlanSchema,
|
|
76
|
+
}).strict(),
|
|
77
|
+
]);
|