eve 0.83.2 → 0.83.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/src/chunks/{use-eve-agent-ZY7NQ2VW.js → use-eve-agent-BE2_zd5q.js} +17 -12
- package/dist/src/chunks/{use-eve-agent-DnbG9c7c.js → use-eve-agent-e8a5vcFO.js} +17 -12
- package/dist/src/client/optimistic-message-submissions.d.ts +2 -3
- package/dist/src/client/optimistic-message-submissions.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/execution/cancelled-model-call-batch.js +1 -1
- package/dist/src/execution/catalog/connection-auth.js +1 -1
- package/dist/src/execution/catalog/rank.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/legacy-session/prepare-step.js +1 -1
- package/dist/src/execution/session/handoff-steps.d.ts +1 -0
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/session/handoff.d.ts +1 -0
- package/dist/src/execution/session/handoff.js +1 -1
- package/dist/src/execution/session/program.js +1 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/web-fetch/html.js +3 -4
- package/dist/src/harness/compaction/engine.js +2 -2
- package/dist/src/harness/compaction/over-limit-error.d.ts +7 -0
- package/dist/src/harness/compaction/over-limit-error.js +1 -0
- package/dist/src/harness/compaction/prompt.js +1 -1
- package/dist/src/harness/compaction/step.d.ts +9 -0
- package/dist/src/harness/compaction/step.js +1 -1
- package/dist/src/harness/emission.d.ts +8 -3
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/model-call/call.d.ts +6 -2
- package/dist/src/harness/model-call/call.js +1 -1
- package/dist/src/harness/model-call/failure.d.ts +7 -0
- package/dist/src/harness/model-call/failure.js +1 -1
- package/dist/src/harness/model-call/run.js +1 -1
- package/dist/src/harness/model-call/usage.js +1 -1
- package/dist/src/harness/session-machine/current.d.ts +8 -0
- package/dist/src/harness/session-machine/current.js +1 -1
- package/dist/src/internal/application/stamped-package-version.js +1 -1
- package/dist/src/internal/authored-asset-import-plugin.d.ts +8 -7
- package/dist/src/internal/authored-asset-import-plugin.js +1 -1
- package/dist/src/internal/nitro/dev-client-address.d.ts +12 -0
- package/dist/src/internal/nitro/dev-client-address.js +1 -1
- package/dist/src/internal/nitro/routes/channel-request-instrumentation.d.ts +6 -3
- package/dist/src/internal/nitro/routes/channel-request-instrumentation.js +1 -1
- package/dist/src/public/channels/auth.d.ts +14 -0
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +6 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +1 -1
- package/dist/src/public/channels/slack/reply-delivery.d.ts +1 -7
- package/dist/src/public/channels/slack/reply-delivery.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +2 -6
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/undelivered-reply.d.ts +30 -0
- package/dist/src/public/channels/undelivered-reply.js +1 -0
- package/dist/src/runtime/connections/mcp-client.d.ts +5 -2
- package/dist/src/runtime/connections/mcp-client.js +1 -1
- package/dist/src/runtime/connections/openapi-client.js +1 -1
- package/dist/src/runtime/connections/openapi-operations.d.ts +4 -0
- package/dist/src/runtime/connections/openapi-operations.js +1 -1
- package/dist/src/runtime/connections/openapi-schema.d.ts +19 -14
- package/dist/src/runtime/connections/openapi-schema.js +1 -1
- package/dist/src/runtime/local-dev-capability.d.ts +2 -2
- package/dist/src/runtime/local-dev-capability.js +1 -1
- package/dist/src/runtime/subagents/workflow.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/shared/connection-types.d.ts +5 -0
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/tools/schema.d.ts +2 -0
- package/dist/src/tools/schema.js +1 -1
- package/dist/src/tools/signature.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/chat-sdk.mdx +1 -1
- package/docs/channels/slack.mdx +1 -1
- package/docs/concepts/default-harness.md +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/connections/openapi.mdx +1 -1
- package/docs/guides/auth-and-route-protection.md +4 -0
- package/docs/reference/cli.md +3 -1
- package/docs/reference/typescript-api.md +3 -1
- package/docs/tools/tasks.md +2 -2
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# eve
|
|
2
2
|
|
|
3
|
+
## 0.83.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3e96a14: An optimistic message no longer stays in the `submitted` state when its turn is cancelled or fails before the agent reads it. `EveAgentStore` now marks that message `failed`, so it keeps its own text, and later messages reconcile against their own submissions. A steered message the cancelled turn never read now also lets its `send()` settle. Thanks @brettcrane for reporting this in #3102.
|
|
8
|
+
- 8077f2d: With `otel({ traceChannelRequests: true })`, the `agent.channel.request` span now ends when the response body finishes, fails, or is cancelled, not when the route handler returns. Session stream requests no longer log `You can only call end() on a span once.` for `workflow.stream.read.connect`, and request spans now cover the full streaming time. Thanks @ahcarpenter for reporting this and proposing the fix in #4256.
|
|
9
|
+
- 54adf15: `chatSdkChannel` now reports failed final reply delivery with an error-id notice and a note to the model, avoids reposting streamed replies, and skips unchanged final edits after state restoration. Thanks @diegojohnsonl for reporting this in #4801.
|
|
10
|
+
- 4280d51: A hook that cancels the turn at `compaction.completed` no longer drops the compaction's summary call from the session's usage. `session.waiting` and session limits now count it.
|
|
11
|
+
- 181caed: Compaction no longer re-runs on every step when the current user message is most of the context window. After a compaction, eve keeps at most 20,000 tokens of the latest conversation word for word next to the summary, with tool results shortened to 2,000 characters; a current message larger than that keeps its start and end, and the cut-out middle is summarized. A compaction that cannot bring the history under the threshold now fails the session, without retrying the step, with an error that says to start a new session or send a smaller message.
|
|
12
|
+
- cea4eb0: Declare `next` as an optional peer dependency, so `eve/next` types resolve the app's own `next` in pnpm workspaces that install more than one `next` version. Thanks @laugharn for reporting this in #5341.
|
|
13
|
+
- 80db4b3: A session started before eve 0.57 now imports on its next message instead of failing with `IncompatibleStateLayoutError` for `eve.mode`. The import drops the framework context keys that those builds saved and the current build no longer defines. Thanks @sunlanchang for reporting this in #5213.
|
|
14
|
+
- 200d2d8: `localDev()` now refuses requests that a browser sends for another website: a non-loopback request host or `Origin`. A web page open in the developer's browser can no longer start sessions or run the agent's tools on an `eve dev` server, including through DNS rebinding. Frontends served from any loopback host and port still authenticate.
|
|
15
|
+
- 243a4a4: `localDev()` now refuses callers on other machines. Before, an `eve dev` server started with `--host 0.0.0.0` gave every LAN caller the `local-dev` principal, so they could run the agent and its local editing tools, which write to the project's `agent/` source. Callers on the same machine are unchanged, including the developer's own clients when `--host` names a LAN address.
|
|
16
|
+
- da515dc: OpenAPI `operations.allow` and `operations.block` now match an operation's `operationId` as written in the spec, as well as its generated tool name. Before, an `operationId` with characters such as `.` or `/` never matched, because eve compared the filter only against the sanitized tool name, so a blocked operation stayed callable.
|
|
17
|
+
- 9a55d23: OpenAPI connection tools no longer reject valid deeply nested input, such as a Notion page title. eve now keeps the spec's referenced schemas under `$defs` instead of copying them inline up to a depth limit, so validation applies at every depth and shared schemas no longer grow exponentially. Thanks @lildesert for reporting this with a minimal reproduction in #3267.
|
|
18
|
+
- b8b36a8: Preserve the original session output stream’s public encryption metadata during deployment handoffs, avoiding repeated run metadata and encryption-key lookups before later turns.
|
|
19
|
+
- 7cf27bb: Text a root session's model writes before `eve__task_wait` in the same step now posts as a reply. Before, Slack showed it only as the thread status, and Telegram, Teams, and other channels dropped it.
|
|
20
|
+
- f3e3140: Fixed a denial-of-service issue in `webFetch` with `format: "text"`: HTML text extraction now runs in linear time, so malformed pages, such as ones with unclosed `<script>` tags or stray `<` characters, can no longer block the event loop. Content after an unclosed `<script>`, `<style>`, `<noscript>`, or `<!--` is now dropped, as browsers do. Thanks @not2face for the report.
|
|
21
|
+
- de1b9aa: Workspace packages bundled from TypeScript source can now import their own files with `?raw` and other relative asset imports. Before, `eve build` failed with "resolves outside package root" when an agent imported such a package. `?raw` now also works for `.json` files and files without an extension, such as a `Dockerfile`.
|
|
22
|
+
|
|
3
23
|
## 0.83.2
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -3019,16 +3019,12 @@ var OptimisticMessageSubmissions = class {
|
|
|
3019
3019
|
return this.submit(input, pending?.eventStartIndex ?? 0, pending?.turnId);
|
|
3020
3020
|
}
|
|
3021
3021
|
apply(event) {
|
|
3022
|
-
|
|
3022
|
+
const settling = this.#settling(event);
|
|
3023
|
+
if (settling.length === 0) {
|
|
3023
3024
|
for (const projection of this.#projections) projection.append(event);
|
|
3024
3025
|
return;
|
|
3025
3026
|
}
|
|
3026
|
-
|
|
3027
|
-
if (matching.length === 0) {
|
|
3028
|
-
for (const projection of this.#projections) projection.append(event);
|
|
3029
|
-
return;
|
|
3030
|
-
}
|
|
3031
|
-
return this.#reconcile(matching, event, false);
|
|
3027
|
+
return this.#settle(settling, event, false);
|
|
3032
3028
|
}
|
|
3033
3029
|
correlate(submissionId, deliveryId, events) {
|
|
3034
3030
|
if (submissionId === void 0) return void 0;
|
|
@@ -3040,9 +3036,8 @@ var OptimisticMessageSubmissions = class {
|
|
|
3040
3036
|
const pending = this.#pending.find((candidate) => candidate.id === submissionId);
|
|
3041
3037
|
if (pending === void 0) return void 0;
|
|
3042
3038
|
for (const event of events.slice(pending.eventStartIndex)) {
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
if (matching.some((candidate) => candidate.id === submissionId)) return this.#reconcile(matching, event, true);
|
|
3039
|
+
const settling = this.#settling(event);
|
|
3040
|
+
if (settling.some((candidate) => candidate.id === submissionId)) return this.#settle(settling, event, true);
|
|
3046
3041
|
}
|
|
3047
3042
|
}
|
|
3048
3043
|
fail(error, submissionId) {
|
|
@@ -3063,12 +3058,22 @@ var OptimisticMessageSubmissions = class {
|
|
|
3063
3058
|
failAll(error) {
|
|
3064
3059
|
for (const pending of this.#pending) this.fail(error, pending.id);
|
|
3065
3060
|
}
|
|
3061
|
+
#settling(event) {
|
|
3062
|
+
if (event.type === "message.received") return this.#matching(event);
|
|
3063
|
+
if (event.type !== "turn.cancelled" && event.type !== "turn.failed") return [];
|
|
3064
|
+
const named = event.meta.deliveryIds ?? [];
|
|
3065
|
+
return this.#pending.filter((pending) => pending.deliveryId !== void 0 && named.includes(pending.deliveryId));
|
|
3066
|
+
}
|
|
3066
3067
|
#matching(event) {
|
|
3067
3068
|
return this.#pending.filter((pending) => pending.deliveryId === void 0 ? !pending.requiresDeliveryId : event.meta.deliveryIds?.includes(pending.deliveryId) === true);
|
|
3068
3069
|
}
|
|
3069
|
-
#
|
|
3070
|
+
#settle(submissions, event, alreadyProjected) {
|
|
3070
3071
|
const ids = submissions.map((pending) => pending.id);
|
|
3071
|
-
this.#withdraw(ids);
|
|
3072
|
+
if (event.type === "message.received") this.#withdraw(ids);
|
|
3073
|
+
else {
|
|
3074
|
+
const error = /* @__PURE__ */ new Error("The turn ended before the agent read the message.");
|
|
3075
|
+
for (const id of ids) this.fail(error, id);
|
|
3076
|
+
}
|
|
3072
3077
|
if (!alreadyProjected) for (const projection of this.#projections) projection.append(event);
|
|
3073
3078
|
return {
|
|
3074
3079
|
alreadyProjected,
|
|
@@ -3018,16 +3018,12 @@ var OptimisticMessageSubmissions = class {
|
|
|
3018
3018
|
return this.submit(input, pending?.eventStartIndex ?? 0, pending?.turnId);
|
|
3019
3019
|
}
|
|
3020
3020
|
apply(event) {
|
|
3021
|
-
|
|
3021
|
+
const settling = this.#settling(event);
|
|
3022
|
+
if (settling.length === 0) {
|
|
3022
3023
|
for (const projection of this.#projections) projection.append(event);
|
|
3023
3024
|
return;
|
|
3024
3025
|
}
|
|
3025
|
-
|
|
3026
|
-
if (matching.length === 0) {
|
|
3027
|
-
for (const projection of this.#projections) projection.append(event);
|
|
3028
|
-
return;
|
|
3029
|
-
}
|
|
3030
|
-
return this.#reconcile(matching, event, false);
|
|
3026
|
+
return this.#settle(settling, event, false);
|
|
3031
3027
|
}
|
|
3032
3028
|
correlate(submissionId, deliveryId, events) {
|
|
3033
3029
|
if (submissionId === void 0) return void 0;
|
|
@@ -3039,9 +3035,8 @@ var OptimisticMessageSubmissions = class {
|
|
|
3039
3035
|
const pending = this.#pending.find((candidate) => candidate.id === submissionId);
|
|
3040
3036
|
if (pending === void 0) return void 0;
|
|
3041
3037
|
for (const event of events.slice(pending.eventStartIndex)) {
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
if (matching.some((candidate) => candidate.id === submissionId)) return this.#reconcile(matching, event, true);
|
|
3038
|
+
const settling = this.#settling(event);
|
|
3039
|
+
if (settling.some((candidate) => candidate.id === submissionId)) return this.#settle(settling, event, true);
|
|
3045
3040
|
}
|
|
3046
3041
|
}
|
|
3047
3042
|
fail(error, submissionId) {
|
|
@@ -3062,12 +3057,22 @@ var OptimisticMessageSubmissions = class {
|
|
|
3062
3057
|
failAll(error) {
|
|
3063
3058
|
for (const pending of this.#pending) this.fail(error, pending.id);
|
|
3064
3059
|
}
|
|
3060
|
+
#settling(event) {
|
|
3061
|
+
if (event.type === "message.received") return this.#matching(event);
|
|
3062
|
+
if (event.type !== "turn.cancelled" && event.type !== "turn.failed") return [];
|
|
3063
|
+
const named = event.meta.deliveryIds ?? [];
|
|
3064
|
+
return this.#pending.filter((pending) => pending.deliveryId !== void 0 && named.includes(pending.deliveryId));
|
|
3065
|
+
}
|
|
3065
3066
|
#matching(event) {
|
|
3066
3067
|
return this.#pending.filter((pending) => pending.deliveryId === void 0 ? !pending.requiresDeliveryId : event.meta.deliveryIds?.includes(pending.deliveryId) === true);
|
|
3067
3068
|
}
|
|
3068
|
-
#
|
|
3069
|
+
#settle(submissions, event, alreadyProjected) {
|
|
3069
3070
|
const ids = submissions.map((pending) => pending.id);
|
|
3070
|
-
this.#withdraw(ids);
|
|
3071
|
+
if (event.type === "message.received") this.#withdraw(ids);
|
|
3072
|
+
else {
|
|
3073
|
+
const error = /* @__PURE__ */ new Error("The turn ended before the agent read the message.");
|
|
3074
|
+
for (const id of ids) this.fail(error, id);
|
|
3075
|
+
}
|
|
3071
3076
|
if (!alreadyProjected) for (const projection of this.#projections) projection.append(event);
|
|
3072
3077
|
return {
|
|
3073
3078
|
alreadyProjected,
|
|
@@ -3,9 +3,8 @@ import type { MessageStreamEvent } from "#protocol/message.js";
|
|
|
3
3
|
import type { SendTurnPayload } from "#client/types.js";
|
|
4
4
|
interface ReconciledSubmissions {
|
|
5
5
|
readonly alreadyProjected: boolean;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}>;
|
|
6
|
+
/** The event that settled the submissions: their `message.received`, or their turn's end. */
|
|
7
|
+
readonly event: MessageStreamEvent;
|
|
9
8
|
readonly ids: readonly string[];
|
|
10
9
|
}
|
|
11
10
|
/** Owns optimistic message projection and server-delivery reconciliation. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createSubmissionId,summarizeUserContent}from"#client/eve-agent-store-helpers.js";var OptimisticMessageSubmissions=class{#e;#t;#n=[];constructor(e,t){this.#t=e,this.#e=t}reset(){this.#n=[]}submit(e,t,n){if(e.message===void 0)return;let r={createdAt:Date.now(),eventStartIndex:t,id:createSubmissionId(),message:summarizeUserContent(e.message),turnId:n,requiresDeliveryId:!0};if(this.#n=[...this.#n,r],this.#e)for(let e of this.#t)e.append({data:{createdAt:r.createdAt,message:r.message,submissionId:r.id,turnId:n},type:`client.message.submitted`});return r.id}resubmit(e,t){let n=this.#n.find(t=>t.id===e),r=t.message===void 0?void 0:summarizeUserContent(t.message);return n?.message===r?e:(n!==void 0&&this.#
|
|
1
|
+
import{createSubmissionId,summarizeUserContent}from"#client/eve-agent-store-helpers.js";var OptimisticMessageSubmissions=class{#e;#t;#n=[];constructor(e,t){this.#t=e,this.#e=t}reset(){this.#n=[]}submit(e,t,n){if(e.message===void 0)return;let r={createdAt:Date.now(),eventStartIndex:t,id:createSubmissionId(),message:summarizeUserContent(e.message),turnId:n,requiresDeliveryId:!0};if(this.#n=[...this.#n,r],this.#e)for(let e of this.#t)e.append({data:{createdAt:r.createdAt,message:r.message,submissionId:r.id,turnId:n},type:`client.message.submitted`});return r.id}resubmit(e,t){let n=this.#n.find(t=>t.id===e),r=t.message===void 0?void 0:summarizeUserContent(t.message);return n?.message===r?e:(n!==void 0&&this.#o([n.id]),this.submit(t,n?.eventStartIndex??0,n?.turnId))}apply(e){let t=this.#r(e);if(t.length===0){for(let t of this.#t)t.append(e);return}return this.#a(t,e,!1)}correlate(e,t,n){if(e===void 0)return;this.#n=this.#n.map(n=>n.id===e?{...n,deliveryId:t,requiresDeliveryId:t!==void 0}:n);let r=this.#n.find(t=>t.id===e);if(r!==void 0)for(let t of n.slice(r.eventStartIndex)){let n=this.#r(t);if(n.some(t=>t.id===e))return this.#a(n,t,!0)}}fail(e,t){let n=t===void 0?this.#n[0]:this.#n.find(e=>e.id===t);if(n!==void 0){this.#n=this.#n.filter(e=>e.id!==n.id);for(let t of this.#t)t.replace(e=>e.type===`client.message.submitted`&&e.data.submissionId===n.id,{data:{createdAt:n.createdAt,error:{message:e.message},message:n.message,submissionId:n.id,turnId:n.turnId},type:`client.message.failed`})}}failAll(e){for(let t of this.#n)this.fail(e,t.id)}#r(e){if(e.type===`message.received`)return this.#i(e);if(e.type!==`turn.cancelled`&&e.type!==`turn.failed`)return[];let t=e.meta.deliveryIds??[];return this.#n.filter(e=>e.deliveryId!==void 0&&t.includes(e.deliveryId))}#i(e){return this.#n.filter(t=>t.deliveryId===void 0?!t.requiresDeliveryId:e.meta.deliveryIds?.includes(t.deliveryId)===!0)}#a(e,t,n){let r=e.map(e=>e.id);if(t.type===`message.received`)this.#o(r);else{let e=Error(`The turn ended before the agent read the message.`);for(let t of r)this.fail(e,t)}if(!n)for(let e of this.#t)e.append(t);return{alreadyProjected:n,event:t,ids:r}}#o(e){let t=new Set(e);this.#n=this.#n.filter(e=>!t.has(e.id));for(let e of this.#t)e.remove(e=>e.type===`client.message.submitted`&&t.has(e.data.submissionId))}};export{OptimisticMessageSubmissions};
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"zod": "4.5.4",
|
|
62
62
|
"zod-validation-error": "5.0.0"
|
|
63
63
|
},
|
|
64
|
-
"scriptHash": "
|
|
64
|
+
"scriptHash": "ca0d1cac1d58bfe2accdeb13ad8bc14b51bd709a890983fbd3c4e53ed7309faf",
|
|
65
65
|
"toolVersions": {
|
|
66
66
|
"rolldown": "1.2.9",
|
|
67
67
|
"typescript": "7.0.2"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{appliedSession,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,OfferedCatalogToolsKey,SandboxKey,TurnDeliveryIdsKey}from"#context/keys.js";import{createDurableSessionValues}from"#execution/durable-session-store.js";import{preserveSerializedSessionDynamicModelSelection}from"#context/serialized-dynamic-model-selection.js";import{withContextScope}from"#context/run-step.js";import{serializeContext}from"#context/serialize.js";import{preserveCancelledTurnMessage}from"#execution/cancelled-turn-message.js";import{takeDeferredMessage}from"#harness/hitl/index.js";import{preserveSerializedInstrumentationState}from"#instrumentation/state.js";import{preserveSerializedAgentTraceState}from"#tracing/eve/agent-trace-context-store.js";const log=createLogger(`execution.cancelled-turn`);async function cancelledWithoutCheckpoint(e,t,n){let r=appliedSession(e),i=r??t,a=n;if(r!==void 0){let e=takeDeferredMessage(r);i=e.session,e.message!==void 0&&(a={...n,message:e.message})}if(e.get(SandboxKey)===void 0&&hasFileParts(a?.message))try{return(await withContextScope(e,i,async e=>({result:void 0,session:await preserveCancelledTurnMessage(e,a)}))).session}catch(t){log.warn(`staging a cancelled turn's attachments failed`,{error:t}),e.clearVirtualContext()}return await contextStorage.run(e,()=>preserveCancelledTurnMessage(i,a))}function hasFileParts(e){return Array.isArray(e)&&e.some(e=>e.type===`file`)}async function createCancelledModelCallBatchResult(e){let t=serializeContext(e.ctx),n=e.checkpoint
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{appliedSession,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,OfferedCatalogToolsKey,SandboxKey,TurnDeliveryIdsKey}from"#context/keys.js";import{getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{createDurableSessionValues}from"#execution/durable-session-store.js";import{preserveSerializedSessionDynamicModelSelection}from"#context/serialized-dynamic-model-selection.js";import{withContextScope}from"#context/run-step.js";import{serializeContext}from"#context/serialize.js";import{preserveCancelledTurnMessage}from"#execution/cancelled-turn-message.js";import{takeDeferredMessage}from"#harness/hitl/index.js";import{preserveSerializedInstrumentationState}from"#instrumentation/state.js";import{preserveSerializedAgentTraceState}from"#tracing/eve/agent-trace-context-store.js";const log=createLogger(`execution.cancelled-turn`);async function cancelledWithoutCheckpoint(e,t,n){let r=appliedSession(e),i=r??t,a=n;if(r!==void 0){let e=takeDeferredMessage(r);i=e.session,e.message!==void 0&&(a={...n,message:e.message})}if(e.get(SandboxKey)===void 0&&hasFileParts(a?.message))try{return(await withContextScope(e,i,async e=>({result:void 0,session:await preserveCancelledTurnMessage(e,a)}))).session}catch(t){log.warn(`staging a cancelled turn's attachments failed`,{error:t}),e.clearVirtualContext()}return await contextStorage.run(e,()=>preserveCancelledTurnMessage(i,a))}function hasFileParts(e){return Array.isArray(e)&&e.some(e=>e.type===`file`)}function keepAppliedTurnUsage(e,t){let n=getTurnUsageState(t?.state);return n===void 0?e:setTurnUsageState(e,n)}async function createCancelledModelCallBatchResult(e){let t=serializeContext(e.ctx),n=e.checkpoint===void 0?await cancelledWithoutCheckpoint(e.ctx,e.initialSession,e.stepInput):keepAppliedTurnUsage(e.checkpoint.result.session,appliedSession(e.ctx)),r={...e.checkpoint?.serializedContext??e.beforeBatchContext,[AuthKey.name]:t[AuthKey.name],[OfferedCatalogToolsKey.name]:t[OfferedCatalogToolsKey.name],[TurnDeliveryIdsKey.name]:t[TurnDeliveryIdsKey.name]};return{action:`cancelled`,serializedContext:preserveSerializedInstrumentationState(preserveSerializedAgentTraceState(preserveSerializedSessionDynamicModelSelection(r,t),t),t),...createDurableSessionValues(saveSessionProjection(n,e.ctx))}}export{createCancelledModelCallBatchResult};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{toErrorMessage}from"#shared/errors.js";import{CALL_TOOL_NAME}from"#protocol/catalog-tools.js";import{isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{getAuthorizationResults}from"#harness/authorization.js";import{passesToolFilter}from"#runtime/connections/mcp-client.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{createAuthorizationExecution}from"#runtime/connections/scoped-authorization.js";import{supportsInteractiveAuthorization}from"#shared/connection-types.js";const log=createLogger(`framework.catalog-connections`);async function completeConnectionSignIn(e,t){assertPendingSignInInstance(t);let n=await interactiveAuthorization(t),r=createAuthorizationExecution();n!==void 0&&await r.complete(n);let i=e.getClient(t.connectionName);return n!==void 0&&r.isJustAuthorized(n)&&await i.close(),{auth:r,client:i,scoped:n}}async function listConnectionTools(e,{auth:t,client:n,scoped:r}){let i=e.connectionName;try{return{tools:await listToolMetadata(e,n)}}catch(e){return isConnectionAuthorizationRequiredError(e)?r===void 0?{failure:`"${i}" requires authorization and cannot start interactive sign-in.`}:t.isJustAuthorized(r)?{failure:`Authorization failed for "${i}": the service rejected the token immediately after authorization.`}:{authorization:r,error:e}:(log.warn(`failed to load connection tools`,{connection:i,error:e}),{failure:listingFailureMessage(i,e)})}}const LISTING_TIMEOUT_MS=1e4;var ListingTimeoutError=class extends Error{};async function listToolMetadata(e,t){let{connectionName:n}=e,r,i=new Promise((e,t)=>{r=setTimeout(()=>{t(new ListingTimeoutError(`"${n}" did not list its tools within ${LISTING_TIMEOUT_MS/1e3}s. Try again later.`))},LISTING_TIMEOUT_MS)});try{return(await listConnectionMetadata(n,t,i)).filter(t=>passesToolFilter(t.name,e.tools))}finally{clearTimeout(r)}}async function listConnectionMetadata(e,t,n){let r=Promise.race([t.getToolMetadata(),n]),i=t.eventActions;if(i===void 0)return r;let[a,o]=await Promise.allSettled([r,listEventActions(e,i,n)]);for(let e of[a,o])if(e.status===`rejected`&&isConnectionAuthorizationRequiredError(e.reason))throw e.reason;let s=o.status===`fulfilled`?o.value:[];if(a.status===`rejected`){if(s.length>0)return s;throw a.reason}let c=a.value;if(c.some(e=>i.ownsName(e.name)))throw Error(`Remote tool names conflict with eve's event action namespace.`);return[...c,...s]}async function listEventActions(e,t,n){try{return await Promise.race([t.metadata(),n])}catch(n){if(isConnectionAuthorizationRequiredError(n))throw n;return log.warn(`failed to discover connection events`,{connection:e,error:n}),t.recoveryMetadata()}}function listingFailureMessage(e,t){return t instanceof ListingTimeoutError?t.message:isConnectionAuthorizationFailedError(t)?`Authorization failed for "${e}": ${t.message}`:`Failed to load tools for "${e}": ${toErrorMessage(t)}`}async function interactiveAuthorization(e){let t=await resolveConnectionAuthorization(e);if(t!==void 0&&supportsInteractiveAuthorization(t))return{scope:e.connectionName,instanceId:e.instanceId,connection:{url:e.url??``},authorization:t}}function assertPendingSignInInstance(e){for(let t of getAuthorizationResults())if(t.name===e.connectionName&&t.instanceId!==void 0&&t.instanceId!==e.instanceId)throw Error(`Authorization for "${t.name}" cannot complete because its resolved connection changed while sign-in was pending. Sign in again with ${CALL_TOOL_NAME}({ name: "${t.name}" }).`)}export{completeConnectionSignIn,listConnectionTools,listToolMetadata,listingFailureMessage};
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{toErrorMessage}from"#shared/errors.js";import{CALL_TOOL_NAME}from"#protocol/catalog-tools.js";import{isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#connections/errors.js";import{getAuthorizationResults}from"#harness/authorization.js";import{passesToolFilter}from"#runtime/connections/mcp-client.js";import{resolveConnectionAuthorization}from"#runtime/connections/resolve-authorization.js";import{createAuthorizationExecution}from"#runtime/connections/scoped-authorization.js";import{supportsInteractiveAuthorization}from"#shared/connection-types.js";const log=createLogger(`framework.catalog-connections`);async function completeConnectionSignIn(e,t){assertPendingSignInInstance(t);let n=await interactiveAuthorization(t),r=createAuthorizationExecution();n!==void 0&&await r.complete(n);let i=e.getClient(t.connectionName);return n!==void 0&&r.isJustAuthorized(n)&&await i.close(),{auth:r,client:i,scoped:n}}async function listConnectionTools(e,{auth:t,client:n,scoped:r}){let i=e.connectionName;try{return{tools:await listToolMetadata(e,n)}}catch(e){return isConnectionAuthorizationRequiredError(e)?r===void 0?{failure:`"${i}" requires authorization and cannot start interactive sign-in.`}:t.isJustAuthorized(r)?{failure:`Authorization failed for "${i}": the service rejected the token immediately after authorization.`}:{authorization:r,error:e}:(log.warn(`failed to load connection tools`,{connection:i,error:e}),{failure:listingFailureMessage(i,e)})}}const LISTING_TIMEOUT_MS=1e4;var ListingTimeoutError=class extends Error{};async function listToolMetadata(e,t){let{connectionName:n}=e,r,i=new Promise((e,t)=>{r=setTimeout(()=>{t(new ListingTimeoutError(`"${n}" did not list its tools within ${LISTING_TIMEOUT_MS/1e3}s. Try again later.`))},LISTING_TIMEOUT_MS)});try{return(await listConnectionMetadata(n,t,i)).filter(t=>passesToolFilter(t.operationId===void 0?[t.name]:[t.name,t.operationId],e.tools))}finally{clearTimeout(r)}}async function listConnectionMetadata(e,t,n){let r=Promise.race([t.getToolMetadata(),n]),i=t.eventActions;if(i===void 0)return r;let[a,o]=await Promise.allSettled([r,listEventActions(e,i,n)]);for(let e of[a,o])if(e.status===`rejected`&&isConnectionAuthorizationRequiredError(e.reason))throw e.reason;let s=o.status===`fulfilled`?o.value:[];if(a.status===`rejected`){if(s.length>0)return s;throw a.reason}let c=a.value;if(c.some(e=>i.ownsName(e.name)))throw Error(`Remote tool names conflict with eve's event action namespace.`);return[...c,...s]}async function listEventActions(e,t,n){try{return await Promise.race([t.metadata(),n])}catch(n){if(isConnectionAuthorizationRequiredError(n))throw n;return log.warn(`failed to discover connection events`,{connection:e,error:n}),t.recoveryMetadata()}}function listingFailureMessage(e,t){return t instanceof ListingTimeoutError?t.message:isConnectionAuthorizationFailedError(t)?`Authorization failed for "${e}": ${t.message}`:`Failed to load tools for "${e}": ${toErrorMessage(t)}`}async function interactiveAuthorization(e){let t=await resolveConnectionAuthorization(e);if(t!==void 0&&supportsInteractiveAuthorization(t))return{scope:e.connectionName,instanceId:e.instanceId,connection:{url:e.url??``},authorization:t}}function assertPendingSignInInstance(e){for(let t of getAuthorizationResults())if(t.name===e.connectionName&&t.instanceId!==void 0&&t.instanceId!==e.instanceId)throw Error(`Authorization for "${t.name}" cannot complete because its resolved connection changed while sign-in was pending. Sign in again with ${CALL_TOOL_NAME}({ name: "${t.name}" }).`)}export{completeConnectionSignIn,listConnectionTools,listToolMetadata,listingFailureMessage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";import{connectionToolName}from"#connections/ownership.js";function rankCandidates(e,t){let n=tokenize(e),r=scoringTerms(n);return t.map(e=>({candidate:e,...rankCandidate(n,r,e)})).filter(e=>e.score>0).sort((e,t)=>e.tier-t.tier||t.score-e.score||compareCodeUnits(e.candidate.connection?.name??``,t.candidate.connection?.name??``)||compareCodeUnits(e.candidate.name,t.candidate.name)).map(e=>e.candidate)}function isEmptyQuery(e){return tokenize(e).length===0}function closestNames(e,t){return isEmptyQuery(e)?[]:rankCandidates(e,t).slice(0,5).map(e=>e.name)}const Tier={exact:0,exactWithoutNamespace:1,connection:2,namePrefix:3,keyword:4};function rankCandidate(e,t,n){let r=n.connection===void 0?n.name:connectionToolName(n.connection.name,n.name),i=tokenize(r),a=r.lastIndexOf(`__`),o=tokenize(a<0?r:r.slice(a+2)),s=sameWords(i,e)?Tier.exact:sameWords(o,e)?Tier.exactWithoutNamespace:n.connection!==void 0&&startsWithWholeWords(tokenize(n.connection.name),e)?Tier.connection:startsWithWords(i,e)||startsWithWords(o,e)?Tier.namePrefix:Tier.keyword;return{score:scoreFields(t,candidateFields(n)),tier:s}}const FILLER_WORDS=new Set([`a`,`an`,`and`,`for`,`in`,`is`,`me`,`my`,`of`,`or`,`please`,`the`,`to`,`with`]);function scoringTerms(e){let t=e.filter(e=>e.length>1&&!FILLER_WORDS.has(e));return t.length>0?t:e}function sameWords(e,t){return e.length===t.length&&startsWithWholeWords(e,t)}function startsWithWholeWords(e,t){return t.length<=e.length&&t.every((t,n)=>e[n]===t)}function startsWithWords(e,t){return t.length<=e.length&&t.every((n,r)=>r===t.length-1?e[r].startsWith(n):e[r]===n)}function candidateFields(e){let t=isObject(e.inputSchema?.properties)?Object.entries(e.inputSchema.properties):[],n=t.flatMap(([,e])=>
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{followRefs}from"#tools/schema.js";import{connectionToolName}from"#connections/ownership.js";function rankCandidates(e,t){let n=tokenize(e),r=scoringTerms(n);return t.map(e=>({candidate:e,...rankCandidate(n,r,e)})).filter(e=>e.score>0).sort((e,t)=>e.tier-t.tier||t.score-e.score||compareCodeUnits(e.candidate.connection?.name??``,t.candidate.connection?.name??``)||compareCodeUnits(e.candidate.name,t.candidate.name)).map(e=>e.candidate)}function isEmptyQuery(e){return tokenize(e).length===0}function closestNames(e,t){return isEmptyQuery(e)?[]:rankCandidates(e,t).slice(0,5).map(e=>e.name)}const Tier={exact:0,exactWithoutNamespace:1,connection:2,namePrefix:3,keyword:4};function rankCandidate(e,t,n){let r=n.connection===void 0?n.name:connectionToolName(n.connection.name,n.name),i=tokenize(r),a=r.lastIndexOf(`__`),o=tokenize(a<0?r:r.slice(a+2)),s=sameWords(i,e)?Tier.exact:sameWords(o,e)?Tier.exactWithoutNamespace:n.connection!==void 0&&startsWithWholeWords(tokenize(n.connection.name),e)?Tier.connection:startsWithWords(i,e)||startsWithWords(o,e)?Tier.namePrefix:Tier.keyword;return{score:scoreFields(t,candidateFields(n)),tier:s}}const FILLER_WORDS=new Set([`a`,`an`,`and`,`for`,`in`,`is`,`me`,`my`,`of`,`or`,`please`,`the`,`to`,`with`]);function scoringTerms(e){let t=e.filter(e=>e.length>1&&!FILLER_WORDS.has(e));return t.length>0?t:e}function sameWords(e,t){return e.length===t.length&&startsWithWholeWords(e,t)}function startsWithWholeWords(e,t){return t.length<=e.length&&t.every((t,n)=>e[n]===t)}function startsWithWords(e,t){return t.length<=e.length&&t.every((n,r)=>r===t.length-1?e[r].startsWith(n):e[r]===n)}function candidateFields(e){let t=isObject(e.inputSchema?.properties)?Object.entries(e.inputSchema.properties):[],n=e.inputSchema??{},r=t.flatMap(([,e])=>{for(let t of followRefs(n,e))if(typeof t.description==`string`)return[t.description];return[]});return[[tokenize(e.name),6],[tokenize(e.connection?.name??``),4],[t.flatMap(([e])=>tokenize(e)),3],[proseWords(e.description),2],[r.flatMap(proseWords),1],[proseWords(e.connection?.description??``),1]]}function scoreFields(e,t){let n=0;for(let r of e)for(let[e,i]of t)e.some(e=>matchesWord(e,r))&&(n+=i);return n}function matchesWord(e,t){return e.startsWith(t)||e.length>=3&&t.startsWith(e)}function tokenize(e){return e.replaceAll(/([A-Z]+)([A-Z][a-z])/gu,`$1 $2`).replaceAll(/([a-z0-9])([A-Z])/gu,`$1 $2`).toLowerCase().split(/[^a-z0-9]+/u).filter(e=>e!==``)}function proseWords(e){return tokenize(e).filter(e=>e.length>1)}function compareCodeUnits(e,t){return e<t?-1:+(e>t)}export{closestNames,compareCodeUnits,isEmptyQuery,rankCandidates};
|
|
@@ -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.83.
|
|
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.83.3//runWorkflowProgramTask`;export{runWorkflowProgramTask};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readLegacyTurnInput}from"./input.js";import{importConversation,readLegacySnapshot}from"./snapshot.js";import{isObject}from"#shared/guards.js";import{SESSION_INBOX_CONTEXT_KEY}from"#execution/session-inbox/address.js";import{getWorld,resolveRunEncryptionKey}from"#internal/workflow/runtime.js";import{hydrateWorkflowArguments}from"#compiled/@workflow/core/serialization.js";import{DEFAULT_SESSION_TIMEOUT_MS}from"#execution/session/timeout.js";async function prepareLegacySessionStep(e){"use step";let t=readLegacyTurnInput(e),n=readLegacySnapshot(t.sessionState),{history:r,sessionState:i}=importConversation(n),a=await getWorld(),o=await a.runs.get(i.sessionId),s=await hydrateWorkflowArguments(o.input,o.runId,await resolveRunEncryptionKey(a,o)),c=Array.isArray(s)&&isObject(s[0])?s[0]:void 0;if(c===void 0)throw Error(`Cannot read the original session timeout.`);let l=c.sessionTimeoutMs;if(l!==void 0&&l!==!1&&(typeof l!=`number`||!Number.isFinite(l)||l<0))throw Error(`Invalid original session timeout.`);let u=l??DEFAULT_SESSION_TIMEOUT_MS,d={...t.serializedContext,"eve.sessionId":i.sessionId,[SESSION_INBOX_CONTEXT_KEY]:{sessionId:i.sessionId}};delete d[`eve.sessionCallback`];let f=d[`eve.channel`];return isObject(f)&&f.kind===`subagent`&&isObject(f.state)&&(d[`eve.channel`]={...f,state:{...f.state,parentContinuationToken:``}}),{input:{...t,retention:t.retention??c.retention},history:r,originalSession:n,sessionState:i,serializedContext:d,sessionTimeoutMs:u,deploymentId:process.env.VERCEL_DEPLOYMENT_ID?.trim()||await a.getDeploymentId()}}export{prepareLegacySessionStep};
|
|
1
|
+
import{readLegacyTurnInput}from"./input.js";import{importConversation,readLegacySnapshot}from"./snapshot.js";import{isObject}from"#shared/guards.js";import{SESSION_INBOX_CONTEXT_KEY}from"#execution/session-inbox/address.js";import{getWorld,resolveRunEncryptionKey}from"#internal/workflow/runtime.js";import{hydrateWorkflowArguments}from"#compiled/@workflow/core/serialization.js";import{DEFAULT_SESSION_TIMEOUT_MS}from"#execution/session/timeout.js";const RETIRED_CONTEXT_KEYS=[`eve.activityObserver`,`eve.activityPendingBlockers`,`eve.activityRootTurnId`,`eve.connectionSearchResults`,`eve.internal.backgroundToolExecution`,`eve.mode`,`eve.pendingSkillAnnouncement`,`eve.pendingTurnSleepDuration`,`eve.subagentDepth`,`eve.tasksEnabled`,`eve.todo`,`eve.turnTaskDelivery`,`eve.turnTaskState`];async function prepareLegacySessionStep(e){"use step";let t=readLegacyTurnInput(e),n=readLegacySnapshot(t.sessionState),{history:r,sessionState:i}=importConversation(n),a=await getWorld(),o=await a.runs.get(i.sessionId),s=await hydrateWorkflowArguments(o.input,o.runId,await resolveRunEncryptionKey(a,o)),c=Array.isArray(s)&&isObject(s[0])?s[0]:void 0;if(c===void 0)throw Error(`Cannot read the original session timeout.`);let l=c.sessionTimeoutMs;if(l!==void 0&&l!==!1&&(typeof l!=`number`||!Number.isFinite(l)||l<0))throw Error(`Invalid original session timeout.`);let u=l??DEFAULT_SESSION_TIMEOUT_MS,d={...t.serializedContext,"eve.sessionId":i.sessionId,[SESSION_INBOX_CONTEXT_KEY]:{sessionId:i.sessionId}};delete d[`eve.sessionCallback`];for(let e of RETIRED_CONTEXT_KEYS)delete d[e];let f=d[`eve.channel`];return isObject(f)&&f.kind===`subagent`&&isObject(f.state)&&(d[`eve.channel`]={...f,state:{...f.state,parentContinuationToken:``}}),{input:{...t,retention:t.retention??c.retention},history:r,originalSession:n,sessionState:i,serializedContext:d,sessionTimeoutMs:u,deploymentId:process.env.VERCEL_DEPLOYMENT_ID?.trim()||await a.getDeploymentId()}}export{prepareLegacySessionStep};
|
|
@@ -9,6 +9,7 @@ export type SuccessorStartInput = SessionHandoffStart & {
|
|
|
9
9
|
readonly attemptKey: string;
|
|
10
10
|
readonly checkpoint: SessionCheckpoint;
|
|
11
11
|
readonly hookTokens: readonly string[];
|
|
12
|
+
readonly sessionWritable: WritableStream<Uint8Array>;
|
|
12
13
|
/** The owner starting the successor, which hands over what it accepts meanwhile. */
|
|
13
14
|
readonly sourceRunId: string;
|
|
14
15
|
readonly targetDeploymentId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{getSandboxEnvironmentRuntime}from"#shared/sandbox-environment.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{cancelRun,
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{getSandboxEnvironmentRuntime}from"#shared/sandbox-environment.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{cancelRun,getWorld,resumeHook}from"#internal/workflow/runtime.js";import{hasRunEnded,startWorkflowOnDeployment,workflowEntryReference}from"#execution/workflow-runtime.js";import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{IncompatibleStateLayoutError,deserializeContext}from"#context/serialize.js";import{readDurableSession}from"#execution/durable-session-read.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{findSessionHookHolder}from"#execution/session-inbox/owner.js";import{EVE_PREWARM_ATTRIBUTE,EVE_SESSION_ATTRIBUTE,EVE_VERSION_ATTRIBUTE}from"#execution/eve-workflow-attributes.js";import{owningSandboxDefinition}from"#runtime/sandbox/registry.js";import{isRetiredSandboxSessionState,resolvePersistedSandboxSessionState}from"#sandbox/state.js";import{SESSION_CHECKPOINT_VERSION}from"#execution/session/handoff.js";import{mapWithConcurrency}from"#shared/map-with-concurrency.js";import{isSessionStateIdleForHandoff}from"#execution/session/handoff-state.js";import{SESSION_HANDOFF_VERSION}from"#execution/session/entry-input.js";import{traceSessionHandover}from"#execution/session/handover-tracing.js";const log=createLogger(`execution.handoff`);async function startSuccessorStep(e){"use step";let{activationToken:t,anchorRunId:n,checkpoint:r,sessionWritable:i,targetDeploymentId:a,...o}=e,{capabilities:s}=await getWorld();if(s?.hookForceClaim!==!0||s.hookRetention?.active!==!0)return log.warn(`session handoff unavailable: the Workflow world cannot force-claim hooks`,{sessionId:n}),{kind:`unsupported`};if(!isSessionStateIdleForHandoff(r))return{kind:`not-idle`};let c={...o,activationToken:t,checkpoint:r,handoffVersion:SESSION_HANDOFF_VERSION,kind:`handoff`,ownerDeploymentId:a,sessionWritable:i,sessionId:n};return{kind:`started`,runId:(await startWorkflowOnDeployment(workflowEntryReference,[c],a,r.retention===void 0?void 0:{experimental_retention:r.retention})).runId}}async function hasRunEndedStep(e){"use step";return await hasRunEnded(e.runId)}async function prepareSuccessorStep(e){"use step";let{migration:t}=e,unreadable=t=>(log.warn(`session handoff refused: this deployment cannot read the checkpoint`,{detail:t,readableCheckpointVersion:SESSION_CHECKPOINT_VERSION,sessionId:e.sessionId}),{kind:`incompatible`,reason:`checkpoint-version`});if(t.kind===`incompatible`)return unreadable(t.detail);let{checkpoint:n}=t,r=n.sessionTimeoutMs;if(r!==!1&&(typeof r!=`number`||!Number.isFinite(r)||r<0))throw Error(`Session checkpoint contains an invalid timeout duration.`);let i;try{i=await deserializeContext(n.serializedContext)}catch(e){if(e instanceof IncompatibleStateLayoutError)return unreadable(e.message);throw e}let a=i.require(BundleKey),o=readDurableSession(n.sessionState).sandboxState?.session;if(o!=null&&!isRetiredSandboxSessionState(o)){let e=owningSandboxDefinition(getResolvedRuntimeAgentNode(a.graph,a.nodeId).sandboxRegistry.sandbox);if(e.kind!==`independent`)throw Error(`Session checkpoint sandbox has no resolved provider.`);let t=getSandboxEnvironmentRuntime(e.environment),n=resolvePersistedSandboxSessionState(o,t);if(n?.providerName!==t.providerName||n.stateProtocolVersion!==t.stateProtocolVersion)throw Error(`Session checkpoint sandbox provider state is incompatible.`)}if(!isSessionStateIdleForHandoff(n))throw Error(`Session checkpoint contains pending work and cannot be handed off.`);return e.source!==void 0&&!await holdsEveryAddress(e.source)?{kind:`source-gone`}:(await recordSessionOwner(e.sessionId),(e.handoffVersion??1)<SESSION_HANDOFF_VERSION&&log.info(`session moved from an owner that releases its addresses first`,{handoffVersion:e.handoffVersion??1,sessionId:e.sessionId}),{kind:`valid`})}async function holdsEveryAddress(e){return(await mapWithConcurrency(e.hookTokens,16,e=>findSessionHookHolder(sessionInboxHookToken(e)))).every(t=>t?.runId===e.runId)}async function stopUntrackedChildSessionsStep(e){"use step";let t=await getWorld();for(let n of e.runIds)if(n!==e.sessionId)try{await cancelRun(t,n,{cancelReason:`Session upgraded`})}catch(t){[...walkCauseChain(t)].some(e=>EntityConflictError.is(e)||RunExpiredError.is(e)||WorkflowRunNotFoundError.is(e))||logError(log,`could not stop a subagent session after handoff`,t,{childRunId:n,sessionId:e.sessionId})}}async function reportSessionHandoffRetainedStep(e){"use step";log.warn(`session handoff failed; the current owner keeps the session`,{...e,checkpointVersion:SESSION_CHECKPOINT_VERSION})}async function recordSessionOwnerStep(e){"use step";await recordSessionOwner(e.sessionId)}async function recordSessionOwner(e){let{setAttributes:t}=await import(`#compiled/@workflow/core/index.js`);await t({[EVE_SESSION_ATTRIBUTE]:e,[EVE_PREWARM_ATTRIBUTE]:`1`,[EVE_VERSION_ATTRIBUTE]:resolveInstalledPackageInfo().version},{allowReservedAttributes:!0})}async function signalSessionOwnerActivationStep(e){"use step";try{await resumeHook(e.token,e.activation)}catch(e){if(!HookNotFoundError.is(e))throw e}}async function reportSessionTakenOverOutsideAttemptStep(e){"use step";log.error(`session taken over with no handoff attempt open; this run leaves without finalizing`,{sessionId:e.sessionId})}async function reportHandoverPartStuckStep(e){"use step";log.warn(`session handover part keeps failing; the previous owner keeps retrying`,e)}async function sendSessionHandoverPartStep(e){"use step";let t={"eve.handoff.buffered_payload_count":e.bufferedPayloadCount,"eve.handoff.part_index":e.part.index};e.part.index===0&&traceSessionHandover(`forwarding_started`,e.sessionId,e.part.attemptKey,t);try{let n=await resumeHook(sessionInboxHookToken(sessionCommandHookToken(e.sessionId)),{...e.part,kind:`handover`});return traceSessionHandover(e.part.final===!0?`final_submitted`:`part_submitted`,e.sessionId,e.part.attemptKey,{...t,"eve.handoff.destination_run_id":n.runId}),`delivered`}catch(e){if(HookNotFoundError.is(e))return`session-ended`;throw e}}async function signalSessionAnchorStep(e){"use step";await resumeHook(e.token,e.result)}export{hasRunEndedStep,prepareSuccessorStep,recordSessionOwnerStep,reportHandoverPartStuckStep,reportSessionHandoffRetainedStep,reportSessionTakenOverOutsideAttemptStep,sendSessionHandoverPartStep,signalSessionAnchorStep,signalSessionOwnerActivationStep,startSuccessorStep,stopUntrackedChildSessionsStep};
|
|
@@ -53,6 +53,7 @@ interface SessionHandoffInput {
|
|
|
53
53
|
readonly inbox: SessionInboxHandle;
|
|
54
54
|
readonly isInitialOwner: boolean;
|
|
55
55
|
readonly sessionId: string;
|
|
56
|
+
readonly sessionWritable: WritableStream<Uint8Array>;
|
|
56
57
|
}
|
|
57
58
|
export declare function sessionAnchorToken(sessionId: string): string;
|
|
58
59
|
/** Only one run per attempt can hold this; a successor that loses it exits untouched. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";import{createHook,getWorkflowMetadata,sleep}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{hasRunEndedStep,reportHandoverPartStuckStep,reportSessionHandoffRetainedStep,reportSessionTakenOverOutsideAttemptStep,sendSessionHandoverPartStep,startSuccessorStep}from"#execution/session/handoff-steps.js";import{abandonHandoverIfRunEnds,watchRunEnd}from"#execution/session/run-watch.js";import{isSessionStateIdleForHandoff}from"#execution/session/handoff-state.js";import{readAcceptedDeploymentId}from"#execution/session/accepted-deployment.js";const SESSION_CHECKPOINT_VERSION=17;function sessionAnchorToken(e){return`${e}:anchor`}function handoffLeaseToken(e){return`eve:handoff:lease:${e}`}const HANDOFF_LEASE_RETENTION=`7d`;function verdictRunId(e){return e.kind===`verdict`&&e.verdict.kind!==`active`?e.verdict.runId:void 0}async function sendSessionHandover(e){let{attemptKey:t,sessionId:n}=e,r=e.payloads.filter(e=>e.kind!==`handover`);for(let[e,i]of r.entries())if(await sendHandoverPart({attemptKey:t,index:e,payloads:[i]},n,r.length)===`session-ended`)return;await sendHandoverPart({attemptKey:t,final:!0,index:r.length,payloads:[]},n,r.length)}async function sendHandoverPart(e,t,n){for(let r=1,i=1;;r++)try{return await sendSessionHandoverPartStep({bufferedPayloadCount:n,part:e,sessionId:t})}catch(n){r===HANDOVER_PART_FAILURES_BEFORE_REPORT&&await reportHandoverPartStuckStep({attemptKey:e.attemptKey,error:isObject(n)&&typeof n.message==`string`?n.message:void 0,failures:r,index:e.index,sessionId:t}).catch(()=>{}),await sleep(i*1e3),i=Math.min(i*2,60)}}const HANDOVER_PART_FAILURES_BEFORE_REPORT=5;var SessionHandoff=class{input;anchor;incompatibleTargetDeploymentIds=new Set;attempts=0;worldUnsupported=!1;constructor(e){this.input=e}async tryTransfer(e,t){let{delivery:n}=e,r=readAcceptedDeploymentId(n);return r===void 0?{kind:`retained`,reason:`missing-deployment`}:r===this.input.deploymentId?{kind:`retained`,reason:`same-deployment`}:this.incompatibleTargetDeploymentIds.has(r)?{kind:`retained`,reason:`known-incompatible`}:e.handoffEligible?await this.transfer(t,r,{delivery:n}):{kind:`retained`,reason:`busy`}}async tryCompactionTransfer(e){let{deploymentId:t}=this.input;return this.incompatibleTargetDeploymentIds.has(t)?{kind:`retained`,reason:`known-incompatible`}:await this.transfer(e,t,{reason:`compaction`})}async tryPrewarmTransfer(e,t,n){return t===this.input.deploymentId?{kind:`retained`,reason:`same-deployment`}:this.incompatibleTargetDeploymentIds.has(t)?{kind:`retained`,reason:`known-incompatible`}:await this.transfer(e,t,{reason:`prewarm`,sessionTimeoutDeadline:n})}async transfer(e,t,n){let{inbox:r}=this.input;if(this.worldUnsupported)return{kind:`retained`,reason:`unsupported-world`};if(r.awaitingHandover)return{kind:`retained`,reason:`busy`};if(!isSessionStateIdleForHandoff(e))return{kind:`retained`,reason:`not-idle`};let i=getWorkflowMetadata().workflowRunId,a=this.attempts++,o=`${i}:${String(a)}`,s=r.claimedTokens,c=createHook({token:`${i}:handoff:${String(a)}`});this.ensureAnchor();let l=new AbortController,u=Date.now();try{let a;try{let r=await startSuccessorStep({...n,activationToken:c.token,anchorRunId:this.input.sessionId,attemptKey:o,checkpoint:{...this.input.checkpoint,...e,version:17},hookTokens:s,sourceRunId:i,targetDeploymentId:t});if(r.kind===`not-idle`)return{kind:`retained`,reason:`not-idle`};if(r.kind===`unsupported`)return this.worldUnsupported=!0,{kind:`retained`,reason:`unsupported-world`};a=r.runId}catch(e){let n=await this.fenceAttempt(o);if(n.kind!==`live`)return n.kind===`done`&&await this.holdEveryToken(s),await this.reportRetained(`activation-failed`,t,e),{kind:`retained`,reason:`activation-failed`};a=n.runId}let d=r.whenTakenOver(l.signal).then(()=>({kind:`taken-over`})),f,p;for(;;){if(f===void 0&&p===void 0&&r.hasPending()){let e=u+3e5-Date.now();p=sleep(Math.max(0,e)).then(()=>({kind:`deadline`}))}let e;try{e=await Promise.race([d,c.then(e=>({kind:`verdict`,verdict:e})),f===void 0?p??r.whenArrival().then(()=>({kind:`arrival`})):f.ended.then(()=>({kind:`candidate-ended`}))])}finally{f?.stop()}if(e.kind===`taken-over`)return await this.handOver(o);if(e.kind===`arrival`)continue;let n=e.kind===`candidate-ended`?a:verdictRunId(e),i=await this.fenceAttempt(o,n);if(i.kind===`live`){a=i.runId,f=watchRunEnd(a);continue}i.kind===`done`&&i.runId!==verdictRunId(e)&&await this.holdEveryToken(s);let l=e.kind===`verdict`?await this.recover(e.verdict,{attemptKey:o,candidateRunId:a,hookTokens:s,targetDeploymentId:t}):this.recoverFromSilentCandidate(e.kind);return await this.reportRetained(l.reason,t,l.error),{kind:`retained`,reason:l.reason}}}finally{l.abort(),await disposeHook(c)}}async adoptTakeover(){return await reportSessionTakenOverOutsideAttemptStep({sessionId:this.input.sessionId}),this.ensureAnchor(),{kind:`transferred`}}async fenceAttempt(e,t){let n=createHook({experimental_minRetention:`7d`,token:handoffLeaseToken(e)});try{await claimHookOwnership(n)}catch(e){if(!isHookConflictError(e)||typeof e.conflictingRunId!=`string`)throw e;let n=e.conflictingRunId;return n===t||await hasRunEndedStep({runId:n})?{kind:`done`,runId:n}:{kind:`live`,runId:n}}return{kind:`won`}}async handOver(e){return await sendSessionHandover({attemptKey:e,payloads:this.input.inbox.drain(),sessionId:this.input.sessionId}),{kind:`transferred`}}async holdEveryToken(e){await this.input.inbox.claimSessionHooks(e,{force:!0})}recoverFromSilentCandidate(e){return{error:Error(e===`deadline`?`The successor run did not report within 5 minutes.`:`The successor run ended before the handoff settled.`),reason:`activation-failed`}}async recover(e,t){let{inbox:n}=this.input;switch(e.kind){case`active`:return{error:Error(`Successor reported active without a takeover.`),reason:`activation-failed`};case`incompatible`:return this.incompatibleTargetDeploymentIds.add(t.targetDeploymentId),e.payloads.length>0&&n.restore(e.payloads),{reason:`checkpoint-incompatible`};case`failed`:return e.claimedHooks===!0?(await n.claimSessionHooks(t.hookTokens,{force:!0,handover:t.attemptKey}),abandonHandoverIfRunEnds(n,{attemptKey:t.attemptKey,sourceRunId:e.runId??t.candidateRunId})):isHookConflictError(e.error)&&this.incompatibleTargetDeploymentIds.add(t.targetDeploymentId),e.payloads.length>0&&n.restore(e.payloads),{error:e.error,reason:`activation-failed`}}}ensureAnchor(){this.input.isInitialOwner&&this.anchor===void 0&&(this.anchor=createHook({token:sessionAnchorToken(this.input.sessionId)}))}async awaitAnchoredResult(){if(this.anchor===void 0)throw Error(`Session anchor was never claimed.`);try{return await this.anchor}finally{await this.disposeAnchor()}}async disposeAnchor(){if(this.anchor===void 0)return;let e=this.anchor;this.anchor=void 0,await disposeHook(e)}async reportRetained(e,t,n){let r=isObject(n)&&typeof n.message==`string`?n.message:void 0;await reportSessionHandoffRetainedStep({error:r,reason:e,sessionId:this.input.sessionId,sourceDeploymentId:this.input.deploymentId,targetDeploymentId:t})}};export{HANDOFF_LEASE_RETENTION,SESSION_CHECKPOINT_VERSION,SessionHandoff,handoffLeaseToken,sendSessionHandover,sessionAnchorToken};
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{createHook,getWorkflowMetadata,sleep}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{hasRunEndedStep,reportHandoverPartStuckStep,reportSessionHandoffRetainedStep,reportSessionTakenOverOutsideAttemptStep,sendSessionHandoverPartStep,startSuccessorStep}from"#execution/session/handoff-steps.js";import{abandonHandoverIfRunEnds,watchRunEnd}from"#execution/session/run-watch.js";import{isSessionStateIdleForHandoff}from"#execution/session/handoff-state.js";import{readAcceptedDeploymentId}from"#execution/session/accepted-deployment.js";const SESSION_CHECKPOINT_VERSION=17;function sessionAnchorToken(e){return`${e}:anchor`}function handoffLeaseToken(e){return`eve:handoff:lease:${e}`}const HANDOFF_LEASE_RETENTION=`7d`;function verdictRunId(e){return e.kind===`verdict`&&e.verdict.kind!==`active`?e.verdict.runId:void 0}async function sendSessionHandover(e){let{attemptKey:t,sessionId:n}=e,r=e.payloads.filter(e=>e.kind!==`handover`);for(let[e,i]of r.entries())if(await sendHandoverPart({attemptKey:t,index:e,payloads:[i]},n,r.length)===`session-ended`)return;await sendHandoverPart({attemptKey:t,final:!0,index:r.length,payloads:[]},n,r.length)}async function sendHandoverPart(e,t,n){for(let r=1,i=1;;r++)try{return await sendSessionHandoverPartStep({bufferedPayloadCount:n,part:e,sessionId:t})}catch(n){r===HANDOVER_PART_FAILURES_BEFORE_REPORT&&await reportHandoverPartStuckStep({attemptKey:e.attemptKey,error:isObject(n)&&typeof n.message==`string`?n.message:void 0,failures:r,index:e.index,sessionId:t}).catch(()=>{}),await sleep(i*1e3),i=Math.min(i*2,60)}}const HANDOVER_PART_FAILURES_BEFORE_REPORT=5;var SessionHandoff=class{input;anchor;incompatibleTargetDeploymentIds=new Set;attempts=0;worldUnsupported=!1;constructor(e){this.input=e}async tryTransfer(e,t){let{delivery:n}=e,r=readAcceptedDeploymentId(n);return r===void 0?{kind:`retained`,reason:`missing-deployment`}:r===this.input.deploymentId?{kind:`retained`,reason:`same-deployment`}:this.incompatibleTargetDeploymentIds.has(r)?{kind:`retained`,reason:`known-incompatible`}:e.handoffEligible?await this.transfer(t,r,{delivery:n}):{kind:`retained`,reason:`busy`}}async tryCompactionTransfer(e){let{deploymentId:t}=this.input;return this.incompatibleTargetDeploymentIds.has(t)?{kind:`retained`,reason:`known-incompatible`}:await this.transfer(e,t,{reason:`compaction`})}async tryPrewarmTransfer(e,t,n){return t===this.input.deploymentId?{kind:`retained`,reason:`same-deployment`}:this.incompatibleTargetDeploymentIds.has(t)?{kind:`retained`,reason:`known-incompatible`}:await this.transfer(e,t,{reason:`prewarm`,sessionTimeoutDeadline:n})}async transfer(e,t,n){let{inbox:r}=this.input;if(this.worldUnsupported)return{kind:`retained`,reason:`unsupported-world`};if(r.awaitingHandover)return{kind:`retained`,reason:`busy`};if(!isSessionStateIdleForHandoff(e))return{kind:`retained`,reason:`not-idle`};let i=getWorkflowMetadata().workflowRunId,a=this.attempts++,o=`${i}:${String(a)}`,s=r.claimedTokens,c=createHook({token:`${i}:handoff:${String(a)}`});this.ensureAnchor();let l=new AbortController,u=Date.now();try{let a;try{let r=await startSuccessorStep({...n,activationToken:c.token,anchorRunId:this.input.sessionId,attemptKey:o,checkpoint:{...this.input.checkpoint,...e,version:17},hookTokens:s,sessionWritable:this.input.sessionWritable,sourceRunId:i,targetDeploymentId:t});if(r.kind===`not-idle`)return{kind:`retained`,reason:`not-idle`};if(r.kind===`unsupported`)return this.worldUnsupported=!0,{kind:`retained`,reason:`unsupported-world`};a=r.runId}catch(e){let n=await this.fenceAttempt(o);if(n.kind!==`live`)return n.kind===`done`&&await this.holdEveryToken(s),await this.reportRetained(`activation-failed`,t,e),{kind:`retained`,reason:`activation-failed`};a=n.runId}let d=r.whenTakenOver(l.signal).then(()=>({kind:`taken-over`})),f,p;for(;;){if(f===void 0&&p===void 0&&r.hasPending()){let e=u+3e5-Date.now();p=sleep(Math.max(0,e)).then(()=>({kind:`deadline`}))}let e;try{e=await Promise.race([d,c.then(e=>({kind:`verdict`,verdict:e})),f===void 0?p??r.whenArrival().then(()=>({kind:`arrival`})):f.ended.then(()=>({kind:`candidate-ended`}))])}finally{f?.stop()}if(e.kind===`taken-over`)return await this.handOver(o);if(e.kind===`arrival`)continue;let n=e.kind===`candidate-ended`?a:verdictRunId(e),i=await this.fenceAttempt(o,n);if(i.kind===`live`){a=i.runId,f=watchRunEnd(a);continue}i.kind===`done`&&i.runId!==verdictRunId(e)&&await this.holdEveryToken(s);let l=e.kind===`verdict`?await this.recover(e.verdict,{attemptKey:o,candidateRunId:a,hookTokens:s,targetDeploymentId:t}):this.recoverFromSilentCandidate(e.kind);return await this.reportRetained(l.reason,t,l.error),{kind:`retained`,reason:l.reason}}}finally{l.abort(),await disposeHook(c)}}async adoptTakeover(){return await reportSessionTakenOverOutsideAttemptStep({sessionId:this.input.sessionId}),this.ensureAnchor(),{kind:`transferred`}}async fenceAttempt(e,t){let n=createHook({experimental_minRetention:`7d`,token:handoffLeaseToken(e)});try{await claimHookOwnership(n)}catch(e){if(!isHookConflictError(e)||typeof e.conflictingRunId!=`string`)throw e;let n=e.conflictingRunId;return n===t||await hasRunEndedStep({runId:n})?{kind:`done`,runId:n}:{kind:`live`,runId:n}}return{kind:`won`}}async handOver(e){return await sendSessionHandover({attemptKey:e,payloads:this.input.inbox.drain(),sessionId:this.input.sessionId}),{kind:`transferred`}}async holdEveryToken(e){await this.input.inbox.claimSessionHooks(e,{force:!0})}recoverFromSilentCandidate(e){return{error:Error(e===`deadline`?`The successor run did not report within 5 minutes.`:`The successor run ended before the handoff settled.`),reason:`activation-failed`}}async recover(e,t){let{inbox:n}=this.input;switch(e.kind){case`active`:return{error:Error(`Successor reported active without a takeover.`),reason:`activation-failed`};case`incompatible`:return this.incompatibleTargetDeploymentIds.add(t.targetDeploymentId),e.payloads.length>0&&n.restore(e.payloads),{reason:`checkpoint-incompatible`};case`failed`:return e.claimedHooks===!0?(await n.claimSessionHooks(t.hookTokens,{force:!0,handover:t.attemptKey}),abandonHandoverIfRunEnds(n,{attemptKey:t.attemptKey,sourceRunId:e.runId??t.candidateRunId})):isHookConflictError(e.error)&&this.incompatibleTargetDeploymentIds.add(t.targetDeploymentId),e.payloads.length>0&&n.restore(e.payloads),{error:e.error,reason:`activation-failed`}}}ensureAnchor(){this.input.isInitialOwner&&this.anchor===void 0&&(this.anchor=createHook({token:sessionAnchorToken(this.input.sessionId)}))}async awaitAnchoredResult(){if(this.anchor===void 0)throw Error(`Session anchor was never claimed.`);try{return await this.anchor}finally{await this.disposeAnchor()}}async disposeAnchor(){if(this.anchor===void 0)return;let e=this.anchor;this.anchor=void 0,await disposeHook(e)}async reportRetained(e,t,n){let r=isObject(n)&&typeof n.message==`string`?n.message:void 0;await reportSessionHandoffRetainedStep({error:r,reason:e,sessionId:this.input.sessionId,sourceDeploymentId:this.input.deploymentId,targetDeploymentId:t})}};export{HANDOFF_LEASE_RETENTION,SESSION_CHECKPOINT_VERSION,SessionHandoff,handoffLeaseToken,sendSessionHandover,sessionAnchorToken};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{STUB_CONTEXT_KEY}from"#tool-stubs/types.js";import{workingTasks}from"#execution/tasks/table.js";import{settleCancelledTurnStep}from"#execution/settle-cancelled-turn-step.js";import"#execution/session-inbox/inbox.js";import{signalSessionAnchorStep}from"#execution/session/handoff-steps.js";import{SessionInputQueue}from"#execution/session/input-queue.js";import{createTurnControl}from"#execution/session/turn-control.js";import{SessionHandoff,sessionAnchorToken}from"#execution/session/handoff.js";import{notifyCancelledTaskCallerStep,notifyTurnCallerStep,resolveInitialTurnCallerStep}from"#subagents/parent-notification.js";import{withStubPlayback}from"#execution/tool-stubs/playback.js";import{nextTurnDelivery}from"#execution/session/next-input.js";import{SessionExecution}from"#execution/session/turn.js";import{SessionStateCursor}from"#execution/session/state-cursor.js";import{cancelWorkingTasks,sessionTaskTable}from"#execution/tasks/session.js";import{finalizeSession}from"#execution/session/finalization.js";import{prewarmSessionStep}from"#execution/session/prewarm-step.js";function createSafeOuterWorkflowError(){let e=Error(`Agent workflow failed. Inspect the private session trace for details.`);return e.name=`EveWorkflowFailure`,e}async function runPreparedSession(e,t){let n=e.serializedContext[STUB_CONTEXT_KEY];n!==void 0&&n.rootSessionId===void 0&&(e.serializedContext[STUB_CONTEXT_KEY]={...n,rootSessionId:e.sessionId});let r=new SessionStateCursor({history:e.history,inbox:t,sessionWritable:e.sessionWritable,serializedContext:e.serializedContext,sessionState:e.sessionState}),i={caller:e.caller},a=new SessionHandoff({checkpoint:{capabilities:e.capabilities,retention:e.retention,sessionTimeoutMs:e.sessionTimeoutMs},deploymentId:e.deploymentId,inbox:t,isInitialOwner:e.anchor.kind===`self`,sessionId:e.sessionId}),o={output:``,isError:!0},s,c=!1;try{return o=await withStubPlayback(n,e.sessionId,async()=>{try{s=await runSessionLoop(e,{cursor:r,handoff:a,inbox:t,progress:i})}finally{await t.dispose()}return s.kind===`transferred`?e.anchor.kind===`self`?(o=await a.awaitAnchoredResult(),o):{output:``}:(c=!0,o=await finalizeSession(s.outcome,{caller:i.caller,cursor:r,sessionWritable:e.sessionWritable}),o)}),o}catch(t){throw c||await finalizeSession({error:t,kind:`failed`,turnId:i.turnId},{caller:i.caller,cursor:r,sessionWritable:e.sessionWritable}),createSafeOuterWorkflowError()}finally{await t.dispose(),await reportResultToAnchor(e,o,a,s)}}async function failSession(e){let t;try{t=await resolveInitialTurnCallerStep({serializedContext:e.serializedContext})}catch{}throw await finalizeSession({error:e.error,kind:`failed`},{caller:t,cursor:{serializedContext:e.serializedContext,sessionState:e.sessionState},sessionWritable:e.sessionWritable}),createSafeOuterWorkflowError()}async function reportResultToAnchor(e,t,n,r){switch(e.anchor.kind){case`self`:await n.disposeAnchor(),await e.anchor.notify?.(t);return;case`successor`:if(r?.kind===`transferred`)return;await signalSessionAnchorStep({result:t,token:sessionAnchorToken(e.sessionId)});return}}async function runSessionLoop(e,t){let{cursor:n,handoff:r,inbox:i,progress:a}=t,o=new SessionInputQueue(e.admittedDeliveryKeys),s=new SessionExecution({capabilities:e.capabilities,cursor:n,inbox:i,queue:o,sessionId:e.sessionId}),c=e.sessionTimeoutControl,l=Promise.resolve(),u=!0,d=!1,nextParkedActivity=async()=>{for(;;){let e=await nextTurnDelivery({cursor:n,hasWorkingTasks:()=>workingTasks(sessionTaskTable(n)).length>0,inbox:i,queue:o});if(e.kind===`prewarm`){if(u&&a.caller===void 0&&workingTasks(sessionTaskTable(n)).length===0&&o.pendingCount===0&&!i.hasPending()){let t=c?.getDeadline(),n=await r.tryPrewarmTransfer(transferState(),e.targetDeploymentId,t);if(n.kind===`transferred`)return n}continue}if(e.kind===`workflow`){await s.handleWorkflowMessage(e.message);continue}if(e.kind===`cancel-working-tasks`){await cancelWorkingTasks(n,`turn_cancelled`);continue}if(!(e.kind===`expired`&&c!==void 0&&((o.pendingCount>0||i.hasPending())&&c.recordActivity(),await c.handleTimerElapsed()===`extended`)))return e}},f=e.initialTurnControl??(e.anchor.kind===`self`?createTurnControl():void 0),p=0,m=!1,runTurn=async e=>{let t=a.caller,n=f;f=void 0,a.turnId=`turn_${String(p++)}`;let r=await s.runTurn(e,{caller:t,control:n});return c?.recordActivity(),r.caller!==void 0&&(a.caller=r.caller),r.compacted===!0&&(m=!0),r},transferState=()=>({admittedDeliveryKeys:o.admittedDeliveryKeys,history:n.history,serializedContext:n.serializedContext,sessionState:n.sessionState}),compactionHandoffReady=()=>m&&a.caller===void 0&&workingTasks(sessionTaskTable(n)).length===0,tryCompactionHandoff=async()=>{if(!compactionHandoffReady()||o.pendingCount>0||i.hasPending())return;let e=await r.tryCompactionTransfer(transferState());return e.kind===`transferred`?e:void 0},runDeliveredTurn=async e=>{let t=await r.tryTransfer(e,transferState());return t.kind===`transferred`?t:(e.delivery.caller!==void 0&&(a.caller=e.delivery.caller),{action:await runTurn({delivery:e.delivery}),kind:`action`})},settleCancelledTurn=async e=>{let t=await n.advanceWithHistory(t=>settleCancelledTurnStep({...t,reportUsage:e}));return a.caller=void 0,t},awaitPrewarmedAction=async()=>{for(;;){let e=await nextParkedActivity();switch(d=!1,e.kind){case`closed`:return i.takenOver?await r.adoptTakeover():{kind:`terminal`,outcome:{kind:`expired`}};case`transferred`:return e;case`expired`:case`reset`:return{kind:`terminal`,outcome:{kind:`expired`}};case`clear`:case`compact`:continue;case`turn`:return await runDeliveredTurn(e);case`cancel-turn`:continue}}},runInitialAction=async()=>{switch(e.start.kind){case`first-message`:return d=!0,u=!1,l=n.advanceBeside(({serializedContext:e,sessionState:t})=>prewarmSessionStep({serializedContext:e,sessionState:t}),()=>d).then(()=>void 0,()=>void 0).finally(()=>{u=!0}),await awaitPrewarmedAction();case`parked`:return{action:{kind:`park`},kind:`action`};case`turn`:{let{input:t}=e.start;return{action:await runTurn(t===void 0?void 0:{delivery:t}),kind:`action`}}}};try{let[t,n]=await Promise.allSettled([runInitialAction(),c?.start()]);if(n.status===`rejected`)throw n.reason;if(t.status===`rejected`)throw t.reason;let o=t.value;if(o.kind!==`action`)return o;let l=o.action;for(;;){if(l.kind===`done`)return{kind:`terminal`,outcome:{action:l,kind:`done`}};if(l.cancelled===!0){let{caller:t}=a,n=await settleCancelledTurn(t!==void 0);if(t!==void 0){let r={caller:t,sessionId:e.sessionId};await notifyCancelledTaskCallerStep(n.usage===void 0?r:{...r,usage:n.usage})}}else l.settled!==void 0&&(a.caller!==void 0&&await notifyTurnCallerStep({caller:a.caller,lifecycle:`parked`,sessionId:e.sessionId,settled:l.settled}),a.caller=void 0);let t=await tryCompactionHandoff();if(t!==void 0)return t;f??=createTurnControl();let n=await nextParkedActivity();switch(n.kind){case`closed`:return i.takenOver?await r.adoptTakeover():{kind:`terminal`,outcome:{kind:`expired`}};case`transferred`:return n;case`expired`:case`reset`:return{kind:`terminal`,outcome:{kind:`expired`}};case`clear`:case`compact`:l=await runTurn({control:n.kind});continue;case`cancel-turn`:await s.cancelTurnWork(),await settleCancelledTurn(!1),c?.recordActivity(),l={...l,settled:void 0};continue;case`turn`:{let e=await runDeliveredTurn(n);if(e.kind!==`action`)return e;l=e.action;continue}}}}finally{d=!1,await l,await c?.dispose()}}export{failSession,runPreparedSession};
|
|
1
|
+
import{STUB_CONTEXT_KEY}from"#tool-stubs/types.js";import{workingTasks}from"#execution/tasks/table.js";import{settleCancelledTurnStep}from"#execution/settle-cancelled-turn-step.js";import"#execution/session-inbox/inbox.js";import{signalSessionAnchorStep}from"#execution/session/handoff-steps.js";import{SessionInputQueue}from"#execution/session/input-queue.js";import{createTurnControl}from"#execution/session/turn-control.js";import{SessionHandoff,sessionAnchorToken}from"#execution/session/handoff.js";import{notifyCancelledTaskCallerStep,notifyTurnCallerStep,resolveInitialTurnCallerStep}from"#subagents/parent-notification.js";import{withStubPlayback}from"#execution/tool-stubs/playback.js";import{nextTurnDelivery}from"#execution/session/next-input.js";import{SessionExecution}from"#execution/session/turn.js";import{SessionStateCursor}from"#execution/session/state-cursor.js";import{cancelWorkingTasks,sessionTaskTable}from"#execution/tasks/session.js";import{finalizeSession}from"#execution/session/finalization.js";import{prewarmSessionStep}from"#execution/session/prewarm-step.js";function createSafeOuterWorkflowError(){let e=Error(`Agent workflow failed. Inspect the private session trace for details.`);return e.name=`EveWorkflowFailure`,e}async function runPreparedSession(e,t){let n=e.serializedContext[STUB_CONTEXT_KEY];n!==void 0&&n.rootSessionId===void 0&&(e.serializedContext[STUB_CONTEXT_KEY]={...n,rootSessionId:e.sessionId});let r=new SessionStateCursor({history:e.history,inbox:t,sessionWritable:e.sessionWritable,serializedContext:e.serializedContext,sessionState:e.sessionState}),i={caller:e.caller},a=new SessionHandoff({checkpoint:{capabilities:e.capabilities,retention:e.retention,sessionTimeoutMs:e.sessionTimeoutMs},deploymentId:e.deploymentId,inbox:t,isInitialOwner:e.anchor.kind===`self`,sessionId:e.sessionId,sessionWritable:e.sessionWritable}),o={output:``,isError:!0},s,c=!1;try{return o=await withStubPlayback(n,e.sessionId,async()=>{try{s=await runSessionLoop(e,{cursor:r,handoff:a,inbox:t,progress:i})}finally{await t.dispose()}return s.kind===`transferred`?e.anchor.kind===`self`?(o=await a.awaitAnchoredResult(),o):{output:``}:(c=!0,o=await finalizeSession(s.outcome,{caller:i.caller,cursor:r,sessionWritable:e.sessionWritable}),o)}),o}catch(t){throw c||await finalizeSession({error:t,kind:`failed`,turnId:i.turnId},{caller:i.caller,cursor:r,sessionWritable:e.sessionWritable}),createSafeOuterWorkflowError()}finally{await t.dispose(),await reportResultToAnchor(e,o,a,s)}}async function failSession(e){let t;try{t=await resolveInitialTurnCallerStep({serializedContext:e.serializedContext})}catch{}throw await finalizeSession({error:e.error,kind:`failed`},{caller:t,cursor:{serializedContext:e.serializedContext,sessionState:e.sessionState},sessionWritable:e.sessionWritable}),createSafeOuterWorkflowError()}async function reportResultToAnchor(e,t,n,r){switch(e.anchor.kind){case`self`:await n.disposeAnchor(),await e.anchor.notify?.(t);return;case`successor`:if(r?.kind===`transferred`)return;await signalSessionAnchorStep({result:t,token:sessionAnchorToken(e.sessionId)});return}}async function runSessionLoop(e,t){let{cursor:n,handoff:r,inbox:i,progress:a}=t,o=new SessionInputQueue(e.admittedDeliveryKeys),s=new SessionExecution({capabilities:e.capabilities,cursor:n,inbox:i,queue:o,sessionId:e.sessionId}),c=e.sessionTimeoutControl,l=Promise.resolve(),u=!0,d=!1,nextParkedActivity=async()=>{for(;;){let e=await nextTurnDelivery({cursor:n,hasWorkingTasks:()=>workingTasks(sessionTaskTable(n)).length>0,inbox:i,queue:o});if(e.kind===`prewarm`){if(u&&a.caller===void 0&&workingTasks(sessionTaskTable(n)).length===0&&o.pendingCount===0&&!i.hasPending()){let t=c?.getDeadline(),n=await r.tryPrewarmTransfer(transferState(),e.targetDeploymentId,t);if(n.kind===`transferred`)return n}continue}if(e.kind===`workflow`){await s.handleWorkflowMessage(e.message);continue}if(e.kind===`cancel-working-tasks`){await cancelWorkingTasks(n,`turn_cancelled`);continue}if(!(e.kind===`expired`&&c!==void 0&&((o.pendingCount>0||i.hasPending())&&c.recordActivity(),await c.handleTimerElapsed()===`extended`)))return e}},f=e.initialTurnControl??(e.anchor.kind===`self`?createTurnControl():void 0),p=0,m=!1,runTurn=async e=>{let t=a.caller,n=f;f=void 0,a.turnId=`turn_${String(p++)}`;let r=await s.runTurn(e,{caller:t,control:n});return c?.recordActivity(),r.caller!==void 0&&(a.caller=r.caller),r.compacted===!0&&(m=!0),r},transferState=()=>({admittedDeliveryKeys:o.admittedDeliveryKeys,history:n.history,serializedContext:n.serializedContext,sessionState:n.sessionState}),compactionHandoffReady=()=>m&&a.caller===void 0&&workingTasks(sessionTaskTable(n)).length===0,tryCompactionHandoff=async()=>{if(!compactionHandoffReady()||o.pendingCount>0||i.hasPending())return;let e=await r.tryCompactionTransfer(transferState());return e.kind===`transferred`?e:void 0},runDeliveredTurn=async e=>{let t=await r.tryTransfer(e,transferState());return t.kind===`transferred`?t:(e.delivery.caller!==void 0&&(a.caller=e.delivery.caller),{action:await runTurn({delivery:e.delivery}),kind:`action`})},settleCancelledTurn=async e=>{let t=await n.advanceWithHistory(t=>settleCancelledTurnStep({...t,reportUsage:e}));return a.caller=void 0,t},awaitPrewarmedAction=async()=>{for(;;){let e=await nextParkedActivity();switch(d=!1,e.kind){case`closed`:return i.takenOver?await r.adoptTakeover():{kind:`terminal`,outcome:{kind:`expired`}};case`transferred`:return e;case`expired`:case`reset`:return{kind:`terminal`,outcome:{kind:`expired`}};case`clear`:case`compact`:continue;case`turn`:return await runDeliveredTurn(e);case`cancel-turn`:continue}}},runInitialAction=async()=>{switch(e.start.kind){case`first-message`:return d=!0,u=!1,l=n.advanceBeside(({serializedContext:e,sessionState:t})=>prewarmSessionStep({serializedContext:e,sessionState:t}),()=>d).then(()=>void 0,()=>void 0).finally(()=>{u=!0}),await awaitPrewarmedAction();case`parked`:return{action:{kind:`park`},kind:`action`};case`turn`:{let{input:t}=e.start;return{action:await runTurn(t===void 0?void 0:{delivery:t}),kind:`action`}}}};try{let[t,n]=await Promise.allSettled([runInitialAction(),c?.start()]);if(n.status===`rejected`)throw n.reason;if(t.status===`rejected`)throw t.reason;let o=t.value;if(o.kind!==`action`)return o;let l=o.action;for(;;){if(l.kind===`done`)return{kind:`terminal`,outcome:{action:l,kind:`done`}};if(l.cancelled===!0){let{caller:t}=a,n=await settleCancelledTurn(t!==void 0);if(t!==void 0){let r={caller:t,sessionId:e.sessionId};await notifyCancelledTaskCallerStep(n.usage===void 0?r:{...r,usage:n.usage})}}else l.settled!==void 0&&(a.caller!==void 0&&await notifyTurnCallerStep({caller:a.caller,lifecycle:`parked`,sessionId:e.sessionId,settled:l.settled}),a.caller=void 0);let t=await tryCompactionHandoff();if(t!==void 0)return t;f??=createTurnControl();let n=await nextParkedActivity();switch(n.kind){case`closed`:return i.takenOver?await r.adoptTakeover():{kind:`terminal`,outcome:{kind:`expired`}};case`transferred`:return n;case`expired`:case`reset`:return{kind:`terminal`,outcome:{kind:`expired`}};case`clear`:case`compact`:l=await runTurn({control:n.kind});continue;case`cancel-turn`:await s.cancelTurnWork(),await settleCancelledTurn(!1),c?.recordActivity(),l={...l,settled:void 0};continue;case`turn`:{let e=await runDeliveredTurn(n);if(e.kind!==`action`)return e;l=e.action;continue}}}}finally{d=!1,await l,await c?.dispose()}}export{failSession,runPreparedSession};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{defaultDeliverResult}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{currentProjection,enterSessionProjection,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,CapabilitiesKey,ChannelDeliveryKey,HandleEventKey,InitiatorAuthKey,OccurrenceIdKey,ParentSessionKey,ScheduleIdKey,ScheduleInstanceKey,SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicToolRuntimeRevisionKey,SessionTitleKey,StaticModelReferenceKey,TurnDeliveryIdsKey}from"#context/keys.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{coalesceTurnInputs,validateHarnessModelMessages}from"#harness/messages.js";import{activeTurnId,isBetweenTurns,storedProjection,turnPosition}from"#harness/session-machine/view.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{createDurableSessionValues,readDurableSession}from"#execution/durable-session-store.js";import{runStep}from"#context/run-step.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{readHitlState}from"#harness/hitl/index.js";import*as agentTraceState from"#tracing/eve/agent-trace-context-store.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey}from"#harness/authorization.js";import{refreshDynamicSessionSubagentsForRuntimeRevision}from"#context/dynamic-subagent-lifecycle.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resolveEffectiveAgentRuntime,resolveSessionUsageLimit}from"#execution/effective-agent-config.js";import{openSessionEventPublisher}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{matchSignIns}from"#harness/session-machine/transitions.js";import{readPendingHistory,withoutPendingHistory}from"#execution/session/pending-history.js";import{dropClosedRecords,saveTransition,sessionView}from"#harness/session-machine/commit.js";import{sessionStartedForResolvers,turnStartedForResolvers}from"#harness/session-machine/resolver-events.js";import{derivePendingState}from"#execution/session/pending-turn-state.js";import{rebindMissingCompiledDynamicToolCallbacks,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{setChannelContext}from"#execution/channel-context.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{createTurnEventHandler}from"#execution/session/turn-event-handler.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";import{deriveSessionTitle}from"#execution/eve-workflow-attributes.js";import{bindTurnCallerContext}from"#subagents/parent-notification.js";import{traceSessionHandover}from"#execution/session/handover-tracing.js";import{startSessionPrewarmers}from"#context/prewarm.js";import{bindDynamicConnections}from"#execution/dynamic-connections.js";import{recoverDynamicConnectionRehydration}from"#execution/dynamic-connection-recovery.js";import{setEveAttributes}from"#runtime/attributes/emit.js";import{RuntimeActionSettlementTimesKey}from"#harness/runtime-action-settlement-state.js";import{matchAuthorizationCallbacks}from"#execution/authorization-callback-match.js";import{attributeAnswers}from"#execution/session/answer-caller.js";import{resolveSessionStepResult}from"#execution/session/turn-step-result.js";import{countRunUsage}from"#execution/agent-sessions/usage.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{createExecutionHistoryView}from"#execution/history-view.js";import{runModelCallBatch}from"#execution/model-call-batching.js";import{createCancelledModelCallBatchResult}from"#execution/cancelled-model-call-batch.js";function channelDeliveryErrorCode(e){if(typeof e==`object`&&e&&`code`in e){let t=e.code;if(typeof t==`string`&&t.length>0)return t}return`CHANNEL_DELIVERY_FAILED`}async function turnStep(e){"use step";return e.handover!==void 0&&traceSessionHandover(`inbox_unblocked`,e.sessionState.sessionId,e.handover.attemptKey,{"eve.handoff.buffered_payload_count":e.handover.payloadCount,"eve.handoff.applied_at_ms":e.handover.appliedAtMs,"eve.handoff.applied_at_clock":`workflow`}),await withSessionStateDelta(e,e=>runSessionStep({...e,serializedContext:bindTurnCallerContext(e.caller,e.serializedContext)}))}async function runSessionStep(e){let t={};try{return await runSessionStepBody(e,t)}finally{await t.title}}async function runSessionStepBody(e,t){let n=e.input?.delivery,r=n,i=e.input?.runtimeResults,a=readDurableSession(e.sessionState);for(let e of i?.delegatedUsage??[])a=countRunUsage(a,e);let o=await deserializeContext(e.serializedContext);enterSessionProjection(o,a.state);let s=o.require(ChannelKey),c=o.require(BundleKey),l=resolveEffectiveAgentRuntime(c,o);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&o.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let{signIns:u}=readHitlState(a.state),d;if(u.length>0&&r!==void 0){let{matches:e,remainingPayloads:t}=matchAuthorizationCallbacks(u,r.payloads);if(r={...r,payloads:t},e.length>0){let n=e.map(e=>e.result.attemptId),i=e.map(e=>e.result);o.set(PendingAuthorizationResultKey,i);let s=sessionView(storedProjection(a.state),a.state),c=matchSignIns(s,{attemptIds:n});if(c.events.length!==0)throw Error(`matchSignIns must not emit events.`);a=saveTransition(a,c),d=e,t.length===0&&(r=void 0)}}r?.payloads.some(e=>e.message!==void 0)&&(o.delete(ScheduleIdKey),o.delete(ScheduleInstanceKey),o.delete(OccurrenceIdKey),r.schedule!==void 0&&(o.set(ScheduleIdKey,r.schedule.definition),r.schedule.instance!==void 0&&o.set(ScheduleInstanceKey,r.schedule.instance),r.schedule.occurrenceId!==void 0&&o.set(OccurrenceIdKey,r.schedule.occurrenceId)));let f=o.get(AuthKey),p=o.has(InitiatorAuthKey);r?.auth!==void 0&&(o.set(AuthKey,r.auth??null),o.has(InitiatorAuthKey)||o.set(InitiatorAuthKey,r.auth??null));let m=r===void 0?d?.find(({challenge:e})=>e.candidateId===void 0)?.challenge.requester:void 0;m!==void 0&&o.set(AuthKey,m);let h=r?.payloads.some(e=>e.message!==void 0)===!0?readPendingHistory(a.state):[],g={...hydrateDurableSession({compactionOverrides:{thresholdPercent:l.thresholdPercent},durable:a,turnAgent:l.turnAgent}),history:validateHarnessModelMessages(e.history)},_=createExecutionHistoryView(g),v=bindSessionInstrumentation({agentName:l.turnAgent.id,ctx:o,rootSessionId:g.rootSessionId??g.sessionId,sessionId:g.sessionId}),y=turnPosition(currentProjection(o)),b=isBetweenTurns(currentProjection(o));if(!y.sessionStarted&&!o.has(SessionTitleKey)&&!o.has(ParentSessionKey)){let e=n?.payloads.find(e=>e.message!==void 0)?.message,r=deriveSessionTitle(n?.title??e);r!==void 0&&(o.set(SessionTitleKey,r),t.title=setEveAttributes({"$eve.title":r}))}n!==void 0&&(await contextStorage.run(o,()=>v?.preparePreamble({sequence:y.sequence,sessionStarted:y.sessionStarted})),await contextStorage.run(o,()=>v?.instrumentChannelDelivery({agentName:c.turnAgent.id,ctx:o,delivery:n,rootSessionId:g.rootSessionId??g.sessionId,sequence:y.sequence,sessionId:g.sessionId,turnId:activeTurnId(y)})));let failChannelDeliveries=async e=>{await contextStorage.run(o,()=>v?.instrumentChannelDelivery({ctx:o,error:e,errorCode:channelDeliveryErrorCode(e),includeTurn:!1,outcome:`failed`})),await v?.flush()},x=openSessionEventPublisher({ctx:o,origin:`own`,sessionWritable:e.sessionWritable}),{adapterCtx:S}=x.dispatcher,C=new AbortController,w=e.abortSignal===void 0?C.signal:AbortSignal.any([e.abortSignal,C.signal]);try{let u=bindDynamicConnections(o,c.resolvedAgent),m={...c.graph.root,turnAgent:l.turnAgent},T=resolveSessionUsageLimit(c),E=!1,D=createTurnEventHandler({abortSignal:w,bundle:c,canCancelTurn:e.input?.control===void 0,hookCancellation:C,ctx:o,dynamicConnections:u,effectiveAgent:l,effectiveNode:m,instrumentation:v,publisher:x}),handleEvent=async(e,t)=>{e.type===`compaction.completed`&&(E=!0),await D(e,t)},O=r!==void 0&&!b?structuredClone(S.state):void 0,k;if(r!==void 0){let e=[];try{for(let t of r.payloads){let n=s.deliver?await s.deliver(t,S):defaultDeliverResult(t);if(n!=null){let r=[...e.length===0?h:[],...t.history??[]];e.push(r.length===0?n:{...n,history:r})}}}catch(e){throw await failChannelDeliveries(e),e}e.length>0&&h.length>0&&(g={...g,state:withoutPendingHistory(g.state)}),k=e.length===0?void 0:e.reduce(coalesceTurnInputs)}let A=r?.auth===void 0?void 0:attributeAnswers({responder:r.auth,state:a.state,stepInput:k});if(A!==void 0&&(k=A,f===void 0?o.delete(AuthKey):o.set(AuthKey,f),p||o.delete(InitiatorAuthKey)),r!==void 0&&k===void 0&&!b)f===void 0?o.delete(AuthKey):o.set(AuthKey,f),S.state=O;else if(n?.payloads.some(e=>e.message!==void 0)){let e=n.deliveryMetadata?.map(e=>e.deliveryId)??[];o.set(TurnDeliveryIdsKey,y.turnId?[...new Set([...o.get(TurnDeliveryIdsKey)??[],...e])]:e)}else!y.sessionStarted&&o.get(ChannelDeliveryKey)!==void 0&&o.set(TurnDeliveryIdsKey,[o.require(ChannelDeliveryKey).deliveryId]);if(i!==void 0&&(i.acceptedAtMsByCallId!==void 0&&o.set(RuntimeActionSettlementTimesKey,i.acceptedAtMsByCallId),k={...k,runtimeActionResults:i.results}),n!==void 0){let e={...s,state:{...S.state}};setChannelContext(o,e)}if(r!==void 0&&k===void 0&&b){await contextStorage.run(o,()=>v?.instrumentChannelDelivery({ctx:o,includeTurn:!1,outcome:`completed`})),await v?.flush();let t=saveSessionProjection(reconcileSessionContinuationToken(o,g),o),n=serializeContext(o),r=t===g?{history:e.history,sessionState:e.sessionState}:createDurableSessionValues(t);return{action:`park`,...derivePendingState(t,currentProjection(o)),serializedContext:n,...r}}let j=c.subagentRegistry.dynamicResolvers??[],M=c.resolvedAgent.dynamicToolResolvers??[],N=buildRuntimeIdentity(m);try{let e=process.env.VERCEL_DEPLOYMENT_ID?.trim(),t=e?`deployment:${e}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(c.compiledArtifactsSource),n=y.sessionStarted;if(o.setVirtualContext(StaticModelReferenceKey,l.turnAgent.model??null),!n)o.set(SessionDynamicSubagentRuntimeRevisionKey,t),o.set(SessionDynamicToolRuntimeRevisionKey,t);else{let e=sessionStartedForResolvers(N);await Promise.all([refreshDynamicSessionSubagentsForRuntimeRevision({ctx:o,resolvers:j,event:e,messages:_.initial.messages,runtimeRevision:t}),contextStorage.run(o,async()=>await refreshDynamicSessionToolsForRuntimeRevision({ctx:o,resolvers:M,event:e,messages:_.initial.messages,runtimeRevision:t}))]),b||await rebindMissingCompiledDynamicToolCallbacks({ctx:o,event:turnStartedForResolvers({sequence:y.sequence,turnId:activeTurnId(y)}),messages:_.initial.messages,resolvers:M})}}catch(e){throw await failChannelDeliveries(e),e}let P=c.resolvedAgent.config?.experimental?.workflow?.modelCallsPerStep??1,F=o.get(CapabilitiesKey),runHarnessStep=async(n,r,i)=>{let a=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:l.thresholdPercent},session:n,turnAgent:l.turnAgent});return createExecutionNodeStep({steeringSignal:e.steeringSignal,abortSignal:w,capabilities:F,clearOnly:e.input?.control===`clear`,compactOnly:e.input?.control===`compact`,createRuntime:createWorkflowRuntime,handleEvent,prepareApprovalTurn:e=>u.dispatch(turnStartedForResolvers(e)),signInCompletions:i,typedAnswers:!hasDelegatedSessionContext(e.serializedContext),historyProjector:_.projector,historyView:_.prepare(a),instrumentation:v,modelResolutionScope:{moduleMap:c.moduleMap,nodeId:c.nodeId},node:m,sessionUsageLimit:T,titleAttributeWrite:t.title})(a,r)},I,L;try{throwIfTurnAborted(w),L=await runModelCallBatch({steeringSignal:e.steeringSignal,initialInput:k,initialSession:g,modelCallsPerStep:P,runStep:async({firstCall:t,session:n,stepInput:r})=>{let i=await runStep(o,n,async n=>{t&&e.input?.control===void 0&&startSessionPrewarmers(o,`turn`),o.setVirtualContext(HandleEventKey,handleEvent),o.setVirtualContext(StaticModelReferenceKey,l.turnAgent.model??null);let i=t&&k?.outputSchema!==void 0?{...n,outputSchema:k.outputSchema}:n,a=turnPosition(currentProjection(o));try{await u.rehydrate(a,N,isBetweenTurns(currentProjection(o))?void 0:{sequence:a.sequence,turnId:activeTurnId(a)})}catch(e){let t=await recoverDynamicConnectionRehydration({emit:handleEvent,error:e,projection:currentProjection(o),session:i});if(t!==void 0)return t;throw e}let s=t&&d!==void 0?d.map(({challenge:e})=>e):void 0;return runHarnessStep(i,r,s)});i.settledTurn===void 0&&throwIfTurnAborted(w);let a={...i,session:saveSessionProjection(i.session,o)};return I={result:a,serializedContext:serializeContext(o)},a}})}catch(t){if(!isTurnCancellation(t)&&!w.aborted)throw await failChannelDeliveries(t),t;return createCancelledModelCallBatchResult({beforeBatchContext:e.serializedContext,checkpoint:I,ctx:o,initialSession:g,stepInput:k})}let R=saveSessionProjection(dropClosedRecords(reconcileSessionContinuationToken(o,L.session),currentProjection(o)),o);agentTraceState.pruneAgentTraceState(o,R.sessionId,R.state);let z=serializeContext(o);L={...L,session:R};let B=resolveSessionStepResult(L,z);return B.action===`done`&&await x.writer.close(),E?{...B,compacted:!0}:B}finally{x.writer.release()}}export{turnStep};
|
|
1
|
+
import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{defaultDeliverResult}from"#channel/adapter.js";import{contextStorage}from"#context/container.js";import{currentProjection,enterSessionProjection,recordAppliedSession,saveSessionProjection}from"#harness/session-machine/current.js";import{AuthKey,CapabilitiesKey,ChannelDeliveryKey,HandleEventKey,InitiatorAuthKey,OccurrenceIdKey,ParentSessionKey,ScheduleIdKey,ScheduleInstanceKey,SessionDynamicSubagentRuntimeRevisionKey,SessionDynamicToolRuntimeRevisionKey,SessionTitleKey,StaticModelReferenceKey,TurnDeliveryIdsKey}from"#context/keys.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{coalesceTurnInputs,validateHarnessModelMessages}from"#harness/messages.js";import{activeTurnId,isBetweenTurns,storedProjection,turnPosition}from"#harness/session-machine/view.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{createDurableSessionValues,readDurableSession}from"#execution/durable-session-store.js";import{runStep}from"#context/run-step.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{readHitlState}from"#harness/hitl/index.js";import*as agentTraceState from"#tracing/eve/agent-trace-context-store.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey}from"#harness/authorization.js";import{refreshDynamicSessionSubagentsForRuntimeRevision}from"#context/dynamic-subagent-lifecycle.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{resolveEffectiveAgentRuntime,resolveSessionUsageLimit}from"#execution/effective-agent-config.js";import{openSessionEventPublisher}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{matchSignIns}from"#harness/session-machine/transitions.js";import{readPendingHistory,withoutPendingHistory}from"#execution/session/pending-history.js";import{dropClosedRecords,saveTransition,sessionView}from"#harness/session-machine/commit.js";import{sessionStartedForResolvers,turnStartedForResolvers}from"#harness/session-machine/resolver-events.js";import{derivePendingState}from"#execution/session/pending-turn-state.js";import{rebindMissingCompiledDynamicToolCallbacks,refreshDynamicSessionToolsForRuntimeRevision}from"#context/dynamic-tool-lifecycle.js";import{hasDelegatedSessionContext}from"#execution/delegated-session-context.js";import{setChannelContext}from"#execution/channel-context.js";import{reconcileSessionContinuationToken}from"#execution/reconcile-session-continuation-token.js";import{createTurnEventHandler}from"#execution/session/turn-event-handler.js";import{isTurnCancellation,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{bindSessionInstrumentation}from"#instrumentation/runtime.js";import{deriveSessionTitle}from"#execution/eve-workflow-attributes.js";import{bindTurnCallerContext}from"#subagents/parent-notification.js";import{traceSessionHandover}from"#execution/session/handover-tracing.js";import{startSessionPrewarmers}from"#context/prewarm.js";import{bindDynamicConnections}from"#execution/dynamic-connections.js";import{recoverDynamicConnectionRehydration}from"#execution/dynamic-connection-recovery.js";import{setEveAttributes}from"#runtime/attributes/emit.js";import{RuntimeActionSettlementTimesKey}from"#harness/runtime-action-settlement-state.js";import{matchAuthorizationCallbacks}from"#execution/authorization-callback-match.js";import{attributeAnswers}from"#execution/session/answer-caller.js";import{resolveSessionStepResult}from"#execution/session/turn-step-result.js";import{countRunUsage}from"#execution/agent-sessions/usage.js";import{buildRuntimeIdentity,createExecutionNodeStep}from"#execution/node-step.js";import{createExecutionHistoryView}from"#execution/history-view.js";import{runModelCallBatch}from"#execution/model-call-batching.js";import{createCancelledModelCallBatchResult}from"#execution/cancelled-model-call-batch.js";function channelDeliveryErrorCode(e){if(typeof e==`object`&&e&&`code`in e){let t=e.code;if(typeof t==`string`&&t.length>0)return t}return`CHANNEL_DELIVERY_FAILED`}async function turnStep(e){"use step";return e.handover!==void 0&&traceSessionHandover(`inbox_unblocked`,e.sessionState.sessionId,e.handover.attemptKey,{"eve.handoff.buffered_payload_count":e.handover.payloadCount,"eve.handoff.applied_at_ms":e.handover.appliedAtMs,"eve.handoff.applied_at_clock":`workflow`}),await withSessionStateDelta(e,e=>runSessionStep({...e,serializedContext:bindTurnCallerContext(e.caller,e.serializedContext)}))}async function runSessionStep(e){let t={};try{return await runSessionStepBody(e,t)}finally{await t.title}}async function runSessionStepBody(e,t){let n=e.input?.delivery,r=n,i=e.input?.runtimeResults,a=readDurableSession(e.sessionState);for(let e of i?.delegatedUsage??[])a=countRunUsage(a,e);let o=await deserializeContext(e.serializedContext);enterSessionProjection(o,a.state);let s=o.require(ChannelKey),c=o.require(BundleKey),l=resolveEffectiveAgentRuntime(c,o);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&o.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let{signIns:u}=readHitlState(a.state),d;if(u.length>0&&r!==void 0){let{matches:e,remainingPayloads:t}=matchAuthorizationCallbacks(u,r.payloads);if(r={...r,payloads:t},e.length>0){let n=e.map(e=>e.result.attemptId),i=e.map(e=>e.result);o.set(PendingAuthorizationResultKey,i);let s=sessionView(storedProjection(a.state),a.state),c=matchSignIns(s,{attemptIds:n});if(c.events.length!==0)throw Error(`matchSignIns must not emit events.`);a=saveTransition(a,c),d=e,t.length===0&&(r=void 0)}}r?.payloads.some(e=>e.message!==void 0)&&(o.delete(ScheduleIdKey),o.delete(ScheduleInstanceKey),o.delete(OccurrenceIdKey),r.schedule!==void 0&&(o.set(ScheduleIdKey,r.schedule.definition),r.schedule.instance!==void 0&&o.set(ScheduleInstanceKey,r.schedule.instance),r.schedule.occurrenceId!==void 0&&o.set(OccurrenceIdKey,r.schedule.occurrenceId)));let f=o.get(AuthKey),p=o.has(InitiatorAuthKey);r?.auth!==void 0&&(o.set(AuthKey,r.auth??null),o.has(InitiatorAuthKey)||o.set(InitiatorAuthKey,r.auth??null));let m=r===void 0?d?.find(({challenge:e})=>e.candidateId===void 0)?.challenge.requester:void 0;m!==void 0&&o.set(AuthKey,m);let h=r?.payloads.some(e=>e.message!==void 0)===!0?readPendingHistory(a.state):[],g={...hydrateDurableSession({compactionOverrides:{thresholdPercent:l.thresholdPercent},durable:a,turnAgent:l.turnAgent}),history:validateHarnessModelMessages(e.history)},_=createExecutionHistoryView(g),v=bindSessionInstrumentation({agentName:l.turnAgent.id,ctx:o,rootSessionId:g.rootSessionId??g.sessionId,sessionId:g.sessionId}),y=turnPosition(currentProjection(o)),b=isBetweenTurns(currentProjection(o));if(!y.sessionStarted&&!o.has(SessionTitleKey)&&!o.has(ParentSessionKey)){let e=n?.payloads.find(e=>e.message!==void 0)?.message,r=deriveSessionTitle(n?.title??e);r!==void 0&&(o.set(SessionTitleKey,r),t.title=setEveAttributes({"$eve.title":r}))}n!==void 0&&(await contextStorage.run(o,()=>v?.preparePreamble({sequence:y.sequence,sessionStarted:y.sessionStarted})),await contextStorage.run(o,()=>v?.instrumentChannelDelivery({agentName:c.turnAgent.id,ctx:o,delivery:n,rootSessionId:g.rootSessionId??g.sessionId,sequence:y.sequence,sessionId:g.sessionId,turnId:activeTurnId(y)})));let failChannelDeliveries=async e=>{await contextStorage.run(o,()=>v?.instrumentChannelDelivery({ctx:o,error:e,errorCode:channelDeliveryErrorCode(e),includeTurn:!1,outcome:`failed`})),await v?.flush()},x=openSessionEventPublisher({ctx:o,origin:`own`,sessionWritable:e.sessionWritable}),{adapterCtx:S}=x.dispatcher,C=new AbortController,w=e.abortSignal===void 0?C.signal:AbortSignal.any([e.abortSignal,C.signal]);try{let u=bindDynamicConnections(o,c.resolvedAgent),m={...c.graph.root,turnAgent:l.turnAgent},T=resolveSessionUsageLimit(c),E=!1,D=createTurnEventHandler({abortSignal:w,bundle:c,canCancelTurn:e.input?.control===void 0,hookCancellation:C,ctx:o,dynamicConnections:u,effectiveAgent:l,effectiveNode:m,instrumentation:v,publisher:x}),handleEvent=async(e,t)=>{e.type===`compaction.completed`&&(E=!0),await D(e,t)},O=r!==void 0&&!b?structuredClone(S.state):void 0,k;if(r!==void 0){let e=[];try{for(let t of r.payloads){let n=s.deliver?await s.deliver(t,S):defaultDeliverResult(t);if(n!=null){let r=[...e.length===0?h:[],...t.history??[]];e.push(r.length===0?n:{...n,history:r})}}}catch(e){throw await failChannelDeliveries(e),e}e.length>0&&h.length>0&&(g={...g,state:withoutPendingHistory(g.state)}),k=e.length===0?void 0:e.reduce(coalesceTurnInputs)}let A=r?.auth===void 0?void 0:attributeAnswers({responder:r.auth,state:a.state,stepInput:k});if(A!==void 0&&(k=A,f===void 0?o.delete(AuthKey):o.set(AuthKey,f),p||o.delete(InitiatorAuthKey)),r!==void 0&&k===void 0&&!b)f===void 0?o.delete(AuthKey):o.set(AuthKey,f),S.state=O;else if(n?.payloads.some(e=>e.message!==void 0)){let e=n.deliveryMetadata?.map(e=>e.deliveryId)??[];o.set(TurnDeliveryIdsKey,y.turnId?[...new Set([...o.get(TurnDeliveryIdsKey)??[],...e])]:e)}else!y.sessionStarted&&o.get(ChannelDeliveryKey)!==void 0&&o.set(TurnDeliveryIdsKey,[o.require(ChannelDeliveryKey).deliveryId]);if(i!==void 0&&(i.acceptedAtMsByCallId!==void 0&&o.set(RuntimeActionSettlementTimesKey,i.acceptedAtMsByCallId),k={...k,runtimeActionResults:i.results}),n!==void 0){let e={...s,state:{...S.state}};setChannelContext(o,e)}if(r!==void 0&&k===void 0&&b){await contextStorage.run(o,()=>v?.instrumentChannelDelivery({ctx:o,includeTurn:!1,outcome:`completed`})),await v?.flush();let t=saveSessionProjection(reconcileSessionContinuationToken(o,g),o),n=serializeContext(o),r=t===g?{history:e.history,sessionState:e.sessionState}:createDurableSessionValues(t);return{action:`park`,...derivePendingState(t,currentProjection(o)),serializedContext:n,...r}}let j=c.subagentRegistry.dynamicResolvers??[],M=c.resolvedAgent.dynamicToolResolvers??[],N=buildRuntimeIdentity(m);try{let e=process.env.VERCEL_DEPLOYMENT_ID?.trim(),t=e?`deployment:${e}`:await resolveRuntimeCompiledArtifactsVersionedCacheKey(c.compiledArtifactsSource),n=y.sessionStarted;if(o.setVirtualContext(StaticModelReferenceKey,l.turnAgent.model??null),!n)o.set(SessionDynamicSubagentRuntimeRevisionKey,t),o.set(SessionDynamicToolRuntimeRevisionKey,t);else{let e=sessionStartedForResolvers(N);await Promise.all([refreshDynamicSessionSubagentsForRuntimeRevision({ctx:o,resolvers:j,event:e,messages:_.initial.messages,runtimeRevision:t}),contextStorage.run(o,async()=>await refreshDynamicSessionToolsForRuntimeRevision({ctx:o,resolvers:M,event:e,messages:_.initial.messages,runtimeRevision:t}))]),b||await rebindMissingCompiledDynamicToolCallbacks({ctx:o,event:turnStartedForResolvers({sequence:y.sequence,turnId:activeTurnId(y)}),messages:_.initial.messages,resolvers:M})}}catch(e){throw await failChannelDeliveries(e),e}let P=c.resolvedAgent.config?.experimental?.workflow?.modelCallsPerStep??1,F=o.get(CapabilitiesKey),runHarnessStep=async(n,r,i)=>{let a=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:l.thresholdPercent},session:n,turnAgent:l.turnAgent});return createExecutionNodeStep({steeringSignal:e.steeringSignal,abortSignal:w,capabilities:F,clearOnly:e.input?.control===`clear`,compactOnly:e.input?.control===`compact`,createRuntime:createWorkflowRuntime,handleEvent,prepareApprovalTurn:e=>u.dispatch(turnStartedForResolvers(e)),signInCompletions:i,typedAnswers:!hasDelegatedSessionContext(e.serializedContext),historyProjector:_.projector,historyView:_.prepare(a),instrumentation:v,modelResolutionScope:{moduleMap:c.moduleMap,nodeId:c.nodeId},node:m,sessionUsageLimit:T,titleAttributeWrite:t.title})(a,r)},I,L;try{throwIfTurnAborted(w),L=await runModelCallBatch({steeringSignal:e.steeringSignal,initialInput:k,initialSession:g,modelCallsPerStep:P,runStep:async({firstCall:t,session:n,stepInput:r})=>{let i=await runStep(o,n,async n=>{t&&e.input?.control===void 0&&startSessionPrewarmers(o,`turn`),o.setVirtualContext(HandleEventKey,handleEvent),o.setVirtualContext(StaticModelReferenceKey,l.turnAgent.model??null);let i=t&&k?.outputSchema!==void 0?{...n,outputSchema:k.outputSchema}:n,a=turnPosition(currentProjection(o));try{await u.rehydrate(a,N,isBetweenTurns(currentProjection(o))?void 0:{sequence:a.sequence,turnId:activeTurnId(a)})}catch(e){let t=await recoverDynamicConnectionRehydration({emit:handleEvent,error:e,projection:currentProjection(o),session:i});if(t!==void 0)return t;throw e}let s=t&&d!==void 0?d.map(({challenge:e})=>e):void 0;return runHarnessStep(i,r,s)});i.settledTurn===void 0&&throwIfTurnAborted(w);let a={...i,session:saveSessionProjection(i.session,o)};return recordAppliedSession(o,a.session),I={result:a,serializedContext:serializeContext(o)},a}})}catch(t){if(!isTurnCancellation(t)&&!w.aborted)throw await failChannelDeliveries(t),t;return createCancelledModelCallBatchResult({beforeBatchContext:e.serializedContext,checkpoint:I,ctx:o,initialSession:g,stepInput:k})}let R=saveSessionProjection(dropClosedRecords(reconcileSessionContinuationToken(o,L.session),currentProjection(o)),o);agentTraceState.pruneAgentTraceState(o,R.sessionId,R.state);let z=serializeContext(o);L={...L,session:R};let B=resolveSessionStepResult(L,z);return B.action===`done`&&await x.writer.close(),E?{...B,compacted:!0}:B}finally{x.writer.release()}}export{turnStep};
|
|
@@ -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.83.
|
|
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.83.3//runAgentRouterTask`;export{runAgentRouterTask};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import TurndownService from"#compiled/turndown/index.js";function convertHtmlToMarkdown(e){let t=new TurndownService({bulletListMarker:`-`,codeBlockStyle:`fenced`,emDelimiter:`*`,headingStyle:`atx`,hr:`---`});return t.remove([`script`,`style`,`meta`,`link`]),t.turndown(e)}function extractTextFromHtml(e){let t=e;return t=t
|
|
2
|
-
`),t=t.replace(/<br\s*\/?>/gi,`
|
|
3
|
-
`),t=t.replace(/<[^>]+>/g,``),t=decodeHtmlEntities(t),t=t.split(`
|
|
1
|
+
import TurndownService from"#compiled/turndown/index.js";function convertHtmlToMarkdown(e){let t=new TurndownService({bulletListMarker:`-`,codeBlockStyle:`fenced`,emDelimiter:`*`,headingStyle:`atx`,hr:`---`});return t.remove([`script`,`style`,`meta`,`link`]),t.turndown(e)}function extractTextFromHtml(e){let t=stripTags(e);return t=decodeHtmlEntities(t),t=t.split(`
|
|
4
2
|
`).map(e=>e.replace(/[ \t]+/g,` `).trim()).join(`
|
|
5
3
|
`).replace(/\n{3,}/g,`
|
|
6
4
|
|
|
7
|
-
`).trim(),t}const
|
|
5
|
+
`).trim(),t}const RAW_TEXT_CLOSE_TAGS=new Map([[`noscript`,/<\/noscript(?=[\s/>])/gi],[`script`,/<\/script(?=[\s/>])/gi],[`style`,/<\/style(?=[\s/>])/gi]]),BLOCK_ELEMENTS=new Set([`article`,`aside`,`blockquote`,`details`,`div`,`figcaption`,`figure`,`footer`,`h1`,`h2`,`h3`,`h4`,`h5`,`h6`,`header`,`li`,`main`,`nav`,`p`,`pre`,`section`,`summary`,`tr`]),TAG_NAME_PATTERN=/^(\/?)([^\s/>]+)/;function stripTags(e){let t=[],n=0;for(;n<e.length;){let r=e.indexOf(`<`,n);if(r===-1)break;if(e.startsWith(`<!--`,r)){t.push(e.slice(n,r));let i=e.indexOf(`-->`,r+4);n=i===-1?e.length:i+3;continue}let i=e.indexOf(`>`,r+1);if(i===-1)break;t.push(e.slice(n,r)),n=i+1;let a=TAG_NAME_PATTERN.exec(e.slice(r+1,i));if(!a)continue;let o=a[1]===`/`,s=a[2].toLowerCase();if(s===`br`||o&&BLOCK_ELEMENTS.has(s)){t.push(`
|
|
6
|
+
`);continue}let c=o?void 0:RAW_TEXT_CLOSE_TAGS.get(s);if(c){c.lastIndex=n;let t=c.exec(e)?e.indexOf(`>`,c.lastIndex):-1;n=t===-1?e.length:t+1}}return t.push(e.slice(n)),t.join(``)}const ENTITY_MAP={"&":`&`,">":`>`,"<":`<`," ":` `,""":`"`,"'":`'`,"'":`'`,"/":`/`},ENTITY_PATTERN=new RegExp(Object.keys(ENTITY_MAP).join(`|`),`gi`);function decodeHtmlEntities(e){return e.replace(ENTITY_PATTERN,e=>ENTITY_MAP[e.toLowerCase()]??e)}export{convertHtmlToMarkdown,extractTextFromHtml};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createFrameworkUserMessage,isFrameworkUserMessage}from"#harness/messages.js";import{COMPACTION_CHECKPOINT_MARKER,COMPACTION_PROMPT_ENVELOPE,COMPACTION_RESUMPTION_MESSAGE,TRANSCRIPT_PAYLOAD_LIMIT,clipMiddleUtf16Safe,createCompactionPrompt,serializeToolResultOutput,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.
|
|
1
|
+
import{createFrameworkUserMessage,isFrameworkUserMessage}from"#harness/messages.js";import{COMPACTION_CHECKPOINT_MARKER,COMPACTION_PROMPT_ENVELOPE,COMPACTION_RESUMPTION_MESSAGE,TRANSCRIPT_PAYLOAD_LIMIT,clipMiddleUtf16Safe,createCompactionPrompt,serializeToolResultOutput,sliceUtf16Safe,stubContentOutputFileParts}from"#harness/compaction/prompt.js";import{CompactionOverLimitError}from"#harness/compaction/over-limit-error.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.replay,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=keptTailBudget(t),c=r?{...t,recentWindowSize:1}:t,planTail=e=>{let t=findLastRealUserIndex(e),n=e[t],r=n===void 0?void 0:fitCurrentMessage(n,s),i=r?.replay??n,a=selectRecentWindowSize(e,c,s);return i!==void 0&&t<e.length-a&&(a=selectRecentWindowSize(e,c,Math.max(0,s-estimateTokens([i])))),{currentIndex:t,fit:r,keep:a,replay:i}},l=planTail(a);if(!r&&l.fit===void 0){let{older:n,recent:r}=splitMessagesForCompaction(a,l.keep);if(n.length===0&&o===void 0)return keepNonToolResultMessages(r);let s=Math.max(0,(i??getInputTokenCount(e,t))-estimateTokens(e));for(let e of COMPACTION_HEURISTICS){let i=e({config:t,older:n,previousCheckpoint:o,recent:r,replay:l.replay,tokenEstimateAdjustment:s});if(i.type===`within-limit`)return i.messages}}let u=capToolResults(a),{currentIndex:d,fit:f,keep:p,replay:m}=planTail(u),h=d<0?void 0:u[d],g=h===void 0?void 0:omitFiles(h),_=g===void 0?void 0:fitCurrentMessage(g,1)?.replay,v=g!==void 0&&_!==void 0&&estimateTokens([_])<estimateTokens([g])?_:g;if(evaluateThreshold(withResumptionGuard(checkpointHead(``),v,1/0),t,`estimate`).type===`over-limit`)throw new CompactionOverLimitError(`The agent's system prompt, tools and memory leave only ~${t.threshold} tokens for the conversation, too few to compact it.`);let{older:y,recent:b}=splitMessagesForCompaction(u,p),x=createCompactionPrompt({messages:f===void 0?y:y.map((e,t)=>t===d?f.cut:e),previousCheckpoint:o,transcriptBudgetTokens:t.threshold}),S=await n({messages:[createFrameworkUserMessage(`context.compaction`,x.prompt)],system:x.system}),fits=e=>evaluateThreshold(e,t,`estimate`).type===`within-limit`,C=withResumptionGuard([...checkpointHead(S),...b],m,t.threshold);if(fits(C))return C;let w=keepNonToolResultMessages(b),T=withResumptionGuard([...checkpointHead(S),...w],m,t.threshold);if(fits(T))return T;let E=withResumptionGuard(checkpointHead(S),m,t.threshold);if(fits(E))return E;let withClippedSummary=e=>{let build=n=>withResumptionGuard(checkpointHead(n<MIN_CLIP_CHARS?sliceUtf16Safe(S,n):clipMiddleUtf16Safe(S,n)),e,t.threshold);if(!fits(build(0)))return;let n=0,r=S.length;for(;n<r;){let e=Math.ceil((n+r)/2);fits(build(e))?n=e:r=e-1}return build(n)},D=withClippedSummary(m);if(D!==void 0)return D;let O=t.threshold-estimateTokens(withResumptionGuard(checkpointHead(``),void 0,t.threshold)),k=withClippedSummary(g===void 0?void 0:fitCurrentMessage(g,O)?.replay??g);if(k===void 0)throw new CompactionOverLimitError(`The agent's system prompt, tools and memory leave only ~${t.threshold} tokens for the conversation, too few to compact it.`);return k}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=serializeToolResultOutput(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.]
|
|
2
2
|
|
|
3
|
-
${clipMiddleUtf16Safe(r,TRANSCRIPT_PAYLOAD_LIMIT-113)}`}})});return t?{...e,content:n}:e})}function withResumptionGuard(e,t,n){let r=e.at(-1)?.role,i=
|
|
3
|
+
${clipMiddleUtf16Safe(r,TRANSCRIPT_PAYLOAD_LIMIT-113)}`}})});return t?{...e,content:n}:e})}function withResumptionGuard(e,t,n){let r=e.at(-1)?.role,i=t!==void 0&&e.some(e=>e.role===`user`&&e.content===t.content);return r!==void 0&&r!==`assistant`?r===`tool`&&t!==void 0&&!i&&estimateTokens([t])<=n?[...e,t]:e:[...e,t!==void 0&&!i?t:createFrameworkUserMessage(`execution.continuation`,COMPACTION_RESUMPTION_MESSAGE)]}function fitCurrentMessage(e,t){let n=messageText(e);if(n===void 0||t<=0||estimateTokens([e])<=t)return;let note=e=>`\n\n[eve: ${e} characters from the middle of this message were cut during context compaction to fit the context window.]\n\n`,split=(t,n)=>splitMessageText(e,t,n,note(n-t)),r=Math.floor(t*4);for(;r>0;){r=Math.min(r,n.length);let e=Math.floor(r*.2),i=sliceUtf16Safe(n,e).length,a=n.length-(r-e),o=n.charCodeAt(a);if(o>=56320&&o<=57343&&(a+=1),i<a){let e=split(i,a);if(estimateTokens([e.replay])<=t)return e}r=Math.floor(r*.9)-1}return split(0,n.length)}const MIN_CLIP_CHARS=40;function checkpointHead(e){return[createFrameworkUserMessage(`context.compaction`,COMPACTION_CHECKPOINT_MARKER),{content:e,role:`assistant`}]}function omitFiles(e){if(typeof e.content==`string`)return e;let t=[],n=!1;for(let r of e.content)r.type===`text`?t.push(r):n||(n=!0,t.push({type:`text`,text:`[eve: a file in this message was omitted during context compaction: it is too large for the context window.]`}));return n?{...e,content:t}:e}function messageText(e){if(typeof e.content==`string`)return e.content;let t=e.content.flatMap(e=>e.type===`text`?[e.text]:[]);return t.length===0?void 0:t.join(``)}function splitMessageText(e,t,n,r){if(typeof e.content==`string`)return{cut:{...e,content:e.content.slice(t,n)},replay:{...e,content:`${e.content.slice(0,t)}${r}${e.content.slice(n)}`}};let i=0,a=!1,o=[],s=[];for(let c of e.content){if(c.type!==`text`){o.push(c),s.push(c);continue}let e=Math.max(0,Math.min(c.text.length,t-i)),l=Math.max(e,Math.min(c.text.length,n-i));i+=c.text.length,l>e&&o.push({...c,text:c.text.slice(e,l)});let u=c.text.slice(0,e),d=c.text.slice(l),f=l>e&&!a;f&&(a=!0);let p=`${u}${f?r:``}${d}`;p.length>0&&s.push({...c,text:p})}return a||s.push({type:`text`,text:r}),{cut:{...e,content:o},replay:{...e,content:s}}}function findLastRealUserIndex(e){for(let t=e.length-1;t>=0;--t){let n=e[t];if(n?.role===`user`&&!isFrameworkUserMessage(n))return t}return-1}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 keptTailBudget(e){return Math.min(2e4,Math.floor(e.threshold/2))}function selectRecentWindowSize(e,t,n){let r=Math.min(t.recentWindowSize,Math.max(e.length-1,0)),i=0,a=0;for(let t=e.length-1;t>=0&&i<r;--t){let r=e[t];if(r===void 0)continue;let o=estimateTokens([r]);if(a+o>n)break;a+=o,i+=1}return i}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};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compaction finished and the history is still over the limit. Retrying would
|
|
3
|
+
* summarize the same history again, so the step reports it as a terminal failure.
|
|
4
|
+
*/
|
|
5
|
+
export declare class CompactionOverLimitError extends Error {
|
|
6
|
+
readonly name = "CompactionOverLimitError";
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var CompactionOverLimitError=class extends Error{name=`CompactionOverLimitError`};export{CompactionOverLimitError};
|
|
@@ -7,7 +7,7 @@ Include:
|
|
|
7
7
|
- What remains to be done, with clear next steps
|
|
8
8
|
- Any critical data, examples, or references needed to continue
|
|
9
9
|
|
|
10
|
-
Be concise, structured, and focused on helping the next LLM seamlessly continue the work. Write in the same language as the conversation. Do not continue the conversation, answer its questions, or invent facts. Only output the handoff summary.`,COMPACTION_PROMPT_ENVELOPE={prompt:formatCompactionPrompt({previousCheckpoint:``,transcript:``}),system:COMPACTION_SYSTEM_PROMPT};function createCompactionPrompt(e){let t=e.messages.map(e=>({content:renderCompactionMessageContent(e),role:e.role}));return degradeOversizedTranscript(e,t),{prompt:formatCompactionPrompt({previousCheckpoint:e.previousCheckpoint?.trim()??`(none)`,transcript:formatCompactionTranscript(t)}),system:COMPACTION_SYSTEM_PROMPT}}function degradeOversizedTranscript(e,t){let n=e.transcriptBudgetTokens;if(n===void 0)return;let r=formatCompactionPrompt({previousCheckpoint:e.previousCheckpoint?.trim()??`(none)`,transcript:formatCompactionTranscript(t)}),i=estimateTokens(r)-n;for(let n=0;n<t.length&&i>0;n+=1){let r=t[n],a=e.messages[n];if(r===void 0||a===void 0)continue;let o=renderCompactionMessageContent(a,2e3);o.length>=r.content.length||(i-=(Buffer.byteLength(r.content)-Buffer.byteLength(o))/4,t[n]={content:o,role:r.role})}}function formatCompactionPrompt(e){return`<previous-checkpoint>
|
|
10
|
+
Be concise, structured, and focused on helping the next LLM seamlessly continue the work. Write in the same language as the conversation. Do not continue the conversation, answer its questions, or invent facts. Only output the handoff summary.`,COMPACTION_PROMPT_ENVELOPE={prompt:formatCompactionPrompt({previousCheckpoint:``,transcript:``}),system:COMPACTION_SYSTEM_PROMPT};function createCompactionPrompt(e){let t=e.messages.map(e=>({content:renderCompactionMessageContent(e),role:e.role}));return degradeOversizedTranscript(e,t),{prompt:formatCompactionPrompt({previousCheckpoint:e.previousCheckpoint?.trim()??`(none)`,transcript:formatCompactionTranscript(t)}),system:COMPACTION_SYSTEM_PROMPT}}function degradeOversizedTranscript(e,t){let n=e.transcriptBudgetTokens;if(n===void 0)return;let r=formatCompactionPrompt({previousCheckpoint:e.previousCheckpoint?.trim()??`(none)`,transcript:formatCompactionTranscript(t)}),i=estimateTokens(r)-n;for(let n=0;n<t.length&&i>0;n+=1){let r=t[n],a=e.messages[n];if(r===void 0||a===void 0)continue;let o=renderCompactionMessageContent(a,Math.max(2e3,r.content.length-Math.ceil(i*4)-64));o.length>=r.content.length||(i-=(Buffer.byteLength(r.content)-Buffer.byteLength(o))/4,t[n]={content:o,role:r.role})}}function formatCompactionPrompt(e){return`<previous-checkpoint>
|
|
11
11
|
${e.previousCheckpoint}
|
|
12
12
|
</previous-checkpoint>
|
|
13
13
|
|
|
@@ -6,6 +6,15 @@ import type { Publish } from "#harness/session-machine/commit.js";
|
|
|
6
6
|
import type { SessionAuthContext } from "#channel/types.js";
|
|
7
7
|
import type { Step } from "#harness/step/context.js";
|
|
8
8
|
import { type TurnPosition } from "#harness/session-machine/view.js";
|
|
9
|
+
/**
|
|
10
|
+
* Throws when the fixed part of the request (instructions, tools, memory)
|
|
11
|
+
* leaves no room for any history: compacting the history cannot help then.
|
|
12
|
+
*/
|
|
13
|
+
export declare function assertFixedPartFits(input: {
|
|
14
|
+
readonly protectedTokens: number;
|
|
15
|
+
readonly requestEnvelopeTokens: number;
|
|
16
|
+
readonly threshold: number;
|
|
17
|
+
}): void;
|
|
9
18
|
/**
|
|
10
19
|
* Processes the step result: extracts input requests, decides whether to
|
|
11
20
|
* park, continue the tool loop, or terminate.
|