effect-agent 0.1.0-beta.97 → 0.1.0-beta.99

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.
Files changed (143) hide show
  1. package/dist/{AgentRuntime-B64362Id.d.mts → AgentRuntime-BMzrJos6.d.mts} +2 -2
  2. package/dist/{AgentRuntime-Cdvqw7l_.mjs → AgentRuntime-BWOnNc0d.mjs} +78 -42
  3. package/dist/AgentRuntime-BWOnNc0d.mjs.map +1 -0
  4. package/dist/{DurableAgentRuntime-DbUvZHDZ.mjs → DurableAgentRuntime-BE_OjQjz.mjs} +471 -252
  5. package/dist/DurableAgentRuntime-BE_OjQjz.mjs.map +1 -0
  6. package/dist/{DurableFailpoint-DQJet828.d.mts → DurableFailpoint-mx3-nsxU.d.mts} +3 -3
  7. package/dist/{EventSource-D6PAAEyK.d.mts → EventSource-BZ73J0s5.d.mts} +3 -3
  8. package/dist/{PreparedInputAdmission-omMbwd--.d.mts → PreparedInputAdmission-BkeI-Xvr.d.mts} +4 -4
  9. package/dist/{Records-CV49DgQK.d.mts → Records-BIiRLqlz.d.mts} +92 -128
  10. package/dist/{Records-BAutSSnJ.mjs → Records-DR1xtbXY.mjs} +35 -8
  11. package/dist/Records-DR1xtbXY.mjs.map +1 -0
  12. package/dist/{RunJournal-DRRRZmG7.mjs → RunJournal-DNs3PM4K.mjs} +80 -23
  13. package/dist/RunJournal-DNs3PM4K.mjs.map +1 -0
  14. package/dist/{RunOptions-Clj8cLsp.d.mts → RunOptions-Bruk54SE.d.mts} +13 -4
  15. package/dist/{Schedule-DePbGfgd.d.mts → Schedule-BNFlluAl.d.mts} +2 -2
  16. package/dist/{Scheduling-C3QpYn0W.mjs → Scheduling-HFH0pST1.mjs} +2 -2
  17. package/dist/{Scheduling-C3QpYn0W.mjs.map → Scheduling-HFH0pST1.mjs.map} +1 -1
  18. package/dist/{Subagent-Cbfzylz1.mjs → Subagent-C2s8PFrd.mjs} +2 -2
  19. package/dist/{Subagent-Cbfzylz1.mjs.map → Subagent-C2s8PFrd.mjs.map} +1 -1
  20. package/dist/{Subagent-Bm1dRecN.d.mts → Subagent-m7ywTCe4.d.mts} +3 -3
  21. package/dist/{Subscription-BR_8Cxh3.d.mts → Subscription-BCQ3L9Zp.d.mts} +3 -3
  22. package/dist/{SubscriptionInput-B95sQbuk.d.mts → SubscriptionInput-Cqu4_RW3.d.mts} +3 -3
  23. package/dist/{ToolReconciler-DQVaJfpE.d.mts → ToolReconciler-BmVRAHKs.d.mts} +8 -4
  24. package/dist/agent-registration-cXpB8cBU.mjs +199 -0
  25. package/dist/agent-registration-cXpB8cBU.mjs.map +1 -0
  26. package/dist/capabilities/Commands.d.mts +1 -1
  27. package/dist/capabilities/RunHooks.d.mts +1 -1
  28. package/dist/capabilities/Subagent.d.mts +1 -1
  29. package/dist/capabilities/Subagent.mjs +1 -1
  30. package/dist/durable/ActivityStore.d.mts +1 -1
  31. package/dist/durable/ActivityStore.mjs +1 -1
  32. package/dist/durable/Admin.d.mts +1 -1
  33. package/dist/durable/Admin.mjs +12 -10
  34. package/dist/durable/Admin.mjs.map +1 -1
  35. package/dist/durable/AgentRegistration.d.mts +2 -2
  36. package/dist/durable/AgentRegistration.mjs +4 -8
  37. package/dist/durable/AgentRegistration.mjs.map +1 -1
  38. package/dist/durable/Certification.d.mts +2 -2
  39. package/dist/durable/CommittedActivity.d.mts +1 -1
  40. package/dist/durable/CommittedActivity.mjs +1 -1
  41. package/dist/durable/Digest.d.mts +1 -1
  42. package/dist/durable/Digest.mjs +1 -1
  43. package/dist/durable/DurableAgentRuntime.d.mts +1 -1
  44. package/dist/durable/DurableAgentRuntime.mjs +1 -1
  45. package/dist/durable/DurableFailpoint.d.mts +1 -1
  46. package/dist/durable/DurableFailpoint.mjs +2 -0
  47. package/dist/durable/DurableFailpoint.mjs.map +1 -1
  48. package/dist/durable/DurableFailpointTestControl.d.mts +1 -1
  49. package/dist/durable/EventSource.d.mts +1 -1
  50. package/dist/durable/EventSource.mjs +1 -1
  51. package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
  52. package/dist/durable/GitHubWorkflowSource.mjs +1 -1
  53. package/dist/durable/MessageDelivery.d.mts +3 -3
  54. package/dist/durable/MessageDelivery.mjs +1 -1
  55. package/dist/durable/MessageDeliveryStoreConformance.d.mts +39 -39
  56. package/dist/durable/MessageDeliveryStoreConformance.mjs +1 -1
  57. package/dist/durable/PersistentHistory.d.mts +1 -1
  58. package/dist/durable/PersistentHistory.mjs +2 -2
  59. package/dist/durable/PreparedInputAdmission.d.mts +1 -1
  60. package/dist/durable/Records.d.mts +2 -2
  61. package/dist/durable/Records.mjs +2 -2
  62. package/dist/durable/Recovery.d.mts +1 -1
  63. package/dist/durable/Recovery.mjs +9 -9
  64. package/dist/durable/Recovery.mjs.map +1 -1
  65. package/dist/durable/RunJournal.d.mts +2 -2
  66. package/dist/durable/RunJournal.mjs +2 -2
  67. package/dist/durable/Schedule.d.mts +1 -1
  68. package/dist/durable/Schedule.mjs +1 -1
  69. package/dist/durable/ScheduleStoreConformance.d.mts +1 -1
  70. package/dist/durable/ScheduleStoreConformance.mjs +1 -1
  71. package/dist/durable/ScheduleTransition.d.mts +1 -1
  72. package/dist/durable/ScheduleTransition.mjs +1 -1
  73. package/dist/durable/Scheduling.d.mts +2 -2
  74. package/dist/durable/Scheduling.mjs +1 -1
  75. package/dist/durable/SqlStorageV2Upgrade.d.mts +2 -2
  76. package/dist/durable/SqlStorageV2Upgrade.mjs +1 -1
  77. package/dist/durable/SqlSubscriptionStore.d.mts +2 -2
  78. package/dist/durable/SqlSubscriptionStore.mjs +1 -1
  79. package/dist/durable/SubmissionLedger.d.mts +1 -1
  80. package/dist/durable/SubmissionLedger.mjs +14 -13
  81. package/dist/durable/SubmissionLedger.mjs.map +1 -1
  82. package/dist/durable/SubmissionLedgerConformance.d.mts +1 -1
  83. package/dist/durable/SubmissionLedgerConformance.mjs +9 -2
  84. package/dist/durable/SubmissionLedgerConformance.mjs.map +1 -1
  85. package/dist/durable/SubmissionStatus.d.mts +1 -1
  86. package/dist/durable/Subscription.d.mts +1 -1
  87. package/dist/durable/Subscription.mjs +1 -1
  88. package/dist/durable/SubscriptionInput.d.mts +1 -1
  89. package/dist/durable/SubscriptionInput.mjs +2 -2
  90. package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
  91. package/dist/durable/SubscriptionStoreConformance.mjs +1 -1
  92. package/dist/durable/SubscriptionTools.d.mts +3 -3
  93. package/dist/durable/SubscriptionTransition.d.mts +1 -1
  94. package/dist/durable/SubscriptionTransition.mjs +1 -1
  95. package/dist/durable/Subscriptions.d.mts +5 -5
  96. package/dist/durable/Subscriptions.mjs +1 -1
  97. package/dist/durable/ThreadContextHistory.d.mts +1 -1
  98. package/dist/durable/ThreadContextHistory.mjs +1 -1
  99. package/dist/durable/ThreadContextHistoryProjection.d.mts +1 -1
  100. package/dist/durable/ThreadContextHistoryProjection.mjs +1 -1
  101. package/dist/durable/ThreadInvariants.d.mts +4 -2
  102. package/dist/durable/ThreadInvariants.mjs +49 -3
  103. package/dist/durable/ThreadInvariants.mjs.map +1 -1
  104. package/dist/durable/ThreadProjection.d.mts +1 -1
  105. package/dist/durable/ThreadProjection.mjs +1 -1
  106. package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
  107. package/dist/durable/ThreadStore.d.mts +1 -1
  108. package/dist/durable/ThreadStore.mjs +1 -1
  109. package/dist/durable/ThreadStoreConformance.d.mts +1 -1
  110. package/dist/durable/ThreadStoreConformance.mjs +1 -1
  111. package/dist/durable/ToolReconciler.d.mts +1 -1
  112. package/dist/durable/ToolReconciler.mjs +9 -5
  113. package/dist/durable/ToolReconciler.mjs.map +1 -1
  114. package/dist/durable/WorkerHost.d.mts +1 -1
  115. package/dist/engine/AgentRuntime.d.mts +1 -1
  116. package/dist/engine/AgentRuntime.mjs +1 -1
  117. package/dist/engine/RunOptions.d.mts +1 -1
  118. package/dist/engine/RunOptions.mjs.map +1 -1
  119. package/dist/index.d.mts +11 -11
  120. package/dist/index.mjs +6 -6
  121. package/package.json +1 -1
  122. package/src/durable/Admin.ts +20 -11
  123. package/src/durable/AgentRegistration.ts +1 -5
  124. package/src/durable/DurableAgentRuntime.ts +947 -464
  125. package/src/durable/DurableFailpoint.ts +2 -0
  126. package/src/durable/Records.ts +30 -5
  127. package/src/durable/Recovery.ts +8 -8
  128. package/src/durable/RunJournal.ts +128 -51
  129. package/src/durable/SubmissionLedger.ts +13 -12
  130. package/src/durable/SubmissionLedgerConformance.ts +13 -2
  131. package/src/durable/ThreadInvariants.ts +70 -5
  132. package/src/durable/ToolReconciler.ts +7 -3
  133. package/src/durable/internal/agent-registration.ts +65 -414
  134. package/src/durable/internal/messaging-host.ts +0 -2
  135. package/src/durable/internal/worker-host.ts +34 -96
  136. package/src/engine/RunOptions.ts +13 -3
  137. package/src/engine/internal/agent-runtime.ts +160 -106
  138. package/dist/AgentRuntime-Cdvqw7l_.mjs.map +0 -1
  139. package/dist/DurableAgentRuntime-DbUvZHDZ.mjs.map +0 -1
  140. package/dist/Records-BAutSSnJ.mjs.map +0 -1
  141. package/dist/RunJournal-DRRRZmG7.mjs.map +0 -1
  142. package/dist/agent-registration-CXGDwvJH.mjs +0 -379
  143. package/dist/agent-registration-CXGDwvJH.mjs.map +0 -1
@@ -102,6 +102,7 @@ import type { Selection } from "../../core/ToolExposure.ts";
102
102
  import { AdditionalToolCatalog, DiscoveryTool, Snapshot } from "../../core/ToolExposure.ts";
103
103
  import {
104
104
  ToolParameterRejection,
105
+ TruncatedToolResult,
105
106
  applyToolResultBounds,
106
107
  unserializableToolResult,
107
108
  type ToolResultBounds,
@@ -697,6 +698,8 @@ type ProviderResultEventPayload =
697
698
  // fail-closed only while the additional staging allocation itself is deterministic and bounded.
698
699
  const MAX_STAGED_PROVIDER_EVENTS = 256;
699
700
  const MAX_STAGED_PROVIDER_BYTES = 1024 * 1024;
701
+ /** Saved outcomes obey the canonical JSON ceiling, independently of today's display policy. */
702
+ const MAX_RESUMED_RESULT_BYTES = 1024 * 1024;
700
703
 
701
704
  const DEFAULT_RUN_BUFFER_LIMITS = {
702
705
  maxModelResponseParts: 16_384,
@@ -1278,7 +1281,7 @@ const effectiveRunBounds = (
1278
1281
  });
1279
1282
 
1280
1283
  const decodeResumedSettledCall = Effect.fn("AgentRuntime.decodeResumedSettledCall")(
1281
- (input: unknown, maxResultBytes: number, providerCallIds: ReadonlySet<string>) =>
1284
+ (input: unknown) =>
1282
1285
  Effect.gen(function* () {
1283
1286
  const raw = yield* Effect.try({
1284
1287
  try: () => {
@@ -1320,12 +1323,7 @@ const decodeResumedSettledCall = Effect.fn("AgentRuntime.decodeResumedSettledCal
1320
1323
  }),
1321
1324
  });
1322
1325
 
1323
- const result = boundedCanonicalJsonSnapshot(
1324
- raw.result,
1325
- typeof raw.id === "string" && providerCallIds.has(raw.id)
1326
- ? MAX_STAGED_PROVIDER_BYTES
1327
- : maxResultBytes,
1328
- );
1326
+ const result = boundedCanonicalJsonSnapshot(raw.result, MAX_RESUMED_RESULT_BYTES);
1329
1327
 
1330
1328
  if (result === undefined) {
1331
1329
  return yield* ModelProtocolError.make({
@@ -2471,13 +2469,17 @@ const executeToolBatch = <Tools extends Record<string, Tool.Any>, HookError, Hoo
2471
2469
 
2472
2470
  // Resolve the whole batch before constructing streams. Only calls with recorded
2473
2471
  // parameter rejection evidence bypass executable-parameter decoding and approval.
2474
- const prepared = yield* Effect.forEach(calls, (call, declarationIndex) =>
2475
- prepareToolCall(
2476
- toolkit,
2477
- call,
2478
- declarationIndex,
2479
- trace.toolParameterRejections.get(call.id),
2472
+ const prepared = yield* Effect.forEach(
2473
+ calls.flatMap((call, declarationIndex) =>
2474
+ settledCallIds?.has(call.id) ? [] : [{ call, declarationIndex }],
2480
2475
  ),
2476
+ ({ call, declarationIndex }) =>
2477
+ prepareToolCall(
2478
+ toolkit,
2479
+ call,
2480
+ declarationIndex,
2481
+ trace.toolParameterRejections.get(call.id),
2482
+ ),
2481
2483
  );
2482
2484
 
2483
2485
  if (
@@ -7038,6 +7040,7 @@ const toolBatchContinuation = <
7038
7040
  if (
7039
7041
  rolloverResult !== undefined &&
7040
7042
  !rolloverResult.isFailure &&
7043
+ trace.applicationCallDescriptors.some((call) => call.toolCallId === rolloverResult.id) &&
7041
7044
  hasTool(agent.definition.toolkit.tools, rolloverResult.name) &&
7042
7045
  Context.get(
7043
7046
  agent.definition.toolkit.tools[rolloverResult.name].annotations,
@@ -7067,6 +7070,7 @@ const toolBatchContinuation = <
7067
7070
 
7068
7071
  if (
7069
7072
  successfulResult !== undefined &&
7073
+ trace.applicationCallDescriptors.some((call) => call.toolCallId === successfulResult.id) &&
7070
7074
  (successfulResult.name === completion?.tool || actionCompletion !== undefined)
7071
7075
  ) {
7072
7076
  const call = trace.applicationCallDescriptors[0];
@@ -7146,13 +7150,10 @@ const toolBatchContinuation = <
7146
7150
  * Resume one canonically declared Tool batch without re-invoking the model
7147
7151
  * (the durable batch-resume seam consumed via `RunOptions.resume`).
7148
7152
  *
7149
- * The declared calls are re-validated through their Tool parameter Schemas
7150
- * before anything executes; a decode failure is a strict no-start boundary
7151
- * (RUN-004/STORE-006). The resumed Turn's response messages are rebuilt in
7152
- * canonical encoded form so official history matches the recorded response.
7153
- * Calls listed in `settled` are injected as final results without starting
7154
- * their handlers — recorded Tool outcomes never rerun — while approval
7155
- * preflight and durable preparation still cover the complete declared batch.
7153
+ * Only unfinished calls are validated through their current parameter Schemas before
7154
+ * execution. Settled siblings retain bounded canonical JSON without looking up old Tools.
7155
+ * The original response and declaration order remain intact; approval, authorization and
7156
+ * durable preparation cover only calls that can still execute.
7156
7157
  * No model request is made and no usage is consumed for the resumed Turn.
7157
7158
  */
7158
7159
  const makeResumeTurn = <
@@ -7197,10 +7198,14 @@ const makeResumeTurn = <
7197
7198
  const tools = agent.definition.toolkit.tools;
7198
7199
  const turn = resume.turn;
7199
7200
  const turnId = resume.turnId;
7201
+ const settledInputs = yield* snapshotResumedSettledCalls(resume, resume.calls.length);
7202
+ const settledCalls = yield* Effect.forEach(settledInputs, decodeResumedSettledCall);
7203
+ const recordedSettledIds = new Set(settledCalls.map((call) => call.id));
7200
7204
  const visibility = yield* RunToolVisibility;
7201
7205
 
7202
7206
  if (
7203
7207
  resume.toolExposure === undefined &&
7208
+ resume.calls.some((call) => !call.providerExecuted && !recordedSettledIds.has(call.id)) &&
7204
7209
  (agent.definition.toolExposure !== undefined ||
7205
7210
  context.toolSelection !== undefined ||
7206
7211
  visibility !== undefined)
@@ -7208,6 +7213,7 @@ const makeResumeTurn = <
7208
7213
  return yield* ModelProtocolError.make({
7209
7214
  message: "Resumed progressive Turn is missing its original Tool exposure",
7210
7215
  });
7216
+
7211
7217
  context.toolCatalog = yield* eligibleCatalog(
7212
7218
  agent.definition,
7213
7219
  { threadId: context.threadId, runId: context.runId, turn, input: context.input },
@@ -7219,24 +7225,19 @@ const makeResumeTurn = <
7219
7225
  const originalExposure = context.toolExposure;
7220
7226
 
7221
7227
  if (originalExposure !== undefined) {
7222
- yield* validateSelection(
7223
- { toolNames: originalExposure.exposedToolNames },
7224
- agent.definition,
7225
- context.toolCatalog,
7226
- false,
7227
- );
7228
- if (originalExposure.selection !== undefined)
7229
- yield* validateSelection(
7230
- originalExposure.selection,
7231
- agent.definition,
7232
- context.toolCatalog,
7233
- false,
7234
- );
7235
7228
  if (resume.calls.some((call) => !originalExposure.exposedToolNames.includes(call.name)))
7236
7229
  return yield* ModelProtocolError.make({
7237
7230
  message: "Resumed Tool call was not exposed in its original model request",
7238
7231
  });
7239
- context.toolSelection = originalExposure.selection;
7232
+ context.toolSelection =
7233
+ originalExposure.selection === undefined
7234
+ ? undefined
7235
+ : {
7236
+ ...originalExposure.selection,
7237
+ toolNames: originalExposure.selection.toolNames.filter((name) =>
7238
+ hasTool(tools, name),
7239
+ ),
7240
+ };
7240
7241
  }
7241
7242
 
7242
7243
  if (!Number.isInteger(turn) || turn <= 0) {
@@ -7300,35 +7301,33 @@ const makeResumeTurn = <
7300
7301
  call.providerExecuted ||
7301
7302
  call.name !== rejection.error.reason.toolName ||
7302
7303
  !sameJson(yield* decodeEventJson(call.params, "Tool parameters"), rejection.parameters) ||
7303
- trace.toolParameterRejections.has(call.id) ||
7304
- tools[call.name]?.failureMode !== "return"
7304
+ trace.toolParameterRejections.has(call.id)
7305
7305
  ) {
7306
7306
  return yield* ModelProtocolError.make({
7307
7307
  message: "Parameter rejection does not match recorded Tool Call on resume",
7308
7308
  });
7309
7309
  }
7310
7310
 
7311
- const validation = yield* Effect.result(
7312
- decodeToolCallParameters<Tools>(
7313
- tools[call.name] as ToolUnion<Tools>,
7314
- call.name,
7315
- call.params,
7316
- "resume",
7317
- ),
7318
- );
7319
-
7320
- if (Result.isSuccess(validation)) {
7321
- return yield* ModelProtocolError.make({
7322
- message: "Recorded parameter rejection contains valid arguments on resume",
7311
+ trace.toolParameterRejections.set(call.id, rejection);
7312
+ if (!recordedSettledIds.has(call.id)) {
7313
+ settledCalls.push({
7314
+ id: call.id,
7315
+ isFailure: true,
7316
+ result: yield* decodeEventJson(
7317
+ boundEncodedToolResult(rejection.error, agent.definition.policy.toolResultBounds),
7318
+ "Rejected Tool result",
7319
+ ),
7323
7320
  });
7321
+ recordedSettledIds.add(call.id);
7324
7322
  }
7325
- trace.toolParameterRejections.set(call.id, rejection);
7326
7323
  }
7327
7324
 
7328
7325
  for (const call of resume.calls) {
7329
- if (!hasTool(tools, call.name)) {
7326
+ if (!recordedSettledIds.has(call.id) && !hasTool(tools, call.name)) {
7330
7327
  return failRunEventStream(
7331
- ModelProtocolError.make({ message: `Turn resume declared unknown Tool ${call.name}` }),
7328
+ ModelProtocolError.make({
7329
+ message: `Turn resume declared unknown unfinished Tool ${call.name}`,
7330
+ }),
7332
7331
  );
7333
7332
  }
7334
7333
  if (trace.toolCalls.has(call.id)) {
@@ -7339,7 +7338,7 @@ const makeResumeTurn = <
7339
7338
  const tool = tools[call.name] as ToolUnion<Tools>;
7340
7339
  const toolCallId = yield* decodeToolCallId(call.id);
7341
7340
 
7342
- if (!trace.toolParameterRejections.has(call.id)) {
7341
+ if (!recordedSettledIds.has(call.id)) {
7343
7342
  yield* decodeToolCallParameters<Tools>(tool, call.name, call.params, "resume");
7344
7343
  }
7345
7344
  const parameters = yield* decodeEventJson(call.params, "Tool parameters");
@@ -7368,24 +7367,32 @@ const makeResumeTurn = <
7368
7367
  providerExecuted: false,
7369
7368
  }),
7370
7369
  );
7371
- trace.applicationCallDescriptors.push({
7372
- toolCallId,
7373
- toolName: call.name,
7374
- parameters,
7375
- executionClass: getToolExecutionClass(tool),
7376
- executionKind: getToolExecutionKind(tool.annotations),
7377
- });
7370
+ if (
7371
+ (!recordedSettledIds.has(call.id) || resume.settledCompletion === call.id) &&
7372
+ hasTool(tools, call.name)
7373
+ )
7374
+ trace.applicationCallDescriptors.push({
7375
+ toolCallId,
7376
+ toolName: call.name,
7377
+ parameters,
7378
+ executionClass: getToolExecutionClass(tool),
7379
+ executionKind: getToolExecutionKind(tool.annotations),
7380
+ });
7378
7381
  }
7379
7382
  const completionTool = agent.definition.completion?.tool;
7380
7383
 
7381
- const actionCompletionCall = trace.applicationToolCalls.find((call) =>
7384
+ const completionCandidates = trace.applicationToolCalls.filter(
7385
+ (call) => !recordedSettledIds.has(call.id) || resume.settledCompletion === call.id,
7386
+ );
7387
+
7388
+ const actionCompletionCall = completionCandidates.find((call) =>
7382
7389
  agent.definition.completionFromTools?.some((declaration) => declaration.tool === call.name),
7383
7390
  );
7384
7391
 
7385
7392
  if (
7386
7393
  (actionCompletionCall !== undefined ||
7387
7394
  (completionTool !== undefined &&
7388
- trace.applicationToolCalls.some((call) => call.name === completionTool))) &&
7395
+ completionCandidates.some((call) => call.name === completionTool))) &&
7389
7396
  trace.applicationToolCalls.length !== 1
7390
7397
  ) {
7391
7398
  return failRunEventStream(
@@ -7398,7 +7405,7 @@ const makeResumeTurn = <
7398
7405
  const completionBatch =
7399
7406
  completionTool !== undefined &&
7400
7407
  trace.applicationToolCalls.length === 1 &&
7401
- trace.applicationToolCalls[0]?.name === completionTool;
7408
+ completionCandidates[0]?.name === completionTool;
7402
7409
 
7403
7410
  if (
7404
7411
  (completionBatch &&
@@ -7421,33 +7428,26 @@ const makeResumeTurn = <
7421
7428
  }
7422
7429
  const settledIds = new Set<string>();
7423
7430
 
7424
- const providerCallIds = new Set(
7425
- [...declarationByCallId].filter(([, call]) => call.providerExecuted).map(([id]) => id),
7426
- );
7427
-
7428
- const settledInputs = yield* snapshotResumedSettledCalls(resume, declarationByCallId.size);
7429
-
7430
- for (const settledInput of settledInputs) {
7431
- const settledCall = yield* decodeResumedSettledCall(
7432
- settledInput,
7433
- agent.definition.policy.toolResultBounds.maxBytes,
7434
- providerCallIds,
7435
- );
7436
-
7431
+ for (const settledCall of settledCalls) {
7437
7432
  const rejection = trace.toolParameterRejections.get(settledCall.id);
7433
+ const rejectionJson = rejection === undefined ? undefined : JSON.stringify(rejection.error);
7434
+
7435
+ // An old policy may have truncated this already-settled error. Verify its exact
7436
+ // retained slices against the canonical rejection, without imposing today's bound.
7437
+ const matchesRejection =
7438
+ rejection === undefined ||
7439
+ sameJson(settledCall.result, rejection.error) ||
7440
+ (Schema.is(Schema.toEncoded(TruncatedToolResult))(settledCall.result) &&
7441
+ rejectionJson !== undefined &&
7442
+ settledCall.result.originalBytes === utf8ByteLength(rejectionJson) &&
7443
+ rejectionJson.startsWith(settledCall.result.head) &&
7444
+ rejectionJson.endsWith(settledCall.result.tail));
7438
7445
 
7439
7446
  if (
7440
7447
  rejection !== undefined &&
7441
7448
  (!settledCall.isFailure ||
7442
7449
  settledCall.toolSelection !== undefined ||
7443
- (settledCall.budgetRejected !== true &&
7444
- !sameJson(
7445
- settledCall.result,
7446
- yield* decodeEventJson(
7447
- boundEncodedToolResult(rejection.error, agent.definition.policy.toolResultBounds),
7448
- "Rejected Tool result",
7449
- ),
7450
- )))
7450
+ (settledCall.budgetRejected !== true && !matchesRejection))
7451
7451
  ) {
7452
7452
  return yield* ModelProtocolError.make({
7453
7453
  message: "Settled result contradicts parameter rejection on resume",
@@ -7490,12 +7490,12 @@ const makeResumeTurn = <
7490
7490
  ...(settledCall.toolSelection === undefined
7491
7491
  ? {}
7492
7492
  : {
7493
- toolSelection: yield* validateSelection(
7494
- settledCall.toolSelection,
7495
- agent.definition,
7496
- context.toolCatalog,
7497
- false,
7498
- ),
7493
+ toolSelection: {
7494
+ ...settledCall.toolSelection,
7495
+ toolNames: settledCall.toolSelection.toolNames.filter((name) =>
7496
+ hasTool(tools, name),
7497
+ ),
7498
+ },
7499
7499
  }),
7500
7500
  id: settledCall.id,
7501
7501
  name: declared.name,
@@ -8116,26 +8116,71 @@ function streamWithCompletion<
8116
8116
 
8117
8117
  const execution = Stream.unwrap(
8118
8118
  Effect.gen(function* () {
8119
- const decodedInput = yield* decodeInput(agent, input);
8119
+ const initial = yield* Effect.gen(function* () {
8120
+ if (options.retainedInput !== undefined) {
8121
+ const encodedInput = yield* Schema.decodeEffect(Schema.Json)(
8122
+ options.retainedInput,
8123
+ ).pipe(
8124
+ Effect.mapError((cause) =>
8125
+ AgentInputError.make({
8126
+ message: `Invalid retained Agent input: ${cause.message}`,
8127
+ }),
8128
+ ),
8129
+ );
8130
+
8131
+ const source = agent.definition.instructions;
8132
+
8133
+ const instructions =
8134
+ typeof source === "function"
8135
+ ? yield* evaluateInstructions<
8136
+ InputSchema["Type"],
8137
+ InstructionError,
8138
+ InstructionRequirements
8139
+ >(source, yield* decodeInput(agent, encodedInput))
8140
+ : yield* evaluateInstructions<
8141
+ undefined,
8142
+ InstructionError,
8143
+ InstructionRequirements
8144
+ >(source, undefined);
8145
+
8146
+ return {
8147
+ instructions,
8148
+ encodedInput,
8149
+ inputPrompt: yield* renderInputPrompt(undefined, undefined, encodedInput),
8150
+ };
8151
+ }
8152
+ const decodedInput = yield* decodeInput(agent, input);
8153
+
8154
+ const instructions = yield* evaluateInstructions<
8155
+ InputSchema["Type"],
8156
+ InstructionError,
8157
+ InstructionRequirements
8158
+ >(agent.definition.instructions, decodedInput);
8120
8159
 
8121
- const instructions = yield* evaluateInstructions<
8122
- InputSchema["Type"],
8123
- InstructionError,
8124
- InstructionRequirements
8125
- >(agent.definition.instructions, decodedInput);
8160
+ const encodedInput = yield* encodeInput(agent, decodedInput);
8126
8161
 
8127
- const encodedInput = yield* encodeInput(agent, decodedInput);
8162
+ return {
8163
+ instructions,
8164
+ encodedInput,
8165
+ inputPrompt:
8166
+ options.frameworkMessage === undefined
8167
+ ? yield* renderInputPrompt(
8168
+ agent.definition.inputPrompt,
8169
+ decodedInput,
8170
+ encodedInput,
8171
+ )
8172
+ : undefined,
8173
+ };
8174
+ });
8175
+
8176
+ const { instructions, encodedInput } = initial;
8128
8177
 
8129
8178
  context.input = encodedInput;
8130
8179
  if (retained !== undefined) yield* retained.stageInput(encodedInput);
8131
8180
 
8132
8181
  const inputPrompt =
8133
8182
  options.frameworkMessage === undefined
8134
- ? yield* renderInputPrompt(
8135
- agent.definition.inputPrompt,
8136
- decodedInput,
8137
- encodedInput,
8138
- )
8183
+ ? (initial.inputPrompt ?? "")
8139
8184
  : yield* Schema.encodeEffect(Schema.fromJsonString(FrameworkMessage))(
8140
8185
  options.frameworkMessage,
8141
8186
  ).pipe(
@@ -8153,12 +8198,21 @@ function streamWithCompletion<
8153
8198
  context.compaction.protectedStart = priorHistoryLength;
8154
8199
  context.compaction.protectedEnd = prompt.content.length;
8155
8200
  } else {
8201
+ const currentPrefix = prompt.content.slice(priorHistoryLength);
8202
+
8203
+ const protectedMessages =
8204
+ options.protectedContext === undefined
8205
+ ? currentPrefix
8206
+ : [
8207
+ ...currentPrefix.filter((message) => message.role === "system"),
8208
+ ...options.protectedContext.content.filter(
8209
+ (message) => message.role !== "system",
8210
+ ),
8211
+ ];
8212
+
8156
8213
  context.preparedCompactionSource = {
8157
- protectedReferences:
8158
- options.protectedContext?.content ?? prompt.content.slice(priorHistoryLength),
8159
- protectedMessages: yield* snapshotCompactionMessages(
8160
- options.protectedContext?.content ?? prompt.content.slice(priorHistoryLength),
8161
- ),
8214
+ protectedReferences: protectedMessages,
8215
+ protectedMessages: yield* snapshotCompactionMessages(protectedMessages),
8162
8216
  prefix: [],
8163
8217
  };
8164
8218
  }