experimental-ash 0.63.0 → 0.64.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/docs/public/advanced/auth-and-route-protection.mdx +26 -20
- package/dist/docs/public/channels/ash.mdx +5 -1
- package/dist/src/chunks/{use-ash-agent-CRWVA4i-.js → use-ash-agent-D7LvOfgD.js} +13 -7
- package/dist/src/chunks/{use-ash-agent-BQJLh7KU.js → use-ash-agent-DPYNpc07.js} +13 -7
- package/dist/src/cli/dev/tui/runner.d.ts +6 -0
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/client/client-error.js +1 -1
- package/dist/src/execution/durable-session-migrations/chain.d.ts +7 -0
- package/dist/src/execution/durable-session-migrations/chain.js +1 -1
- package/dist/src/execution/durable-session-migrations/turn-workflow-v0-to-v1.d.ts +12 -0
- package/dist/src/execution/durable-session-migrations/turn-workflow-v0-to-v1.js +1 -0
- package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +40 -0
- package/dist/src/execution/durable-session-migrations/turn-workflow.js +1 -0
- package/dist/src/execution/sandbox/prewarm.d.ts +1 -0
- package/dist/src/execution/sandbox/prewarm.js +1 -1
- package/dist/src/execution/turn-workflow.d.ts +3 -13
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-steps.d.ts +5 -11
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-artifacts.d.ts +32 -0
- package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -0
- package/dist/src/internal/nitro/host/artifacts-config.js +1 -1
- package/dist/src/internal/nitro/host/configure-nitro-routes.js +3 -3
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
- package/dist/src/internal/nitro/host/prepare-application-host.d.ts +3 -1
- package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
- package/dist/src/internal/nitro/host/start-development-server.js +1 -1
- package/dist/src/internal/nitro/routes/dev-runtime-artifacts.d.ts +10 -0
- package/dist/src/internal/nitro/routes/dev-runtime-artifacts.js +1 -0
- package/dist/src/internal/nitro/routes/runtime-artifacts.d.ts +1 -0
- package/dist/src/internal/nitro/routes/runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/routes/schedule-task.js +1 -1
- package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
- package/dist/src/packages/ash-scaffold/src/web-template.js +5 -16
- package/dist/src/protocol/routes.d.ts +9 -0
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/ash.js +1 -1
- package/dist/src/public/channels/auth.d.ts +45 -3
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/public/channels/slack/inbound.d.ts +3 -1
- package/dist/src/public/channels/slack/inbound.js +1 -1
- package/dist/src/services/dev-client.d.ts +27 -0
- package/dist/src/services/dev-client.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-ash-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-ash-agent.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# experimental-ash
|
|
2
2
|
|
|
3
|
+
## 0.64.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e3a310f: Keep active `ash dev` sessions on immutable runtime artifact snapshots while authored-source HMR publishes fresh snapshots for new prompts. Local dev clients and the `ash dev` TUI now reset stale waiting sessions after HMR so updated tools are used on the next normal message, while pending input-response resumes stay on the original snapshot.
|
|
8
|
+
- c985ea7: Set `x-accel-buffering: no` and `cache-control: no-transform` on the Ash event-stream response so buffering reverse proxies — notably the Vercel sandbox / v0 preview edge — flush events to the browser incrementally instead of withholding the whole stream until it closes. Without this, the Web Chat reply never appeared in v0 previews: the stream stayed pending until a proxy timeout fired.
|
|
9
|
+
- 2eca642: Version turn workflow run inputs: new turn starts carry the current versioned wire shape, and unversioned inputs written by older deployments are migrated into it so in-flight turns survive a rollout.
|
|
10
|
+
|
|
11
|
+
## 0.64.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 76d7a1f: Add `placeholderAuth()` for scaffolded Web Chat channels so production requests return a structured 401 when app auth has not been configured. Generated apps now show setup guidance instead of an internal channel failure, and `ClientError` surfaces structured Ash error messages directly.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 030c0d1: Fix Slack direct messages dropping file uploads. `onDirectMessage` now receives `file_share` messages with their attachments intact, matching the existing `onAppMention` behavior; system subtypes (edits, deletes, joins) and bot-authored echoes are still filtered.
|
|
20
|
+
|
|
3
21
|
## 0.63.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
|
@@ -18,13 +18,13 @@ These settings apply to:
|
|
|
18
18
|
- `POST /ash/v1/session/:sessionId`
|
|
19
19
|
- `GET /ash/v1/session/:sessionId/stream`
|
|
20
20
|
|
|
21
|
-
<CopyPrompt text="Protect the user's Ash HTTP routes through the channel layer. In Ash, route auth and IP policy live on channel factories, usually agent/channels/ash.ts with ashChannel auth config, not in agent.ts. Inspect the existing channel file and app auth code, replace any generated
|
|
21
|
+
<CopyPrompt text="Protect the user's Ash HTTP routes through the channel layer. In Ash, route auth and IP policy live on channel factories, usually agent/channels/ash.ts with ashChannel auth config, not in agent.ts. Inspect the existing channel file and app auth code, replace any generated placeholderAuth guardrail with the smallest AuthFn or helper composition, use helpers such as localDev, vercelOidc, none, httpBasic, jwtHmac, jwtEcdsa, or oidc as appropriate, keep secrets in environment variables, preserve localDev and vercelOidc behavior where useful, verify unauthenticated production browser requests are rejected with 401, and do not commit unless the user asks.">
|
|
22
22
|
Protect the user's Ash HTTP routes through the channel layer. In Ash, route auth and IP policy
|
|
23
23
|
live on channel factories, usually agent/channels/ash.ts with ashChannel auth config, not in
|
|
24
24
|
agent.ts. Inspect the existing channel file and app auth code, replace any generated
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
placeholderAuth guardrail with the smallest AuthFn or helper composition, use helpers such as
|
|
26
|
+
localDev, vercelOidc, none, httpBasic, jwtHmac, jwtEcdsa, or oidc as appropriate, keep secrets in
|
|
27
|
+
environment variables, preserve localDev and vercelOidc behavior where useful, verify
|
|
28
28
|
unauthenticated production browser requests are rejected with 401, and do not commit unless the
|
|
29
29
|
user asks.
|
|
30
30
|
</CopyPrompt>
|
|
@@ -32,31 +32,24 @@ These settings apply to:
|
|
|
32
32
|
## Generated Web Chat Auth
|
|
33
33
|
|
|
34
34
|
`pnpm create experimental-ash-agent` scaffolds `agent/channels/ash.ts` from the Web Chat example.
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
It permits Vercel OIDC and localhost requests, but it will not allow browser requests in
|
|
36
|
+
production until you replace the placeholder with your app's auth:
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
39
|
// agent/channels/ash.ts
|
|
40
40
|
import { ashChannel } from "experimental-ash/channels/ash";
|
|
41
|
-
import {
|
|
42
|
-
|
|
43
|
-
function exampleProductionAuth(): AuthFn<Request> {
|
|
44
|
-
return () => {
|
|
45
|
-
if (process.env.VERCEL_ENV === "production") {
|
|
46
|
-
throw new Error("Configure production auth in agent/channels/ash.ts.");
|
|
47
|
-
}
|
|
48
|
-
return null;
|
|
49
|
-
};
|
|
50
|
-
}
|
|
41
|
+
import { localDev, placeholderAuth, vercelOidc } from "experimental-ash/channels/auth";
|
|
51
42
|
|
|
52
43
|
export default ashChannel({
|
|
53
|
-
auth: [
|
|
44
|
+
auth: [localDev(), vercelOidc(), placeholderAuth()],
|
|
54
45
|
});
|
|
55
46
|
```
|
|
56
47
|
|
|
57
|
-
Replace `
|
|
58
|
-
|
|
59
|
-
|
|
48
|
+
Replace `placeholderAuth()` before a browser user submits a production request. It returns a
|
|
49
|
+
structured 401 in production so generated Web Chat apps can explain that auth is not configured
|
|
50
|
+
instead of showing an internal channel error. If you delete the authored file, Ash falls back to
|
|
51
|
+
its framework default `[localDev(), vercelOidc()]`; that default also does not accept browser
|
|
52
|
+
traffic in production.
|
|
60
53
|
|
|
61
54
|
## Walking The Auth Array
|
|
62
55
|
|
|
@@ -68,6 +61,19 @@ that default also does not accept browser-user traffic in production.
|
|
|
68
61
|
If every entry skips, the request is rejected with `401`. An empty array `auth: []` therefore
|
|
69
62
|
rejects every request.
|
|
70
63
|
|
|
64
|
+
To reject with a specific `401`, throw an `UnauthenticatedError`. To reject with a specific `403`,
|
|
65
|
+
throw a `ForbiddenError`. `routeAuth` turns those errors into HTTP responses; other thrown errors
|
|
66
|
+
still use the normal channel failure path.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { UnauthenticatedError } from "experimental-ash/channels/auth";
|
|
70
|
+
|
|
71
|
+
throw new UnauthenticatedError({
|
|
72
|
+
code: "authentication_required",
|
|
73
|
+
message: "Sign in to continue.",
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
71
77
|
To accept anonymous traffic, include `none()` as the final entry:
|
|
72
78
|
|
|
73
79
|
```ts
|
|
@@ -58,7 +58,11 @@ wire the Ash channel to your app's auth system, such as Clerk, Auth.js, or your
|
|
|
58
58
|
verification.
|
|
59
59
|
|
|
60
60
|
`pnpm create experimental-ash-agent` scaffolds an example `agent/channels/ash.ts` with a production
|
|
61
|
-
auth placeholder so you can replace it before exposing the API to real users.
|
|
61
|
+
auth placeholder so you can replace it before exposing the API to real users. The generated channel
|
|
62
|
+
permits Vercel OIDC and localhost requests and includes `placeholderAuth()`, which returns a
|
|
63
|
+
setup-focused 401 in production until you replace it with your app's auth. If you delete the
|
|
64
|
+
authored file, Ash falls back to `[localDev(), vercelOidc()]`; that default does not admit browser
|
|
65
|
+
users in production.
|
|
62
66
|
|
|
63
67
|
For the full auth model and helper list, see
|
|
64
68
|
[Auth and Route Protection](/docs/auth-and-route-protection).
|
|
@@ -8,6 +8,7 @@ const ASH_CREATE_SESSION_ROUTE_PATH = `${ASH_ROUTE_PREFIX}/session`;
|
|
|
8
8
|
const ASH_CONTINUE_SESSION_ROUTE_PATTERN = `${ASH_ROUTE_PREFIX}/session/:sessionId`;
|
|
9
9
|
const ASH_MESSAGE_STREAM_ROUTE_PATTERN = `${ASH_ROUTE_PREFIX}/session/:sessionId/stream`;
|
|
10
10
|
const ASH_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN = `${ASH_ROUTE_PREFIX}/dev/schedules/:scheduleId`;
|
|
11
|
+
const ASH_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH = `${ASH_ROUTE_PREFIX}/dev/runtime-artifacts`;
|
|
11
12
|
const ASH_CONNECTION_CALLBACK_ROUTE_PATTERN = `${ASH_ROUTE_PREFIX}/connections/:name/callback/:token`;
|
|
12
13
|
const ASH_CALLBACK_ROUTE_PATTERN = `${ASH_ROUTE_PREFIX}/callback/:token`;
|
|
13
14
|
function createAshMessageStreamRoutePath(sessionId) {
|
|
@@ -17,13 +18,24 @@ function createAshContinueSessionRoutePath(sessionId) {
|
|
|
17
18
|
return `${ASH_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}`;
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/shared/guards.ts
|
|
23
|
+
function isObject(value) {
|
|
24
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
//#endregion
|
|
21
28
|
//#region src/client/client-error.ts
|
|
22
29
|
var ClientError = class extends Error {
|
|
23
30
|
status;
|
|
24
31
|
body;
|
|
25
32
|
constructor(status, body) {
|
|
26
|
-
|
|
33
|
+
let message = body || `Server returned ${status}.`;
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(body);
|
|
36
|
+
if (isObject(parsed) && typeof parsed.error === "string") message = parsed.error;
|
|
37
|
+
} catch {}
|
|
38
|
+
super(message);
|
|
27
39
|
this.name = "ClientError";
|
|
28
40
|
this.status = status;
|
|
29
41
|
this.body = body;
|
|
@@ -471,12 +483,6 @@ function encodeBasicCredentials(username, password) {
|
|
|
471
483
|
return btoa(binaryString);
|
|
472
484
|
}
|
|
473
485
|
|
|
474
|
-
//#endregion
|
|
475
|
-
//#region src/shared/guards.ts
|
|
476
|
-
function isObject(value) {
|
|
477
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
486
|
//#endregion
|
|
481
487
|
//#region src/shared/errors.ts
|
|
482
488
|
function toErrorMessage(error) {
|
|
@@ -8,6 +8,7 @@ const ASH_CREATE_SESSION_ROUTE_PATH = `${ASH_ROUTE_PREFIX}/session`;
|
|
|
8
8
|
const ASH_CONTINUE_SESSION_ROUTE_PATTERN = `${ASH_ROUTE_PREFIX}/session/:sessionId`;
|
|
9
9
|
const ASH_MESSAGE_STREAM_ROUTE_PATTERN = `${ASH_ROUTE_PREFIX}/session/:sessionId/stream`;
|
|
10
10
|
const ASH_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN = `${ASH_ROUTE_PREFIX}/dev/schedules/:scheduleId`;
|
|
11
|
+
const ASH_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH = `${ASH_ROUTE_PREFIX}/dev/runtime-artifacts`;
|
|
11
12
|
const ASH_CONNECTION_CALLBACK_ROUTE_PATTERN = `${ASH_ROUTE_PREFIX}/connections/:name/callback/:token`;
|
|
12
13
|
const ASH_CALLBACK_ROUTE_PATTERN = `${ASH_ROUTE_PREFIX}/callback/:token`;
|
|
13
14
|
function createAshMessageStreamRoutePath(sessionId) {
|
|
@@ -17,13 +18,24 @@ function createAshContinueSessionRoutePath(sessionId) {
|
|
|
17
18
|
return `${ASH_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}`;
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/shared/guards.ts
|
|
23
|
+
function isObject(value) {
|
|
24
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
//#endregion
|
|
21
28
|
//#region src/client/client-error.ts
|
|
22
29
|
var ClientError = class extends Error {
|
|
23
30
|
status;
|
|
24
31
|
body;
|
|
25
32
|
constructor(status, body) {
|
|
26
|
-
|
|
33
|
+
let message = body || `Server returned ${status}.`;
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(body);
|
|
36
|
+
if (isObject(parsed) && typeof parsed.error === "string") message = parsed.error;
|
|
37
|
+
} catch {}
|
|
38
|
+
super(message);
|
|
27
39
|
this.name = "ClientError";
|
|
28
40
|
this.status = status;
|
|
29
41
|
this.body = body;
|
|
@@ -471,12 +483,6 @@ function encodeBasicCredentials(username, password) {
|
|
|
471
483
|
return btoa(binaryString);
|
|
472
484
|
}
|
|
473
485
|
|
|
474
|
-
//#endregion
|
|
475
|
-
//#region src/shared/guards.ts
|
|
476
|
-
function isObject(value) {
|
|
477
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
486
|
//#endregion
|
|
481
487
|
//#region src/shared/errors.ts
|
|
482
488
|
function toErrorMessage(error) {
|
|
@@ -126,6 +126,12 @@ export type AshTUIRunnerOptions = TuiDisplayOptions & {
|
|
|
126
126
|
* a richer formatter here.
|
|
127
127
|
*/
|
|
128
128
|
formatTransportError?: (error: unknown) => string;
|
|
129
|
+
/**
|
|
130
|
+
* Local `ash dev` server URL. When present, normal prompts refresh the
|
|
131
|
+
* active session after HMR so the next prompt uses the latest authored
|
|
132
|
+
* artifacts; input-response resumes keep the current session.
|
|
133
|
+
*/
|
|
134
|
+
serverUrl?: string;
|
|
129
135
|
};
|
|
130
136
|
export declare class AshTUIRunner {
|
|
131
137
|
#private;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{TerminalRenderer}from"./terminal-renderer.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{getToolName,isToolUIPart}from"ai";var AshTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d=new Map;#f=new Map;#p=new Map;#m=new Map;#h=new Set;constructor(e){this.#e=e.session,e.client!==void 0&&(this.#t=e.client),this.#n=createRenderer(e)??createDefaultRenderer(e),this.#r=e.name??`Ash`,this.#i=e.tools??`full`,this.#a=e.reasoning??`full`,this.#o=e.subagents??`full`,this.#s=e.connectionAuth??`full`,this.#c=e.assistantResponseStats??`tokensPerSecond`,this.#l=e.contextSize,this.#u=e.formatTransportError??formatErrorMessage}async run(){let e=this.#r,t=[],n=0,generateMessageId=()=>`message-${++n}`,r,i,a=!1,o=!1;for(;;){if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}try{r=await this.#n.readPrompt({title:e})}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let s=parsePromptCommand(r);if(s===`exit`){this.#n.shutdown?.();return}if(s===`new`){this.#g(),t.length=0,n=0,i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}t.push(createUserMessage(generateMessageId(),r)),a=!0}let s=await this.#_({prompt:o?void 0:r,inputResponses:i,messages:t,generateMessageId});try{let n=await this.#n.renderStream(s,{title:e,submittedPrompt:r,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l,waitForExit:!1});if(n&&n.parts.length>0){let a=findPendingToolApprovalRequests(n),s=findPendingQuestionRequests(this.#d);if(a.length>0||s.length>0){let c=[];if(a.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let t of a){let r=await this.#n.readToolApproval(t,{title:e});applyToolApprovalResponse(n,t,r);let i=this.#d.get(t.approvalId);i&&(c.push({requestId:i.requestId,optionId:r.approved?`approve`:`deny`}),this.#d.delete(t.approvalId))}}if(s.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of s){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),c.push(i),this.#d.delete(t.requestId)}}upsertResponseMessage(t,n,o),o=!0,i=c,r=void 0;continue}upsertResponseMessage(t,n,o)}}catch(e){if(isInterruptedError(e))return;throw e}o=!1,i=void 0,r=void 0}}#g(){for(let e of this.#p.values())e.abort();this.#p.clear(),this.#f.clear(),this.#d.clear(),this.#m.clear(),this.#h.clear(),this.#t&&(this.#e=this.#t.session())}async#_(e){let t={};e.prompt!==void 0&&(t.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(t.inputResponses=e.inputResponses);let n;try{n=await this.#e.send(t)}catch(t){if(isInterruptedError(t))throw t;return{uiMessageStream:errorOnlyUIMessageStream({errorText:this.#u(t),generateMessageId:e.generateMessageId,originalMessages:e.messages}),message:lastAssistantMessage(e.messages)}}return{uiMessageStream:ashEventsToUIMessageStream({events:n,generateMessageId:e.generateMessageId,originalMessages:e.messages,pendingInputRequests:this.#d,subagentRuns:this.#f,onSubagentCalled:e=>this.#x(e),onSubagentCompleted:e=>this.#C(e),onConnectionAuthRequired:e=>this.#v(e),onConnectionAuthCompleted:e=>this.#y(e)}),message:lastAssistantMessage(e.messages)}}#v(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#m.set(e.data.name,t),this.#b(t)}#y(e){let t=this.#m.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#m.set(e.data.name,t),this.#h.delete(e.data.name),this.#b(t),this.#n.setConnectionAuthPendingCount?.(this.#h.size)}#b(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}#x(e){let n=e.data.callId;if(this.#p.has(n))return;let r=this.#t;if(!r)return;let i=new AbortController;this.#p.set(n,i),(async()=>{try{let a=r.session({sessionId:e.data.childSessionId,streamIndex:0}).openStream({signal:i.signal});for await(let e of a)if(i.signal.aborted||(this.#w(n,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let t=formatErrorMessage(e),r=this.#f.get(n);if(r){let{key:e,step:i}=openCurrentSubagentSection(r);i.message=i.message?`${i.message}\n\nstream error: ${t}`:`stream error: ${t}`,i.finalized=!0,r.currentSectionKey=null,this.#n.upsertSubagentStep?.({callId:n,subagentName:r.name,sectionKey:e,reasoning:i.reasoning,message:i.message,finalized:!0})}}}finally{this.#p.delete(n)}})()}#S(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={"approval-requested":0,executing:1,done:2,failed:2};e[n.status]>e[r.status]&&(r.status=n.status),r.input=n.input}else t.tools.set(n.childCallId,i);this.#n.markChildToolCallId?.(n.childCallId),this.#n.upsertSubagentTool?.({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#C(e){let t=this.#f.get(e);if(t){for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#n.upsertSubagentStep?.({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null}}#w(e,t){let n=this.#f.get(e);if(!n)return;let r=this.#n,emit=(t,i)=>{r.upsertSubagentStep?.({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent();break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#S(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#S(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;t.data.status===`failed`?(a.status=`failed`,a.errorText=formatActionResultError(t)):(a.status=`done`,a.output=i.output);let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r.upsertSubagentTool?.(o);break}default:break}}};function createDefaultRenderer(t){return t.tools===void 0&&t.reasoning===void 0&&t.subagents===void 0&&t.connectionAuth===void 0&&t.assistantResponseStats===void 0&&t.contextSize===void 0&&t.logs===void 0?new TerminalRenderer:new TerminalRenderer({tools:t.tools,reasoning:t.reasoning,subagents:t.subagents,connectionAuth:t.connectionAuth,assistantResponseStats:t.assistantResponseStats,contextSize:t.contextSize,logs:t.logs})}function createRenderer(t){if(t.renderer)return t.renderer;if(!(!t.screen&&!t.userInput))return new TerminalRenderer({tools:t.tools,reasoning:t.reasoning,subagents:t.subagents,connectionAuth:t.connectionAuth,assistantResponseStats:t.assistantResponseStats,contextSize:t.contextSize,logs:t.logs,input:t.userInput,output:t.screen})}async function*ashEventsToUIMessageStream(e){let{events:t,generateMessageId:n,originalMessages:r,pendingInputRequests:i,subagentRuns:a,onSubagentCalled:o,onSubagentCompleted:s,onConnectionAuthRequired:c,onConnectionAuthCompleted:l}=e,u=new Set,d=new Set,f=new Set,p=!1,m=!1,h,ensureStart=()=>{if(!p)return p=!0,{type:`start`,messageId:lastAssistantMessage(r)?.id??n()}};for await(let e of t){let t=ensureStart();switch(t&&(yield t),e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:yield{type:`start-step`};break;case`step.completed`:h=e.data.usage,yield*closeOpenTextParts(u),yield*closeOpenReasoningParts(d),yield{type:`finish-step`};break;case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex);u.has(n)||(u.add(n),yield{type:`text-start`,id:n}),yield{type:`text-delta`,id:n,delta:t.data.messageDelta};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex);u.delete(t)&&(yield{type:`text-end`,id:t});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex);d.has(n)||(d.add(n),yield{type:`reasoning-start`,id:n}),yield{type:`reasoning-delta`,id:n,delta:t.data.reasoningDelta};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex);d.delete(t)&&(yield{type:`reasoning-end`,id:t});break}case`actions.requested`:{let t=e.data.actions;for(let e of t)e.kind===`tool-call`&&(f.add(e.callId),yield{type:`tool-input-available`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests;for(let e of t){if(e.action.kind!==`tool-call`)continue;let t=e.action.callId;f.has(t)||(f.add(t),yield{type:`tool-input-available`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),i.set(e.requestId,e),!isQuestionRequest(e)&&(yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t})}break}case`action.result`:{let t=e,n=t.data.result.callId;if(!f.has(n))break;t.data.status===`failed`?yield{type:`tool-output-error`,toolCallId:n,errorText:formatActionResultError(t)}:yield{type:`tool-output-available`,toolCallId:n,output:t.data.result.output};break}case`step.failed`:case`turn.failed`:case`session.failed`:yield{type:`error`,errorText:formatFailureMessage(e)};break;case`session.waiting`:case`session.completed`:case`turn.completed`:yield*closeOpenTextParts(u),yield*closeOpenReasoningParts(d),yield{type:`finish`,messageMetadata:createResponseMetadata(h)},m=!0;break;case`subagent.called`:{let t=e;if(!a.has(t.data.callId))a.set(t.data.callId,{name:t.data.name,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map});else{let e=a.get(t.data.callId);e&&(e.name=t.data.name)}o?.(t);break}case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:s?.(e.data.callId);break;case`authorization.required`:c?.(e);break;case`authorization.completed`:l?.(e);break;default:break}}p||(yield{type:`start`,messageId:n()}),m||(yield*closeOpenTextParts(u),yield*closeOpenReasoningParts(d),yield{type:`finish`,messageMetadata:createResponseMetadata(h)})}async function*errorOnlyUIMessageStream(e){yield{type:`start`,messageId:lastAssistantMessage(e.originalMessages)?.id??e.generateMessageId()},yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function*closeOpenTextParts(e){for(let t of e)yield{type:`text-end`,id:t};e.clear()}function*closeOpenReasoningParts(e){for(let t of e)yield{type:`reasoning-end`,id:t};e.clear()}function createResponseMetadata(e){if(!e)return;let{inputTokens:t,outputTokens:n}=e,r=t!=null||n!=null?(t??0)+(n??0):void 0;if(r==null&&n==null)return;let i={};return r!=null&&(i.totalTokens=r),n!=null&&(i.outputTokens=n),{usage:i}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function formatFailureMessage(e){let{code:t,message:n}=e.data;return t?`${t}: ${n}`:n}function createUserMessage(e,t){return{id:e,role:`user`,parts:[{type:`text`,text:t}]}}function upsertResponseMessage(e,t,n){if(n&&e.at(-1)?.role===`assistant`){e[e.length-1]=t;return}e.push(t)}function lastAssistantMessage(e){let t=e.at(-1);return t?.role===`assistant`?t:void 0}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function findPendingQuestionRequests(e){let t=[];for(let n of e.values())isQuestionRequest(n)&&t.push(n);return t}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}function findPendingToolApprovalRequests(e){let t=[];for(let[i,a]of e.parts.entries()){if(!isToolUIPart(a)||a.state!==`approval-requested`||a.approval.isAutomatic===!0)continue;let o={approvalId:a.approval.id,toolCallId:a.toolCallId,toolName:getToolName(a),input:a.input,messageId:e.id,partIndex:i};a.title!==void 0&&(o.title=a.title),a.providerExecuted!==void 0&&(o.providerExecuted=a.providerExecuted),t.push(o)}return t}function applyToolApprovalResponse(e,t,n){let i=e.parts[t.partIndex];if(!i||!isToolUIPart(i)||i.toolCallId!==t.toolCallId)throw Error(`Could not find tool approval request ${t.approvalId}.`);i.state=`approval-responded`;let a={id:t.approvalId,approved:n.approved};n.reason&&(a.reason=n.reason),i.approval=a}function isInterruptedError(e){return e instanceof Error&&e.message===`Interrupted`}function parsePromptCommand(e){let t=e.trim();return t===`/new`?`new`:t===`/exit`||t===`/quit`?`exit`:null}function isAbortLikeError(e){return!!(e instanceof Error&&(e.name===`AbortError`||e.message.toLowerCase().includes(`abort`)))}function formatErrorMessage(e){if(e instanceof Error)return e.message;if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{AshTUIRunner};
|
|
1
|
+
import{TerminalRenderer}from"./terminal-renderer.js";import{createDevelopmentRuntimeArtifactSessionRefresher}from"#services/dev-client.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{getToolName,isToolUIPart}from"ai";var AshTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f=new Map;#p=new Map;#m=new Map;#h=new Map;#g=new Set;constructor(e){this.#e=e.session,e.client!==void 0&&(this.#t=e.client),this.#n=createRenderer(e)??createDefaultRenderer(e),this.#r=e.name??`Ash`,this.#i=e.tools??`full`,this.#a=e.reasoning??`full`,this.#o=e.subagents??`full`,this.#s=e.connectionAuth??`full`,this.#c=e.assistantResponseStats??`tokensPerSecond`,this.#l=e.contextSize,this.#u=e.formatTransportError??formatErrorMessage,e.serverUrl!==void 0&&(this.#d=createDevelopmentRuntimeArtifactSessionRefresher({serverUrl:e.serverUrl}))}async run(){let e=this.#r,t=[],n=0,generateMessageId=()=>`message-${++n}`,r,i,a=!1,o=!1;for(;;){if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}try{r=await this.#n.readPrompt({title:e})}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let s=parsePromptCommand(r);if(s===`exit`){this.#n.shutdown?.();return}if(s===`new`){this.#_(),t.length=0,n=0,i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}t.push(createUserMessage(generateMessageId(),r)),a=!0}let s=await this.#v({prompt:o?void 0:r,inputResponses:i,messages:t,generateMessageId});try{let n=await this.#n.renderStream(s,{title:e,submittedPrompt:r,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l,waitForExit:!1});if(n&&n.parts.length>0){let a=findPendingToolApprovalRequests(n),s=findPendingQuestionRequests(this.#f);if(a.length>0||s.length>0){let c=[];if(a.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let t of a){let r=await this.#n.readToolApproval(t,{title:e});applyToolApprovalResponse(n,t,r);let i=this.#f.get(t.approvalId);i&&(c.push({requestId:i.requestId,optionId:r.approved?`approve`:`deny`}),this.#f.delete(t.approvalId))}}if(s.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of s){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),c.push(i),this.#f.delete(t.requestId)}}upsertResponseMessage(t,n,o),o=!0,i=c,r=void 0;continue}upsertResponseMessage(t,n,o)}}catch(e){if(isInterruptedError(e))return;throw e}o=!1,i=void 0,r=void 0}}#_(){for(let e of this.#m.values())e.abort();this.#m.clear(),this.#p.clear(),this.#f.clear(),this.#h.clear(),this.#g.clear(),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}async#v(e){let t={};e.prompt!==void 0&&(t.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(t.inputResponses=e.inputResponses);let n;try{let e=this.#t;e!==void 0&&this.#d!==void 0&&(this.#e=await this.#d.refresh({createSession:()=>e.session(),inputResponses:t.inputResponses,message:t.message,session:this.#e})),n=await this.#e.send(t)}catch(t){if(isInterruptedError(t))throw t;return{uiMessageStream:errorOnlyUIMessageStream({errorText:this.#u(t),generateMessageId:e.generateMessageId,originalMessages:e.messages}),message:lastAssistantMessage(e.messages)}}return{uiMessageStream:ashEventsToUIMessageStream({events:n,generateMessageId:e.generateMessageId,originalMessages:e.messages,pendingInputRequests:this.#f,subagentRuns:this.#p,onSubagentCalled:e=>this.#S(e),onSubagentCompleted:e=>this.#w(e),onConnectionAuthRequired:e=>this.#y(e),onConnectionAuthCompleted:e=>this.#b(e)}),message:lastAssistantMessage(e.messages)}}#y(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#h.set(e.data.name,t),this.#x(t)}#b(e){let t=this.#h.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#h.set(e.data.name,t),this.#g.delete(e.data.name),this.#x(t),this.#n.setConnectionAuthPendingCount?.(this.#g.size)}#x(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}#S(e){let t=e.data.callId;if(this.#m.has(t))return;let r=this.#t;if(!r)return;let i=new AbortController;this.#m.set(t,i),(async()=>{try{let a=r.session({sessionId:e.data.childSessionId,streamIndex:0}).openStream({signal:i.signal});for await(let e of a)if(i.signal.aborted||(this.#T(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=formatErrorMessage(e),r=this.#p.get(t);if(r){let{key:e,step:i}=openCurrentSubagentSection(r);i.message=i.message?`${i.message}\n\nstream error: ${n}`:`stream error: ${n}`,i.finalized=!0,r.currentSectionKey=null,this.#n.upsertSubagentStep?.({callId:t,subagentName:r.name,sectionKey:e,reasoning:i.reasoning,message:i.message,finalized:!0})}}}finally{this.#m.delete(t)}})()}#C(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={"approval-requested":0,executing:1,done:2,failed:2};e[n.status]>e[r.status]&&(r.status=n.status),r.input=n.input}else t.tools.set(n.childCallId,i);this.#n.markChildToolCallId?.(n.childCallId),this.#n.upsertSubagentTool?.({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#w(e){let t=this.#p.get(e);if(t){for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#n.upsertSubagentStep?.({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null}}#T(e,t){let n=this.#p.get(e);if(!n)return;let r=this.#n,emit=(t,i)=>{r.upsertSubagentStep?.({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent();break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#C(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#C(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;t.data.status===`failed`?(a.status=`failed`,a.errorText=formatActionResultError(t)):(a.status=`done`,a.output=i.output);let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r.upsertSubagentTool?.(o);break}default:break}}};function createDefaultRenderer(t){return t.tools===void 0&&t.reasoning===void 0&&t.subagents===void 0&&t.connectionAuth===void 0&&t.assistantResponseStats===void 0&&t.contextSize===void 0&&t.logs===void 0?new TerminalRenderer:new TerminalRenderer({tools:t.tools,reasoning:t.reasoning,subagents:t.subagents,connectionAuth:t.connectionAuth,assistantResponseStats:t.assistantResponseStats,contextSize:t.contextSize,logs:t.logs})}function createRenderer(t){if(t.renderer)return t.renderer;if(!(!t.screen&&!t.userInput))return new TerminalRenderer({tools:t.tools,reasoning:t.reasoning,subagents:t.subagents,connectionAuth:t.connectionAuth,assistantResponseStats:t.assistantResponseStats,contextSize:t.contextSize,logs:t.logs,input:t.userInput,output:t.screen})}async function*ashEventsToUIMessageStream(e){let{events:t,generateMessageId:n,originalMessages:r,pendingInputRequests:i,subagentRuns:a,onSubagentCalled:o,onSubagentCompleted:s,onConnectionAuthRequired:c,onConnectionAuthCompleted:l}=e,u=new Set,d=new Set,f=new Set,p=!1,m=!1,h,ensureStart=()=>{if(!p)return p=!0,{type:`start`,messageId:lastAssistantMessage(r)?.id??n()}};for await(let e of t){let t=ensureStart();switch(t&&(yield t),e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:yield{type:`start-step`};break;case`step.completed`:h=e.data.usage,yield*closeOpenTextParts(u),yield*closeOpenReasoningParts(d),yield{type:`finish-step`};break;case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex);u.has(n)||(u.add(n),yield{type:`text-start`,id:n}),yield{type:`text-delta`,id:n,delta:t.data.messageDelta};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex);u.delete(t)&&(yield{type:`text-end`,id:t});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex);d.has(n)||(d.add(n),yield{type:`reasoning-start`,id:n}),yield{type:`reasoning-delta`,id:n,delta:t.data.reasoningDelta};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex);d.delete(t)&&(yield{type:`reasoning-end`,id:t});break}case`actions.requested`:{let t=e.data.actions;for(let e of t)e.kind===`tool-call`&&(f.add(e.callId),yield{type:`tool-input-available`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data.requests;for(let e of t){if(e.action.kind!==`tool-call`)continue;let t=e.action.callId;f.has(t)||(f.add(t),yield{type:`tool-input-available`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),i.set(e.requestId,e),!isQuestionRequest(e)&&(yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t})}break}case`action.result`:{let t=e,n=t.data.result.callId;if(!f.has(n))break;t.data.status===`failed`?yield{type:`tool-output-error`,toolCallId:n,errorText:formatActionResultError(t)}:yield{type:`tool-output-available`,toolCallId:n,output:t.data.result.output};break}case`step.failed`:case`turn.failed`:case`session.failed`:yield{type:`error`,errorText:formatFailureMessage(e)};break;case`session.waiting`:case`session.completed`:case`turn.completed`:yield*closeOpenTextParts(u),yield*closeOpenReasoningParts(d),yield{type:`finish`,messageMetadata:createResponseMetadata(h)},m=!0;break;case`subagent.called`:{let t=e;if(!a.has(t.data.callId))a.set(t.data.callId,{name:t.data.name,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map});else{let e=a.get(t.data.callId);e&&(e.name=t.data.name)}o?.(t);break}case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:s?.(e.data.callId);break;case`authorization.required`:c?.(e);break;case`authorization.completed`:l?.(e);break;default:break}}p||(yield{type:`start`,messageId:n()}),m||(yield*closeOpenTextParts(u),yield*closeOpenReasoningParts(d),yield{type:`finish`,messageMetadata:createResponseMetadata(h)})}async function*errorOnlyUIMessageStream(e){yield{type:`start`,messageId:lastAssistantMessage(e.originalMessages)?.id??e.generateMessageId()},yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function*closeOpenTextParts(e){for(let t of e)yield{type:`text-end`,id:t};e.clear()}function*closeOpenReasoningParts(e){for(let t of e)yield{type:`reasoning-end`,id:t};e.clear()}function createResponseMetadata(e){if(!e)return;let{inputTokens:t,outputTokens:n}=e,r=t!=null||n!=null?(t??0)+(n??0):void 0;if(r==null&&n==null)return;let i={};return r!=null&&(i.totalTokens=r),n!=null&&(i.outputTokens=n),{usage:i}}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function formatFailureMessage(e){let{code:t,message:n}=e.data;return t?`${t}: ${n}`:n}function createUserMessage(e,t){return{id:e,role:`user`,parts:[{type:`text`,text:t}]}}function upsertResponseMessage(e,t,n){if(n&&e.at(-1)?.role===`assistant`){e[e.length-1]=t;return}e.push(t)}function lastAssistantMessage(e){let t=e.at(-1);return t?.role===`assistant`?t:void 0}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function findPendingQuestionRequests(e){let t=[];for(let n of e.values())isQuestionRequest(n)&&t.push(n);return t}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}function findPendingToolApprovalRequests(e){let t=[];for(let[n,a]of e.parts.entries()){if(!isToolUIPart(a)||a.state!==`approval-requested`||a.approval.isAutomatic===!0)continue;let o={approvalId:a.approval.id,toolCallId:a.toolCallId,toolName:getToolName(a),input:a.input,messageId:e.id,partIndex:n};a.title!==void 0&&(o.title=a.title),a.providerExecuted!==void 0&&(o.providerExecuted=a.providerExecuted),t.push(o)}return t}function applyToolApprovalResponse(e,t,n){let r=e.parts[t.partIndex];if(!r||!isToolUIPart(r)||r.toolCallId!==t.toolCallId)throw Error(`Could not find tool approval request ${t.approvalId}.`);r.state=`approval-responded`;let a={id:t.approvalId,approved:n.approved};n.reason&&(a.reason=n.reason),r.approval=a}function isInterruptedError(e){return e instanceof Error&&e.message===`Interrupted`}function parsePromptCommand(e){let t=e.trim();return t===`/new`?`new`:t===`/exit`||t===`/quit`?`exit`:null}function isAbortLikeError(e){return!!(e instanceof Error&&(e.name===`AbortError`||e.message.toLowerCase().includes(`abort`)))}function formatErrorMessage(e){if(e instanceof Error)return e.message;if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return String(e)}}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{AshTUIRunner};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AshTUIRunner}from"./runner.js";import{toErrorMessage}from"#shared/errors.js";import{isLocalDevelopmentServerUrl,resolveDevelopmentClientHeaders,resolveDevelopmentOidcToken}from"#services/dev-client/request-headers.js";import{formatVercelAuthChallengeMessage,isVercelAuthChallenge}from"#services/dev-client/vercel-auth-error.js";import{Client}from"#client/index.js";function resolveDevTuiClientOptions(e){let t={headers:()=>resolveDevelopmentClientHeaders({serverUrl:e}),host:e};return isLocalDevelopmentServerUrl(e)?t:{...t,auth:{bearer:resolveDevelopmentOidcToken}}}async function runDevelopmentTui(n){let{serverUrl:r,...i}=n,a=new Client(resolveDevTuiClientOptions(r));await new AshTUIRunner({...i,session:a.session(),client:a,formatTransportError:e=>isVercelAuthChallenge(e)?formatVercelAuthChallengeMessage({serverUrl:r}):toErrorMessage(e)}).run()}export{resolveDevTuiClientOptions,runDevelopmentTui};
|
|
1
|
+
import{AshTUIRunner}from"./runner.js";import{toErrorMessage}from"#shared/errors.js";import{isLocalDevelopmentServerUrl,resolveDevelopmentClientHeaders,resolveDevelopmentOidcToken}from"#services/dev-client/request-headers.js";import{formatVercelAuthChallengeMessage,isVercelAuthChallenge}from"#services/dev-client/vercel-auth-error.js";import{Client}from"#client/index.js";function resolveDevTuiClientOptions(e){let t={headers:()=>resolveDevelopmentClientHeaders({serverUrl:e}),host:e};return isLocalDevelopmentServerUrl(e)?t:{...t,auth:{bearer:resolveDevelopmentOidcToken}}}async function runDevelopmentTui(n){let{serverUrl:r,...i}=n,a=new Client(resolveDevTuiClientOptions(r));await new AshTUIRunner({...i,session:a.session(),client:a,serverUrl:r,formatTransportError:e=>isVercelAuthChallenge(e)?formatVercelAuthChallengeMessage({serverUrl:r}):toErrorMessage(e)}).run()}export{resolveDevTuiClientOptions,runDevelopmentTui};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var ClientError=class extends Error{status;body;constructor(e,t){
|
|
1
|
+
import{isObject}from"#shared/guards.js";var ClientError=class extends Error{status;body;constructor(e,t){let n=t||`Server returned ${e}.`;try{let e=JSON.parse(t);isObject(e)&&typeof e.error==`string`&&(n=e.error)}catch{}super(n),this.name=`ClientError`,this.status=e,this.body=t}};export{ClientError};
|
|
@@ -28,4 +28,11 @@ export declare function runMigrationChain<TOut extends {
|
|
|
28
28
|
readonly migrations: readonly VersionMigration[];
|
|
29
29
|
readonly targetVersion: number;
|
|
30
30
|
readonly label: string;
|
|
31
|
+
/**
|
|
32
|
+
* Version to read a wire value as when it carries no `version` field —
|
|
33
|
+
* for shapes that predate versioning ("version 0"). Omit to require an
|
|
34
|
+
* explicit numeric `version` (the default). A present but non-numeric
|
|
35
|
+
* `version` is always malformed, opt-in or not.
|
|
36
|
+
*/
|
|
37
|
+
readonly initialVersion?: number;
|
|
31
38
|
}): TOut;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function runMigrationChain(e){if(typeof e.value!=`object`||e.value===null
|
|
1
|
+
function runMigrationChain(e){if(typeof e.value!=`object`||e.value===null)throw Error(`${e.label}: value has no numeric "version" field.`);let t=e.value.version,n;if(typeof t==`number`)n=e.value;else if(!(`version`in e.value)&&e.initialVersion!==void 0)n={...e.value,version:e.initialVersion};else throw Error(`${e.label}: value has no numeric "version" field.`);let r=e.initialVersion??1;if(!Number.isInteger(n.version)||n.version<r)throw Error(`${e.label}: version ${n.version} is not a positive integer.`);if(n.version>e.targetVersion)throw Error(`${e.label}: encountered version ${n.version}, which is newer than the supported version ${e.targetVersion}. This usually indicates the wire was written by a newer Ash deployment than the one reading it.`);for(;n.version<e.targetVersion;){let t=e.migrations.find(e=>e.from===n.version);if(!t)throw Error(`${e.label}: no migration registered for version ${n.version} → ${n.version+1}.`);if(t.to!==t.from+1)throw Error(`${e.label}: migration ${t.from} → ${t.to} must step exactly one version at a time.`);let r=t.migrate(n);if(r.version!==t.to)throw Error(`${e.label}: migration ${t.from} → ${t.to} produced a value with version ${r.version}.`);n=r}return n}export{runMigrationChain};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turn workflow input v0 → v1 migration.
|
|
3
|
+
*
|
|
4
|
+
* Before versioning, the driver wrote a flat, unversioned run input;
|
|
5
|
+
* `runMigrationChain` reads that as version 0 (via its `initialVersion`
|
|
6
|
+
* option) and this lifts the flat shape into the nested v1 input. The
|
|
7
|
+
* reshape is inlined rather than delegating to `createTurnWorkflowInput`,
|
|
8
|
+
* so the historical transform stays frozen as the live dispatch
|
|
9
|
+
* constructor evolves.
|
|
10
|
+
*/
|
|
11
|
+
import type { VersionMigration } from "./chain.js";
|
|
12
|
+
export declare const turnWorkflowInputV0ToV1: VersionMigration;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const turnWorkflowInputV0ToV1={from:0,migrate(e){if(!isPreVersionTurnWorkflowInput(e))throw Error(`turn workflow input: version 0 value is not a recognized pre-version shape.`);return{capabilities:e.capabilities,completionToken:e.completionToken,mode:e.mode,stepInput:{input:e.delivery,parentWritable:e.parentWritable,serializedContext:e.serializedContext,sessionState:e.sessionState},version:1}},to:1};function isPreVersionTurnWorkflowInput(e){return typeof e==`object`&&!!e&&`delivery`in e}export{turnWorkflowInputV0ToV1};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turn workflow input migrations.
|
|
3
|
+
*
|
|
4
|
+
* The driver workflow can stay pinned while per-turn child workflows
|
|
5
|
+
* route to latest, so the child workflow run input is a durable wire
|
|
6
|
+
* shape newer code must read. Inputs written before
|
|
7
|
+
* {@link TURN_WORKFLOW_INPUT_VERSION} carry no `version`; the chain reads
|
|
8
|
+
* them as version 0 and the registered v0 → v1 migration lifts the flat
|
|
9
|
+
* shape into the current input, so a turn dispatched by an older
|
|
10
|
+
* deployment still runs after a rollout. Future shape changes bump
|
|
11
|
+
* {@link TURN_WORKFLOW_INPUT_VERSION} and append a v{N} → v{N+1} migration.
|
|
12
|
+
*/
|
|
13
|
+
import type { HookPayload, SessionCapabilities } from "#channel/types.js";
|
|
14
|
+
import type { DurableSessionState } from "#execution/durable-session-store.js";
|
|
15
|
+
import type { RunMode } from "#shared/run-mode.js";
|
|
16
|
+
export declare const TURN_WORKFLOW_INPUT_VERSION = 1;
|
|
17
|
+
export interface TurnStepInput {
|
|
18
|
+
readonly input: HookPayload | undefined;
|
|
19
|
+
readonly parentWritable: WritableStream<Uint8Array>;
|
|
20
|
+
readonly serializedContext: Record<string, unknown>;
|
|
21
|
+
readonly sessionState: DurableSessionState;
|
|
22
|
+
}
|
|
23
|
+
export interface TurnWorkflowInput {
|
|
24
|
+
readonly version: typeof TURN_WORKFLOW_INPUT_VERSION;
|
|
25
|
+
readonly capabilities: SessionCapabilities | undefined;
|
|
26
|
+
readonly completionToken: string;
|
|
27
|
+
readonly mode: RunMode;
|
|
28
|
+
readonly stepInput: TurnStepInput;
|
|
29
|
+
}
|
|
30
|
+
export interface TurnWorkflowDispatchInput {
|
|
31
|
+
readonly capabilities: SessionCapabilities | undefined;
|
|
32
|
+
readonly completionToken: string;
|
|
33
|
+
readonly delivery: HookPayload;
|
|
34
|
+
readonly mode: RunMode;
|
|
35
|
+
readonly parentWritable: WritableStream<Uint8Array>;
|
|
36
|
+
readonly serializedContext: Record<string, unknown>;
|
|
37
|
+
readonly sessionState: DurableSessionState;
|
|
38
|
+
}
|
|
39
|
+
export declare function createTurnWorkflowInput(input: TurnWorkflowDispatchInput): TurnWorkflowInput;
|
|
40
|
+
export declare function migrateTurnWorkflowInput(value: unknown): TurnWorkflowInput;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{runMigrationChain}from"./chain.js";import{turnWorkflowInputV0ToV1}from"./turn-workflow-v0-to-v1.js";const TURN_WORKFLOW_INPUT_VERSION=1,turnWorkflowInputMigrations=[turnWorkflowInputV0ToV1];function createTurnWorkflowInput(e){return{capabilities:e.capabilities,completionToken:e.completionToken,mode:e.mode,stepInput:{input:e.delivery,parentWritable:e.parentWritable,serializedContext:e.serializedContext,sessionState:e.sessionState},version:1}}function migrateTurnWorkflowInput(t){return runMigrationChain({initialVersion:0,label:`turn workflow input`,migrations:turnWorkflowInputMigrations,targetVersion:1,value:t})}export{TURN_WORKFLOW_INPUT_VERSION,createTurnWorkflowInput,migrateTurnWorkflowInput};
|
|
@@ -38,6 +38,7 @@ export declare function prewarmSandboxes(input: PrewarmSandboxesInput): Promise<
|
|
|
38
38
|
*/
|
|
39
39
|
export declare function prewarmAppSandboxes(input: {
|
|
40
40
|
readonly appRoot: string;
|
|
41
|
+
readonly compiledArtifactsSource?: RuntimeCompiledArtifactsSource;
|
|
41
42
|
readonly loadAgentGraph?: (input: Readonly<{
|
|
42
43
|
compiledArtifactsSource: RuntimeDiskCompiledArtifactsSource;
|
|
43
44
|
}>) => Promise<ResolvedAgentGraphBundle>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{toErrorMessage}from"#shared/errors.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{createBundledRuntimeCompiledArtifactsSource}from"#runtime/compiled-artifacts-source.js";import{createRuntimeSandboxTemplateKey}from"#runtime/sandbox/keys.js";import{createRuntimeSandboxTemplatePlan}from"#runtime/sandbox/template-plan.js";import{loadCompiledModuleMapFromAuthoredSource}from"#internal/authored-module-map-loader.js";import{createAuthoredSourceRuntimeCompiledArtifactsSource}from"#internal/application/runtime-compiled-artifacts-source.js";import{loadCompileMetadata}from"#runtime/loaders/compile-metadata.js";import{withBundledCompiledArtifacts}from"#runtime/loaders/bundled-artifacts.js";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{resolveRuntimeCompilerArtifactPaths}from"#runtime/loaders/artifact-paths.js";import{resolveRuntimeAgentGraph}from"#runtime/resolve-agent-graph.js";import{materializeWorkspaceDirectory}from"#runtime/workspace/seed-files.js";async function prewarmSandboxes(t){let n=await collectPrewarmTargets(t);if(n.length===0)return;t.log?.(`Ash: initializing ${n.length} sandbox ${pluralize(n.length,`template`)}...`);let r=t.dispatch??(async({backend:e,input:t})=>await e.prewarm(t)),i=0;await Promise.all(n.map(async({backend:n,label:a,input:o})=>{t.log?.(`Ash: initializing sandbox template "${a}"...`);let s;try{s=await r({backend:n,input:o})}catch(r){throw t.log?.(`Ash: failed to initialize sandbox template "${a}" on backend "${n.name}": ${toErrorMessage(r)}`),r}s.reused?(i+=1,t.log?.(`Ash: reused cached sandbox template "${a}".`)):t.log?.(`Ash: built sandbox template "${a}".`)})),t.log?.(`Ash: initialized ${n.length} sandbox ${pluralize(n.length,`template`)} (${i} reused, ${n.length-i} built).`)}async function prewarmAppSandboxes(e){let t=createAuthoredSourceRuntimeCompiledArtifactsSource(e.appRoot)
|
|
1
|
+
import{toErrorMessage}from"#shared/errors.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{createBundledRuntimeCompiledArtifactsSource}from"#runtime/compiled-artifacts-source.js";import{createRuntimeSandboxTemplateKey}from"#runtime/sandbox/keys.js";import{createRuntimeSandboxTemplatePlan}from"#runtime/sandbox/template-plan.js";import{loadCompiledModuleMapFromAuthoredSource}from"#internal/authored-module-map-loader.js";import{createAuthoredSourceRuntimeCompiledArtifactsSource}from"#internal/application/runtime-compiled-artifacts-source.js";import{loadCompileMetadata}from"#runtime/loaders/compile-metadata.js";import{withBundledCompiledArtifacts}from"#runtime/loaders/bundled-artifacts.js";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{resolveRuntimeCompilerArtifactPaths}from"#runtime/loaders/artifact-paths.js";import{resolveRuntimeAgentGraph}from"#runtime/resolve-agent-graph.js";import{materializeWorkspaceDirectory}from"#runtime/workspace/seed-files.js";async function prewarmSandboxes(t){let n=await collectPrewarmTargets(t);if(n.length===0)return;t.log?.(`Ash: initializing ${n.length} sandbox ${pluralize(n.length,`template`)}...`);let r=t.dispatch??(async({backend:e,input:t})=>await e.prewarm(t)),i=0;await Promise.all(n.map(async({backend:n,label:a,input:o})=>{t.log?.(`Ash: initializing sandbox template "${a}"...`);let s;try{s=await r({backend:n,input:o})}catch(r){throw t.log?.(`Ash: failed to initialize sandbox template "${a}" on backend "${n.name}": ${toErrorMessage(r)}`),r}s.reused?(i+=1,t.log?.(`Ash: reused cached sandbox template "${a}".`)):t.log?.(`Ash: built sandbox template "${a}".`)})),t.log?.(`Ash: initialized ${n.length} sandbox ${pluralize(n.length,`template`)} (${i} reused, ${n.length-i} built).`)}async function prewarmAppSandboxes(e){let t=e.compiledArtifactsSource??createAuthoredSourceRuntimeCompiledArtifactsSource(e.appRoot);if(t.kind!==`disk`)throw Error(`prewarmAppSandboxes requires disk-backed compiled artifacts.`);let n=await(e.loadAgentGraph??loadGraphFromArtifacts)({compiledArtifactsSource:t});await prewarmSandboxes({appRoot:t.appRoot,compiledArtifactsSource:t,dispatch:e.dispatch,graph:n,log:e.log})}async function prewarmBuiltAppSandboxes(e){let t=createAuthoredSourceRuntimeCompiledArtifactsSource(e.appRoot),[r,i,u]=await Promise.all([loadCompileMetadata({compiledArtifactsSource:t}),loadCompiledManifest({compiledArtifactsSource:t}),loadCompiledModuleMapFromAuthoredSource({compiledArtifactsSource:t})]);await withBundledCompiledArtifacts({manifest:i,metadata:r??void 0,moduleMap:u,sessionId:`built-app-prewarm`},async()=>{let t=createBundledRuntimeCompiledArtifactsSource(),r=await resolveRuntimeAgentGraph({manifest:i,moduleMap:u});await prewarmSandboxes({appRoot:e.appRoot,compiledArtifactsSource:t,dispatch:e.dispatch,graph:r,log:e.log})})}async function collectPrewarmTargets(e){let t=resolveRuntimeCompilerArtifactPaths(e.appRoot).compileDirectoryPath,n={appRoot:e.appRoot},a=[];return await Promise.all(collectNodeSandboxes(e.graph).map(async({definition:o,nodeId:s,workspaceResourceRoot:c})=>{let l=createRuntimeSandboxTemplatePlan({definition:o,workspaceResourceRoot:c}),u=await createRuntimeSandboxTemplateKey({backendName:o.backend.name,compiledArtifactsSource:e.compiledArtifactsSource,nodeId:s,sourceId:o.sourceId,templatePlan:l});u!==null&&a.push({backend:o.backend,label:formatLabel(s),input:{bootstrap:o.bootstrap,seedFiles:await loadResourceRootSeedFiles({compileDirectoryPath:t,workspaceResourceRoot:c}),runtimeContext:n,templateKey:u}})})),a.sort((e,t)=>e.label.localeCompare(t.label))}async function loadResourceRootSeedFiles(e){return e.workspaceResourceRoot.rootEntries.length===0?[]:(await materializeWorkspaceDirectory(`${e.compileDirectoryPath}/${e.workspaceResourceRoot.logicalPath}`)).map(e=>({content:e.content,path:e.path}))}async function loadGraphFromArtifacts(e){let[t,n]=await Promise.all([loadCompiledManifest({compiledArtifactsSource:e.compiledArtifactsSource}),loadCompiledModuleMapFromAuthoredSource({compiledArtifactsSource:e.compiledArtifactsSource})]);return await resolveRuntimeAgentGraph({manifest:t,moduleMap:n})}function collectNodeSandboxes(e){return[...e.nodesByNodeId.entries()].flatMap(([e,t])=>{let n=t.sandboxRegistry.sandbox;return n===null?[]:[{...n,nodeId:e}]})}function pluralize(e,t){return e===1?t:`${t}s`}function formatLabel(e){return e===ROOT_RUNTIME_AGENT_NODE_ID?`root`:e}export{prewarmAppSandboxes,prewarmBuiltAppSandboxes,prewarmSandboxes};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import type { HookPayload, SessionCapabilities } from "#channel/types.js";
|
|
2
|
-
import type { RunMode } from "#shared/run-mode.js";
|
|
3
|
-
import type { DurableSessionState } from "#execution/durable-session-store.js";
|
|
4
1
|
import type { NextDriverAction } from "#execution/next-driver-action.js";
|
|
2
|
+
import { type TurnWorkflowInput } from "#execution/durable-session-migrations/turn-workflow.js";
|
|
5
3
|
/**
|
|
6
4
|
* Hook payload the turn child workflow delivers to the parent driver
|
|
7
5
|
* on completion. `turn-result` wraps a {@link NextDriverAction} the
|
|
@@ -15,15 +13,7 @@ export type TurnCompletionPayload = {
|
|
|
15
13
|
readonly kind: "turn-error";
|
|
16
14
|
readonly error: unknown;
|
|
17
15
|
};
|
|
18
|
-
export
|
|
19
|
-
readonly capabilities: SessionCapabilities | undefined;
|
|
20
|
-
readonly completionToken: string;
|
|
21
|
-
readonly delivery: HookPayload;
|
|
22
|
-
readonly mode: RunMode;
|
|
23
|
-
readonly parentWritable: WritableStream<Uint8Array>;
|
|
24
|
-
readonly serializedContext: Record<string, unknown>;
|
|
25
|
-
readonly sessionState: DurableSessionState;
|
|
26
|
-
}
|
|
16
|
+
export type { TurnWorkflowInput };
|
|
27
17
|
/**
|
|
28
18
|
* Short-lived workflow that owns one runtime turn for the driver.
|
|
29
19
|
*
|
|
@@ -32,7 +22,7 @@ export interface TurnWorkflowInput {
|
|
|
32
22
|
* {@link NextDriverAction} and reports it back through
|
|
33
23
|
* {@link notifyDriverStep}.
|
|
34
24
|
*/
|
|
35
|
-
export declare function turnWorkflow(
|
|
25
|
+
export declare function turnWorkflow(rawInput: unknown): Promise<void>;
|
|
36
26
|
/** Resumes the driver's one-shot completion hook with the turn result. */
|
|
37
27
|
export declare function notifyDriverStep(input: {
|
|
38
28
|
readonly completionToken: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{normalizeSerializableError}from"#execution/workflow-errors.js";import{turnStep}from"#execution/workflow-steps.js";async function turnWorkflow(
|
|
1
|
+
import{normalizeSerializableError}from"#execution/workflow-errors.js";import{migrateTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{turnStep}from"#execution/workflow-steps.js";async function turnWorkflow(r){"use workflow";let i=migrateTurnWorkflowInput(r),a=i.stepInput;try{for(;;){let e=await turnStep(a);if(e.action===`done`){await notifyDriverStep({completionToken:i.completionToken,payload:{action:{kind:`done`,output:e.output??``,isError:e.isError,serializedContext:e.serializedContext,sessionState:e.sessionState},kind:`turn-result`}});return}if(e.action===`dispatch-code-mode-runtime-actions`){await notifyDriverStep({completionToken:i.completionToken,payload:{action:{kind:`dispatch-code-mode-runtime-actions`,pendingActionKeys:e.pendingRuntimeActionKeys,serializedContext:e.serializedContext,sessionState:e.sessionState},kind:`turn-result`}});return}if(e.action===`park`){let t=e.pendingRuntimeActionKeys;if(!(t!==void 0||e.hasPendingAuthorization||e.hasPendingInputBatch&&i.capabilities?.requestInput===!0||i.mode===`conversation`))throw Error("Task mode cannot wait for follow-up input (`next: null`).");let n=t===void 0?{kind:`park`,serializedContext:e.serializedContext,sessionState:e.sessionState,authorizationNames:e.authorizationNames}:{kind:`dispatch-runtime-actions`,pendingActionKeys:t,serializedContext:e.serializedContext,sessionState:e.sessionState};await notifyDriverStep({completionToken:i.completionToken,payload:{action:n,kind:`turn-result`}});return}a={input:void 0,parentWritable:a.parentWritable,serializedContext:e.serializedContext,sessionState:e.sessionState}}}catch(t){throw await notifyDriverStep({completionToken:i.completionToken,payload:{error:normalizeSerializableError(t),kind:`turn-error`}}),t}}async function notifyDriverStep(e){"use step";let{resumeHook:t}=await import(`#compiled/@workflow/core/runtime.js`);await t(e.completionToken,e.payload)}export{notifyDriverStep,turnWorkflow};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { DeliverPayload,
|
|
1
|
+
import type { DeliverPayload, SessionAuthContext, SubagentInputRequestHookPayload } from "#channel/types.js";
|
|
2
2
|
import { deserializeContext } from "#context/serialize.js";
|
|
3
3
|
import type { HarnessSession, StepInput } from "#harness/types.js";
|
|
4
4
|
import type { JsonObject } from "#shared/json.js";
|
|
5
5
|
import type { RunMode } from "#shared/run-mode.js";
|
|
6
6
|
import { type DurableSessionState } from "#execution/durable-session-store.js";
|
|
7
|
-
import { type
|
|
7
|
+
import { type TurnStepInput, type TurnWorkflowDispatchInput } from "#execution/durable-session-migrations/turn-workflow.js";
|
|
8
8
|
/**
|
|
9
9
|
* Result of one durable harness step, consumed by the turn workflow.
|
|
10
10
|
*
|
|
@@ -33,17 +33,11 @@ export type DurableStepResult = {
|
|
|
33
33
|
readonly serializedContext: Record<string, unknown>;
|
|
34
34
|
readonly sessionState: DurableSessionState;
|
|
35
35
|
};
|
|
36
|
-
|
|
37
|
-
export interface TurnStepInput {
|
|
38
|
-
readonly input: HookPayload | undefined;
|
|
39
|
-
readonly parentWritable: WritableStream<Uint8Array>;
|
|
40
|
-
readonly serializedContext: Record<string, unknown>;
|
|
41
|
-
readonly sessionState: DurableSessionState;
|
|
42
|
-
}
|
|
36
|
+
export type { TurnStepInput };
|
|
43
37
|
/**
|
|
44
38
|
* Runs one atomic harness step inside a durable `"use step"` boundary.
|
|
45
39
|
*/
|
|
46
|
-
export declare function turnStep(
|
|
40
|
+
export declare function turnStep(rawInput: TurnStepInput): Promise<DurableStepResult>;
|
|
47
41
|
/**
|
|
48
42
|
* Re-stamps `session.continuationToken` from `ContinuationTokenKey`
|
|
49
43
|
* after channels call `setContinuationToken(...)`. Idempotent when the
|
|
@@ -104,6 +98,6 @@ export declare function routeProxiedDeliverStep(input: {
|
|
|
104
98
|
readonly sessionState: DurableSessionState;
|
|
105
99
|
}): Promise<RoutedDeliverResult>;
|
|
106
100
|
/** Starts a per-turn child workflow for the current driver session. */
|
|
107
|
-
export declare function dispatchTurnStep(input:
|
|
101
|
+
export declare function dispatchTurnStep(input: TurnWorkflowDispatchInput): Promise<{
|
|
108
102
|
readonly runId: string;
|
|
109
103
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,formatError}from"#internal/logging.js";import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ContinuationTokenKey,ModeKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionFailedEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{buildTurnAttributes,readRootSessionId}from"#execution/ash-workflow-attributes.js";import{setAshAttributes}from"#runtime/attributes/emit.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{getRuntimeActionKeyFromInterrupt,isCodeModeRuntimeActionInterrupt}from"#harness/code-mode-runtime-action-state.js";import{getPendingCodeModeInterrupt}from"#harness/code-mode-interrupt-state.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{createWorkflowRuntime,startWorkflowPreferLatest}from"#execution/workflow-runtime.js";import{getHarnessEmissionState}from"#harness/emission.js";import{upsertProxyInputRequests}from"#harness/proxy-input-requests.js";import{setChannelContext}from"#execution/channel-context.js";import{coalesceTurnInputs}from"#harness/messages.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent}from"#context/dynamic-tool-lifecycle.js";import{runStep,withContextScope}from"#context/run-step.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,getPendingAuthorization}from"#harness/authorization.js";import{createExecutionNodeStep}from"#execution/node-step.js";import{emitProxiedInputRequest,routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{turnWorkflow}from"#execution/turn-workflow.js";async function turnStep(e){"use step";await setAshAttributes(buildTurnAttributes({parentSessionId:e.sessionState.sessionId,rootSessionId:readRootSessionId(e.serializedContext)??e.sessionState.sessionId}));let t=await readDurableSession(e.sessionState),o=await deserializeContext(e.serializedContext),l=o.require(ChannelKey),f=o.require(BundleKey),p=hydrateDurableSession({compactionOverrides:{thresholdPercent:f.resolvedAgent.config.compaction?.thresholdPercent},durable:t,turnAgent:f.turnAgent});try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&o.set(CallbackBaseUrlKey,t.url.replace(/\/$/,``))}catch{}let m=getPendingAuthorization(t.state),h;if(m&&e.input?.kind===`deliver`){let t=[],n=[];for(let r of e.input.payloads){let e=r.authorizationCallback;if(e){let n=m.challenges.find(t=>t.name===e.connectionName);n&&t.push({name:n.name,state:n.state,callback:e.request,hookUrl:n.hookUrl})}else n.push(r)}t.length>0&&(o.set(PendingAuthorizationResultKey,t),h=t.map(e=>e.name),e=n.length>0?{...e,input:{...e.input,payloads:n}}:{...e,input:void 0})}e.input?.kind===`deliver`&&e.input.auth!==void 0&&o.set(AuthKey,e.input.auth??null);let g=buildAdapterContext(l,o),_;if(e.input?.kind===`deliver`){let t=[];for(let n of e.input.payloads){let e=l.deliver?await l.deliver(n,g):defaultDeliverResult(n);e!=null&&t.push(e)}_=t.length===0?void 0:t.reduce(coalesceTurnInputs)}else e.input?.kind===`runtime-action-result`&&(_={runtimeActionResults:e.input.results});if(e.input?.kind===`deliver`&&setChannelContext(o,{...l,state:{...g.state}}),e.input?.kind===`deliver`&&_===void 0){let t=reconcileSessionContinuationToken(o,p),n=serializeContext(o),r=t===p?e.sessionState:createDurableSessionState({session:t});return{action:`park`,...derivePendingState(t),serializedContext:n,sessionState:r}}let v=e.parentWritable.getWriter(),y=f.hookRegistry,b=f.resolvedAgent.dynamicInstructionsResolvers??[],x=f.resolvedAgent.dynamicSkillResolvers??[],S=f.resolvedAgent.dynamicToolResolvers??[],emit=async e=>{let t=await callAdapterEventHandler(l,e,g);return setChannelContext(o,{...l,state:{...g.state}}),await v.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t))),t},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:o,registry:y,event:n}),await dispatchDynamicToolEvent({ctx:o,resolvers:S,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:o,resolvers:x,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:o,resolvers:b,event:n,messages:t??[]})},C=o.require(ModeKey),w=await runStep(o,p,async e=>{let t=resolveEffectiveOutputSchema({agentOutputSchema:f.turnAgent.outputSchema,input:_,mode:C,session:e});if(h){let e=getHarnessEmissionState(t.state);for(let t of h)await handleEvent(createAuthorizationCompletedEvent({name:t,outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}let n=o.get(CapabilitiesKey);return(async(e,t)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:f.resolvedAgent.config.compaction?.thresholdPercent},refreshSystemPrompt:shouldRefreshSystemPromptFromTurnAgent(f.compiledArtifactsSource),session:e,turnAgent:f.turnAgent});return createExecutionNodeStep({capabilities:n,compiledArtifactsSource:f.compiledArtifactsSource,createRuntime:createWorkflowRuntime,handleEvent,mode:C,node:f.graph.root})(r,t)})(t,_)}),T=reconcileSessionContinuationToken(o,w.session),E=serializeContext(o);w={...w,session:T};let D=createDurableSessionState({session:w.session});if(w.next!==null&&typeof w.next==`object`&&`done`in w.next)return await v.close(),{action:`done`,output:w.next.output,isError:w.next.isError,serializedContext:E,sessionState:D};if(w.next===null){v.releaseLock();let e=getPendingCodeModeInterrupt(w.session.state);return e!==void 0&&isCodeModeRuntimeActionInterrupt(e.interrupt)?{action:`dispatch-code-mode-runtime-actions`,pendingRuntimeActionKeys:[getRuntimeActionKeyFromInterrupt(e.interrupt)],serializedContext:E,sessionState:D}:{action:`park`,...derivePendingState(w.session),serializedContext:E,sessionState:D}}return v.releaseLock(),{action:`continue`,serializedContext:E,sessionState:D}}function shouldRefreshSystemPromptFromTurnAgent(e){return e.kind===`disk`&&e.moduleMapLoaderPath!==void 0}function derivePendingState(e){let t=getPendingRuntimeActionBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationNames:n?.challenges.map(e=>e.name),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingRuntimeActionKeys:t.actions.map(e=>getRuntimeActionRequestKey(e))}}function reconcileSessionContinuationToken(e,t){let n=e.get(ContinuationTokenKey);return n===void 0||n===t.continuationToken?t:{...t,continuationToken:n}}function resolveEffectiveOutputSchema(e){let{agentOutputSchema:t,input:n,mode:r,session:i}=e;return n?.outputSchema===void 0?r===`task`&&i.outputSchema===void 0&&t!==void 0?{...i,outputSchema:t}:i:{...i,outputSchema:n.outputSchema}}const log=createLogger(`execution.workflow-entry`);async function emitTerminalSessionFailureStep(e){"use step";let r=formatError(e.error),i=typeof r.name==`string`?r.name:`WORKFLOW_EXECUTION_FAILED`,a=typeof r.message==`string`?r.message:String(e.error),o=e.serializedContext[`ash.sessionId`]??``;log.error(`workflow loop threw — emitting terminal session.failed`,{sessionId:o,errorId:typeof r.errorId==`string`?r.errorId:void 0,code:i,message:a,detail:typeof r.detail==`string`?r.detail:void 0});let s=createSessionFailedEvent({code:i,details:r,message:a,sessionId:o});try{let t=await deserializeContext(e.serializedContext),r=t.get(ChannelKey);r!==void 0&&await callAdapterEventHandler(r,s,buildAdapterContext(r,t))}catch(e){log.error(`adapter failed to handle terminal session.failed event`,{errorId:typeof r.errorId==`string`?r.errorId:void 0,sessionId:o,error:e})}try{let t=e.parentWritable.getWriter();try{await t.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(s)))}finally{t.releaseLock()}}catch(e){log.error(`failed to write terminal session.failed event to durable stream`,{errorId:typeof r.errorId==`string`?r.errorId:void 0,sessionId:o,error:e})}}async function runProxyInputRequestStep(e){"use step";let t=await readDurableSession(e.sessionState),r=await deserializeContext(e.serializedContext),i=r.require(ChannelKey),a=buildAdapterContext(i,r),o=r.require(ModeKey),c=r.require(BundleKey),l=hydrateDurableSession({compactionOverrides:{thresholdPercent:c.resolvedAgent.config.compaction?.thresholdPercent},durable:t,turnAgent:c.turnAgent}),u=e.parentWritable.getWriter(),d;try{let emit=async e=>{let t=await callAdapterEventHandler(i,e,a);await u.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t)))};d=await withContextScope(r,l,async t=>{let n=await emitProxiedInputRequest({emit,hookPayload:e.hookPayload,mode:o,session:t});return{result:n.entries,session:n.session}})}finally{u.releaseLock()}return setChannelContext(r,{...i,state:{...a.state}}),{serializedContext:serializeContext(r),sessionState:createDurableSessionState({session:reconcileSessionContinuationToken(r,upsertProxyInputRequests({entries:d.result,forChildContinuationToken:e.hookPayload.childContinuationToken,session:d.session}))})}}async function routeProxiedDeliverStep(e){"use step";let t=await readDurableSession(e.sessionState),n=routeDeliverPayload({payload:e.payload,state:t.state}),{resumeHook:r}=await import(`#compiled/@workflow/core/runtime.js`);for(let t of n.forChildren)await r(t.childContinuationToken,{auth:e.auth,kind:`deliver`,payloads:[t.payload]});return{remainder:n.forSelf}}async function dispatchTurnStep(e){"use step";return{runId:(await startWorkflowPreferLatest(turnWorkflow,[e])).runId}}export{dispatchTurnStep,emitTerminalSessionFailureStep,reconcileSessionContinuationToken,resolveEffectiveOutputSchema,routeProxiedDeliverStep,runProxyInputRequestStep,turnStep};
|
|
1
|
+
import{createLogger,formatError}from"#internal/logging.js";import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ContinuationTokenKey,ModeKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionFailedEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{buildTurnAttributes,readRootSessionId}from"#execution/ash-workflow-attributes.js";import{setAshAttributes}from"#runtime/attributes/emit.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{getRuntimeActionKeyFromInterrupt,isCodeModeRuntimeActionInterrupt}from"#harness/code-mode-runtime-action-state.js";import{getPendingCodeModeInterrupt}from"#harness/code-mode-interrupt-state.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{createWorkflowRuntime,startWorkflowPreferLatest}from"#execution/workflow-runtime.js";import{getHarnessEmissionState}from"#harness/emission.js";import{upsertProxyInputRequests}from"#harness/proxy-input-requests.js";import{setChannelContext}from"#execution/channel-context.js";import{createTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{coalesceTurnInputs}from"#harness/messages.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent}from"#context/dynamic-tool-lifecycle.js";import{runStep,withContextScope}from"#context/run-step.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,getPendingAuthorization}from"#harness/authorization.js";import{createExecutionNodeStep}from"#execution/node-step.js";import{emitProxiedInputRequest,routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{turnWorkflow}from"#execution/turn-workflow.js";async function turnStep(e){"use step";let t=e;await setAshAttributes(buildTurnAttributes({parentSessionId:t.sessionState.sessionId,rootSessionId:readRootSessionId(t.serializedContext)??t.sessionState.sessionId}));let o=await readDurableSession(t.sessionState),l=await deserializeContext(t.serializedContext),f=l.require(ChannelKey),p=l.require(BundleKey),m=hydrateDurableSession({compactionOverrides:{thresholdPercent:p.resolvedAgent.config.compaction?.thresholdPercent},durable:o,turnAgent:p.turnAgent});try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&l.set(CallbackBaseUrlKey,t.url.replace(/\/$/,``))}catch{}let h=getPendingAuthorization(o.state),g;if(h&&t.input?.kind===`deliver`){let e=[],n=[];for(let r of t.input.payloads){let t=r.authorizationCallback;if(t){let n=h.challenges.find(e=>e.name===t.connectionName);n&&e.push({name:n.name,state:n.state,callback:t.request,hookUrl:n.hookUrl})}else n.push(r)}e.length>0&&(l.set(PendingAuthorizationResultKey,e),g=e.map(e=>e.name),t=n.length>0?{...t,input:{...t.input,payloads:n}}:{...t,input:void 0})}t.input?.kind===`deliver`&&t.input.auth!==void 0&&l.set(AuthKey,t.input.auth??null);let _=buildAdapterContext(f,l),v;if(t.input?.kind===`deliver`){let e=[];for(let n of t.input.payloads){let t=f.deliver?await f.deliver(n,_):defaultDeliverResult(n);t!=null&&e.push(t)}v=e.length===0?void 0:e.reduce(coalesceTurnInputs)}else t.input?.kind===`runtime-action-result`&&(v={runtimeActionResults:t.input.results});if(t.input?.kind===`deliver`&&setChannelContext(l,{...f,state:{..._.state}}),t.input?.kind===`deliver`&&v===void 0){let e=reconcileSessionContinuationToken(l,m),n=serializeContext(l),r=e===m?t.sessionState:createDurableSessionState({session:e});return{action:`park`,...derivePendingState(e),serializedContext:n,sessionState:r}}let y=t.parentWritable.getWriter(),b=p.hookRegistry,x=p.resolvedAgent.dynamicInstructionsResolvers??[],S=p.resolvedAgent.dynamicSkillResolvers??[],C=p.resolvedAgent.dynamicToolResolvers??[],emit=async e=>{let t=await callAdapterEventHandler(f,e,_);return setChannelContext(l,{...f,state:{..._.state}}),await y.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t))),t},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:l,registry:b,event:n}),await dispatchDynamicToolEvent({ctx:l,resolvers:C,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:l,resolvers:S,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:l,resolvers:x,event:n,messages:t??[]})},w=l.require(ModeKey),T=await runStep(l,m,async e=>{let t=resolveEffectiveOutputSchema({agentOutputSchema:p.turnAgent.outputSchema,input:v,mode:w,session:e});if(g){let e=getHarnessEmissionState(t.state);for(let t of g)await handleEvent(createAuthorizationCompletedEvent({name:t,outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}let n=l.get(CapabilitiesKey);return(async(e,t)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:p.resolvedAgent.config.compaction?.thresholdPercent},refreshSystemPrompt:shouldRefreshSystemPromptFromTurnAgent(p.compiledArtifactsSource),session:e,turnAgent:p.turnAgent});return createExecutionNodeStep({capabilities:n,compiledArtifactsSource:p.compiledArtifactsSource,createRuntime:createWorkflowRuntime,handleEvent,mode:w,node:p.graph.root})(r,t)})(t,v)}),E=reconcileSessionContinuationToken(l,T.session),D=serializeContext(l);T={...T,session:E};let O=createDurableSessionState({session:T.session});if(T.next!==null&&typeof T.next==`object`&&`done`in T.next)return await y.close(),{action:`done`,output:T.next.output,isError:T.next.isError,serializedContext:D,sessionState:O};if(T.next===null){y.releaseLock();let e=getPendingCodeModeInterrupt(T.session.state);return e!==void 0&&isCodeModeRuntimeActionInterrupt(e.interrupt)?{action:`dispatch-code-mode-runtime-actions`,pendingRuntimeActionKeys:[getRuntimeActionKeyFromInterrupt(e.interrupt)],serializedContext:D,sessionState:O}:{action:`park`,...derivePendingState(T.session),serializedContext:D,sessionState:O}}return y.releaseLock(),{action:`continue`,serializedContext:D,sessionState:O}}function shouldRefreshSystemPromptFromTurnAgent(e){return e.kind===`disk`&&e.moduleMapLoaderPath!==void 0}function derivePendingState(e){let t=getPendingRuntimeActionBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationNames:n?.challenges.map(e=>e.name),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingRuntimeActionKeys:t.actions.map(e=>getRuntimeActionRequestKey(e))}}function reconcileSessionContinuationToken(e,t){let n=e.get(ContinuationTokenKey);return n===void 0||n===t.continuationToken?t:{...t,continuationToken:n}}function resolveEffectiveOutputSchema(e){let{agentOutputSchema:t,input:n,mode:r,session:i}=e;return n?.outputSchema===void 0?r===`task`&&i.outputSchema===void 0&&t!==void 0?{...i,outputSchema:t}:i:{...i,outputSchema:n.outputSchema}}const log=createLogger(`execution.workflow-entry`);async function emitTerminalSessionFailureStep(e){"use step";let r=formatError(e.error),i=typeof r.name==`string`?r.name:`WORKFLOW_EXECUTION_FAILED`,a=typeof r.message==`string`?r.message:String(e.error),o=e.serializedContext[`ash.sessionId`]??``;log.error(`workflow loop threw — emitting terminal session.failed`,{sessionId:o,errorId:typeof r.errorId==`string`?r.errorId:void 0,code:i,message:a,detail:typeof r.detail==`string`?r.detail:void 0});let s=createSessionFailedEvent({code:i,details:r,message:a,sessionId:o});try{let t=await deserializeContext(e.serializedContext),r=t.get(ChannelKey);r!==void 0&&await callAdapterEventHandler(r,s,buildAdapterContext(r,t))}catch(e){log.error(`adapter failed to handle terminal session.failed event`,{errorId:typeof r.errorId==`string`?r.errorId:void 0,sessionId:o,error:e})}try{let t=e.parentWritable.getWriter();try{await t.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(s)))}finally{t.releaseLock()}}catch(e){log.error(`failed to write terminal session.failed event to durable stream`,{errorId:typeof r.errorId==`string`?r.errorId:void 0,sessionId:o,error:e})}}async function runProxyInputRequestStep(e){"use step";let t=await readDurableSession(e.sessionState),r=await deserializeContext(e.serializedContext),i=r.require(ChannelKey),a=buildAdapterContext(i,r),o=r.require(ModeKey),c=r.require(BundleKey),l=hydrateDurableSession({compactionOverrides:{thresholdPercent:c.resolvedAgent.config.compaction?.thresholdPercent},durable:t,turnAgent:c.turnAgent}),u=e.parentWritable.getWriter(),d;try{let emit=async e=>{let t=await callAdapterEventHandler(i,e,a);await u.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t)))};d=await withContextScope(r,l,async t=>{let n=await emitProxiedInputRequest({emit,hookPayload:e.hookPayload,mode:o,session:t});return{result:n.entries,session:n.session}})}finally{u.releaseLock()}return setChannelContext(r,{...i,state:{...a.state}}),{serializedContext:serializeContext(r),sessionState:createDurableSessionState({session:reconcileSessionContinuationToken(r,upsertProxyInputRequests({entries:d.result,forChildContinuationToken:e.hookPayload.childContinuationToken,session:d.session}))})}}async function routeProxiedDeliverStep(e){"use step";let t=await readDurableSession(e.sessionState),n=routeDeliverPayload({payload:e.payload,state:t.state}),{resumeHook:r}=await import(`#compiled/@workflow/core/runtime.js`);for(let t of n.forChildren)await r(t.childContinuationToken,{auth:e.auth,kind:`deliver`,payloads:[t.payload]});return{remainder:n.forSelf}}async function dispatchTurnStep(e){"use step";return{runId:(await startWorkflowPreferLatest(turnWorkflow,[createTurnWorkflowInput(e)])).runId}}export{dispatchTurnStep,emitTerminalSessionFailureStep,reconcileSessionContinuationToken,resolveEffectiveOutputSchema,routeProxiedDeliverStep,runProxyInputRequestStep,turnStep};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire}from"node:module";import{basename,dirname,join}from"node:path";import{existsSync,readFileSync,realpathSync}from"node:fs";import{ASH_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const WORKFLOW_MODULE_ALIASES={"workflow/api":`src/compiled/@workflow/core/runtime.js`,"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`,"workflow/runtime":`src/compiled/@workflow/core/runtime.js`};function resolveFallbackPackageVersion(){return`0.
|
|
1
|
+
import{createRequire}from"node:module";import{basename,dirname,join}from"node:path";import{existsSync,readFileSync,realpathSync}from"node:fs";import{ASH_PACKAGE_NAME}from"#internal/package-name.js";import{fileURLToPath}from"node:url";let cachedPackageInfo;const WORKFLOW_MODULE_ALIASES={"workflow/api":`src/compiled/@workflow/core/runtime.js`,"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`,"workflow/runtime":`src/compiled/@workflow/core/runtime.js`};function resolveFallbackPackageVersion(){return`0.64.1`}const FALLBACK_PACKAGE_INFO={name:ASH_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const require=createRequire(resolveCurrentModulePath());function isBuildOutputPackageRoot(e){return basename(e)===`dist`&&existsSync(join(dirname(e),`package.json`))}function resolvePackageBuildRoot(){let e=dirname(realpathSync(resolveCurrentModulePath()));for(;;){if(isBuildOutputPackageRoot(e))return e;let t=dirname(e);if(t===e)return null;e=t}}function findNearestPackageRoot(e){let t=e;for(;;){if(existsSync(join(t,`package.json`))&&!isBuildOutputPackageRoot(t))return t;let r=dirname(t);if(r===t)throw Error(`Failed to resolve package root from "${e}".`);t=r}}function resolvePackageRoot(){return findNearestPackageRoot(dirname(realpathSync(resolveCurrentModulePath())))}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){return require.resolve(e)}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(!(typeof t.name!=`string`||typeof t.version!=`string`))return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let n=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(n?.name===t)return n}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),ASH_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(require.resolve(`${ASH_PACKAGE_NAME}/package.json`),ASH_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?require.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveInstalledPackageInfo,resolvePackageDependencyPath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
|