eve 0.75.0 → 0.75.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/src/cli/commands/deploy.js +1 -1
  3. package/dist/src/cli/commands/link.d.ts +2 -1
  4. package/dist/src/cli/commands/link.js +1 -1
  5. package/dist/src/cli/commands/registry.js +1 -1
  6. package/dist/src/cli/commands/vercel-non-interactive.d.ts +6 -4
  7. package/dist/src/cli/commands/vercel-non-interactive.js +1 -1
  8. package/dist/src/compiled/.vendor-stamp.json +8 -8
  9. package/dist/src/compiled/@eve/catalog/index.js +1 -1
  10. package/dist/src/compiled/@workflow/core/global.d.ts +10 -0
  11. package/dist/src/compiled/@workflow/core/index.js +1 -1
  12. package/dist/src/compiled/@workflow/core/private.d.ts +11 -0
  13. package/dist/src/compiled/@workflow/core/private.js +1 -1
  14. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +36 -8
  15. package/dist/src/compiled/@workflow/core/runtime/helpers.js +1 -1
  16. package/dist/src/compiled/@workflow/core/runtime/lifecycle-hooks.d.ts +10 -6
  17. package/dist/src/compiled/@workflow/core/runtime/out-of-band-observation.d.ts +159 -0
  18. package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +28 -4
  19. package/dist/src/compiled/@workflow/core/runtime.js +4 -4
  20. package/dist/src/compiled/@workflow/core/serialization.js +1 -1
  21. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  22. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  23. package/dist/src/compiled/@workflow/world-local/index.js +5 -5
  24. package/dist/src/compiled/@workflow/world-vercel/index.js +4 -4
  25. package/dist/src/compiled/_chunks/workflow/{attribute-changes-CSqvJx6j.js → attribute-changes-BW-kbMMn.js} +1 -1
  26. package/dist/src/compiled/_chunks/workflow/dist-CyBgVS7g.js +1 -0
  27. package/dist/src/compiled/_chunks/workflow/{helpers-BXCuoPUb.js → helpers-DlLD3ov_.js} +1 -1
  28. package/dist/src/compiled/_chunks/workflow/private-tQUuwBoQ.js +1 -0
  29. package/dist/src/compiled/_chunks/workflow/{resume-hook-CvENCrxc.js → resume-hook-DMsV_b4n.js} +1 -1
  30. package/dist/src/compiled/_chunks/workflow/{run-8pLWuR2U.js → run-DzdAqdb1.js} +1 -1
  31. package/dist/src/compiled/_chunks/workflow/{serialization-vDozzDhh.js → serialization-DPdYS_w2.js} +2 -2
  32. package/dist/src/compiled/_chunks/workflow/sleep-BY6leHh8.js +1 -0
  33. package/dist/src/compiled/_chunks/workflow/{token-BKeK6DmC.js → token-D5ugC3PI.js} +1 -1
  34. package/dist/src/compiled/_chunks/workflow/{token-util-CddTZ_ef.js → token-util-Bla5Z0G9.js} +1 -1
  35. package/dist/src/compiled/_chunks/workflow/undici-D-ILjOKD.js +95 -0
  36. package/dist/src/compiled/_chunks/workflow/{wait-until-A344L2AG.js → wait-until-xbRRDuUf.js} +1 -1
  37. package/dist/src/eve-channel/request.js +1 -1
  38. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  39. package/dist/src/execution/ndjson-stream.d.ts +6 -6
  40. package/dist/src/execution/ndjson-stream.js +3 -3
  41. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  42. package/dist/src/harness/compaction/engine.d.ts +8 -19
  43. package/dist/src/harness/compaction/engine.js +1 -1
  44. package/dist/src/harness/compaction/step.d.ts +7 -1
  45. package/dist/src/harness/compaction/step.js +1 -1
  46. package/dist/src/harness/emission.js +1 -1
  47. package/dist/src/harness/model-call/call.d.ts +2 -3
  48. package/dist/src/harness/model-call/call.js +1 -1
  49. package/dist/src/harness/model-call/model.d.ts +4 -5
  50. package/dist/src/harness/model-call/model.js +1 -1
  51. package/dist/src/harness/model-call/request.d.ts +1 -2
  52. package/dist/src/harness/model-call/request.js +1 -1
  53. package/dist/src/harness/model-call/retry.d.ts +1 -1
  54. package/dist/src/harness/model-call/retry.js +1 -1
  55. package/dist/src/harness/model-call/tools.d.ts +3 -4
  56. package/dist/src/harness/model-call/tools.js +1 -1
  57. package/dist/src/harness/model-call/usage.js +1 -1
  58. package/dist/src/harness/model-profile.d.ts +23 -0
  59. package/dist/src/harness/model-profile.js +1 -0
  60. package/dist/src/harness/prompt-cache.d.ts +5 -53
  61. package/dist/src/harness/prompt-cache.js +1 -1
  62. package/dist/src/harness/provider-safety.d.ts +3 -5
  63. package/dist/src/harness/provider-safety.js +1 -1
  64. package/dist/src/harness/provider-tools.d.ts +5 -13
  65. package/dist/src/harness/provider-tools.js +1 -1
  66. package/dist/src/harness/step-hooks.d.ts +2 -3
  67. package/dist/src/harness/step-hooks.js +1 -1
  68. package/dist/src/harness/tools.d.ts +2 -3
  69. package/dist/src/harness/tools.js +1 -1
  70. package/dist/src/harness/turn-tag-state.d.ts +12 -0
  71. package/dist/src/harness/turn-tag-state.js +1 -1
  72. package/dist/src/internal/application/package.js +1 -1
  73. package/dist/src/internal/gateway.d.ts +0 -13
  74. package/dist/src/internal/gateway.js +1 -1
  75. package/dist/src/setup/scaffold/create/project.js +1 -1
  76. package/dist/src/setup/scaffold/create/web-template.d.ts +3 -2
  77. package/dist/src/setup/scaffold/create/web-template.js +383 -411
  78. package/dist/src/setup/vercel-project.d.ts +1 -1
  79. package/dist/src/setup/vercel-project.js +0 -0
  80. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  81. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  82. package/package.json +6 -6
  83. package/dist/src/compiled/_chunks/workflow/dist-DmXynLVH.js +0 -1
  84. package/dist/src/compiled/_chunks/workflow/private-Dlf90Zvn.js +0 -1
  85. package/dist/src/compiled/_chunks/workflow/signal-exit-iIdjQcCK.js +0 -95
  86. package/dist/src/compiled/_chunks/workflow/sleep-BMqbraZM.js +0 -1
@@ -1 +1 @@
1
- import{s as e}from"./rolldown-runtime-B_knIduE.js";import"./dist-DmXynLVH.js";function t(e,t=8){return Math.min(8,e??t)}function n(t){import(`./functions-CKkqf9V6.js`).then(t=>e(t.default,1)).then(({waitUntil:e})=>{e(t)})}function r(e,t){n(e.catch(e=>{if(e?.name!==`AbortError`&&e?.name!==`ResponseAborted`)try{t(e)}catch{}}))}async function i(e){let t=e();return n(t.catch(()=>{})),t}export{i as n,t as r,r as t};
1
+ import{s as e}from"./rolldown-runtime-B_knIduE.js";import"./dist-CyBgVS7g.js";function t(e,t=8){return Math.min(8,e??t)}function n(t){import(`./functions-CKkqf9V6.js`).then(t=>e(t.default,1)).then(({waitUntil:e})=>{e(t)})}function r(e,t){n(e.catch(e=>{if(e?.name!==`AbortError`&&e?.name!==`ResponseAborted`)try{t(e)}catch{}}))}async function i(e){let t=e();return n(t.catch(()=>{})),t}export{i as n,t as r,r as t};
@@ -1,4 +1,4 @@
1
- import{isInputResponse}from"#shared/input.js";import{hasInternalRefScheme}from"#internal/attachments/url-refs.js";import{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_CONTROL_VERSION,EVE_STREAM_CONTROL_VERSION_QUERY,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_LEASE_ENDED_CONTROL,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{parseJsonObject}from"#shared/json.js";import{LEGACY_REMOTE_AGENT_PROTOCOL_VERSION,splitLegacyTaskFields}from"#execution/legacy-remote-agent/protocol.js";import{collectUploadPolicyViolations,formatUploadPolicyViolation}from"#public/channels/upload-policy.js";import{parseToolStubs}from"#tool-stubs/rules.js";import{parseSessionCallback}from"#channel/session-callback.js";import{isMissingWorkflowRunError}from"#internal/workflow/is-inactive-workflow-run-error.js";import{REMOTE_AGENT_PROTOCOL_MISMATCH,REMOTE_AGENT_PROTOCOL_VERSION,readRemoteAgentProtocolVersion}from"#protocol/remote-agent-protocol.js";import{parseTurnPolicyField}from"#eve-channel/turn-policy-request.js";import{validateMessageFreeCreate}from"#eve-channel/create-request.js";async function deriveOperationContinuationToken(e){let t=JSON.stringify([`eve:create-session:v1`,e.auth.authenticator,e.auth.issuer??null,e.auth.principalType,e.auth.principalId,e.operationId]),n=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(t));return`eve:op:${Array.from(new Uint8Array(n),e=>e.toString(16).padStart(2,`0`)).join(``).slice(0,32)}`}function parseCreateBody(e){let t=splitLegacyTaskFields(e),{payload:n}=t;if(n.inputResponses!==void 0)return Response.json({error:`'inputResponses' is only accepted for an existing session.`,ok:!1},{status:400});let r=parseMessageField(n.message);if(r instanceof Response)return r;let i=parseClientContextField(n.clientContext);if(i instanceof Response)return i;let a=parseCallbackField(n.callback);if(a instanceof Response)return a;let o=a===void 0?void 0:parseProtocolVersionField(n.protocolVersion);if(o instanceof Response)return o;let s=parseCapabilitiesField(n.capabilities);if(s instanceof Response)return s;let c=parseOutputSchemaField(n.outputSchema);if(c instanceof Response)return c;let l=validateMessageFreeCreate({callback:a,hasClientContext:n.clientContext!==void 0,hasMessageField:`message`in n,message:r,outputSchema:c});if(l!==void 0)return l;let u=n.operationId;if(u!==void 0&&(typeof u!=`string`||!u))return Response.json({error:`Expected 'operationId' to be a non-empty string.`,ok:!1},{status:400});let d={callback:a,capabilities:s,context:i,outputSchema:c};if(n.stubs!==void 0)try{d.stubs=parseToolStubs(n.stubs)}catch(e){return Response.json({ok:!1,error:e instanceof Error?e.message:`Invalid tool stubs.`},{status:400})}return r!==void 0&&(d.message=r),typeof u==`string`&&(d.operationId=u),o!==void 0&&(d.protocolVersion=o),o===LEGACY_REMOTE_AGENT_PROTOCOL_VERSION&&(d.legacyRemoteAgentCaller=t.taskId===void 0?{}:{taskId:t.taskId}),d}function parseSessionMessageBody(e){let{payload:t}=splitLegacyTaskFields(e);if(Object.hasOwn(t,`stubs`))return Response.json({ok:!1,error:`Tool stubs are fixed at session creation.`},{status:400});let n=rejectSessionContinuationToken(t);if(n!==null)return n;let r=parseMessageField(t.message);if(r instanceof Response)return r;let i=parseCallbackField(t.callback);if(i instanceof Response)return i;let a=parseInputResponses$1(t.inputResponses);if(a instanceof Response)return a;let o=parseClientContextField(t.clientContext);if(o instanceof Response)return o;let s=parseOutputSchemaField(t.outputSchema);if(s instanceof Response)return s;let c=parseTurnPolicyField(t.turnPolicy);return c instanceof Response?c:r===void 0&&a===void 0?Response.json({error:`Expected a non-empty 'message' or a non-empty 'inputResponses' array.`,ok:!1},{status:400}):r!==void 0&&a!==void 0?Response.json({error:`'message' and 'inputResponses' are mutually exclusive.`,ok:!1},{status:400}):{callback:i,message:r,inputResponses:a,context:o,outputSchema:s,turnPolicy:c}}async function parseCancelTurnBody(e){let t=await parseOptionalJsonRequest(e);if(t instanceof Response)return t;let n=rejectSessionContinuationToken(t);if(n!==null)return n;let r=t.turnId;return r!==void 0&&(typeof r!=`string`||r.length===0)?Response.json({error:`Expected 'turnId' to be a non-empty string.`,ok:!1},{status:400}):typeof r==`string`?{turnId:r}:{}}async function parseJsonRequest(e){let t;try{t=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}return typeof t!=`object`||!t||Array.isArray(t)?Response.json({error:`Expected a JSON object.`,ok:!1},{status:400}):t}async function parseResetBody(e){let t=await parseOptionalJsonRequest(e);if(t instanceof Response)return t;let n=rejectSessionContinuationToken(t);if(n!==null)return n;let r=t.reason;return r!==void 0&&(typeof r!=`string`||r.length===0)?Response.json({error:`Expected 'reason' to be a non-empty string.`,ok:!1},{status:400}):r===void 0?{}:{reason:r}}async function parseSessionControlBody(e){let t=await parseOptionalJsonRequest(e);return t instanceof Response?t:rejectSessionContinuationToken(t)??t}async function parseOptionalJsonRequest(e){let t;try{t=await e.text()}catch{return Response.json({error:`Unreadable request body.`,ok:!1},{status:400})}if(t.trim().length===0)return{};let n;try{n=JSON.parse(t)}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}return typeof n!=`object`||!n||Array.isArray(n)?Response.json({error:`Expected a JSON object.`,ok:!1},{status:400}):n}function rejectSessionContinuationToken(e){return`continuationToken`in e?Response.json({error:`Session-ID routes do not accept 'continuationToken'.`,ok:!1},{status:400}):null}function requireSessionId(e){return e.sessionId||Response.json({error:`Missing session id.`,ok:!1},{status:400})}async function createSessionStreamResponse(e,t){let n=parseStartIndex(e);if(n instanceof Response)return n;let r=parseIncludeTailIndex(e);try{let i=await t.getStreamTailIndex(),a=await t.getEventStream({startIndex:n}),o=new URL(e.url).searchParams.get(EVE_STREAM_CONTROL_VERSION_QUERY)===EVE_STREAM_CONTROL_VERSION?EVE_STREAM_CONTROL_VERSION:void 0,s=new Headers({"cache-control":`no-store, no-transform`,"content-type":EVE_MESSAGE_STREAM_CONTENT_TYPE,"x-accel-buffering":`no`,[EVE_SESSION_ID_HEADER]:t.id,[EVE_STREAM_FORMAT_HEADER]:EVE_MESSAGE_STREAM_FORMAT,[EVE_STREAM_VERSION_HEADER]:EVE_MESSAGE_STREAM_VERSION});return r&&s.set(EVE_STREAM_TAIL_INDEX_HEADER,String(i)),new Response(serializeAsNdjson(a,e.signal,r?streamEventLimit(n,i):void 0,o!==void 0),{headers:s})}catch(e){let t=isMissingWorkflowRunError(e);return Response.json({error:t?`Session not found.`:`Session stream unavailable.`,ok:!1},{status:t?404:503})}}function parseOutputSchemaField(e){if(e!==void 0)try{return parseJsonObject(e)}catch{return Response.json({error:`Expected 'outputSchema' to be a JSON-serializable object.`,ok:!1},{status:400})}}function parseCallbackField(e){if(e===void 0)return;let t=parseSessionCallback(e);return t.ok?t.callback:Response.json({error:t.message,ok:!1},{status:400})}function parseProtocolVersionField(e){if(e!==void 0&&typeof e!=`number`)return Response.json({error:`Expected 'protocolVersion' to be a number.`,ok:!1},{status:400});let t=readRemoteAgentProtocolVersion(e);return t===REMOTE_AGENT_PROTOCOL_VERSION||t===LEGACY_REMOTE_AGENT_PROTOCOL_VERSION?t:Response.json({code:REMOTE_AGENT_PROTOCOL_MISMATCH,error:`This deployment speaks eve remote agent protocol ${String(REMOTE_AGENT_PROTOCOL_VERSION)}, but the caller speaks protocol ${String(t)}. Upgrade both deployments to the same eve release.`,ok:!1,protocolVersion:REMOTE_AGENT_PROTOCOL_VERSION},{status:409})}function parseCapabilitiesField(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return Response.json({error:`Expected 'capabilities' to be an object.`,ok:!1},{status:400});let t=Object.keys(e),n=Reflect.get(e,`requestInput`);return t.some(e=>e!==`requestInput`)||n!==void 0&&typeof n!=`boolean`?Response.json({error:`Expected 'capabilities.requestInput' to be a boolean when provided.`,ok:!1},{status:400}):n===void 0?{}:{requestInput:n}}function parseMessageField(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=parseMessagePart(n);if(e instanceof Response)return e;t.push(e)}return t}function parseMessagePart(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});if(hasInternalRefScheme(t.data))return Response.json({error:`File part 'data' must not use a framework-internal ref scheme.`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function checkUploadPolicy(e,t){if(!e.message)return null;let n=collectUploadPolicyViolations(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:formatUploadPolicyViolation(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function parseInputResponses$1(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(isInputResponse);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function parseClientContextField(e){if(e!==void 0){if(typeof e==`string`)return e.length>0?[toClientContextMessage(e)]:void 0;if(Array.isArray(e))return e.length===0?void 0:e.every(e=>typeof e==`string`&&e.length>0)?e.map(e=>toClientContextMessage(e)):Response.json({error:`Expected 'clientContext' array entries to be non-empty strings.`,ok:!1},{status:400});if(typeof e!=`object`||!e)return Response.json({error:`Expected 'clientContext' to be a string, string array, or JSON object.`,ok:!1},{status:400});try{let t=parseJsonObject(e);return[toClientContextMessage(JSON.stringify(t))]}catch{return Response.json({error:`Expected 'clientContext' to be a JSON-serializable object.`,ok:!1},{status:400})}}}function toClientContextMessage(e){return`Client context:
1
+ import{isInputResponse}from"#shared/input.js";import{hasInternalRefScheme}from"#internal/attachments/url-refs.js";import{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_CONTROL_VERSION,EVE_STREAM_CONTROL_VERSION_QUERY,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_LEASE_ENDED_CONTROL,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{parseJsonObject}from"#shared/json.js";import{LEGACY_REMOTE_AGENT_PROTOCOL_VERSION,splitLegacyTaskFields}from"#execution/legacy-remote-agent/protocol.js";import{collectUploadPolicyViolations,formatUploadPolicyViolation}from"#public/channels/upload-policy.js";import{parseToolStubs}from"#tool-stubs/rules.js";import{parseSessionCallback}from"#channel/session-callback.js";import{isMissingWorkflowRunError}from"#internal/workflow/is-inactive-workflow-run-error.js";import{REMOTE_AGENT_PROTOCOL_MISMATCH,REMOTE_AGENT_PROTOCOL_VERSION,readRemoteAgentProtocolVersion}from"#protocol/remote-agent-protocol.js";import{parseTurnPolicyField}from"#eve-channel/turn-policy-request.js";import{validateMessageFreeCreate}from"#eve-channel/create-request.js";async function deriveOperationContinuationToken(e){let t=JSON.stringify([`eve:create-session:v1`,e.auth.authenticator,e.auth.issuer??null,e.auth.principalType,e.auth.principalId,e.operationId]),n=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(t));return`eve:op:${Array.from(new Uint8Array(n),e=>e.toString(16).padStart(2,`0`)).join(``).slice(0,32)}`}function parseCreateBody(e){let t=splitLegacyTaskFields(e),{payload:n}=t;if(n.inputResponses!==void 0)return Response.json({error:`'inputResponses' is only accepted for an existing session.`,ok:!1},{status:400});let r=parseMessageField(n.message);if(r instanceof Response)return r;let i=parseClientContextField(n.clientContext);if(i instanceof Response)return i;let a=parseCallbackField(n.callback);if(a instanceof Response)return a;let o=a===void 0?void 0:parseProtocolVersionField(n.protocolVersion);if(o instanceof Response)return o;let s=parseCapabilitiesField(n.capabilities);if(s instanceof Response)return s;let c=parseOutputSchemaField(n.outputSchema);if(c instanceof Response)return c;let l=validateMessageFreeCreate({callback:a,hasClientContext:n.clientContext!==void 0,hasMessageField:`message`in n,message:r,outputSchema:c});if(l!==void 0)return l;let u=n.operationId;if(u!==void 0&&(typeof u!=`string`||!u))return Response.json({error:`Expected 'operationId' to be a non-empty string.`,ok:!1},{status:400});let d={callback:a,capabilities:s,context:i,outputSchema:c};if(n.stubs!==void 0)try{d.stubs=parseToolStubs(n.stubs)}catch(e){return Response.json({ok:!1,error:e instanceof Error?e.message:`Invalid tool stubs.`},{status:400})}return r!==void 0&&(d.message=r),typeof u==`string`&&(d.operationId=u),o!==void 0&&(d.protocolVersion=o),o===LEGACY_REMOTE_AGENT_PROTOCOL_VERSION&&(d.legacyRemoteAgentCaller=t.taskId===void 0?{}:{taskId:t.taskId}),d}function parseSessionMessageBody(e){let{payload:t}=splitLegacyTaskFields(e);if(Object.hasOwn(t,`stubs`))return Response.json({ok:!1,error:`Tool stubs are fixed at session creation.`},{status:400});let n=rejectSessionContinuationToken(t);if(n!==null)return n;let r=parseMessageField(t.message);if(r instanceof Response)return r;let i=parseCallbackField(t.callback);if(i instanceof Response)return i;let a=parseInputResponses$1(t.inputResponses);if(a instanceof Response)return a;let o=parseClientContextField(t.clientContext);if(o instanceof Response)return o;let s=parseOutputSchemaField(t.outputSchema);if(s instanceof Response)return s;let c=parseTurnPolicyField(t.turnPolicy);return c instanceof Response?c:r===void 0&&a===void 0?Response.json({error:`Expected a non-empty 'message' or a non-empty 'inputResponses' array.`,ok:!1},{status:400}):r!==void 0&&a!==void 0?Response.json({error:`'message' and 'inputResponses' are mutually exclusive.`,ok:!1},{status:400}):{callback:i,message:r,inputResponses:a,context:o,outputSchema:s,turnPolicy:c}}async function parseCancelTurnBody(e){let t=await parseOptionalJsonRequest(e);if(t instanceof Response)return t;let n=rejectSessionContinuationToken(t);if(n!==null)return n;let r=t.turnId;return r!==void 0&&(typeof r!=`string`||r.length===0)?Response.json({error:`Expected 'turnId' to be a non-empty string.`,ok:!1},{status:400}):typeof r==`string`?{turnId:r}:{}}async function parseJsonRequest(e){let t;try{t=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}return typeof t!=`object`||!t||Array.isArray(t)?Response.json({error:`Expected a JSON object.`,ok:!1},{status:400}):t}async function parseResetBody(e){let t=await parseOptionalJsonRequest(e);if(t instanceof Response)return t;let n=rejectSessionContinuationToken(t);if(n!==null)return n;let r=t.reason;return r!==void 0&&(typeof r!=`string`||r.length===0)?Response.json({error:`Expected 'reason' to be a non-empty string.`,ok:!1},{status:400}):r===void 0?{}:{reason:r}}async function parseSessionControlBody(e){let t=await parseOptionalJsonRequest(e);return t instanceof Response?t:rejectSessionContinuationToken(t)??t}async function parseOptionalJsonRequest(e){let t;try{t=await e.text()}catch{return Response.json({error:`Unreadable request body.`,ok:!1},{status:400})}if(t.trim().length===0)return{};let n;try{n=JSON.parse(t)}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}return typeof n!=`object`||!n||Array.isArray(n)?Response.json({error:`Expected a JSON object.`,ok:!1},{status:400}):n}function rejectSessionContinuationToken(e){return`continuationToken`in e?Response.json({error:`Session-ID routes do not accept 'continuationToken'.`,ok:!1},{status:400}):null}function requireSessionId(e){return e.sessionId||Response.json({error:`Missing session id.`,ok:!1},{status:400})}async function createSessionStreamResponse(e,t){let n=parseStartIndex(e);if(n instanceof Response)return n;let r=parseIncludeTailIndex(e);try{let i=t.getEventStream({startIndex:n});i.catch(()=>{});let a;try{a=await t.getStreamTailIndex()}catch(e){throw i.then(e=>e.cancel()).catch(()=>{}),e}let o=await i,s=new URL(e.url).searchParams.get(EVE_STREAM_CONTROL_VERSION_QUERY)===EVE_STREAM_CONTROL_VERSION?EVE_STREAM_CONTROL_VERSION:void 0,c=new Headers({"cache-control":`no-store, no-transform`,"content-type":EVE_MESSAGE_STREAM_CONTENT_TYPE,"x-accel-buffering":`no`,[EVE_SESSION_ID_HEADER]:t.id,[EVE_STREAM_FORMAT_HEADER]:EVE_MESSAGE_STREAM_FORMAT,[EVE_STREAM_VERSION_HEADER]:EVE_MESSAGE_STREAM_VERSION});return r&&c.set(EVE_STREAM_TAIL_INDEX_HEADER,String(a)),new Response(serializeAsNdjson(o,e.signal,r?streamEventLimit(n,a):void 0,s!==void 0),{headers:c})}catch(e){let t=isMissingWorkflowRunError(e);return Response.json({error:t?`Session not found.`:`Session stream unavailable.`,ok:!1},{status:t?404:503})}}function parseOutputSchemaField(e){if(e!==void 0)try{return parseJsonObject(e)}catch{return Response.json({error:`Expected 'outputSchema' to be a JSON-serializable object.`,ok:!1},{status:400})}}function parseCallbackField(e){if(e===void 0)return;let t=parseSessionCallback(e);return t.ok?t.callback:Response.json({error:t.message,ok:!1},{status:400})}function parseProtocolVersionField(e){if(e!==void 0&&typeof e!=`number`)return Response.json({error:`Expected 'protocolVersion' to be a number.`,ok:!1},{status:400});let t=readRemoteAgentProtocolVersion(e);return t===REMOTE_AGENT_PROTOCOL_VERSION||t===LEGACY_REMOTE_AGENT_PROTOCOL_VERSION?t:Response.json({code:REMOTE_AGENT_PROTOCOL_MISMATCH,error:`This deployment speaks eve remote agent protocol ${String(REMOTE_AGENT_PROTOCOL_VERSION)}, but the caller speaks protocol ${String(t)}. Upgrade both deployments to the same eve release.`,ok:!1,protocolVersion:REMOTE_AGENT_PROTOCOL_VERSION},{status:409})}function parseCapabilitiesField(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return Response.json({error:`Expected 'capabilities' to be an object.`,ok:!1},{status:400});let t=Object.keys(e),n=Reflect.get(e,`requestInput`);return t.some(e=>e!==`requestInput`)||n!==void 0&&typeof n!=`boolean`?Response.json({error:`Expected 'capabilities.requestInput' to be a boolean when provided.`,ok:!1},{status:400}):n===void 0?{}:{requestInput:n}}function parseMessageField(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=parseMessagePart(n);if(e instanceof Response)return e;t.push(e)}return t}function parseMessagePart(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});if(hasInternalRefScheme(t.data))return Response.json({error:`File part 'data' must not use a framework-internal ref scheme.`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function checkUploadPolicy(e,t){if(!e.message)return null;let n=collectUploadPolicyViolations(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:formatUploadPolicyViolation(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function parseInputResponses$1(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(isInputResponse);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function parseClientContextField(e){if(e!==void 0){if(typeof e==`string`)return e.length>0?[toClientContextMessage(e)]:void 0;if(Array.isArray(e))return e.length===0?void 0:e.every(e=>typeof e==`string`&&e.length>0)?e.map(e=>toClientContextMessage(e)):Response.json({error:`Expected 'clientContext' array entries to be non-empty strings.`,ok:!1},{status:400});if(typeof e!=`object`||!e)return Response.json({error:`Expected 'clientContext' to be a string, string array, or JSON object.`,ok:!1},{status:400});try{let t=parseJsonObject(e);return[toClientContextMessage(JSON.stringify(t))]}catch{return Response.json({error:`Expected 'clientContext' to be a JSON-serializable object.`,ok:!1},{status:400})}}}function toClientContextMessage(e){return`Client context:
2
2
  ${e}`}function parseIncludeTailIndex(e){let t=new URL(e.url).searchParams.get(`includeTailIndex`);return t===`1`||t===`true`}function parseStartIndex(e){let t=new URL(e.url).searchParams.get(`startIndex`);if(t===null)return;let n=Number(t);return!/^-?\d+$/.test(t)||!Number.isSafeInteger(n)?Response.json({error:`Expected startIndex to be an integer.`,ok:!1},{status:400}):n}function streamEventLimit(e,t){if(t===void 0)return;let n=e===void 0?0:e<0?Math.max(0,t+1+e):e;return Math.max(0,t-n+1)}function serializeAsNdjson(e,t,n,r=!1){let i=new TextEncoder,a=0,o,s,clearTimers=()=>{clearTimeout(o),clearTimeout(s),o=void 0,s=void 0},scheduleHeartbeat=e=>{clearTimeout(o),o=setTimeout(()=>{try{e.enqueue(i.encode(`
3
3
  `)),scheduleHeartbeat(e)}catch{clearTimers()}},1e4)},startLease=e=>{scheduleHeartbeat(e),s=setTimeout(()=>{clearTimers();try{e.enqueue(i.encode(`${JSON.stringify(EVE_STREAM_LEASE_ENDED_CONTROL)}\n`)),e.terminate()}catch{}},6e4)},c=new TransformStream({start(e){e.enqueue(i.encode(`
4
4
  `)),n===0?e.terminate():r&&startLease(e)},transform(e,t){t.enqueue(i.encode(`${JSON.stringify(e)}\n`)),a+=1,a===n?(clearTimers(),t.terminate()):r&&scheduleHeartbeat(t)},flush(){clearTimers()}});return e.pipeTo(c.writable,{signal:t}).catch(()=>{}).finally(clearTimers),c.readable}export{checkUploadPolicy,createSessionStreamResponse,deriveOperationContinuationToken,parseCancelTurnBody,parseCreateBody,parseIncludeTailIndex,parseJsonRequest,parseOptionalJsonRequest,parseResetBody,parseSessionControlBody,parseSessionMessageBody,parseStartIndex,rejectSessionContinuationToken,requireSessionId};
@@ -1 +1 @@
1
- import{runJsProgram}from"#execution/dynamic-workflow/workflow.js";async function runWorkflowProgramTask(e,t){"use workflow";return runJsProgram(e.js,t,{maxSubagents:e.maxSubagents??0})}runWorkflowProgramTask.workflowId=`workflow//eve@0.75.0//runWorkflowProgramTask`;export{runWorkflowProgramTask};
1
+ import{runJsProgram}from"#execution/dynamic-workflow/workflow.js";async function runWorkflowProgramTask(e,t){"use workflow";return runJsProgram(e.js,t,{maxSubagents:e.maxSubagents??0})}runWorkflowProgramTask.workflowId=`workflow//eve@0.75.1//runWorkflowProgramTask`;export{runWorkflowProgramTask};
@@ -2,9 +2,9 @@
2
2
  * Transforms a byte stream of newline-delimited JSON (NDJSON) into a
3
3
  * stream of parsed values.
4
4
  *
5
- * The byte stream is produced lazily by `createByteStream`, so the
6
- * underlying source (a world-local run readable) is only opened when the
7
- * returned stream is consumed.
5
+ * The source is read on demand: each pull reads only until it can enqueue
6
+ * at least one value, so a slow consumer applies backpressure to the source
7
+ * instead of this stream buffering everything the source can deliver.
8
8
  *
9
9
  * Cancellation is forwarded to the source. When the returned stream is
10
10
  * cancelled — e.g. an SSE client disconnects and the server cancels the
@@ -12,8 +12,8 @@
12
12
  * runs that never reach EOF: a parked (`session.waiting`) durable run keeps
13
13
  * its event stream open indefinitely, and the world-local streamer runs a
14
14
  * filesystem poll until its reader is cancelled. Without forwarding the
15
- * cancel, the read loop below would block on `reader.read()` forever and
16
- * that poll would leak for the life of the process, degrading streaming
17
- * throughput for every other session.
15
+ * cancel, a pending `reader.read()` would block forever and that poll would
16
+ * leak for the life of the process, degrading streaming throughput for every
17
+ * other session.
18
18
  */
19
19
  export declare function parseNdjsonStream<T>(createByteStream: () => ReadableStream<Uint8Array>, parse?: (value: unknown) => T): ReadableStream<T>;
@@ -1,3 +1,3 @@
1
- function parseNdjsonStream(e,t=e=>e){let n=new TextDecoder,r=``,i,a=!1;return new ReadableStream({async start(o){i=e().getReader();try{for(;;){let{value:e,done:a}=await i.read();if(a)break;r+=n.decode(e,{stream:!0});for(let e=r.indexOf(`
2
- `);e!==-1;e=r.indexOf(`
3
- `)){let n=r.slice(0,e).trim();r=r.slice(e+1),n.length>0&&o.enqueue(t(JSON.parse(n)))}}if(a)return;r+=n.decode();let e=r.trim();e.length>0&&o.enqueue(t(JSON.parse(e))),o.close()}catch(e){a||o.error(e)}finally{i.releaseLock()}},async cancel(e){a=!0,await i?.cancel(e)}})}export{parseNdjsonStream};
1
+ function parseNdjsonStream(e,t=e=>e){let n=new TextDecoder,r=``,i,a=!1;return new ReadableStream({start(){i=e().getReader()},async pull(e){try{for(;;){let{value:o,done:s}=await i.read();if(a)return;if(s){r+=n.decode();let i=r.trim();i.length>0&&e.enqueue(t(JSON.parse(i))),e.close();return}r+=n.decode(o,{stream:!0});let c=!1;for(let n=r.indexOf(`
2
+ `);n!==-1;n=r.indexOf(`
3
+ `)){let i=r.slice(0,n).trim();r=r.slice(n+1),i.length>0&&(e.enqueue(t(JSON.parse(i))),c=!0)}if(c)return}}catch(t){if(a)return;e.error(t),await i.cancel(t).catch(()=>{})}},async cancel(e){a=!0,await i?.cancel(e)}})}export{parseNdjsonStream};
@@ -1 +1 @@
1
- import{decide}from"#ai/decide.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{message:r,status:i}=await(await t.agent(n).send(e.message,{signal:t.abortSignal})).result();if(i===`failed`)throw Error(`Agent "${n}" failed to handle the task.`);return r??null}async function chooseTarget(e,t,n){"use step";let r=Object.keys(t);if(r.length===0)throw Error(`agentRouter requires at least one available agent with a description.`);return r.length===1?r[0]:(await decide({abortSignal:n,state:{message:e},questions:{route:{type:`choice`,instructions:`Which subagent should handle this task?`,criteria:t}}})).answers.route.choice}function descriptions(e){return Object.fromEntries(Object.entries(e.agents).flatMap(([e,t])=>{let n=t.description.trim();return n.length===0?[]:[[e,n]]}))}runAgentRouterTask.workflowId=`workflow//eve@0.75.0//runAgentRouterTask`;export{runAgentRouterTask};
1
+ import{decide}from"#ai/decide.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{message:r,status:i}=await(await t.agent(n).send(e.message,{signal:t.abortSignal})).result();if(i===`failed`)throw Error(`Agent "${n}" failed to handle the task.`);return r??null}async function chooseTarget(e,t,n){"use step";let r=Object.keys(t);if(r.length===0)throw Error(`agentRouter requires at least one available agent with a description.`);return r.length===1?r[0]:(await decide({abortSignal:n,state:{message:e},questions:{route:{type:`choice`,instructions:`Which subagent should handle this task?`,criteria:t}}})).answers.route.choice}function descriptions(e){return Object.fromEntries(Object.entries(e.agents).flatMap(([e,t])=>{let n=t.description.trim();return n.length===0?[]:[[e,n]]}))}runAgentRouterTask.workflowId=`workflow//eve@0.75.1//runAgentRouterTask`;export{runAgentRouterTask};
@@ -1,6 +1,5 @@
1
- import { generateText, type LanguageModel, type ModelMessage, type TelemetryOptions } from "ai";
2
- import type { RuntimeModelReference } from "#runtime/agent/bootstrap.js";
3
- import type { CompactionConfig, ToolLoopHarnessConfig } from "#harness/types.js";
1
+ import type { ModelMessage } from "ai";
2
+ import type { CompactionConfig } from "#harness/types.js";
4
3
  /**
5
4
  * Best available input-token count: the model-reported count from the last
6
5
  * step, plus a rough character-based estimate of whatever messages have been
@@ -12,25 +11,15 @@ export declare function getInputTokenCount(messages: readonly ModelMessage[], co
12
11
  * exceed the compaction threshold.
13
12
  */
14
13
  export declare function shouldCompact(messages: readonly ModelMessage[], config: CompactionConfig, requestEnvelopeTokens?: number, previousEnvelopeTokens?: number): boolean;
15
- /**
16
- * Resolves the model used to summarize older context during compaction.
17
- *
18
- * Reuses the active turn model when compaction should summarize with the same
19
- * reference, and resolves the authored compaction model only when configured.
20
- */
21
- export declare function resolveCompactionModel(input: {
22
- readonly compactionModelReference?: RuntimeModelReference;
23
- readonly model: LanguageModel;
24
- readonly modelReference: RuntimeModelReference;
25
- readonly resolveModel: ToolLoopHarnessConfig["resolveModel"];
26
- }): Promise<{
27
- readonly model: LanguageModel;
28
- readonly providerOptions: Parameters<typeof generateText>[0]["providerOptions"];
29
- }>;
14
+ /** Summarizes one compaction prompt with the compaction model, returning the summary text. */
15
+ export type CompactionSummarizer = (prompt: {
16
+ readonly messages: ModelMessage[];
17
+ readonly system: string;
18
+ }) => Promise<string>;
30
19
  /**
31
20
  * Compacts messages by escalation: try each {@link CompactionHeuristic} in
32
21
  * order, then fall back to summarizing the older region with the compaction
33
22
  * model — keeping the recent tail verbatim when it fits, degrading it to
34
23
  * text-only, then shrinking the window.
35
24
  */
36
- export declare function compactMessages(messages: ModelMessage[], model: LanguageModel, config: CompactionConfig, providerOptions?: Parameters<typeof generateText>[0]["providerOptions"], telemetry?: TelemetryOptions, headers?: Record<string, string>, abortSignal?: AbortSignal, forceSummary?: boolean, historyInputTokenCount?: number): Promise<ModelMessage[]>;
25
+ export declare function compactMessages(messages: ModelMessage[], config: CompactionConfig, summarize: CompactionSummarizer, forceSummary?: boolean, historyInputTokenCount?: number): Promise<ModelMessage[]>;
@@ -1 +1 @@
1
- import{generateText}from"ai";import{createFrameworkUserMessage,isFrameworkUserMessage}from"#harness/messages.js";import{COMPACTION_CHECKPOINT_MARKER,COMPACTION_PROMPT_ENVELOPE,COMPACTION_RESUMPTION_MESSAGE,TRANSCRIPT_PAYLOAD_LIMIT,createCompactionPrompt,sliceUtf16Safe,stubContentOutputFileParts}from"#harness/compaction/prompt.js";import{estimateTokens}from"#harness/token-estimate.js";const COMPACTION_PROMPT_OVERHEAD_TOKENS=estimateTokens([{content:COMPACTION_PROMPT_ENVELOPE.system,role:`system`},createFrameworkUserMessage(`context.compaction`,COMPACTION_PROMPT_ENVELOPE.prompt)]);function getInputTokenCount(e,t,n=0,r=0){let i=t.lastKnownInputTokens,a=t.lastKnownPromptMessageCount;return i===void 0||a===void 0||!Number.isInteger(a)||a<0||a>e.length?estimateTokens(e)+n:i+estimateTokens(e.slice(a))+Math.max(0,n-r)}function shouldCompact(e,t,n=0,r=0){return e.length>0&&getInputTokenCount(e,t,n,r)+COMPACTION_PROMPT_OVERHEAD_TOKENS>t.threshold}async function resolveCompactionModel(e){let t=e.compactionModelReference??e.modelReference;return{model:t===e.modelReference?e.model:await e.resolveModel(t),providerOptions:t.providerOptions}}const COMPACTION_HEURISTICS=[toolResultCapHeuristic];function toolResultCapHeuristic(e){let t=withResumptionGuard([...e.previousCheckpoint===void 0?[]:[createFrameworkUserMessage(`context.compaction`,COMPACTION_CHECKPOINT_MARKER),{content:e.previousCheckpoint,role:`assistant`}],...capToolResults(e.older),...e.recent],e.conversation,e.config.threshold);return evaluateThreshold(t,e.config,`should-compact`,e.tokenEstimateAdjustment).type===`within-limit`?{messages:t,type:`within-limit`}:{type:`insufficient`}}function evaluateThreshold(e,t,n,r=0){let i=n===`should-compact`?COMPACTION_PROMPT_OVERHEAD_TOKENS:0,a=estimateTokens(e)+i+r;return{estimatedTokens:a,type:a<=t.threshold?`within-limit`:`over-limit`}}async function compactMessages(e,t,n,r,i,a,o,s=!1,c){let{conversation:l,previousCheckpoint:u}=extractPreviousCheckpoint(e),d=selectRecentWindowSize(l,s?{...n,recentWindowSize:1}:n);if(!s){let{older:t,recent:r}=splitMessagesForCompaction(l,d);if(t.length===0&&u===void 0)return keepNonToolResultMessages(r);let i=Math.max(0,(c??getInputTokenCount(e,n))-estimateTokens(e));for(let e of COMPACTION_HEURISTICS){let a=e({config:n,conversation:l,older:t,previousCheckpoint:u,recent:r,tokenEstimateAdjustment:i});if(a.type===`within-limit`)return a.messages}}for(;;){let{older:e,recent:s}=splitMessagesForCompaction(l,d),c=createCompactionPrompt({messages:e,previousCheckpoint:u,transcriptBudgetTokens:n.threshold}),f=await generateText({abortSignal:o,headers:a,messages:[createFrameworkUserMessage(`context.compaction`,c.prompt)],model:t,providerOptions:r,system:c.system,telemetry:i?{...i,functionId:`eve.compaction`}:void 0});if(f.text.trim().length===0)throw Error(`The compaction model returned an empty summary. Finish reason: ${f.finishReason}.`);let p=[createFrameworkUserMessage(`context.compaction`,COMPACTION_CHECKPOINT_MARKER),{content:f.text,role:`assistant`}],m=withResumptionGuard([...p,...s],l,n.threshold);if(evaluateThreshold(m,n,`estimate`).type===`within-limit`)return m;let h=withResumptionGuard([...p,...keepNonToolResultMessages(s)],l,n.threshold);if(evaluateThreshold(h,n,`estimate`).type===`within-limit`||d===0)return h;--d}}function capToolResults(e){return e.map(e=>{if(e.role!==`tool`||typeof e.content==`string`)return e;let t=!1,n=e.content.map(e=>{if(e.type!==`tool-result`)return e;let n=stubContentOutputFileParts(e.output),r=JSON.stringify(n)??``;return r.length<=TRANSCRIPT_PAYLOAD_LIMIT?n===e.output?e:(t=!0,{...e,output:n}):(t=!0,{...e,output:{type:`text`,value:`[Truncated by eve: tool result reduced during context compaction. Re-run the tool if you need the full output.]\n\n${sliceUtf16Safe(r,TRANSCRIPT_PAYLOAD_LIMIT)}`}})});return t?{...e,content:n}:e})}function withResumptionGuard(e,t,n){let r=e.at(-1)?.role,i=findLastRealUserMessage(t),a=i!==void 0&&e.some(e=>e.role===`user`&&e.content===i.content);return r!==void 0&&r!==`assistant`?r===`tool`&&i!==void 0&&!a&&estimateTokens([i])<=n?[...e,i]:e:[...e,i!==void 0&&!a?i:createFrameworkUserMessage(`execution.continuation`,COMPACTION_RESUMPTION_MESSAGE)]}function findLastRealUserMessage(e){for(let t=e.length-1;t>=0;--t){let n=e[t];if(n?.role===`user`&&typeof n.content==`string`&&!isFrameworkUserMessage(n))return n}}function extractPreviousCheckpoint(e){let t=e[0],n=e[1];return t?.role!==`user`||t.content!==COMPACTION_CHECKPOINT_MARKER||n?.role!==`assistant`?{conversation:[...e],previousCheckpoint:void 0}:{conversation:e.slice(2),previousCheckpoint:assistantMessageText(n)}}function keepNonToolResultMessages(e){let t=[];for(let n of e)if(n.role!==`tool`){if(n.role===`assistant`){let e=assistantMessageText(n);e.length>0&&t.push({content:e,role:`assistant`});continue}t.push(n)}return t}function assistantMessageText(e){return typeof e.content==`string`?e.content.trim():e.content.filter(e=>e.type===`text`).map(e=>e.text).join(``).trim()}function selectRecentWindowSize(e,t){let n=Math.min(t.recentWindowSize,Math.max(e.length-1,0)),r=resolveCompactionSummaryReserve(t),i=0,a=0;for(let o=e.length-1;o>=0&&i<n;--o){let n=e[o];if(n===void 0)continue;let s=estimateTokens([n]);if(a+s+r>t.threshold)break;a+=s,i+=1}return i}function resolveCompactionSummaryReserve(e){return Math.min(2048,Math.max(64,Math.floor(e.threshold/4)))}function splitMessagesForCompaction(e,t){if(t<=0)return{older:[...e],recent:[]};let n=e.length-t;for(;n<e.length&&e[n]?.role===`tool`;)n+=1;return{older:e.slice(0,n),recent:e.slice(n)}}export{compactMessages,getInputTokenCount,resolveCompactionModel,shouldCompact};
1
+ import{createFrameworkUserMessage,isFrameworkUserMessage}from"#harness/messages.js";import{COMPACTION_CHECKPOINT_MARKER,COMPACTION_PROMPT_ENVELOPE,COMPACTION_RESUMPTION_MESSAGE,TRANSCRIPT_PAYLOAD_LIMIT,createCompactionPrompt,sliceUtf16Safe,stubContentOutputFileParts}from"#harness/compaction/prompt.js";import{estimateTokens}from"#harness/token-estimate.js";const COMPACTION_PROMPT_OVERHEAD_TOKENS=estimateTokens([{content:COMPACTION_PROMPT_ENVELOPE.system,role:`system`},createFrameworkUserMessage(`context.compaction`,COMPACTION_PROMPT_ENVELOPE.prompt)]);function getInputTokenCount(e,t,n=0,r=0){let i=t.lastKnownInputTokens,a=t.lastKnownPromptMessageCount;return i===void 0||a===void 0||!Number.isInteger(a)||a<0||a>e.length?estimateTokens(e)+n:i+estimateTokens(e.slice(a))+Math.max(0,n-r)}function shouldCompact(e,t,n=0,r=0){return e.length>0&&getInputTokenCount(e,t,n,r)+COMPACTION_PROMPT_OVERHEAD_TOKENS>t.threshold}const COMPACTION_HEURISTICS=[toolResultCapHeuristic];function toolResultCapHeuristic(e){let t=withResumptionGuard([...e.previousCheckpoint===void 0?[]:[createFrameworkUserMessage(`context.compaction`,COMPACTION_CHECKPOINT_MARKER),{content:e.previousCheckpoint,role:`assistant`}],...capToolResults(e.older),...e.recent],e.conversation,e.config.threshold);return evaluateThreshold(t,e.config,`should-compact`,e.tokenEstimateAdjustment).type===`within-limit`?{messages:t,type:`within-limit`}:{type:`insufficient`}}function evaluateThreshold(e,t,n,r=0){let i=n===`should-compact`?COMPACTION_PROMPT_OVERHEAD_TOKENS:0,a=estimateTokens(e)+i+r;return{estimatedTokens:a,type:a<=t.threshold?`within-limit`:`over-limit`}}async function compactMessages(e,t,n,r=!1,i){let{conversation:a,previousCheckpoint:o}=extractPreviousCheckpoint(e),s=selectRecentWindowSize(a,r?{...t,recentWindowSize:1}:t);if(!r){let{older:n,recent:r}=splitMessagesForCompaction(a,s);if(n.length===0&&o===void 0)return keepNonToolResultMessages(r);let c=Math.max(0,(i??getInputTokenCount(e,t))-estimateTokens(e));for(let e of COMPACTION_HEURISTICS){let i=e({config:t,conversation:a,older:n,previousCheckpoint:o,recent:r,tokenEstimateAdjustment:c});if(i.type===`within-limit`)return i.messages}}for(;;){let{older:e,recent:r}=splitMessagesForCompaction(a,s),i=createCompactionPrompt({messages:e,previousCheckpoint:o,transcriptBudgetTokens:t.threshold}),c=await n({messages:[createFrameworkUserMessage(`context.compaction`,i.prompt)],system:i.system}),l=[createFrameworkUserMessage(`context.compaction`,COMPACTION_CHECKPOINT_MARKER),{content:c,role:`assistant`}],u=withResumptionGuard([...l,...r],a,t.threshold);if(evaluateThreshold(u,t,`estimate`).type===`within-limit`)return u;let d=withResumptionGuard([...l,...keepNonToolResultMessages(r)],a,t.threshold);if(evaluateThreshold(d,t,`estimate`).type===`within-limit`||s===0)return d;--s}}function capToolResults(e){return e.map(e=>{if(e.role!==`tool`||typeof e.content==`string`)return e;let t=!1,n=e.content.map(e=>{if(e.type!==`tool-result`)return e;let n=stubContentOutputFileParts(e.output),r=JSON.stringify(n)??``;return r.length<=TRANSCRIPT_PAYLOAD_LIMIT?n===e.output?e:(t=!0,{...e,output:n}):(t=!0,{...e,output:{type:`text`,value:`[Truncated by eve: tool result reduced during context compaction. Re-run the tool if you need the full output.]\n\n${sliceUtf16Safe(r,TRANSCRIPT_PAYLOAD_LIMIT)}`}})});return t?{...e,content:n}:e})}function withResumptionGuard(e,t,n){let r=e.at(-1)?.role,i=findLastRealUserMessage(t),a=i!==void 0&&e.some(e=>e.role===`user`&&e.content===i.content);return r!==void 0&&r!==`assistant`?r===`tool`&&i!==void 0&&!a&&estimateTokens([i])<=n?[...e,i]:e:[...e,i!==void 0&&!a?i:createFrameworkUserMessage(`execution.continuation`,COMPACTION_RESUMPTION_MESSAGE)]}function findLastRealUserMessage(e){for(let t=e.length-1;t>=0;--t){let n=e[t];if(n?.role===`user`&&typeof n.content==`string`&&!isFrameworkUserMessage(n))return n}}function extractPreviousCheckpoint(e){let t=e[0],n=e[1];return t?.role!==`user`||t.content!==COMPACTION_CHECKPOINT_MARKER||n?.role!==`assistant`?{conversation:[...e],previousCheckpoint:void 0}:{conversation:e.slice(2),previousCheckpoint:assistantMessageText(n)}}function keepNonToolResultMessages(e){let t=[];for(let n of e)if(n.role!==`tool`){if(n.role===`assistant`){let e=assistantMessageText(n);e.length>0&&t.push({content:e,role:`assistant`});continue}t.push(n)}return t}function assistantMessageText(e){return typeof e.content==`string`?e.content.trim():e.content.filter(e=>e.type===`text`).map(e=>e.text).join(``).trim()}function selectRecentWindowSize(e,t){let n=Math.min(t.recentWindowSize,Math.max(e.length-1,0)),r=resolveCompactionSummaryReserve(t),i=0,a=0;for(let o=e.length-1;o>=0&&i<n;--o){let n=e[o];if(n===void 0)continue;let s=estimateTokens([n]);if(a+s+r>t.threshold)break;a+=s,i+=1}return i}function resolveCompactionSummaryReserve(e){return Math.min(2048,Math.max(64,Math.floor(e.threshold/4)))}function splitMessagesForCompaction(e,t){if(t<=0)return{older:[...e],recent:[]};let n=e.length-t;for(;n<e.length&&e[n]?.role===`tool`;)n+=1;return{older:e.slice(0,n),recent:e.slice(n)}}export{compactMessages,getInputTokenCount,shouldCompact};
@@ -1,4 +1,4 @@
1
- import type { LanguageModel, TelemetryOptions } from "ai";
1
+ import { type LanguageModel, type TelemetryOptions } from "ai";
2
2
  import { type HarnessSession, type StepResult, type ToolLoopHarnessConfig } from "#harness/types.js";
3
3
  import { type HarnessModelMessage } from "#harness/messages.js";
4
4
  import type { HistoryViewProjector } from "#shared/history-view.js";
@@ -26,6 +26,8 @@ export declare function replaceSessionHistory(session: HarnessSession, history:
26
26
  export declare function maybeCompact(input: {
27
27
  readonly abortSignal?: AbortSignal;
28
28
  readonly auth: SessionAuthContext | null;
29
+ /** A manual compaction runs between turns, so no turn's usage reports its summary calls. */
30
+ readonly betweenTurns?: boolean;
29
31
  readonly emissionState: TurnPosition;
30
32
  readonly force?: boolean;
31
33
  readonly historyProjector?: HistoryViewProjector;
@@ -41,6 +43,10 @@ export declare function maybeCompact(input: {
41
43
  readonly telemetry?: TelemetryOptions;
42
44
  }): Promise<{
43
45
  readonly compacted: boolean;
46
+ /** The summary failed; `session` still counts the summary calls that finished. */
47
+ readonly failure?: {
48
+ readonly error: unknown;
49
+ };
44
50
  readonly messages: HarnessModelMessage[];
45
51
  readonly session: HarnessSession;
46
52
  }>;
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{AuthKey,HistoryStateKey}from"#context/keys.js";import{createCompactionCompletedEvent,createCompactionRequestedEvent}from"#protocol/message.js";import{validateHarnessModelMessages}from"#harness/messages.js";import{drainMemoryCommit,prepareMemoryCompaction}from"#context/memory-lifecycle.js";import{canonicalizeMemoryRecords,shouldCanonicalizeMemory}from"#shared/memory-state.js";import{activeTurnId}from"#harness/session-machine/view.js";import{resolveConversationId}from"#shared/conversation-identity.js";import{idle}from"#harness/session-machine/transitions.js";import{stepStartedForResolvers}from"#harness/session-machine/resolver-events.js";import{requireSessionModelReference}from"#harness/types.js";import{buildGatewayAttributionHeaders,resolveEffectiveRuntimeModel}from"#harness/model-call/model.js";import{compactMessages,getInputTokenCount,resolveCompactionModel,shouldCompact}from"#harness/compaction/engine.js";import{gatewayModelId}from"#harness/model-call/usage.js";import{getRequestEnvelopeTokens}from"#harness/request-envelope.js";import{resolveCallProviderOptions}from"#harness/provider-safety.js";const log=createLogger(`harness.tool-loop`);async function compactHistory(e){let{config:t}=e;if(e.session.history.length>0)try{if(e.ctx!==void 0&&t.dispatchDynamicModelEvent!==void 0){let n=e.position();await t.dispatchDynamicModelEvent({ctx:e.ctx,event:stepStartedForResolvers({modelId:e.session.agent.modelReference?.id??`dynamic`,sequence:n.sequence,stepIndex:n.stepIndex,turnId:activeTurnId(n)}),messages:validateHarnessModelMessages(e.projectHistory(e.session.history))})}let n=await resolveEffectiveRuntimeModel({config:t,ctx:e.ctx,session:e.session});e.session=n.session;let r=e.position();e.session=(await maybeCompact({abortSignal:t.abortSignal,auth:e.ctx?.get(AuthKey)??null,emissionState:{...r,turnId:activeTurnId(r)},force:!0,historyProjector:t.historyProjector,messages:[...e.session.history],model:n.model,publish:e.publish,requestEnvelopeTokens:getRequestEnvelopeTokens(e.session),resolveModel:t.resolveModel,runtimeIdentity:t.runtimeIdentity,session:e.session,telemetry:e.instrumentation?.telemetry()})).session}catch(t){logError(log,`manual session compaction failed`,t,{sessionId:e.session.sessionId})}return await e.apply(idle(e.view())),{next:null,session:e.session}}function replaceSessionHistory(e,t){return contextStorage.getStore()?.delete(HistoryStateKey),{...e,history:t,compaction:{recentWindowSize:e.compaction.recentWindowSize,threshold:e.compaction.threshold,thresholdPercent:e.compaction.thresholdPercent}}}async function maybeCompact(e){let{emissionState:t,publish:n}=e,r=e.messages,i=e.session,a=e.promptMessages??r,o=validateHarnessModelMessages(e.historyProjector?.({messages:a,state:i.state})??a),s=e.force===!0||shouldCompact(o,i.compaction,e.requestEnvelopeTokens,getRequestEnvelopeTokens(i)),c=shouldCanonicalizeMemory(r);if(!s&&!c)return{compacted:!1,messages:r,session:i};let l=await resolveCompactionModel({compactionModelReference:i.agent.compactionModelReference,model:e.model,modelReference:requireSessionModelReference(i),resolveModel:e.resolveModel}),u=i.agent.compactionModelReference??requireSessionModelReference(i),d=resolveCallProviderOptions({auth:e.auth,conversationId:resolveConversationId(i.rootSessionId??i.sessionId),model:l.model,modelReference:u,providerOptions:l.providerOptions});{let a=contextStorage.getStore();a!==void 0&&prepareMemoryCompaction(a,{history:r,state:i.state}),await n(createCompactionRequestedEvent({modelId:gatewayModelId(l.model)??`unknown`,sequence:t.sequence,sessionId:i.sessionId,stepIndex:t.stepIndex,turnId:t.turnId,usageInputTokens:getInputTokenCount(o,i.compaction,e.requestEnvelopeTokens,getRequestEnvelopeTokens(i))}),o)}let f=canonicalizeMemoryRecords(r),p=validateHarnessModelMessages(e.historyProjector?.({messages:f.ordinary,state:i.state})??f.ordinary),m=e.requestEnvelopeTokens??0,h={...i.compaction,threshold:Math.max(1,i.compaction.threshold-m),lastKnownInputTokens:i.compaction.lastKnownInputTokens===void 0?void 0:Math.max(0,i.compaction.lastKnownInputTokens-Math.min(getRequestEnvelopeTokens(i)??0,m))},g=s?await compactMessages([...p],l.model,h,d,e.telemetry,buildGatewayAttributionHeaders(l.model,e.runtimeIdentity),e.abortSignal,e.force===!0,e.requestEnvelopeTokens===void 0?void 0:Math.max(0,getInputTokenCount(o,i.compaction,m,getRequestEnvelopeTokens(i))-m)):[...p];r=validateHarnessModelMessages([...f.memory,...g]);{let a=contextStorage.getStore();if(a!==void 0&&prepareMemoryCompaction(a,{history:r,state:i.state}),await n(createCompactionCompletedEvent({modelId:gatewayModelId(l.model)??`unknown`,sequence:t.sequence,sessionId:i.sessionId,stepIndex:t.stepIndex,turnId:t.turnId}),e.historyProjector?.({messages:r,state:i.state})??r),a!==void 0){let e=drainMemoryCommit(a);e!==void 0&&(r=validateHarnessModelMessages([...r,...e.recalledMessages]),i={...i,state:e.state})}}return{compacted:!0,messages:r,session:replaceSessionHistory(i,r)}}export{compactHistory,maybeCompact,replaceSessionHistory};
1
+ import{streamText}from"ai";import{createLogger,logError}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{AuthKey,HistoryStateKey}from"#context/keys.js";import{createCompactionCompletedEvent,createCompactionRequestedEvent}from"#protocol/message.js";import{validateHarnessModelMessages}from"#harness/messages.js";import{drainMemoryCommit,prepareMemoryCompaction}from"#context/memory-lifecycle.js";import{canonicalizeMemoryRecords,shouldCanonicalizeMemory}from"#shared/memory-state.js";import{activeTurnId}from"#harness/session-machine/view.js";import{resolveConversationId}from"#shared/conversation-identity.js";import{addTurnUsage,addUsageOutsideTurns}from"#harness/turn-tag-state.js";import{idle}from"#harness/session-machine/transitions.js";import{stepStartedForResolvers}from"#harness/session-machine/resolver-events.js";import{requireSessionModelReference}from"#harness/types.js";import{buildGatewayAttributionHeaders,resolveEffectiveRuntimeModel}from"#harness/model-call/model.js";import{compactMessages,getInputTokenCount,shouldCompact}from"#harness/compaction/engine.js";import{normalizeModelStreamError}from"#harness/model-call/errors.js";import{runModelCallWithRetries}from"#harness/model-call/retry.js";import{extractGatewayCostUsd,extractTokenUsageDelta,gatewayModelId}from"#harness/model-call/usage.js";import{resolveModelProfile}from"#harness/model-profile.js";import{getRequestEnvelopeTokens}from"#harness/request-envelope.js";import{resolveCallProviderOptions}from"#harness/provider-safety.js";const log=createLogger(`harness.tool-loop`);async function compactHistory(e){let{config:t}=e;if(e.session.history.length>0)try{if(e.ctx!==void 0&&t.dispatchDynamicModelEvent!==void 0){let n=e.position();await t.dispatchDynamicModelEvent({ctx:e.ctx,event:stepStartedForResolvers({modelId:e.session.agent.modelReference?.id??`dynamic`,sequence:n.sequence,stepIndex:n.stepIndex,turnId:activeTurnId(n)}),messages:validateHarnessModelMessages(e.projectHistory(e.session.history))})}let n=await resolveEffectiveRuntimeModel({config:t,ctx:e.ctx,session:e.session});e.session=n.session;let r=e.position(),i=await maybeCompact({abortSignal:t.abortSignal,auth:e.ctx?.get(AuthKey)??null,betweenTurns:!0,emissionState:{...r,turnId:activeTurnId(r)},force:!0,historyProjector:t.historyProjector,messages:[...e.session.history],model:n.model,publish:e.publish,requestEnvelopeTokens:getRequestEnvelopeTokens(e.session),resolveModel:t.resolveModel,runtimeIdentity:t.runtimeIdentity,session:e.session,telemetry:e.instrumentation?.telemetry()});if(e.session=i.session,i.failure!==void 0)throw i.failure.error}catch(t){logError(log,`manual session compaction failed`,t,{sessionId:e.session.sessionId})}return await e.apply(idle(e.view())),{next:null,session:e.session}}function replaceSessionHistory(e,t){return contextStorage.getStore()?.delete(HistoryStateKey),{...e,history:t,compaction:{recentWindowSize:e.compaction.recentWindowSize,threshold:e.compaction.threshold,thresholdPercent:e.compaction.thresholdPercent}}}async function maybeCompact(e){let{emissionState:t,publish:n}=e,r=e.messages,i=e.session,a=e.promptMessages??r,o=validateHarnessModelMessages(e.historyProjector?.({messages:a,state:i.state})??a),s=e.force===!0||shouldCompact(o,i.compaction,e.requestEnvelopeTokens,getRequestEnvelopeTokens(i)),c=shouldCanonicalizeMemory(r);if(!s&&!c)return{compacted:!1,messages:r,session:i};let l=requireSessionModelReference(i),u=i.agent.compactionModelReference??l,d=u===l?e.model:await e.resolveModel(u),f=resolveModelProfile(d),p=resolveCallProviderOptions({auth:e.auth,conversationId:resolveConversationId(i.rootSessionId??i.sessionId),profile:f,providerOptions:u.providerOptions}),m={abortSignal:e.abortSignal,headers:buildGatewayAttributionHeaders(f,e.runtimeIdentity),model:d,providerOptions:p,telemetry:e.telemetry&&{...e.telemetry,functionId:`eve.compaction`}},h=[],summarize=async n=>{let r=await runModelCallWithRetries(()=>streamCompactionSummary({...m,...n}),{sessionId:i.sessionId,turnId:t.turnId},e.abortSignal);if(h.push(r.usage),r.text.trim().length===0)throw Error(`The compaction model returned an empty summary. Finish reason: ${r.finishReason}.`);return r.text};{let a=contextStorage.getStore();a!==void 0&&prepareMemoryCompaction(a,{history:r,state:i.state}),await n(createCompactionRequestedEvent({modelId:gatewayModelId(d)??`unknown`,sequence:t.sequence,sessionId:i.sessionId,stepIndex:t.stepIndex,turnId:t.turnId,usageInputTokens:getInputTokenCount(o,i.compaction,e.requestEnvelopeTokens,getRequestEnvelopeTokens(i))}),o)}let g=canonicalizeMemoryRecords(r),_=validateHarnessModelMessages(e.historyProjector?.({messages:g.ordinary,state:i.state})??g.ordinary),v=e.requestEnvelopeTokens??0,y={...i.compaction,threshold:Math.max(1,i.compaction.threshold-v),lastKnownInputTokens:i.compaction.lastKnownInputTokens===void 0?void 0:Math.max(0,i.compaction.lastKnownInputTokens-Math.min(getRequestEnvelopeTokens(i)??0,v))},b=[..._],x;try{s&&(b=await compactMessages([..._],y,summarize,e.force===!0,e.requestEnvelopeTokens===void 0?void 0:Math.max(0,getInputTokenCount(o,i.compaction,v,getRequestEnvelopeTokens(i))-v)))}catch(e){x={error:e}}for(let n of h)i=e.betweenTurns===!0?addUsageOutsideTurns(i,n):addTurnUsage(i,t.turnId,n);if(x!==void 0)return{compacted:!1,failure:x,messages:e.messages,session:i};r=validateHarnessModelMessages([...g.memory,...b]);{let a=contextStorage.getStore();if(a!==void 0&&prepareMemoryCompaction(a,{history:r,state:i.state}),await n(createCompactionCompletedEvent({modelId:gatewayModelId(d)??`unknown`,sequence:t.sequence,sessionId:i.sessionId,stepIndex:t.stepIndex,turnId:t.turnId}),e.historyProjector?.({messages:r,state:i.state})??r),a!==void 0){let e=drainMemoryCommit(a);e!==void 0&&(r=validateHarnessModelMessages([...r,...e.recalledMessages]),i={...i,state:e.state})}}return{compacted:!0,messages:r,session:replaceSessionHistory(i,r)}}async function streamCompactionSummary(e){let t=streamText({...e,onError:()=>{}});for await(let e of t.fullStream)if(e.type===`error`)throw normalizeModelStreamError(e.error);let[n,r,i,a]=await Promise.all([t.text,t.finishReason,t.usage,t.providerMetadata]);return{finishReason:r,text:n,usage:extractTokenUsageDelta({costUsd:extractGatewayCostUsd(a),usage:i})}}export{compactHistory,maybeCompact,replaceSessionHistory};
@@ -1 +1 @@
1
- import{createActionInputAppendedEvent,createActionPartialEvent,createActionResultEvent,createActionsRequestedEvent,createMessageAppendedEvent,createMessageCompletedEvent,createReasoningAppendedEvent,createReasoningCompletedEvent}from"#protocol/message.js";import{createRuntimeToolResultFromStepResult,createRuntimeToolResultFromToolError,createToolResultMessagePartFromToolError}from"#harness/action-result-helpers.js";import{emitNestedToolActions}from"#harness/nested-actions.js";import{createInvalidToolCallInputError,isInvalidToolCall,resolveProviderToolCallRequest}from"#harness/tool-call-input-errors.js";import{collectActionPresentation,createPresentedRuntimeActionRequestFromToolCall}from"#harness/action-presentation.js";import{projectDeltaPresentation,projectResultPresentation}from"#harness/tool-presentation.js";import{createProviderStreamActionBatch}from"#harness/stream-actions.js";import{normalizeModelStreamError}from"#harness/model-call/errors.js";import{createOrderedStreamEmitter}from"#harness/ordered-stream-emitter.js";import{interruptStreamOnFailure}from"#harness/interruptible-stream.js";import{isInlineAuthorizationToolResult}from"#harness/inline-tool-authorization.js";import{normalizeAssistantStepFinishReason}from"#harness/finish-reason.js";async function emitStreamContent(e,t,n,r){let i=createOrderedStreamEmitter(e),a=createProviderStreamActionBatch({emitFn:i.emit,onActionsEmitted:e=>{for(let{request:t,toolName:n}of e)r?.unsettledActionToolNames?.set(t.action.callId,n)},state:t});try{return await consumeStreamContent(i.emit,t,interruptStreamOnFailure(n,i.failureSignal),a,r)}finally{try{await a.cancel()}finally{await i.closeAndDrain()}}}function reportedFinishReason(e,t){return t&&e===`stop`?`tool-calls`:e}async function consumeStreamContent(e,t,n,r,i){let a=``,o=``,s=`stop`,c,l=new Set,u=new Set,d=new Set,f=new Set,p=new Set,m=new Set,h=[],g=[],_=new Map,v=new Map,flushCurrentMessage=async()=>{o.length!==0&&(await e(createMessageCompletedEvent({finishReason:`tool-calls`,message:o,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),o=``)},emitActionInput=async(n,r,a)=>{await e(createActionInputAppendedEvent({callId:n,inputTextDelta:a,sequence:t.sequence,stepIndex:t.stepIndex,toolName:r,turnId:t.turnId})),i?.unsettledActionToolNames?.set(n,r)},emitActionRequest=async(n,r)=>{let{action:a}=n;u.has(a.callId)||(o.trim().length>0&&await flushCurrentMessage(),u.add(a.callId),_.set(a.callId,a.input),await e(createActionsRequestedEvent({actions:[a],presentation:collectActionPresentation([n]),sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),i?.unsettledActionToolNames?.set(a.callId,r))},collectProviderToolCall=async e=>{if(f.has(e.toolCallId)||(f.add(e.toolCallId),u.has(e.toolCallId)))return;u.add(e.toolCallId),o.trim().length>0&&await flushCurrentMessage();let t=resolveProviderToolCallRequest(e,i?.tools??new Map);if(t.toolError!==void 0){m.add(e.toolCallId),await emitActionResult(createRuntimeToolResultFromToolError(t.toolError)),p.add(e.toolCallId),g.push(createToolResultMessagePartFromToolError(t.toolError));return}_.set(t.request.action.callId,t.request.action.input),r.observe(t.request,e.toolName)},emitActionResult=async n=>{if(d.has(n.callId))return;d.add(n.callId),await emitNestedToolActions(e,t,n.callId);let r=n.isError===!0?void 0:projectResultPresentation(i?.tools.get(n.toolName),n.callId,_.get(n.callId),n.output);await e(createActionResultEvent({presentation:r,result:n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),i?.unsettledActionToolNames?.delete(n.callId)},emitActionPartial=async n=>{let r=projectDeltaPresentation(i?.tools.get(n.toolName),n.callId,_.get(n.callId),n.output);await e(createActionPartialEvent({presentation:r,result:n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId}))},emitToolCall=async e=>{if(isInvalidToolCall(e)){m.add(e.toolCallId);return}if(!(i===void 0||i.excludedActionToolNames.has(e.toolName)))try{await emitActionRequest(createPresentedRuntimeActionRequestFromToolCall({toolCall:e,tools:i.tools}),e.toolName)}catch(t){if(t instanceof TypeError){let n=createInvalidToolCallInputError({error:t,toolCall:e});m.add(e.toolCallId),o.trim().length>0&&await flushCurrentMessage(),await emitActionResult(createRuntimeToolResultFromToolError(n)),p.add(e.toolCallId),g.push(createToolResultMessagePartFromToolError(n));return}throw t}};for await(let d of n)if(c===void 0)switch(d.type){case`reasoning-delta`:await r.flush(),a+=d.text,await e(createReasoningAppendedEvent({reasoningDelta:d.text,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId}));break;case`text-delta`:await r.flush(),a.trim().length>0&&(await e(createReasoningCompletedEvent({reasoning:a,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),a=``),o+=d.text,await e(createMessageAppendedEvent({messageDelta:d.text,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId}));break;case`tool-input-start`:if(i===void 0||d.providerExecuted===!0||i.excludedActionToolNames.has(d.toolName)){v.delete(d.id);break}await r.flush(),o.trim().length>0&&await flushCurrentMessage(),v.set(d.id,{toolName:d.toolName});break;case`tool-input-delta`:{let e=v.get(d.id);if(e===void 0)break;await r.flush(),await emitActionInput(d.id,e.toolName,d.delta);break}case`tool-input-end`:v.delete(d.id);break;case`tool-call`:{let e=d;v.delete(e.toolCallId),l.add(e.toolCallId),e.providerExecuted===!0?await collectProviderToolCall(e):(await r.flush(),await emitToolCall(e));break}case`tool-result`:{let e=d;if(e.preliminary===!0){e.providerExecuted!==!0&&await emitActionPartial(createRuntimeToolResultFromStepResult(e));break}if(e.providerExecuted===!0){await collectProviderToolCall({input:`input`in e?e.input:void 0,toolCallId:e.toolCallId,toolName:e.toolName}),await r.flush(),await emitActionResult(createRuntimeToolResultFromStepResult(e));break}if(l.has(d.toolCallId)){if(isInlineAuthorizationToolResult(e))break;u.has(d.toolCallId)&&(await emitActionResult(createRuntimeToolResultFromStepResult(e)),p.add(d.toolCallId));break}if(await r.flush(),await flushCurrentMessage(),isInlineAuthorizationToolResult(e)){p.add(d.toolCallId),h.push(e);break}await emitActionResult(createRuntimeToolResultFromStepResult(e)),p.add(d.toolCallId);break}case`tool-error`:{let e=d;e.providerExecuted===!0?(await collectProviderToolCall(e),await r.flush(),await emitActionResult(createRuntimeToolResultFromToolError(e))):u.has(e.toolCallId)&&(await emitActionResult(createRuntimeToolResultFromToolError(e)),p.add(e.toolCallId),g.push(createToolResultMessagePartFromToolError(e)));break}case`finish-step`:s=normalizeAssistantStepFinishReason(d.finishReason),await r.flush();break;case`error`:c=normalizeModelStreamError(d.error);break;case`abort`:throw new DOMException(d.reason??`The model stream was aborted.`,`AbortError`)}if(await r.flush(),c!==void 0)throw c;return a.trim().length>0&&await e(createReasoningCompletedEvent({reasoning:a,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),s!==`content-filter`&&o.trim().length>0&&await e(createMessageCompletedEvent({finishReason:reportedFinishReason(s,i?.hidesHeldText===!0),message:o,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),{emittedActionCallIds:u,handledInlineToolResultCallIds:p,invalidInputToolCallIds:m,inlineAuthorizationResults:h,trailingInlineToolResultParts:g}}export{emitStreamContent};
1
+ import{createActionInputAppendedEvent,createActionPartialEvent,createActionResultEvent,createActionsRequestedEvent,createMessageAppendedEvent,createMessageCompletedEvent,createReasoningAppendedEvent,createReasoningCompletedEvent}from"#protocol/message.js";import{createRuntimeToolResultFromStepResult,createRuntimeToolResultFromToolError,createToolResultMessagePartFromToolError}from"#harness/action-result-helpers.js";import{emitNestedToolActions}from"#harness/nested-actions.js";import{normalizeModelStreamError}from"#harness/model-call/errors.js";import{createInvalidToolCallInputError,isInvalidToolCall,resolveProviderToolCallRequest}from"#harness/tool-call-input-errors.js";import{collectActionPresentation,createPresentedRuntimeActionRequestFromToolCall}from"#harness/action-presentation.js";import{projectDeltaPresentation,projectResultPresentation}from"#harness/tool-presentation.js";import{createProviderStreamActionBatch}from"#harness/stream-actions.js";import{createOrderedStreamEmitter}from"#harness/ordered-stream-emitter.js";import{interruptStreamOnFailure}from"#harness/interruptible-stream.js";import{isInlineAuthorizationToolResult}from"#harness/inline-tool-authorization.js";import{normalizeAssistantStepFinishReason}from"#harness/finish-reason.js";async function emitStreamContent(e,t,n,r){let i=createOrderedStreamEmitter(e),a=createProviderStreamActionBatch({emitFn:i.emit,onActionsEmitted:e=>{for(let{request:t,toolName:n}of e)r?.unsettledActionToolNames?.set(t.action.callId,n)},state:t});try{return await consumeStreamContent(i.emit,t,interruptStreamOnFailure(n,i.failureSignal),a,r)}finally{try{await a.cancel()}finally{await i.closeAndDrain()}}}function reportedFinishReason(e,t){return t&&e===`stop`?`tool-calls`:e}async function consumeStreamContent(e,t,n,r,i){let a=``,o=``,s=`stop`,c,l=new Set,u=new Set,d=new Set,f=new Set,p=new Set,m=new Set,h=[],g=[],_=new Map,v=new Map,flushCurrentMessage=async()=>{o.length!==0&&(await e(createMessageCompletedEvent({finishReason:`tool-calls`,message:o,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),o=``)},emitActionInput=async(n,r,a)=>{await e(createActionInputAppendedEvent({callId:n,inputTextDelta:a,sequence:t.sequence,stepIndex:t.stepIndex,toolName:r,turnId:t.turnId})),i?.unsettledActionToolNames?.set(n,r)},emitActionRequest=async(n,r)=>{let{action:a}=n;u.has(a.callId)||(o.trim().length>0&&await flushCurrentMessage(),u.add(a.callId),_.set(a.callId,a.input),await e(createActionsRequestedEvent({actions:[a],presentation:collectActionPresentation([n]),sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),i?.unsettledActionToolNames?.set(a.callId,r))},collectProviderToolCall=async e=>{if(f.has(e.toolCallId)||(f.add(e.toolCallId),u.has(e.toolCallId)))return;u.add(e.toolCallId),o.trim().length>0&&await flushCurrentMessage();let t=resolveProviderToolCallRequest(e,i?.tools??new Map);if(t.toolError!==void 0){m.add(e.toolCallId),await emitActionResult(createRuntimeToolResultFromToolError(t.toolError)),p.add(e.toolCallId),g.push(createToolResultMessagePartFromToolError(t.toolError));return}_.set(t.request.action.callId,t.request.action.input),r.observe(t.request,e.toolName)},emitActionResult=async n=>{if(d.has(n.callId))return;d.add(n.callId),await emitNestedToolActions(e,t,n.callId);let r=n.isError===!0?void 0:projectResultPresentation(i?.tools.get(n.toolName),n.callId,_.get(n.callId),n.output);await e(createActionResultEvent({presentation:r,result:n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),i?.unsettledActionToolNames?.delete(n.callId)},emitActionPartial=async n=>{let r=projectDeltaPresentation(i?.tools.get(n.toolName),n.callId,_.get(n.callId),n.output);await e(createActionPartialEvent({presentation:r,result:n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId}))},emitToolCall=async e=>{if(isInvalidToolCall(e)){m.add(e.toolCallId);return}if(!(i===void 0||i.excludedActionToolNames.has(e.toolName)))try{await emitActionRequest(createPresentedRuntimeActionRequestFromToolCall({toolCall:e,tools:i.tools}),e.toolName)}catch(t){if(t instanceof TypeError){let n=createInvalidToolCallInputError({error:t,toolCall:e});m.add(e.toolCallId),o.trim().length>0&&await flushCurrentMessage(),await emitActionResult(createRuntimeToolResultFromToolError(n)),p.add(e.toolCallId),g.push(createToolResultMessagePartFromToolError(n));return}throw t}};for await(let d of n)if(c===void 0)switch(d.type){case`reasoning-delta`:await r.flush(),a+=d.text,await e(createReasoningAppendedEvent({reasoningDelta:d.text,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId}));break;case`text-delta`:await r.flush(),a.trim().length>0&&(await e(createReasoningCompletedEvent({reasoning:a,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),a=``),o+=d.text,await e(createMessageAppendedEvent({messageDelta:d.text,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId}));break;case`tool-input-start`:if(i===void 0||d.providerExecuted===!0||i.excludedActionToolNames.has(d.toolName)){v.delete(d.id);break}await r.flush(),o.trim().length>0&&await flushCurrentMessage(),v.set(d.id,{toolName:d.toolName});break;case`tool-input-delta`:{let e=v.get(d.id);if(e===void 0)break;await r.flush(),await emitActionInput(d.id,e.toolName,d.delta);break}case`tool-input-end`:v.delete(d.id);break;case`tool-call`:{let e=d;v.delete(e.toolCallId),l.add(e.toolCallId),e.providerExecuted===!0?await collectProviderToolCall(e):(await r.flush(),await emitToolCall(e));break}case`tool-result`:{let e=d;if(e.preliminary===!0){e.providerExecuted!==!0&&await emitActionPartial(createRuntimeToolResultFromStepResult(e));break}if(e.providerExecuted===!0){await collectProviderToolCall({input:`input`in e?e.input:void 0,toolCallId:e.toolCallId,toolName:e.toolName}),await r.flush(),await emitActionResult(createRuntimeToolResultFromStepResult(e));break}if(l.has(d.toolCallId)){if(isInlineAuthorizationToolResult(e))break;u.has(d.toolCallId)&&(await emitActionResult(createRuntimeToolResultFromStepResult(e)),p.add(d.toolCallId));break}if(await r.flush(),await flushCurrentMessage(),isInlineAuthorizationToolResult(e)){p.add(d.toolCallId),h.push(e);break}await emitActionResult(createRuntimeToolResultFromStepResult(e)),p.add(d.toolCallId);break}case`tool-error`:{let e=d;e.providerExecuted===!0?(await collectProviderToolCall(e),await r.flush(),await emitActionResult(createRuntimeToolResultFromToolError(e))):u.has(e.toolCallId)&&(await emitActionResult(createRuntimeToolResultFromToolError(e)),p.add(e.toolCallId),g.push(createToolResultMessagePartFromToolError(e)));break}case`finish-step`:s=normalizeAssistantStepFinishReason(d.finishReason),await r.flush();break;case`error`:c=normalizeModelStreamError(d.error);break;case`abort`:throw new DOMException(d.reason??`The model stream was aborted.`,`AbortError`)}if(await r.flush(),c!==void 0)throw c;return a.trim().length>0&&await e(createReasoningCompletedEvent({reasoning:a,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),s!==`content-filter`&&o.trim().length>0&&await e(createMessageCompletedEvent({finishReason:reportedFinishReason(s,i?.hidesHeldText===!0),message:o,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),{emittedActionCallIds:u,handledInlineToolResultCallIds:p,invalidInputToolCallIds:m,inlineAuthorizationResults:h,trailingInlineToolResultParts:g}}export{emitStreamContent};
@@ -1,7 +1,7 @@
1
1
  import { type LanguageModel, type ModelMessage } from "ai";
2
2
  import type { GenerationSteering } from "#harness/generation-steering.js";
3
3
  import type { HarnessModelMessage, UserModelMessage } from "#harness/messages.js";
4
- import { type AnthropicCacheMarker, type PromptCachePath } from "#harness/prompt-cache.js";
4
+ import { type ModelProfile } from "#harness/model-profile.js";
5
5
  import type { Step } from "#harness/step/context.js";
6
6
  import { type Prompt } from "#harness/step/prompt.js";
7
7
  import { type HarnessStepResult } from "#harness/step-hooks.js";
@@ -36,8 +36,7 @@ interface ModelCallerInput {
36
36
  * may first compact the prompt, which rewrites the durable messages the step later commits.
37
37
  */
38
38
  export declare class ModelCaller {
39
- readonly cachePath: PromptCachePath;
40
- readonly marker: AnthropicCacheMarker | undefined;
39
+ readonly profile: ModelProfile;
41
40
  private readonly attributionHeaders;
42
41
  /** The prompt as the model reads it, projected for its history view. */
43
42
  private projectedMessages;
@@ -1 +1 @@
1
- import{buildGatewayAttributionHeaders}from"./model.js";import{isEmptyModelResponse,rethrowNoOutputAsEmptyResponse}from"./recovery.js";import{modelInstructions,requestMessages,withTrailingUserNote}from"./request.js";import{answerSkippedToolCalls,appendMissingToolResultMessages,extractToolResultCallIds,withAccumulatedResponseMessages}from"./response.js";import{runModelCallWithRetries}from"./retry.js";import{logToolExecutionError,prepareModelTools}from"./tools.js";import{extractGatewayCostUsd,extractTokenUsageDelta}from"./usage.js";import{ToolLoopAgent,isStepCount}from"ai";import{createLogger,logError}from"#internal/logging.js";import{AuthKey,HistoryStateKey}from"#context/keys.js";import{createStepCompletedEvent}from"#protocol/message.js";import{activeTurnId}from"#harness/session-machine/view.js";import{accumulateTurnUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{hydrateSandboxAttachments,moveToolResultFilesToUserMessages}from"#harness/attachment-staging.js";import{discardAttempt}from"#harness/session-machine/transitions.js";import{throwIfTurnAborted}from"#harness/turn-cancellation.js";import{summarizeKnownError}from"#harness/semantic-errors/index.js";import{estimateTokens}from"#harness/token-estimate.js";import{estimateRequestEnvelope}from"#harness/request-envelope.js";import{workingTaskIds}from"#execution/tasks/model-step.js";import{ContentFilteredModelResponseError,EmptyModelResponseError}from"#harness/model-call/errors.js";import{interruptStreamOnFailure}from"#harness/interruptible-stream.js";import{buildToolApproval}from"#harness/tools.js";import{compactPrompt,projectPrompt,withClientContext}from"#harness/step/prompt.js";import{emitStreamContent}from"#harness/emission.js";import{FINAL_OUTPUT_TOOL_NAME}from"#harness/final-output.js";import{detectPromptCachePath,getAnthropicCacheMarker}from"#harness/prompt-cache.js";import{buildStepHooks,emitStepActions,readGatewayGenerationId}from"#harness/step-hooks.js";import{maybeCompact}from"#harness/compaction/step.js";const environment=process.env.NODE_ENV??`unknown`,log=createLogger(`harness.tool-loop`);var ModelCaller=class{cachePath;marker;attributionHeaders;projectedMessages;request;tools;modelMessages=[];requestEnvelopeTokens=0;interruptedUsage;compactionFailure;attemptIndex=0;step;prompt;input;constructor(e,t,n){this.step=e,this.prompt=t,this.input=n,this.cachePath=detectPromptCachePath(n.model),this.marker=this.cachePath.kind===`anthropic-direct`?getAnthropicCacheMarker():void 0,this.attributionHeaders=buildGatewayAttributionHeaders(n.model,e.config.runtimeIdentity),this.projectedMessages=n.projectedMessages,this.request=this.buildRequest(e.config.tools)}async call(e){let t=new Map;return await runModelCallWithRetries(async n=>(n>1&&(await this.settleRetriedActions(t),t=new Map),await this.attempt({...e,suppressStepStartedEmission:n!==1||e.suppressStepStartedEmission},t)),{canRetry:()=>this.compactionFailure===void 0,sessionId:this.step.session.sessionId,turnId:this.step.position().turnId},this.input.generation.signal)}async settleRetriedActions(e){for(let[t,n]of e)await this.step.apply(discardAttempt(this.step.view(),{calls:[{callId:t,toolName:n}]})),e.delete(t)}throwIfCompactionFailed(){if(this.compactionFailure!==void 0)throw this.compactionFailure.error}async steered(){let{step:e}=this;return throwIfTurnAborted(e.config.abortSignal),e.ctx?.set(HistoryStateKey,this.request.historyState),this.interruptedUsage!==void 0&&(e.session=setTurnUsageState(e.session,accumulateTurnUsage({previous:getTurnUsageState(e.session.state),turnId:e.position().turnId,usage:this.interruptedUsage}))),await e.emit?.(createStepCompletedEvent({...e.position(),finishReason:`other`,usage:this.interruptedUsage})),{next:e.runStep,session:{...e.session,history:[...this.request.history]},steered:!0}}clearInterruptedUsage(){this.interruptedUsage=void 0}buildRequest(e){return requestMessages(this.step,{coordinationTools:e,hidesHeldText:this.input.hidesHeldText,messages:this.prompt.messages,pendingApprovalsNote:this.input.pendingApprovalsNote,projectedMessages:this.projectedMessages,turnMessages:this.input.turnMessages})}instructions(e){return modelInstructions({extraSystemNote:e,marker:this.marker,session:this.step.session,systemMessages:this.request.systemMessages})}async prepare(e){let t=await prepareModelTools(this.step,{model:this.input.model,approvedTools:this.input.approvedTools,disabledProviderTools:e.disabledProviderTools,generation:this.input.generation,marker:this.marker});return this.tools=t,this.request=this.buildRequest(t.coordinationTools),this.requestEnvelopeTokens=await estimateRequestEnvelope({history:this.projectedMessages,instructions:this.instructions(e.extraSystemNote),messages:withTrailingUserNote(this.request.nonSystemMessages,e.trailingUserNote),tools:t.effectiveTools}),t}async compact(e,t){let{step:n,prompt:r}=this,{config:i}=n,a;try{a=await maybeCompact({abortSignal:i.abortSignal,auth:n.ctx?.get(AuthKey)??null,emissionState:n.position(),historyProjector:i.historyProjector,messages:[...r.messages],model:this.input.model,promptMessages:withClientContext(r),publish:n.publish,requestEnvelopeTokens:this.requestEnvelopeTokens,resolveModel:i.resolveModel,runtimeIdentity:i.runtimeIdentity,session:n.session,telemetry:n.instrumentation?.telemetry()})}catch(e){throw this.compactionFailure={error:e},e}if(n.session=a.session,!a.compacted)return t;compactPrompt(n,r,a.messages);let{compaction:o}=n.session;return n.session={...n.session,compaction:{recentWindowSize:o.recentWindowSize,threshold:o.threshold,thresholdPercent:o.thresholdPercent}},this.projectedMessages=projectPrompt(n,r),await this.prepare(e)}async attempt(e,t){let{step:n}=this,{generation:r,model:i}=this.input,a=await this.compact(e,await this.prepare(e));this.requestEnvelopeTokens=Math.max(0,this.requestEnvelopeTokens-(estimateTokens(this.request.history)-estimateTokens(this.prompt.messages))),r.begin(),this.modelMessages=await hydrateSandboxAttachments(this.request.nonSystemMessages),typeof this.input.model!=`string`&&typeof this.input.model.provider==`string`&&this.input.model.provider.endsWith(`.chat`)&&(this.modelMessages=moveToolResultFilesToUserMessages(this.modelMessages));let o=this.instructions(e.extraSystemNote),s=n.instrumentation?.resolveRuntimeContext({emissionState:n.position(),environment,modelInput:{instructions:o,messages:this.modelMessages},session:n.session})??{};e.retryReason&&(s[`eve.retry.reason`]=e.retryReason);let c=withTrailingUserNote(this.modelMessages,e.trailingUserNote),l=n.position(),u=n.instrumentation?.prepareAttempt({isFrameworkTool:e=>n.frameworkToolNames.has(e),attemptIndex:this.attemptIndex++,runtimeContext:s,stepIndex:l.stepIndex,turnId:activeTurnId(l)});this.input.setAttemptScope(u?.scope);let d=buildStepHooks({auth:n.ctx?.get(AuthKey)??null,cachePath:this.cachePath,marker:this.marker,session:n.session,startStep:e.suppressStepStartedEmission===!0?void 0:this.input.startStep}),f={headers:this.attributionHeaders,instructions:o,model:i,onLanguageModelCallEnd:e=>{r.interrupted||(this.interruptedUsage=extractTokenUsageDelta({costUsd:extractGatewayCostUsd(e.providerMetadata),usage:e.usage}))},onToolExecutionEnd:logToolExecutionError,onError(e){r.interrupted||summarizeKnownError(e.error)?.tags.includes(`config`)!==!0&&logError(log,`tool-loop stream error`,e.error)},onStepEnd:d.onStepEnd,onStepStart:d.onStepStart,prepareStep:d.prepareStep,reasoning:n.session.agent.modelReference?.reasoning??n.session.agent.reasoning,runtimeContext:s,stopWhen:isStepCount(1),telemetry:u?.telemetry,toolApproval:buildToolApproval(a.modelTools,r.signal),tools:a.effectiveTools},p=new ToolLoopAgent(f);try{let e=n.emit===void 0?await this.generate(p,c,d.stepResult):await this.stream(p,c,d.stepResult,a,t);return await u?.complete(),e}catch(e){return r.interrupted?await u?.complete():await u?.fail(e),r.check(),rethrowNoOutputAsEmptyResponse(e)}}async stream(e,t,n,r,i){let{step:a}=this,{generation:o}=this.input,s=new Set([FINAL_OUTPUT_TOOL_NAME]),c=await e.stream({abortSignal:o.signal,messages:t}),{emittedActionCallIds:l,handledInlineToolResultCallIds:u,invalidInputToolCallIds:d,inlineAuthorizationResults:f,trailingInlineToolResultParts:p}=await emitStreamContent(a.publish,a.position(),interruptStreamOnFailure(c.fullStream,o.signal),{excludedActionToolNames:s,hidesHeldText:this.input.hidesHeldText&&workingTaskIds(a.session).length>0,tools:r.presentationTools,unsettledActionToolNames:i});throwIfTurnAborted(a.config.abortSignal),o.check();let[m,h]=await Promise.all([n,c.responseMessages]);assertUsableResponse(m,h,f.length>0||p.length>0);let g=answerSkippedToolCalls(m,r.effectiveTools);await emitStepActions(a.publish,a.position(),g.length===0?m:withAccumulatedResponseMessages({stepResult:m,responseMessages:appendMissingToolResultMessages({append:g,responseMessages:m.response.messages})}),{emittedActionCallIds:l,excludedActionCallIds:d,excludedActionToolNames:s,handledInlineToolResultCallIds:u,tools:r.presentationTools});let _=new Map(m.toolResults.map(e=>[e.toolCallId,e]));for(let e of f)_.set(e.toolCallId,e);return withAccumulatedResponseMessages({invalidInputToolCallIds:d,responseMessages:appendMissingToolResultMessages({append:[...p,...answerSkippedToolCalls(m,r.effectiveTools)],responseMessages:h}),stepResult:m,toolResults:[..._.values()]})}async generate(e,t,n){let{generation:r}=this.input,i=await e.generate({abortSignal:r.signal,messages:t});throwIfTurnAborted(this.step.config.abortSignal),r.check();let a=await n;return assertUsableResponse(a,i.responseMessages,!1),withAccumulatedResponseMessages({responseMessages:appendMissingToolResultMessages({append:answerSkippedToolCalls(a,this.tools.effectiveTools),responseMessages:i.responseMessages}),stepResult:a})}};function assertUsableResponse(e,t,n){if(e.finishReason===`content-filter`)throw new ContentFilteredModelResponseError(readGatewayGenerationId(e.providerMetadata));if(isEmptyModelResponse(e)&&extractToolResultCallIds(t).size===0&&!n)throw new EmptyModelResponseError}export{ModelCaller};
1
+ import{buildGatewayAttributionHeaders}from"./model.js";import{isEmptyModelResponse,rethrowNoOutputAsEmptyResponse}from"./recovery.js";import{modelInstructions,requestMessages,withTrailingUserNote}from"./request.js";import{answerSkippedToolCalls,appendMissingToolResultMessages,extractToolResultCallIds,withAccumulatedResponseMessages}from"./response.js";import{runModelCallWithRetries}from"./retry.js";import{logToolExecutionError,prepareModelTools}from"./tools.js";import{extractGatewayCostUsd,extractTokenUsageDelta}from"./usage.js";import{ToolLoopAgent,isStepCount}from"ai";import{createLogger,logError}from"#internal/logging.js";import{AuthKey,HistoryStateKey}from"#context/keys.js";import{createStepCompletedEvent}from"#protocol/message.js";import{activeTurnId}from"#harness/session-machine/view.js";import{addTurnUsage}from"#harness/turn-tag-state.js";import{hydrateSandboxAttachments,moveToolResultFilesToUserMessages}from"#harness/attachment-staging.js";import{discardAttempt}from"#harness/session-machine/transitions.js";import{throwIfTurnAborted}from"#harness/turn-cancellation.js";import{summarizeKnownError}from"#harness/semantic-errors/index.js";import{estimateTokens}from"#harness/token-estimate.js";import{ContentFilteredModelResponseError,EmptyModelResponseError}from"#harness/model-call/errors.js";import{resolveModelProfile}from"#harness/model-profile.js";import{estimateRequestEnvelope}from"#harness/request-envelope.js";import{workingTaskIds}from"#execution/tasks/model-step.js";import{interruptStreamOnFailure}from"#harness/interruptible-stream.js";import{buildToolApproval}from"#harness/tools.js";import{compactPrompt,projectPrompt,withClientContext}from"#harness/step/prompt.js";import{emitStreamContent}from"#harness/emission.js";import{FINAL_OUTPUT_TOOL_NAME}from"#harness/final-output.js";import{buildStepHooks,emitStepActions,readGatewayGenerationId}from"#harness/step-hooks.js";import{maybeCompact}from"#harness/compaction/step.js";const environment=process.env.NODE_ENV??`unknown`,log=createLogger(`harness.tool-loop`);var ModelCaller=class{profile;attributionHeaders;projectedMessages;request;tools;modelMessages=[];requestEnvelopeTokens=0;interruptedUsage;compactionFailure;attemptIndex=0;step;prompt;input;constructor(e,t,n){this.step=e,this.prompt=t,this.input=n,this.profile=resolveModelProfile(n.model),this.attributionHeaders=buildGatewayAttributionHeaders(this.profile,e.config.runtimeIdentity),this.projectedMessages=n.projectedMessages,this.request=this.buildRequest(e.config.tools)}async call(e){let t=new Map;return await runModelCallWithRetries(async n=>(n>1&&(await this.settleRetriedActions(t),t=new Map),await this.attempt({...e,suppressStepStartedEmission:n!==1||e.suppressStepStartedEmission},t)),{canRetry:()=>this.compactionFailure===void 0,sessionId:this.step.session.sessionId,turnId:this.step.position().turnId},this.input.generation.signal)}async settleRetriedActions(e){for(let[t,n]of e)await this.step.apply(discardAttempt(this.step.view(),{calls:[{callId:t,toolName:n}]})),e.delete(t)}throwIfCompactionFailed(){if(this.compactionFailure!==void 0)throw this.compactionFailure.error}async steered(){let{step:e}=this;return throwIfTurnAborted(e.config.abortSignal),e.ctx?.set(HistoryStateKey,this.request.historyState),this.interruptedUsage!==void 0&&(e.session=addTurnUsage(e.session,e.position().turnId,this.interruptedUsage)),await e.emit?.(createStepCompletedEvent({...e.position(),finishReason:`other`,usage:this.interruptedUsage})),{next:e.runStep,session:{...e.session,history:[...this.request.history]},steered:!0}}clearInterruptedUsage(){this.interruptedUsage=void 0}buildRequest(e){return requestMessages(this.step,{coordinationTools:e,hidesHeldText:this.input.hidesHeldText,messages:this.prompt.messages,pendingApprovalsNote:this.input.pendingApprovalsNote,projectedMessages:this.projectedMessages,turnMessages:this.input.turnMessages})}instructions(e){return modelInstructions({anthropicCache:this.profile.anthropicCache,extraSystemNote:e,session:this.step.session,systemMessages:this.request.systemMessages})}async prepare(e){let t=await prepareModelTools(this.step,{approvedTools:this.input.approvedTools,disabledProviderTools:e.disabledProviderTools,generation:this.input.generation,profile:this.profile});return this.tools=t,this.request=this.buildRequest(t.coordinationTools),this.requestEnvelopeTokens=await estimateRequestEnvelope({history:this.projectedMessages,instructions:this.instructions(e.extraSystemNote),messages:withTrailingUserNote(this.request.nonSystemMessages,e.trailingUserNote),tools:t.effectiveTools}),t}async compact(e,t){let{step:n,prompt:r}=this,{config:i}=n,a;try{if(a=await maybeCompact({abortSignal:i.abortSignal,auth:n.ctx?.get(AuthKey)??null,emissionState:n.position(),historyProjector:i.historyProjector,messages:[...r.messages],model:this.input.model,promptMessages:withClientContext(r),publish:n.publish,requestEnvelopeTokens:this.requestEnvelopeTokens,resolveModel:i.resolveModel,runtimeIdentity:i.runtimeIdentity,session:n.session,telemetry:n.instrumentation?.telemetry()}),a.failure!==void 0)throw a.failure.error}catch(e){throw this.compactionFailure={error:e},e}if(n.session=a.session,!a.compacted)return t;compactPrompt(n,r,a.messages);let{compaction:o}=n.session;return n.session={...n.session,compaction:{recentWindowSize:o.recentWindowSize,threshold:o.threshold,thresholdPercent:o.thresholdPercent}},this.projectedMessages=projectPrompt(n,r),await this.prepare(e)}async attempt(e,t){let{step:n}=this,{generation:r,model:i}=this.input,a=await this.compact(e,await this.prepare(e));this.requestEnvelopeTokens=Math.max(0,this.requestEnvelopeTokens-(estimateTokens(this.request.history)-estimateTokens(this.prompt.messages))),r.begin(),this.modelMessages=await hydrateSandboxAttachments(this.request.nonSystemMessages),this.profile.filesOutsideToolResults&&(this.modelMessages=moveToolResultFilesToUserMessages(this.modelMessages));let o=this.instructions(e.extraSystemNote),s=n.instrumentation?.resolveRuntimeContext({emissionState:n.position(),environment,modelInput:{instructions:o,messages:this.modelMessages},session:n.session})??{};e.retryReason&&(s[`eve.retry.reason`]=e.retryReason);let c=withTrailingUserNote(this.modelMessages,e.trailingUserNote),l=n.position(),u=n.instrumentation?.prepareAttempt({isFrameworkTool:e=>n.frameworkToolNames.has(e),attemptIndex:this.attemptIndex++,runtimeContext:s,stepIndex:l.stepIndex,turnId:activeTurnId(l)});this.input.setAttemptScope(u?.scope);let d=buildStepHooks({auth:n.ctx?.get(AuthKey)??null,profile:this.profile,session:n.session,startStep:e.suppressStepStartedEmission===!0?void 0:this.input.startStep}),f={headers:this.attributionHeaders,instructions:o,model:i,onLanguageModelCallEnd:e=>{r.interrupted||(this.interruptedUsage=extractTokenUsageDelta({costUsd:extractGatewayCostUsd(e.providerMetadata),usage:e.usage}))},onToolExecutionEnd:logToolExecutionError,onError(e){r.interrupted||summarizeKnownError(e.error)?.tags.includes(`config`)!==!0&&logError(log,`tool-loop stream error`,e.error)},onStepEnd:d.onStepEnd,onStepStart:d.onStepStart,prepareStep:d.prepareStep,reasoning:n.session.agent.modelReference?.reasoning??n.session.agent.reasoning,runtimeContext:s,stopWhen:isStepCount(1),telemetry:u?.telemetry,toolApproval:buildToolApproval(a.modelTools,r.signal),tools:a.effectiveTools},p=new ToolLoopAgent(f);try{let e=n.emit===void 0?await this.generate(p,c,d.stepResult):await this.stream(p,c,d.stepResult,a,t);return await u?.complete(),e}catch(e){return r.interrupted?await u?.complete():await u?.fail(e),r.check(),rethrowNoOutputAsEmptyResponse(e)}}async stream(e,t,n,r,i){let{step:a}=this,{generation:o}=this.input,s=new Set([FINAL_OUTPUT_TOOL_NAME]),c=await e.stream({abortSignal:o.signal,messages:t}),{emittedActionCallIds:l,handledInlineToolResultCallIds:u,invalidInputToolCallIds:d,inlineAuthorizationResults:f,trailingInlineToolResultParts:p}=await emitStreamContent(a.publish,a.position(),interruptStreamOnFailure(c.fullStream,o.signal),{excludedActionToolNames:s,hidesHeldText:this.input.hidesHeldText&&workingTaskIds(a.session).length>0,tools:r.presentationTools,unsettledActionToolNames:i});throwIfTurnAborted(a.config.abortSignal),o.check();let[m,h]=await Promise.all([n,c.responseMessages]);assertUsableResponse(m,h,f.length>0||p.length>0);let g=answerSkippedToolCalls(m,r.effectiveTools);await emitStepActions(a.publish,a.position(),g.length===0?m:withAccumulatedResponseMessages({stepResult:m,responseMessages:appendMissingToolResultMessages({append:g,responseMessages:m.response.messages})}),{emittedActionCallIds:l,excludedActionCallIds:d,excludedActionToolNames:s,handledInlineToolResultCallIds:u,tools:r.presentationTools});let _=new Map(m.toolResults.map(e=>[e.toolCallId,e]));for(let e of f)_.set(e.toolCallId,e);return withAccumulatedResponseMessages({invalidInputToolCallIds:d,responseMessages:appendMissingToolResultMessages({append:[...p,...answerSkippedToolCalls(m,r.effectiveTools)],responseMessages:h}),stepResult:m,toolResults:[..._.values()]})}async generate(e,t,n){let{generation:r}=this.input,i=await e.generate({abortSignal:r.signal,messages:t});throwIfTurnAborted(this.step.config.abortSignal),r.check();let a=await n;return assertUsableResponse(a,i.responseMessages,!1),withAccumulatedResponseMessages({responseMessages:appendMissingToolResultMessages({append:answerSkippedToolCalls(a,this.tools.effectiveTools),responseMessages:i.responseMessages}),stepResult:a})}};function assertUsableResponse(e,t,n){if(e.finishReason===`content-filter`)throw new ContentFilteredModelResponseError(readGatewayGenerationId(e.providerMetadata));if(isEmptyModelResponse(e)&&extractToolResultCallIds(t).size===0&&!n)throw new EmptyModelResponseError}export{ModelCaller};
@@ -1,13 +1,12 @@
1
1
  import type { LanguageModel } from "ai";
2
2
  import type { HarnessSession, ToolLoopHarnessConfig } from "#harness/types.js";
3
3
  import { contextStorage } from "#context/container.js";
4
+ import type { ModelProfile } from "#harness/model-profile.js";
4
5
  /**
5
- * Builds AI Gateway app attribution headers when the model is gateway-routed.
6
- *
7
- * Bare model ids and `gateway.*` model instances route through AI Gateway.
8
- * Direct-provider model instances receive no Gateway-specific headers.
6
+ * Builds AI Gateway app attribution headers, including eve's User-Agent product token, for a
7
+ * Gateway-routed model. Direct-provider models receive no Gateway-specific headers.
9
8
  */
10
- export declare function buildGatewayAttributionHeaders(model: LanguageModel, runtimeIdentity: ToolLoopHarnessConfig["runtimeIdentity"]): Record<string, string> | undefined;
9
+ export declare function buildGatewayAttributionHeaders(profile: ModelProfile, runtimeIdentity: ToolLoopHarnessConfig["runtimeIdentity"]): Record<string, string> | undefined;
11
10
  export declare function resolveEffectiveRuntimeModel(input: {
12
11
  readonly config: ToolLoopHarnessConfig;
13
12
  readonly ctx: ReturnType<typeof contextStorage.getStore>;
@@ -1 +1 @@
1
- import"#context/container.js";import{resolveProviderHeaders}from"#internal/gateway.js";import{getEffectiveModelSelection}from"#context/effective-model.js";function buildGatewayAttributionHeaders(e,t){let n=resolveProviderHeaders(e);if(n===void 0)return;let r=t?.agentName??t?.agentId,i=process.env.VERCEL_PROJECT_PRODUCTION_URL||process.env.VERCEL_URL,a=i?`https://${i}`:void 0,o={...n};return r&&(o[`x-title`]=r),a&&(o[`http-referer`]=a),o}async function resolveEffectiveRuntimeModel(e){if(e.ctx===void 0){let t=e.session.agent.modelReference;if(t===void 0)throw Error(`Dynamic model selection is unavailable outside an eve runtime context.`);return{model:await e.config.resolveModel(t),session:e.session}}let t=getEffectiveModelSelection(e.ctx);if(t===null)throw Error(`Dynamic model selection is required before model-dependent work begins. Add a matching resolver handler that returns a concrete model.`);return{model:t.model===void 0?await e.config.resolveModel(t.reference):t.model,session:updateSessionModelReference(e.session,t.reference)}}function updateSessionModelReference(e,t){return e.agent.modelReference===t?e:{...e,agent:{...e.agent,modelReference:t},compaction:updateCompactionThresholdForModelReference({compaction:e.compaction,modelReference:t})}}function updateCompactionThresholdForModelReference(e){return e.modelReference.contextWindowTokens===void 0?e.compaction:{...e.compaction,threshold:Math.max(1,Math.floor(e.modelReference.contextWindowTokens*(e.compaction.thresholdPercent??.9)))}}export{buildGatewayAttributionHeaders,resolveEffectiveRuntimeModel};
1
+ import"#context/container.js";import{appendPackageUserAgent}from"#internal/user-agent.js";import{getEffectiveModelSelection}from"#context/effective-model.js";function buildGatewayAttributionHeaders(e,t){if(!e.gateway)return;let n=t?.agentName??t?.agentId,r=process.env.VERCEL_PROJECT_PRODUCTION_URL||process.env.VERCEL_URL,i=r?`https://${r}`:void 0,a=Object.fromEntries(appendPackageUserAgent(new Headers));return n&&(a[`x-title`]=n),i&&(a[`http-referer`]=i),a}async function resolveEffectiveRuntimeModel(e){if(e.ctx===void 0){let t=e.session.agent.modelReference;if(t===void 0)throw Error(`Dynamic model selection is unavailable outside an eve runtime context.`);return{model:await e.config.resolveModel(t),session:e.session}}let t=getEffectiveModelSelection(e.ctx);if(t===null)throw Error(`Dynamic model selection is required before model-dependent work begins. Add a matching resolver handler that returns a concrete model.`);return{model:t.model===void 0?await e.config.resolveModel(t.reference):t.model,session:updateSessionModelReference(e.session,t.reference)}}function updateSessionModelReference(e,t){return e.agent.modelReference===t?e:{...e,agent:{...e.agent,modelReference:t},compaction:updateCompactionThresholdForModelReference({compaction:e.compaction,modelReference:t})}}function updateCompactionThresholdForModelReference(e){return e.modelReference.contextWindowTokens===void 0?e.compaction:{...e.compaction,threshold:Math.max(1,Math.floor(e.modelReference.contextWindowTokens*(e.compaction.thresholdPercent??.9)))}}export{buildGatewayAttributionHeaders,resolveEffectiveRuntimeModel};
@@ -1,7 +1,6 @@
1
1
  import type { ModelMessage, SystemModelMessage } from "ai";
2
2
  import { createCurrentMessages } from "#harness/current-messages.js";
3
3
  import { type HarnessModelMessage, type UserModelMessage } from "#harness/messages.js";
4
- import { type AnthropicCacheMarker } from "#harness/prompt-cache.js";
5
4
  import type { Step } from "#harness/step/context.js";
6
5
  import type { HarnessSession, HarnessToolMap } from "#harness/types.js";
7
6
  export type RequestMessages = ReturnType<typeof createCurrentMessages>;
@@ -22,7 +21,7 @@ export declare function requestMessages(step: Step, input: {
22
21
  export declare function modelInstructions(input: {
23
22
  readonly session: HarnessSession;
24
23
  readonly systemMessages: readonly SystemModelMessage[];
25
- readonly marker: AnthropicCacheMarker | undefined;
24
+ readonly anthropicCache: boolean;
26
25
  readonly extraSystemNote?: string;
27
26
  }): SystemModelMessage | string | undefined;
28
27
  /** A retry's note, trailing the call's messages. */
@@ -1,3 +1,3 @@
1
- import{HistoryStateKey}from"#context/keys.js";import{createFrameworkUserMessage}from"#harness/messages.js";import{getPendingAnnouncements}from"#harness/announcements.js";import{buildDynamicInstructionMessages}from"#context/dynamic-instruction-lifecycle.js";import{PendingSkillAnnouncementKey}from"#context/dynamic-skill-lifecycle.js";import{taskSystemMessages}from"#execution/tasks/model-step.js";import{applySystemCacheBreakpoint}from"#harness/prompt-cache.js";import{createCurrentMessages}from"#harness/current-messages.js";function requestMessages(e,t){let{ctx:n}=e,r=createCurrentMessages(t.messages,{historyState:n?.get(HistoryStateKey),currentTurnMessages:t.turnMessages,projectedMessages:t.projectedMessages});return n!==void 0&&r.addSystem(buildDynamicInstructionMessages(n)),r.addSystem(taskSystemMessages(t.coordinationTools,{finalReplyOnly:t.hidesHeldText})),r.addAnnouncements({availableSkills:n?.get(PendingSkillAnnouncementKey),keyed:getPendingAnnouncements(n)}),t.pendingApprovalsNote!==void 0&&r.add(t.pendingApprovalsNote,`context.state`,{cacheFriendly:!1}),r}function modelInstructions(e){let{session:t}=e,n=e.extraSystemNote?[{role:`system`,content:e.extraSystemNote}]:[];if(e.systemMessages.length===0&&n.length===0)return t.agent.system??void 0;let r=t.agent.system?[{role:`system`,content:t.agent.system}]:[],i=[...n,...r,...e.systemMessages];return mergeSystemInstructions(e.marker?applySystemCacheBreakpoint(i,e.marker):i)}function withTrailingUserNote(e,t){return t?[...e,createFrameworkUserMessage(`execution.retry`,t)]:[...e]}function mergeSystemInstructions(e){if(e.length===0)return;if(e.length===1)return{...e[0]};let t;for(let n of e)n.providerOptions!==void 0&&(t={...t,...n.providerOptions});let n={role:`system`,content:e.map(e=>e.content).join(`
1
+ import{HistoryStateKey}from"#context/keys.js";import{createFrameworkUserMessage}from"#harness/messages.js";import{getPendingAnnouncements}from"#harness/announcements.js";import{buildDynamicInstructionMessages}from"#context/dynamic-instruction-lifecycle.js";import{PendingSkillAnnouncementKey}from"#context/dynamic-skill-lifecycle.js";import{taskSystemMessages}from"#execution/tasks/model-step.js";import{createCurrentMessages}from"#harness/current-messages.js";import{applySystemCacheBreakpoint}from"#harness/prompt-cache.js";function requestMessages(e,t){let{ctx:n}=e,r=createCurrentMessages(t.messages,{historyState:n?.get(HistoryStateKey),currentTurnMessages:t.turnMessages,projectedMessages:t.projectedMessages});return n!==void 0&&r.addSystem(buildDynamicInstructionMessages(n)),r.addSystem(taskSystemMessages(t.coordinationTools,{finalReplyOnly:t.hidesHeldText})),r.addAnnouncements({availableSkills:n?.get(PendingSkillAnnouncementKey),keyed:getPendingAnnouncements(n)}),t.pendingApprovalsNote!==void 0&&r.add(t.pendingApprovalsNote,`context.state`,{cacheFriendly:!1}),r}function modelInstructions(e){let{session:t}=e,n=e.extraSystemNote?[{role:`system`,content:e.extraSystemNote}]:[];if(e.systemMessages.length===0&&n.length===0)return t.agent.system??void 0;let r=t.agent.system?[{role:`system`,content:t.agent.system}]:[],i=[...n,...r,...e.systemMessages];return mergeSystemInstructions(e.anthropicCache?applySystemCacheBreakpoint(i):i)}function withTrailingUserNote(e,t){return t?[...e,createFrameworkUserMessage(`execution.retry`,t)]:[...e]}function mergeSystemInstructions(e){if(e.length===0)return;if(e.length===1)return{...e[0]};let t;for(let n of e)n.providerOptions!==void 0&&(t={...t,...n.providerOptions});let n={role:`system`,content:e.map(e=>e.content).join(`
2
2
 
3
3
  `)};return t!==void 0&&(n.providerOptions=t),n}export{mergeSystemInstructions,modelInstructions,requestMessages,withTrailingUserNote};
@@ -8,4 +8,4 @@ export declare function runModelCallWithRetries<T>(fn: (attempt: number) => Prom
8
8
  readonly sessionId: string;
9
9
  readonly turnId: string;
10
10
  readonly canRetry?: () => boolean;
11
- }, signal: AbortSignal): Promise<T>;
11
+ }, signal?: AbortSignal): Promise<T>;
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{setTimeout}from"node:timers/promises";import{classifyModelCallError}from"#harness/model-call/errors.js";const log=createLogger(`harness.tool-loop`);async function runModelCallWithRetries(e,t,n){for(let r=1;;r++){n.throwIfAborted();try{return await e(r)}catch(e){if(n.throwIfAborted(),t.canRetry?.()===!1||r===3||classifyModelCallError(e)!==`retry`)throw e;let i=500*2**(r-1)+Math.floor(Math.random()*250);log.warn(`model call failed transiently — retrying`,{attempt:r,delayMs:i,sessionId:t.sessionId,turnId:t.turnId,error:e}),await setTimeout(i,void 0,{signal:n})}}}export{runModelCallWithRetries};
1
+ import{createLogger}from"#internal/logging.js";import{setTimeout}from"node:timers/promises";import{classifyModelCallError}from"#harness/model-call/errors.js";const log=createLogger(`harness.tool-loop`);async function runModelCallWithRetries(e,t,n){for(let r=1;;r++){n?.throwIfAborted();try{return await e(r)}catch(e){if(n?.throwIfAborted(),t.canRetry?.()===!1||r===3||classifyModelCallError(e)!==`retry`)throw e;let i=500*2**(r-1)+Math.floor(Math.random()*250);log.warn(`model call failed transiently — retrying`,{attempt:r,delayMs:i,sessionId:t.sessionId,turnId:t.turnId,error:e}),await setTimeout(i,void 0,{signal:n})}}}export{runModelCallWithRetries};
@@ -1,9 +1,9 @@
1
1
  import type { ToolSet } from "ai";
2
2
  import type { HarnessToolDefinition } from "#harness/execute-tool.js";
3
3
  import type { GenerationSteering } from "#harness/generation-steering.js";
4
- import { type AnthropicCacheMarker } from "#harness/prompt-cache.js";
4
+ import type { ModelProfile } from "#harness/model-profile.js";
5
5
  import type { Step } from "#harness/step/context.js";
6
- import { type HarnessToolMap } from "#harness/types.js";
6
+ import type { HarnessToolMap } from "#harness/types.js";
7
7
  /** The tools one model call offers, and the views of them the step reads afterwards. */
8
8
  export interface ModelTools {
9
9
  /** What the AI SDK receives. */
@@ -23,10 +23,9 @@ export interface ModelTools {
23
23
  */
24
24
  export declare function prepareModelTools(step: Step, input: {
25
25
  readonly approvedTools: ReadonlySet<string>;
26
- readonly model: import("ai").LanguageModel;
27
26
  readonly disabledProviderTools?: ReadonlySet<string>;
28
27
  readonly generation: GenerationSteering;
29
- readonly marker: AnthropicCacheMarker | undefined;
28
+ readonly profile: ModelProfile;
30
29
  }): Promise<ModelTools>;
31
30
  /**
32
31
  * Wired as the agent's `onToolExecutionEnd`. On the `tool-error` branch
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{toModelSchema}from"#tools/schema.js";import{resolveModelProvider}from"#internal/gateway.js";import{buildDynamicSubagentTools}from"#context/dynamic-subagent-lifecycle.js";import{isTurnCancellation}from"#harness/turn-cancellation.js";import{requireSessionModelReference}from"#harness/types.js";import{withTaskTools}from"#execution/tasks/model-step.js";import{buildToolSetFromDefinitions,buildToolSetWithProviderTools}from"#harness/tools.js";import{buildDynamicTools}from"#context/build-dynamic-tools.js";import{FINAL_OUTPUT_TOOL_NAME,buildFinalOutputTool}from"#harness/final-output.js";import{applyLastToolCacheBreakpoint}from"#harness/prompt-cache.js";import{getAdvertisedTools}from"#harness/advertised-tools.js";const log=createLogger(`harness.tool-loop`);async function prepareModelTools(e,t){let{ctx:n}=e,{approvedTools:r,disabledProviderTools:i,marker:a}=t,o=withTaskTools(getAdvertisedTools({session:e.session,tools:buildHarnessToolsWithDynamicSubagents(e.config.tools,n)})),s=await buildToolSetWithProviderTools({approvedTools:r,disabledProviderTools:i,modelProvider:resolveModelProvider(t.model),modelReference:requireSessionModelReference(e.session),tools:o}),c=new Map(o);if(n!==void 0){let t=getAdvertisedTools({session:e.session,tools:buildDynamicTools(n)}),a=buildToolSetFromDefinitions({approvedTools:r,disabledProviderTools:i,tools:t});for(let[e,t]of Object.entries(a)){if(o.get(e)?.workflowId!==void 0)throw Error(`Dynamic tool "${e}" collides with a coordination-visible deferred tool.`);s[e]=t}let l=new Set;for(let e of t)l.has(e.name)||(l.add(e.name),c.set(e.name,e))}e.session.outputSchema!==void 0&&(s[FINAL_OUTPUT_TOOL_NAME]=buildFinalOutputTool(e.session.outputSchema));let l=await getAdvertisedTools({modelTools:s,session:e.session,tools:o});e.session=l.session;let{modelTools:u}=l,d=new Map;if(!e.hasDelegatedCaller&&e.session.outputSchema===void 0)for(let[e,t]of Object.entries(u)){let n=c.get(e)?.endsTurn;t.type!==`provider`&&n!==void 0&&n!==!1&&(d.set(e,n),n===!0&&(t.description=`${t.description??``}\n\n${ENDS_TURN_TOOL_NOTE}`.trimStart()))}let f=a?applyLastToolCacheBreakpoint(u,a):u;for(let e of Object.values(f)){e.inputSchema=toModelSchema(e.inputSchema,`input`),e.outputSchema!==void 0&&(e.outputSchema=toModelSchema(e.outputSchema,`output`));let n=e.execute;n!==void 0&&(e.execute=(...e)=>(t.generation.protectToolExecution(),n(...e)))}return e.frameworkToolNames=new Set([...c].filter(([,e])=>e.frameworkTool===!0).map(([e])=>e)),{coordinationTools:o,effectiveTools:f,endsTurnTools:d,modelTools:u,presentationTools:c}}function logToolExecutionError(e){e.toolOutput.type!==`tool-error`||isTurnCancellation(e.toolOutput.error)||logError(log,`tool execution failed`,e.toolOutput.error,{toolName:e.toolCall.toolName,toolCallId:e.toolCall.toolCallId})}function buildHarnessToolsWithDynamicSubagents(e,t){let n=new Map(e);if(t===void 0)return n;for(let e of buildDynamicSubagentTools(t)){if(n.has(e.name))throw Error(`Dynamic subagent "${e.name}" collides with another runtime-visible tool name.`);n.set(e.name,e)}return n}const ENDS_TURN_TOOL_NOTE=`Calling this tool ends your turn once it succeeds: do not write a reply or call other tools in the same step. If it fails, you will see the error and can continue.`;export{ENDS_TURN_TOOL_NOTE,logToolExecutionError,prepareModelTools};
1
+ import{createLogger,logError}from"#internal/logging.js";import{toModelSchema}from"#tools/schema.js";import{buildDynamicSubagentTools}from"#context/dynamic-subagent-lifecycle.js";import{isTurnCancellation}from"#harness/turn-cancellation.js";import{withTaskTools}from"#execution/tasks/model-step.js";import{buildToolSetFromDefinitions,buildToolSetWithProviderTools}from"#harness/tools.js";import{buildDynamicTools}from"#context/build-dynamic-tools.js";import{FINAL_OUTPUT_TOOL_NAME,buildFinalOutputTool}from"#harness/final-output.js";import{applyLastToolCacheBreakpoint}from"#harness/prompt-cache.js";import{getAdvertisedTools}from"#harness/advertised-tools.js";const log=createLogger(`harness.tool-loop`);async function prepareModelTools(e,t){let{ctx:n}=e,{approvedTools:r,disabledProviderTools:i,profile:a}=t,o=withTaskTools(getAdvertisedTools({session:e.session,tools:buildHarnessToolsWithDynamicSubagents(e.config.tools,n)})),s=await buildToolSetWithProviderTools({approvedTools:r,disabledProviderTools:i,profile:a,tools:o}),c=new Map(o);if(n!==void 0){let t=getAdvertisedTools({session:e.session,tools:buildDynamicTools(n)}),a=buildToolSetFromDefinitions({approvedTools:r,disabledProviderTools:i,tools:t});for(let[e,t]of Object.entries(a)){if(o.get(e)?.workflowId!==void 0)throw Error(`Dynamic tool "${e}" collides with a coordination-visible deferred tool.`);s[e]=t}let l=new Set;for(let e of t)l.has(e.name)||(l.add(e.name),c.set(e.name,e))}e.session.outputSchema!==void 0&&(s[FINAL_OUTPUT_TOOL_NAME]=buildFinalOutputTool(e.session.outputSchema));let l=await getAdvertisedTools({modelTools:s,session:e.session,tools:o});e.session=l.session;let{modelTools:u}=l,d=new Map;if(!e.hasDelegatedCaller&&e.session.outputSchema===void 0)for(let[e,t]of Object.entries(u)){let n=c.get(e)?.endsTurn;t.type!==`provider`&&n!==void 0&&n!==!1&&(d.set(e,n),n===!0&&(t.description=`${t.description??``}\n\n${ENDS_TURN_TOOL_NOTE}`.trimStart()))}let f=a.anthropicCache?applyLastToolCacheBreakpoint(u):u;for(let e of Object.values(f)){e.inputSchema=toModelSchema(e.inputSchema,`input`),e.outputSchema!==void 0&&(e.outputSchema=toModelSchema(e.outputSchema,`output`));let n=e.execute;n!==void 0&&(e.execute=(...e)=>(t.generation.protectToolExecution(),n(...e)))}return e.frameworkToolNames=new Set([...c].filter(([,e])=>e.frameworkTool===!0).map(([e])=>e)),{coordinationTools:o,effectiveTools:f,endsTurnTools:d,modelTools:u,presentationTools:c}}function logToolExecutionError(e){e.toolOutput.type!==`tool-error`||isTurnCancellation(e.toolOutput.error)||logError(log,`tool execution failed`,e.toolOutput.error,{toolName:e.toolCall.toolName,toolCallId:e.toolCall.toolCallId})}function buildHarnessToolsWithDynamicSubagents(e,t){let n=new Map(e);if(t===void 0)return n;for(let e of buildDynamicSubagentTools(t)){if(n.has(e.name))throw Error(`Dynamic subagent "${e.name}" collides with another runtime-visible tool name.`);n.set(e.name,e)}return n}const ENDS_TURN_TOOL_NOTE=`Calling this tool ends your turn once it succeeds: do not write a reply or call other tools in the same step. If it fails, you will see the error and can continue.`;export{ENDS_TURN_TOOL_NOTE,logToolExecutionError,prepareModelTools};
@@ -1 +1 @@
1
- import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{accumulateTurnUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{setEveAttributes}from"#runtime/attributes/emit.js";function gatewayModelId(e){try{return formatLanguageModelGatewayId(e)}catch{return}}function extractTokenUsageDelta(e){let t=e.usage;if(t!==void 0||e.costUsd!==void 0)return{cacheReadTokens:t?.inputTokenDetails?.cacheReadTokens,cacheWriteTokens:t?.inputTokenDetails?.cacheWriteTokens,costUsd:e.costUsd,inputTokens:t?.inputTokens,outputTokens:t?.outputTokens}}function extractGatewayCostUsd(e){let t=readGatewayMetadata(e)?.cost;if(typeof t==`number`&&Number.isFinite(t))return t;if(typeof t==`string`){let e=Number(t);return Number.isFinite(e)?e:void 0}}function readGatewayMetadata(e){let t=e?.gateway;return t&&typeof t==`object`&&!Array.isArray(t)?t:void 0}async function recordModelUsage(e,t){let n=accumulateTurnUsage({previous:getTurnUsageState(e.session.state),turnId:e.position().turnId,usage:extractTokenUsageDelta({costUsd:extractGatewayCostUsd(t.result.providerMetadata),usage:t.result.usage})});e.session=setTurnUsageState(e.session,n);let r={"$eve.model":gatewayModelId(t.model),"$eve.input_tokens":n.inputTokens,"$eve.output_tokens":n.outputTokens,"$eve.cache_read_tokens":n.cacheReadTokens,"$eve.cache_write_tokens":n.cacheWriteTokens,"$eve.cost_usd":n.sawCost?n.costUsd:void 0,"$eve.tool_count":e.config.tools.size};await e.config.titleAttributeWrite,await setEveAttributes(r)}export{extractGatewayCostUsd,extractTokenUsageDelta,gatewayModelId,recordModelUsage};
1
+ import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{addTurnUsage,getTurnUsageState}from"#harness/turn-tag-state.js";import{setEveAttributes}from"#runtime/attributes/emit.js";function gatewayModelId(e){try{return formatLanguageModelGatewayId(e)}catch{return}}function extractTokenUsageDelta(e){let t=e.usage;if(t!==void 0||e.costUsd!==void 0)return{cacheReadTokens:t?.inputTokenDetails?.cacheReadTokens,cacheWriteTokens:t?.inputTokenDetails?.cacheWriteTokens,costUsd:e.costUsd,inputTokens:t?.inputTokens,outputTokens:t?.outputTokens}}function extractGatewayCostUsd(e){let t=readGatewayMetadata(e)?.cost;if(typeof t==`number`&&Number.isFinite(t))return t;if(typeof t==`string`){let e=Number(t);return Number.isFinite(e)?e:void 0}}function readGatewayMetadata(e){let t=e?.gateway;return t&&typeof t==`object`&&!Array.isArray(t)?t:void 0}async function recordModelUsage(e,t){e.session=addTurnUsage(e.session,e.position().turnId,extractTokenUsageDelta({costUsd:extractGatewayCostUsd(t.result.providerMetadata),usage:t.result.usage}));let n=getTurnUsageState(e.session.state),r={"$eve.model":gatewayModelId(t.model),"$eve.input_tokens":n?.inputTokens,"$eve.output_tokens":n?.outputTokens,"$eve.cache_read_tokens":n?.cacheReadTokens,"$eve.cache_write_tokens":n?.cacheWriteTokens,"$eve.cost_usd":n?.sawCost?n.costUsd:void 0,"$eve.tool_count":e.config.tools.size};await e.config.titleAttributeWrite,await setEveAttributes(r)}export{extractGatewayCostUsd,extractTokenUsageDelta,gatewayModelId,recordModelUsage};
@@ -0,0 +1,23 @@
1
+ import type { LanguageModel } from "ai";
2
+ /**
3
+ * What eve assumes about the model serving one call. Every decision that shapes a request for
4
+ * its provider reads this record, so a step and its compaction agree about the model.
5
+ */
6
+ export interface ModelProfile {
7
+ /** Routed through AI Gateway, which caches automatically and serves Gateway tools. */
8
+ readonly gateway: boolean;
9
+ /**
10
+ * Who serves the request: a Gateway id's vendor (`openai/gpt-5` → `openai`), which Gateway
11
+ * translates for whichever host it routes to, otherwise the SDK provider's top-level name
12
+ * (`anthropic`, `amazon-bedrock`, `vertex`, `azure`). It names the host, not the model family:
13
+ * hosts of the same family accept different things (Bedrock and Vertex reject Anthropic's web
14
+ * search tool), so a capability a host shares with its family gets its own flag, like
15
+ * `anthropicCache`.
16
+ */
17
+ readonly provider: string;
18
+ /** Takes Anthropic prompt-cache breakpoints. */
19
+ readonly anthropicCache: boolean;
20
+ /** Chat Completions APIs can't carry files in tool results, so they move to user messages. */
21
+ readonly filesOutsideToolResults: boolean;
22
+ }
23
+ export declare function resolveModelProfile(model: LanguageModel): ModelProfile;
@@ -0,0 +1 @@
1
+ function resolveModelProfile(e){let t=typeof e==`string`?`gateway`:lowerCaseOrEmpty(e.provider),n=typeof e==`string`?e:lowerCaseOrEmpty(e.modelId),r=t.split(`.`)[0];return r===`gateway`?{anthropicCache:!1,filesOutsideToolResults:!1,gateway:!0,provider:n.split(`/`)[0]}:{anthropicCache:t.includes(`anthropic`)||t.includes(`bedrock`)&&n.includes(`anthropic`),filesOutsideToolResults:t.endsWith(`.chat`),gateway:!1,provider:r}}function lowerCaseOrEmpty(e){return typeof e==`string`?e.toLowerCase():``}export{resolveModelProfile};