@irogane/kaji 0.2.0-beta.11
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/LICENSE +105 -0
- package/README.md +598 -0
- package/contracts/README.md +14 -0
- package/contracts/beta-core-v1.json +52 -0
- package/contracts/cli/init-cases-v1.json +27 -0
- package/contracts/errors/error-codes.json +48 -0
- package/contracts/errors/integration-recovery-v1.json +127 -0
- package/contracts/errors/provider-normalization.json +111 -0
- package/contracts/events/conformance-invalid.json +20 -0
- package/contracts/events/conformance.json +511 -0
- package/contracts/events/new-kaji-event-v1.schema.json +1021 -0
- package/contracts/events/stored-kaji-event-v1.schema.json +1025 -0
- package/contracts/feature-tiers-v1.json +488 -0
- package/contracts/integrations/abi-index-v1.json +8 -0
- package/contracts/integrations/conformance-invalid.json +443 -0
- package/contracts/integrations/conformance-valid.json +121 -0
- package/contracts/integrations/copy-provenance-v1.schema.json +61 -0
- package/contracts/integrations/echo-tool-abi-v1.json +37 -0
- package/contracts/integrations/github-api-conformance-v1.json +644 -0
- package/contracts/integrations/github-tool-abi-typescript-v1.json +369 -0
- package/contracts/integrations/github-tool-abi-v1.json +146 -0
- package/contracts/integrations/gmail-api-conformance-v1.json +750 -0
- package/contracts/integrations/gmail-tool-abi-v1.json +62 -0
- package/contracts/integrations/index.schema.json +37 -0
- package/contracts/integrations/manifest.schema.json +119 -0
- package/contracts/parity/expected-normalized.json +4906 -0
- package/contracts/parity/scenarios.json +100 -0
- package/contracts/parity/scenarios.schema.json +214 -0
- package/contracts/providers/cost-conformance.json +112 -0
- package/contracts/release/github-proof-v1.schema.json +138 -0
- package/contracts/release/gmail-proof-v1.schema.json +138 -0
- package/contracts/release/kaji-ts-consumer-handoff-v1.schema.json +1289 -0
- package/contracts/release/publisher-identity-receipt-v1.schema.json +319 -0
- package/contracts/release/typescript-onboarding-evidence-v1.schema.json +740 -0
- package/contracts/tools/conformance-invalid.json +271 -0
- package/contracts/tools/conformance-valid.json +78 -0
- package/contracts/tools/tool-schema-v1.schema.json +18 -0
- package/dist/anthropic.cjs +1231 -0
- package/dist/anthropic.cjs.map +1 -0
- package/dist/anthropic.d.cts +26 -0
- package/dist/anthropic.d.ts +26 -0
- package/dist/anthropic.js +270 -0
- package/dist/anthropic.js.map +1 -0
- package/dist/auth.cjs +1507 -0
- package/dist/auth.cjs.map +1 -0
- package/dist/auth.d.cts +129 -0
- package/dist/auth.d.ts +129 -0
- package/dist/auth.js +1039 -0
- package/dist/auth.js.map +1 -0
- package/dist/base-B9FRMcP8.d.cts +140 -0
- package/dist/base-nHQd1VtS.d.ts +140 -0
- package/dist/chunk-AAM33KAO.js +4367 -0
- package/dist/chunk-AAM33KAO.js.map +1 -0
- package/dist/chunk-KAJ6BM64.js +153 -0
- package/dist/chunk-KAJ6BM64.js.map +1 -0
- package/dist/chunk-KCAXIOZS.js +308 -0
- package/dist/chunk-KCAXIOZS.js.map +1 -0
- package/dist/chunk-LSJ4AVO2.js +243 -0
- package/dist/chunk-LSJ4AVO2.js.map +1 -0
- package/dist/chunk-TM7ZGOJX.js +716 -0
- package/dist/chunk-TM7ZGOJX.js.map +1 -0
- package/dist/cli/bin.d.ts +2 -0
- package/dist/cli/bin.js +13 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/chunk-2RCWPRVY.js +6277 -0
- package/dist/cli/chunk-2RCWPRVY.js.map +1 -0
- package/dist/cli/chunk-SEBX54TR.js +681 -0
- package/dist/cli/chunk-SEBX54TR.js.map +1 -0
- package/dist/cli/index.d.ts +232 -0
- package/dist/cli/index.js +11 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-worker.d.ts +2 -0
- package/dist/cli/init-worker.js +18 -0
- package/dist/cli/init-worker.js.map +1 -0
- package/dist/cli/integration-copy-worker.js +48 -0
- package/dist/cli/integration-copy-worker.js.map +1 -0
- package/dist/cli/package-entry-cjs.cjs +21 -0
- package/dist/cli/package-entry-cjs.cjs.map +1 -0
- package/dist/cli/package-entry-cjs.d.cts +2 -0
- package/dist/cli/package-entry.d.ts +2 -0
- package/dist/cli/package-entry.js +13 -0
- package/dist/cli/package-entry.js.map +1 -0
- package/dist/context-BaFHrQHv.d.cts +21 -0
- package/dist/context-BaFHrQHv.d.ts +21 -0
- package/dist/context-C-YPY-GS.d.cts +1538 -0
- package/dist/context-C-YPY-GS.d.ts +1538 -0
- package/dist/index.cjs +12346 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1560 -0
- package/dist/index.d.ts +1560 -0
- package/dist/index.js +7852 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/github.cjs +2092 -0
- package/dist/integrations/github.cjs.map +1 -0
- package/dist/integrations/github.d.cts +21 -0
- package/dist/integrations/github.d.ts +21 -0
- package/dist/integrations/github.js +2088 -0
- package/dist/integrations/github.js.map +1 -0
- package/dist/integrations.cjs +3370 -0
- package/dist/integrations.cjs.map +1 -0
- package/dist/integrations.d.cts +202 -0
- package/dist/integrations.d.ts +202 -0
- package/dist/integrations.js +2650 -0
- package/dist/integrations.js.map +1 -0
- package/dist/observability-Cj--OkME.d.cts +96 -0
- package/dist/observability-Cj--OkME.d.ts +96 -0
- package/dist/openai.cjs +1235 -0
- package/dist/openai.cjs.map +1 -0
- package/dist/openai.d.cts +32 -0
- package/dist/openai.d.ts +32 -0
- package/dist/openai.js +272 -0
- package/dist/openai.js.map +1 -0
- package/dist/testing.cjs +554 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +43 -0
- package/dist/testing.d.ts +43 -0
- package/dist/testing.js +118 -0
- package/dist/testing.js.map +1 -0
- package/package.json +188 -0
- package/registry/echo/index.ts +53 -0
- package/registry/echo/manifest.json +53 -0
- package/registry/github/LICENSE +105 -0
- package/registry/github/client.ts +1727 -0
- package/registry/github/index.ts +263 -0
- package/registry/github/manifest.json +227 -0
- package/registry/github/owner-fixtures.json +10 -0
- package/registry/github/tests/github.test.ts +32 -0
- package/registry/gmail/LICENSE +105 -0
- package/registry/gmail/client.ts +548 -0
- package/registry/gmail/index.ts +165 -0
- package/registry/gmail/manifest.json +102 -0
- package/registry/gmail/owner-fixtures.json +10 -0
- package/registry/gmail/tests/gmail.test.ts +32 -0
- package/registry/index.json +21 -0
- package/registry/index.schema.json +37 -0
- package/registry/schema.json +119 -0
|
@@ -0,0 +1,4367 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
import Ajv2020 from 'ajv/dist/2020.js';
|
|
3
|
+
|
|
4
|
+
// src/events/types.ts
|
|
5
|
+
var EventType = {
|
|
6
|
+
SESSION_CREATED: "session.created",
|
|
7
|
+
SESSION_CLOSED: "session.closed",
|
|
8
|
+
USER_MESSAGE: "user.message",
|
|
9
|
+
USER_AUDIO_CHUNK: "user.audio.chunk",
|
|
10
|
+
TRANSCRIPT_PARTIAL: "transcript.partial",
|
|
11
|
+
TRANSCRIPT_FINAL: "transcript.final",
|
|
12
|
+
MEMORY_RETRIEVAL_STARTED: "memory.retrieval.started",
|
|
13
|
+
MEMORY_RETRIEVAL_COMPLETED: "memory.retrieval.completed",
|
|
14
|
+
AGENT_REASONING_STARTED: "agent.reasoning.started",
|
|
15
|
+
AGENT_MESSAGE_DELTA: "agent.message.delta",
|
|
16
|
+
AGENT_MESSAGE_COMPLETED: "agent.message.completed",
|
|
17
|
+
AGENT_TURN_EXHAUSTED: "agent.turn.exhausted",
|
|
18
|
+
AGENT_TURN_FAILED: "agent.turn.failed",
|
|
19
|
+
TOOL_CALL_REQUESTED: "tool.call.requested",
|
|
20
|
+
TOOL_CALL_STARTED: "tool.call.started",
|
|
21
|
+
TOOL_CALL_COMPLETED: "tool.call.completed",
|
|
22
|
+
TOOL_CALL_FAILED: "tool.call.failed",
|
|
23
|
+
TOOL_APPROVAL_REQUESTED: "tool.approval.requested",
|
|
24
|
+
TOOL_APPROVAL_APPROVED: "tool.approval.approved",
|
|
25
|
+
TOOL_APPROVAL_REJECTED: "tool.approval.rejected",
|
|
26
|
+
WORKFLOW_STARTED: "workflow.started",
|
|
27
|
+
WORKFLOW_COMPLETED: "workflow.completed",
|
|
28
|
+
WORKFLOW_FAILED: "workflow.failed",
|
|
29
|
+
CANCELLATION_REQUESTED: "cancellation.requested",
|
|
30
|
+
CANCELLATION_COMPLETED: "cancellation.completed"
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// src/events/errors.ts
|
|
34
|
+
var DURABLE_JSON_SUBJECTS = /* @__PURE__ */ new Set([
|
|
35
|
+
"tool_result",
|
|
36
|
+
"workflow_result",
|
|
37
|
+
"event_metadata",
|
|
38
|
+
"memory_document",
|
|
39
|
+
"pending_tool_call",
|
|
40
|
+
"event"
|
|
41
|
+
]);
|
|
42
|
+
var InvalidDurableValueError = class extends Error {
|
|
43
|
+
constructor(subject) {
|
|
44
|
+
super(`Invalid durable JSON value for ${subject}`);
|
|
45
|
+
this.subject = subject;
|
|
46
|
+
this.name = "InvalidDurableValueError";
|
|
47
|
+
}
|
|
48
|
+
subject;
|
|
49
|
+
code = "INVALID_DURABLE_VALUE";
|
|
50
|
+
};
|
|
51
|
+
var DurableJsonLimitError = class extends Error {
|
|
52
|
+
constructor(subject, maxBytes) {
|
|
53
|
+
super(`Durable JSON value for ${subject} exceeds ${maxBytes} UTF-8 bytes`);
|
|
54
|
+
this.subject = subject;
|
|
55
|
+
this.maxBytes = maxBytes;
|
|
56
|
+
this.name = "DurableJsonLimitError";
|
|
57
|
+
}
|
|
58
|
+
subject;
|
|
59
|
+
maxBytes;
|
|
60
|
+
code = "EVENT_PAYLOAD_TOO_LARGE";
|
|
61
|
+
};
|
|
62
|
+
var EventSchemaIncompatibleError = class extends Error {
|
|
63
|
+
constructor(path) {
|
|
64
|
+
super(`Event schema is incompatible at ${path}`);
|
|
65
|
+
this.path = path;
|
|
66
|
+
this.name = "EventSchemaIncompatibleError";
|
|
67
|
+
}
|
|
68
|
+
path;
|
|
69
|
+
code = "EVENT_SCHEMA_INCOMPATIBLE";
|
|
70
|
+
};
|
|
71
|
+
var EventIdConflictError = class extends Error {
|
|
72
|
+
constructor(eventId) {
|
|
73
|
+
super(`Event id ${eventId} already belongs to a different event`);
|
|
74
|
+
this.eventId = eventId;
|
|
75
|
+
this.name = "EventIdConflictError";
|
|
76
|
+
}
|
|
77
|
+
eventId;
|
|
78
|
+
code = "EVENT_ID_CONFLICT";
|
|
79
|
+
};
|
|
80
|
+
var EventStoreCapacityError = class extends Error {
|
|
81
|
+
constructor(sessionId, message) {
|
|
82
|
+
super(message);
|
|
83
|
+
this.sessionId = sessionId;
|
|
84
|
+
this.name = "EventStoreCapacityError";
|
|
85
|
+
}
|
|
86
|
+
sessionId;
|
|
87
|
+
code = "EVENT_STORE_CAPACITY_EXCEEDED";
|
|
88
|
+
};
|
|
89
|
+
var SessionPurgeBusyError = class extends Error {
|
|
90
|
+
constructor(sessionId) {
|
|
91
|
+
super(`Session ${sessionId} cannot be purged while work is active`);
|
|
92
|
+
this.sessionId = sessionId;
|
|
93
|
+
this.name = "SessionPurgeBusyError";
|
|
94
|
+
}
|
|
95
|
+
sessionId;
|
|
96
|
+
code = "SESSION_PURGE_BUSY";
|
|
97
|
+
};
|
|
98
|
+
var SessionPurgeUnsupportedError = class extends Error {
|
|
99
|
+
constructor(sessionId, component = "event_store") {
|
|
100
|
+
super(`Session ${sessionId} cannot be purged by ${component.replaceAll("_", " ")}`);
|
|
101
|
+
this.sessionId = sessionId;
|
|
102
|
+
this.component = component;
|
|
103
|
+
this.name = "SessionPurgeUnsupportedError";
|
|
104
|
+
}
|
|
105
|
+
sessionId;
|
|
106
|
+
component;
|
|
107
|
+
code = "SESSION_PURGE_UNSUPPORTED";
|
|
108
|
+
};
|
|
109
|
+
var EventBufferOverflowError = class extends Error {
|
|
110
|
+
constructor(lastSequence, latestSequence) {
|
|
111
|
+
super(
|
|
112
|
+
`Subscriber buffer overflowed after sequence ${lastSequence}; latest sequence is ${latestSequence}`
|
|
113
|
+
);
|
|
114
|
+
this.lastSequence = lastSequence;
|
|
115
|
+
this.latestSequence = latestSequence;
|
|
116
|
+
this.name = "EventBufferOverflowError";
|
|
117
|
+
}
|
|
118
|
+
lastSequence;
|
|
119
|
+
latestSequence;
|
|
120
|
+
code = "EVENT_BUFFER_OVERFLOW";
|
|
121
|
+
};
|
|
122
|
+
var EventDeliveryError = class extends Error {
|
|
123
|
+
constructor(phase, eventId, persisted, options) {
|
|
124
|
+
super(`Event ${phase} failed for ${eventId}`, options);
|
|
125
|
+
this.phase = phase;
|
|
126
|
+
this.eventId = eventId;
|
|
127
|
+
this.persisted = persisted;
|
|
128
|
+
this.name = "EventDeliveryError";
|
|
129
|
+
this.code = phase === "append" ? "EVENT_APPEND_FAILED" : "EVENT_PUBLISH_FAILED";
|
|
130
|
+
}
|
|
131
|
+
phase;
|
|
132
|
+
eventId;
|
|
133
|
+
persisted;
|
|
134
|
+
code;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// src/internal/uuid.ts
|
|
138
|
+
function defaultUuid() {
|
|
139
|
+
const c = globalThis.crypto;
|
|
140
|
+
if (c?.randomUUID) return c.randomUUID();
|
|
141
|
+
const hex = (bytes) => Math.floor(Math.random() * 16 ** (bytes * 2)).toString(16).padStart(bytes * 2, "0");
|
|
142
|
+
return `${hex(4)}-${hex(2)}-${hex(2)}-${hex(2)}-${hex(6)}`;
|
|
143
|
+
}
|
|
144
|
+
var systemIdFactory = Object.freeze({
|
|
145
|
+
next: (_scope) => defaultUuid()
|
|
146
|
+
});
|
|
147
|
+
var systemClock = Object.freeze({
|
|
148
|
+
nowWallSeconds: () => Date.now() / 1e3,
|
|
149
|
+
nowMonotonic: () => globalThis.performance.now()
|
|
150
|
+
});
|
|
151
|
+
var systemTimerScheduler = Object.freeze({
|
|
152
|
+
schedule: (delayMs, callback) => {
|
|
153
|
+
if (!Number.isFinite(delayMs) || delayMs < 0) {
|
|
154
|
+
throw new RangeError("delayMs must be a finite non-negative number");
|
|
155
|
+
}
|
|
156
|
+
let remaining = Math.max(0, delayMs);
|
|
157
|
+
let timer;
|
|
158
|
+
let cancelled = false;
|
|
159
|
+
const arm = () => {
|
|
160
|
+
const step = Math.min(remaining, 2147483647);
|
|
161
|
+
timer = setTimeout(() => {
|
|
162
|
+
if (cancelled) return;
|
|
163
|
+
remaining -= step;
|
|
164
|
+
if (remaining <= 0) callback();
|
|
165
|
+
else arm();
|
|
166
|
+
}, step);
|
|
167
|
+
};
|
|
168
|
+
arm();
|
|
169
|
+
return {
|
|
170
|
+
cancel: () => {
|
|
171
|
+
cancelled = true;
|
|
172
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// src/contracts/integration-recovery.ts
|
|
179
|
+
var DOCS = "https://kaji.dev/docs/integrations/recovery-v1";
|
|
180
|
+
function recovery(errorCode, recoveryCode, anchor, problem, cause, fix) {
|
|
181
|
+
return Object.freeze({
|
|
182
|
+
errorCode,
|
|
183
|
+
recoveryCode,
|
|
184
|
+
docUrl: `${DOCS}#${anchor}`,
|
|
185
|
+
problem,
|
|
186
|
+
cause,
|
|
187
|
+
fix
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
var INTEGRATION_RECOVERY = Object.freeze({
|
|
191
|
+
github_token_missing: recovery(
|
|
192
|
+
"INTEGRATION_AUTH_REQUIRED",
|
|
193
|
+
"CONFIGURE_GITHUB_TOKEN",
|
|
194
|
+
"github-token",
|
|
195
|
+
"GitHub authentication is required.",
|
|
196
|
+
"The configured GitHub token is unavailable.",
|
|
197
|
+
"Set the manifest-declared GitHub token environment variable and retry."
|
|
198
|
+
),
|
|
199
|
+
gmail_grant_missing: recovery(
|
|
200
|
+
"INTEGRATION_AUTH_REQUIRED",
|
|
201
|
+
"CONNECT_GMAIL",
|
|
202
|
+
"gmail-grant",
|
|
203
|
+
"Gmail authorization is required.",
|
|
204
|
+
"No Gmail grant exists for this principal.",
|
|
205
|
+
"Use the package-qualified connect command for this runtime and principal, then retry."
|
|
206
|
+
),
|
|
207
|
+
keychain_missing: recovery(
|
|
208
|
+
"INTEGRATION_AUTH_ERROR",
|
|
209
|
+
"RESTORE_KEYCHAIN",
|
|
210
|
+
"keychain-missing",
|
|
211
|
+
"The macOS Keychain is unavailable.",
|
|
212
|
+
"The Keychain command could not be found.",
|
|
213
|
+
"Restore `/usr/bin/security` on a supported macOS host and retry."
|
|
214
|
+
),
|
|
215
|
+
keychain_locked: recovery(
|
|
216
|
+
"INTEGRATION_AUTH_ERROR",
|
|
217
|
+
"UNLOCK_KEYCHAIN",
|
|
218
|
+
"keychain-locked",
|
|
219
|
+
"The macOS Keychain is locked.",
|
|
220
|
+
"The stored integration grant cannot be read while Keychain is locked.",
|
|
221
|
+
"Unlock the login Keychain and retry."
|
|
222
|
+
),
|
|
223
|
+
keychain_corrupt: recovery(
|
|
224
|
+
"INTEGRATION_AUTH_ERROR",
|
|
225
|
+
"RESET_GMAIL_GRANT",
|
|
226
|
+
"keychain-corrupt",
|
|
227
|
+
"The stored Gmail grant is invalid.",
|
|
228
|
+
"The Keychain entry is corrupt or incomplete.",
|
|
229
|
+
"Disconnect Gmail locally, then reconnect with the same principal."
|
|
230
|
+
),
|
|
231
|
+
keychain_unsupported: recovery(
|
|
232
|
+
"INTEGRATION_AUTH_ERROR",
|
|
233
|
+
"USE_SUPPORTED_KEYCHAIN",
|
|
234
|
+
"keychain-unsupported",
|
|
235
|
+
"Secure Gmail grant storage is unsupported.",
|
|
236
|
+
"This host cannot provide the required macOS Keychain boundary.",
|
|
237
|
+
"Use a supported macOS host; do not fall back to plaintext storage."
|
|
238
|
+
),
|
|
239
|
+
gmail_scope_drift: recovery(
|
|
240
|
+
"INTEGRATION_AUTH_REQUIRED",
|
|
241
|
+
"RECONNECT_GMAIL",
|
|
242
|
+
"gmail-scope-drift",
|
|
243
|
+
"The Gmail grant no longer has the required scopes.",
|
|
244
|
+
"Stored and required OAuth scopes differ.",
|
|
245
|
+
"Use the package-qualified connect command for this runtime and principal, then consent again."
|
|
246
|
+
),
|
|
247
|
+
policy_rejected: recovery(
|
|
248
|
+
"INTEGRATION_POLICY_REJECTED",
|
|
249
|
+
"REVIEW_INTEGRATION_POLICY",
|
|
250
|
+
"policy-rejected",
|
|
251
|
+
"The integration request was rejected before dispatch.",
|
|
252
|
+
"A fixed-origin, repository, recipient, or schema policy did not match.",
|
|
253
|
+
"Review the integration allowlist and request shape before retrying."
|
|
254
|
+
),
|
|
255
|
+
api_rejected: recovery(
|
|
256
|
+
"INTEGRATION_API_ERROR",
|
|
257
|
+
"REVIEW_PROVIDER_REJECTION",
|
|
258
|
+
"api-rejected",
|
|
259
|
+
"The provider rejected the integration request.",
|
|
260
|
+
"The provider returned a confirmed non-retryable API rejection.",
|
|
261
|
+
"Review the request against the provider response guidance before retrying manually."
|
|
262
|
+
),
|
|
263
|
+
transient_read_failed: recovery(
|
|
264
|
+
"INTEGRATION_API_ERROR",
|
|
265
|
+
"RETRY_INTEGRATION_READ",
|
|
266
|
+
"transient-read",
|
|
267
|
+
"The integration read did not complete.",
|
|
268
|
+
"The provider returned a transient failure before any external effect.",
|
|
269
|
+
"Retry the idempotent read with bounded backoff."
|
|
270
|
+
),
|
|
271
|
+
rate_limited: recovery(
|
|
272
|
+
"INTEGRATION_RATE_LIMITED",
|
|
273
|
+
"RETRY_AFTER_RATE_LIMIT",
|
|
274
|
+
"rate-limited",
|
|
275
|
+
"The provider rate limit was reached.",
|
|
276
|
+
"The provider confirmed that this request was rate limited.",
|
|
277
|
+
"Reduce parallelism and retry only after the bounded provider delay."
|
|
278
|
+
),
|
|
279
|
+
redirect_rejected: recovery(
|
|
280
|
+
"INTEGRATION_REDIRECT_REJECTED",
|
|
281
|
+
"REJECT_PROVIDER_REDIRECT",
|
|
282
|
+
"redirect-rejected",
|
|
283
|
+
"The provider returned a redirect that Kaji will not follow.",
|
|
284
|
+
"Fixed-origin integration requests reject every redirect.",
|
|
285
|
+
"Verify the provider endpoint; do not retry an ambiguous mutation blindly."
|
|
286
|
+
),
|
|
287
|
+
response_limit_exceeded: recovery(
|
|
288
|
+
"INTEGRATION_RESPONSE_LIMIT",
|
|
289
|
+
"REDUCE_INTEGRATION_RESPONSE",
|
|
290
|
+
"response-limit",
|
|
291
|
+
"The integration response exceeded a safety bound.",
|
|
292
|
+
"Provider headers or body were malformed or too large.",
|
|
293
|
+
"Narrow the read request; reconcile a mutation before any retry."
|
|
294
|
+
),
|
|
295
|
+
github_mutation_unknown: recovery(
|
|
296
|
+
"TOOL_EXECUTION_FAILED",
|
|
297
|
+
"RECONCILE_GITHUB_MUTATION",
|
|
298
|
+
"github-mutation-unknown",
|
|
299
|
+
"The GitHub mutation outcome is unknown.",
|
|
300
|
+
"The connection failed after dispatch without a confirmed provider result.",
|
|
301
|
+
"Reconcile the GitHub issue or comment marker before any manual retry."
|
|
302
|
+
),
|
|
303
|
+
gmail_mutation_unknown: recovery(
|
|
304
|
+
"TOOL_EXECUTION_FAILED",
|
|
305
|
+
"RECONCILE_GMAIL_MUTATION",
|
|
306
|
+
"gmail-mutation-unknown",
|
|
307
|
+
"The Gmail mutation outcome is unknown.",
|
|
308
|
+
"The connection failed after dispatch without a confirmed provider result.",
|
|
309
|
+
"Reconcile the Gmail draft key or sent message before any manual retry."
|
|
310
|
+
)
|
|
311
|
+
});
|
|
312
|
+
function closedRecoveryFields(value) {
|
|
313
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
314
|
+
const candidate = value;
|
|
315
|
+
if (typeof candidate.reason_code !== "string" || typeof candidate.recovery_code !== "string" || typeof candidate.doc_url !== "string") {
|
|
316
|
+
return void 0;
|
|
317
|
+
}
|
|
318
|
+
const recovery2 = INTEGRATION_RECOVERY[candidate.reason_code];
|
|
319
|
+
if (recovery2 === void 0 || recovery2.recoveryCode !== candidate.recovery_code || recovery2.docUrl !== candidate.doc_url || "error_code" in candidate && recovery2.errorCode !== candidate.error_code) {
|
|
320
|
+
return void 0;
|
|
321
|
+
}
|
|
322
|
+
return Object.freeze({
|
|
323
|
+
reason_code: candidate.reason_code,
|
|
324
|
+
recovery_code: candidate.recovery_code,
|
|
325
|
+
doc_url: candidate.doc_url
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
function closedTransportFailureFields(value) {
|
|
329
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
330
|
+
const candidate = value;
|
|
331
|
+
const fields = closedRecoveryFields(candidate);
|
|
332
|
+
if (fields === void 0 || typeof candidate.error_code !== "string") return void 0;
|
|
333
|
+
const recovery2 = INTEGRATION_RECOVERY[fields.reason_code];
|
|
334
|
+
if (candidate.error_code !== recovery2.errorCode) return void 0;
|
|
335
|
+
return Object.freeze({ error_code: recovery2.errorCode, ...fields });
|
|
336
|
+
}
|
|
337
|
+
function isClosedRecoveryTuple(reasonCode, recoveryCode, docUrl, errorCode) {
|
|
338
|
+
if (reasonCode === void 0 && recoveryCode === void 0 && docUrl === void 0) return true;
|
|
339
|
+
return closedRecoveryFields({
|
|
340
|
+
error_code: errorCode,
|
|
341
|
+
reason_code: reasonCode,
|
|
342
|
+
recovery_code: recoveryCode,
|
|
343
|
+
doc_url: docUrl
|
|
344
|
+
}) !== void 0;
|
|
345
|
+
}
|
|
346
|
+
function cloneAndFreezeJson(value) {
|
|
347
|
+
return cloneJsonValue(value, /* @__PURE__ */ new WeakSet());
|
|
348
|
+
}
|
|
349
|
+
function structurallyEqualJson(left, right) {
|
|
350
|
+
return canonicalJsonValue(left) === canonicalJsonValue(right);
|
|
351
|
+
}
|
|
352
|
+
function canonicalJsonValue(value, subject = "JSON value") {
|
|
353
|
+
const ancestors = /* @__PURE__ */ new WeakSet();
|
|
354
|
+
const assertUnicodeScalarString = (text) => {
|
|
355
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
356
|
+
const unit = text.charCodeAt(index);
|
|
357
|
+
if (unit >= 55296 && unit <= 56319) {
|
|
358
|
+
const next = text.charCodeAt(index + 1);
|
|
359
|
+
if (!(next >= 56320 && next <= 57343)) {
|
|
360
|
+
throw new TypeError(`${subject} contains an unpaired Unicode surrogate`);
|
|
361
|
+
}
|
|
362
|
+
index += 1;
|
|
363
|
+
} else if (unit >= 56320 && unit <= 57343) {
|
|
364
|
+
throw new TypeError(`${subject} contains an unpaired Unicode surrogate`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
const encode = (item) => {
|
|
369
|
+
if (item === null) return "null";
|
|
370
|
+
switch (typeof item) {
|
|
371
|
+
case "boolean":
|
|
372
|
+
return item ? "true" : "false";
|
|
373
|
+
case "string":
|
|
374
|
+
assertUnicodeScalarString(item);
|
|
375
|
+
return JSON.stringify(item);
|
|
376
|
+
case "number":
|
|
377
|
+
if (!Number.isFinite(item)) throw new TypeError(`${subject} contains a non-finite number`);
|
|
378
|
+
if (Number.isInteger(item) && !Number.isSafeInteger(item)) {
|
|
379
|
+
throw new TypeError(`${subject} contains an integer outside the I-JSON safe range`);
|
|
380
|
+
}
|
|
381
|
+
return Object.is(item, -0) ? "0" : item.toString();
|
|
382
|
+
case "object": {
|
|
383
|
+
if (ancestors.has(item)) throw new TypeError(`${subject} must be acyclic`);
|
|
384
|
+
if (Object.getOwnPropertySymbols(item).length > 0) {
|
|
385
|
+
throw new TypeError(`${subject} JSON object keys must be strings`);
|
|
386
|
+
}
|
|
387
|
+
ancestors.add(item);
|
|
388
|
+
try {
|
|
389
|
+
if (Array.isArray(item)) {
|
|
390
|
+
const descriptors = Object.getOwnPropertyDescriptors(item);
|
|
391
|
+
const values = [];
|
|
392
|
+
for (let index = 0; index < item.length; index += 1) {
|
|
393
|
+
const descriptor = descriptors[String(index)];
|
|
394
|
+
if (descriptor === void 0 || !descriptor.enumerable || !("value" in descriptor)) {
|
|
395
|
+
throw new TypeError(`${subject} array values must be enumerable data values`);
|
|
396
|
+
}
|
|
397
|
+
values.push(encode(descriptor.value));
|
|
398
|
+
}
|
|
399
|
+
for (const key of Object.keys(descriptors)) {
|
|
400
|
+
if (key === "length") continue;
|
|
401
|
+
const index = Number(key);
|
|
402
|
+
if (Number.isInteger(index) && index >= 0 && index < item.length && String(index) === key) {
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
throw new TypeError(`${subject} arrays cannot carry named properties`);
|
|
406
|
+
}
|
|
407
|
+
return `[${values.join(",")}]`;
|
|
408
|
+
}
|
|
409
|
+
const prototype = Object.getPrototypeOf(item);
|
|
410
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
411
|
+
throw new TypeError(`${subject} contains a non-plain object`);
|
|
412
|
+
}
|
|
413
|
+
const keys = Object.getOwnPropertyNames(item);
|
|
414
|
+
for (const key of keys) {
|
|
415
|
+
assertUnicodeScalarString(key);
|
|
416
|
+
const descriptor = Object.getOwnPropertyDescriptor(item, key);
|
|
417
|
+
if (descriptor === void 0 || !descriptor.enumerable || !("value" in descriptor)) {
|
|
418
|
+
throw new TypeError(
|
|
419
|
+
`${subject} JSON object properties must be enumerable data values`
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return `{${keys.sort().map((key) => {
|
|
424
|
+
const descriptor = Object.getOwnPropertyDescriptor(item, key);
|
|
425
|
+
return `${JSON.stringify(key)}:${encode(descriptor.value)}`;
|
|
426
|
+
}).join(",")}}`;
|
|
427
|
+
} finally {
|
|
428
|
+
ancestors.delete(item);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
default:
|
|
432
|
+
throw new TypeError(`${subject} contains non-JSON value ${typeof item}`);
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
return encode(value);
|
|
436
|
+
}
|
|
437
|
+
function durableJsonSnapshot(value, subject, maxBytes) {
|
|
438
|
+
if (!DURABLE_JSON_SUBJECTS.has(subject)) {
|
|
439
|
+
throw new RangeError("Durable JSON subject must use the closed vocabulary");
|
|
440
|
+
}
|
|
441
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) {
|
|
442
|
+
throw new RangeError("maxBytes must be a non-negative safe integer");
|
|
443
|
+
}
|
|
444
|
+
let encoded;
|
|
445
|
+
try {
|
|
446
|
+
encoded = canonicalJsonValue(value, subject);
|
|
447
|
+
} catch {
|
|
448
|
+
throw new InvalidDurableValueError(subject);
|
|
449
|
+
}
|
|
450
|
+
if (new TextEncoder().encode(encoded).byteLength > maxBytes) {
|
|
451
|
+
throw new DurableJsonLimitError(subject, maxBytes);
|
|
452
|
+
}
|
|
453
|
+
return cloneAndFreezeJson(JSON.parse(encoded));
|
|
454
|
+
}
|
|
455
|
+
function cloneJsonValue(value, ancestors) {
|
|
456
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return value;
|
|
457
|
+
if (typeof value === "number") {
|
|
458
|
+
if (!Number.isFinite(value) || Number.isInteger(value) && !Number.isSafeInteger(value)) {
|
|
459
|
+
throw new TypeError("Event values must be JSON-safe");
|
|
460
|
+
}
|
|
461
|
+
return value;
|
|
462
|
+
}
|
|
463
|
+
if (Array.isArray(value)) {
|
|
464
|
+
enter(value, ancestors);
|
|
465
|
+
const clone = value.map((item) => cloneJsonValue(item, ancestors));
|
|
466
|
+
ancestors.delete(value);
|
|
467
|
+
return Object.freeze(clone);
|
|
468
|
+
}
|
|
469
|
+
if (typeof value === "object") {
|
|
470
|
+
assertJsonObject(value);
|
|
471
|
+
enter(value, ancestors);
|
|
472
|
+
const clone = {};
|
|
473
|
+
for (const [key, child] of Object.entries(value)) {
|
|
474
|
+
Object.defineProperty(clone, key, {
|
|
475
|
+
value: cloneJsonValue(child, ancestors),
|
|
476
|
+
enumerable: true,
|
|
477
|
+
writable: true,
|
|
478
|
+
configurable: true
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
ancestors.delete(value);
|
|
482
|
+
return Object.freeze(clone);
|
|
483
|
+
}
|
|
484
|
+
throw new TypeError("Event values must be JSON-safe");
|
|
485
|
+
}
|
|
486
|
+
function assertJsonObject(value) {
|
|
487
|
+
const prototype = Object.getPrototypeOf(value);
|
|
488
|
+
if (prototype !== Object.prototype && prototype !== null || Object.getOwnPropertySymbols(value).length > 0) {
|
|
489
|
+
throw new TypeError("Event values must be JSON-safe");
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
function enter(value, ancestors) {
|
|
493
|
+
if (ancestors.has(value)) throw new TypeError("Event values must be JSON-safe and acyclic");
|
|
494
|
+
ancestors.add(value);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// contracts/events/new-kaji-event-v1.schema.json
|
|
498
|
+
var new_kaji_event_v1_schema_default = {
|
|
499
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
500
|
+
$id: "https://kaji.dev/contracts/events/new-kaji-event-v1.schema.json",
|
|
501
|
+
title: "New Kaji event",
|
|
502
|
+
"x-maxSerializedBytes": 1048576,
|
|
503
|
+
$defs: {
|
|
504
|
+
nonEmptyId: {
|
|
505
|
+
type: "string",
|
|
506
|
+
minLength: 1
|
|
507
|
+
},
|
|
508
|
+
integrationRecoveryFields: {
|
|
509
|
+
oneOf: [
|
|
510
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_REQUIRED" }, reason_code: { const: "github_token_missing" }, recovery_code: { const: "CONFIGURE_GITHUB_TOKEN" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#github-token" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
511
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_REQUIRED" }, reason_code: { const: "gmail_grant_missing" }, recovery_code: { const: "CONNECT_GMAIL" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#gmail-grant" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
512
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_ERROR" }, reason_code: { const: "keychain_missing" }, recovery_code: { const: "RESTORE_KEYCHAIN" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#keychain-missing" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
513
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_ERROR" }, reason_code: { const: "keychain_locked" }, recovery_code: { const: "UNLOCK_KEYCHAIN" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#keychain-locked" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
514
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_ERROR" }, reason_code: { const: "keychain_corrupt" }, recovery_code: { const: "RESET_GMAIL_GRANT" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#keychain-corrupt" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
515
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_ERROR" }, reason_code: { const: "keychain_unsupported" }, recovery_code: { const: "USE_SUPPORTED_KEYCHAIN" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#keychain-unsupported" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
516
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_REQUIRED" }, reason_code: { const: "gmail_scope_drift" }, recovery_code: { const: "RECONNECT_GMAIL" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#gmail-scope-drift" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
517
|
+
{ properties: { error_code: { const: "INTEGRATION_POLICY_REJECTED" }, reason_code: { const: "policy_rejected" }, recovery_code: { const: "REVIEW_INTEGRATION_POLICY" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#policy-rejected" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
518
|
+
{ properties: { error_code: { const: "INTEGRATION_API_ERROR" }, reason_code: { const: "api_rejected" }, recovery_code: { const: "REVIEW_PROVIDER_REJECTION" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#api-rejected" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
519
|
+
{ properties: { error_code: { const: "INTEGRATION_API_ERROR" }, reason_code: { const: "transient_read_failed" }, recovery_code: { const: "RETRY_INTEGRATION_READ" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#transient-read" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
520
|
+
{ properties: { error_code: { const: "INTEGRATION_RATE_LIMITED" }, reason_code: { const: "rate_limited" }, recovery_code: { const: "RETRY_AFTER_RATE_LIMIT" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#rate-limited" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
521
|
+
{ properties: { error_code: { const: "INTEGRATION_REDIRECT_REJECTED" }, reason_code: { const: "redirect_rejected" }, recovery_code: { const: "REJECT_PROVIDER_REDIRECT" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#redirect-rejected" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
522
|
+
{ properties: { error_code: { const: "INTEGRATION_RESPONSE_LIMIT" }, reason_code: { const: "response_limit_exceeded" }, recovery_code: { const: "REDUCE_INTEGRATION_RESPONSE" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#response-limit" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
523
|
+
{ properties: { error_code: { const: "TOOL_EXECUTION_FAILED" }, reason_code: { const: "github_mutation_unknown" }, recovery_code: { const: "RECONCILE_GITHUB_MUTATION" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#github-mutation-unknown" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
524
|
+
{ properties: { error_code: { const: "TOOL_EXECUTION_FAILED" }, reason_code: { const: "gmail_mutation_unknown" }, recovery_code: { const: "RECONCILE_GMAIL_MUTATION" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#gmail-mutation-unknown" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] }
|
|
525
|
+
]
|
|
526
|
+
},
|
|
527
|
+
safeInteger: {
|
|
528
|
+
type: "integer",
|
|
529
|
+
minimum: -9007199254740991,
|
|
530
|
+
maximum: 9007199254740991
|
|
531
|
+
},
|
|
532
|
+
positiveInteger: {
|
|
533
|
+
allOf: [
|
|
534
|
+
{
|
|
535
|
+
$ref: "#/$defs/safeInteger"
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
minimum: 1
|
|
539
|
+
}
|
|
540
|
+
]
|
|
541
|
+
},
|
|
542
|
+
nonNegativeInteger: {
|
|
543
|
+
allOf: [
|
|
544
|
+
{
|
|
545
|
+
$ref: "#/$defs/safeInteger"
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
minimum: 0
|
|
549
|
+
}
|
|
550
|
+
]
|
|
551
|
+
},
|
|
552
|
+
jsonNumber: {
|
|
553
|
+
oneOf: [
|
|
554
|
+
{
|
|
555
|
+
$ref: "#/$defs/safeInteger"
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
type: "number",
|
|
559
|
+
not: {
|
|
560
|
+
type: "integer"
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
]
|
|
564
|
+
},
|
|
565
|
+
nonNegativeNumber: {
|
|
566
|
+
allOf: [
|
|
567
|
+
{
|
|
568
|
+
$ref: "#/$defs/jsonNumber"
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
minimum: 0
|
|
572
|
+
}
|
|
573
|
+
]
|
|
574
|
+
},
|
|
575
|
+
jsonValue: {
|
|
576
|
+
oneOf: [
|
|
577
|
+
{
|
|
578
|
+
type: "null"
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
type: "boolean"
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
$ref: "#/$defs/jsonNumber"
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
type: "string"
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
type: "array",
|
|
591
|
+
items: {
|
|
592
|
+
$ref: "#/$defs/jsonValue"
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
type: "object",
|
|
597
|
+
additionalProperties: {
|
|
598
|
+
$ref: "#/$defs/jsonValue"
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
]
|
|
602
|
+
},
|
|
603
|
+
jsonObject: {
|
|
604
|
+
type: "object",
|
|
605
|
+
additionalProperties: {
|
|
606
|
+
$ref: "#/$defs/jsonValue"
|
|
607
|
+
}
|
|
608
|
+
},
|
|
609
|
+
tokenUsage: {
|
|
610
|
+
type: "object",
|
|
611
|
+
properties: {
|
|
612
|
+
input: {
|
|
613
|
+
$ref: "#/$defs/nonNegativeInteger"
|
|
614
|
+
},
|
|
615
|
+
output: {
|
|
616
|
+
$ref: "#/$defs/nonNegativeInteger"
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
required: [
|
|
620
|
+
"input",
|
|
621
|
+
"output"
|
|
622
|
+
],
|
|
623
|
+
additionalProperties: false
|
|
624
|
+
},
|
|
625
|
+
base: {
|
|
626
|
+
type: "object",
|
|
627
|
+
properties: {
|
|
628
|
+
id: {
|
|
629
|
+
$ref: "#/$defs/nonEmptyId"
|
|
630
|
+
},
|
|
631
|
+
version: {
|
|
632
|
+
const: "1.0"
|
|
633
|
+
},
|
|
634
|
+
timestamp: {
|
|
635
|
+
$ref: "#/$defs/jsonNumber"
|
|
636
|
+
},
|
|
637
|
+
session_id: {
|
|
638
|
+
$ref: "#/$defs/nonEmptyId"
|
|
639
|
+
},
|
|
640
|
+
turn_id: {
|
|
641
|
+
$ref: "#/$defs/nonEmptyId"
|
|
642
|
+
},
|
|
643
|
+
metadata: {
|
|
644
|
+
$ref: "#/$defs/jsonObject"
|
|
645
|
+
}
|
|
646
|
+
},
|
|
647
|
+
required: [
|
|
648
|
+
"id",
|
|
649
|
+
"version",
|
|
650
|
+
"timestamp",
|
|
651
|
+
"session_id"
|
|
652
|
+
]
|
|
653
|
+
},
|
|
654
|
+
sessionCreated: {
|
|
655
|
+
allOf: [
|
|
656
|
+
{
|
|
657
|
+
$ref: "#/$defs/base"
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
type: "object",
|
|
661
|
+
properties: {
|
|
662
|
+
type: {
|
|
663
|
+
const: "session.created"
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
required: [
|
|
667
|
+
"type"
|
|
668
|
+
]
|
|
669
|
+
}
|
|
670
|
+
],
|
|
671
|
+
unevaluatedProperties: false
|
|
672
|
+
},
|
|
673
|
+
sessionClosed: {
|
|
674
|
+
allOf: [
|
|
675
|
+
{
|
|
676
|
+
$ref: "#/$defs/base"
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
type: "object",
|
|
680
|
+
properties: {
|
|
681
|
+
type: {
|
|
682
|
+
const: "session.closed"
|
|
683
|
+
},
|
|
684
|
+
reason: {
|
|
685
|
+
type: [
|
|
686
|
+
"string",
|
|
687
|
+
"null"
|
|
688
|
+
]
|
|
689
|
+
}
|
|
690
|
+
},
|
|
691
|
+
required: [
|
|
692
|
+
"type"
|
|
693
|
+
]
|
|
694
|
+
}
|
|
695
|
+
],
|
|
696
|
+
unevaluatedProperties: false
|
|
697
|
+
},
|
|
698
|
+
userMessage: {
|
|
699
|
+
allOf: [
|
|
700
|
+
{
|
|
701
|
+
$ref: "#/$defs/base"
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
type: "object",
|
|
705
|
+
properties: {
|
|
706
|
+
type: {
|
|
707
|
+
const: "user.message"
|
|
708
|
+
},
|
|
709
|
+
content: {
|
|
710
|
+
type: "string"
|
|
711
|
+
}
|
|
712
|
+
},
|
|
713
|
+
required: [
|
|
714
|
+
"type",
|
|
715
|
+
"content"
|
|
716
|
+
]
|
|
717
|
+
}
|
|
718
|
+
],
|
|
719
|
+
unevaluatedProperties: false
|
|
720
|
+
},
|
|
721
|
+
userAudioChunk: {
|
|
722
|
+
allOf: [
|
|
723
|
+
{
|
|
724
|
+
$ref: "#/$defs/base"
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
type: "object",
|
|
728
|
+
properties: {
|
|
729
|
+
type: {
|
|
730
|
+
const: "user.audio.chunk"
|
|
731
|
+
},
|
|
732
|
+
chunk_size_bytes: {
|
|
733
|
+
$ref: "#/$defs/safeInteger"
|
|
734
|
+
}
|
|
735
|
+
},
|
|
736
|
+
required: [
|
|
737
|
+
"type",
|
|
738
|
+
"chunk_size_bytes"
|
|
739
|
+
]
|
|
740
|
+
}
|
|
741
|
+
],
|
|
742
|
+
unevaluatedProperties: false
|
|
743
|
+
},
|
|
744
|
+
transcriptPartial: {
|
|
745
|
+
allOf: [
|
|
746
|
+
{
|
|
747
|
+
$ref: "#/$defs/base"
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
type: "object",
|
|
751
|
+
properties: {
|
|
752
|
+
type: {
|
|
753
|
+
const: "transcript.partial"
|
|
754
|
+
},
|
|
755
|
+
text: {
|
|
756
|
+
type: "string"
|
|
757
|
+
}
|
|
758
|
+
},
|
|
759
|
+
required: [
|
|
760
|
+
"type",
|
|
761
|
+
"text"
|
|
762
|
+
]
|
|
763
|
+
}
|
|
764
|
+
],
|
|
765
|
+
unevaluatedProperties: false
|
|
766
|
+
},
|
|
767
|
+
transcriptFinal: {
|
|
768
|
+
allOf: [
|
|
769
|
+
{
|
|
770
|
+
$ref: "#/$defs/base"
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
type: "object",
|
|
774
|
+
properties: {
|
|
775
|
+
type: {
|
|
776
|
+
const: "transcript.final"
|
|
777
|
+
},
|
|
778
|
+
text: {
|
|
779
|
+
type: "string"
|
|
780
|
+
}
|
|
781
|
+
},
|
|
782
|
+
required: [
|
|
783
|
+
"type",
|
|
784
|
+
"text"
|
|
785
|
+
]
|
|
786
|
+
}
|
|
787
|
+
],
|
|
788
|
+
unevaluatedProperties: false
|
|
789
|
+
},
|
|
790
|
+
memoryRetrievalStarted: {
|
|
791
|
+
allOf: [
|
|
792
|
+
{
|
|
793
|
+
$ref: "#/$defs/base"
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
type: "object",
|
|
797
|
+
properties: {
|
|
798
|
+
type: {
|
|
799
|
+
const: "memory.retrieval.started"
|
|
800
|
+
},
|
|
801
|
+
query: {
|
|
802
|
+
type: "string"
|
|
803
|
+
}
|
|
804
|
+
},
|
|
805
|
+
required: [
|
|
806
|
+
"type",
|
|
807
|
+
"query"
|
|
808
|
+
]
|
|
809
|
+
}
|
|
810
|
+
],
|
|
811
|
+
unevaluatedProperties: false
|
|
812
|
+
},
|
|
813
|
+
memoryRetrievalCompleted: {
|
|
814
|
+
allOf: [
|
|
815
|
+
{
|
|
816
|
+
$ref: "#/$defs/base"
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
type: "object",
|
|
820
|
+
properties: {
|
|
821
|
+
type: {
|
|
822
|
+
const: "memory.retrieval.completed"
|
|
823
|
+
},
|
|
824
|
+
query: {
|
|
825
|
+
type: "string"
|
|
826
|
+
},
|
|
827
|
+
documents: {
|
|
828
|
+
type: "array",
|
|
829
|
+
items: {
|
|
830
|
+
$ref: "#/$defs/jsonObject"
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
},
|
|
834
|
+
required: [
|
|
835
|
+
"type",
|
|
836
|
+
"query",
|
|
837
|
+
"documents"
|
|
838
|
+
]
|
|
839
|
+
}
|
|
840
|
+
],
|
|
841
|
+
unevaluatedProperties: false
|
|
842
|
+
},
|
|
843
|
+
agentReasoningStarted: {
|
|
844
|
+
allOf: [
|
|
845
|
+
{
|
|
846
|
+
$ref: "#/$defs/base"
|
|
847
|
+
},
|
|
848
|
+
{
|
|
849
|
+
type: "object",
|
|
850
|
+
properties: {
|
|
851
|
+
type: {
|
|
852
|
+
const: "agent.reasoning.started"
|
|
853
|
+
}
|
|
854
|
+
},
|
|
855
|
+
required: [
|
|
856
|
+
"type"
|
|
857
|
+
]
|
|
858
|
+
}
|
|
859
|
+
],
|
|
860
|
+
unevaluatedProperties: false
|
|
861
|
+
},
|
|
862
|
+
agentMessageDelta: {
|
|
863
|
+
allOf: [
|
|
864
|
+
{
|
|
865
|
+
$ref: "#/$defs/base"
|
|
866
|
+
},
|
|
867
|
+
{
|
|
868
|
+
type: "object",
|
|
869
|
+
properties: {
|
|
870
|
+
type: {
|
|
871
|
+
const: "agent.message.delta"
|
|
872
|
+
},
|
|
873
|
+
delta: {
|
|
874
|
+
type: "string"
|
|
875
|
+
}
|
|
876
|
+
},
|
|
877
|
+
required: [
|
|
878
|
+
"type",
|
|
879
|
+
"delta"
|
|
880
|
+
]
|
|
881
|
+
}
|
|
882
|
+
],
|
|
883
|
+
unevaluatedProperties: false
|
|
884
|
+
},
|
|
885
|
+
agentMessageCompleted: {
|
|
886
|
+
allOf: [
|
|
887
|
+
{
|
|
888
|
+
$ref: "#/$defs/base"
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
type: "object",
|
|
892
|
+
properties: {
|
|
893
|
+
type: {
|
|
894
|
+
const: "agent.message.completed"
|
|
895
|
+
},
|
|
896
|
+
content: {
|
|
897
|
+
type: "string"
|
|
898
|
+
},
|
|
899
|
+
tokens: {
|
|
900
|
+
oneOf: [
|
|
901
|
+
{ $ref: "#/$defs/tokenUsage" },
|
|
902
|
+
{ type: "null" }
|
|
903
|
+
]
|
|
904
|
+
},
|
|
905
|
+
cost_usd: {
|
|
906
|
+
oneOf: [
|
|
907
|
+
{ $ref: "#/$defs/nonNegativeNumber" },
|
|
908
|
+
{ type: "null" }
|
|
909
|
+
]
|
|
910
|
+
}
|
|
911
|
+
},
|
|
912
|
+
required: [
|
|
913
|
+
"type",
|
|
914
|
+
"content"
|
|
915
|
+
]
|
|
916
|
+
}
|
|
917
|
+
],
|
|
918
|
+
unevaluatedProperties: false
|
|
919
|
+
},
|
|
920
|
+
agentTurnExhausted: {
|
|
921
|
+
allOf: [
|
|
922
|
+
{
|
|
923
|
+
$ref: "#/$defs/base"
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
type: "object",
|
|
927
|
+
properties: {
|
|
928
|
+
type: {
|
|
929
|
+
const: "agent.turn.exhausted"
|
|
930
|
+
},
|
|
931
|
+
max_iterations: {
|
|
932
|
+
$ref: "#/$defs/nonNegativeInteger"
|
|
933
|
+
},
|
|
934
|
+
pending_tool_calls: {
|
|
935
|
+
type: "array",
|
|
936
|
+
items: {
|
|
937
|
+
$ref: "#/$defs/jsonObject"
|
|
938
|
+
}
|
|
939
|
+
},
|
|
940
|
+
reason: {
|
|
941
|
+
type: [
|
|
942
|
+
"string",
|
|
943
|
+
"null"
|
|
944
|
+
]
|
|
945
|
+
}
|
|
946
|
+
},
|
|
947
|
+
required: [
|
|
948
|
+
"type",
|
|
949
|
+
"max_iterations",
|
|
950
|
+
"pending_tool_calls"
|
|
951
|
+
]
|
|
952
|
+
}
|
|
953
|
+
],
|
|
954
|
+
unevaluatedProperties: false
|
|
955
|
+
},
|
|
956
|
+
agentTurnFailed: {
|
|
957
|
+
allOf: [
|
|
958
|
+
{
|
|
959
|
+
$ref: "#/$defs/base"
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
type: "object",
|
|
963
|
+
properties: {
|
|
964
|
+
type: {
|
|
965
|
+
const: "agent.turn.failed"
|
|
966
|
+
},
|
|
967
|
+
turn_id: {
|
|
968
|
+
$ref: "#/$defs/nonEmptyId"
|
|
969
|
+
},
|
|
970
|
+
error: {
|
|
971
|
+
type: "string",
|
|
972
|
+
minLength: 1,
|
|
973
|
+
maxLength: 200
|
|
974
|
+
},
|
|
975
|
+
error_code: {
|
|
976
|
+
type: "string"
|
|
977
|
+
},
|
|
978
|
+
phase: {
|
|
979
|
+
enum: [
|
|
980
|
+
"queue",
|
|
981
|
+
"provider_open",
|
|
982
|
+
"provider_stream",
|
|
983
|
+
"approval",
|
|
984
|
+
"tool"
|
|
985
|
+
]
|
|
986
|
+
},
|
|
987
|
+
retryable: {
|
|
988
|
+
type: "boolean"
|
|
989
|
+
},
|
|
990
|
+
outcome: {
|
|
991
|
+
enum: [
|
|
992
|
+
"not_started",
|
|
993
|
+
"failed",
|
|
994
|
+
"unknown"
|
|
995
|
+
]
|
|
996
|
+
}
|
|
997
|
+
},
|
|
998
|
+
required: [
|
|
999
|
+
"type",
|
|
1000
|
+
"turn_id",
|
|
1001
|
+
"error"
|
|
1002
|
+
]
|
|
1003
|
+
}
|
|
1004
|
+
],
|
|
1005
|
+
unevaluatedProperties: false
|
|
1006
|
+
},
|
|
1007
|
+
toolCallRequested: {
|
|
1008
|
+
allOf: [
|
|
1009
|
+
{
|
|
1010
|
+
$ref: "#/$defs/base"
|
|
1011
|
+
},
|
|
1012
|
+
{
|
|
1013
|
+
type: "object",
|
|
1014
|
+
properties: {
|
|
1015
|
+
type: {
|
|
1016
|
+
const: "tool.call.requested"
|
|
1017
|
+
},
|
|
1018
|
+
turn_id: {
|
|
1019
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1020
|
+
},
|
|
1021
|
+
tool_name: {
|
|
1022
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1023
|
+
},
|
|
1024
|
+
tool_args: {
|
|
1025
|
+
$ref: "#/$defs/jsonObject",
|
|
1026
|
+
"x-maxSerializedBytes": 65536
|
|
1027
|
+
},
|
|
1028
|
+
tool_call_id: {
|
|
1029
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1030
|
+
}
|
|
1031
|
+
},
|
|
1032
|
+
required: [
|
|
1033
|
+
"type",
|
|
1034
|
+
"turn_id",
|
|
1035
|
+
"tool_name",
|
|
1036
|
+
"tool_args",
|
|
1037
|
+
"tool_call_id"
|
|
1038
|
+
]
|
|
1039
|
+
}
|
|
1040
|
+
],
|
|
1041
|
+
unevaluatedProperties: false
|
|
1042
|
+
},
|
|
1043
|
+
toolCallStarted: {
|
|
1044
|
+
allOf: [
|
|
1045
|
+
{
|
|
1046
|
+
$ref: "#/$defs/base"
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
type: "object",
|
|
1050
|
+
properties: {
|
|
1051
|
+
type: {
|
|
1052
|
+
const: "tool.call.started"
|
|
1053
|
+
},
|
|
1054
|
+
turn_id: {
|
|
1055
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1056
|
+
},
|
|
1057
|
+
tool_name: {
|
|
1058
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1059
|
+
},
|
|
1060
|
+
tool_call_id: {
|
|
1061
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1062
|
+
}
|
|
1063
|
+
},
|
|
1064
|
+
required: [
|
|
1065
|
+
"type",
|
|
1066
|
+
"turn_id",
|
|
1067
|
+
"tool_name",
|
|
1068
|
+
"tool_call_id"
|
|
1069
|
+
]
|
|
1070
|
+
}
|
|
1071
|
+
],
|
|
1072
|
+
unevaluatedProperties: false
|
|
1073
|
+
},
|
|
1074
|
+
toolCallCompleted: {
|
|
1075
|
+
allOf: [
|
|
1076
|
+
{
|
|
1077
|
+
$ref: "#/$defs/base"
|
|
1078
|
+
},
|
|
1079
|
+
{
|
|
1080
|
+
type: "object",
|
|
1081
|
+
properties: {
|
|
1082
|
+
type: {
|
|
1083
|
+
const: "tool.call.completed"
|
|
1084
|
+
},
|
|
1085
|
+
turn_id: {
|
|
1086
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1087
|
+
},
|
|
1088
|
+
tool_name: {
|
|
1089
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1090
|
+
},
|
|
1091
|
+
tool_call_id: {
|
|
1092
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1093
|
+
},
|
|
1094
|
+
result: {
|
|
1095
|
+
$ref: "#/$defs/jsonValue",
|
|
1096
|
+
"x-maxSerializedBytes": 65536
|
|
1097
|
+
},
|
|
1098
|
+
tokens: {
|
|
1099
|
+
oneOf: [
|
|
1100
|
+
{ $ref: "#/$defs/tokenUsage" },
|
|
1101
|
+
{ type: "null" }
|
|
1102
|
+
]
|
|
1103
|
+
},
|
|
1104
|
+
cost_usd: {
|
|
1105
|
+
oneOf: [
|
|
1106
|
+
{ $ref: "#/$defs/nonNegativeNumber" },
|
|
1107
|
+
{ type: "null" }
|
|
1108
|
+
]
|
|
1109
|
+
}
|
|
1110
|
+
},
|
|
1111
|
+
required: [
|
|
1112
|
+
"type",
|
|
1113
|
+
"turn_id",
|
|
1114
|
+
"tool_name",
|
|
1115
|
+
"tool_call_id",
|
|
1116
|
+
"result"
|
|
1117
|
+
]
|
|
1118
|
+
}
|
|
1119
|
+
],
|
|
1120
|
+
unevaluatedProperties: false
|
|
1121
|
+
},
|
|
1122
|
+
toolCallFailed: {
|
|
1123
|
+
allOf: [
|
|
1124
|
+
{
|
|
1125
|
+
$ref: "#/$defs/base"
|
|
1126
|
+
},
|
|
1127
|
+
{
|
|
1128
|
+
type: "object",
|
|
1129
|
+
properties: {
|
|
1130
|
+
type: {
|
|
1131
|
+
const: "tool.call.failed"
|
|
1132
|
+
},
|
|
1133
|
+
turn_id: {
|
|
1134
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1135
|
+
},
|
|
1136
|
+
tool_name: {
|
|
1137
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1138
|
+
},
|
|
1139
|
+
tool_call_id: {
|
|
1140
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1141
|
+
},
|
|
1142
|
+
error: {
|
|
1143
|
+
type: "string",
|
|
1144
|
+
minLength: 1,
|
|
1145
|
+
maxLength: 200
|
|
1146
|
+
},
|
|
1147
|
+
error_code: {
|
|
1148
|
+
type: "string"
|
|
1149
|
+
},
|
|
1150
|
+
error_path: {
|
|
1151
|
+
type: "string"
|
|
1152
|
+
},
|
|
1153
|
+
retryable: {
|
|
1154
|
+
type: "boolean"
|
|
1155
|
+
},
|
|
1156
|
+
outcome: {
|
|
1157
|
+
enum: [
|
|
1158
|
+
"not_started",
|
|
1159
|
+
"failed",
|
|
1160
|
+
"unknown"
|
|
1161
|
+
]
|
|
1162
|
+
},
|
|
1163
|
+
reason_code: {
|
|
1164
|
+
type: "string"
|
|
1165
|
+
},
|
|
1166
|
+
recovery_code: {
|
|
1167
|
+
type: "string"
|
|
1168
|
+
},
|
|
1169
|
+
doc_url: {
|
|
1170
|
+
type: "string"
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1173
|
+
required: [
|
|
1174
|
+
"type",
|
|
1175
|
+
"turn_id",
|
|
1176
|
+
"tool_name",
|
|
1177
|
+
"tool_call_id",
|
|
1178
|
+
"error"
|
|
1179
|
+
]
|
|
1180
|
+
},
|
|
1181
|
+
{
|
|
1182
|
+
if: {
|
|
1183
|
+
anyOf: [
|
|
1184
|
+
{ required: ["reason_code"] },
|
|
1185
|
+
{ required: ["recovery_code"] },
|
|
1186
|
+
{ required: ["doc_url"] }
|
|
1187
|
+
]
|
|
1188
|
+
},
|
|
1189
|
+
then: {
|
|
1190
|
+
$ref: "#/$defs/integrationRecoveryFields"
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
],
|
|
1194
|
+
unevaluatedProperties: false
|
|
1195
|
+
},
|
|
1196
|
+
toolApprovalRequested: {
|
|
1197
|
+
allOf: [
|
|
1198
|
+
{
|
|
1199
|
+
$ref: "#/$defs/base"
|
|
1200
|
+
},
|
|
1201
|
+
{
|
|
1202
|
+
type: "object",
|
|
1203
|
+
properties: {
|
|
1204
|
+
type: {
|
|
1205
|
+
const: "tool.approval.requested"
|
|
1206
|
+
},
|
|
1207
|
+
turn_id: {
|
|
1208
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1209
|
+
},
|
|
1210
|
+
tool_name: {
|
|
1211
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1212
|
+
},
|
|
1213
|
+
tool_call_id: {
|
|
1214
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1215
|
+
},
|
|
1216
|
+
tool_args: {
|
|
1217
|
+
$ref: "#/$defs/jsonObject",
|
|
1218
|
+
"x-maxSerializedBytes": 65536
|
|
1219
|
+
},
|
|
1220
|
+
risk: {
|
|
1221
|
+
enum: [
|
|
1222
|
+
"read",
|
|
1223
|
+
"write",
|
|
1224
|
+
"external_effect",
|
|
1225
|
+
"destructive",
|
|
1226
|
+
"admin"
|
|
1227
|
+
]
|
|
1228
|
+
}
|
|
1229
|
+
},
|
|
1230
|
+
required: [
|
|
1231
|
+
"type",
|
|
1232
|
+
"turn_id",
|
|
1233
|
+
"tool_name",
|
|
1234
|
+
"tool_call_id",
|
|
1235
|
+
"tool_args",
|
|
1236
|
+
"risk"
|
|
1237
|
+
]
|
|
1238
|
+
}
|
|
1239
|
+
],
|
|
1240
|
+
unevaluatedProperties: false
|
|
1241
|
+
},
|
|
1242
|
+
toolApprovalApproved: {
|
|
1243
|
+
allOf: [
|
|
1244
|
+
{
|
|
1245
|
+
$ref: "#/$defs/base"
|
|
1246
|
+
},
|
|
1247
|
+
{
|
|
1248
|
+
type: "object",
|
|
1249
|
+
properties: {
|
|
1250
|
+
type: {
|
|
1251
|
+
const: "tool.approval.approved"
|
|
1252
|
+
},
|
|
1253
|
+
turn_id: {
|
|
1254
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1255
|
+
},
|
|
1256
|
+
tool_name: {
|
|
1257
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1258
|
+
},
|
|
1259
|
+
tool_call_id: {
|
|
1260
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1261
|
+
}
|
|
1262
|
+
},
|
|
1263
|
+
required: [
|
|
1264
|
+
"type",
|
|
1265
|
+
"turn_id",
|
|
1266
|
+
"tool_name",
|
|
1267
|
+
"tool_call_id"
|
|
1268
|
+
]
|
|
1269
|
+
}
|
|
1270
|
+
],
|
|
1271
|
+
unevaluatedProperties: false
|
|
1272
|
+
},
|
|
1273
|
+
toolApprovalRejected: {
|
|
1274
|
+
allOf: [
|
|
1275
|
+
{
|
|
1276
|
+
$ref: "#/$defs/base"
|
|
1277
|
+
},
|
|
1278
|
+
{
|
|
1279
|
+
type: "object",
|
|
1280
|
+
properties: {
|
|
1281
|
+
type: {
|
|
1282
|
+
const: "tool.approval.rejected"
|
|
1283
|
+
},
|
|
1284
|
+
turn_id: {
|
|
1285
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1286
|
+
},
|
|
1287
|
+
tool_name: {
|
|
1288
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1289
|
+
},
|
|
1290
|
+
tool_call_id: {
|
|
1291
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1292
|
+
},
|
|
1293
|
+
error_code: {
|
|
1294
|
+
enum: [
|
|
1295
|
+
"APPROVAL_REJECTED",
|
|
1296
|
+
"APPROVAL_TIMEOUT",
|
|
1297
|
+
"TURN_TIMEOUT",
|
|
1298
|
+
"TOOL_CANCELLED",
|
|
1299
|
+
"APPROVAL_UNAVAILABLE"
|
|
1300
|
+
]
|
|
1301
|
+
},
|
|
1302
|
+
reason: {
|
|
1303
|
+
type: "string",
|
|
1304
|
+
minLength: 1,
|
|
1305
|
+
maxLength: 200,
|
|
1306
|
+
pattern: "\\S"
|
|
1307
|
+
}
|
|
1308
|
+
},
|
|
1309
|
+
required: [
|
|
1310
|
+
"type",
|
|
1311
|
+
"turn_id",
|
|
1312
|
+
"tool_name",
|
|
1313
|
+
"tool_call_id",
|
|
1314
|
+
"error_code",
|
|
1315
|
+
"reason"
|
|
1316
|
+
]
|
|
1317
|
+
}
|
|
1318
|
+
],
|
|
1319
|
+
unevaluatedProperties: false
|
|
1320
|
+
},
|
|
1321
|
+
workflowStarted: {
|
|
1322
|
+
allOf: [
|
|
1323
|
+
{
|
|
1324
|
+
$ref: "#/$defs/base"
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
type: "object",
|
|
1328
|
+
properties: {
|
|
1329
|
+
type: {
|
|
1330
|
+
const: "workflow.started"
|
|
1331
|
+
},
|
|
1332
|
+
workflow_name: {
|
|
1333
|
+
type: "string"
|
|
1334
|
+
}
|
|
1335
|
+
},
|
|
1336
|
+
required: [
|
|
1337
|
+
"type",
|
|
1338
|
+
"workflow_name"
|
|
1339
|
+
]
|
|
1340
|
+
}
|
|
1341
|
+
],
|
|
1342
|
+
unevaluatedProperties: false
|
|
1343
|
+
},
|
|
1344
|
+
workflowCompleted: {
|
|
1345
|
+
allOf: [
|
|
1346
|
+
{
|
|
1347
|
+
$ref: "#/$defs/base"
|
|
1348
|
+
},
|
|
1349
|
+
{
|
|
1350
|
+
type: "object",
|
|
1351
|
+
properties: {
|
|
1352
|
+
type: {
|
|
1353
|
+
const: "workflow.completed"
|
|
1354
|
+
},
|
|
1355
|
+
workflow_name: {
|
|
1356
|
+
type: "string"
|
|
1357
|
+
},
|
|
1358
|
+
result: {
|
|
1359
|
+
$ref: "#/$defs/jsonValue"
|
|
1360
|
+
}
|
|
1361
|
+
},
|
|
1362
|
+
required: [
|
|
1363
|
+
"type",
|
|
1364
|
+
"workflow_name",
|
|
1365
|
+
"result"
|
|
1366
|
+
]
|
|
1367
|
+
}
|
|
1368
|
+
],
|
|
1369
|
+
unevaluatedProperties: false
|
|
1370
|
+
},
|
|
1371
|
+
workflowFailed: {
|
|
1372
|
+
allOf: [
|
|
1373
|
+
{
|
|
1374
|
+
$ref: "#/$defs/base"
|
|
1375
|
+
},
|
|
1376
|
+
{
|
|
1377
|
+
type: "object",
|
|
1378
|
+
properties: {
|
|
1379
|
+
type: {
|
|
1380
|
+
const: "workflow.failed"
|
|
1381
|
+
},
|
|
1382
|
+
workflow_name: {
|
|
1383
|
+
type: "string"
|
|
1384
|
+
},
|
|
1385
|
+
error: {
|
|
1386
|
+
type: "string"
|
|
1387
|
+
}
|
|
1388
|
+
},
|
|
1389
|
+
required: [
|
|
1390
|
+
"type",
|
|
1391
|
+
"workflow_name",
|
|
1392
|
+
"error"
|
|
1393
|
+
]
|
|
1394
|
+
}
|
|
1395
|
+
],
|
|
1396
|
+
unevaluatedProperties: false
|
|
1397
|
+
},
|
|
1398
|
+
cancellationRequested: {
|
|
1399
|
+
allOf: [
|
|
1400
|
+
{
|
|
1401
|
+
$ref: "#/$defs/base"
|
|
1402
|
+
},
|
|
1403
|
+
{
|
|
1404
|
+
type: "object",
|
|
1405
|
+
properties: {
|
|
1406
|
+
type: {
|
|
1407
|
+
const: "cancellation.requested"
|
|
1408
|
+
},
|
|
1409
|
+
reason: {
|
|
1410
|
+
type: "string"
|
|
1411
|
+
}
|
|
1412
|
+
},
|
|
1413
|
+
required: [
|
|
1414
|
+
"type",
|
|
1415
|
+
"reason"
|
|
1416
|
+
]
|
|
1417
|
+
}
|
|
1418
|
+
],
|
|
1419
|
+
unevaluatedProperties: false
|
|
1420
|
+
},
|
|
1421
|
+
cancellationCompleted: {
|
|
1422
|
+
allOf: [
|
|
1423
|
+
{
|
|
1424
|
+
$ref: "#/$defs/base"
|
|
1425
|
+
},
|
|
1426
|
+
{
|
|
1427
|
+
type: "object",
|
|
1428
|
+
properties: {
|
|
1429
|
+
type: {
|
|
1430
|
+
const: "cancellation.completed"
|
|
1431
|
+
}
|
|
1432
|
+
},
|
|
1433
|
+
required: [
|
|
1434
|
+
"type"
|
|
1435
|
+
]
|
|
1436
|
+
}
|
|
1437
|
+
],
|
|
1438
|
+
unevaluatedProperties: false
|
|
1439
|
+
}
|
|
1440
|
+
},
|
|
1441
|
+
oneOf: [
|
|
1442
|
+
{
|
|
1443
|
+
$ref: "#/$defs/sessionCreated"
|
|
1444
|
+
},
|
|
1445
|
+
{
|
|
1446
|
+
$ref: "#/$defs/sessionClosed"
|
|
1447
|
+
},
|
|
1448
|
+
{
|
|
1449
|
+
$ref: "#/$defs/userMessage"
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
$ref: "#/$defs/userAudioChunk"
|
|
1453
|
+
},
|
|
1454
|
+
{
|
|
1455
|
+
$ref: "#/$defs/transcriptPartial"
|
|
1456
|
+
},
|
|
1457
|
+
{
|
|
1458
|
+
$ref: "#/$defs/transcriptFinal"
|
|
1459
|
+
},
|
|
1460
|
+
{
|
|
1461
|
+
$ref: "#/$defs/memoryRetrievalStarted"
|
|
1462
|
+
},
|
|
1463
|
+
{
|
|
1464
|
+
$ref: "#/$defs/memoryRetrievalCompleted"
|
|
1465
|
+
},
|
|
1466
|
+
{
|
|
1467
|
+
$ref: "#/$defs/agentReasoningStarted"
|
|
1468
|
+
},
|
|
1469
|
+
{
|
|
1470
|
+
$ref: "#/$defs/agentMessageDelta"
|
|
1471
|
+
},
|
|
1472
|
+
{
|
|
1473
|
+
$ref: "#/$defs/agentMessageCompleted"
|
|
1474
|
+
},
|
|
1475
|
+
{
|
|
1476
|
+
$ref: "#/$defs/agentTurnExhausted"
|
|
1477
|
+
},
|
|
1478
|
+
{
|
|
1479
|
+
$ref: "#/$defs/agentTurnFailed"
|
|
1480
|
+
},
|
|
1481
|
+
{
|
|
1482
|
+
$ref: "#/$defs/toolCallRequested"
|
|
1483
|
+
},
|
|
1484
|
+
{
|
|
1485
|
+
$ref: "#/$defs/toolCallStarted"
|
|
1486
|
+
},
|
|
1487
|
+
{
|
|
1488
|
+
$ref: "#/$defs/toolCallCompleted"
|
|
1489
|
+
},
|
|
1490
|
+
{
|
|
1491
|
+
$ref: "#/$defs/toolCallFailed"
|
|
1492
|
+
},
|
|
1493
|
+
{
|
|
1494
|
+
$ref: "#/$defs/toolApprovalRequested"
|
|
1495
|
+
},
|
|
1496
|
+
{
|
|
1497
|
+
$ref: "#/$defs/toolApprovalApproved"
|
|
1498
|
+
},
|
|
1499
|
+
{
|
|
1500
|
+
$ref: "#/$defs/toolApprovalRejected"
|
|
1501
|
+
},
|
|
1502
|
+
{
|
|
1503
|
+
$ref: "#/$defs/workflowStarted"
|
|
1504
|
+
},
|
|
1505
|
+
{
|
|
1506
|
+
$ref: "#/$defs/workflowCompleted"
|
|
1507
|
+
},
|
|
1508
|
+
{
|
|
1509
|
+
$ref: "#/$defs/workflowFailed"
|
|
1510
|
+
},
|
|
1511
|
+
{
|
|
1512
|
+
$ref: "#/$defs/cancellationRequested"
|
|
1513
|
+
},
|
|
1514
|
+
{
|
|
1515
|
+
$ref: "#/$defs/cancellationCompleted"
|
|
1516
|
+
}
|
|
1517
|
+
]
|
|
1518
|
+
};
|
|
1519
|
+
|
|
1520
|
+
// contracts/events/stored-kaji-event-v1.schema.json
|
|
1521
|
+
var stored_kaji_event_v1_schema_default = {
|
|
1522
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1523
|
+
$id: "https://kaji.dev/contracts/events/stored-kaji-event-v1.schema.json",
|
|
1524
|
+
title: "Stored Kaji event",
|
|
1525
|
+
"x-maxSerializedBytes": 1048576,
|
|
1526
|
+
$defs: {
|
|
1527
|
+
nonEmptyId: {
|
|
1528
|
+
type: "string",
|
|
1529
|
+
minLength: 1
|
|
1530
|
+
},
|
|
1531
|
+
integrationRecoveryFields: {
|
|
1532
|
+
oneOf: [
|
|
1533
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_REQUIRED" }, reason_code: { const: "github_token_missing" }, recovery_code: { const: "CONFIGURE_GITHUB_TOKEN" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#github-token" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1534
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_REQUIRED" }, reason_code: { const: "gmail_grant_missing" }, recovery_code: { const: "CONNECT_GMAIL" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#gmail-grant" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1535
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_ERROR" }, reason_code: { const: "keychain_missing" }, recovery_code: { const: "RESTORE_KEYCHAIN" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#keychain-missing" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1536
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_ERROR" }, reason_code: { const: "keychain_locked" }, recovery_code: { const: "UNLOCK_KEYCHAIN" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#keychain-locked" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1537
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_ERROR" }, reason_code: { const: "keychain_corrupt" }, recovery_code: { const: "RESET_GMAIL_GRANT" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#keychain-corrupt" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1538
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_ERROR" }, reason_code: { const: "keychain_unsupported" }, recovery_code: { const: "USE_SUPPORTED_KEYCHAIN" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#keychain-unsupported" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1539
|
+
{ properties: { error_code: { const: "INTEGRATION_AUTH_REQUIRED" }, reason_code: { const: "gmail_scope_drift" }, recovery_code: { const: "RECONNECT_GMAIL" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#gmail-scope-drift" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1540
|
+
{ properties: { error_code: { const: "INTEGRATION_POLICY_REJECTED" }, reason_code: { const: "policy_rejected" }, recovery_code: { const: "REVIEW_INTEGRATION_POLICY" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#policy-rejected" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1541
|
+
{ properties: { error_code: { const: "INTEGRATION_API_ERROR" }, reason_code: { const: "api_rejected" }, recovery_code: { const: "REVIEW_PROVIDER_REJECTION" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#api-rejected" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1542
|
+
{ properties: { error_code: { const: "INTEGRATION_API_ERROR" }, reason_code: { const: "transient_read_failed" }, recovery_code: { const: "RETRY_INTEGRATION_READ" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#transient-read" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1543
|
+
{ properties: { error_code: { const: "INTEGRATION_RATE_LIMITED" }, reason_code: { const: "rate_limited" }, recovery_code: { const: "RETRY_AFTER_RATE_LIMIT" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#rate-limited" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1544
|
+
{ properties: { error_code: { const: "INTEGRATION_REDIRECT_REJECTED" }, reason_code: { const: "redirect_rejected" }, recovery_code: { const: "REJECT_PROVIDER_REDIRECT" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#redirect-rejected" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1545
|
+
{ properties: { error_code: { const: "INTEGRATION_RESPONSE_LIMIT" }, reason_code: { const: "response_limit_exceeded" }, recovery_code: { const: "REDUCE_INTEGRATION_RESPONSE" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#response-limit" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1546
|
+
{ properties: { error_code: { const: "TOOL_EXECUTION_FAILED" }, reason_code: { const: "github_mutation_unknown" }, recovery_code: { const: "RECONCILE_GITHUB_MUTATION" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#github-mutation-unknown" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] },
|
|
1547
|
+
{ properties: { error_code: { const: "TOOL_EXECUTION_FAILED" }, reason_code: { const: "gmail_mutation_unknown" }, recovery_code: { const: "RECONCILE_GMAIL_MUTATION" }, doc_url: { const: "https://kaji.dev/docs/integrations/recovery-v1#gmail-mutation-unknown" } }, required: ["error_code", "reason_code", "recovery_code", "doc_url"] }
|
|
1548
|
+
]
|
|
1549
|
+
},
|
|
1550
|
+
safeInteger: {
|
|
1551
|
+
type: "integer",
|
|
1552
|
+
minimum: -9007199254740991,
|
|
1553
|
+
maximum: 9007199254740991
|
|
1554
|
+
},
|
|
1555
|
+
positiveInteger: {
|
|
1556
|
+
allOf: [
|
|
1557
|
+
{
|
|
1558
|
+
$ref: "#/$defs/safeInteger"
|
|
1559
|
+
},
|
|
1560
|
+
{
|
|
1561
|
+
minimum: 1
|
|
1562
|
+
}
|
|
1563
|
+
]
|
|
1564
|
+
},
|
|
1565
|
+
nonNegativeInteger: {
|
|
1566
|
+
allOf: [
|
|
1567
|
+
{
|
|
1568
|
+
$ref: "#/$defs/safeInteger"
|
|
1569
|
+
},
|
|
1570
|
+
{
|
|
1571
|
+
minimum: 0
|
|
1572
|
+
}
|
|
1573
|
+
]
|
|
1574
|
+
},
|
|
1575
|
+
jsonNumber: {
|
|
1576
|
+
oneOf: [
|
|
1577
|
+
{
|
|
1578
|
+
$ref: "#/$defs/safeInteger"
|
|
1579
|
+
},
|
|
1580
|
+
{
|
|
1581
|
+
type: "number",
|
|
1582
|
+
not: {
|
|
1583
|
+
type: "integer"
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
]
|
|
1587
|
+
},
|
|
1588
|
+
nonNegativeNumber: {
|
|
1589
|
+
allOf: [
|
|
1590
|
+
{
|
|
1591
|
+
$ref: "#/$defs/jsonNumber"
|
|
1592
|
+
},
|
|
1593
|
+
{
|
|
1594
|
+
minimum: 0
|
|
1595
|
+
}
|
|
1596
|
+
]
|
|
1597
|
+
},
|
|
1598
|
+
jsonValue: {
|
|
1599
|
+
oneOf: [
|
|
1600
|
+
{
|
|
1601
|
+
type: "null"
|
|
1602
|
+
},
|
|
1603
|
+
{
|
|
1604
|
+
type: "boolean"
|
|
1605
|
+
},
|
|
1606
|
+
{
|
|
1607
|
+
$ref: "#/$defs/jsonNumber"
|
|
1608
|
+
},
|
|
1609
|
+
{
|
|
1610
|
+
type: "string"
|
|
1611
|
+
},
|
|
1612
|
+
{
|
|
1613
|
+
type: "array",
|
|
1614
|
+
items: {
|
|
1615
|
+
$ref: "#/$defs/jsonValue"
|
|
1616
|
+
}
|
|
1617
|
+
},
|
|
1618
|
+
{
|
|
1619
|
+
type: "object",
|
|
1620
|
+
additionalProperties: {
|
|
1621
|
+
$ref: "#/$defs/jsonValue"
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
]
|
|
1625
|
+
},
|
|
1626
|
+
jsonObject: {
|
|
1627
|
+
type: "object",
|
|
1628
|
+
additionalProperties: {
|
|
1629
|
+
$ref: "#/$defs/jsonValue"
|
|
1630
|
+
}
|
|
1631
|
+
},
|
|
1632
|
+
tokenUsage: {
|
|
1633
|
+
type: "object",
|
|
1634
|
+
properties: {
|
|
1635
|
+
input: {
|
|
1636
|
+
$ref: "#/$defs/nonNegativeInteger"
|
|
1637
|
+
},
|
|
1638
|
+
output: {
|
|
1639
|
+
$ref: "#/$defs/nonNegativeInteger"
|
|
1640
|
+
}
|
|
1641
|
+
},
|
|
1642
|
+
required: [
|
|
1643
|
+
"input",
|
|
1644
|
+
"output"
|
|
1645
|
+
],
|
|
1646
|
+
additionalProperties: false
|
|
1647
|
+
},
|
|
1648
|
+
base: {
|
|
1649
|
+
type: "object",
|
|
1650
|
+
properties: {
|
|
1651
|
+
id: {
|
|
1652
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1653
|
+
},
|
|
1654
|
+
version: {
|
|
1655
|
+
const: "1.0"
|
|
1656
|
+
},
|
|
1657
|
+
timestamp: {
|
|
1658
|
+
$ref: "#/$defs/jsonNumber"
|
|
1659
|
+
},
|
|
1660
|
+
session_id: {
|
|
1661
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1662
|
+
},
|
|
1663
|
+
turn_id: {
|
|
1664
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1665
|
+
},
|
|
1666
|
+
metadata: {
|
|
1667
|
+
$ref: "#/$defs/jsonObject"
|
|
1668
|
+
},
|
|
1669
|
+
sequence: {
|
|
1670
|
+
$ref: "#/$defs/positiveInteger"
|
|
1671
|
+
}
|
|
1672
|
+
},
|
|
1673
|
+
required: [
|
|
1674
|
+
"id",
|
|
1675
|
+
"version",
|
|
1676
|
+
"timestamp",
|
|
1677
|
+
"session_id",
|
|
1678
|
+
"sequence"
|
|
1679
|
+
]
|
|
1680
|
+
},
|
|
1681
|
+
sessionCreated: {
|
|
1682
|
+
allOf: [
|
|
1683
|
+
{
|
|
1684
|
+
$ref: "#/$defs/base"
|
|
1685
|
+
},
|
|
1686
|
+
{
|
|
1687
|
+
type: "object",
|
|
1688
|
+
properties: {
|
|
1689
|
+
type: {
|
|
1690
|
+
const: "session.created"
|
|
1691
|
+
}
|
|
1692
|
+
},
|
|
1693
|
+
required: [
|
|
1694
|
+
"type"
|
|
1695
|
+
]
|
|
1696
|
+
}
|
|
1697
|
+
],
|
|
1698
|
+
unevaluatedProperties: false
|
|
1699
|
+
},
|
|
1700
|
+
sessionClosed: {
|
|
1701
|
+
allOf: [
|
|
1702
|
+
{
|
|
1703
|
+
$ref: "#/$defs/base"
|
|
1704
|
+
},
|
|
1705
|
+
{
|
|
1706
|
+
type: "object",
|
|
1707
|
+
properties: {
|
|
1708
|
+
type: {
|
|
1709
|
+
const: "session.closed"
|
|
1710
|
+
},
|
|
1711
|
+
reason: {
|
|
1712
|
+
type: [
|
|
1713
|
+
"string",
|
|
1714
|
+
"null"
|
|
1715
|
+
]
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1718
|
+
required: [
|
|
1719
|
+
"type"
|
|
1720
|
+
]
|
|
1721
|
+
}
|
|
1722
|
+
],
|
|
1723
|
+
unevaluatedProperties: false
|
|
1724
|
+
},
|
|
1725
|
+
userMessage: {
|
|
1726
|
+
allOf: [
|
|
1727
|
+
{
|
|
1728
|
+
$ref: "#/$defs/base"
|
|
1729
|
+
},
|
|
1730
|
+
{
|
|
1731
|
+
type: "object",
|
|
1732
|
+
properties: {
|
|
1733
|
+
type: {
|
|
1734
|
+
const: "user.message"
|
|
1735
|
+
},
|
|
1736
|
+
content: {
|
|
1737
|
+
type: "string"
|
|
1738
|
+
}
|
|
1739
|
+
},
|
|
1740
|
+
required: [
|
|
1741
|
+
"type",
|
|
1742
|
+
"content"
|
|
1743
|
+
]
|
|
1744
|
+
}
|
|
1745
|
+
],
|
|
1746
|
+
unevaluatedProperties: false
|
|
1747
|
+
},
|
|
1748
|
+
userAudioChunk: {
|
|
1749
|
+
allOf: [
|
|
1750
|
+
{
|
|
1751
|
+
$ref: "#/$defs/base"
|
|
1752
|
+
},
|
|
1753
|
+
{
|
|
1754
|
+
type: "object",
|
|
1755
|
+
properties: {
|
|
1756
|
+
type: {
|
|
1757
|
+
const: "user.audio.chunk"
|
|
1758
|
+
},
|
|
1759
|
+
chunk_size_bytes: {
|
|
1760
|
+
$ref: "#/$defs/safeInteger"
|
|
1761
|
+
}
|
|
1762
|
+
},
|
|
1763
|
+
required: [
|
|
1764
|
+
"type",
|
|
1765
|
+
"chunk_size_bytes"
|
|
1766
|
+
]
|
|
1767
|
+
}
|
|
1768
|
+
],
|
|
1769
|
+
unevaluatedProperties: false
|
|
1770
|
+
},
|
|
1771
|
+
transcriptPartial: {
|
|
1772
|
+
allOf: [
|
|
1773
|
+
{
|
|
1774
|
+
$ref: "#/$defs/base"
|
|
1775
|
+
},
|
|
1776
|
+
{
|
|
1777
|
+
type: "object",
|
|
1778
|
+
properties: {
|
|
1779
|
+
type: {
|
|
1780
|
+
const: "transcript.partial"
|
|
1781
|
+
},
|
|
1782
|
+
text: {
|
|
1783
|
+
type: "string"
|
|
1784
|
+
}
|
|
1785
|
+
},
|
|
1786
|
+
required: [
|
|
1787
|
+
"type",
|
|
1788
|
+
"text"
|
|
1789
|
+
]
|
|
1790
|
+
}
|
|
1791
|
+
],
|
|
1792
|
+
unevaluatedProperties: false
|
|
1793
|
+
},
|
|
1794
|
+
transcriptFinal: {
|
|
1795
|
+
allOf: [
|
|
1796
|
+
{
|
|
1797
|
+
$ref: "#/$defs/base"
|
|
1798
|
+
},
|
|
1799
|
+
{
|
|
1800
|
+
type: "object",
|
|
1801
|
+
properties: {
|
|
1802
|
+
type: {
|
|
1803
|
+
const: "transcript.final"
|
|
1804
|
+
},
|
|
1805
|
+
text: {
|
|
1806
|
+
type: "string"
|
|
1807
|
+
}
|
|
1808
|
+
},
|
|
1809
|
+
required: [
|
|
1810
|
+
"type",
|
|
1811
|
+
"text"
|
|
1812
|
+
]
|
|
1813
|
+
}
|
|
1814
|
+
],
|
|
1815
|
+
unevaluatedProperties: false
|
|
1816
|
+
},
|
|
1817
|
+
memoryRetrievalStarted: {
|
|
1818
|
+
allOf: [
|
|
1819
|
+
{
|
|
1820
|
+
$ref: "#/$defs/base"
|
|
1821
|
+
},
|
|
1822
|
+
{
|
|
1823
|
+
type: "object",
|
|
1824
|
+
properties: {
|
|
1825
|
+
type: {
|
|
1826
|
+
const: "memory.retrieval.started"
|
|
1827
|
+
},
|
|
1828
|
+
query: {
|
|
1829
|
+
type: "string"
|
|
1830
|
+
}
|
|
1831
|
+
},
|
|
1832
|
+
required: [
|
|
1833
|
+
"type",
|
|
1834
|
+
"query"
|
|
1835
|
+
]
|
|
1836
|
+
}
|
|
1837
|
+
],
|
|
1838
|
+
unevaluatedProperties: false
|
|
1839
|
+
},
|
|
1840
|
+
memoryRetrievalCompleted: {
|
|
1841
|
+
allOf: [
|
|
1842
|
+
{
|
|
1843
|
+
$ref: "#/$defs/base"
|
|
1844
|
+
},
|
|
1845
|
+
{
|
|
1846
|
+
type: "object",
|
|
1847
|
+
properties: {
|
|
1848
|
+
type: {
|
|
1849
|
+
const: "memory.retrieval.completed"
|
|
1850
|
+
},
|
|
1851
|
+
query: {
|
|
1852
|
+
type: "string"
|
|
1853
|
+
},
|
|
1854
|
+
documents: {
|
|
1855
|
+
type: "array",
|
|
1856
|
+
items: {
|
|
1857
|
+
$ref: "#/$defs/jsonObject"
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
},
|
|
1861
|
+
required: [
|
|
1862
|
+
"type",
|
|
1863
|
+
"query",
|
|
1864
|
+
"documents"
|
|
1865
|
+
]
|
|
1866
|
+
}
|
|
1867
|
+
],
|
|
1868
|
+
unevaluatedProperties: false
|
|
1869
|
+
},
|
|
1870
|
+
agentReasoningStarted: {
|
|
1871
|
+
allOf: [
|
|
1872
|
+
{
|
|
1873
|
+
$ref: "#/$defs/base"
|
|
1874
|
+
},
|
|
1875
|
+
{
|
|
1876
|
+
type: "object",
|
|
1877
|
+
properties: {
|
|
1878
|
+
type: {
|
|
1879
|
+
const: "agent.reasoning.started"
|
|
1880
|
+
}
|
|
1881
|
+
},
|
|
1882
|
+
required: [
|
|
1883
|
+
"type"
|
|
1884
|
+
]
|
|
1885
|
+
}
|
|
1886
|
+
],
|
|
1887
|
+
unevaluatedProperties: false
|
|
1888
|
+
},
|
|
1889
|
+
agentMessageDelta: {
|
|
1890
|
+
allOf: [
|
|
1891
|
+
{
|
|
1892
|
+
$ref: "#/$defs/base"
|
|
1893
|
+
},
|
|
1894
|
+
{
|
|
1895
|
+
type: "object",
|
|
1896
|
+
properties: {
|
|
1897
|
+
type: {
|
|
1898
|
+
const: "agent.message.delta"
|
|
1899
|
+
},
|
|
1900
|
+
delta: {
|
|
1901
|
+
type: "string"
|
|
1902
|
+
}
|
|
1903
|
+
},
|
|
1904
|
+
required: [
|
|
1905
|
+
"type",
|
|
1906
|
+
"delta"
|
|
1907
|
+
]
|
|
1908
|
+
}
|
|
1909
|
+
],
|
|
1910
|
+
unevaluatedProperties: false
|
|
1911
|
+
},
|
|
1912
|
+
agentMessageCompleted: {
|
|
1913
|
+
allOf: [
|
|
1914
|
+
{
|
|
1915
|
+
$ref: "#/$defs/base"
|
|
1916
|
+
},
|
|
1917
|
+
{
|
|
1918
|
+
type: "object",
|
|
1919
|
+
properties: {
|
|
1920
|
+
type: {
|
|
1921
|
+
const: "agent.message.completed"
|
|
1922
|
+
},
|
|
1923
|
+
content: {
|
|
1924
|
+
type: "string"
|
|
1925
|
+
},
|
|
1926
|
+
tokens: {
|
|
1927
|
+
oneOf: [
|
|
1928
|
+
{ $ref: "#/$defs/tokenUsage" },
|
|
1929
|
+
{ type: "null" }
|
|
1930
|
+
]
|
|
1931
|
+
},
|
|
1932
|
+
cost_usd: {
|
|
1933
|
+
oneOf: [
|
|
1934
|
+
{ $ref: "#/$defs/nonNegativeNumber" },
|
|
1935
|
+
{ type: "null" }
|
|
1936
|
+
]
|
|
1937
|
+
}
|
|
1938
|
+
},
|
|
1939
|
+
required: [
|
|
1940
|
+
"type",
|
|
1941
|
+
"content"
|
|
1942
|
+
]
|
|
1943
|
+
}
|
|
1944
|
+
],
|
|
1945
|
+
unevaluatedProperties: false
|
|
1946
|
+
},
|
|
1947
|
+
agentTurnExhausted: {
|
|
1948
|
+
allOf: [
|
|
1949
|
+
{
|
|
1950
|
+
$ref: "#/$defs/base"
|
|
1951
|
+
},
|
|
1952
|
+
{
|
|
1953
|
+
type: "object",
|
|
1954
|
+
properties: {
|
|
1955
|
+
type: {
|
|
1956
|
+
const: "agent.turn.exhausted"
|
|
1957
|
+
},
|
|
1958
|
+
max_iterations: {
|
|
1959
|
+
$ref: "#/$defs/nonNegativeInteger"
|
|
1960
|
+
},
|
|
1961
|
+
pending_tool_calls: {
|
|
1962
|
+
type: "array",
|
|
1963
|
+
items: {
|
|
1964
|
+
$ref: "#/$defs/jsonObject"
|
|
1965
|
+
}
|
|
1966
|
+
},
|
|
1967
|
+
reason: {
|
|
1968
|
+
type: [
|
|
1969
|
+
"string",
|
|
1970
|
+
"null"
|
|
1971
|
+
]
|
|
1972
|
+
}
|
|
1973
|
+
},
|
|
1974
|
+
required: [
|
|
1975
|
+
"type",
|
|
1976
|
+
"max_iterations",
|
|
1977
|
+
"pending_tool_calls"
|
|
1978
|
+
]
|
|
1979
|
+
}
|
|
1980
|
+
],
|
|
1981
|
+
unevaluatedProperties: false
|
|
1982
|
+
},
|
|
1983
|
+
agentTurnFailed: {
|
|
1984
|
+
allOf: [
|
|
1985
|
+
{
|
|
1986
|
+
$ref: "#/$defs/base"
|
|
1987
|
+
},
|
|
1988
|
+
{
|
|
1989
|
+
type: "object",
|
|
1990
|
+
properties: {
|
|
1991
|
+
type: {
|
|
1992
|
+
const: "agent.turn.failed"
|
|
1993
|
+
},
|
|
1994
|
+
turn_id: {
|
|
1995
|
+
$ref: "#/$defs/nonEmptyId"
|
|
1996
|
+
},
|
|
1997
|
+
error: {
|
|
1998
|
+
type: "string",
|
|
1999
|
+
minLength: 1,
|
|
2000
|
+
maxLength: 200
|
|
2001
|
+
},
|
|
2002
|
+
error_code: {
|
|
2003
|
+
type: "string"
|
|
2004
|
+
},
|
|
2005
|
+
phase: {
|
|
2006
|
+
enum: [
|
|
2007
|
+
"queue",
|
|
2008
|
+
"provider_open",
|
|
2009
|
+
"provider_stream",
|
|
2010
|
+
"approval",
|
|
2011
|
+
"tool"
|
|
2012
|
+
]
|
|
2013
|
+
},
|
|
2014
|
+
retryable: {
|
|
2015
|
+
type: "boolean"
|
|
2016
|
+
},
|
|
2017
|
+
outcome: {
|
|
2018
|
+
enum: [
|
|
2019
|
+
"not_started",
|
|
2020
|
+
"failed",
|
|
2021
|
+
"unknown"
|
|
2022
|
+
]
|
|
2023
|
+
}
|
|
2024
|
+
},
|
|
2025
|
+
required: [
|
|
2026
|
+
"type",
|
|
2027
|
+
"turn_id",
|
|
2028
|
+
"error"
|
|
2029
|
+
]
|
|
2030
|
+
}
|
|
2031
|
+
],
|
|
2032
|
+
unevaluatedProperties: false
|
|
2033
|
+
},
|
|
2034
|
+
toolCallRequested: {
|
|
2035
|
+
allOf: [
|
|
2036
|
+
{
|
|
2037
|
+
$ref: "#/$defs/base"
|
|
2038
|
+
},
|
|
2039
|
+
{
|
|
2040
|
+
type: "object",
|
|
2041
|
+
properties: {
|
|
2042
|
+
type: {
|
|
2043
|
+
const: "tool.call.requested"
|
|
2044
|
+
},
|
|
2045
|
+
turn_id: {
|
|
2046
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2047
|
+
},
|
|
2048
|
+
tool_name: {
|
|
2049
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2050
|
+
},
|
|
2051
|
+
tool_args: {
|
|
2052
|
+
$ref: "#/$defs/jsonObject",
|
|
2053
|
+
"x-maxSerializedBytes": 65536
|
|
2054
|
+
},
|
|
2055
|
+
tool_call_id: {
|
|
2056
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2057
|
+
}
|
|
2058
|
+
},
|
|
2059
|
+
required: [
|
|
2060
|
+
"type",
|
|
2061
|
+
"turn_id",
|
|
2062
|
+
"tool_name",
|
|
2063
|
+
"tool_args",
|
|
2064
|
+
"tool_call_id"
|
|
2065
|
+
]
|
|
2066
|
+
}
|
|
2067
|
+
],
|
|
2068
|
+
unevaluatedProperties: false
|
|
2069
|
+
},
|
|
2070
|
+
toolCallStarted: {
|
|
2071
|
+
allOf: [
|
|
2072
|
+
{
|
|
2073
|
+
$ref: "#/$defs/base"
|
|
2074
|
+
},
|
|
2075
|
+
{
|
|
2076
|
+
type: "object",
|
|
2077
|
+
properties: {
|
|
2078
|
+
type: {
|
|
2079
|
+
const: "tool.call.started"
|
|
2080
|
+
},
|
|
2081
|
+
turn_id: {
|
|
2082
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2083
|
+
},
|
|
2084
|
+
tool_name: {
|
|
2085
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2086
|
+
},
|
|
2087
|
+
tool_call_id: {
|
|
2088
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2089
|
+
}
|
|
2090
|
+
},
|
|
2091
|
+
required: [
|
|
2092
|
+
"type",
|
|
2093
|
+
"turn_id",
|
|
2094
|
+
"tool_name",
|
|
2095
|
+
"tool_call_id"
|
|
2096
|
+
]
|
|
2097
|
+
}
|
|
2098
|
+
],
|
|
2099
|
+
unevaluatedProperties: false
|
|
2100
|
+
},
|
|
2101
|
+
toolCallCompleted: {
|
|
2102
|
+
allOf: [
|
|
2103
|
+
{
|
|
2104
|
+
$ref: "#/$defs/base"
|
|
2105
|
+
},
|
|
2106
|
+
{
|
|
2107
|
+
type: "object",
|
|
2108
|
+
properties: {
|
|
2109
|
+
type: {
|
|
2110
|
+
const: "tool.call.completed"
|
|
2111
|
+
},
|
|
2112
|
+
turn_id: {
|
|
2113
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2114
|
+
},
|
|
2115
|
+
tool_name: {
|
|
2116
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2117
|
+
},
|
|
2118
|
+
tool_call_id: {
|
|
2119
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2120
|
+
},
|
|
2121
|
+
result: {
|
|
2122
|
+
$ref: "#/$defs/jsonValue",
|
|
2123
|
+
"x-maxSerializedBytes": 65536
|
|
2124
|
+
},
|
|
2125
|
+
tokens: {
|
|
2126
|
+
oneOf: [
|
|
2127
|
+
{ $ref: "#/$defs/tokenUsage" },
|
|
2128
|
+
{ type: "null" }
|
|
2129
|
+
]
|
|
2130
|
+
},
|
|
2131
|
+
cost_usd: {
|
|
2132
|
+
oneOf: [
|
|
2133
|
+
{ $ref: "#/$defs/nonNegativeNumber" },
|
|
2134
|
+
{ type: "null" }
|
|
2135
|
+
]
|
|
2136
|
+
}
|
|
2137
|
+
},
|
|
2138
|
+
required: [
|
|
2139
|
+
"type",
|
|
2140
|
+
"turn_id",
|
|
2141
|
+
"tool_name",
|
|
2142
|
+
"tool_call_id",
|
|
2143
|
+
"result"
|
|
2144
|
+
]
|
|
2145
|
+
}
|
|
2146
|
+
],
|
|
2147
|
+
unevaluatedProperties: false
|
|
2148
|
+
},
|
|
2149
|
+
toolCallFailed: {
|
|
2150
|
+
allOf: [
|
|
2151
|
+
{
|
|
2152
|
+
$ref: "#/$defs/base"
|
|
2153
|
+
},
|
|
2154
|
+
{
|
|
2155
|
+
type: "object",
|
|
2156
|
+
properties: {
|
|
2157
|
+
type: {
|
|
2158
|
+
const: "tool.call.failed"
|
|
2159
|
+
},
|
|
2160
|
+
turn_id: {
|
|
2161
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2162
|
+
},
|
|
2163
|
+
tool_name: {
|
|
2164
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2165
|
+
},
|
|
2166
|
+
tool_call_id: {
|
|
2167
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2168
|
+
},
|
|
2169
|
+
error: {
|
|
2170
|
+
type: "string",
|
|
2171
|
+
minLength: 1,
|
|
2172
|
+
maxLength: 200
|
|
2173
|
+
},
|
|
2174
|
+
error_code: {
|
|
2175
|
+
type: "string"
|
|
2176
|
+
},
|
|
2177
|
+
error_path: {
|
|
2178
|
+
type: "string"
|
|
2179
|
+
},
|
|
2180
|
+
retryable: {
|
|
2181
|
+
type: "boolean"
|
|
2182
|
+
},
|
|
2183
|
+
outcome: {
|
|
2184
|
+
enum: [
|
|
2185
|
+
"not_started",
|
|
2186
|
+
"failed",
|
|
2187
|
+
"unknown"
|
|
2188
|
+
]
|
|
2189
|
+
},
|
|
2190
|
+
reason_code: {
|
|
2191
|
+
type: "string"
|
|
2192
|
+
},
|
|
2193
|
+
recovery_code: {
|
|
2194
|
+
type: "string"
|
|
2195
|
+
},
|
|
2196
|
+
doc_url: {
|
|
2197
|
+
type: "string"
|
|
2198
|
+
}
|
|
2199
|
+
},
|
|
2200
|
+
required: [
|
|
2201
|
+
"type",
|
|
2202
|
+
"turn_id",
|
|
2203
|
+
"tool_name",
|
|
2204
|
+
"tool_call_id",
|
|
2205
|
+
"error"
|
|
2206
|
+
]
|
|
2207
|
+
},
|
|
2208
|
+
{
|
|
2209
|
+
if: {
|
|
2210
|
+
anyOf: [
|
|
2211
|
+
{ required: ["reason_code"] },
|
|
2212
|
+
{ required: ["recovery_code"] },
|
|
2213
|
+
{ required: ["doc_url"] }
|
|
2214
|
+
]
|
|
2215
|
+
},
|
|
2216
|
+
then: {
|
|
2217
|
+
$ref: "#/$defs/integrationRecoveryFields"
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
],
|
|
2221
|
+
unevaluatedProperties: false
|
|
2222
|
+
},
|
|
2223
|
+
toolApprovalRequested: {
|
|
2224
|
+
allOf: [
|
|
2225
|
+
{
|
|
2226
|
+
$ref: "#/$defs/base"
|
|
2227
|
+
},
|
|
2228
|
+
{
|
|
2229
|
+
type: "object",
|
|
2230
|
+
properties: {
|
|
2231
|
+
type: {
|
|
2232
|
+
const: "tool.approval.requested"
|
|
2233
|
+
},
|
|
2234
|
+
turn_id: {
|
|
2235
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2236
|
+
},
|
|
2237
|
+
tool_name: {
|
|
2238
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2239
|
+
},
|
|
2240
|
+
tool_call_id: {
|
|
2241
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2242
|
+
},
|
|
2243
|
+
tool_args: {
|
|
2244
|
+
$ref: "#/$defs/jsonObject",
|
|
2245
|
+
"x-maxSerializedBytes": 65536
|
|
2246
|
+
},
|
|
2247
|
+
risk: {
|
|
2248
|
+
enum: [
|
|
2249
|
+
"read",
|
|
2250
|
+
"write",
|
|
2251
|
+
"external_effect",
|
|
2252
|
+
"destructive",
|
|
2253
|
+
"admin"
|
|
2254
|
+
]
|
|
2255
|
+
}
|
|
2256
|
+
},
|
|
2257
|
+
required: [
|
|
2258
|
+
"type",
|
|
2259
|
+
"turn_id",
|
|
2260
|
+
"tool_name",
|
|
2261
|
+
"tool_call_id",
|
|
2262
|
+
"tool_args",
|
|
2263
|
+
"risk"
|
|
2264
|
+
]
|
|
2265
|
+
}
|
|
2266
|
+
],
|
|
2267
|
+
unevaluatedProperties: false
|
|
2268
|
+
},
|
|
2269
|
+
toolApprovalApproved: {
|
|
2270
|
+
allOf: [
|
|
2271
|
+
{
|
|
2272
|
+
$ref: "#/$defs/base"
|
|
2273
|
+
},
|
|
2274
|
+
{
|
|
2275
|
+
type: "object",
|
|
2276
|
+
properties: {
|
|
2277
|
+
type: {
|
|
2278
|
+
const: "tool.approval.approved"
|
|
2279
|
+
},
|
|
2280
|
+
turn_id: {
|
|
2281
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2282
|
+
},
|
|
2283
|
+
tool_name: {
|
|
2284
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2285
|
+
},
|
|
2286
|
+
tool_call_id: {
|
|
2287
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2288
|
+
}
|
|
2289
|
+
},
|
|
2290
|
+
required: [
|
|
2291
|
+
"type",
|
|
2292
|
+
"turn_id",
|
|
2293
|
+
"tool_name",
|
|
2294
|
+
"tool_call_id"
|
|
2295
|
+
]
|
|
2296
|
+
}
|
|
2297
|
+
],
|
|
2298
|
+
unevaluatedProperties: false
|
|
2299
|
+
},
|
|
2300
|
+
toolApprovalRejected: {
|
|
2301
|
+
allOf: [
|
|
2302
|
+
{
|
|
2303
|
+
$ref: "#/$defs/base"
|
|
2304
|
+
},
|
|
2305
|
+
{
|
|
2306
|
+
type: "object",
|
|
2307
|
+
properties: {
|
|
2308
|
+
type: {
|
|
2309
|
+
const: "tool.approval.rejected"
|
|
2310
|
+
},
|
|
2311
|
+
turn_id: {
|
|
2312
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2313
|
+
},
|
|
2314
|
+
tool_name: {
|
|
2315
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2316
|
+
},
|
|
2317
|
+
tool_call_id: {
|
|
2318
|
+
$ref: "#/$defs/nonEmptyId"
|
|
2319
|
+
},
|
|
2320
|
+
error_code: {
|
|
2321
|
+
enum: [
|
|
2322
|
+
"APPROVAL_REJECTED",
|
|
2323
|
+
"APPROVAL_TIMEOUT",
|
|
2324
|
+
"TURN_TIMEOUT",
|
|
2325
|
+
"TOOL_CANCELLED",
|
|
2326
|
+
"APPROVAL_UNAVAILABLE"
|
|
2327
|
+
]
|
|
2328
|
+
},
|
|
2329
|
+
reason: {
|
|
2330
|
+
type: "string",
|
|
2331
|
+
minLength: 1,
|
|
2332
|
+
maxLength: 200,
|
|
2333
|
+
pattern: "\\S"
|
|
2334
|
+
}
|
|
2335
|
+
},
|
|
2336
|
+
required: [
|
|
2337
|
+
"type",
|
|
2338
|
+
"turn_id",
|
|
2339
|
+
"tool_name",
|
|
2340
|
+
"tool_call_id",
|
|
2341
|
+
"error_code",
|
|
2342
|
+
"reason"
|
|
2343
|
+
]
|
|
2344
|
+
}
|
|
2345
|
+
],
|
|
2346
|
+
unevaluatedProperties: false
|
|
2347
|
+
},
|
|
2348
|
+
workflowStarted: {
|
|
2349
|
+
allOf: [
|
|
2350
|
+
{
|
|
2351
|
+
$ref: "#/$defs/base"
|
|
2352
|
+
},
|
|
2353
|
+
{
|
|
2354
|
+
type: "object",
|
|
2355
|
+
properties: {
|
|
2356
|
+
type: {
|
|
2357
|
+
const: "workflow.started"
|
|
2358
|
+
},
|
|
2359
|
+
workflow_name: {
|
|
2360
|
+
type: "string"
|
|
2361
|
+
}
|
|
2362
|
+
},
|
|
2363
|
+
required: [
|
|
2364
|
+
"type",
|
|
2365
|
+
"workflow_name"
|
|
2366
|
+
]
|
|
2367
|
+
}
|
|
2368
|
+
],
|
|
2369
|
+
unevaluatedProperties: false
|
|
2370
|
+
},
|
|
2371
|
+
workflowCompleted: {
|
|
2372
|
+
allOf: [
|
|
2373
|
+
{
|
|
2374
|
+
$ref: "#/$defs/base"
|
|
2375
|
+
},
|
|
2376
|
+
{
|
|
2377
|
+
type: "object",
|
|
2378
|
+
properties: {
|
|
2379
|
+
type: {
|
|
2380
|
+
const: "workflow.completed"
|
|
2381
|
+
},
|
|
2382
|
+
workflow_name: {
|
|
2383
|
+
type: "string"
|
|
2384
|
+
},
|
|
2385
|
+
result: {
|
|
2386
|
+
$ref: "#/$defs/jsonValue"
|
|
2387
|
+
}
|
|
2388
|
+
},
|
|
2389
|
+
required: [
|
|
2390
|
+
"type",
|
|
2391
|
+
"workflow_name",
|
|
2392
|
+
"result"
|
|
2393
|
+
]
|
|
2394
|
+
}
|
|
2395
|
+
],
|
|
2396
|
+
unevaluatedProperties: false
|
|
2397
|
+
},
|
|
2398
|
+
workflowFailed: {
|
|
2399
|
+
allOf: [
|
|
2400
|
+
{
|
|
2401
|
+
$ref: "#/$defs/base"
|
|
2402
|
+
},
|
|
2403
|
+
{
|
|
2404
|
+
type: "object",
|
|
2405
|
+
properties: {
|
|
2406
|
+
type: {
|
|
2407
|
+
const: "workflow.failed"
|
|
2408
|
+
},
|
|
2409
|
+
workflow_name: {
|
|
2410
|
+
type: "string"
|
|
2411
|
+
},
|
|
2412
|
+
error: {
|
|
2413
|
+
type: "string"
|
|
2414
|
+
}
|
|
2415
|
+
},
|
|
2416
|
+
required: [
|
|
2417
|
+
"type",
|
|
2418
|
+
"workflow_name",
|
|
2419
|
+
"error"
|
|
2420
|
+
]
|
|
2421
|
+
}
|
|
2422
|
+
],
|
|
2423
|
+
unevaluatedProperties: false
|
|
2424
|
+
},
|
|
2425
|
+
cancellationRequested: {
|
|
2426
|
+
allOf: [
|
|
2427
|
+
{
|
|
2428
|
+
$ref: "#/$defs/base"
|
|
2429
|
+
},
|
|
2430
|
+
{
|
|
2431
|
+
type: "object",
|
|
2432
|
+
properties: {
|
|
2433
|
+
type: {
|
|
2434
|
+
const: "cancellation.requested"
|
|
2435
|
+
},
|
|
2436
|
+
reason: {
|
|
2437
|
+
type: "string"
|
|
2438
|
+
}
|
|
2439
|
+
},
|
|
2440
|
+
required: [
|
|
2441
|
+
"type",
|
|
2442
|
+
"reason"
|
|
2443
|
+
]
|
|
2444
|
+
}
|
|
2445
|
+
],
|
|
2446
|
+
unevaluatedProperties: false
|
|
2447
|
+
},
|
|
2448
|
+
cancellationCompleted: {
|
|
2449
|
+
allOf: [
|
|
2450
|
+
{
|
|
2451
|
+
$ref: "#/$defs/base"
|
|
2452
|
+
},
|
|
2453
|
+
{
|
|
2454
|
+
type: "object",
|
|
2455
|
+
properties: {
|
|
2456
|
+
type: {
|
|
2457
|
+
const: "cancellation.completed"
|
|
2458
|
+
}
|
|
2459
|
+
},
|
|
2460
|
+
required: [
|
|
2461
|
+
"type"
|
|
2462
|
+
]
|
|
2463
|
+
}
|
|
2464
|
+
],
|
|
2465
|
+
unevaluatedProperties: false
|
|
2466
|
+
}
|
|
2467
|
+
},
|
|
2468
|
+
oneOf: [
|
|
2469
|
+
{
|
|
2470
|
+
$ref: "#/$defs/sessionCreated"
|
|
2471
|
+
},
|
|
2472
|
+
{
|
|
2473
|
+
$ref: "#/$defs/sessionClosed"
|
|
2474
|
+
},
|
|
2475
|
+
{
|
|
2476
|
+
$ref: "#/$defs/userMessage"
|
|
2477
|
+
},
|
|
2478
|
+
{
|
|
2479
|
+
$ref: "#/$defs/userAudioChunk"
|
|
2480
|
+
},
|
|
2481
|
+
{
|
|
2482
|
+
$ref: "#/$defs/transcriptPartial"
|
|
2483
|
+
},
|
|
2484
|
+
{
|
|
2485
|
+
$ref: "#/$defs/transcriptFinal"
|
|
2486
|
+
},
|
|
2487
|
+
{
|
|
2488
|
+
$ref: "#/$defs/memoryRetrievalStarted"
|
|
2489
|
+
},
|
|
2490
|
+
{
|
|
2491
|
+
$ref: "#/$defs/memoryRetrievalCompleted"
|
|
2492
|
+
},
|
|
2493
|
+
{
|
|
2494
|
+
$ref: "#/$defs/agentReasoningStarted"
|
|
2495
|
+
},
|
|
2496
|
+
{
|
|
2497
|
+
$ref: "#/$defs/agentMessageDelta"
|
|
2498
|
+
},
|
|
2499
|
+
{
|
|
2500
|
+
$ref: "#/$defs/agentMessageCompleted"
|
|
2501
|
+
},
|
|
2502
|
+
{
|
|
2503
|
+
$ref: "#/$defs/agentTurnExhausted"
|
|
2504
|
+
},
|
|
2505
|
+
{
|
|
2506
|
+
$ref: "#/$defs/agentTurnFailed"
|
|
2507
|
+
},
|
|
2508
|
+
{
|
|
2509
|
+
$ref: "#/$defs/toolCallRequested"
|
|
2510
|
+
},
|
|
2511
|
+
{
|
|
2512
|
+
$ref: "#/$defs/toolCallStarted"
|
|
2513
|
+
},
|
|
2514
|
+
{
|
|
2515
|
+
$ref: "#/$defs/toolCallCompleted"
|
|
2516
|
+
},
|
|
2517
|
+
{
|
|
2518
|
+
$ref: "#/$defs/toolCallFailed"
|
|
2519
|
+
},
|
|
2520
|
+
{
|
|
2521
|
+
$ref: "#/$defs/toolApprovalRequested"
|
|
2522
|
+
},
|
|
2523
|
+
{
|
|
2524
|
+
$ref: "#/$defs/toolApprovalApproved"
|
|
2525
|
+
},
|
|
2526
|
+
{
|
|
2527
|
+
$ref: "#/$defs/toolApprovalRejected"
|
|
2528
|
+
},
|
|
2529
|
+
{
|
|
2530
|
+
$ref: "#/$defs/workflowStarted"
|
|
2531
|
+
},
|
|
2532
|
+
{
|
|
2533
|
+
$ref: "#/$defs/workflowCompleted"
|
|
2534
|
+
},
|
|
2535
|
+
{
|
|
2536
|
+
$ref: "#/$defs/workflowFailed"
|
|
2537
|
+
},
|
|
2538
|
+
{
|
|
2539
|
+
$ref: "#/$defs/cancellationRequested"
|
|
2540
|
+
},
|
|
2541
|
+
{
|
|
2542
|
+
$ref: "#/$defs/cancellationCompleted"
|
|
2543
|
+
}
|
|
2544
|
+
]
|
|
2545
|
+
};
|
|
2546
|
+
|
|
2547
|
+
// src/events/schemas.ts
|
|
2548
|
+
var MAX_DURABLE_TOOL_ARGUMENT_BYTES = 64 * 1024;
|
|
2549
|
+
var MAX_DURABLE_TOOL_RESULT_BYTES = 64 * 1024;
|
|
2550
|
+
var MAX_DURABLE_EVENT_BYTES = 1024 * 1024;
|
|
2551
|
+
function durableToolArgumentsSize(value) {
|
|
2552
|
+
return new TextEncoder().encode(canonicalJsonValue(value, "tool arguments")).byteLength;
|
|
2553
|
+
}
|
|
2554
|
+
var durableJsonValue = z.unknown().superRefine((value, ctx) => {
|
|
2555
|
+
try {
|
|
2556
|
+
canonicalJsonValue(value, "event value");
|
|
2557
|
+
} catch {
|
|
2558
|
+
ctx.addIssue({ code: "custom", message: "event value must contain only JSON values" });
|
|
2559
|
+
}
|
|
2560
|
+
});
|
|
2561
|
+
var durableJsonObject = z.record(z.string(), durableJsonValue).superRefine((value, ctx) => {
|
|
2562
|
+
try {
|
|
2563
|
+
canonicalJsonValue(value, "event value");
|
|
2564
|
+
} catch {
|
|
2565
|
+
ctx.addIssue({ code: "custom", message: "event value must contain only JSON values" });
|
|
2566
|
+
}
|
|
2567
|
+
});
|
|
2568
|
+
function durableSubjectValue(subject, maxBytes) {
|
|
2569
|
+
return z.unknown().superRefine((value, ctx) => {
|
|
2570
|
+
try {
|
|
2571
|
+
durableJsonSnapshot(value, subject, maxBytes);
|
|
2572
|
+
} catch {
|
|
2573
|
+
ctx.addIssue({ code: "custom", message: `${subject} must be bounded durable JSON` });
|
|
2574
|
+
}
|
|
2575
|
+
});
|
|
2576
|
+
}
|
|
2577
|
+
function durableSubjectObject(subject) {
|
|
2578
|
+
return z.record(z.string(), z.unknown()).superRefine((value, ctx) => {
|
|
2579
|
+
try {
|
|
2580
|
+
durableJsonSnapshot(value, subject, MAX_DURABLE_EVENT_BYTES);
|
|
2581
|
+
} catch {
|
|
2582
|
+
ctx.addIssue({ code: "custom", message: `${subject} must be bounded durable JSON` });
|
|
2583
|
+
}
|
|
2584
|
+
});
|
|
2585
|
+
}
|
|
2586
|
+
var durableToolArguments = durableJsonObject.superRefine((value, ctx) => {
|
|
2587
|
+
let size;
|
|
2588
|
+
try {
|
|
2589
|
+
size = durableToolArgumentsSize(value);
|
|
2590
|
+
} catch {
|
|
2591
|
+
ctx.addIssue({ code: "custom", message: "tool_args must contain only JSON values" });
|
|
2592
|
+
return;
|
|
2593
|
+
}
|
|
2594
|
+
if (size > MAX_DURABLE_TOOL_ARGUMENT_BYTES) {
|
|
2595
|
+
ctx.addIssue({
|
|
2596
|
+
code: "custom",
|
|
2597
|
+
message: "tool_args cannot exceed 65536 serialized bytes; payload redacted"
|
|
2598
|
+
});
|
|
2599
|
+
}
|
|
2600
|
+
});
|
|
2601
|
+
var nonEmptyId = z.string().min(1);
|
|
2602
|
+
var baseShape = {
|
|
2603
|
+
id: nonEmptyId.default(() => defaultUuid()),
|
|
2604
|
+
version: z.literal("1.0").default("1.0"),
|
|
2605
|
+
timestamp: z.number().default(() => Date.now() / 1e3),
|
|
2606
|
+
session_id: nonEmptyId,
|
|
2607
|
+
turn_id: nonEmptyId.optional(),
|
|
2608
|
+
metadata: durableSubjectObject("event_metadata").default(() => ({}))
|
|
2609
|
+
};
|
|
2610
|
+
function maxUnicodeCodePoints(field) {
|
|
2611
|
+
return (value, ctx) => {
|
|
2612
|
+
if (Array.from(value).length > 200) {
|
|
2613
|
+
ctx.addIssue({ code: "custom", message: `${field} must contain at most 200 characters` });
|
|
2614
|
+
}
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2617
|
+
function event(shape) {
|
|
2618
|
+
return z.object(baseShape).extend(shape).strict();
|
|
2619
|
+
}
|
|
2620
|
+
var SessionCreated = event({
|
|
2621
|
+
type: z.literal(EventType.SESSION_CREATED)
|
|
2622
|
+
});
|
|
2623
|
+
var SessionClosed = event({
|
|
2624
|
+
type: z.literal(EventType.SESSION_CLOSED),
|
|
2625
|
+
reason: z.string().nullish()
|
|
2626
|
+
});
|
|
2627
|
+
var UserMessage = event({
|
|
2628
|
+
type: z.literal(EventType.USER_MESSAGE),
|
|
2629
|
+
content: z.string()
|
|
2630
|
+
});
|
|
2631
|
+
var UserAudioChunk = event({
|
|
2632
|
+
type: z.literal(EventType.USER_AUDIO_CHUNK),
|
|
2633
|
+
chunk_size_bytes: z.number().int()
|
|
2634
|
+
});
|
|
2635
|
+
var TranscriptPartial = event({
|
|
2636
|
+
type: z.literal(EventType.TRANSCRIPT_PARTIAL),
|
|
2637
|
+
text: z.string()
|
|
2638
|
+
});
|
|
2639
|
+
var TranscriptFinal = event({
|
|
2640
|
+
type: z.literal(EventType.TRANSCRIPT_FINAL),
|
|
2641
|
+
text: z.string()
|
|
2642
|
+
});
|
|
2643
|
+
var MemoryRetrievalStarted = event({
|
|
2644
|
+
type: z.literal(EventType.MEMORY_RETRIEVAL_STARTED),
|
|
2645
|
+
query: z.string()
|
|
2646
|
+
});
|
|
2647
|
+
var MemoryRetrievalCompleted = event({
|
|
2648
|
+
type: z.literal(EventType.MEMORY_RETRIEVAL_COMPLETED),
|
|
2649
|
+
query: z.string(),
|
|
2650
|
+
documents: z.array(durableSubjectObject("memory_document"))
|
|
2651
|
+
});
|
|
2652
|
+
var AgentReasoningStarted = event({
|
|
2653
|
+
type: z.literal(EventType.AGENT_REASONING_STARTED)
|
|
2654
|
+
});
|
|
2655
|
+
var AgentMessageDelta = event({
|
|
2656
|
+
type: z.literal(EventType.AGENT_MESSAGE_DELTA),
|
|
2657
|
+
delta: z.string()
|
|
2658
|
+
});
|
|
2659
|
+
var AgentMessageCompleted = event({
|
|
2660
|
+
type: z.literal(EventType.AGENT_MESSAGE_COMPLETED),
|
|
2661
|
+
content: z.string(),
|
|
2662
|
+
tokens: z.object({ input: z.number().int().nonnegative(), output: z.number().int().nonnegative() }).strict().nullish(),
|
|
2663
|
+
cost_usd: z.number().nonnegative().nullish()
|
|
2664
|
+
});
|
|
2665
|
+
var AgentTurnExhausted = event({
|
|
2666
|
+
type: z.literal(EventType.AGENT_TURN_EXHAUSTED),
|
|
2667
|
+
max_iterations: z.number().int().nonnegative(),
|
|
2668
|
+
pending_tool_calls: z.array(durableSubjectObject("pending_tool_call")),
|
|
2669
|
+
reason: z.string().nullish()
|
|
2670
|
+
});
|
|
2671
|
+
var AgentTurnFailed = event({
|
|
2672
|
+
type: z.literal(EventType.AGENT_TURN_FAILED),
|
|
2673
|
+
turn_id: z.string().min(1),
|
|
2674
|
+
error: z.string().min(1).superRefine(maxUnicodeCodePoints("error")),
|
|
2675
|
+
error_code: z.string().optional(),
|
|
2676
|
+
phase: z.enum(["queue", "provider_open", "provider_stream", "approval", "tool"]).optional(),
|
|
2677
|
+
retryable: z.boolean().optional(),
|
|
2678
|
+
outcome: z.enum(["not_started", "failed", "unknown"]).optional()
|
|
2679
|
+
});
|
|
2680
|
+
var ToolCallRequested = event({
|
|
2681
|
+
type: z.literal(EventType.TOOL_CALL_REQUESTED),
|
|
2682
|
+
turn_id: z.string().min(1),
|
|
2683
|
+
tool_name: z.string().min(1),
|
|
2684
|
+
tool_args: durableToolArguments,
|
|
2685
|
+
tool_call_id: z.string().min(1)
|
|
2686
|
+
});
|
|
2687
|
+
var ToolCallStarted = event({
|
|
2688
|
+
type: z.literal(EventType.TOOL_CALL_STARTED),
|
|
2689
|
+
turn_id: z.string().min(1),
|
|
2690
|
+
tool_name: z.string().min(1),
|
|
2691
|
+
tool_call_id: z.string().min(1)
|
|
2692
|
+
});
|
|
2693
|
+
var ToolCallCompleted = event({
|
|
2694
|
+
type: z.literal(EventType.TOOL_CALL_COMPLETED),
|
|
2695
|
+
turn_id: z.string().min(1),
|
|
2696
|
+
tool_name: z.string().min(1),
|
|
2697
|
+
tool_call_id: z.string().min(1),
|
|
2698
|
+
result: durableSubjectValue("tool_result", MAX_DURABLE_TOOL_RESULT_BYTES),
|
|
2699
|
+
tokens: z.object({ input: z.number().int().nonnegative(), output: z.number().int().nonnegative() }).strict().nullish(),
|
|
2700
|
+
cost_usd: z.number().nonnegative().nullish()
|
|
2701
|
+
});
|
|
2702
|
+
var ToolCallFailed = event({
|
|
2703
|
+
type: z.literal(EventType.TOOL_CALL_FAILED),
|
|
2704
|
+
turn_id: z.string().min(1),
|
|
2705
|
+
tool_name: z.string().min(1),
|
|
2706
|
+
tool_call_id: z.string().min(1),
|
|
2707
|
+
error: z.string().min(1).superRefine(maxUnicodeCodePoints("error")),
|
|
2708
|
+
error_code: z.string().optional(),
|
|
2709
|
+
error_path: z.string().optional(),
|
|
2710
|
+
retryable: z.boolean().optional(),
|
|
2711
|
+
outcome: z.enum(["not_started", "failed", "unknown"]).optional(),
|
|
2712
|
+
reason_code: z.string().optional(),
|
|
2713
|
+
recovery_code: z.string().optional(),
|
|
2714
|
+
doc_url: z.string().optional()
|
|
2715
|
+
}).superRefine((value, ctx) => {
|
|
2716
|
+
if (!isClosedRecoveryTuple(value.reason_code, value.recovery_code, value.doc_url, value.error_code)) {
|
|
2717
|
+
ctx.addIssue({
|
|
2718
|
+
code: "custom",
|
|
2719
|
+
path: ["reason_code"],
|
|
2720
|
+
message: "integration recovery metadata must be a closed tuple"
|
|
2721
|
+
});
|
|
2722
|
+
}
|
|
2723
|
+
});
|
|
2724
|
+
var ToolApprovalRequested = event({
|
|
2725
|
+
type: z.literal(EventType.TOOL_APPROVAL_REQUESTED),
|
|
2726
|
+
turn_id: z.string().min(1),
|
|
2727
|
+
tool_name: z.string().min(1),
|
|
2728
|
+
tool_call_id: z.string().min(1),
|
|
2729
|
+
tool_args: durableToolArguments,
|
|
2730
|
+
risk: z.enum(["read", "write", "external_effect", "destructive", "admin"])
|
|
2731
|
+
});
|
|
2732
|
+
var ToolApprovalApproved = event({
|
|
2733
|
+
type: z.literal(EventType.TOOL_APPROVAL_APPROVED),
|
|
2734
|
+
turn_id: z.string().min(1),
|
|
2735
|
+
tool_name: z.string().min(1),
|
|
2736
|
+
tool_call_id: z.string().min(1)
|
|
2737
|
+
});
|
|
2738
|
+
var ToolApprovalRejected = event({
|
|
2739
|
+
type: z.literal(EventType.TOOL_APPROVAL_REJECTED),
|
|
2740
|
+
turn_id: z.string().min(1),
|
|
2741
|
+
tool_name: z.string().min(1),
|
|
2742
|
+
tool_call_id: z.string().min(1),
|
|
2743
|
+
error_code: z.enum([
|
|
2744
|
+
"APPROVAL_REJECTED",
|
|
2745
|
+
"APPROVAL_TIMEOUT",
|
|
2746
|
+
"TURN_TIMEOUT",
|
|
2747
|
+
"TOOL_CANCELLED",
|
|
2748
|
+
"APPROVAL_UNAVAILABLE"
|
|
2749
|
+
]),
|
|
2750
|
+
reason: z.string().min(1).refine((value) => value.trim().length > 0, "reason must not be blank").superRefine(maxUnicodeCodePoints("reason"))
|
|
2751
|
+
});
|
|
2752
|
+
var WorkflowStarted = event({
|
|
2753
|
+
type: z.literal(EventType.WORKFLOW_STARTED),
|
|
2754
|
+
workflow_name: z.string()
|
|
2755
|
+
});
|
|
2756
|
+
var WorkflowCompleted = event({
|
|
2757
|
+
type: z.literal(EventType.WORKFLOW_COMPLETED),
|
|
2758
|
+
workflow_name: z.string(),
|
|
2759
|
+
result: durableSubjectValue("workflow_result", MAX_DURABLE_EVENT_BYTES)
|
|
2760
|
+
});
|
|
2761
|
+
var WorkflowFailed = event({
|
|
2762
|
+
type: z.literal(EventType.WORKFLOW_FAILED),
|
|
2763
|
+
workflow_name: z.string(),
|
|
2764
|
+
error: z.string()
|
|
2765
|
+
});
|
|
2766
|
+
var CancellationRequested = event({
|
|
2767
|
+
type: z.literal(EventType.CANCELLATION_REQUESTED),
|
|
2768
|
+
reason: z.string()
|
|
2769
|
+
});
|
|
2770
|
+
var CancellationCompleted = event({
|
|
2771
|
+
type: z.literal(EventType.CANCELLATION_COMPLETED)
|
|
2772
|
+
});
|
|
2773
|
+
var KajiEvent = z.discriminatedUnion("type", [
|
|
2774
|
+
SessionCreated,
|
|
2775
|
+
SessionClosed,
|
|
2776
|
+
UserMessage,
|
|
2777
|
+
UserAudioChunk,
|
|
2778
|
+
TranscriptPartial,
|
|
2779
|
+
TranscriptFinal,
|
|
2780
|
+
MemoryRetrievalStarted,
|
|
2781
|
+
MemoryRetrievalCompleted,
|
|
2782
|
+
AgentReasoningStarted,
|
|
2783
|
+
AgentMessageDelta,
|
|
2784
|
+
AgentMessageCompleted,
|
|
2785
|
+
AgentTurnExhausted,
|
|
2786
|
+
AgentTurnFailed,
|
|
2787
|
+
ToolCallRequested,
|
|
2788
|
+
ToolCallStarted,
|
|
2789
|
+
ToolCallCompleted,
|
|
2790
|
+
ToolCallFailed,
|
|
2791
|
+
ToolApprovalRequested,
|
|
2792
|
+
ToolApprovalApproved,
|
|
2793
|
+
ToolApprovalRejected,
|
|
2794
|
+
WorkflowStarted,
|
|
2795
|
+
WorkflowCompleted,
|
|
2796
|
+
WorkflowFailed,
|
|
2797
|
+
CancellationRequested,
|
|
2798
|
+
CancellationCompleted
|
|
2799
|
+
]);
|
|
2800
|
+
var NewKajiEvent = KajiEvent;
|
|
2801
|
+
var StoredKajiEvent = z.object({ sequence: z.number().int().positive() }).loose().transform((value, ctx) => {
|
|
2802
|
+
const { sequence, ...candidate } = value;
|
|
2803
|
+
const parsed = KajiEvent.safeParse(candidate);
|
|
2804
|
+
if (!parsed.success) {
|
|
2805
|
+
for (const issue of parsed.error.issues) ctx.addIssue({ ...issue });
|
|
2806
|
+
return z.NEVER;
|
|
2807
|
+
}
|
|
2808
|
+
return cloneAndFreezeJson({ ...parsed.data, sequence });
|
|
2809
|
+
});
|
|
2810
|
+
var EVENT_TYPES = new Set(Object.values(EventType));
|
|
2811
|
+
var wireAjv = new Ajv2020({ allErrors: true, strict: false });
|
|
2812
|
+
var newWireValidator = wireAjv.compile(new_kaji_event_v1_schema_default);
|
|
2813
|
+
var storedWireValidator = wireAjv.compile(stored_kaji_event_v1_schema_default);
|
|
2814
|
+
var variantValidators = /* @__PURE__ */ new Map();
|
|
2815
|
+
function pointerSegment(value) {
|
|
2816
|
+
return String(value).replaceAll("~", "~0").replaceAll("/", "~1");
|
|
2817
|
+
}
|
|
2818
|
+
function schemaDefName(eventType) {
|
|
2819
|
+
const [head, ...tail] = eventType.split(".");
|
|
2820
|
+
return `${head}${tail.map((part) => part[0].toUpperCase() + part.slice(1)).join("")}`;
|
|
2821
|
+
}
|
|
2822
|
+
function selectedWireValidator(stored, eventType) {
|
|
2823
|
+
const key = `${stored ? "stored" : "new"}:${eventType}`;
|
|
2824
|
+
const existing = variantValidators.get(key);
|
|
2825
|
+
if (existing !== void 0) return existing;
|
|
2826
|
+
const schema = stored ? stored_kaji_event_v1_schema_default : new_kaji_event_v1_schema_default;
|
|
2827
|
+
const compiled = wireAjv.compile({
|
|
2828
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
2829
|
+
$defs: schema.$defs,
|
|
2830
|
+
$ref: `#/$defs/${schemaDefName(eventType)}`
|
|
2831
|
+
});
|
|
2832
|
+
variantValidators.set(key, compiled);
|
|
2833
|
+
return compiled;
|
|
2834
|
+
}
|
|
2835
|
+
function schemaErrorPointer(error) {
|
|
2836
|
+
if (error.keyword === "required") {
|
|
2837
|
+
return `${error.instancePath}/${pointerSegment(error.params.missingProperty)}`;
|
|
2838
|
+
}
|
|
2839
|
+
if (error.keyword === "unevaluatedProperties" || error.keyword === "additionalProperties") {
|
|
2840
|
+
const property = error.params.unevaluatedProperty ?? error.params.additionalProperty;
|
|
2841
|
+
if (property !== void 0) return `${error.instancePath}/${pointerSegment(property)}`;
|
|
2842
|
+
}
|
|
2843
|
+
return error.instancePath || "/";
|
|
2844
|
+
}
|
|
2845
|
+
function firstSchemaErrorPointer(errors) {
|
|
2846
|
+
const pointers = (errors ?? []).filter((error) => error.keyword !== "allOf" && error.keyword !== "oneOf").map(schemaErrorPointer).sort(
|
|
2847
|
+
(left, right) => Number(left === "/") - Number(right === "/") || left.localeCompare(right)
|
|
2848
|
+
);
|
|
2849
|
+
return pointers[0] ?? "/";
|
|
2850
|
+
}
|
|
2851
|
+
function wirePreflight(value, stored) {
|
|
2852
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2853
|
+
throw new EventSchemaIncompatibleError("/");
|
|
2854
|
+
}
|
|
2855
|
+
const document = value;
|
|
2856
|
+
if ([document.reason_code, document.recovery_code, document.doc_url].some(
|
|
2857
|
+
(field) => field !== void 0
|
|
2858
|
+
) && !isClosedRecoveryTuple(
|
|
2859
|
+
document.reason_code,
|
|
2860
|
+
document.recovery_code,
|
|
2861
|
+
document.doc_url,
|
|
2862
|
+
document.error_code
|
|
2863
|
+
)) {
|
|
2864
|
+
throw new EventSchemaIncompatibleError("/reason_code");
|
|
2865
|
+
}
|
|
2866
|
+
for (const field of ["id", "version", "timestamp", "type", "session_id"]) {
|
|
2867
|
+
if (!(field in document)) throw new EventSchemaIncompatibleError(`/${field}`);
|
|
2868
|
+
}
|
|
2869
|
+
for (const field of ["id", "session_id", "turn_id"]) {
|
|
2870
|
+
if (document[field] === "") throw new EventSchemaIncompatibleError(`/${field}`);
|
|
2871
|
+
}
|
|
2872
|
+
if (stored && !("sequence" in document)) throw new EventSchemaIncompatibleError("/sequence");
|
|
2873
|
+
if (!stored && "sequence" in document) throw new EventSchemaIncompatibleError("/sequence");
|
|
2874
|
+
if (typeof document.type !== "string" || !EVENT_TYPES.has(document.type)) {
|
|
2875
|
+
throw new EventSchemaIncompatibleError("/type");
|
|
2876
|
+
}
|
|
2877
|
+
return document;
|
|
2878
|
+
}
|
|
2879
|
+
function zodIssuePointer(error) {
|
|
2880
|
+
const issue = error.issues[0];
|
|
2881
|
+
if (issue === void 0 || issue.path.length === 0) return "/";
|
|
2882
|
+
const path = [...issue.path];
|
|
2883
|
+
if (typeof path[0] === "string" && EVENT_TYPES.has(path[0])) path.shift();
|
|
2884
|
+
return `/${path.map(pointerSegment).join("/")}`;
|
|
2885
|
+
}
|
|
2886
|
+
function durableErrorPointer(error) {
|
|
2887
|
+
const pointers = {
|
|
2888
|
+
tool_result: "/result",
|
|
2889
|
+
workflow_result: "/result",
|
|
2890
|
+
event_metadata: "/metadata",
|
|
2891
|
+
memory_document: "/documents",
|
|
2892
|
+
pending_tool_call: "/pending_tool_calls",
|
|
2893
|
+
event: "/"
|
|
2894
|
+
};
|
|
2895
|
+
return pointers[error.subject];
|
|
2896
|
+
}
|
|
2897
|
+
function ownDataValue(document, key, subject) {
|
|
2898
|
+
const descriptor = Object.getOwnPropertyDescriptor(document, key);
|
|
2899
|
+
if (descriptor === void 0) return { present: false };
|
|
2900
|
+
if (!descriptor.enumerable || !("value" in descriptor)) {
|
|
2901
|
+
throw new InvalidDurableValueError(subject);
|
|
2902
|
+
}
|
|
2903
|
+
return { present: true, value: descriptor.value };
|
|
2904
|
+
}
|
|
2905
|
+
function snapshotArrayItems(value, subject) {
|
|
2906
|
+
if (!Array.isArray(value)) throw new InvalidDurableValueError(subject);
|
|
2907
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
2908
|
+
for (let index = 0; index < value.length; index++) {
|
|
2909
|
+
const descriptor = descriptors[String(index)];
|
|
2910
|
+
if (descriptor === void 0 || !descriptor.enumerable || !("value" in descriptor)) {
|
|
2911
|
+
throw new InvalidDurableValueError(subject);
|
|
2912
|
+
}
|
|
2913
|
+
durableJsonSnapshot(descriptor.value, subject, MAX_DURABLE_EVENT_BYTES);
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
function snapshotEventSubjects(document) {
|
|
2917
|
+
const metadata = ownDataValue(document, "metadata", "event_metadata");
|
|
2918
|
+
if (metadata.present) {
|
|
2919
|
+
durableJsonSnapshot(metadata.value, "event_metadata", MAX_DURABLE_EVENT_BYTES);
|
|
2920
|
+
}
|
|
2921
|
+
const type = ownDataValue(document, "type", "event");
|
|
2922
|
+
if (!type.present) return;
|
|
2923
|
+
if (type.value === EventType.TOOL_CALL_COMPLETED) {
|
|
2924
|
+
const result = ownDataValue(document, "result", "tool_result");
|
|
2925
|
+
if (result.present) {
|
|
2926
|
+
durableJsonSnapshot(result.value, "tool_result", MAX_DURABLE_TOOL_RESULT_BYTES);
|
|
2927
|
+
}
|
|
2928
|
+
} else if (type.value === EventType.WORKFLOW_COMPLETED) {
|
|
2929
|
+
const result = ownDataValue(document, "result", "workflow_result");
|
|
2930
|
+
if (result.present) {
|
|
2931
|
+
durableJsonSnapshot(result.value, "workflow_result", MAX_DURABLE_EVENT_BYTES);
|
|
2932
|
+
}
|
|
2933
|
+
} else if (type.value === EventType.MEMORY_RETRIEVAL_COMPLETED) {
|
|
2934
|
+
const documents = ownDataValue(document, "documents", "event");
|
|
2935
|
+
if (documents.present) snapshotArrayItems(documents.value, "memory_document");
|
|
2936
|
+
} else if (type.value === EventType.AGENT_TURN_EXHAUSTED) {
|
|
2937
|
+
const pending = ownDataValue(document, "pending_tool_calls", "event");
|
|
2938
|
+
if (pending.present) snapshotArrayItems(pending.value, "pending_tool_call");
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
function durableEventSnapshot(value) {
|
|
2942
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
2943
|
+
snapshotEventSubjects(value);
|
|
2944
|
+
}
|
|
2945
|
+
return durableJsonSnapshot(value, "event", MAX_DURABLE_EVENT_BYTES);
|
|
2946
|
+
}
|
|
2947
|
+
function descriptorSafeWireSnapshot(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
2948
|
+
if (value === null || typeof value !== "object") return value;
|
|
2949
|
+
if (ancestors.has(value)) throw new InvalidDurableValueError("event");
|
|
2950
|
+
const isArray = Array.isArray(value);
|
|
2951
|
+
const prototype = Object.getPrototypeOf(value);
|
|
2952
|
+
if (!isArray && prototype !== Object.prototype && prototype !== null) {
|
|
2953
|
+
throw new InvalidDurableValueError("event");
|
|
2954
|
+
}
|
|
2955
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
2956
|
+
throw new InvalidDurableValueError("event");
|
|
2957
|
+
}
|
|
2958
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
2959
|
+
const clone = isArray ? [] : Object.create(prototype);
|
|
2960
|
+
ancestors.add(value);
|
|
2961
|
+
try {
|
|
2962
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
2963
|
+
if (isArray && key === "length") continue;
|
|
2964
|
+
if (!descriptor.enumerable || !("value" in descriptor)) {
|
|
2965
|
+
throw new InvalidDurableValueError("event");
|
|
2966
|
+
}
|
|
2967
|
+
Object.defineProperty(clone, key, {
|
|
2968
|
+
value: descriptorSafeWireSnapshot(descriptor.value, ancestors),
|
|
2969
|
+
enumerable: true,
|
|
2970
|
+
writable: true,
|
|
2971
|
+
configurable: true
|
|
2972
|
+
});
|
|
2973
|
+
}
|
|
2974
|
+
if (isArray && clone.length !== value.length) {
|
|
2975
|
+
throw new InvalidDurableValueError("event");
|
|
2976
|
+
}
|
|
2977
|
+
return Object.freeze(clone);
|
|
2978
|
+
} finally {
|
|
2979
|
+
ancestors.delete(value);
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
function validateWireEvent(value, stored) {
|
|
2983
|
+
let durableFailure;
|
|
2984
|
+
let snapshot;
|
|
2985
|
+
try {
|
|
2986
|
+
snapshot = durableEventSnapshot(value);
|
|
2987
|
+
} catch (error) {
|
|
2988
|
+
if (error instanceof InvalidDurableValueError || error instanceof DurableJsonLimitError) {
|
|
2989
|
+
durableFailure = error;
|
|
2990
|
+
try {
|
|
2991
|
+
snapshot = descriptorSafeWireSnapshot(value);
|
|
2992
|
+
} catch {
|
|
2993
|
+
throw new EventSchemaIncompatibleError(durableErrorPointer(error));
|
|
2994
|
+
}
|
|
2995
|
+
} else {
|
|
2996
|
+
throw new EventSchemaIncompatibleError("/");
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
if (typeof snapshot !== "object" || snapshot === null || Array.isArray(snapshot)) {
|
|
3000
|
+
throw new EventSchemaIncompatibleError("/");
|
|
3001
|
+
}
|
|
3002
|
+
const document = wirePreflight(snapshot, stored);
|
|
3003
|
+
const validator = stored ? storedWireValidator : newWireValidator;
|
|
3004
|
+
const eventType = document.type;
|
|
3005
|
+
if (!validator(document)) {
|
|
3006
|
+
const selected = selectedWireValidator(stored, eventType);
|
|
3007
|
+
selected(document);
|
|
3008
|
+
throw new EventSchemaIncompatibleError(
|
|
3009
|
+
firstSchemaErrorPointer(selected.errors ?? validator.errors)
|
|
3010
|
+
);
|
|
3011
|
+
}
|
|
3012
|
+
if (durableFailure !== void 0) {
|
|
3013
|
+
throw new EventSchemaIncompatibleError(durableErrorPointer(durableFailure));
|
|
3014
|
+
}
|
|
3015
|
+
const candidate = stored ? Object.fromEntries(Object.entries(document).filter(([key]) => key !== "sequence")) : document;
|
|
3016
|
+
const parsed = KajiEvent.safeParse(candidate);
|
|
3017
|
+
if (!parsed.success) throw new EventSchemaIncompatibleError(zodIssuePointer(parsed.error));
|
|
3018
|
+
return { event: parsed.data, document };
|
|
3019
|
+
}
|
|
3020
|
+
function validateNewEvent(value) {
|
|
3021
|
+
return validateWireEvent(value, false).event;
|
|
3022
|
+
}
|
|
3023
|
+
function snapshotNewEvent(value) {
|
|
3024
|
+
return validateNewEvent(durableEventSnapshot(value));
|
|
3025
|
+
}
|
|
3026
|
+
function snapshotStoredEventForAppend(value) {
|
|
3027
|
+
return validateStoredEvent(durableEventSnapshot(value));
|
|
3028
|
+
}
|
|
3029
|
+
function validateStoredEvent(value) {
|
|
3030
|
+
const { event: event2, document } = validateWireEvent(value, true);
|
|
3031
|
+
const sequence = document.sequence;
|
|
3032
|
+
return cloneAndFreezeJson({ ...event2, sequence });
|
|
3033
|
+
}
|
|
3034
|
+
|
|
3035
|
+
// src/observability.ts
|
|
3036
|
+
var SPAN_NAMES = /* @__PURE__ */ new Set([
|
|
3037
|
+
"kaji.turn",
|
|
3038
|
+
"kaji.provider",
|
|
3039
|
+
"kaji.tool",
|
|
3040
|
+
"kaji.integration.auth",
|
|
3041
|
+
"kaji.integration.request"
|
|
3042
|
+
]);
|
|
3043
|
+
var TRACE_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
3044
|
+
"session.id",
|
|
3045
|
+
"turn.id",
|
|
3046
|
+
"request.id",
|
|
3047
|
+
"trace.id",
|
|
3048
|
+
"tool.call_id",
|
|
3049
|
+
"provider.family",
|
|
3050
|
+
"integration.name",
|
|
3051
|
+
"integration.operation",
|
|
3052
|
+
"http.status_family"
|
|
3053
|
+
]);
|
|
3054
|
+
var METRIC_UNITS = Object.freeze({
|
|
3055
|
+
"kaji.turn.queue_wait_ms": "ms",
|
|
3056
|
+
"kaji.turn.duration_ms": "ms",
|
|
3057
|
+
"kaji.turn.iterations": "count",
|
|
3058
|
+
"kaji.provider.duration_ms": "ms",
|
|
3059
|
+
"kaji.provider.retries": "count",
|
|
3060
|
+
"kaji.replay.input_events": "count",
|
|
3061
|
+
"kaji.context.messages": "count",
|
|
3062
|
+
"kaji.context.characters": "count",
|
|
3063
|
+
"kaji.tool.queue_wait_ms": "ms",
|
|
3064
|
+
"kaji.tool.active": "gauge",
|
|
3065
|
+
"kaji.tool.duration_ms": "ms",
|
|
3066
|
+
"kaji.journal.failures": "count",
|
|
3067
|
+
"kaji.subscriber.lag_events": "count",
|
|
3068
|
+
"kaji.subscriber.overflow": "count",
|
|
3069
|
+
"kaji.integration.auth_ms": "ms",
|
|
3070
|
+
"kaji.integration.request_ms": "ms"
|
|
3071
|
+
});
|
|
3072
|
+
var METRIC_NAMES = Object.freeze(
|
|
3073
|
+
Object.keys(METRIC_UNITS)
|
|
3074
|
+
);
|
|
3075
|
+
var ALLOWED_LABELS = Object.freeze({
|
|
3076
|
+
"kaji.turn.queue_wait_ms": [],
|
|
3077
|
+
"kaji.turn.duration_ms": ["outcome"],
|
|
3078
|
+
"kaji.turn.iterations": ["outcome"],
|
|
3079
|
+
"kaji.provider.duration_ms": ["provider_family", "status"],
|
|
3080
|
+
"kaji.provider.retries": ["provider_family"],
|
|
3081
|
+
"kaji.replay.input_events": [],
|
|
3082
|
+
"kaji.context.messages": [],
|
|
3083
|
+
"kaji.context.characters": [],
|
|
3084
|
+
"kaji.tool.queue_wait_ms": ["outcome"],
|
|
3085
|
+
"kaji.tool.active": [],
|
|
3086
|
+
"kaji.tool.duration_ms": ["outcome", "error_code"],
|
|
3087
|
+
"kaji.journal.failures": ["stage"],
|
|
3088
|
+
"kaji.subscriber.lag_events": [],
|
|
3089
|
+
"kaji.subscriber.overflow": ["stage"],
|
|
3090
|
+
"kaji.integration.auth_ms": ["integration", "operation", "outcome"],
|
|
3091
|
+
"kaji.integration.request_ms": ["integration", "operation", "outcome"]
|
|
3092
|
+
});
|
|
3093
|
+
var STABLE_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
3094
|
+
"NONE",
|
|
3095
|
+
"OTHER",
|
|
3096
|
+
"INVALID_TOOL_SCHEMA",
|
|
3097
|
+
"INVALID_TOOL_ARGUMENTS",
|
|
3098
|
+
"UNCLASSIFIED_TOOL_RISK",
|
|
3099
|
+
"MISSING_TOOL_IDENTITY",
|
|
3100
|
+
"TOOL_NOT_ALLOWED",
|
|
3101
|
+
"APPROVAL_UNAVAILABLE",
|
|
3102
|
+
"APPROVAL_REJECTED",
|
|
3103
|
+
"APPROVAL_TIMEOUT",
|
|
3104
|
+
"TOOL_CANCELLED",
|
|
3105
|
+
"TOOL_TIMEOUT",
|
|
3106
|
+
"TURN_TIMEOUT",
|
|
3107
|
+
"TOOL_EXECUTION_FAILED",
|
|
3108
|
+
"TOOL_START_RECORD_FAILED",
|
|
3109
|
+
"IDEMPOTENCY_CAPACITY_EXCEEDED",
|
|
3110
|
+
"IDEMPOTENCY_CONFLICT",
|
|
3111
|
+
"INTEGRATION_AUTH_ERROR",
|
|
3112
|
+
"INTEGRATION_AUTH_REQUIRED",
|
|
3113
|
+
"INTEGRATION_API_ERROR",
|
|
3114
|
+
"INTEGRATION_POLICY_REJECTED",
|
|
3115
|
+
"INTEGRATION_RATE_LIMITED",
|
|
3116
|
+
"INTEGRATION_REDIRECT_REJECTED",
|
|
3117
|
+
"INTEGRATION_RESPONSE_LIMIT"
|
|
3118
|
+
]);
|
|
3119
|
+
function validLabel(key, value) {
|
|
3120
|
+
if (typeof value !== "string") return false;
|
|
3121
|
+
const text = value;
|
|
3122
|
+
if (key === "provider_family") {
|
|
3123
|
+
return text === "openai" || text === "anthropic" || text === "custom";
|
|
3124
|
+
}
|
|
3125
|
+
if (key === "status") {
|
|
3126
|
+
return text === "success" || text === "cancelled" || text === "error";
|
|
3127
|
+
}
|
|
3128
|
+
if (key === "stage") {
|
|
3129
|
+
return ["append", "publish", "lag", "overflow"].includes(text);
|
|
3130
|
+
}
|
|
3131
|
+
if (key === "error_code") return STABLE_ERROR_CODES.has(text);
|
|
3132
|
+
if (key === "outcome") {
|
|
3133
|
+
return [
|
|
3134
|
+
"acquired",
|
|
3135
|
+
"completed",
|
|
3136
|
+
"failed",
|
|
3137
|
+
"cancelled",
|
|
3138
|
+
"timeout",
|
|
3139
|
+
"not_started",
|
|
3140
|
+
"unknown",
|
|
3141
|
+
"success",
|
|
3142
|
+
"error"
|
|
3143
|
+
].includes(text);
|
|
3144
|
+
}
|
|
3145
|
+
if (key === "integration") return text === "github" || text === "gmail";
|
|
3146
|
+
if (key === "operation") return ["read", "mutation", "token"].includes(text);
|
|
3147
|
+
return false;
|
|
3148
|
+
}
|
|
3149
|
+
function recordMetric(sink, name, value, labels) {
|
|
3150
|
+
if (!Number.isFinite(value)) return;
|
|
3151
|
+
if (sink === NOOP_METRICS) return;
|
|
3152
|
+
if (!Object.hasOwn(METRIC_UNITS, name)) return;
|
|
3153
|
+
const sanitized = {};
|
|
3154
|
+
const allowed = ALLOWED_LABELS[name];
|
|
3155
|
+
const supplied = Object.keys(labels);
|
|
3156
|
+
if (supplied.length !== allowed.length || supplied.some((key) => !allowed.includes(key))) return;
|
|
3157
|
+
for (const key of allowed) {
|
|
3158
|
+
const raw = labels[key];
|
|
3159
|
+
if (!validLabel(key, raw)) return;
|
|
3160
|
+
sanitized[key] = raw;
|
|
3161
|
+
}
|
|
3162
|
+
const measurement = Object.freeze({
|
|
3163
|
+
name,
|
|
3164
|
+
value,
|
|
3165
|
+
unit: METRIC_UNITS[name],
|
|
3166
|
+
labels: Object.freeze(sanitized)
|
|
3167
|
+
});
|
|
3168
|
+
try {
|
|
3169
|
+
const pending = sink.record(measurement);
|
|
3170
|
+
if (pending !== void 0) void Promise.resolve(pending).catch(() => void 0);
|
|
3171
|
+
} catch {
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3174
|
+
var NOOP_SPAN = Object.freeze({
|
|
3175
|
+
setAttribute: () => {
|
|
3176
|
+
},
|
|
3177
|
+
recordError: () => {
|
|
3178
|
+
},
|
|
3179
|
+
end: () => {
|
|
3180
|
+
}
|
|
3181
|
+
});
|
|
3182
|
+
var NOOP_METRICS = Object.freeze({ record: () => {
|
|
3183
|
+
} });
|
|
3184
|
+
var NOOP_TRACE = Object.freeze({ startSpan: () => NOOP_SPAN });
|
|
3185
|
+
function validTraceAttribute(name, value) {
|
|
3186
|
+
if (typeof value !== "string") return false;
|
|
3187
|
+
if (name === "integration.name") return value === "github" || value === "gmail";
|
|
3188
|
+
if (name === "integration.operation") {
|
|
3189
|
+
return value === "read" || value === "mutation" || value === "token";
|
|
3190
|
+
}
|
|
3191
|
+
if (name === "http.status_family") return /^(?:[1-5]xx|none)$/.test(value);
|
|
3192
|
+
return true;
|
|
3193
|
+
}
|
|
3194
|
+
function startSpan(sink, name, attributes = {}) {
|
|
3195
|
+
if (sink === NOOP_TRACE) return NOOP_SPAN;
|
|
3196
|
+
if (!SPAN_NAMES.has(name)) return NOOP_SPAN;
|
|
3197
|
+
let safeAttributes;
|
|
3198
|
+
try {
|
|
3199
|
+
const entries = Object.entries(attributes);
|
|
3200
|
+
if (entries.some(
|
|
3201
|
+
([key, value]) => !TRACE_ATTRIBUTES.has(key) || !validTraceAttribute(key, value)
|
|
3202
|
+
)) {
|
|
3203
|
+
return NOOP_SPAN;
|
|
3204
|
+
}
|
|
3205
|
+
safeAttributes = Object.freeze(Object.fromEntries(entries));
|
|
3206
|
+
} catch {
|
|
3207
|
+
return NOOP_SPAN;
|
|
3208
|
+
}
|
|
3209
|
+
let inner;
|
|
3210
|
+
try {
|
|
3211
|
+
inner = sink.startSpan(name, safeAttributes);
|
|
3212
|
+
} catch {
|
|
3213
|
+
return NOOP_SPAN;
|
|
3214
|
+
}
|
|
3215
|
+
let ended = false;
|
|
3216
|
+
return {
|
|
3217
|
+
setAttribute(attributeName, value) {
|
|
3218
|
+
if (ended) return;
|
|
3219
|
+
if (!TRACE_ATTRIBUTES.has(attributeName) || !validTraceAttribute(attributeName, value))
|
|
3220
|
+
return;
|
|
3221
|
+
try {
|
|
3222
|
+
inner.setAttribute(attributeName, value);
|
|
3223
|
+
} catch {
|
|
3224
|
+
}
|
|
3225
|
+
},
|
|
3226
|
+
recordError(error) {
|
|
3227
|
+
if (ended) return;
|
|
3228
|
+
try {
|
|
3229
|
+
const kind = error instanceof Error ? error.name : typeof error;
|
|
3230
|
+
inner.recordError(new Error(`${kind}: details redacted`));
|
|
3231
|
+
} catch {
|
|
3232
|
+
}
|
|
3233
|
+
},
|
|
3234
|
+
end() {
|
|
3235
|
+
if (ended) return;
|
|
3236
|
+
ended = true;
|
|
3237
|
+
try {
|
|
3238
|
+
inner.end();
|
|
3239
|
+
} catch {
|
|
3240
|
+
}
|
|
3241
|
+
}
|
|
3242
|
+
};
|
|
3243
|
+
}
|
|
3244
|
+
function providerFamily(provider) {
|
|
3245
|
+
try {
|
|
3246
|
+
const declared = provider.providerFamily;
|
|
3247
|
+
if (declared === "openai" || declared === "anthropic" || declared === "custom") {
|
|
3248
|
+
return declared;
|
|
3249
|
+
}
|
|
3250
|
+
const name = provider.constructor?.name.toLowerCase() ?? "";
|
|
3251
|
+
if (name.includes("openai")) return "openai";
|
|
3252
|
+
if (name.includes("anthropic")) return "anthropic";
|
|
3253
|
+
} catch {
|
|
3254
|
+
}
|
|
3255
|
+
return "custom";
|
|
3256
|
+
}
|
|
3257
|
+
|
|
3258
|
+
// src/sessions/replay.ts
|
|
3259
|
+
function approvalKey(turnId, toolCallId, toolName) {
|
|
3260
|
+
return JSON.stringify([turnId, toolCallId, toolName]);
|
|
3261
|
+
}
|
|
3262
|
+
var lastAssistantIndexes = /* @__PURE__ */ new WeakMap();
|
|
3263
|
+
function cloneSessionState(state) {
|
|
3264
|
+
const snapshot = structuredClone(state);
|
|
3265
|
+
const lastAssistantIndex = lastAssistantIndexes.get(state);
|
|
3266
|
+
if (lastAssistantIndex !== void 0) {
|
|
3267
|
+
lastAssistantIndexes.set(snapshot, lastAssistantIndex);
|
|
3268
|
+
}
|
|
3269
|
+
return snapshot;
|
|
3270
|
+
}
|
|
3271
|
+
function createSessionState(sessionId) {
|
|
3272
|
+
return {
|
|
3273
|
+
sessionId,
|
|
3274
|
+
isActive: false,
|
|
3275
|
+
messages: [],
|
|
3276
|
+
pendingApprovals: /* @__PURE__ */ new Set(),
|
|
3277
|
+
approvedApprovals: /* @__PURE__ */ new Set(),
|
|
3278
|
+
rejectedApprovals: /* @__PURE__ */ new Map(),
|
|
3279
|
+
totalTokens: { input: 0, output: 0 },
|
|
3280
|
+
totalCostUsd: 0
|
|
3281
|
+
};
|
|
3282
|
+
}
|
|
3283
|
+
function replaySession(events) {
|
|
3284
|
+
const validated = events.map(validateStoredEvent);
|
|
3285
|
+
const first = validated[0];
|
|
3286
|
+
if (first === void 0) {
|
|
3287
|
+
throw new Error("Cannot replay empty event log");
|
|
3288
|
+
}
|
|
3289
|
+
if (validated.some((event2) => event2.session_id !== first.session_id)) {
|
|
3290
|
+
throw new Error("Cannot replay events from mixed sessions");
|
|
3291
|
+
}
|
|
3292
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3293
|
+
let previous = 0;
|
|
3294
|
+
for (const event2 of validated) {
|
|
3295
|
+
if (!Number.isInteger(event2.sequence) || event2.sequence <= 0) {
|
|
3296
|
+
throw new Error("Stored event sequence must be a positive integer");
|
|
3297
|
+
}
|
|
3298
|
+
if (seen.has(event2.sequence)) throw new Error(`Duplicate event sequence ${event2.sequence}`);
|
|
3299
|
+
if (event2.sequence < previous) {
|
|
3300
|
+
throw new Error(`Non-monotonic event sequence ${event2.sequence} after ${previous}`);
|
|
3301
|
+
}
|
|
3302
|
+
seen.add(event2.sequence);
|
|
3303
|
+
previous = event2.sequence;
|
|
3304
|
+
}
|
|
3305
|
+
const state = createSessionState(first.session_id);
|
|
3306
|
+
for (const event2 of validated) applyEvent(state, event2);
|
|
3307
|
+
return state;
|
|
3308
|
+
}
|
|
3309
|
+
function applyEvent(state, event2) {
|
|
3310
|
+
if (event2.session_id !== state.sessionId) {
|
|
3311
|
+
throw new Error("Cannot project events from mixed sessions");
|
|
3312
|
+
}
|
|
3313
|
+
return applyKajiEvent(state, event2);
|
|
3314
|
+
}
|
|
3315
|
+
function applyKajiEvent(state, event2) {
|
|
3316
|
+
switch (event2.type) {
|
|
3317
|
+
case EventType.SESSION_CREATED:
|
|
3318
|
+
state.isActive = true;
|
|
3319
|
+
break;
|
|
3320
|
+
case EventType.SESSION_CLOSED:
|
|
3321
|
+
state.isActive = false;
|
|
3322
|
+
break;
|
|
3323
|
+
case EventType.AGENT_REASONING_STARTED:
|
|
3324
|
+
lastAssistantIndexes.delete(state);
|
|
3325
|
+
break;
|
|
3326
|
+
case EventType.USER_MESSAGE:
|
|
3327
|
+
state.messages.push({ role: "user", content: event2.content });
|
|
3328
|
+
lastAssistantIndexes.delete(state);
|
|
3329
|
+
return state.messages.length - 1;
|
|
3330
|
+
case EventType.AGENT_MESSAGE_COMPLETED:
|
|
3331
|
+
{
|
|
3332
|
+
const lastAssistant = { role: "assistant", content: event2.content };
|
|
3333
|
+
state.messages.push(lastAssistant);
|
|
3334
|
+
lastAssistantIndexes.set(state, state.messages.length - 1);
|
|
3335
|
+
}
|
|
3336
|
+
if (event2.tokens) {
|
|
3337
|
+
state.totalTokens.input += event2.tokens.input;
|
|
3338
|
+
state.totalTokens.output += event2.tokens.output;
|
|
3339
|
+
}
|
|
3340
|
+
if (event2.cost_usd) {
|
|
3341
|
+
state.totalCostUsd += event2.cost_usd;
|
|
3342
|
+
}
|
|
3343
|
+
return state.messages.length - 1;
|
|
3344
|
+
case EventType.TRANSCRIPT_FINAL:
|
|
3345
|
+
state.messages.push({ role: "user", content: event2.text });
|
|
3346
|
+
lastAssistantIndexes.delete(state);
|
|
3347
|
+
return state.messages.length - 1;
|
|
3348
|
+
case EventType.TOOL_CALL_REQUESTED: {
|
|
3349
|
+
let lastAssistantIndex = lastAssistantIndexes.get(state);
|
|
3350
|
+
if (lastAssistantIndex === void 0) {
|
|
3351
|
+
state.messages.push({ role: "assistant", content: "", toolCalls: [] });
|
|
3352
|
+
lastAssistantIndex = state.messages.length - 1;
|
|
3353
|
+
lastAssistantIndexes.set(state, lastAssistantIndex);
|
|
3354
|
+
}
|
|
3355
|
+
const lastAssistant = state.messages[lastAssistantIndex];
|
|
3356
|
+
lastAssistant.toolCalls ??= [];
|
|
3357
|
+
lastAssistant.toolCalls.push({
|
|
3358
|
+
id: event2.tool_call_id,
|
|
3359
|
+
name: event2.tool_name,
|
|
3360
|
+
args: structuredClone(event2.tool_args)
|
|
3361
|
+
});
|
|
3362
|
+
return lastAssistantIndex;
|
|
3363
|
+
}
|
|
3364
|
+
case EventType.TOOL_CALL_COMPLETED:
|
|
3365
|
+
state.messages.push({
|
|
3366
|
+
role: "tool",
|
|
3367
|
+
name: event2.tool_name,
|
|
3368
|
+
content: stringifyResult(event2.result),
|
|
3369
|
+
// H3: carry the real tool_call_id through so buildMessages can
|
|
3370
|
+
// reference it; a real provider rejects a tool result whose id does
|
|
3371
|
+
// not match the originating request.
|
|
3372
|
+
toolCallId: event2.tool_call_id
|
|
3373
|
+
});
|
|
3374
|
+
return state.messages.length - 1;
|
|
3375
|
+
case EventType.TOOL_CALL_FAILED:
|
|
3376
|
+
state.messages.push({
|
|
3377
|
+
role: "tool",
|
|
3378
|
+
name: event2.tool_name,
|
|
3379
|
+
content: `Error: ${event2.error}`,
|
|
3380
|
+
toolCallId: event2.tool_call_id
|
|
3381
|
+
});
|
|
3382
|
+
if (event2.turn_id !== void 0) {
|
|
3383
|
+
state.pendingApprovals.delete(
|
|
3384
|
+
approvalKey(event2.turn_id, event2.tool_call_id, event2.tool_name)
|
|
3385
|
+
);
|
|
3386
|
+
}
|
|
3387
|
+
return state.messages.length - 1;
|
|
3388
|
+
case EventType.TOOL_APPROVAL_REQUESTED:
|
|
3389
|
+
{
|
|
3390
|
+
const key = approvalKey(event2.turn_id, event2.tool_call_id, event2.tool_name);
|
|
3391
|
+
if (!state.approvedApprovals.has(key) && !state.rejectedApprovals.has(key)) {
|
|
3392
|
+
state.pendingApprovals.add(key);
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
break;
|
|
3396
|
+
case EventType.TOOL_APPROVAL_APPROVED:
|
|
3397
|
+
{
|
|
3398
|
+
const key = approvalKey(event2.turn_id, event2.tool_call_id, event2.tool_name);
|
|
3399
|
+
if (state.pendingApprovals.delete(key)) state.approvedApprovals.add(key);
|
|
3400
|
+
}
|
|
3401
|
+
break;
|
|
3402
|
+
case EventType.TOOL_APPROVAL_REJECTED:
|
|
3403
|
+
{
|
|
3404
|
+
const key = approvalKey(event2.turn_id, event2.tool_call_id, event2.tool_name);
|
|
3405
|
+
if (state.pendingApprovals.delete(key)) {
|
|
3406
|
+
state.rejectedApprovals.set(key, event2.error_code);
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
break;
|
|
3410
|
+
}
|
|
3411
|
+
return null;
|
|
3412
|
+
}
|
|
3413
|
+
function stringifyResult(result) {
|
|
3414
|
+
return canonicalJsonValue(result, "tool result");
|
|
3415
|
+
}
|
|
3416
|
+
|
|
3417
|
+
// src/runtime/limits.ts
|
|
3418
|
+
var DEFAULT_TURN_EXECUTION_LIMITS = Object.freeze({
|
|
3419
|
+
turnTimeoutMs: 12e4,
|
|
3420
|
+
providerCancellationGraceMs: 5e3,
|
|
3421
|
+
providerTextMaxBytes: 262144,
|
|
3422
|
+
providerToolArgumentsMaxBytes: 65536,
|
|
3423
|
+
providerResponseMaxBytes: 524288,
|
|
3424
|
+
providerToolCallsMax: 64
|
|
3425
|
+
});
|
|
3426
|
+
function resolveTurnExecutionLimits(overrides = {}) {
|
|
3427
|
+
const limits = { ...DEFAULT_TURN_EXECUTION_LIMITS, ...overrides };
|
|
3428
|
+
for (const [name, value] of Object.entries(limits)) {
|
|
3429
|
+
if (!Number.isInteger(value) || value < 1) {
|
|
3430
|
+
throw new RangeError(`${name} must be a positive integer`);
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
return Object.freeze(limits);
|
|
3434
|
+
}
|
|
3435
|
+
var TurnTimeoutError = class extends Error {
|
|
3436
|
+
constructor(phase, retryable, outcome) {
|
|
3437
|
+
super(`Turn deadline exceeded during ${phase}`);
|
|
3438
|
+
this.phase = phase;
|
|
3439
|
+
this.retryable = retryable;
|
|
3440
|
+
this.outcome = outcome;
|
|
3441
|
+
if (typeof retryable !== "boolean") throw new TypeError("retryable must be a boolean");
|
|
3442
|
+
if (!["queue", "provider_open", "provider_stream", "approval", "tool"].includes(phase)) {
|
|
3443
|
+
throw new TypeError("phase must be a supported turn phase");
|
|
3444
|
+
}
|
|
3445
|
+
if (!["not_started", "failed", "unknown"].includes(outcome)) {
|
|
3446
|
+
throw new TypeError("outcome must be a supported turn outcome");
|
|
3447
|
+
}
|
|
3448
|
+
this.name = "TurnTimeoutError";
|
|
3449
|
+
}
|
|
3450
|
+
phase;
|
|
3451
|
+
retryable;
|
|
3452
|
+
outcome;
|
|
3453
|
+
code = "TURN_TIMEOUT";
|
|
3454
|
+
};
|
|
3455
|
+
var ProviderCancellationContractViolation = class extends Error {
|
|
3456
|
+
constructor(phase = "provider_stream") {
|
|
3457
|
+
super("Provider did not stop after cancellation");
|
|
3458
|
+
this.phase = phase;
|
|
3459
|
+
this.name = "ProviderCancellationContractViolation";
|
|
3460
|
+
}
|
|
3461
|
+
phase;
|
|
3462
|
+
code = "PROVIDER_CANCELLATION_CONTRACT_VIOLATION";
|
|
3463
|
+
retryable = false;
|
|
3464
|
+
outcome = "unknown";
|
|
3465
|
+
};
|
|
3466
|
+
var PROVIDER_VIOLATION_DETAILS = /* @__PURE__ */ new WeakMap();
|
|
3467
|
+
function attachProviderViolationSettlement(error, settlement) {
|
|
3468
|
+
PROVIDER_VIOLATION_DETAILS.set(error, { settlement });
|
|
3469
|
+
return error;
|
|
3470
|
+
}
|
|
3471
|
+
function providerViolationSettlement(error) {
|
|
3472
|
+
return PROVIDER_VIOLATION_DETAILS.get(error)?.settlement;
|
|
3473
|
+
}
|
|
3474
|
+
|
|
3475
|
+
// src/runtime/cancellation.ts
|
|
3476
|
+
var CancellationError = class extends Error {
|
|
3477
|
+
constructor(message = "Agent run was cancelled") {
|
|
3478
|
+
super(message);
|
|
3479
|
+
this.name = "CancellationError";
|
|
3480
|
+
}
|
|
3481
|
+
};
|
|
3482
|
+
function throwIfCancellationRequested(token) {
|
|
3483
|
+
if (!token?.isCancelled) return;
|
|
3484
|
+
if (typeof token.throwIfCancelled === "function") {
|
|
3485
|
+
token.throwIfCancelled();
|
|
3486
|
+
}
|
|
3487
|
+
throw new CancellationError();
|
|
3488
|
+
}
|
|
3489
|
+
function isCancellationCompatible(error) {
|
|
3490
|
+
return error instanceof CancellationError || typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
|
|
3491
|
+
}
|
|
3492
|
+
var CancellationToken = class {
|
|
3493
|
+
controller = new AbortController();
|
|
3494
|
+
/** Whether `cancel()` has been called. */
|
|
3495
|
+
get isCancelled() {
|
|
3496
|
+
return this.controller.signal.aborted;
|
|
3497
|
+
}
|
|
3498
|
+
/**
|
|
3499
|
+
* The underlying `AbortSignal`. Pass this directly to APIs that accept
|
|
3500
|
+
* one (the OpenAI / Anthropic SDKs, `fetch`, etc.) so the network call
|
|
3501
|
+
* aborts on cancel instead of just polling out at the next yield point.
|
|
3502
|
+
*/
|
|
3503
|
+
get signal() {
|
|
3504
|
+
return this.controller.signal;
|
|
3505
|
+
}
|
|
3506
|
+
cancel() {
|
|
3507
|
+
if (!this.controller.signal.aborted) {
|
|
3508
|
+
this.controller.abort();
|
|
3509
|
+
}
|
|
3510
|
+
}
|
|
3511
|
+
throwIfCancelled() {
|
|
3512
|
+
if (this.controller.signal.aborted) {
|
|
3513
|
+
throw new CancellationError();
|
|
3514
|
+
}
|
|
3515
|
+
}
|
|
3516
|
+
};
|
|
3517
|
+
var DeadlineCancellationScope = class {
|
|
3518
|
+
constructor(parent, deadlineMonotonicMs, cancellationGraceMs, clock, scheduler) {
|
|
3519
|
+
this.parent = parent;
|
|
3520
|
+
this.deadlineMonotonicMs = deadlineMonotonicMs;
|
|
3521
|
+
this.cancellationGraceMs = cancellationGraceMs;
|
|
3522
|
+
this.clock = clock;
|
|
3523
|
+
this.scheduler = scheduler;
|
|
3524
|
+
if (!Number.isFinite(deadlineMonotonicMs) || deadlineMonotonicMs < 0) {
|
|
3525
|
+
throw new RangeError("deadlineMonotonicMs must be a finite non-negative number");
|
|
3526
|
+
}
|
|
3527
|
+
if (!Number.isFinite(cancellationGraceMs) || cancellationGraceMs <= 0) {
|
|
3528
|
+
throw new RangeError("cancellationGraceMs must be a positive finite number");
|
|
3529
|
+
}
|
|
3530
|
+
this.deadlineWake = new Promise((resolve) => {
|
|
3531
|
+
this.resolveDeadline = resolve;
|
|
3532
|
+
});
|
|
3533
|
+
this.parentWake = new Promise((resolve) => {
|
|
3534
|
+
this.resolveParent = resolve;
|
|
3535
|
+
});
|
|
3536
|
+
this.parentAbort = () => {
|
|
3537
|
+
this.requestCancellation("parent");
|
|
3538
|
+
this.resolveParent();
|
|
3539
|
+
};
|
|
3540
|
+
parent.signal.addEventListener("abort", this.parentAbort, { once: true });
|
|
3541
|
+
if (parent.isCancelled) this.parentAbort();
|
|
3542
|
+
this.deadlineTimer = scheduler.schedule(
|
|
3543
|
+
Math.max(0, deadlineMonotonicMs - clock.nowMonotonic()),
|
|
3544
|
+
() => {
|
|
3545
|
+
this.requestCancellation("deadline");
|
|
3546
|
+
this.resolveDeadline();
|
|
3547
|
+
}
|
|
3548
|
+
);
|
|
3549
|
+
}
|
|
3550
|
+
parent;
|
|
3551
|
+
deadlineMonotonicMs;
|
|
3552
|
+
cancellationGraceMs;
|
|
3553
|
+
clock;
|
|
3554
|
+
scheduler;
|
|
3555
|
+
token = new CancellationToken();
|
|
3556
|
+
deadlineWake;
|
|
3557
|
+
parentWake;
|
|
3558
|
+
resolveDeadline;
|
|
3559
|
+
resolveParent;
|
|
3560
|
+
parentAbort;
|
|
3561
|
+
deadlineTimer;
|
|
3562
|
+
iterator;
|
|
3563
|
+
activeNext;
|
|
3564
|
+
closePromise;
|
|
3565
|
+
transferred = false;
|
|
3566
|
+
yielded = false;
|
|
3567
|
+
dispatched = false;
|
|
3568
|
+
cancellationRequestedAtMs;
|
|
3569
|
+
cancellationSource;
|
|
3570
|
+
async *consume(stream) {
|
|
3571
|
+
this.iterator = stream[Symbol.asyncIterator]();
|
|
3572
|
+
let providerError;
|
|
3573
|
+
try {
|
|
3574
|
+
while (true) {
|
|
3575
|
+
if (this.parent.isCancelled) await this.abort(void 0, true, "parent");
|
|
3576
|
+
if (this.clock.nowMonotonic() >= this.deadlineMonotonicMs) {
|
|
3577
|
+
await this.abort(void 0, false, "deadline");
|
|
3578
|
+
}
|
|
3579
|
+
if (this.token.isCancelled && this.cancellationSource === void 0) {
|
|
3580
|
+
await this.abort(void 0, true, "provider");
|
|
3581
|
+
}
|
|
3582
|
+
this.dispatched = true;
|
|
3583
|
+
const next = this.iterator.next();
|
|
3584
|
+
this.activeNext = next;
|
|
3585
|
+
const settlementEvidence = () => ({
|
|
3586
|
+
settledAtMs: this.clock.nowMonotonic(),
|
|
3587
|
+
cancellationSource: this.cancellationSource,
|
|
3588
|
+
parentCancelled: this.parent.isCancelled,
|
|
3589
|
+
tokenCancelled: this.token.isCancelled
|
|
3590
|
+
});
|
|
3591
|
+
const providerResult = next.then(
|
|
3592
|
+
(result) => ({ status: "settled", result, ...settlementEvidence() }),
|
|
3593
|
+
(error) => ({ status: "failed", error, ...settlementEvidence() })
|
|
3594
|
+
);
|
|
3595
|
+
const wake = await Promise.race([
|
|
3596
|
+
providerResult,
|
|
3597
|
+
this.deadlineWake.then(() => ({ status: "deadline" })),
|
|
3598
|
+
this.parentWake.then(() => ({ status: "parent" }))
|
|
3599
|
+
]);
|
|
3600
|
+
if (wake.status === "failed") {
|
|
3601
|
+
if ((wake.parentCancelled || wake.cancellationSource === "parent") && isCancellationCompatible(wake.error)) {
|
|
3602
|
+
await this.abort(next, true, "parent");
|
|
3603
|
+
}
|
|
3604
|
+
if (wake.cancellationSource === "deadline" || wake.settledAtMs >= this.deadlineMonotonicMs) {
|
|
3605
|
+
await this.abort(next, false, "deadline");
|
|
3606
|
+
}
|
|
3607
|
+
if (wake.cancellationSource === "provider" || wake.tokenCancelled && wake.cancellationSource === void 0) {
|
|
3608
|
+
await this.abort(next, true, "provider");
|
|
3609
|
+
}
|
|
3610
|
+
this.activeNext = void 0;
|
|
3611
|
+
throw wake.error;
|
|
3612
|
+
}
|
|
3613
|
+
if (this.parent.isCancelled) await this.abort(next, true, "parent");
|
|
3614
|
+
if (wake.status === "deadline" || this.clock.nowMonotonic() >= this.deadlineMonotonicMs) {
|
|
3615
|
+
await this.abort(next, false, "deadline");
|
|
3616
|
+
}
|
|
3617
|
+
if (this.token.isCancelled && this.cancellationSource === void 0) {
|
|
3618
|
+
await this.abort(next, true, "provider");
|
|
3619
|
+
}
|
|
3620
|
+
if (wake.status !== "settled") continue;
|
|
3621
|
+
this.activeNext = void 0;
|
|
3622
|
+
if (wake.result.done) return;
|
|
3623
|
+
this.yielded = true;
|
|
3624
|
+
yield wake.result.value;
|
|
3625
|
+
}
|
|
3626
|
+
} catch (error) {
|
|
3627
|
+
if (error instanceof ProviderCancellationContractViolation) {
|
|
3628
|
+
this.transferred = true;
|
|
3629
|
+
} else {
|
|
3630
|
+
providerError = error;
|
|
3631
|
+
}
|
|
3632
|
+
throw error;
|
|
3633
|
+
} finally {
|
|
3634
|
+
if (!this.transferred) {
|
|
3635
|
+
try {
|
|
3636
|
+
await this.finishClose();
|
|
3637
|
+
} catch (closeError) {
|
|
3638
|
+
if (closeError instanceof ProviderCancellationContractViolation) {
|
|
3639
|
+
this.transferred = true;
|
|
3640
|
+
if (providerError !== void 0 && closeError.cause === void 0) {
|
|
3641
|
+
Object.defineProperty(closeError, "cause", {
|
|
3642
|
+
value: providerError,
|
|
3643
|
+
configurable: true
|
|
3644
|
+
});
|
|
3645
|
+
}
|
|
3646
|
+
throw closeError;
|
|
3647
|
+
}
|
|
3648
|
+
if (providerError === void 0) throw closeError;
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
dispose() {
|
|
3654
|
+
this.deadlineTimer.cancel();
|
|
3655
|
+
this.parent.signal.removeEventListener("abort", this.parentAbort);
|
|
3656
|
+
}
|
|
3657
|
+
async abort(active, callerCancelled, source) {
|
|
3658
|
+
this.requestCancellation(source);
|
|
3659
|
+
const settlement = Promise.resolve(active).catch(() => void 0).then(() => this.closeOnce());
|
|
3660
|
+
let graceTimer;
|
|
3661
|
+
const grace = new Promise((resolve) => {
|
|
3662
|
+
const requestedAt = this.cancellationRequestedAtMs ?? this.clock.nowMonotonic();
|
|
3663
|
+
const remaining = Math.max(
|
|
3664
|
+
0,
|
|
3665
|
+
requestedAt + this.cancellationGraceMs - this.clock.nowMonotonic()
|
|
3666
|
+
);
|
|
3667
|
+
graceTimer = this.scheduler.schedule(remaining, () => resolve({ status: "grace" }));
|
|
3668
|
+
});
|
|
3669
|
+
try {
|
|
3670
|
+
const result = await Promise.race([
|
|
3671
|
+
settlement.then(
|
|
3672
|
+
() => ({ status: "settled" }),
|
|
3673
|
+
() => ({ status: "failed" })
|
|
3674
|
+
),
|
|
3675
|
+
grace
|
|
3676
|
+
]);
|
|
3677
|
+
if (result.status === "settled") {
|
|
3678
|
+
if (callerCancelled) throw new CancellationError();
|
|
3679
|
+
throw new TurnTimeoutError(
|
|
3680
|
+
this.yielded ? "provider_stream" : "provider_open",
|
|
3681
|
+
true,
|
|
3682
|
+
this.dispatched ? "unknown" : "not_started"
|
|
3683
|
+
);
|
|
3684
|
+
}
|
|
3685
|
+
if (result.status === "failed") {
|
|
3686
|
+
this.transferred = true;
|
|
3687
|
+
throw this.contractViolation(settlement);
|
|
3688
|
+
}
|
|
3689
|
+
this.transferred = true;
|
|
3690
|
+
throw this.contractViolation(settlement);
|
|
3691
|
+
} finally {
|
|
3692
|
+
graceTimer?.cancel();
|
|
3693
|
+
}
|
|
3694
|
+
}
|
|
3695
|
+
closeOnce() {
|
|
3696
|
+
if (this.closePromise !== void 0) return this.closePromise;
|
|
3697
|
+
const iterator = this.iterator;
|
|
3698
|
+
this.closePromise = (async () => {
|
|
3699
|
+
if (this.activeNext !== void 0) {
|
|
3700
|
+
try {
|
|
3701
|
+
await this.activeNext;
|
|
3702
|
+
} catch {
|
|
3703
|
+
}
|
|
3704
|
+
}
|
|
3705
|
+
await iterator?.return?.();
|
|
3706
|
+
})();
|
|
3707
|
+
return this.closePromise;
|
|
3708
|
+
}
|
|
3709
|
+
async finishClose() {
|
|
3710
|
+
if (this.iterator === void 0) return;
|
|
3711
|
+
const close = this.closeOnce();
|
|
3712
|
+
const settled = close.then(
|
|
3713
|
+
() => ({ status: "settled" }),
|
|
3714
|
+
() => ({ status: "failed" })
|
|
3715
|
+
);
|
|
3716
|
+
const wake = await Promise.race([
|
|
3717
|
+
settled,
|
|
3718
|
+
this.deadlineWake.then(() => ({ status: "deadline" })),
|
|
3719
|
+
this.parentWake.then(() => ({ status: "parent" }))
|
|
3720
|
+
]);
|
|
3721
|
+
if (wake.status === "settled") return;
|
|
3722
|
+
if (wake.status === "failed") {
|
|
3723
|
+
this.transferred = true;
|
|
3724
|
+
throw this.contractViolation(close);
|
|
3725
|
+
}
|
|
3726
|
+
if (this.parent.isCancelled) await this.abort(this.activeNext, true, "parent");
|
|
3727
|
+
if (wake.status === "deadline" || this.clock.nowMonotonic() >= this.deadlineMonotonicMs) {
|
|
3728
|
+
await this.abort(this.activeNext, false, "deadline");
|
|
3729
|
+
}
|
|
3730
|
+
await close;
|
|
3731
|
+
}
|
|
3732
|
+
requestCancellation(source) {
|
|
3733
|
+
if (this.cancellationRequestedAtMs === void 0) {
|
|
3734
|
+
this.cancellationRequestedAtMs = this.clock.nowMonotonic();
|
|
3735
|
+
}
|
|
3736
|
+
this.cancellationSource ??= source;
|
|
3737
|
+
this.token.cancel();
|
|
3738
|
+
}
|
|
3739
|
+
contractViolation(settlement) {
|
|
3740
|
+
const phase = this.yielded ? "provider_stream" : "provider_open";
|
|
3741
|
+
return attachProviderViolationSettlement(
|
|
3742
|
+
new ProviderCancellationContractViolation(phase),
|
|
3743
|
+
settlement
|
|
3744
|
+
);
|
|
3745
|
+
}
|
|
3746
|
+
};
|
|
3747
|
+
function createDeadlineCancellationScope(parent, deadlineMonotonicMs, cancellationGraceMs, clock, scheduler) {
|
|
3748
|
+
return new DeadlineCancellationScope(
|
|
3749
|
+
parent,
|
|
3750
|
+
deadlineMonotonicMs,
|
|
3751
|
+
cancellationGraceMs,
|
|
3752
|
+
clock,
|
|
3753
|
+
scheduler
|
|
3754
|
+
);
|
|
3755
|
+
}
|
|
3756
|
+
|
|
3757
|
+
// src/providers/base.ts
|
|
3758
|
+
var PROVIDER_RESPONSE_DIAGNOSTICS = /* @__PURE__ */ Symbol.for(
|
|
3759
|
+
"kaji.provider.responseDiagnostics"
|
|
3760
|
+
);
|
|
3761
|
+
function withProviderResponseDiagnostics(options, sink) {
|
|
3762
|
+
const internal = { ...options };
|
|
3763
|
+
Object.defineProperty(internal, PROVIDER_RESPONSE_DIAGNOSTICS, {
|
|
3764
|
+
value: sink,
|
|
3765
|
+
enumerable: false
|
|
3766
|
+
});
|
|
3767
|
+
return internal;
|
|
3768
|
+
}
|
|
3769
|
+
function getProviderResponseDiagnostics(options) {
|
|
3770
|
+
return options?.[PROVIDER_RESPONSE_DIAGNOSTICS];
|
|
3771
|
+
}
|
|
3772
|
+
var DEFAULT_PROVIDER_RESPONSE_LIMITS = Object.freeze({
|
|
3773
|
+
textMaxBytes: 262144,
|
|
3774
|
+
toolArgumentsMaxBytes: 65536,
|
|
3775
|
+
responseMaxBytes: 524288,
|
|
3776
|
+
toolCallsMax: 64
|
|
3777
|
+
});
|
|
3778
|
+
function resolveProviderResponseLimits(limits) {
|
|
3779
|
+
const resolved = { ...DEFAULT_PROVIDER_RESPONSE_LIMITS, ...limits };
|
|
3780
|
+
for (const [name, value] of Object.entries(resolved)) {
|
|
3781
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
3782
|
+
throw new RangeError(`${name} must be a positive safe integer`);
|
|
3783
|
+
}
|
|
3784
|
+
}
|
|
3785
|
+
return Object.freeze(resolved);
|
|
3786
|
+
}
|
|
3787
|
+
function parseRetryAfterMs(error) {
|
|
3788
|
+
if (typeof error !== "object" || error === null) return void 0;
|
|
3789
|
+
const headers = "headers" in error ? error.headers : "response" in error && typeof error.response === "object" ? error.response?.headers ?? null : null;
|
|
3790
|
+
if (typeof headers !== "object" || headers === null) return void 0;
|
|
3791
|
+
const retryAfter = headers["retry-after"];
|
|
3792
|
+
if (!retryAfter) return void 0;
|
|
3793
|
+
const seconds = Number(retryAfter);
|
|
3794
|
+
return Number.isFinite(seconds) ? seconds * 1e3 : void 0;
|
|
3795
|
+
}
|
|
3796
|
+
async function withRetry(fn, retry, cancellationToken, metricsSink = NOOP_METRICS, providerFamily2 = "custom") {
|
|
3797
|
+
const { maxAttempts, baseDelayMs } = retry;
|
|
3798
|
+
let lastError;
|
|
3799
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
3800
|
+
throwIfCancellationRequested(cancellationToken);
|
|
3801
|
+
try {
|
|
3802
|
+
return await fn();
|
|
3803
|
+
} catch (error) {
|
|
3804
|
+
const statusCode = typeof error === "object" && error !== null && "status" in error ? error.status : void 0;
|
|
3805
|
+
if (statusCode !== 429 || attempt === maxAttempts) {
|
|
3806
|
+
throw error;
|
|
3807
|
+
}
|
|
3808
|
+
const retryAfterMs = parseRetryAfterMs(error) ?? baseDelayMs * 2 ** (attempt - 1);
|
|
3809
|
+
recordMetric(metricsSink, "kaji.provider.retries", 1, {
|
|
3810
|
+
provider_family: providerFamily2
|
|
3811
|
+
});
|
|
3812
|
+
lastError = error;
|
|
3813
|
+
await cancellableDelay(retryAfterMs, cancellationToken);
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
throw lastError;
|
|
3817
|
+
}
|
|
3818
|
+
async function openStreamWithRetry(create, retry, cancellationToken, metricsSink = NOOP_METRICS, providerFamily2 = "custom") {
|
|
3819
|
+
const opened = await withRetry(
|
|
3820
|
+
async () => {
|
|
3821
|
+
const stream = await create();
|
|
3822
|
+
const iterator = stream[Symbol.asyncIterator]();
|
|
3823
|
+
try {
|
|
3824
|
+
return { iterator, first: await iterator.next() };
|
|
3825
|
+
} catch (error) {
|
|
3826
|
+
try {
|
|
3827
|
+
await iterator.return?.();
|
|
3828
|
+
} catch {
|
|
3829
|
+
}
|
|
3830
|
+
throw error;
|
|
3831
|
+
}
|
|
3832
|
+
},
|
|
3833
|
+
retry,
|
|
3834
|
+
cancellationToken,
|
|
3835
|
+
metricsSink,
|
|
3836
|
+
providerFamily2
|
|
3837
|
+
);
|
|
3838
|
+
return new BufferedAsyncIterator(opened.iterator, opened.first);
|
|
3839
|
+
}
|
|
3840
|
+
var BufferedAsyncIterator = class {
|
|
3841
|
+
constructor(inner, first) {
|
|
3842
|
+
this.inner = inner;
|
|
3843
|
+
this.first = first;
|
|
3844
|
+
}
|
|
3845
|
+
inner;
|
|
3846
|
+
first;
|
|
3847
|
+
firstPending = true;
|
|
3848
|
+
closed = false;
|
|
3849
|
+
closePromise;
|
|
3850
|
+
async next() {
|
|
3851
|
+
if (this.closed) return { value: void 0, done: true };
|
|
3852
|
+
if (this.firstPending) {
|
|
3853
|
+
this.firstPending = false;
|
|
3854
|
+
if (this.first.done) this.markNaturallyClosed();
|
|
3855
|
+
return this.first;
|
|
3856
|
+
}
|
|
3857
|
+
try {
|
|
3858
|
+
const next = await this.inner.next();
|
|
3859
|
+
if (next.done) this.markNaturallyClosed();
|
|
3860
|
+
return next;
|
|
3861
|
+
} catch (error) {
|
|
3862
|
+
try {
|
|
3863
|
+
await this.close();
|
|
3864
|
+
} catch {
|
|
3865
|
+
}
|
|
3866
|
+
throw error;
|
|
3867
|
+
}
|
|
3868
|
+
}
|
|
3869
|
+
async return(value) {
|
|
3870
|
+
await this.close();
|
|
3871
|
+
return { value, done: true };
|
|
3872
|
+
}
|
|
3873
|
+
async throw(error) {
|
|
3874
|
+
await this.close();
|
|
3875
|
+
throw error;
|
|
3876
|
+
}
|
|
3877
|
+
[Symbol.asyncIterator]() {
|
|
3878
|
+
return this;
|
|
3879
|
+
}
|
|
3880
|
+
markNaturallyClosed() {
|
|
3881
|
+
this.closed = true;
|
|
3882
|
+
this.closePromise = Promise.resolve();
|
|
3883
|
+
}
|
|
3884
|
+
close() {
|
|
3885
|
+
if (this.closePromise !== void 0) return this.closePromise;
|
|
3886
|
+
this.closed = true;
|
|
3887
|
+
this.firstPending = false;
|
|
3888
|
+
try {
|
|
3889
|
+
const result = this.inner.return?.();
|
|
3890
|
+
this.closePromise = Promise.resolve(result).then(() => void 0);
|
|
3891
|
+
} catch (error) {
|
|
3892
|
+
this.closePromise = Promise.reject(error);
|
|
3893
|
+
}
|
|
3894
|
+
return this.closePromise;
|
|
3895
|
+
}
|
|
3896
|
+
};
|
|
3897
|
+
async function cancellableDelay(delayMs, cancellationToken) {
|
|
3898
|
+
throwIfCancellationRequested(cancellationToken);
|
|
3899
|
+
if (cancellationToken === void 0) {
|
|
3900
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
3901
|
+
return;
|
|
3902
|
+
}
|
|
3903
|
+
const signal = cancellationToken?.signal;
|
|
3904
|
+
if (signal === void 0) {
|
|
3905
|
+
const deadline = globalThis.performance.now() + delayMs;
|
|
3906
|
+
while (globalThis.performance.now() < deadline) {
|
|
3907
|
+
throwIfCancellationRequested(cancellationToken);
|
|
3908
|
+
await new Promise(
|
|
3909
|
+
(resolve) => setTimeout(resolve, Math.min(10, deadline - globalThis.performance.now()))
|
|
3910
|
+
);
|
|
3911
|
+
}
|
|
3912
|
+
throwIfCancellationRequested(cancellationToken);
|
|
3913
|
+
return;
|
|
3914
|
+
}
|
|
3915
|
+
if (signal.aborted) throw new CancellationError();
|
|
3916
|
+
await new Promise((resolve, reject) => {
|
|
3917
|
+
const timer = setTimeout(() => {
|
|
3918
|
+
signal.removeEventListener("abort", onAbort);
|
|
3919
|
+
resolve();
|
|
3920
|
+
}, delayMs);
|
|
3921
|
+
const onAbort = () => {
|
|
3922
|
+
clearTimeout(timer);
|
|
3923
|
+
signal.removeEventListener("abort", onAbort);
|
|
3924
|
+
reject(new CancellationError());
|
|
3925
|
+
};
|
|
3926
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
3927
|
+
});
|
|
3928
|
+
}
|
|
3929
|
+
|
|
3930
|
+
// src/providers/errors.ts
|
|
3931
|
+
var PROVIDER_ERROR_BRAND = /* @__PURE__ */ Symbol.for("kaji.ProviderError.v1");
|
|
3932
|
+
var PROVIDER_CONFIG_ERROR_BRAND = /* @__PURE__ */ Symbol.for("kaji.ProviderConfigError.v1");
|
|
3933
|
+
var PROVIDER_API_ERROR_BRAND = /* @__PURE__ */ Symbol.for("kaji.ProviderAPIError.v1");
|
|
3934
|
+
var PROVIDER_CONNECTION_ERROR_BRAND = /* @__PURE__ */ Symbol.for("kaji.ProviderConnectionError.v1");
|
|
3935
|
+
var PROVIDER_RATE_LIMITED_ERROR_BRAND = /* @__PURE__ */ Symbol.for("kaji.ProviderRateLimitedError.v1");
|
|
3936
|
+
var PROVIDER_OUTPUT_LIMIT_ERROR_BRAND = /* @__PURE__ */ Symbol.for("kaji.ProviderOutputLimitError.v1");
|
|
3937
|
+
function brand(value, key) {
|
|
3938
|
+
Object.defineProperty(value, key, { value: true });
|
|
3939
|
+
}
|
|
3940
|
+
function hasBrand(value, key) {
|
|
3941
|
+
return typeof value === "object" && value !== null && Reflect.get(value, key) === true;
|
|
3942
|
+
}
|
|
3943
|
+
var ProviderError = class extends Error {
|
|
3944
|
+
service;
|
|
3945
|
+
action;
|
|
3946
|
+
statusCode;
|
|
3947
|
+
static [Symbol.hasInstance](value) {
|
|
3948
|
+
return hasBrand(value, PROVIDER_ERROR_BRAND);
|
|
3949
|
+
}
|
|
3950
|
+
constructor(message, options = {}) {
|
|
3951
|
+
super(message);
|
|
3952
|
+
brand(this, PROVIDER_ERROR_BRAND);
|
|
3953
|
+
this.name = new.target.name;
|
|
3954
|
+
this.service = options.service ?? "provider";
|
|
3955
|
+
this.action = options.action ?? "request";
|
|
3956
|
+
if (options.statusCode !== void 0) this.statusCode = options.statusCode;
|
|
3957
|
+
}
|
|
3958
|
+
};
|
|
3959
|
+
var ProviderConfigError = class extends ProviderError {
|
|
3960
|
+
static [Symbol.hasInstance](value) {
|
|
3961
|
+
return hasBrand(value, PROVIDER_CONFIG_ERROR_BRAND);
|
|
3962
|
+
}
|
|
3963
|
+
constructor(message, options = {}) {
|
|
3964
|
+
super(message, { ...options, action: "configure" });
|
|
3965
|
+
brand(this, PROVIDER_CONFIG_ERROR_BRAND);
|
|
3966
|
+
}
|
|
3967
|
+
};
|
|
3968
|
+
var ProviderAPIError = class extends ProviderError {
|
|
3969
|
+
static [Symbol.hasInstance](value) {
|
|
3970
|
+
return hasBrand(value, PROVIDER_API_ERROR_BRAND);
|
|
3971
|
+
}
|
|
3972
|
+
constructor(message, options = {}) {
|
|
3973
|
+
super(message, { ...options, action: options.action ?? "api call" });
|
|
3974
|
+
brand(this, PROVIDER_API_ERROR_BRAND);
|
|
3975
|
+
}
|
|
3976
|
+
};
|
|
3977
|
+
var ProviderConnectionError = class extends ProviderError {
|
|
3978
|
+
static [Symbol.hasInstance](value) {
|
|
3979
|
+
return hasBrand(value, PROVIDER_CONNECTION_ERROR_BRAND);
|
|
3980
|
+
}
|
|
3981
|
+
constructor(message, options = {}) {
|
|
3982
|
+
super(message, { ...options, action: options.action ?? "connect" });
|
|
3983
|
+
brand(this, PROVIDER_CONNECTION_ERROR_BRAND);
|
|
3984
|
+
}
|
|
3985
|
+
};
|
|
3986
|
+
var ProviderRateLimitedError = class extends ProviderError {
|
|
3987
|
+
retryAfterMs;
|
|
3988
|
+
attempts;
|
|
3989
|
+
static [Symbol.hasInstance](value) {
|
|
3990
|
+
return hasBrand(value, PROVIDER_RATE_LIMITED_ERROR_BRAND);
|
|
3991
|
+
}
|
|
3992
|
+
constructor(message, options) {
|
|
3993
|
+
super(message, { ...options, action: "api call", statusCode: 429 });
|
|
3994
|
+
brand(this, PROVIDER_RATE_LIMITED_ERROR_BRAND);
|
|
3995
|
+
this.retryAfterMs = options.retryAfterMs;
|
|
3996
|
+
this.attempts = options.attempts;
|
|
3997
|
+
}
|
|
3998
|
+
};
|
|
3999
|
+
var ProviderOutputLimitError = class extends Error {
|
|
4000
|
+
constructor(dimension, limit) {
|
|
4001
|
+
if (!["text", "tool_arguments", "total_response", "tool_calls"].includes(dimension)) {
|
|
4002
|
+
throw new TypeError("unknown provider output dimension");
|
|
4003
|
+
}
|
|
4004
|
+
if (!Number.isSafeInteger(limit) || limit < 1) {
|
|
4005
|
+
throw new RangeError("provider output limit must be a positive safe integer");
|
|
4006
|
+
}
|
|
4007
|
+
const unit = dimension === "tool_calls" ? "calls" : "bytes";
|
|
4008
|
+
super(`Provider output exceeded ${dimension} limit of ${limit} ${unit}`);
|
|
4009
|
+
this.dimension = dimension;
|
|
4010
|
+
this.limit = limit;
|
|
4011
|
+
brand(this, PROVIDER_OUTPUT_LIMIT_ERROR_BRAND);
|
|
4012
|
+
this.name = "ProviderOutputLimitError";
|
|
4013
|
+
}
|
|
4014
|
+
dimension;
|
|
4015
|
+
limit;
|
|
4016
|
+
code = "PROVIDER_OUTPUT_LIMIT";
|
|
4017
|
+
phase = "provider_stream";
|
|
4018
|
+
retryable = false;
|
|
4019
|
+
outcome = "unknown";
|
|
4020
|
+
static [Symbol.hasInstance](value) {
|
|
4021
|
+
return hasBrand(value, PROVIDER_OUTPUT_LIMIT_ERROR_BRAND);
|
|
4022
|
+
}
|
|
4023
|
+
};
|
|
4024
|
+
function errorStatusCode(error) {
|
|
4025
|
+
if (typeof error !== "object" || error === null) return void 0;
|
|
4026
|
+
const status = "status" in error ? error.status : void 0;
|
|
4027
|
+
const statusCode = "statusCode" in error ? error.statusCode : void 0;
|
|
4028
|
+
return typeof status === "number" ? status : typeof statusCode === "number" ? statusCode : void 0;
|
|
4029
|
+
}
|
|
4030
|
+
var NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
4031
|
+
"EAI_AGAIN",
|
|
4032
|
+
"ECONNABORTED",
|
|
4033
|
+
"ECONNREFUSED",
|
|
4034
|
+
"ECONNRESET",
|
|
4035
|
+
"ENETUNREACH",
|
|
4036
|
+
"ENOTFOUND",
|
|
4037
|
+
"ETIMEDOUT",
|
|
4038
|
+
"UND_ERR_CONNECT_TIMEOUT"
|
|
4039
|
+
]);
|
|
4040
|
+
var NETWORK_ERROR_TYPE_NAMES = /* @__PURE__ */ new Set([
|
|
4041
|
+
"APIConnectionError",
|
|
4042
|
+
"APIConnectionTimeoutError",
|
|
4043
|
+
"APITimeoutError"
|
|
4044
|
+
]);
|
|
4045
|
+
function isNetworkError(error) {
|
|
4046
|
+
if (typeof error !== "object" || error === null) return false;
|
|
4047
|
+
const code = "code" in error ? error.code : void 0;
|
|
4048
|
+
const constructorName = error.constructor?.name;
|
|
4049
|
+
return typeof code === "string" && NETWORK_ERROR_CODES.has(code) || typeof constructorName === "string" && NETWORK_ERROR_TYPE_NAMES.has(constructorName);
|
|
4050
|
+
}
|
|
4051
|
+
function providerAPIErrorFromUnknown(service, error, action = "request") {
|
|
4052
|
+
if (error instanceof ProviderConfigError) {
|
|
4053
|
+
return new ProviderConfigError(`${service} configuration failed`, {
|
|
4054
|
+
service,
|
|
4055
|
+
statusCode: error.statusCode
|
|
4056
|
+
});
|
|
4057
|
+
}
|
|
4058
|
+
if (error instanceof ProviderConnectionError) {
|
|
4059
|
+
return new ProviderConnectionError(`${service} ${action} failed due to a network error`, {
|
|
4060
|
+
service,
|
|
4061
|
+
action,
|
|
4062
|
+
statusCode: error.statusCode
|
|
4063
|
+
});
|
|
4064
|
+
}
|
|
4065
|
+
if (error instanceof ProviderRateLimitedError) {
|
|
4066
|
+
return new ProviderRateLimitedError(`${service} rate limit exceeded`, {
|
|
4067
|
+
service,
|
|
4068
|
+
retryAfterMs: error.retryAfterMs,
|
|
4069
|
+
attempts: error.attempts
|
|
4070
|
+
});
|
|
4071
|
+
}
|
|
4072
|
+
if (error instanceof ProviderError) {
|
|
4073
|
+
return new ProviderAPIError(`${service} ${action} failed`, {
|
|
4074
|
+
service,
|
|
4075
|
+
action,
|
|
4076
|
+
statusCode: error.statusCode
|
|
4077
|
+
});
|
|
4078
|
+
}
|
|
4079
|
+
if (isNetworkError(error)) {
|
|
4080
|
+
return new ProviderConnectionError(`${service} ${action} failed due to a network error`, {
|
|
4081
|
+
service,
|
|
4082
|
+
action
|
|
4083
|
+
});
|
|
4084
|
+
}
|
|
4085
|
+
return new ProviderAPIError(`${service} ${action} failed`, {
|
|
4086
|
+
service,
|
|
4087
|
+
action,
|
|
4088
|
+
statusCode: errorStatusCode(error)
|
|
4089
|
+
});
|
|
4090
|
+
}
|
|
4091
|
+
function normalizeProviderError(error) {
|
|
4092
|
+
const status = error.statusCode ?? null;
|
|
4093
|
+
if (error instanceof ProviderConfigError) {
|
|
4094
|
+
return {
|
|
4095
|
+
type: "config",
|
|
4096
|
+
code: "PROVIDER_CONFIG_ERROR",
|
|
4097
|
+
service: error.service,
|
|
4098
|
+
action: error.action,
|
|
4099
|
+
status,
|
|
4100
|
+
retryable: false
|
|
4101
|
+
};
|
|
4102
|
+
}
|
|
4103
|
+
if (error instanceof ProviderConnectionError) {
|
|
4104
|
+
return {
|
|
4105
|
+
type: "network",
|
|
4106
|
+
code: "PROVIDER_NETWORK_ERROR",
|
|
4107
|
+
service: error.service,
|
|
4108
|
+
action: error.action,
|
|
4109
|
+
status,
|
|
4110
|
+
retryable: true
|
|
4111
|
+
};
|
|
4112
|
+
}
|
|
4113
|
+
if (error instanceof ProviderRateLimitedError || status === 429) {
|
|
4114
|
+
return {
|
|
4115
|
+
type: "rate_limit",
|
|
4116
|
+
code: "PROVIDER_RATE_LIMITED",
|
|
4117
|
+
service: error.service,
|
|
4118
|
+
action: error.action,
|
|
4119
|
+
status,
|
|
4120
|
+
retryable: true
|
|
4121
|
+
};
|
|
4122
|
+
}
|
|
4123
|
+
if (status === 401 || status === 403) {
|
|
4124
|
+
return {
|
|
4125
|
+
type: "auth",
|
|
4126
|
+
code: "PROVIDER_AUTH_ERROR",
|
|
4127
|
+
service: error.service,
|
|
4128
|
+
action: error.action,
|
|
4129
|
+
status,
|
|
4130
|
+
retryable: false
|
|
4131
|
+
};
|
|
4132
|
+
}
|
|
4133
|
+
return {
|
|
4134
|
+
type: "api",
|
|
4135
|
+
code: "PROVIDER_API_ERROR",
|
|
4136
|
+
service: error.service,
|
|
4137
|
+
action: error.action,
|
|
4138
|
+
status,
|
|
4139
|
+
retryable: status !== null && status >= 500
|
|
4140
|
+
};
|
|
4141
|
+
}
|
|
4142
|
+
|
|
4143
|
+
// src/providers/response-budget.ts
|
|
4144
|
+
function scanUtf8Scalars(fragment, pendingHighSurrogate) {
|
|
4145
|
+
if (typeof fragment !== "string")
|
|
4146
|
+
throw new TypeError("provider output fragments must be strings");
|
|
4147
|
+
const input = `${pendingHighSurrogate ?? ""}${fragment}`;
|
|
4148
|
+
const scalars = [];
|
|
4149
|
+
let bytes = 0;
|
|
4150
|
+
let pending;
|
|
4151
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
4152
|
+
const unit = input.charCodeAt(index);
|
|
4153
|
+
if (unit >= 55296 && unit <= 56319) {
|
|
4154
|
+
if (index + 1 >= input.length) {
|
|
4155
|
+
pending = input[index];
|
|
4156
|
+
break;
|
|
4157
|
+
}
|
|
4158
|
+
const low = input.charCodeAt(index + 1);
|
|
4159
|
+
if (!(low >= 56320 && low <= 57343)) {
|
|
4160
|
+
throw new TypeError("provider output contains an unpaired Unicode surrogate");
|
|
4161
|
+
}
|
|
4162
|
+
scalars.push({ text: input.slice(index, index + 2), bytes: 4 });
|
|
4163
|
+
bytes += 4;
|
|
4164
|
+
index += 1;
|
|
4165
|
+
continue;
|
|
4166
|
+
}
|
|
4167
|
+
if (unit >= 56320 && unit <= 57343) {
|
|
4168
|
+
throw new TypeError("provider output contains an unpaired Unicode surrogate");
|
|
4169
|
+
}
|
|
4170
|
+
const scalarBytes = unit <= 127 ? 1 : unit <= 2047 ? 2 : 3;
|
|
4171
|
+
scalars.push({ text: input[index], bytes: scalarBytes });
|
|
4172
|
+
bytes += scalarBytes;
|
|
4173
|
+
}
|
|
4174
|
+
return pending === void 0 ? { scalars, bytes } : { scalars, bytes, pendingHighSurrogate: pending };
|
|
4175
|
+
}
|
|
4176
|
+
function utf8ByteLength(value) {
|
|
4177
|
+
const scan = scanUtf8Scalars(value);
|
|
4178
|
+
if (scan.pendingHighSurrogate !== void 0) {
|
|
4179
|
+
throw new TypeError("provider output contains an unpaired Unicode surrogate");
|
|
4180
|
+
}
|
|
4181
|
+
return scan.bytes;
|
|
4182
|
+
}
|
|
4183
|
+
var LinearStringParts = class {
|
|
4184
|
+
parts = [];
|
|
4185
|
+
_fragmentCount = 0;
|
|
4186
|
+
_joinOperations = 0;
|
|
4187
|
+
get fragmentCount() {
|
|
4188
|
+
return this._fragmentCount;
|
|
4189
|
+
}
|
|
4190
|
+
get joinOperations() {
|
|
4191
|
+
return this._joinOperations;
|
|
4192
|
+
}
|
|
4193
|
+
append(fragment) {
|
|
4194
|
+
if (!fragment) return;
|
|
4195
|
+
this.parts.push(fragment);
|
|
4196
|
+
this._fragmentCount += 1;
|
|
4197
|
+
}
|
|
4198
|
+
join() {
|
|
4199
|
+
this._joinOperations += 1;
|
|
4200
|
+
return this.parts.join("");
|
|
4201
|
+
}
|
|
4202
|
+
};
|
|
4203
|
+
var ProviderResponseBudget = class {
|
|
4204
|
+
limits;
|
|
4205
|
+
textBytes = 0;
|
|
4206
|
+
totalBytes = 0;
|
|
4207
|
+
callCount = 0;
|
|
4208
|
+
rawFragments = 0;
|
|
4209
|
+
argumentJoins = 0;
|
|
4210
|
+
textPendingHighSurrogate;
|
|
4211
|
+
rawToolCalls = /* @__PURE__ */ new Map();
|
|
4212
|
+
constructor(limits) {
|
|
4213
|
+
this.limits = resolveProviderResponseLimits(limits);
|
|
4214
|
+
}
|
|
4215
|
+
get diagnostics() {
|
|
4216
|
+
return Object.freeze({
|
|
4217
|
+
textBytes: this.textBytes,
|
|
4218
|
+
totalResponseBytes: this.totalBytes,
|
|
4219
|
+
toolCalls: this.callCount,
|
|
4220
|
+
rawFragments: this.rawFragments,
|
|
4221
|
+
toolArgumentJoinOperations: this.argumentJoins
|
|
4222
|
+
});
|
|
4223
|
+
}
|
|
4224
|
+
get providerDiagnostics() {
|
|
4225
|
+
return Object.freeze({
|
|
4226
|
+
rawFragments: this.rawFragments,
|
|
4227
|
+
toolArgumentJoinOperations: this.argumentJoins
|
|
4228
|
+
});
|
|
4229
|
+
}
|
|
4230
|
+
acceptRaw(input) {
|
|
4231
|
+
const text = input.text ?? "";
|
|
4232
|
+
const textScan = scanUtf8Scalars(text, this.textPendingHighSurrogate);
|
|
4233
|
+
const nextTextBytes = this.textBytes + textScan.bytes;
|
|
4234
|
+
if (nextTextBytes > this.limits.textMaxBytes) {
|
|
4235
|
+
throw new ProviderOutputLimitError("text", this.limits.textMaxBytes);
|
|
4236
|
+
}
|
|
4237
|
+
const nextStates = new Map([...this.rawToolCalls].map(([key, state]) => [key, { ...state }]));
|
|
4238
|
+
let addedTotal = textScan.bytes;
|
|
4239
|
+
let addedCalls = 0;
|
|
4240
|
+
let addedFragments = text ? 1 : 0;
|
|
4241
|
+
for (const fragment of input.toolFragments ?? []) {
|
|
4242
|
+
let state = nextStates.get(fragment.key);
|
|
4243
|
+
if (fragment.startsCall) {
|
|
4244
|
+
if (state !== void 0) throw new TypeError("provider tool call started more than once");
|
|
4245
|
+
state = { argumentBytes: 0 };
|
|
4246
|
+
nextStates.set(fragment.key, state);
|
|
4247
|
+
addedCalls += 1;
|
|
4248
|
+
} else if (state === void 0) {
|
|
4249
|
+
throw new TypeError("provider tool fragment must start a call before appending");
|
|
4250
|
+
}
|
|
4251
|
+
const id = scanUtf8Scalars(fragment.idFragment ?? "", state.idPending);
|
|
4252
|
+
const name = scanUtf8Scalars(fragment.nameFragment ?? "", state.namePending);
|
|
4253
|
+
const args = scanUtf8Scalars(fragment.argumentsFragment ?? "", state.argumentsPending);
|
|
4254
|
+
state.idPending = id.pendingHighSurrogate;
|
|
4255
|
+
state.namePending = name.pendingHighSurrogate;
|
|
4256
|
+
state.argumentsPending = args.pendingHighSurrogate;
|
|
4257
|
+
state.argumentBytes += args.bytes;
|
|
4258
|
+
if (state.argumentBytes > this.limits.toolArgumentsMaxBytes) {
|
|
4259
|
+
throw new ProviderOutputLimitError("tool_arguments", this.limits.toolArgumentsMaxBytes);
|
|
4260
|
+
}
|
|
4261
|
+
addedTotal += id.bytes + name.bytes + args.bytes;
|
|
4262
|
+
addedFragments += Number(Boolean(fragment.idFragment));
|
|
4263
|
+
addedFragments += Number(Boolean(fragment.nameFragment));
|
|
4264
|
+
addedFragments += Number(Boolean(fragment.argumentsFragment));
|
|
4265
|
+
}
|
|
4266
|
+
const nextCalls = this.callCount + addedCalls;
|
|
4267
|
+
if (nextCalls > this.limits.toolCallsMax) {
|
|
4268
|
+
throw new ProviderOutputLimitError("tool_calls", this.limits.toolCallsMax);
|
|
4269
|
+
}
|
|
4270
|
+
const nextTotal = this.totalBytes + addedTotal;
|
|
4271
|
+
if (nextTotal > this.limits.responseMaxBytes) {
|
|
4272
|
+
throw new ProviderOutputLimitError("total_response", this.limits.responseMaxBytes);
|
|
4273
|
+
}
|
|
4274
|
+
this.textBytes = nextTextBytes;
|
|
4275
|
+
this.totalBytes = nextTotal;
|
|
4276
|
+
this.callCount = nextCalls;
|
|
4277
|
+
this.rawFragments += addedFragments;
|
|
4278
|
+
this.textPendingHighSurrogate = textScan.pendingHighSurrogate;
|
|
4279
|
+
this.rawToolCalls = nextStates;
|
|
4280
|
+
}
|
|
4281
|
+
acceptNormalized(delta, toolCalls) {
|
|
4282
|
+
const textScan = scanUtf8Scalars(delta, this.textPendingHighSurrogate);
|
|
4283
|
+
const nextTextBytes = this.textBytes + textScan.bytes;
|
|
4284
|
+
if (nextTextBytes > this.limits.textMaxBytes) {
|
|
4285
|
+
throw new ProviderOutputLimitError("text", this.limits.textMaxBytes);
|
|
4286
|
+
}
|
|
4287
|
+
let addedTotal = textScan.bytes;
|
|
4288
|
+
const serializedCalls = [];
|
|
4289
|
+
for (const call of toolCalls) {
|
|
4290
|
+
const descriptors = Object.getOwnPropertyDescriptors(call);
|
|
4291
|
+
const id = dataProperty(descriptors, "id");
|
|
4292
|
+
const name = dataProperty(descriptors, "name");
|
|
4293
|
+
const args = dataProperty(descriptors, "args");
|
|
4294
|
+
if (typeof id !== "string" || typeof name !== "string") {
|
|
4295
|
+
throw new TypeError("provider tool call id and name must be strings");
|
|
4296
|
+
}
|
|
4297
|
+
const encodedArguments = canonicalJsonValue(args ?? {}, "tool arguments");
|
|
4298
|
+
const argumentBytes = utf8ByteLength(encodedArguments);
|
|
4299
|
+
if (argumentBytes > this.limits.toolArgumentsMaxBytes) {
|
|
4300
|
+
throw new ProviderOutputLimitError("tool_arguments", this.limits.toolArgumentsMaxBytes);
|
|
4301
|
+
}
|
|
4302
|
+
addedTotal += utf8ByteLength(id) + utf8ByteLength(name) + argumentBytes;
|
|
4303
|
+
serializedCalls.push({ id, name, encodedArguments });
|
|
4304
|
+
}
|
|
4305
|
+
const nextCalls = this.callCount + serializedCalls.length;
|
|
4306
|
+
if (nextCalls > this.limits.toolCallsMax) {
|
|
4307
|
+
throw new ProviderOutputLimitError("tool_calls", this.limits.toolCallsMax);
|
|
4308
|
+
}
|
|
4309
|
+
const nextTotal = this.totalBytes + addedTotal;
|
|
4310
|
+
if (nextTotal > this.limits.responseMaxBytes) {
|
|
4311
|
+
throw new ProviderOutputLimitError("total_response", this.limits.responseMaxBytes);
|
|
4312
|
+
}
|
|
4313
|
+
const detached = serializedCalls.map(
|
|
4314
|
+
({ id, name, encodedArguments }) => Object.freeze({
|
|
4315
|
+
id,
|
|
4316
|
+
name,
|
|
4317
|
+
args: cloneAndFreezeJson(JSON.parse(encodedArguments))
|
|
4318
|
+
})
|
|
4319
|
+
);
|
|
4320
|
+
this.textBytes = nextTextBytes;
|
|
4321
|
+
this.totalBytes = nextTotal;
|
|
4322
|
+
this.callCount = nextCalls;
|
|
4323
|
+
this.textPendingHighSurrogate = textScan.pendingHighSurrogate;
|
|
4324
|
+
return Object.freeze({ delta, toolCalls: Object.freeze(detached) });
|
|
4325
|
+
}
|
|
4326
|
+
finishRawTool(key) {
|
|
4327
|
+
const state = this.rawToolCalls.get(key);
|
|
4328
|
+
if (state === void 0) throw new TypeError("unknown provider tool call");
|
|
4329
|
+
assertNoPendingSurrogate(state.idPending);
|
|
4330
|
+
assertNoPendingSurrogate(state.namePending);
|
|
4331
|
+
assertNoPendingSurrogate(state.argumentsPending);
|
|
4332
|
+
}
|
|
4333
|
+
finish() {
|
|
4334
|
+
assertNoPendingSurrogate(this.textPendingHighSurrogate);
|
|
4335
|
+
for (const key of this.rawToolCalls.keys()) this.finishRawTool(key);
|
|
4336
|
+
}
|
|
4337
|
+
recordToolArgumentJoin() {
|
|
4338
|
+
this.argumentJoins += 1;
|
|
4339
|
+
}
|
|
4340
|
+
};
|
|
4341
|
+
function dataProperty(descriptors, key) {
|
|
4342
|
+
const descriptor = descriptors[key];
|
|
4343
|
+
if (descriptor === void 0) return void 0;
|
|
4344
|
+
if (!descriptor.enumerable || !("value" in descriptor)) {
|
|
4345
|
+
throw new TypeError("provider tool calls must contain enumerable data properties");
|
|
4346
|
+
}
|
|
4347
|
+
return descriptor.value;
|
|
4348
|
+
}
|
|
4349
|
+
function assertNoPendingSurrogate(pending) {
|
|
4350
|
+
if (pending !== void 0) {
|
|
4351
|
+
throw new TypeError("provider output contains an unpaired Unicode surrogate");
|
|
4352
|
+
}
|
|
4353
|
+
}
|
|
4354
|
+
async function closeProviderStream(stream) {
|
|
4355
|
+
if (typeof stream !== "object" || stream === null) return;
|
|
4356
|
+
const candidate = stream;
|
|
4357
|
+
const close = candidate.controller?.abort?.bind(candidate.controller) ?? candidate.abort?.bind(candidate) ?? candidate.return?.bind(candidate) ?? candidate.close?.bind(candidate);
|
|
4358
|
+
if (close === void 0) return;
|
|
4359
|
+
try {
|
|
4360
|
+
await close();
|
|
4361
|
+
} catch {
|
|
4362
|
+
}
|
|
4363
|
+
}
|
|
4364
|
+
|
|
4365
|
+
export { AgentTurnFailed, CancellationError, CancellationToken, DEFAULT_PROVIDER_RESPONSE_LIMITS, DEFAULT_TURN_EXECUTION_LIMITS, DurableJsonLimitError, EventBufferOverflowError, EventDeliveryError, EventIdConflictError, EventSchemaIncompatibleError, EventStoreCapacityError, EventType, InvalidDurableValueError, KajiEvent, LinearStringParts, MAX_DURABLE_TOOL_ARGUMENT_BYTES, MAX_DURABLE_TOOL_RESULT_BYTES, METRIC_NAMES, NOOP_METRICS, NOOP_TRACE, NewKajiEvent, ProviderAPIError, ProviderCancellationContractViolation, ProviderConfigError, ProviderConnectionError, ProviderError, ProviderOutputLimitError, ProviderRateLimitedError, ProviderResponseBudget, SessionCreated, SessionPurgeBusyError, SessionPurgeUnsupportedError, StoredKajiEvent, TurnTimeoutError, applyEvent, approvalKey, canonicalJsonValue, cloneAndFreezeJson, cloneSessionState, closeProviderStream, closedRecoveryFields, closedTransportFailureFields, createDeadlineCancellationScope, createSessionState, durableJsonSnapshot, durableToolArgumentsSize, getProviderResponseDiagnostics, normalizeProviderError, openStreamWithRetry, providerAPIErrorFromUnknown, providerFamily, providerViolationSettlement, recordMetric, replaySession, resolveProviderResponseLimits, resolveTurnExecutionLimits, scanUtf8Scalars, snapshotNewEvent, snapshotStoredEventForAppend, startSpan, structurallyEqualJson, systemClock, systemIdFactory, systemTimerScheduler, throwIfCancellationRequested, validateNewEvent, validateStoredEvent, withProviderResponseDiagnostics, withRetry };
|
|
4366
|
+
//# sourceMappingURL=chunk-AAM33KAO.js.map
|
|
4367
|
+
//# sourceMappingURL=chunk-AAM33KAO.js.map
|