@yielded/agent 0.1.0-beta.173 → 0.1.0-beta.174
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Admin-BX9ns28E.d.mts → Admin-BHmp2V9p.d.mts} +25 -16
- package/dist/{Agent-9aBoIi74.d.mts → Agent-B39jRnFv.d.mts} +2 -2
- package/dist/{Agent-0WvBWWbM.mjs → Agent-BiRbr73L.mjs} +7 -6
- package/dist/Agent-BiRbr73L.mjs.map +1 -0
- package/dist/{AgentRuntime-CQ-qcETl.mjs → AgentRuntime-B6qZlD3f.mjs} +199 -191
- package/dist/AgentRuntime-B6qZlD3f.mjs.map +1 -0
- package/dist/{AgentRuntime-BfP14534.d.mts → AgentRuntime-BD3ZHAMq.d.mts} +10 -10
- package/dist/{Digest-DCuPlhNk.mjs → Digest-EpeqWEdv.mjs} +41 -14
- package/dist/Digest-EpeqWEdv.mjs.map +1 -0
- package/dist/{DurableAgentRuntime-BAmSkWYr.mjs → DurableAgentRuntime-CBBjRNJN.mjs} +1447 -1424
- package/dist/DurableAgentRuntime-CBBjRNJN.mjs.map +1 -0
- package/dist/{EventSource-BwliwQz9.d.mts → EventSource-C9aaJaXT.d.mts} +2 -2
- package/dist/{MessageDelivery-B943ebI_.d.mts → MessageDelivery-BGDm-c46.d.mts} +42 -42
- package/dist/{Messaging-C_6OOg_s.d.mts → Messaging-SVu6rWV8.d.mts} +12 -6
- package/dist/{MessagingHost-B8oKM7AC.d.mts → MessagingHost-C6SOAcoG.d.mts} +2 -2
- package/dist/{Output-Dsx6k52t.d.mts → Output-CRamN1Fy.d.mts} +2 -2
- package/dist/{PreparedInputAdmission-CxSJSiTl.d.mts → PreparedInputAdmission-BvDqlgiP.d.mts} +3 -3
- package/dist/{RunContinuation-DHYNAQFi.mjs → RunContinuation-4ZATcVLB.mjs} +113 -56
- package/dist/RunContinuation-4ZATcVLB.mjs.map +1 -0
- package/dist/{RunContinuation-FHM7XPjq.d.mts → RunContinuation-CTJ1jGrO.d.mts} +6 -6
- package/dist/{RunJournal-kfKVxJj7.mjs → RunJournal-CNZqA3Ge.mjs} +33 -5
- package/dist/RunJournal-CNZqA3Ge.mjs.map +1 -0
- package/dist/{RunOptions-D8zxFIrZ.d.mts → RunOptions-Be77lKVZ.d.mts} +2 -2
- package/dist/{RunStorage-uqPxps09.mjs → RunStorage-BHjuuERI.mjs} +9 -6
- package/dist/RunStorage-BHjuuERI.mjs.map +1 -0
- package/dist/{Scheduling-CVyfXlBR.mjs → Scheduling-NG8slKdI.mjs} +11 -11
- package/dist/Scheduling-NG8slKdI.mjs.map +1 -0
- package/dist/{Subagent-vpffemql.mjs → Subagent-CTIpnzlB.mjs} +53 -40
- package/dist/Subagent-CTIpnzlB.mjs.map +1 -0
- package/dist/{Subagent-E6tvd7-k.d.mts → Subagent-DKhZA72u.d.mts} +19 -8
- package/dist/{SubagentHost-B6w2m-SI.d.mts → SubagentHost-D1xBgn9g.d.mts} +2 -2
- package/dist/{Subscription-DONig54Q.d.mts → Subscription-BNg9VCRl.d.mts} +2 -2
- package/dist/{SubscriptionInput-mJIRxWJM.d.mts → SubscriptionInput-BUoXv-_K.d.mts} +2 -2
- package/dist/{ThreadImport-DpHxjBrA.d.mts → ThreadImport-CMgzttvr.d.mts} +5 -5
- package/dist/{ThreadImport-DckUMEqJ.mjs → ThreadImport-CodYoJoa.mjs} +7 -7
- package/dist/ThreadImport-CodYoJoa.mjs.map +1 -0
- package/dist/{ThreadStore-CEekRa80.mjs → ThreadStore-59uDGXul.mjs} +163 -84
- package/dist/ThreadStore-59uDGXul.mjs.map +1 -0
- package/dist/{ThreadTransfer-B4gTQLIl.mjs → ThreadTransfer-3jigUl3g.mjs} +3 -3
- package/dist/{ThreadTransfer-B4gTQLIl.mjs.map → ThreadTransfer-3jigUl3g.mjs.map} +1 -1
- package/dist/{WorkerAdmission-DFVbbVh2.mjs → WorkerAdmission-DDYJdOsU.mjs} +4 -4
- package/dist/{WorkerAdmission-DFVbbVh2.mjs.map → WorkerAdmission-DDYJdOsU.mjs.map} +1 -1
- package/dist/{agent-registration-ByMZ_cK5.mjs → agent-registration-DRbyhAu-.mjs} +69 -56
- package/dist/agent-registration-DRbyhAu-.mjs.map +1 -0
- package/dist/capabilities/Approval.mjs +2 -2
- package/dist/capabilities/Approval.mjs.map +1 -1
- package/dist/capabilities/BrowserUse.d.mts +102 -1867
- package/dist/capabilities/BrowserUse.mjs +74 -798
- package/dist/capabilities/BrowserUse.mjs.map +1 -1
- package/dist/capabilities/Budget.mjs +3 -1
- package/dist/capabilities/Budget.mjs.map +1 -1
- package/dist/capabilities/CodeMode.d.mts +1 -1
- package/dist/capabilities/CodeMode.mjs +16 -9
- package/dist/capabilities/CodeMode.mjs.map +1 -1
- package/dist/capabilities/Commands.d.mts +1 -1
- package/dist/capabilities/McpClient.mjs +1 -1
- package/dist/capabilities/McpClient.mjs.map +1 -1
- package/dist/capabilities/Messaging.d.mts +1 -1
- package/dist/capabilities/Messaging.mjs +4 -4
- package/dist/capabilities/Messaging.mjs.map +1 -1
- package/dist/capabilities/ModelContext.mjs +7 -5
- package/dist/capabilities/ModelContext.mjs.map +1 -1
- package/dist/capabilities/Redaction.mjs +49 -19
- package/dist/capabilities/Redaction.mjs.map +1 -1
- package/dist/capabilities/RunHooks.d.mts +1 -1
- package/dist/capabilities/RunHooks.mjs +1 -1
- package/dist/capabilities/RunHooks.mjs.map +1 -1
- package/dist/capabilities/Subagent.d.mts +1 -1
- package/dist/capabilities/Subagent.mjs +1 -1
- package/dist/capabilities/SubagentReservations.mjs +3 -1
- package/dist/capabilities/SubagentReservations.mjs.map +1 -1
- package/dist/capabilities/WebCapture.mjs.map +1 -1
- package/dist/capabilities/WebSearch.mjs +7 -7
- package/dist/capabilities/WebSearch.mjs.map +1 -1
- package/dist/core/Agent.d.mts +1 -1
- package/dist/core/Agent.mjs +1 -1
- package/dist/core/AgentUpdates.mjs +8 -8
- package/dist/core/AgentUpdates.mjs.map +1 -1
- package/dist/core/Thread.mjs +1 -1
- package/dist/core/Thread.mjs.map +1 -1
- package/dist/core/Usage.mjs +2 -2
- package/dist/core/Usage.mjs.map +1 -1
- package/dist/durable/Admin.d.mts +1 -1
- package/dist/durable/AgentRegistration.d.mts +1 -1
- package/dist/durable/AgentRegistration.mjs +1 -1
- package/dist/durable/Certification.d.mts +1 -1
- package/dist/durable/CommittedActivity.d.mts +1 -1
- package/dist/durable/CommittedActivity.mjs +2 -2
- package/dist/durable/Digest.mjs +1 -1
- package/dist/durable/DurableAgentRuntime.d.mts +1 -1
- package/dist/durable/DurableAgentRuntime.mjs +2 -2
- package/dist/durable/EventSource.d.mts +1 -1
- package/dist/durable/EventSource.mjs +6 -6
- package/dist/durable/EventSource.mjs.map +1 -1
- package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
- package/dist/durable/LifecyclePublication.d.mts +1 -1
- package/dist/durable/LifecyclePublication.mjs +1 -1
- package/dist/durable/MessageDelivery.d.mts +1 -1
- package/dist/durable/MessageDelivery.mjs +1 -1
- package/dist/durable/MessageDeliveryStoreConformance.d.mts +2 -2
- package/dist/durable/MessageDeliveryStoreConformance.mjs +1 -1
- package/dist/durable/PersistentHistory.d.mts +1 -1
- package/dist/durable/PersistentHistory.mjs +3 -3
- package/dist/durable/PreparedInputAdmission.d.mts +1 -1
- package/dist/durable/RecordFormat.mjs +2 -2
- package/dist/durable/RecordFormat.mjs.map +1 -1
- package/dist/durable/Recovery.d.mts +1 -1
- package/dist/durable/RunContinuation.d.mts +2 -2
- package/dist/durable/RunContinuation.mjs +2 -2
- package/dist/durable/RunJournal.d.mts +1 -1
- package/dist/durable/RunJournal.mjs +1 -1
- package/dist/durable/RunStorage.d.mts +1 -1
- package/dist/durable/RunStorage.mjs +1 -1
- package/dist/durable/Scheduling.d.mts +1 -1
- package/dist/durable/Scheduling.mjs +1 -1
- package/dist/durable/SettlementPublisher.d.mts +1 -1
- package/dist/durable/SettlementPublisher.mjs +2 -2
- package/dist/durable/SubmissionLedger.d.mts +1 -1
- package/dist/durable/SubmissionLedger.mjs +5 -1
- package/dist/durable/SubmissionLedger.mjs.map +1 -1
- package/dist/durable/SubmissionLedgerConformance.d.mts +1 -1
- package/dist/durable/SubmissionLedgerConformance.mjs +4 -4
- package/dist/durable/SubmissionStatus.d.mts +1 -1
- package/dist/durable/Subscription.d.mts +1 -1
- package/dist/durable/SubscriptionInput.d.mts +1 -1
- package/dist/durable/SubscriptionInput.mjs +3 -3
- package/dist/durable/SubscriptionInput.mjs.map +1 -1
- package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
- package/dist/durable/SubscriptionStoreConformance.mjs +2 -2
- package/dist/durable/SubscriptionStoreConformance.mjs.map +1 -1
- package/dist/durable/SubscriptionTools.d.mts +2 -2
- package/dist/durable/SubscriptionTransition.d.mts +1 -1
- package/dist/durable/Subscriptions.d.mts +5 -5
- package/dist/durable/Subscriptions.mjs +2 -2
- package/dist/durable/Subscriptions.mjs.map +1 -1
- package/dist/durable/ThreadArchiveRange.d.mts +1 -1
- package/dist/durable/ThreadContextHistory.d.mts +1 -1
- package/dist/durable/ThreadContextHistory.mjs +1 -1
- package/dist/durable/ThreadImport.d.mts +1 -1
- package/dist/durable/ThreadImport.mjs +1 -1
- package/dist/durable/ThreadInvariants.d.mts +3 -3
- package/dist/durable/ThreadInvariants.mjs +4 -4
- package/dist/durable/ThreadInvariants.mjs.map +1 -1
- package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
- package/dist/durable/ThreadReader.d.mts +1 -1
- package/dist/durable/ThreadReader.mjs +1 -1
- package/dist/durable/ThreadStore.d.mts +1 -1
- package/dist/durable/ThreadStore.mjs +1 -1
- package/dist/durable/ThreadStoreConformance.d.mts +1 -1
- package/dist/durable/ThreadStoreConformance.mjs +3 -3
- package/dist/durable/ThreadTransfer.d.mts +1 -1
- package/dist/durable/ThreadTransfer.mjs +1 -1
- package/dist/durable/ThreadWork.d.mts +1 -1
- package/dist/durable/ThreadWork.mjs +4 -4
- package/dist/durable/ThreadWork.mjs.map +1 -1
- package/dist/durable/WorkerAdmission.d.mts +1 -1
- package/dist/durable/WorkerAdmission.mjs +1 -1
- package/dist/durable/WorkerHost.d.mts +2 -2
- package/dist/engine/AgentRuntime.d.mts +1 -1
- package/dist/engine/AgentRuntime.mjs +1 -1
- package/dist/engine/MessagingHost.d.mts +1 -1
- package/dist/engine/Output.d.mts +1 -1
- package/dist/engine/RunOptions.d.mts +1 -1
- package/dist/engine/SubagentHost.d.mts +1 -1
- package/dist/index.d.mts +19 -19
- package/dist/index.mjs +14 -14
- package/dist/{run-context-reader-OcsZr4bk.d.mts → run-context-reader-CC7ZD95F.d.mts} +2 -2
- package/package.json +1 -1
- package/src/capabilities/Approval.ts +58 -60
- package/src/capabilities/BrowserUse.ts +89 -944
- package/src/capabilities/Budget.ts +8 -1
- package/src/capabilities/CodeMode.ts +57 -33
- package/src/capabilities/McpClient.ts +2 -2
- package/src/capabilities/Messaging.ts +51 -55
- package/src/capabilities/ModelContext.ts +5 -2
- package/src/capabilities/Redaction.ts +64 -34
- package/src/capabilities/RunHooks.ts +52 -55
- package/src/capabilities/Subagent.ts +33 -33
- package/src/capabilities/SubagentReservations.ts +9 -1
- package/src/capabilities/WebCapture.ts +6 -0
- package/src/capabilities/WebSearch.ts +10 -7
- package/src/capabilities/internal/subagent-background.ts +202 -158
- package/src/core/Agent.ts +11 -6
- package/src/core/AgentUpdates.ts +8 -8
- package/src/core/Thread.ts +9 -10
- package/src/core/Usage.ts +7 -8
- package/src/core/internal/agent-updates.ts +1 -0
- package/src/durable/DurableAgentRuntime.ts +645 -625
- package/src/durable/EventSource.ts +15 -9
- package/src/durable/RecordFormat.ts +5 -3
- package/src/durable/RunContinuation.ts +233 -81
- package/src/durable/RunJournal.ts +10 -9
- package/src/durable/RunStorage.ts +122 -124
- package/src/durable/Scheduling.ts +639 -651
- package/src/durable/SubmissionLedger.ts +4 -0
- package/src/durable/SubscriptionInput.ts +5 -3
- package/src/durable/SubscriptionStoreConformance.ts +23 -23
- package/src/durable/Subscriptions.ts +18 -19
- package/src/durable/ThreadImport.ts +18 -19
- package/src/durable/ThreadInvariants.ts +2 -1
- package/src/durable/ThreadStore.ts +215 -111
- package/src/durable/ThreadWork.ts +1 -2
- package/src/durable/internal/StorageOwner.ts +10 -4
- package/src/durable/internal/agent-registration.ts +96 -89
- package/src/durable/internal/canonical-json.ts +61 -20
- package/src/durable/internal/prompt-history-cache.ts +13 -4
- package/src/durable/internal/record-encoding.ts +120 -64
- package/src/durable/internal/schedule-time.ts +6 -6
- package/src/durable/internal/usage-totals.ts +38 -0
- package/src/durable/internal/worker-host.ts +69 -74
- package/src/engine/internal/agent-runtime.ts +1067 -1018
- package/src/engine/internal/provisional-text.ts +12 -10
- package/src/engine/internal/tool-exposure.ts +22 -18
- package/src/engine/internal/tool-telemetry.ts +12 -7
- package/dist/Agent-0WvBWWbM.mjs.map +0 -1
- package/dist/AgentRuntime-CQ-qcETl.mjs.map +0 -1
- package/dist/Digest-DCuPlhNk.mjs.map +0 -1
- package/dist/DurableAgentRuntime-BAmSkWYr.mjs.map +0 -1
- package/dist/RunContinuation-DHYNAQFi.mjs.map +0 -1
- package/dist/RunJournal-kfKVxJj7.mjs.map +0 -1
- package/dist/RunStorage-uqPxps09.mjs.map +0 -1
- package/dist/Scheduling-CVyfXlBR.mjs.map +0 -1
- package/dist/Subagent-vpffemql.mjs.map +0 -1
- package/dist/ThreadImport-DckUMEqJ.mjs.map +0 -1
- package/dist/ThreadStore-CEekRa80.mjs.map +0 -1
- package/dist/agent-registration-ByMZ_cK5.mjs.map +0 -1
|
@@ -262,6 +262,11 @@ const pruneRetiredHierarchy = (
|
|
|
262
262
|
return nodes;
|
|
263
263
|
};
|
|
264
264
|
|
|
265
|
+
/** Internal lifetime misuse remains a defect, with an Error message and stack. */
|
|
266
|
+
class RetiredBudgetHandle extends Schema.TaggedError<RetiredBudgetHandle>()("RetiredBudgetHandle", {
|
|
267
|
+
message: Schema.String,
|
|
268
|
+
}) {}
|
|
269
|
+
|
|
265
270
|
const makeNode = (
|
|
266
271
|
ledger: Ref.Ref<BudgetLedger>,
|
|
267
272
|
key: string,
|
|
@@ -273,7 +278,9 @@ const makeNode = (
|
|
|
273
278
|
|
|
274
279
|
const retiredDefect = () =>
|
|
275
280
|
Effect.die(
|
|
276
|
-
|
|
281
|
+
RetiredBudgetHandle.make({
|
|
282
|
+
message: `Usage budget handle ${config.level}:${config.id} was used after retirement`,
|
|
283
|
+
}),
|
|
277
284
|
);
|
|
278
285
|
|
|
279
286
|
const liveHierarchy = (state: BudgetLedger): ReadonlyArray<LedgerNode> | undefined => {
|
|
@@ -300,11 +300,16 @@ const renderJsonSchemaType = (
|
|
|
300
300
|
indent: string,
|
|
301
301
|
): string => {
|
|
302
302
|
if (depth > MAX_RENDER_DEPTH) {
|
|
303
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously bounds recursive Schema declaration rendering before creating the Tool.
|
|
303
304
|
throw new Error("Code Mode declaration rendering exceeded its depth bound");
|
|
304
305
|
}
|
|
305
306
|
if (!isJsonSchemaRecord(schema)) {
|
|
307
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects unsupported JSON Schema declaration fragments.
|
|
306
308
|
throw new Error(`Code Mode cannot render the JSON schema fragment ${JSON.stringify(schema)}`);
|
|
307
309
|
}
|
|
310
|
+
// An empty schema is explicitly unconstrained, including Schema.Json's array items.
|
|
311
|
+
// This is a faithful declaration; unrecognized nonempty fragments still fail below.
|
|
312
|
+
if (Object.keys(schema).length === 0) return "unknown";
|
|
308
313
|
const reference = schema.$ref;
|
|
309
314
|
|
|
310
315
|
if (typeof reference === "string") {
|
|
@@ -314,6 +319,7 @@ const renderJsonSchemaType = (
|
|
|
314
319
|
const resolved = key === undefined ? undefined : defs[key];
|
|
315
320
|
|
|
316
321
|
if (resolved === undefined) {
|
|
322
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects unresolved declaration references.
|
|
317
323
|
throw new Error(`Code Mode cannot resolve the JSON schema reference ${reference}`);
|
|
318
324
|
}
|
|
319
325
|
|
|
@@ -353,6 +359,7 @@ const renderJsonSchemaType = (
|
|
|
353
359
|
}
|
|
354
360
|
case "array": {
|
|
355
361
|
if (!("items" in schema)) {
|
|
362
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously requires item schemas for array declarations.
|
|
356
363
|
throw new Error("Code Mode cannot render an array schema without items");
|
|
357
364
|
}
|
|
358
365
|
|
|
@@ -398,6 +405,7 @@ const renderJsonSchemaType = (
|
|
|
398
405
|
break;
|
|
399
406
|
}
|
|
400
407
|
}
|
|
408
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects declaration schemas it cannot faithfully render.
|
|
401
409
|
throw new Error(
|
|
402
410
|
`Code Mode cannot render the JSON schema fragment ${JSON.stringify(schema).slice(0, 200)}; fix or simplify the Tool's Schema`,
|
|
403
411
|
);
|
|
@@ -420,8 +428,26 @@ interface ResolvedMethod {
|
|
|
420
428
|
readonly tool: Tool.Any;
|
|
421
429
|
}
|
|
422
430
|
|
|
423
|
-
|
|
424
|
-
|
|
431
|
+
interface RenderedMethod extends ResolvedMethod {
|
|
432
|
+
readonly declaration: string;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/** Render once at the synchronous construction boundary; describe only selects frozen declarations. */
|
|
436
|
+
const renderMethodDeclaration = (method: string, tool: Tool.Any): string => {
|
|
437
|
+
const parameters = renderTopLevel(Tool.getJsonSchema(tool), " ");
|
|
438
|
+
const success = renderTopLevel(Tool.getJsonSchemaFromSchema(tool.successSchema), " ");
|
|
439
|
+
|
|
440
|
+
// A description is arbitrary text: newlines and comment terminators
|
|
441
|
+
// must not be able to break out of the documentation comment.
|
|
442
|
+
const safeDescription = tool.description?.replaceAll("*/", "*\\/").replaceAll(/\s*\n\s*/g, " ");
|
|
443
|
+
|
|
444
|
+
const description = safeDescription === undefined ? "" : ` /** ${safeDescription} */\n`;
|
|
445
|
+
|
|
446
|
+
return `${description} ${method}(input: ${parameters}): Promise<${success}>;`;
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
const renderDeclarations = (methods: ReadonlyArray<RenderedMethod>): string => {
|
|
450
|
+
const namespaces = new Map<string, Array<RenderedMethod>>();
|
|
425
451
|
|
|
426
452
|
for (const method of methods) {
|
|
427
453
|
const existing = namespaces.get(method.namespace) ?? [];
|
|
@@ -431,20 +457,7 @@ const renderDeclarations = (methods: ReadonlyArray<ResolvedMethod>): string => {
|
|
|
431
457
|
}
|
|
432
458
|
|
|
433
459
|
const blocks = [...namespaces.entries()].map(([namespace, members]) => {
|
|
434
|
-
const lines = members.map((member) =>
|
|
435
|
-
const parameters = renderTopLevel(Tool.getJsonSchema(member.tool), " ");
|
|
436
|
-
const success = renderTopLevel(Tool.getJsonSchemaFromSchema(member.tool.successSchema), " ");
|
|
437
|
-
|
|
438
|
-
// A description is arbitrary text: newlines and comment terminators
|
|
439
|
-
// must not be able to break out of the documentation comment.
|
|
440
|
-
const safeDescription = member.tool.description
|
|
441
|
-
?.replaceAll("*/", "*\\/")
|
|
442
|
-
.replaceAll(/\s*\n\s*/g, " ");
|
|
443
|
-
|
|
444
|
-
const description = safeDescription === undefined ? "" : ` /** ${safeDescription} */\n`;
|
|
445
|
-
|
|
446
|
-
return `${description} ${member.method}(input: ${parameters}): Promise<${success}>;`;
|
|
447
|
-
});
|
|
460
|
+
const lines = members.map((member) => member.declaration);
|
|
448
461
|
|
|
449
462
|
return `declare const ${namespace}: {\n${lines.join("\n")}\n};`;
|
|
450
463
|
});
|
|
@@ -581,6 +594,7 @@ const make = <
|
|
|
581
594
|
maxEgressBytes < 256 ||
|
|
582
595
|
maxEgressBytes > 4 * 1024 * 1024
|
|
583
596
|
) {
|
|
597
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects invalid egress bounds before creating the Tool.
|
|
584
598
|
throw new Error(
|
|
585
599
|
`Code Mode maxEgressBytes must be an integer between 256 and ${4 * 1024 * 1024}; received ${String(maxEgressBytes)}`,
|
|
586
600
|
);
|
|
@@ -593,15 +607,18 @@ const make = <
|
|
|
593
607
|
|
|
594
608
|
for (const [namespace, namespaceMethods] of Object.entries(options.tools)) {
|
|
595
609
|
if (Option.isNone(decodeIdentifier(namespace))) {
|
|
610
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously requires valid JavaScript namespace identifiers.
|
|
596
611
|
throw new Error(`Code Mode namespace ${namespace} is not a valid JavaScript identifier`);
|
|
597
612
|
}
|
|
598
613
|
const entries = Object.entries(namespaceMethods);
|
|
599
614
|
|
|
600
615
|
if (entries.length === 0) {
|
|
616
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects namespaces without callable methods.
|
|
601
617
|
throw new Error(`Code Mode namespace ${namespace} declares no methods`);
|
|
602
618
|
}
|
|
603
619
|
for (const [method, tool] of entries) {
|
|
604
620
|
if (Option.isNone(decodeIdentifier(method))) {
|
|
621
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously requires valid JavaScript method identifiers.
|
|
605
622
|
throw new Error(
|
|
606
623
|
`Code Mode method ${namespace}.${method} is not a valid JavaScript identifier`,
|
|
607
624
|
);
|
|
@@ -609,6 +626,7 @@ const make = <
|
|
|
609
626
|
const approval = tool.needsApproval;
|
|
610
627
|
|
|
611
628
|
if (approval !== undefined && approval !== false) {
|
|
629
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects approval-requiring Tools from its programmatic allowlist.
|
|
612
630
|
throw new Error(
|
|
613
631
|
`Code Mode rejects Tool ${tool.name} (${namespace}.${method}): approval-requiring Tools cannot be invoked programmatically in the ephemeral slice`,
|
|
614
632
|
);
|
|
@@ -616,6 +634,7 @@ const make = <
|
|
|
616
634
|
const existing = toolsByName.get(tool.name);
|
|
617
635
|
|
|
618
636
|
if (existing !== undefined && existing !== tool) {
|
|
637
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously rejects conflicting Tools sharing one name.
|
|
619
638
|
throw new Error(
|
|
620
639
|
`Code Mode selected two different Tools named ${tool.name}; Tool names must identify one Tool`,
|
|
621
640
|
);
|
|
@@ -626,15 +645,21 @@ const make = <
|
|
|
626
645
|
}
|
|
627
646
|
}
|
|
628
647
|
if (methods.length === 0) {
|
|
648
|
+
// oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- CodeMode.make synchronously requires a nonempty Tool allowlist.
|
|
629
649
|
throw new Error("Code Mode requires at least one allowlisted Tool");
|
|
630
650
|
}
|
|
631
651
|
|
|
632
652
|
// Declarations derive from the encoded Schemas and fail construction closed
|
|
633
653
|
// on anything the renderer cannot express.
|
|
634
|
-
const
|
|
654
|
+
const renderedMethods = methods.map((method): RenderedMethod => ({
|
|
655
|
+
...method,
|
|
656
|
+
declaration: renderMethodDeclaration(method.method, method.tool),
|
|
657
|
+
}));
|
|
658
|
+
|
|
659
|
+
const declarations = renderDeclarations(renderedMethods);
|
|
635
660
|
|
|
636
661
|
const methodsByPath = new Map(
|
|
637
|
-
|
|
662
|
+
renderedMethods.map((method) => [`${method.namespace}.${method.method}`, method]),
|
|
638
663
|
);
|
|
639
664
|
|
|
640
665
|
const describe = Effect.fnUntraced(function* (
|
|
@@ -662,7 +687,7 @@ const make = <
|
|
|
662
687
|
),
|
|
663
688
|
);
|
|
664
689
|
|
|
665
|
-
const selectedMethods: Array<
|
|
690
|
+
const selectedMethods: Array<RenderedMethod> = [];
|
|
666
691
|
|
|
667
692
|
for (const path of paths) {
|
|
668
693
|
const method = methodsByPath.get(path);
|
|
@@ -799,7 +824,13 @@ const make = <
|
|
|
799
824
|
});
|
|
800
825
|
|
|
801
826
|
const build = Effect.gen(function* () {
|
|
802
|
-
const captured =
|
|
827
|
+
const captured =
|
|
828
|
+
yield* Effect.context<
|
|
829
|
+
Tool.HandlerServices<
|
|
830
|
+
CodeModeSelectedRecord<Namespaces>[keyof CodeModeSelectedRecord<Namespaces>]
|
|
831
|
+
>
|
|
832
|
+
>();
|
|
833
|
+
|
|
803
834
|
const redactionServices = yield* Effect.context<Exclude<RedactionRequirements, Scope.Scope>>();
|
|
804
835
|
const configuredRedactor = options.redactEgress;
|
|
805
836
|
|
|
@@ -975,20 +1006,10 @@ const make = <
|
|
|
975
1006
|
);
|
|
976
1007
|
}).pipe(
|
|
977
1008
|
Effect.scoped,
|
|
978
|
-
//
|
|
979
|
-
// inside another Run can never shadow it; the captured construction
|
|
980
|
-
// context supplies the selected handlers' services (same idiom as
|
|
981
|
-
// Subagent.layer). TypeScript cannot reduce the deferred Exclude
|
|
982
|
-
// over the generic namespace record, so the same private-assertion
|
|
983
|
-
// contract as the engine's provideHookServices pins the identity
|
|
984
|
-
// that providing the captured Context leaves no requirements; it
|
|
985
|
-
// never bypasses validation.
|
|
1009
|
+
// Keep invocation authority innermost while restoring the declared handler services.
|
|
986
1010
|
Effect.provideService(ToolBroker, broker),
|
|
987
|
-
Effect.
|
|
988
|
-
)
|
|
989
|
-
CodeExecutionResult,
|
|
990
|
-
CodeExecutionError | ToolBrokerUnavailableError | ToolBrokerConfigurationError
|
|
991
|
-
>;
|
|
1011
|
+
Effect.updateContext((current: Context.Context<never>) => Context.merge(current, captured)),
|
|
1012
|
+
);
|
|
992
1013
|
|
|
993
1014
|
return yield* execution.pipe(
|
|
994
1015
|
Effect.catch((error) => failureEgress(error).pipe(Effect.flatMap(Effect.fail))),
|
|
@@ -1052,6 +1073,9 @@ const make = <
|
|
|
1052
1073
|
never,
|
|
1053
1074
|
| CodeExecutor
|
|
1054
1075
|
| Tool.HandlersFor<CodeModeSelectedRecord<Namespaces>>
|
|
1076
|
+
| Tool.HandlerServices<
|
|
1077
|
+
CodeModeSelectedRecord<Namespaces>[keyof CodeModeSelectedRecord<Namespaces>]
|
|
1078
|
+
>
|
|
1055
1079
|
| Exclude<RedactionRequirements, Scope.Scope>
|
|
1056
1080
|
>,
|
|
1057
1081
|
) as unknown as Layer.Layer<
|
|
@@ -141,8 +141,8 @@ const isNotificationTag = (tag: string): boolean => tag.startsWith("notification
|
|
|
141
141
|
const isRpcClientError = Schema.is(RpcClientError.RpcClientError);
|
|
142
142
|
|
|
143
143
|
const protocolDefect = (message: string, cause?: unknown): RpcClientError.RpcClientError =>
|
|
144
|
-
|
|
145
|
-
reason:
|
|
144
|
+
RpcClientError.RpcClientError.make({
|
|
145
|
+
reason: RpcClientError.RpcClientDefect.make({ message, cause }),
|
|
146
146
|
});
|
|
147
147
|
|
|
148
148
|
const InitializeProtocolVersion = Schema.Struct({ protocolVersion: Schema.String });
|
|
@@ -41,47 +41,46 @@ const host: Effect.Effect<MessagingHost["Service"], MessagingError, MessagingHos
|
|
|
41
41
|
),
|
|
42
42
|
);
|
|
43
43
|
|
|
44
|
-
const dispatch = <Name extends string, Input extends Schema.Top>(
|
|
44
|
+
const dispatch = Effect.fnUntraced(function* <Name extends string, Input extends Schema.Top>(
|
|
45
45
|
declaration: Peer<Name, Input>,
|
|
46
46
|
input: Input["Type"],
|
|
47
47
|
options: { readonly idempotencyKey: IdempotencyKey; readonly inReplyTo?: MessageRef },
|
|
48
48
|
operation: "send" | "reply",
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
?
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
});
|
|
49
|
+
) {
|
|
50
|
+
const service = yield* host;
|
|
51
|
+
const invalid = () => MessagingError.make({ operation, reason: "invalid-input" });
|
|
52
|
+
|
|
53
|
+
const idempotencyKey = yield* Schema.decodeEffect(IdempotencyKey)(options.idempotencyKey).pipe(
|
|
54
|
+
Effect.mapError(invalid),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const encodedInput = yield* Schema.encodeEffect(declaration.target.input)(input).pipe(
|
|
58
|
+
Effect.mapError(invalid),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const inReplyTo =
|
|
62
|
+
options.inReplyTo === undefined
|
|
63
|
+
? undefined
|
|
64
|
+
: yield* Schema.decodeEffect(MessageRef)(options.inReplyTo).pipe(Effect.mapError(invalid));
|
|
65
|
+
|
|
66
|
+
const request = {
|
|
67
|
+
...declaration,
|
|
68
|
+
encodedInput,
|
|
69
|
+
idempotencyKey,
|
|
70
|
+
...(inReplyTo === undefined ? {} : { inReplyTo }),
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const result =
|
|
74
|
+
operation === "reply"
|
|
75
|
+
? inReplyTo === undefined
|
|
76
|
+
? yield* invalid()
|
|
77
|
+
: yield* service.reply({ ...request, inReplyTo })
|
|
78
|
+
: yield* service.send(request);
|
|
79
|
+
|
|
80
|
+
return yield* Schema.decodeEffect(MessageStatus)(result).pipe(
|
|
81
|
+
Effect.mapError(() => MessagingError.make({ operation, reason: "corrupt" })),
|
|
82
|
+
);
|
|
83
|
+
});
|
|
85
84
|
|
|
86
85
|
/** Retain a durable message. Its status distinguishes outbound retention from destination acceptance. */
|
|
87
86
|
export const send = <Name extends string, Input extends Schema.Top>(
|
|
@@ -99,36 +98,33 @@ export const reply = <Name extends string, Input extends Schema.Top>(
|
|
|
99
98
|
) => dispatch(declaration, input, { ...options, inReplyTo }, "reply");
|
|
100
99
|
|
|
101
100
|
/** Return bounded provenance for messages from this peer, without granting permission to reply. */
|
|
102
|
-
export const inbox = <Name extends string, Input extends Schema.Top>(
|
|
101
|
+
export const inbox = Effect.fnUntraced(function* <Name extends string, Input extends Schema.Top>(
|
|
103
102
|
declaration: Peer<Name, Input>,
|
|
104
103
|
options: { readonly after?: number; readonly limit?: number } = {},
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
const service = yield* host;
|
|
104
|
+
) {
|
|
105
|
+
const service = yield* host;
|
|
108
106
|
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
return yield* service.inbox({ ...declaration, ...options, limit: options.limit ?? 20 });
|
|
108
|
+
});
|
|
111
109
|
|
|
112
|
-
export const inspect = <Name extends string, Input extends Schema.Top>(
|
|
110
|
+
export const inspect = Effect.fnUntraced(function* <Name extends string, Input extends Schema.Top>(
|
|
113
111
|
declaration: Peer<Name, Input>,
|
|
114
112
|
message: MessageRef,
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
const service = yield* host;
|
|
113
|
+
) {
|
|
114
|
+
const service = yield* host;
|
|
118
115
|
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
return yield* service.inspect({ ...declaration, message });
|
|
117
|
+
});
|
|
121
118
|
|
|
122
119
|
/** Explicitly renew a parked delivery's bounded retry budget, retaining its complete frozen envelope. */
|
|
123
|
-
export const retry = <Name extends string, Input extends Schema.Top>(
|
|
120
|
+
export const retry = Effect.fnUntraced(function* <Name extends string, Input extends Schema.Top>(
|
|
124
121
|
declaration: Peer<Name, Input>,
|
|
125
122
|
message: MessageRef,
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
const service = yield* host;
|
|
123
|
+
) {
|
|
124
|
+
const service = yield* host;
|
|
129
125
|
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
return yield* service.retry({ ...declaration, message });
|
|
127
|
+
});
|
|
132
128
|
|
|
133
129
|
const modelKey = Effect.fnUntraced(function* () {
|
|
134
130
|
const source = yield* (yield* host).context;
|
|
@@ -177,8 +177,10 @@ export const prepareModelContext = <
|
|
|
177
177
|
>(
|
|
178
178
|
snapshot: ThreadSnapshot,
|
|
179
179
|
transforms?: { readonly [Index in keyof Requirements]: ContextTransform<Requirements[Index]> },
|
|
180
|
-
): Effect.Effect<PreparedModelContext, ContextTransformError, Requirements[number]> =>
|
|
181
|
-
|
|
180
|
+
): Effect.Effect<PreparedModelContext, ContextTransformError, Requirements[number]> => {
|
|
181
|
+
const declared: ReadonlyArray<ContextTransform<Requirements[number]>> = transforms ?? [];
|
|
182
|
+
|
|
183
|
+
return declared
|
|
182
184
|
.reduce<
|
|
183
185
|
Effect.Effect<ReadonlyArray<ModelContextMessage>, ContextTransformError, Requirements[number]>
|
|
184
186
|
>(
|
|
@@ -198,6 +200,7 @@ export const prepareModelContext = <
|
|
|
198
200
|
}),
|
|
199
201
|
),
|
|
200
202
|
);
|
|
203
|
+
};
|
|
201
204
|
|
|
202
205
|
const exactSourceRange = (
|
|
203
206
|
snapshot: ThreadSnapshot,
|
|
@@ -35,28 +35,67 @@ interface RedactionCounter {
|
|
|
35
35
|
nodes: number;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const
|
|
38
|
+
const encodingFailure = () =>
|
|
39
|
+
RedactionError.make({
|
|
40
|
+
reason: "encoding-failed",
|
|
41
|
+
message: "Could not encode the structurally redacted preview",
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const redactValue = Effect.fnUntraced(function* (
|
|
45
|
+
value: unknown,
|
|
46
|
+
depth: number,
|
|
47
|
+
counter: RedactionCounter,
|
|
48
|
+
): Effect.fn.Return<Schema.Json, RedactionError> {
|
|
39
49
|
if (depth > MAX_REDACTION_DEPTH) {
|
|
40
|
-
|
|
50
|
+
return yield* RedactionError.make({
|
|
41
51
|
reason: "input-too-deep",
|
|
42
52
|
message: `Decoded value exceeds redaction depth ${MAX_REDACTION_DEPTH}`,
|
|
43
53
|
});
|
|
44
54
|
}
|
|
45
55
|
counter.nodes += 1;
|
|
46
56
|
if (counter.nodes > MAX_REDACTION_NODES) {
|
|
47
|
-
|
|
57
|
+
return yield* RedactionError.make({
|
|
48
58
|
reason: "input-too-large",
|
|
49
59
|
message: `Decoded value exceeds redaction node count ${MAX_REDACTION_NODES}`,
|
|
50
60
|
});
|
|
51
61
|
}
|
|
52
|
-
|
|
53
|
-
|
|
62
|
+
|
|
63
|
+
const collection = yield* Effect.try({
|
|
64
|
+
try: () => {
|
|
65
|
+
if (Array.isArray(value)) {
|
|
66
|
+
const redacted: Array<Schema.Json> = [];
|
|
67
|
+
|
|
68
|
+
redacted.length = value.length;
|
|
69
|
+
|
|
70
|
+
return { _tag: "Array" as const, values: value, redacted };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return value !== null && typeof value === "object"
|
|
74
|
+
? { _tag: "Object" as const, entries: Object.entries(value) }
|
|
75
|
+
: undefined;
|
|
76
|
+
},
|
|
77
|
+
catch: encodingFailure,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (collection?._tag === "Array") {
|
|
81
|
+
const { redacted } = collection;
|
|
82
|
+
|
|
83
|
+
for (let index = 0; index < redacted.length; index += 1) {
|
|
84
|
+
const item = yield* Effect.try({
|
|
85
|
+
try: () => (index in collection.values ? { value: collection.values[index] } : undefined),
|
|
86
|
+
catch: encodingFailure,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
if (item !== undefined) redacted[index] = yield* redactValue(item.value, depth + 1, counter);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return redacted;
|
|
54
93
|
}
|
|
55
|
-
if (
|
|
94
|
+
if (collection?._tag === "Object") {
|
|
56
95
|
const redacted: Record<string, Schema.Json> = {};
|
|
57
96
|
|
|
58
|
-
for (const [key, item] of
|
|
59
|
-
redacted[key] = redactValue(item, depth + 1, counter);
|
|
97
|
+
for (const [key, item] of collection.entries) {
|
|
98
|
+
redacted[key] = yield* redactValue(item, depth + 1, counter);
|
|
60
99
|
}
|
|
61
100
|
|
|
62
101
|
return redacted;
|
|
@@ -72,7 +111,7 @@ const redactValue = (value: unknown, depth: number, counter: RedactionCounter):
|
|
|
72
111
|
if (typeof value === "boolean") return "[REDACTED:boolean]";
|
|
73
112
|
|
|
74
113
|
return "[REDACTED:unsupported]";
|
|
75
|
-
};
|
|
114
|
+
});
|
|
76
115
|
|
|
77
116
|
const truncateUtf8 = (value: string, maxBytes: number): string => {
|
|
78
117
|
if (utf8ByteLength(value) <= maxBytes) {
|
|
@@ -128,30 +167,21 @@ export const redactedTranscript = (
|
|
|
128
167
|
* Tool-specific Layers may expose explicitly reviewed fields instead.
|
|
129
168
|
*/
|
|
130
169
|
export const StructuralRedactorLive = Layer.succeed(Redactor)({
|
|
131
|
-
redact: (decodedValue)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}).pipe(
|
|
146
|
-
Effect.flatMap((preview) =>
|
|
147
|
-
Schema.decodeEffect(RedactedPreview)(preview).pipe(
|
|
148
|
-
Effect.mapError(() =>
|
|
149
|
-
RedactionError.make({
|
|
150
|
-
reason: "encoding-failed",
|
|
151
|
-
message: "Redacted preview did not satisfy its bounded schema",
|
|
152
|
-
}),
|
|
153
|
-
),
|
|
154
|
-
),
|
|
170
|
+
redact: Effect.fnUntraced(function* (decodedValue) {
|
|
171
|
+
const structurallyRedacted = yield* redactValue(decodedValue, 0, { nodes: 0 });
|
|
172
|
+
|
|
173
|
+
const preview = yield* Effect.try({
|
|
174
|
+
try: () => truncateUtf8(JSON.stringify(structurallyRedacted), MAX_REDACTED_PREVIEW_BYTES),
|
|
175
|
+
catch: encodingFailure,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
return yield* Schema.decodeEffect(RedactedPreview)(preview).pipe(
|
|
179
|
+
Effect.mapError(() =>
|
|
180
|
+
RedactionError.make({
|
|
181
|
+
reason: "encoding-failed",
|
|
182
|
+
message: "Redacted preview did not satisfy its bounded schema",
|
|
183
|
+
}),
|
|
155
184
|
),
|
|
156
|
-
)
|
|
185
|
+
);
|
|
186
|
+
}),
|
|
157
187
|
});
|
|
@@ -82,70 +82,67 @@ export const toRunApprovalHook = (
|
|
|
82
82
|
| RedactionError,
|
|
83
83
|
ApprovalResolver | ApprovalAudit | Redactor
|
|
84
84
|
> => ({
|
|
85
|
-
request: (engineRequest)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}),
|
|
94
|
-
),
|
|
95
|
-
);
|
|
85
|
+
request: Effect.fnUntraced(function* (engineRequest) {
|
|
86
|
+
const validatedPolicy = yield* Schema.decodeEffect(RunApprovalAdapterPolicySchema)(policy).pipe(
|
|
87
|
+
Effect.mapError((error) =>
|
|
88
|
+
ApprovalAdapterError.make({
|
|
89
|
+
message: `Approval adapter policy is invalid: ${error.message}`,
|
|
90
|
+
}),
|
|
91
|
+
),
|
|
92
|
+
);
|
|
96
93
|
|
|
97
|
-
|
|
94
|
+
const now = yield* Clock.currentTimeMillis;
|
|
98
95
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
const metadata = yield* Effect.try({
|
|
97
|
+
try: () => ({
|
|
98
|
+
actionSummary: policy.actionSummary(engineRequest),
|
|
99
|
+
resourceTargets: policy.resourceTargets(engineRequest),
|
|
100
|
+
}),
|
|
101
|
+
catch: () =>
|
|
102
|
+
ApprovalAdapterError.make({
|
|
103
|
+
message: "Approval policy failed while describing the native Tool request",
|
|
103
104
|
}),
|
|
104
|
-
|
|
105
|
-
ApprovalAdapterError.make({
|
|
106
|
-
message: "Approval policy failed while describing the native Tool request",
|
|
107
|
-
}),
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
const draft = yield* Schema.decodeEffect(ApprovalRequestDraft)({
|
|
111
|
-
requestId: engineRequest.request.approvalId,
|
|
112
|
-
runId: engineRequest.runId,
|
|
113
|
-
threadId: engineRequest.threadId,
|
|
114
|
-
toolCallId: engineRequest.toolCallId,
|
|
115
|
-
toolName: engineRequest.toolName,
|
|
116
|
-
actionSummary: metadata.actionSummary,
|
|
117
|
-
resourceTargets: metadata.resourceTargets,
|
|
118
|
-
risk: validatedPolicy.risk,
|
|
119
|
-
expiresAt: DateTime.formatIso(
|
|
120
|
-
DateTime.toUtc(DateTime.makeUnsafe(now + validatedPolicy.expiresInMillis)),
|
|
121
|
-
),
|
|
122
|
-
denial: validatedPolicy.denial,
|
|
123
|
-
}).pipe(
|
|
124
|
-
Effect.mapError((error) =>
|
|
125
|
-
ApprovalAdapterError.make({
|
|
126
|
-
message: `Approval adapter policy is invalid: ${error.message}`,
|
|
127
|
-
}),
|
|
128
|
-
),
|
|
129
|
-
);
|
|
105
|
+
});
|
|
130
106
|
|
|
131
|
-
|
|
132
|
-
|
|
107
|
+
const draft = yield* Schema.decodeEffect(ApprovalRequestDraft)({
|
|
108
|
+
requestId: engineRequest.request.approvalId,
|
|
109
|
+
runId: engineRequest.runId,
|
|
110
|
+
threadId: engineRequest.threadId,
|
|
111
|
+
toolCallId: engineRequest.toolCallId,
|
|
112
|
+
toolName: engineRequest.toolName,
|
|
113
|
+
actionSummary: metadata.actionSummary,
|
|
114
|
+
resourceTargets: metadata.resourceTargets,
|
|
115
|
+
risk: validatedPolicy.risk,
|
|
116
|
+
expiresAt: DateTime.formatIso(
|
|
117
|
+
DateTime.toUtc(DateTime.makeUnsafe(now + validatedPolicy.expiresInMillis)),
|
|
118
|
+
),
|
|
119
|
+
denial: validatedPolicy.denial,
|
|
120
|
+
}).pipe(
|
|
121
|
+
Effect.mapError((error) =>
|
|
122
|
+
ApprovalAdapterError.make({
|
|
123
|
+
message: `Approval adapter policy is invalid: ${error.message}`,
|
|
124
|
+
}),
|
|
125
|
+
),
|
|
126
|
+
);
|
|
133
127
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
if (decision.timedOut && request.denial === "recoverable") {
|
|
138
|
-
return {
|
|
139
|
-
_tag: "unresolved" as const,
|
|
140
|
-
reason: decision.reason,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
128
|
+
const request = yield* makeApprovalRequest(draft, engineRequest.parameters);
|
|
129
|
+
const decision = yield* requestApproval(request);
|
|
143
130
|
|
|
131
|
+
if (decision._tag === "ApprovalApproved") {
|
|
132
|
+
return { _tag: "approved" as const };
|
|
133
|
+
}
|
|
134
|
+
if (decision.timedOut && request.denial === "recoverable") {
|
|
144
135
|
return {
|
|
145
|
-
_tag: "
|
|
136
|
+
_tag: "unresolved" as const,
|
|
146
137
|
reason: decision.reason,
|
|
147
138
|
};
|
|
148
|
-
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
_tag: "denied" as const,
|
|
143
|
+
reason: decision.reason,
|
|
144
|
+
};
|
|
145
|
+
}),
|
|
149
146
|
});
|
|
150
147
|
|
|
151
148
|
/**
|