experimental-ash 0.46.0 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/docs/public/advanced/hooks.mdx +7 -7
  3. package/dist/docs/public/advanced/typescript-api.md +1 -1
  4. package/dist/docs/public/channels/index.md +2 -2
  5. package/dist/docs/public/channels/slack.mdx +12 -17
  6. package/dist/docs/public/frontend/use-ash-agent.md +13 -17
  7. package/dist/src/channel/adapter.js +1 -1
  8. package/dist/src/channel/routes.d.ts +14 -7
  9. package/dist/src/channel/send.js +1 -1
  10. package/dist/src/channel/types.d.ts +6 -3
  11. package/dist/src/client/index.d.ts +1 -1
  12. package/dist/src/client/message-reducer-types.d.ts +1 -0
  13. package/dist/src/client/message-reducer.js +1 -1
  14. package/dist/src/client/message-response.d.ts +2 -2
  15. package/dist/src/client/message-response.js +1 -1
  16. package/dist/src/client/output-schema.d.ts +12 -0
  17. package/dist/src/client/output-schema.js +1 -0
  18. package/dist/src/client/session.d.ts +2 -2
  19. package/dist/src/client/session.js +1 -1
  20. package/dist/src/client/types.d.ts +17 -2
  21. package/dist/src/compiler/compile-from-memory.d.ts +1 -0
  22. package/dist/src/compiler/compile-from-memory.js +1 -1
  23. package/dist/src/compiler/manifest.d.ts +4 -0
  24. package/dist/src/compiler/manifest.js +1 -1
  25. package/dist/src/compiler/normalize-agent-config.js +1 -1
  26. package/dist/src/compiler/normalize-subagent.js +1 -1
  27. package/dist/src/compiler/remote-agent-node.d.ts +2 -0
  28. package/dist/src/compiler/remote-agent-node.js +1 -1
  29. package/dist/src/context/build-dynamic-tools.d.ts +13 -0
  30. package/dist/src/context/build-dynamic-tools.js +1 -0
  31. package/dist/src/context/dynamic-instruction-lifecycle.d.ts +13 -13
  32. package/dist/src/context/dynamic-instruction-lifecycle.js +1 -1
  33. package/dist/src/context/dynamic-resolve-context.d.ts +12 -0
  34. package/dist/src/context/dynamic-resolve-context.js +1 -0
  35. package/dist/src/context/dynamic-skill-lifecycle.js +1 -1
  36. package/dist/src/context/dynamic-tool-lifecycle.d.ts +4 -10
  37. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  38. package/dist/src/context/hook-lifecycle.d.ts +2 -2
  39. package/dist/src/context/hook-lifecycle.js +1 -1
  40. package/dist/src/context/keys.d.ts +30 -23
  41. package/dist/src/context/keys.js +1 -1
  42. package/dist/src/execution/create-session-step.d.ts +2 -0
  43. package/dist/src/execution/create-session-step.js +1 -1
  44. package/dist/src/execution/durable-session-store.d.ts +2 -0
  45. package/dist/src/execution/next-driver-action.d.ts +1 -0
  46. package/dist/src/execution/remote-agent-dispatch.js +1 -1
  47. package/dist/src/execution/session.d.ts +1 -0
  48. package/dist/src/execution/session.js +1 -1
  49. package/dist/src/execution/turn-workflow.js +1 -1
  50. package/dist/src/execution/workflow-entry.js +1 -1
  51. package/dist/src/execution/workflow-steps.d.ts +22 -1
  52. package/dist/src/execution/workflow-steps.js +1 -1
  53. package/dist/src/harness/code-mode.js +1 -1
  54. package/dist/src/harness/compaction.js +1 -1
  55. package/dist/src/harness/messages.js +1 -1
  56. package/dist/src/harness/prompt-cache.d.ts +11 -1
  57. package/dist/src/harness/prompt-cache.js +1 -1
  58. package/dist/src/harness/tool-loop.js +1 -1
  59. package/dist/src/harness/types.d.ts +17 -5
  60. package/dist/src/internal/application/package.js +1 -1
  61. package/dist/src/internal/authored-definition/core.js +1 -1
  62. package/dist/src/internal/json-schema.d.ts +1 -6
  63. package/dist/src/internal/json-schema.js +1 -1
  64. package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
  65. package/dist/src/protocol/message.d.ts +29 -3
  66. package/dist/src/protocol/message.js +2 -2
  67. package/dist/src/public/channels/ash.js +2 -2
  68. package/dist/src/public/channels/discord/discordChannel.d.ts +1 -2
  69. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  70. package/dist/src/public/channels/slack/slackChannel.d.ts +3 -7
  71. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  72. package/dist/src/public/channels/teams/teamsChannel.d.ts +1 -2
  73. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  74. package/dist/src/public/channels/telegram/telegramChannel.d.ts +1 -2
  75. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  76. package/dist/src/public/definitions/instructions.d.ts +7 -12
  77. package/dist/src/public/definitions/remote-agent.d.ts +9 -0
  78. package/dist/src/public/definitions/skill.js +1 -1
  79. package/dist/src/runtime/agent/bootstrap-model-utils.js +1 -1
  80. package/dist/src/runtime/agent/bootstrap.d.ts +1 -0
  81. package/dist/src/runtime/agent/bootstrap.js +1 -1
  82. package/dist/src/runtime/agent/mock-model-adapter.js +2 -2
  83. package/dist/src/runtime/agent/mock-structured-output.d.ts +5 -0
  84. package/dist/src/runtime/agent/mock-structured-output.js +1 -0
  85. package/dist/src/runtime/framework-tools/final-output.d.ts +14 -0
  86. package/dist/src/runtime/framework-tools/final-output.js +1 -0
  87. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  88. package/dist/src/runtime/resolve-agent.js +1 -1
  89. package/dist/src/runtime/types.d.ts +2 -0
  90. package/dist/src/shared/agent-definition.d.ts +9 -0
  91. package/dist/src/shared/dynamic-tool-definition.d.ts +20 -0
  92. package/dist/src/shared/dynamic-tool-definition.js +1 -1
  93. package/dist/src/shared/json-schema.d.ts +7 -0
  94. package/dist/src/shared/json-schema.js +1 -0
  95. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # experimental-ash
2
2
 
3
+ ## 0.48.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 28259a5: Align dynamic tools, instructions, and skills with consistent additive semantics and strict role boundaries.
8
+
9
+ **Breaking changes:**
10
+
11
+ - `InstructionsDefinition.modelContext` removed — instructions produce system messages only via `markdown`
12
+ - `DeliverPayload.modelContext` replaced with `context: string[]` — channel context is now user messages persisted in session history
13
+ - `StepInput.modelContext` replaced with `context: string[]`
14
+ - `SendPayload.modelContext` replaced with `context: string[]`
15
+ - Dynamic instructions restricted to `session.started` and `turn.started` events (no `step.started`)
16
+ - Dynamic skills restricted to `session.started` and `turn.started` events (no `step.started`)
17
+ - Compaction output changed from `role: "system"` to a user/assistant turn in conversation history
18
+
19
+ **New features:**
20
+
21
+ - `defineInstructions` contributions persist across workflow step boundaries via scoped durable keys
22
+ - `defineSkill` stamps `SKILL_BRAND` for consistent entry detection (replaces duck-typing)
23
+ - System cache breakpoint added (4th Anthropic cache slot) to preserve system prefix when tools change
24
+ - Null-returning tool resolvers correctly clear durable metadata
25
+ - Skill announcements use virtual context with durable backing (rebuild from manifest on step boundaries)
26
+ - Shared `buildResolveContext` extracted for all three dynamic lifecycle dispatchers
27
+
28
+ ## 0.47.0
29
+
30
+ ### Minor Changes
31
+
32
+ - f12c464: Ash message turns can now request deterministic structured output with `outputSchema`; fulfilled turns emit `result.completed` and client results expose typed `data`. Agents may also declare task-mode `outputSchema` for structured subagent, schedule, and job results.
33
+
3
34
  ## 0.46.0
4
35
 
5
36
  ### Minor Changes
@@ -14,15 +14,15 @@ Use a hook when you want to run code **around** a turn (before the model
14
14
  runs, around stream events) without writing a tool, a context provider,
15
15
  or a channel adapter handler.
16
16
 
17
- <CopyPrompt text="Add an Ash hook to the user's project. Ash hooks live under agent/hooks, use defineHook from experimental-ash/hooks, and can subscribe to lifecycle.session, lifecycle.turn, or stream events. Use lifecycle hooks when the model needs ephemeral modelContext before the next model call; use events handlers for observe-only side effects after events are durably recorded. Inspect existing hooks and agent/lib, choose the smallest hook file and path-derived slug, use defineState only when durable shared state is needed, wrap best-effort side effects so they do not fail sessions accidentally, verify the relevant lifecycle or stream event behavior, and do not commit unless the user asks.">
17
+ <CopyPrompt text="Add an Ash hook to the user's project. Ash hooks live under agent/hooks, use defineHook from experimental-ash/hooks, and can subscribe to lifecycle.session, lifecycle.turn, or stream events. Use lifecycle hooks when the model needs side effects before the next model call (e.g. setting state); use events handlers for observe-only side effects after events are durably recorded. Inspect existing hooks and agent/lib, choose the smallest hook file and path-derived slug, use defineState only when durable shared state is needed, wrap best-effort side effects so they do not fail sessions accidentally, verify the relevant lifecycle or stream event behavior, and do not commit unless the user asks.">
18
18
  Add an Ash hook to the user's project. Ash hooks live under agent/hooks, use defineHook from
19
19
  experimental-ash/hooks, and can subscribe to lifecycle.session, lifecycle.turn, or stream events.
20
- Use lifecycle hooks when the model needs ephemeral modelContext before the next model call; use
21
- events handlers for observe-only side effects after events are durably recorded. Inspect existing
22
- hooks and agent/lib, choose the smallest hook file and path-derived slug, use defineState only
23
- when durable shared state is needed, wrap best-effort side effects so they do not fail sessions
24
- accidentally, verify the relevant lifecycle or stream event behavior, and do not commit unless the
25
- user asks.
20
+ Use lifecycle hooks when the model needs side effects before the next model call (e.g. setting
21
+ state); use events handlers for observe-only side effects after events are durably recorded.
22
+ Inspect existing hooks and agent/lib, choose the smallest hook file and path-derived slug, use
23
+ defineState only when durable shared state is needed, wrap best-effort side effects so they do not
24
+ fail sessions accidentally, verify the relevant lifecycle or stream event behavior, and do not
25
+ commit unless the user asks.
26
26
  </CopyPrompt>
27
27
 
28
28
  ## The Main API
@@ -112,7 +112,7 @@ Channel and Slack types exported from `experimental-ash/channels/slack`:
112
112
  `since: (message) => boolean` for a custom boundary.
113
113
  - `SlackInteractionAction` - action type for `onInteraction`
114
114
  - `SlackMentionResult` / `SlackInboundResult` - return type of `onAppMention` / `onDirectMessage`
115
- (`{ auth, modelContext? } | null`)
115
+ (`{ auth, context? } | null`)
116
116
  - `defaultSlackAuth(message, ctx)` - default Slack actor-to-session-auth projection
117
117
  - `Card`, `Button`, `Actions`, `Section`, `Modal`, `Table`, etc. - card builders re-exported for
118
118
  rendering Slack messages
@@ -412,8 +412,8 @@ await args.receive(slack, {
412
412
  ```
413
413
 
414
414
  For inbound mentions in an existing Slack thread, `onAppMention` and
415
- `onDirectMessage` may return `modelContext` to inject fetched thread
416
- history into the next model call without persisting it. See
415
+ `onDirectMessage` may return `context` to inject thread history as
416
+ user messages in session history. See
417
417
  [Slack thread context](/docs/channels/slack#thread-context).
418
418
 
419
419
  `threadTs` and `initialMessage` are mutually exclusive: pass `threadTs` to join an existing
@@ -188,8 +188,8 @@ export default slackChannel({
188
188
  - **`onAppMention(ctx, message)`** -- decides whether to dispatch a turn for an inbound
189
189
  `app_mention`, with what `auth` context, and runs any pre-dispatch side effects (typing
190
190
  indicators, logging, feature-flag lookups). Return `{ auth }` to dispatch or `null` to silently
191
- drop the mention. Return `{ auth, modelContext }` to add ephemeral messages to the next model
192
- call without writing them to durable session history. May be sync or async; the framework awaits
191
+ drop the mention. Return `{ auth, context }` to append context strings as user messages in
192
+ session history before the delivery message. May be sync or async; the framework awaits
193
193
  the result before dispatching. Thrown errors are caught, logged, and drop the mention -- wrap
194
194
  best-effort side effects in `try/catch` if you want them to be non-fatal. The default
195
195
  `onAppMention` derives a workspace-scoped auth from the Slack actor and posts a `"Thinking…"`
@@ -212,19 +212,18 @@ run inside the workflow context, not on the inbound webhook side.
212
212
 
213
213
  When the bot is mentioned in an existing Slack thread, the triggering mention is delivered to the
214
214
  agent by default, but prior thread replies are not injected automatically. Fetch thread history in
215
- `onAppMention` or `onDirectMessage` and return `modelContext` when the agent should see that
216
- background on the next model call.
215
+ `onAppMention` or `onDirectMessage` and return `context` when the agent should see that
216
+ background.
217
217
 
218
218
  Use `since: "last-agent-reply"` for repeated tags in the same thread. It returns only messages
219
219
  after the agent's last Slack reply and before the current mention, so the injected context stays
220
- small and can be modeled as a `role: "user"` message without changing the system prompt.
220
+ small.
221
221
 
222
222
  ```ts
223
223
  import {
224
224
  defaultSlackAuth,
225
225
  loadThreadContextMessages,
226
226
  slackChannel,
227
- type ModelMessage,
228
227
  } from "experimental-ash/channels/slack";
229
228
 
230
229
  export default slackChannel({
@@ -242,23 +241,19 @@ export default slackChannel({
242
241
  .map((entry) => `${entry.isMe ? "you" : (entry.user ?? "user")}: ${entry.markdown}`)
243
242
  .join("\n");
244
243
 
245
- const modelContext: ModelMessage[] = [
246
- {
247
- role: "user",
248
- content:
249
- "Recent Slack thread messages since your last reply, oldest first. " +
250
- "Use them as background context for the current mention.\n\n" +
251
- transcript,
252
- },
244
+ const context = [
245
+ "Recent Slack thread messages since your last reply, oldest first. " +
246
+ "Use them as background context for the current mention.\n\n" +
247
+ transcript,
253
248
  ];
254
249
 
255
- return { auth, modelContext };
250
+ return { auth, context };
256
251
  },
257
252
  });
258
253
  ```
259
254
 
260
- `modelContext` is one-shot context: it is used for the model call that dispatches this inbound
261
- message and is never persisted to `session.history`.
255
+ `context` strings are appended as user messages to `session.history` before the delivery message.
256
+ They persist across the session and are visible to the model on all subsequent turns.
262
257
 
263
258
  ### Direct Messages
264
259
 
@@ -193,26 +193,22 @@ const agent = useAshAgent({
193
193
  });
194
194
  ```
195
195
 
196
- `clientContext` is rendered as ephemeral model context for the next turn only.
197
- It is never persisted to durable message history.
196
+ `clientContext` is appended as user messages to session history before
197
+ the delivery message. It persists across the session and is visible
198
+ to the model on all subsequent turns (until compaction summarizes it).
198
199
 
199
- Use authored lifecycle hooks for server-side enrichment:
200
+ Use dynamic instructions for server-side system prompt enrichment:
200
201
 
201
202
  ```ts
202
- // agent/hooks/profile.ts
203
- import { defineHook } from "experimental-ash/hooks";
204
-
205
- export default defineHook({
206
- lifecycle: {
207
- async session(_input, ctx) {
208
- return {
209
- modelContext: [
210
- {
211
- role: "system",
212
- content: `Session ${ctx.session.sessionId} has server-side profile context.`,
213
- },
214
- ],
215
- };
203
+ // agent/instructions/profile.ts
204
+ import { defineDynamic, defineInstructions } from "experimental-ash/instructions";
205
+
206
+ export default defineDynamic({
207
+ events: {
208
+ async "session.started"(_event, ctx) {
209
+ return defineInstructions({
210
+ markdown: `Session ${ctx.session.id} has server-side profile context.`,
211
+ });
216
212
  },
217
213
  },
218
214
  });
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";const log=createLogger(`channel.adapter`);function defaultDeliverResult(e){if(e.message!==void 0)return{inputResponses:e.inputResponses,message:e.message,modelContext:e.modelContext};if(e.inputResponses!==void 0&&e.inputResponses.length>0)return{inputResponses:e.inputResponses,modelContext:e.modelContext};if(e.modelContext!==void 0&&e.modelContext.length>0)return{modelContext:e.modelContext}}function getAdapterKind(e){return e.kind}async function callAdapterEventHandler(e,t,n){let r=e[t.type];if(r===void 0)return t;try{await r(`data`in t?t.data:void 0,n)}catch(n){log.error(`adapter event handler threw — event swallowed`,{adapterKind:getAdapterKind(e),eventType:t.type,error:n})}return t}export{callAdapterEventHandler,defaultDeliverResult,getAdapterKind};
1
+ import{createLogger}from"#internal/logging.js";const log=createLogger(`channel.adapter`);function defaultDeliverResult(e){if(e.message!==void 0)return{inputResponses:e.inputResponses,message:e.message,context:e.context,outputSchema:e.outputSchema};if(e.inputResponses!==void 0&&e.inputResponses.length>0)return{inputResponses:e.inputResponses,context:e.context,outputSchema:e.outputSchema};if(e.context!==void 0&&e.context.length>0)return{context:e.context,outputSchema:e.outputSchema};if(e.outputSchema!==void 0)return{outputSchema:e.outputSchema}}function getAdapterKind(e){return e.kind}async function callAdapterEventHandler(e,t,n){let r=e[t.type];if(r===void 0)return t;try{await r(`data`in t?t.data:void 0,n)}catch(n){log.error(`adapter event handler threw — event swallowed`,{adapterKind:getAdapterKind(e),eventType:t.type,error:n})}return t}export{callAdapterEventHandler,defaultDeliverResult,getAdapterKind};
@@ -1,9 +1,10 @@
1
- import type { ModelMessage, UserContent } from "ai";
1
+ import type { UserContent } from "ai";
2
2
  import type { CrossChannelReceiveFn } from "#channel/cross-channel-receive.js";
3
3
  import type { SessionAuthContext, SessionCallback } from "#channel/types.js";
4
4
  import type { InputResponse } from "#runtime/input/types.js";
5
5
  import type { Session } from "#channel/session.js";
6
6
  import type { RunMode } from "#shared/run-mode.js";
7
+ import type { JsonObject } from "#shared/json.js";
7
8
  export interface RouteHandlerArgs<TState = undefined> {
8
9
  send: SendFn<TState>;
9
10
  getSession: GetSessionFn;
@@ -23,13 +24,19 @@ export interface SendPayload {
23
24
  readonly message?: string | UserContent;
24
25
  readonly inputResponses?: readonly InputResponse[];
25
26
  /**
26
- * Ephemeral messages contributed by the channel, appended to the
27
- * dispatched turn's first model call via `StepInput.modelContext`.
28
- * Never persisted to durable session history. Use `role: "system"`
29
- * for background context that should land before the user message;
30
- * other roles land after the user message.
27
+ * Context strings contributed by the channel. Each entry is appended
28
+ * as a `role: "user"` message to `session.history` before the
29
+ * delivery message, persisted across the session.
31
30
  */
32
- readonly modelContext?: readonly ModelMessage[];
31
+ readonly context?: readonly string[];
32
+ /**
33
+ * Run-scoped JSON schema the turn's result must match. Orthogonal to
34
+ * {@link BaseSendOptions.mode}: a schema is enforced in either mode. Mode
35
+ * only decides what happens when the agent fails to produce it — a
36
+ * conversation run parks recoverably and waits for more input, a task run
37
+ * (which cannot wait) finishes as an error.
38
+ */
39
+ readonly outputSchema?: JsonObject;
33
40
  }
34
41
  export type SendFn<TState = undefined> = (input: string | UserContent | SendPayload, options: SendOptions<TState>) => Promise<Session>;
35
42
  type BaseSendOptions = {
@@ -1 +1 @@
1
- import{createSession}from"#channel/session.js";import{createLogger}from"#internal/logging.js";import{isRuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{serializeUrlFilePart}from"#internal/attachments/url-refs.js";const log=createLogger(`channel.send`);function createSendFn(t,r,i){return async(a,o)=>{let s=o.auth,c=o.callback,l=o.mode??`conversation`,u=o.state,d=o.continuationToken,f=`${i}:${d}`,{message:p,inputResponses:m,modelContext:h}=normalizeSendInput(a),g=serializeUrlFilePartsInMessage(p);try{let{sessionId:n}=await t.deliver({auth:s,continuationToken:f,payload:{inputResponses:m,message:g,modelContext:h}});return createSession(n,d,t)}catch(e){isRuntimeNoActiveSessionError(e)||log.warn(`deliver failed, falling back to starting a new session`,{continuationToken:f})}if(m&&m.length>0)throw Error(`Cannot deliver inputResponses — the target session was not found via continuation token.`);let _=u?{...r,state:{...r.state,...u}}:r;return createSession((await t.run({adapter:_,auth:s,capabilities:l===`conversation`?{requestInput:!0}:void 0,channelName:i,callback:c,continuationToken:f,input:{message:g??``,modelContext:h},mode:l})).sessionId,d,t)}}function serializeUrlFilePartsInMessage(e){if(e===void 0||typeof e==`string`)return e;let t=!1,n=e.map(e=>e.type===`file`&&e.data instanceof URL&&e.data.protocol!==`data:`?(t=!0,{...e,data:serializeUrlFilePart(e.data)}):e);return t?n:e}function normalizeSendInput(e){return typeof e==`string`||Array.isArray(e)?{message:e}:e}export{createSendFn};
1
+ import{createSession}from"#channel/session.js";import{createLogger}from"#internal/logging.js";import{isRuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{serializeUrlFilePart}from"#internal/attachments/url-refs.js";const log=createLogger(`channel.send`);function createSendFn(t,r,i){return async(a,o)=>{let s=o.auth,c=o.callback,l=o.mode??`conversation`,u=o.state,d=o.continuationToken,f=`${i}:${d}`,{message:p,inputResponses:m,context:h,outputSchema:g}=normalizeSendInput(a),_=serializeUrlFilePartsInMessage(p);try{let{sessionId:n}=await t.deliver({auth:s,continuationToken:f,payload:{inputResponses:m,message:_,context:h,outputSchema:g}});return createSession(n,d,t)}catch(e){isRuntimeNoActiveSessionError(e)||log.warn(`deliver failed, falling back to starting a new session`,{continuationToken:f})}if(m&&m.length>0)throw Error(`Cannot deliver inputResponses — the target session was not found via continuation token.`);let v=u?{...r,state:{...r.state,...u}}:r;return createSession((await t.run({adapter:v,auth:s,capabilities:l===`conversation`?{requestInput:!0}:void 0,channelName:i,callback:c,continuationToken:f,input:{message:_??``,context:h,outputSchema:g},mode:l})).sessionId,d,t)}}function serializeUrlFilePartsInMessage(e){if(e===void 0||typeof e==`string`)return e;let t=!1,n=e.map(e=>e.type===`file`&&e.data instanceof URL&&e.data.protocol!==`data:`?(t=!0,{...e,data:serializeUrlFilePart(e.data)}):e);return t?n:e}function normalizeSendInput(e){return typeof e==`string`||Array.isArray(e)?{message:e}:e}export{createSendFn};
@@ -1,9 +1,10 @@
1
- import type { ModelMessage, UserContent } from "ai";
1
+ import type { UserContent } from "ai";
2
2
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
3
3
  import type { RunMode } from "#shared/run-mode.js";
4
4
  import type { RuntimeActionResult } from "#runtime/actions/types.js";
5
5
  import type { InputRequest, InputResponse } from "#runtime/input/types.js";
6
6
  import type { ChannelAdapter } from "#channel/adapter.js";
7
+ import type { JsonObject } from "#shared/json.js";
7
8
  export type { ContextAccessor } from "#context/key.js";
8
9
  export type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
9
10
  /**
@@ -69,7 +70,8 @@ export type EventEmitFn = (event: HandleMessageStreamEvent) => Promise<void>;
69
70
  export interface DeliverPayload {
70
71
  readonly inputResponses?: readonly InputResponse[];
71
72
  readonly message?: string | UserContent;
72
- readonly modelContext?: readonly ModelMessage[];
73
+ readonly context?: readonly string[];
74
+ readonly outputSchema?: JsonObject;
73
75
  readonly [key: string]: unknown;
74
76
  }
75
77
  /**
@@ -213,7 +215,8 @@ export interface RunInput {
213
215
  readonly initiatorAuth?: SessionAuthContext | null;
214
216
  readonly input: {
215
217
  readonly message: string | UserContent;
216
- readonly modelContext?: readonly ModelMessage[];
218
+ readonly context?: readonly string[];
219
+ readonly outputSchema?: JsonObject;
217
220
  };
218
221
  readonly mode: RunMode;
219
222
  readonly parent?: SessionParent;
@@ -6,7 +6,7 @@ export { ClientSession } from "#client/session.js";
6
6
  export type { ClientAuth, ClientOptions, HeadersValue, HealthResult, MessageResult, OpenStreamOptions, SendMessageOptions, SendTurnInput, SessionState, TokenValue, } from "#client/types.js";
7
7
  export type { AshAgentReducer, AshAgentReducerEvent, ClientInputRespondedEvent, ClientMessageFailedEvent, ClientMessageSubmittedEvent, } from "#client/reducer.js";
8
8
  export type { AshMessageData, AshDynamicToolPart, AshMessageInputRequest, AshMessage, AshMessageMetadata, AshMessagePart, AshMessageToolMetadata, } from "#client/message-reducer.js";
9
- export type { ActionResultStreamEvent, ActionsRequestedStreamEvent, AssistantStepFinishReason, CompactionCompletedStreamEvent, CompactionRequestedStreamEvent, AuthorizationCompletedStreamEvent, ConnectionAuthorizationOutcome, AuthorizationRequiredStreamEvent, HandleMessageStreamEvent, InputRequestedStreamEvent, MessageAppendedStreamEvent, MessageCompletedStreamEvent, MessageReceivedStreamEvent, ReasoningAppendedStreamEvent, ReasoningCompletedStreamEvent, SessionCompletedStreamEvent, SessionFailedStreamEvent, SessionStartedStreamEvent, SessionWaitingStreamEvent, StepCompletedStreamEvent, StepFailedStreamEvent, StepStartedStreamEvent, SubagentCalledStreamEvent, SubagentChildEventStreamEvent, SubagentCompletedStreamEvent, SubagentStartedStreamEvent, TurnCompletedStreamEvent, TurnFailedStreamEvent, TurnStartedStreamEvent, } from "#protocol/message.js";
9
+ export type { ActionResultStreamEvent, ActionsRequestedStreamEvent, AssistantStepFinishReason, CompactionCompletedStreamEvent, CompactionRequestedStreamEvent, AuthorizationCompletedStreamEvent, ConnectionAuthorizationOutcome, AuthorizationRequiredStreamEvent, HandleMessageStreamEvent, InputRequestedStreamEvent, MessageAppendedStreamEvent, MessageCompletedStreamEvent, MessageReceivedStreamEvent, ReasoningAppendedStreamEvent, ReasoningCompletedStreamEvent, ResultCompletedStreamEvent, SessionCompletedStreamEvent, SessionFailedStreamEvent, SessionStartedStreamEvent, SessionWaitingStreamEvent, StepCompletedStreamEvent, StepFailedStreamEvent, StepStartedStreamEvent, SubagentCalledStreamEvent, SubagentChildEventStreamEvent, SubagentCompletedStreamEvent, SubagentStartedStreamEvent, TurnCompletedStreamEvent, TurnFailedStreamEvent, TurnStartedStreamEvent, } from "#protocol/message.js";
10
10
  export { isCurrentTurnBoundaryEvent } from "#protocol/message.js";
11
11
  export type { InputOption, InputRequest, InputResponse } from "#runtime/input/types.js";
12
12
  export { inputOptionSchema, inputRequestSchema, inputResponseSchema, isInputRequest, isInputResponse, } from "#runtime/input/types.js";
@@ -16,6 +16,7 @@ export interface AshMessage {
16
16
  }
17
17
  export interface AshMessageMetadata {
18
18
  readonly optimistic?: true;
19
+ readonly result?: unknown;
19
20
  readonly status?: "complete" | "failed" | "streaming" | "submitted";
20
21
  readonly turnId?: string;
21
22
  }
@@ -1 +1 @@
1
- function defaultMessageReducer(){return{initial(){return{messages:[]}},reduce(e,t){return reduceMessageData(e,t)}}}function reduceMessageData(e,t){switch(t.type){case`client.message.submitted`:return upsertMessage(e,{id:optimisticUserMessageId(t.data.submissionId),metadata:{optimistic:!0,status:`submitted`},parts:[{type:`text`,text:t.data.message}],role:`user`});case`client.message.failed`:return upsertMessage(e,{id:optimisticUserMessageId(t.data.submissionId),metadata:{optimistic:!0,status:`failed`},parts:[{type:`text`,text:t.data.message}],role:`user`});case`client.input.responded`:{let n=e;for(let e of t.data.responses)n=respondToInputRequest(n,e);return n}case`message.received`:return upsertMessage(e,{id:`${t.data.turnId}:user`,metadata:{status:`complete`,turnId:t.data.turnId},parts:[{type:`text`,text:t.data.message,state:`done`}],role:`user`});case`step.started`:return updateAssistantMessage(e,t.data.turnId,e=>ensureStepStartPart(e,t.data.stepIndex));case`reasoning.appended`:return updateAssistantMessage(e,t.data.turnId,e=>upsertPart(ensureStepStartPart(e,t.data.stepIndex),{state:`streaming`,stepIndex:t.data.stepIndex,text:t.data.reasoningSoFar,type:`reasoning`}));case`reasoning.completed`:return updateAssistantMessage(e,t.data.turnId,e=>upsertPart(ensureStepStartPart(e,t.data.stepIndex),{state:`done`,stepIndex:t.data.stepIndex,text:t.data.reasoning,type:`reasoning`}));case`actions.requested`:{let n=e;for(let e of t.data.actions){let r=normalizeActionRequest(e);n=updateAssistantMessage(n,t.data.turnId,n=>upsertPart(ensureStepStartPart(n,t.data.stepIndex),{input:`input`in e?e.input:void 0,state:`input-available`,stepIndex:t.data.stepIndex,toolCallId:e.callId,toolMetadata:createToolMetadata(r),toolName:r.toolName,type:`dynamic-tool`}))}return n}case`input.requested`:{let n=e;for(let e of t.data.requests){let r=normalizeActionRequest(e.action);n=updateAssistantMessage(n,t.data.turnId,n=>upsertPart(ensureStepStartPart(n,t.data.stepIndex),{approval:{id:e.requestId},input:e.action.input,state:`approval-requested`,stepIndex:t.data.stepIndex,toolCallId:e.action.callId,toolMetadata:createToolMetadata(r,{inputRequest:toMessageInputRequest(e)}),toolName:r.toolName,type:`dynamic-tool`}))}return n}case`action.result`:{let n=normalizeActionResult(t.data.result),r=findToolPart(e,t.data.result.callId),i=t.data.error?.code===`TOOL_EXECUTION_DENIED`,a=t.data.status===`failed`&&!i,o=r?.approval?.id??t.data.result.callId,s=mergeToolMetadata(r?.toolMetadata,createToolMetadata(n)),c={input:r?.input,stepIndex:t.data.stepIndex,toolCallId:t.data.result.callId,toolMetadata:s,toolName:r?.toolName??n.toolName,type:`dynamic-tool`},l;return l=i?{...c,approval:{approved:!1,id:o,reason:t.data.error?.message},state:`output-denied`}:a?{...c,approval:approvedApproval(r),errorText:t.data.error?.message??stringifyUnknown(t.data.result.output),state:`output-error`}:{...c,approval:approvedApproval(r),output:t.data.result.output,state:`output-available`},r===void 0?updateAssistantMessage(e,t.data.turnId,e=>upsertPart(ensureStepStartPart(e,t.data.stepIndex),l)):updateToolPart(e,t.data.result.callId,l)}case`message.appended`:return updateAssistantMessage(e,t.data.turnId,e=>upsertPart(ensureStepStartPart(e,t.data.stepIndex),{state:`streaming`,stepIndex:t.data.stepIndex,text:t.data.messageSoFar,type:`text`}));case`message.completed`:return updateAssistantMessage(e,t.data.turnId,e=>t.data.message===null?completeExistingTextPart(e):upsertPart(ensureStepStartPart(e,t.data.stepIndex),{state:`done`,stepIndex:t.data.stepIndex,text:t.data.message,type:`text`}));case`turn.completed`:return updateAssistantMetadata(e,t.data.turnId,{status:`complete`});case`turn.failed`:case`session.failed`:return e;default:return e}}function respondToInputRequest(e,t){let n=findToolPartByApprovalId(e,t.requestId);if(!n)return e;let r={id:t.requestId};return t.text!==void 0&&(r.reason=t.text),updateToolPart(e,n.toolCallId,{approval:r,input:n.input,state:`approval-responded`,stepIndex:n.stepIndex,toolCallId:n.toolCallId,toolMetadata:mergeToolMetadata(n.toolMetadata,{ash:{inputResponse:t,kind:n.toolMetadata?.ash?.kind??`unknown`,name:n.toolMetadata?.ash?.name??n.toolName}}),toolName:n.toolName,type:`dynamic-tool`})}function updateAssistantMessage(e,t,n){return upsertMessage(e,n(e.messages.find(e=>e.role===`assistant`&&e.metadata?.turnId===t)??createAssistantMessage(t)))}function updateAssistantMetadata(e,t,n){return updateAssistantMessage(e,t,e=>({...e,metadata:{...e.metadata,...n}}))}function createAssistantMessage(e){return{id:`${e}:assistant`,metadata:{status:`streaming`,turnId:e},parts:[],role:`assistant`}}function ensureStepStartPart(e,t){let n=e.parts.filter(e=>e.type===`step-start`).length;if(n>t)return e;let r=t-n+1;return{...e,parts:[...e.parts,...Array.from({length:r},()=>({type:`step-start`}))]}}function upsertPart(e,t){let n=e.parts.findIndex(e=>partKey(e)===partKey(t)),r=n===-1?[...e.parts,t]:[...e.parts.slice(0,n),t,...e.parts.slice(n+1)];return{...e,metadata:{...e.metadata,status:t.type===`text`&&t.state===`done`?`complete`:`streaming`},parts:r}}function completeExistingTextPart(e){let t=findLastIndex(e.parts,e=>e.type===`text`);if(t===-1)return e;let n=e.parts[t];return n?.type===`text`?{...e,metadata:{...e.metadata,status:`complete`},parts:[...e.parts.slice(0,t),{...n,state:`done`},...e.parts.slice(t+1)]}:e}function updateToolPart(e,t,n){let r=e.messages.find(e=>e.role===`assistant`&&e.parts.some(e=>e.type===`dynamic-tool`&&e.toolCallId===t));return r?upsertMessage(e,upsertPart(r,n)):e}function findToolPart(e,t){for(let n of e.messages)for(let e of n.parts)if(e.type===`dynamic-tool`&&e.toolCallId===t)return e}function findToolPartByApprovalId(e,t){for(let n of e.messages)for(let e of n.parts)if(e.type===`dynamic-tool`&&e.approval?.id===t)return e}function partKey(e){switch(e.type){case`text`:return`text:${e.stepIndex??0}`;case`reasoning`:return`reasoning:${e.stepIndex??0}`;case`step-start`:return`step-start`;case`dynamic-tool`:return`dynamic-tool:${e.toolCallId}`}}function upsertMessage(e,t){let n=e.messages.findIndex(e=>e.id===t.id);return n===-1?{messages:[...e.messages,t]}:{messages:[...e.messages.slice(0,n),t,...e.messages.slice(n+1)]}}function toMessageInputRequest(e){return{allowFreeform:e.allowFreeform,display:e.display,options:e.options,prompt:e.prompt,requestId:e.requestId}}function createToolMetadata(e,t){return{ash:{inputRequest:t?.inputRequest,kind:e.kind,name:e.name}}}function mergeToolMetadata(e,t){let n=t.ash?.kind??e?.ash?.kind??`unknown`,r=t.ash?.name??e?.ash?.name??`unknown`;return{ash:{...e?.ash,...t.ash,inputRequest:t.ash?.inputRequest??e?.ash?.inputRequest,inputResponse:t.ash?.inputResponse??e?.ash?.inputResponse,kind:n,name:r}}}function approvedApproval(e){if(e?.approval?.id)return{approved:!0,id:e.approval.id,isAutomatic:e.approval.isAutomatic,reason:e.approval.reason}}function normalizeActionRequest(e){switch(e.kind){case`load-skill`:return{kind:`load-skill`,name:`load_skill`,toolName:`ash:load-skill`};case`tool-call`:return{kind:`tool-call`,name:e.toolName,toolName:e.toolName};case`subagent-call`:return{kind:`subagent-call`,name:e.subagentName,toolName:`ash:subagent:${e.subagentName}`};case`remote-agent-call`:return{kind:`subagent-call`,name:e.remoteAgentName,toolName:`ash:subagent:${e.remoteAgentName}`}}}function normalizeActionResult(e){switch(e.kind){case`load-skill-result`:return{kind:`load-skill`,name:e.name??`load_skill`,toolName:`ash:load-skill`};case`tool-result`:return{kind:`tool-call`,name:e.toolName,toolName:e.toolName};case`subagent-result`:return{kind:`subagent-call`,name:e.subagentName,toolName:`ash:subagent:${e.subagentName}`}}}function optimisticUserMessageId(e){return`optimistic:${e}:user`}function stringifyUnknown(e){if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return`Action failed.`}}function findLastIndex(e,t){for(let n=e.length-1;n>=0;--n)if(t(e[n]))return n;return-1}export{defaultMessageReducer};
1
+ function defaultMessageReducer(){return{initial(){return{messages:[]}},reduce(e,t){return reduceMessageData(e,t)}}}function reduceMessageData(e,t){switch(t.type){case`client.message.submitted`:return upsertMessage(e,{id:optimisticUserMessageId(t.data.submissionId),metadata:{optimistic:!0,status:`submitted`},parts:[{type:`text`,text:t.data.message}],role:`user`});case`client.message.failed`:return upsertMessage(e,{id:optimisticUserMessageId(t.data.submissionId),metadata:{optimistic:!0,status:`failed`},parts:[{type:`text`,text:t.data.message}],role:`user`});case`client.input.responded`:{let n=e;for(let e of t.data.responses)n=respondToInputRequest(n,e);return n}case`message.received`:return upsertMessage(e,{id:`${t.data.turnId}:user`,metadata:{status:`complete`,turnId:t.data.turnId},parts:[{type:`text`,text:t.data.message,state:`done`}],role:`user`});case`step.started`:return updateAssistantMessage(e,t.data.turnId,e=>ensureStepStartPart(e,t.data.stepIndex));case`reasoning.appended`:return updateAssistantMessage(e,t.data.turnId,e=>upsertPart(ensureStepStartPart(e,t.data.stepIndex),{state:`streaming`,stepIndex:t.data.stepIndex,text:t.data.reasoningSoFar,type:`reasoning`}));case`reasoning.completed`:return updateAssistantMessage(e,t.data.turnId,e=>upsertPart(ensureStepStartPart(e,t.data.stepIndex),{state:`done`,stepIndex:t.data.stepIndex,text:t.data.reasoning,type:`reasoning`}));case`actions.requested`:{let n=e;for(let e of t.data.actions){let r=normalizeActionRequest(e);n=updateAssistantMessage(n,t.data.turnId,n=>upsertPart(ensureStepStartPart(n,t.data.stepIndex),{input:`input`in e?e.input:void 0,state:`input-available`,stepIndex:t.data.stepIndex,toolCallId:e.callId,toolMetadata:createToolMetadata(r),toolName:r.toolName,type:`dynamic-tool`}))}return n}case`input.requested`:{let n=e;for(let e of t.data.requests){let r=normalizeActionRequest(e.action);n=updateAssistantMessage(n,t.data.turnId,n=>upsertPart(ensureStepStartPart(n,t.data.stepIndex),{approval:{id:e.requestId},input:e.action.input,state:`approval-requested`,stepIndex:t.data.stepIndex,toolCallId:e.action.callId,toolMetadata:createToolMetadata(r,{inputRequest:toMessageInputRequest(e)}),toolName:r.toolName,type:`dynamic-tool`}))}return n}case`action.result`:{let n=normalizeActionResult(t.data.result),r=findToolPart(e,t.data.result.callId),i=t.data.error?.code===`TOOL_EXECUTION_DENIED`,a=t.data.status===`failed`&&!i,o=r?.approval?.id??t.data.result.callId,s=mergeToolMetadata(r?.toolMetadata,createToolMetadata(n)),c={input:r?.input,stepIndex:t.data.stepIndex,toolCallId:t.data.result.callId,toolMetadata:s,toolName:r?.toolName??n.toolName,type:`dynamic-tool`},l;return l=i?{...c,approval:{approved:!1,id:o,reason:t.data.error?.message},state:`output-denied`}:a?{...c,approval:approvedApproval(r),errorText:t.data.error?.message??stringifyUnknown(t.data.result.output),state:`output-error`}:{...c,approval:approvedApproval(r),output:t.data.result.output,state:`output-available`},r===void 0?updateAssistantMessage(e,t.data.turnId,e=>upsertPart(ensureStepStartPart(e,t.data.stepIndex),l)):updateToolPart(e,t.data.result.callId,l)}case`message.appended`:return updateAssistantMessage(e,t.data.turnId,e=>upsertPart(ensureStepStartPart(e,t.data.stepIndex),{state:`streaming`,stepIndex:t.data.stepIndex,text:t.data.messageSoFar,type:`text`}));case`message.completed`:return updateAssistantMessage(e,t.data.turnId,e=>t.data.message===null?completeExistingTextPart(e):upsertPart(ensureStepStartPart(e,t.data.stepIndex),{state:`done`,stepIndex:t.data.stepIndex,text:t.data.message,type:`text`}));case`result.completed`:return updateAssistantMetadata(e,t.data.turnId,{result:t.data.result});case`turn.completed`:return updateAssistantMetadata(e,t.data.turnId,{status:`complete`});case`turn.failed`:case`session.failed`:return e;default:return e}}function respondToInputRequest(e,t){let n=findToolPartByApprovalId(e,t.requestId);if(!n)return e;let r={id:t.requestId};return t.text!==void 0&&(r.reason=t.text),updateToolPart(e,n.toolCallId,{approval:r,input:n.input,state:`approval-responded`,stepIndex:n.stepIndex,toolCallId:n.toolCallId,toolMetadata:mergeToolMetadata(n.toolMetadata,{ash:{inputResponse:t,kind:n.toolMetadata?.ash?.kind??`unknown`,name:n.toolMetadata?.ash?.name??n.toolName}}),toolName:n.toolName,type:`dynamic-tool`})}function updateAssistantMessage(e,t,n){return upsertMessage(e,n(e.messages.find(e=>e.role===`assistant`&&e.metadata?.turnId===t)??createAssistantMessage(t)))}function updateAssistantMetadata(e,t,n){return updateAssistantMessage(e,t,e=>({...e,metadata:{...e.metadata,...n}}))}function createAssistantMessage(e){return{id:`${e}:assistant`,metadata:{status:`streaming`,turnId:e},parts:[],role:`assistant`}}function ensureStepStartPart(e,t){let n=e.parts.filter(e=>e.type===`step-start`).length;if(n>t)return e;let r=t-n+1;return{...e,parts:[...e.parts,...Array.from({length:r},()=>({type:`step-start`}))]}}function upsertPart(e,t){let n=e.parts.findIndex(e=>partKey(e)===partKey(t)),r=n===-1?[...e.parts,t]:[...e.parts.slice(0,n),t,...e.parts.slice(n+1)];return{...e,metadata:{...e.metadata,status:t.type===`text`&&t.state===`done`?`complete`:`streaming`},parts:r}}function completeExistingTextPart(e){let t=findLastIndex(e.parts,e=>e.type===`text`);if(t===-1)return e;let n=e.parts[t];return n?.type===`text`?{...e,metadata:{...e.metadata,status:`complete`},parts:[...e.parts.slice(0,t),{...n,state:`done`},...e.parts.slice(t+1)]}:e}function updateToolPart(e,t,n){let r=e.messages.find(e=>e.role===`assistant`&&e.parts.some(e=>e.type===`dynamic-tool`&&e.toolCallId===t));return r?upsertMessage(e,upsertPart(r,n)):e}function findToolPart(e,t){for(let n of e.messages)for(let e of n.parts)if(e.type===`dynamic-tool`&&e.toolCallId===t)return e}function findToolPartByApprovalId(e,t){for(let n of e.messages)for(let e of n.parts)if(e.type===`dynamic-tool`&&e.approval?.id===t)return e}function partKey(e){switch(e.type){case`text`:return`text:${e.stepIndex??0}`;case`reasoning`:return`reasoning:${e.stepIndex??0}`;case`step-start`:return`step-start`;case`dynamic-tool`:return`dynamic-tool:${e.toolCallId}`}}function upsertMessage(e,t){let n=e.messages.findIndex(e=>e.id===t.id);return n===-1?{messages:[...e.messages,t]}:{messages:[...e.messages.slice(0,n),t,...e.messages.slice(n+1)]}}function toMessageInputRequest(e){return{allowFreeform:e.allowFreeform,display:e.display,options:e.options,prompt:e.prompt,requestId:e.requestId}}function createToolMetadata(e,t){return{ash:{inputRequest:t?.inputRequest,kind:e.kind,name:e.name}}}function mergeToolMetadata(e,t){let n=t.ash?.kind??e?.ash?.kind??`unknown`,r=t.ash?.name??e?.ash?.name??`unknown`;return{ash:{...e?.ash,...t.ash,inputRequest:t.ash?.inputRequest??e?.ash?.inputRequest,inputResponse:t.ash?.inputResponse??e?.ash?.inputResponse,kind:n,name:r}}}function approvedApproval(e){if(e?.approval?.id)return{approved:!0,id:e.approval.id,isAutomatic:e.approval.isAutomatic,reason:e.approval.reason}}function normalizeActionRequest(e){switch(e.kind){case`load-skill`:return{kind:`load-skill`,name:`load_skill`,toolName:`ash:load-skill`};case`tool-call`:return{kind:`tool-call`,name:e.toolName,toolName:e.toolName};case`subagent-call`:return{kind:`subagent-call`,name:e.subagentName,toolName:`ash:subagent:${e.subagentName}`};case`remote-agent-call`:return{kind:`subagent-call`,name:e.remoteAgentName,toolName:`ash:subagent:${e.remoteAgentName}`}}}function normalizeActionResult(e){switch(e.kind){case`load-skill-result`:return{kind:`load-skill`,name:e.name??`load_skill`,toolName:`ash:load-skill`};case`tool-result`:return{kind:`tool-call`,name:e.toolName,toolName:e.toolName};case`subagent-result`:return{kind:`subagent-call`,name:e.subagentName,toolName:`ash:subagent:${e.subagentName}`}}}function optimisticUserMessageId(e){return`optimistic:${e}:user`}function stringifyUnknown(e){if(typeof e==`string`)return e;try{return JSON.stringify(e)}catch{return`Action failed.`}}function findLastIndex(e,t){for(let n=e.length-1;n>=0;--n)if(t(e[n]))return n;return-1}export{defaultMessageReducer};
@@ -16,7 +16,7 @@ interface MessageResponseInput {
16
16
  * separately — either collected via {@link result} or iterated with
17
17
  * `for await...of`.
18
18
  */
19
- export declare class MessageResponse implements AsyncIterable<HandleMessageStreamEvent> {
19
+ export declare class MessageResponse<TOutput = unknown> implements AsyncIterable<HandleMessageStreamEvent> {
20
20
  #private;
21
21
  /**
22
22
  * Continuation token returned by the server for follow-up messages.
@@ -32,7 +32,7 @@ export declare class MessageResponse implements AsyncIterable<HandleMessageStrea
32
32
  * Consumes the full event stream and returns the aggregated
33
33
  * {@link MessageResult}.
34
34
  */
35
- result(): Promise<MessageResult>;
35
+ result(): Promise<MessageResult<TOutput>>;
36
36
  /**
37
37
  * Yields stream events one at a time.
38
38
  *
@@ -1 +1 @@
1
- import{deriveResultStatus,extractCompletedMessage}from"#client/session-utils.js";var MessageResponse=class{continuationToken;sessionId;#e=!1;#t;constructor(e){this.continuationToken=e.continuationToken,this.sessionId=e.sessionId,this.#t=e.createStream}async result(){let t=[];for await(let e of this)t.push(e);return{events:t,message:extractCompletedMessage(t),sessionId:this.sessionId,status:deriveResultStatus(t)}}[Symbol.asyncIterator](){if(this.#e)throw Error(`MessageResponse has already been consumed.`);return this.#e=!0,this.#t()}};export{MessageResponse};
1
+ import{deriveResultStatus,extractCompletedMessage}from"#client/session-utils.js";import{extractCompletedResult}from"#client/output-schema.js";var MessageResponse=class{continuationToken;sessionId;#e=!1;#t;constructor(e){this.continuationToken=e.continuationToken,this.sessionId=e.sessionId,this.#t=e.createStream}async result(){let t=[];for await(let e of this)t.push(e);return{data:extractCompletedResult(t),events:t,message:extractCompletedMessage(t),sessionId:this.sessionId,status:deriveResultStatus(t)}}[Symbol.asyncIterator](){if(this.#e)throw Error(`MessageResponse has already been consumed.`);return this.#e=!0,this.#t()}};export{MessageResponse};
@@ -0,0 +1,12 @@
1
+ import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
2
+ import type { HandleMessageStreamEvent } from "#protocol/message.js";
3
+ import type { JsonObject } from "#shared/json.js";
4
+ /**
5
+ * Normalizes a client-supplied output schema into the wire-safe JSON Schema
6
+ * representation accepted by Ash message routes.
7
+ */
8
+ export declare function normalizeOutputSchemaForRequest<TOutput>(schema: StandardJSONSchemaV1<unknown, TOutput> | JsonObject | undefined): JsonObject | undefined;
9
+ /**
10
+ * Extracts the most recent finalized structured result from a turn event list.
11
+ */
12
+ export declare function extractCompletedResult<TOutput>(events: readonly HandleMessageStreamEvent[]): TOutput | undefined;
@@ -0,0 +1 @@
1
+ import{normalizeJsonSchemaDefinition}from"#shared/json-schema.js";function normalizeOutputSchemaForRequest(t){return t===void 0?void 0:normalizeJsonSchemaDefinition(t)}function extractCompletedResult(e){let t;for(let n of e)isResultCompletedEvent(n)&&(t=n.data.result);return t}function isResultCompletedEvent(e){return e.type===`result.completed`}export{extractCompletedResult,normalizeOutputSchemaForRequest};
@@ -36,14 +36,14 @@ export declare class ClientSession {
36
36
  * The session's state is updated automatically after the stream is
37
37
  * consumed.
38
38
  */
39
- sendMessage(message: string, options?: SendMessageOptions): Promise<MessageResponse>;
39
+ sendMessage<TOutput = unknown>(message: string, options?: SendMessageOptions<TOutput>): Promise<MessageResponse<TOutput>>;
40
40
  /**
41
41
  * Sends one turn payload to the agent.
42
42
  *
43
43
  * Use this to submit follow-up text, HITL results, or both in a single
44
44
  * request.
45
45
  */
46
- send(input: SendTurnInput, options?: SendMessageOptions): Promise<MessageResponse>;
46
+ send<TOutput = unknown>(input: SendTurnInput, options?: SendMessageOptions<TOutput>): Promise<MessageResponse<TOutput>>;
47
47
  /**
48
48
  * Opens this session's event stream using the current session ID and stream
49
49
  * index.
@@ -1 +1 @@
1
- import{ASH_CREATE_SESSION_ROUTE_PATH,createAshContinueSessionRoutePath,createAshMessageStreamRoutePath}from"#protocol/routes.js";import{openStreamIterable}from"#client/open-stream.js";import{ASH_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{ClientError}from"#client/client-error.js";import{advanceSession}from"#client/session-utils.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";var ClientSession=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get state(){return this.#t}async sendMessage(e,t){return this.send({message:e},t)}async send(e,t){let n=this.#t,{continuationToken:r,sessionId:i}=await this.#n(e,n,t);return new MessageResponse({continuationToken:r,createStream:()=>this.#r(i,r,n,t),sessionId:i})}openStream(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);return openStreamIterable({host:this.#e.host,maxReconnectAttempts:this.#e.maxReconnectAttempts,resolveHeaders:()=>this.#e.resolveHeaders(),sessionId:t,signal:e?.signal,startIndex:e?.startIndex??this.#t.streamIndex})}async#n(n,r,a){let s=r.sessionId?createAshContinueSessionRoutePath(r.sessionId):ASH_CREATE_SESSION_ROUTE_PATH,c=createClientUrl(this.#e.host,s),l=await this.#e.resolveHeaders(a?.headers);l.set(`content-type`,`application/json`);let u=createHandleMessageBody({input:n,session:r});if(u===null)throw Error(`Session.send requires a non-empty message, inputResponses, or both.`);let d=await fetch(c,{body:JSON.stringify(u),headers:l,method:`POST`,signal:a?.signal??null});if(!d.ok){let e=await d.text();throw new ClientError(d.status,e)}let f=await d.json(),p=(typeof f.sessionId==`string`?f.sessionId:void 0)??d.headers.get(ASH_SESSION_ID_HEADER)?.trim()??r.sessionId;if(!p)throw Error(`Message route did not return a session id.`);return{continuationToken:typeof f.continuationToken==`string`?f.continuationToken:void 0,sessionId:p}}async*#r(e,t,n,r){let i=[];try{let t=n.sessionId===e?n.streamIndex:0,o=this.#e.maxReconnectAttempts;for(;;){let n=await this.#i(e,t,r?.signal),s=!1;try{for await(let e of readNdjsonStream(n))if(i.push(e),t+=1,yield e,isCurrentTurnBoundaryEvent(e)){s=!0;break}}catch(e){if(!isStreamDisconnectError(e))throw e}if(s||o<=0)break;--o}}finally{this.#t=advanceSession({continuationToken:t,events:i,sessionId:e,session:n})}}async#i(e,t,r){let i=createClientUrl(this.#e.host,createAshMessageStreamRoutePath(e),t>0?{startIndex:String(t)}:void 0),a=await this.#e.resolveHeaders(),s=await fetch(i,{headers:a,signal:r??null});if(!s.ok){let e=await s.text();throw new ClientError(s.status,e)}if(!s.body)throw new ClientError(s.status,`Response body is null.`);return s.body}};function createHandleMessageBody(e){let t={};return e.input.message!==void 0&&(t.message=e.input.message),e.input.inputResponses!==void 0&&e.input.inputResponses.length>0&&(t.inputResponses=e.input.inputResponses),e.input.clientContext!==void 0&&(t.clientContext=e.input.clientContext),e.session.continuationToken!==void 0&&(t.continuationToken=e.session.continuationToken),Object.keys(t).length===0||e.session.continuationToken===void 0&&t.message===void 0||e.session.continuationToken!==void 0&&t.message===void 0&&t.inputResponses===void 0?null:t}export{ClientSession};
1
+ import{ASH_CREATE_SESSION_ROUTE_PATH,createAshContinueSessionRoutePath,createAshMessageStreamRoutePath}from"#protocol/routes.js";import{openStreamIterable}from"#client/open-stream.js";import{ASH_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{ClientError}from"#client/client-error.js";import{advanceSession}from"#client/session-utils.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{normalizeOutputSchemaForRequest}from"#client/output-schema.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";var ClientSession=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get state(){return this.#t}async sendMessage(e,t){return this.send({message:e},t)}async send(e,t){let n=this.#t,{continuationToken:r,sessionId:i}=await this.#n(e,n,t);return new MessageResponse({continuationToken:r,createStream:()=>this.#r(i,r,n,t),sessionId:i})}openStream(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);return openStreamIterable({host:this.#e.host,maxReconnectAttempts:this.#e.maxReconnectAttempts,resolveHeaders:()=>this.#e.resolveHeaders(),sessionId:t,signal:e?.signal,startIndex:e?.startIndex??this.#t.streamIndex})}async#n(n,r,a){let s=r.sessionId?createAshContinueSessionRoutePath(r.sessionId):ASH_CREATE_SESSION_ROUTE_PATH,c=createClientUrl(this.#e.host,s),l=await this.#e.resolveHeaders(a?.headers);l.set(`content-type`,`application/json`);let u=createHandleMessageBody({input:n,outputSchema:normalizeOutputSchemaForRequest(a?.outputSchema),session:r});if(u===null)throw Error(`Session.send requires a non-empty message, inputResponses, or both.`);let d=await fetch(c,{body:JSON.stringify(u),headers:l,method:`POST`,signal:a?.signal??null});if(!d.ok){let e=await d.text();throw new ClientError(d.status,e)}let f=await d.json(),p=(typeof f.sessionId==`string`?f.sessionId:void 0)??d.headers.get(ASH_SESSION_ID_HEADER)?.trim()??r.sessionId;if(!p)throw Error(`Message route did not return a session id.`);return{continuationToken:typeof f.continuationToken==`string`?f.continuationToken:void 0,sessionId:p}}async*#r(e,t,n,r){let i=[];try{let t=n.sessionId===e?n.streamIndex:0,o=this.#e.maxReconnectAttempts;for(;;){let n=await this.#i(e,t,r?.signal),s=!1;try{for await(let e of readNdjsonStream(n))if(i.push(e),t+=1,yield e,isCurrentTurnBoundaryEvent(e)){s=!0;break}}catch(e){if(!isStreamDisconnectError(e))throw e}if(s||o<=0)break;--o}}finally{this.#t=advanceSession({continuationToken:t,events:i,sessionId:e,session:n})}}async#i(e,t,r){let i=createClientUrl(this.#e.host,createAshMessageStreamRoutePath(e),t>0?{startIndex:String(t)}:void 0),a=await this.#e.resolveHeaders(),s=await fetch(i,{headers:a,signal:r??null});if(!s.ok){let e=await s.text();throw new ClientError(s.status,e)}if(!s.body)throw new ClientError(s.status,`Response body is null.`);return s.body}};function createHandleMessageBody(e){let t={};return e.input.message!==void 0&&(t.message=e.input.message),e.input.inputResponses!==void 0&&e.input.inputResponses.length>0&&(t.inputResponses=e.input.inputResponses),e.input.clientContext!==void 0&&(t.clientContext=e.input.clientContext),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),e.session.continuationToken!==void 0&&(t.continuationToken=e.session.continuationToken),Object.keys(t).length===0||e.session.continuationToken===void 0&&t.message===void 0||e.session.continuationToken!==void 0&&t.message===void 0&&t.inputResponses===void 0?null:t}export{ClientSession};
@@ -1,4 +1,5 @@
1
1
  import type { UserContent } from "ai";
2
+ import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
2
3
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
3
4
  import type { InputResponse } from "#runtime/input/types.js";
4
5
  import type { JsonObject } from "#shared/json.js";
@@ -54,7 +55,16 @@ export interface ClientOptions {
54
55
  /**
55
56
  * Per-message options for {@link Client.sendMessage}.
56
57
  */
57
- export interface SendMessageOptions {
58
+ export interface SendMessageOptions<TOutput = unknown> {
59
+ /**
60
+ * Optional schema the harness must satisfy before this turn terminates.
61
+ *
62
+ * The client lowers Standard Schema implementations (Zod, Valibot,
63
+ * ArkType, etc.) to JSON Schema before sending the request. The server is
64
+ * authoritative for validation; {@link MessageResult.data} is typed to this
65
+ * schema's output type and is not revalidated client-side.
66
+ */
67
+ readonly outputSchema?: StandardJSONSchemaV1<unknown, TOutput> | JsonObject;
58
68
  /**
59
69
  * Abort signal for cancelling the request.
60
70
  */
@@ -104,7 +114,12 @@ export interface OpenStreamOptions {
104
114
  * Aggregated result of one message turn, returned by
105
115
  * {@link MessageResponse.result}.
106
116
  */
107
- export interface MessageResult {
117
+ export interface MessageResult<TOutput = unknown> {
118
+ /**
119
+ * Final structured result emitted by the harness, when this turn requested
120
+ * an output schema and the server fulfilled it.
121
+ */
122
+ readonly data: TOutput | undefined;
108
123
  /**
109
124
  * The final completed assistant message text, or `undefined` if no terminal
110
125
  * `message.completed` event was observed.
@@ -19,6 +19,7 @@ export interface CompileFromMemoryInput {
19
19
  readonly agentRoot?: string;
20
20
  /** Model id assigned to the synthetic agent config. */
21
21
  readonly model: string;
22
+ readonly outputSchema?: JsonObject;
22
23
  /**
23
24
  * Authored tools to project into the compiled manifest and module map.
24
25
  *
@@ -1 +1 @@
1
- import{ROOT_COMPILED_AGENT_NODE_ID,createCompiledAgentManifest}from"#compiler/manifest.js";function compileFromMemory(t){let n=t.appRoot??`/virtual/ash-memory-app`,r=t.agentRoot??`${n}/agent`,i=t.name??`memory-agent`,a={model:{id:t.model},name:i},o=(t.tools??[]).map(e=>({description:e.description??`${e.name} test tool.`,inputSchema:e.inputSchema??null,logicalPath:`tools/${e.name}.ts`,name:e.name,sourceId:createMemorySourceId(`tools/${e.name}.ts`),sourceKind:`module`}));return{manifest:createCompiledAgentManifest({agentRoot:r,appRoot:n,config:a,skills:(t.skills??[]).map(e=>({description:e.description,logicalPath:`skills/${e.name}.md`,markdown:e.markdown??`# ${e.name}\n`,name:e.name,sourceId:createMemorySourceId(`skills/${e.name}.md`),sourceKind:`markdown`})),tools:o}),moduleMap:{nodes:{[ROOT_COMPILED_AGENT_NODE_ID]:{modules:Object.fromEntries(o.map(e=>[e.sourceId,Object.freeze({})]))}}}}}function createMemorySourceId(e){return`memory::${e}`}export{compileFromMemory};
1
+ import{ROOT_COMPILED_AGENT_NODE_ID,createCompiledAgentManifest}from"#compiler/manifest.js";function compileFromMemory(t){let n=t.appRoot??`/virtual/ash-memory-app`,r=t.agentRoot??`${n}/agent`,i=t.name??`memory-agent`,a={model:{id:t.model},name:i};t.outputSchema!==void 0&&(a.outputSchema=t.outputSchema);let o=(t.tools??[]).map(e=>({description:e.description??`${e.name} test tool.`,inputSchema:e.inputSchema??null,logicalPath:`tools/${e.name}.ts`,name:e.name,sourceId:createMemorySourceId(`tools/${e.name}.ts`),sourceKind:`module`}));return{manifest:createCompiledAgentManifest({agentRoot:r,appRoot:n,config:a,skills:(t.skills??[]).map(e=>({description:e.description,logicalPath:`skills/${e.name}.md`,markdown:e.markdown??`# ${e.name}\n`,name:e.name,sourceId:createMemorySourceId(`skills/${e.name}.md`),sourceKind:`markdown`})),tools:o}),moduleMap:{nodes:{[ROOT_COMPILED_AGENT_NODE_ID]:{modules:Object.fromEntries(o.map(e=>[e.sourceId,Object.freeze({})]))}}}}}function createMemorySourceId(e){return`memory::${e}`}export{compileFromMemory};
@@ -269,6 +269,7 @@ declare const compiledAgentNodeManifestSchema: z.ZodObject<{
269
269
  description: string;
270
270
  entryPath: string;
271
271
  name: string;
272
+ outputSchema?: import("../shared/json.js").JsonObject;
272
273
  path: string;
273
274
  rootPath: string;
274
275
  url: string;
@@ -276,6 +277,7 @@ declare const compiledAgentNodeManifestSchema: z.ZodObject<{
276
277
  description: string;
277
278
  entryPath: string;
278
279
  name: string;
280
+ outputSchema?: import("../shared/json.js").JsonObject;
279
281
  path: string;
280
282
  rootPath: string;
281
283
  url: string;
@@ -336,6 +338,7 @@ export declare const compiledAgentManifestSchema: z.ZodObject<{
336
338
  description: string;
337
339
  entryPath: string;
338
340
  name: string;
341
+ outputSchema?: import("../shared/json.js").JsonObject;
339
342
  path: string;
340
343
  rootPath: string;
341
344
  url: string;
@@ -343,6 +346,7 @@ export declare const compiledAgentManifestSchema: z.ZodObject<{
343
346
  description: string;
344
347
  entryPath: string;
345
348
  name: string;
349
+ outputSchema?: import("../shared/json.js").JsonObject;
346
350
  path: string;
347
351
  rootPath: string;
348
352
  url: string;
@@ -1 +1 @@
1
- import{z}from"#compiled/zod/index.js";import{discoverDiagnosticsSummarySchema}from"#discover/diagnostics.js";import{compiledRemoteAgentNodeSchema}from"#compiler/remote-agent-node.js";import{jsonObjectSchema}from"#shared/json-schemas.js";const COMPILED_AGENT_MANIFEST_KIND=`ash-agent-compiled-manifest`,ROOT_COMPILED_AGENT_NODE_ID=`__root__`,COMPILED_AGENT_MANIFEST_VERSION=25,moduleSourceRefSchema=z.object({exportName:z.string().optional(),sourceKind:z.literal(`module`),logicalPath:z.string(),sourceId:z.string()}).strict(),channelMethodSchema=z.union([z.literal(`GET`),z.literal(`POST`),z.literal(`PUT`),z.literal(`PATCH`),z.literal(`DELETE`)]),compiledChannelDefinitionSchema=z.object({kind:z.literal(`channel`),name:z.string(),logicalPath:z.string(),method:channelMethodSchema,urlPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),exportName:z.string().optional(),adapterKind:z.string().optional()}).strict(),disabledCompiledChannelEntrySchema=z.object({kind:z.literal(`disabled`),name:z.string(),logicalPath:z.string()}).strict(),compiledChannelEntrySchema=z.union([compiledChannelDefinitionSchema,disabledCompiledChannelEntrySchema]),compiledRuntimeModelReferenceSchema=z.object({contextWindowTokens:z.number().int().positive().optional(),id:z.string(),source:moduleSourceRefSchema.optional(),providerOptions:z.record(z.string(),jsonObjectSchema).optional()}).strict(),compiledAgentBuildDefinitionSchema=z.object({externalDependencies:z.array(z.string()).optional()}).strict(),compiledAgentCompactionDefinitionSchema=z.object({model:compiledRuntimeModelReferenceSchema.optional(),thresholdPercent:z.number().finite().min(0).max(1).optional()}).strict(),compiledAgentConfigSchema=z.object({build:compiledAgentBuildDefinitionSchema.optional(),compaction:compiledAgentCompactionDefinitionSchema.optional(),description:z.string().optional(),experimental:z.object({codeMode:z.boolean().optional()}).strict().optional(),model:compiledRuntimeModelReferenceSchema,name:z.string(),source:moduleSourceRefSchema.optional()}).strict(),compiledInstructionsSchema=z.object({name:z.string(),logicalPath:z.string(),markdown:z.string(),sourceId:z.string(),sourceKind:z.union([z.literal(`markdown`),z.literal(`module`)])}).strict(),compiledSkillBaseFields={name:z.string(),description:z.string(),license:z.string().optional(),markdown:z.string(),metadata:z.record(z.string(),z.string()).optional(),sourceId:z.string(),logicalPath:z.string()},compiledSkillSourceSchema=z.discriminatedUnion(`sourceKind`,[z.object({...compiledSkillBaseFields,sourceKind:z.literal(`markdown`)}).strict(),z.object({...compiledSkillBaseFields,sourceKind:z.literal(`module`),exportName:z.string().optional()}).strict(),z.object({...compiledSkillBaseFields,sourceKind:z.literal(`skill-package`),skillId:z.string(),skillFilePath:z.string(),rootPath:z.string(),assetsPath:z.string().optional(),referencesPath:z.string().optional(),scriptsPath:z.string().optional()}).strict()]),compiledScheduleDefinitionSchema=z.object({cron:z.string(),hasRun:z.boolean(),name:z.string(),logicalPath:z.string(),markdown:z.string().optional(),sourceId:z.string(),sourceKind:z.union([z.literal(`markdown`),z.literal(`module`)])}).strict(),compiledSandboxDefinitionSchema=z.object({description:z.string().optional(),exportName:z.string().optional(),logicalPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledSandboxWorkspaceSchema=z.object({logicalPath:z.string(),rootEntries:z.array(z.string()).readonly(),sourceId:z.string(),sourcePath:z.string()}).strict(),compiledWorkspaceResourceRootSchema=z.object({logicalPath:z.string(),rootEntries:z.array(z.string()).readonly()}).strict(),compiledConnectionDefinitionSchema=z.object({connectionName:z.string(),description:z.string(),exportName:z.string().optional(),logicalPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),url:z.string(),vercelConnect:z.object({connector:z.string()}).strict().optional()}).strict(),compiledToolDefinitionSchema=z.object({description:z.string(),exportName:z.string().optional(),inputSchema:jsonObjectSchema.nullable(),logicalPath:z.string(),name:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledDynamicToolDefinitionSchema=z.object({eventNames:z.array(z.string()).readonly(),exportName:z.string().optional(),logicalPath:z.string(),slug:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledDynamicSkillDefinitionSchema=z.object({eventNames:z.array(z.string()).readonly(),exportName:z.string().optional(),logicalPath:z.string(),slug:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledDynamicInstructionsDefinitionSchema=z.object({eventNames:z.array(z.string()).readonly(),exportName:z.string().optional(),logicalPath:z.string(),slug:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledHookDefinitionSchema=z.object({exportName:z.string().optional(),logicalPath:z.string(),slug:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledAgentNodeManifestSchema=z.object({agentRoot:z.string(),appRoot:z.string(),channels:z.array(compiledChannelEntrySchema),config:compiledAgentConfigSchema,connections:z.array(compiledConnectionDefinitionSchema),diagnosticsSummary:discoverDiagnosticsSummarySchema,disabledFrameworkTools:z.array(z.string()).readonly(),dynamicInstructions:z.array(compiledDynamicInstructionsDefinitionSchema).default([]),dynamicSkills:z.array(compiledDynamicSkillDefinitionSchema).default([]),dynamicTools:z.array(compiledDynamicToolDefinitionSchema).default([]),hooks:z.array(compiledHookDefinitionSchema),sandbox:compiledSandboxDefinitionSchema.nullable(),sandboxWorkspaces:z.array(compiledSandboxWorkspaceSchema),schedules:z.array(compiledScheduleDefinitionSchema),remoteAgents:z.array(compiledRemoteAgentNodeSchema),skills:z.array(compiledSkillSourceSchema).readonly(),instructions:compiledInstructionsSchema.optional(),tools:z.array(compiledToolDefinitionSchema),workspaceResourceRoot:compiledWorkspaceResourceRootSchema}).strict(),compiledSubagentNodeSchema=z.object({agent:compiledAgentNodeManifestSchema,description:z.string(),entryPath:z.string(),logicalPath:z.string(),name:z.string(),nodeId:z.string(),rootPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),exportName:z.string().optional()}).strict(),compiledSubagentEdgeSchema=z.object({childNodeId:z.string(),parentNodeId:z.string()}).strict(),compiledAgentManifestSchema=z.object({agentRoot:z.string(),appRoot:z.string(),channels:z.array(compiledChannelEntrySchema),config:compiledAgentConfigSchema,connections:z.array(compiledConnectionDefinitionSchema),diagnosticsSummary:discoverDiagnosticsSummarySchema,disabledFrameworkTools:z.array(z.string()).readonly(),dynamicInstructions:z.array(compiledDynamicInstructionsDefinitionSchema).default([]),dynamicSkills:z.array(compiledDynamicSkillDefinitionSchema).default([]),dynamicTools:z.array(compiledDynamicToolDefinitionSchema).default([]),hooks:z.array(compiledHookDefinitionSchema),kind:z.literal(COMPILED_AGENT_MANIFEST_KIND),remoteAgents:z.array(compiledRemoteAgentNodeSchema),sandbox:compiledSandboxDefinitionSchema.nullable(),sandboxWorkspaces:z.array(compiledSandboxWorkspaceSchema),schedules:z.array(compiledScheduleDefinitionSchema),skills:z.array(compiledSkillSourceSchema).readonly(),subagentEdges:z.array(compiledSubagentEdgeSchema),subagents:z.array(compiledSubagentNodeSchema),instructions:compiledInstructionsSchema.optional(),tools:z.array(compiledToolDefinitionSchema),version:z.literal(25),workspaceResourceRoot:compiledWorkspaceResourceRootSchema}).strict();function createCompiledAgentNodeManifest(e){let t={agentRoot:e.agentRoot,appRoot:e.appRoot,channels:[...e.channels??[]],connections:[...e.connections??[]],config:{build:e.config.build===void 0?void 0:{externalDependencies:e.config.build.externalDependencies===void 0?void 0:[...e.config.build.externalDependencies]},compaction:{model:e.config.compaction?.model===void 0?void 0:cloneCompiledRuntimeModelReference(e.config.compaction.model),thresholdPercent:e.config.compaction?.thresholdPercent},description:e.config.description,experimental:e.config.experimental===void 0?void 0:{codeMode:e.config.experimental.codeMode},model:cloneCompiledRuntimeModelReference(e.config.model),name:e.config.name,source:e.config.source===void 0?void 0:{...e.config.source}},diagnosticsSummary:e.diagnosticsSummary??{errors:0,warnings:0},disabledFrameworkTools:[...e.disabledFrameworkTools??[]],dynamicInstructions:[...e.dynamicInstructions??[]],dynamicSkills:[...e.dynamicSkills??[]],dynamicTools:[...e.dynamicTools??[]],hooks:[...e.hooks??[]],remoteAgents:[...e.remoteAgents??[]],sandbox:e.sandbox??null,sandboxWorkspaces:[...e.sandboxWorkspaces??[]],schedules:[...e.schedules??[]],skills:[...e.skills??[]],tools:[...e.tools??[]],workspaceResourceRoot:e.workspaceResourceRoot??{logicalPath:``,rootEntries:deriveResourceRootEntries({sandboxWorkspaces:e.sandboxWorkspaces,skills:e.skills})}};return e.instructions!==void 0&&(t.instructions=e.instructions),t}function deriveResourceRootEntries(e){let t=new Set;(e.skills??[]).length>0&&t.add(`skills/`);for(let n of e.sandboxWorkspaces??[])for(let e of n.rootEntries)t.add(e);return[...t].sort((e,t)=>e.localeCompare(t))}function createCompiledSubagentNodeId(e,t){return e===`__root__`?t:`${e}::${t}`}function createCompiledAgentManifest(e){return{...createCompiledAgentNodeManifest(e),kind:COMPILED_AGENT_MANIFEST_KIND,subagentEdges:[...e.subagentEdges??[]],subagents:[...e.subagents??[]],version:25}}function cloneCompiledRuntimeModelReference(e){return e.contextWindowTokens===void 0&&e.source===void 0&&e.providerOptions===void 0?{id:e.id}:e.source===void 0?e.providerOptions===void 0?{contextWindowTokens:e.contextWindowTokens,id:e.id}:{contextWindowTokens:e.contextWindowTokens,id:e.id,providerOptions:{...e.providerOptions}}:e.contextWindowTokens===void 0&&e.providerOptions===void 0?{id:e.id,source:{...e.source}}:{contextWindowTokens:e.contextWindowTokens,id:e.id,providerOptions:e.providerOptions===void 0?void 0:{...e.providerOptions},source:{...e.source}}}export{COMPILED_AGENT_MANIFEST_KIND,COMPILED_AGENT_MANIFEST_VERSION,ROOT_COMPILED_AGENT_NODE_ID,compiledAgentManifestSchema,createCompiledAgentManifest,createCompiledAgentNodeManifest,createCompiledSubagentNodeId,deriveResourceRootEntries};
1
+ import{z}from"#compiled/zod/index.js";import{discoverDiagnosticsSummarySchema}from"#discover/diagnostics.js";import{compiledRemoteAgentNodeSchema}from"#compiler/remote-agent-node.js";import{jsonObjectSchema}from"#shared/json-schemas.js";const COMPILED_AGENT_MANIFEST_KIND=`ash-agent-compiled-manifest`,ROOT_COMPILED_AGENT_NODE_ID=`__root__`,COMPILED_AGENT_MANIFEST_VERSION=25,moduleSourceRefSchema=z.object({exportName:z.string().optional(),sourceKind:z.literal(`module`),logicalPath:z.string(),sourceId:z.string()}).strict(),channelMethodSchema=z.union([z.literal(`GET`),z.literal(`POST`),z.literal(`PUT`),z.literal(`PATCH`),z.literal(`DELETE`)]),compiledChannelDefinitionSchema=z.object({kind:z.literal(`channel`),name:z.string(),logicalPath:z.string(),method:channelMethodSchema,urlPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),exportName:z.string().optional(),adapterKind:z.string().optional()}).strict(),disabledCompiledChannelEntrySchema=z.object({kind:z.literal(`disabled`),name:z.string(),logicalPath:z.string()}).strict(),compiledChannelEntrySchema=z.union([compiledChannelDefinitionSchema,disabledCompiledChannelEntrySchema]),compiledRuntimeModelReferenceSchema=z.object({contextWindowTokens:z.number().int().positive().optional(),id:z.string(),source:moduleSourceRefSchema.optional(),providerOptions:z.record(z.string(),jsonObjectSchema).optional()}).strict(),compiledAgentBuildDefinitionSchema=z.object({externalDependencies:z.array(z.string()).optional()}).strict(),compiledAgentCompactionDefinitionSchema=z.object({model:compiledRuntimeModelReferenceSchema.optional(),thresholdPercent:z.number().finite().min(0).max(1).optional()}).strict(),compiledAgentConfigSchema=z.object({build:compiledAgentBuildDefinitionSchema.optional(),compaction:compiledAgentCompactionDefinitionSchema.optional(),description:z.string().optional(),experimental:z.object({codeMode:z.boolean().optional()}).strict().optional(),model:compiledRuntimeModelReferenceSchema,name:z.string(),outputSchema:jsonObjectSchema.optional(),source:moduleSourceRefSchema.optional()}).strict(),compiledInstructionsSchema=z.object({name:z.string(),logicalPath:z.string(),markdown:z.string(),sourceId:z.string(),sourceKind:z.union([z.literal(`markdown`),z.literal(`module`)])}).strict(),compiledSkillBaseFields={name:z.string(),description:z.string(),license:z.string().optional(),markdown:z.string(),metadata:z.record(z.string(),z.string()).optional(),sourceId:z.string(),logicalPath:z.string()},compiledSkillSourceSchema=z.discriminatedUnion(`sourceKind`,[z.object({...compiledSkillBaseFields,sourceKind:z.literal(`markdown`)}).strict(),z.object({...compiledSkillBaseFields,sourceKind:z.literal(`module`),exportName:z.string().optional()}).strict(),z.object({...compiledSkillBaseFields,sourceKind:z.literal(`skill-package`),skillId:z.string(),skillFilePath:z.string(),rootPath:z.string(),assetsPath:z.string().optional(),referencesPath:z.string().optional(),scriptsPath:z.string().optional()}).strict()]),compiledScheduleDefinitionSchema=z.object({cron:z.string(),hasRun:z.boolean(),name:z.string(),logicalPath:z.string(),markdown:z.string().optional(),sourceId:z.string(),sourceKind:z.union([z.literal(`markdown`),z.literal(`module`)])}).strict(),compiledSandboxDefinitionSchema=z.object({description:z.string().optional(),exportName:z.string().optional(),logicalPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledSandboxWorkspaceSchema=z.object({logicalPath:z.string(),rootEntries:z.array(z.string()).readonly(),sourceId:z.string(),sourcePath:z.string()}).strict(),compiledWorkspaceResourceRootSchema=z.object({logicalPath:z.string(),rootEntries:z.array(z.string()).readonly()}).strict(),compiledConnectionDefinitionSchema=z.object({connectionName:z.string(),description:z.string(),exportName:z.string().optional(),logicalPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),url:z.string(),vercelConnect:z.object({connector:z.string()}).strict().optional()}).strict(),compiledToolDefinitionSchema=z.object({description:z.string(),exportName:z.string().optional(),inputSchema:jsonObjectSchema.nullable(),logicalPath:z.string(),name:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledDynamicToolDefinitionSchema=z.object({eventNames:z.array(z.string()).readonly(),exportName:z.string().optional(),logicalPath:z.string(),slug:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledDynamicSkillDefinitionSchema=z.object({eventNames:z.array(z.string()).readonly(),exportName:z.string().optional(),logicalPath:z.string(),slug:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledDynamicInstructionsDefinitionSchema=z.object({eventNames:z.array(z.string()).readonly(),exportName:z.string().optional(),logicalPath:z.string(),slug:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledHookDefinitionSchema=z.object({exportName:z.string().optional(),logicalPath:z.string(),slug:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledAgentNodeManifestSchema=z.object({agentRoot:z.string(),appRoot:z.string(),channels:z.array(compiledChannelEntrySchema),config:compiledAgentConfigSchema,connections:z.array(compiledConnectionDefinitionSchema),diagnosticsSummary:discoverDiagnosticsSummarySchema,disabledFrameworkTools:z.array(z.string()).readonly(),dynamicInstructions:z.array(compiledDynamicInstructionsDefinitionSchema).default([]),dynamicSkills:z.array(compiledDynamicSkillDefinitionSchema).default([]),dynamicTools:z.array(compiledDynamicToolDefinitionSchema).default([]),hooks:z.array(compiledHookDefinitionSchema),sandbox:compiledSandboxDefinitionSchema.nullable(),sandboxWorkspaces:z.array(compiledSandboxWorkspaceSchema),schedules:z.array(compiledScheduleDefinitionSchema),remoteAgents:z.array(compiledRemoteAgentNodeSchema),skills:z.array(compiledSkillSourceSchema).readonly(),instructions:compiledInstructionsSchema.optional(),tools:z.array(compiledToolDefinitionSchema),workspaceResourceRoot:compiledWorkspaceResourceRootSchema}).strict(),compiledSubagentNodeSchema=z.object({agent:compiledAgentNodeManifestSchema,description:z.string(),entryPath:z.string(),logicalPath:z.string(),name:z.string(),nodeId:z.string(),rootPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),exportName:z.string().optional()}).strict(),compiledSubagentEdgeSchema=z.object({childNodeId:z.string(),parentNodeId:z.string()}).strict(),compiledAgentManifestSchema=z.object({agentRoot:z.string(),appRoot:z.string(),channels:z.array(compiledChannelEntrySchema),config:compiledAgentConfigSchema,connections:z.array(compiledConnectionDefinitionSchema),diagnosticsSummary:discoverDiagnosticsSummarySchema,disabledFrameworkTools:z.array(z.string()).readonly(),dynamicInstructions:z.array(compiledDynamicInstructionsDefinitionSchema).default([]),dynamicSkills:z.array(compiledDynamicSkillDefinitionSchema).default([]),dynamicTools:z.array(compiledDynamicToolDefinitionSchema).default([]),hooks:z.array(compiledHookDefinitionSchema),kind:z.literal(COMPILED_AGENT_MANIFEST_KIND),remoteAgents:z.array(compiledRemoteAgentNodeSchema),sandbox:compiledSandboxDefinitionSchema.nullable(),sandboxWorkspaces:z.array(compiledSandboxWorkspaceSchema),schedules:z.array(compiledScheduleDefinitionSchema),skills:z.array(compiledSkillSourceSchema).readonly(),subagentEdges:z.array(compiledSubagentEdgeSchema),subagents:z.array(compiledSubagentNodeSchema),instructions:compiledInstructionsSchema.optional(),tools:z.array(compiledToolDefinitionSchema),version:z.literal(25),workspaceResourceRoot:compiledWorkspaceResourceRootSchema}).strict();function createCompiledAgentNodeManifest(e){let t={agentRoot:e.agentRoot,appRoot:e.appRoot,channels:[...e.channels??[]],connections:[...e.connections??[]],config:{build:e.config.build===void 0?void 0:{externalDependencies:e.config.build.externalDependencies===void 0?void 0:[...e.config.build.externalDependencies]},compaction:{model:e.config.compaction?.model===void 0?void 0:cloneCompiledRuntimeModelReference(e.config.compaction.model),thresholdPercent:e.config.compaction?.thresholdPercent},description:e.config.description,experimental:e.config.experimental===void 0?void 0:{codeMode:e.config.experimental.codeMode},model:cloneCompiledRuntimeModelReference(e.config.model),name:e.config.name,outputSchema:e.config.outputSchema,source:e.config.source===void 0?void 0:{...e.config.source}},diagnosticsSummary:e.diagnosticsSummary??{errors:0,warnings:0},disabledFrameworkTools:[...e.disabledFrameworkTools??[]],dynamicInstructions:[...e.dynamicInstructions??[]],dynamicSkills:[...e.dynamicSkills??[]],dynamicTools:[...e.dynamicTools??[]],hooks:[...e.hooks??[]],remoteAgents:[...e.remoteAgents??[]],sandbox:e.sandbox??null,sandboxWorkspaces:[...e.sandboxWorkspaces??[]],schedules:[...e.schedules??[]],skills:[...e.skills??[]],tools:[...e.tools??[]],workspaceResourceRoot:e.workspaceResourceRoot??{logicalPath:``,rootEntries:deriveResourceRootEntries({sandboxWorkspaces:e.sandboxWorkspaces,skills:e.skills})}};return e.instructions!==void 0&&(t.instructions=e.instructions),t}function deriveResourceRootEntries(e){let t=new Set;(e.skills??[]).length>0&&t.add(`skills/`);for(let n of e.sandboxWorkspaces??[])for(let e of n.rootEntries)t.add(e);return[...t].sort((e,t)=>e.localeCompare(t))}function createCompiledSubagentNodeId(e,t){return e===`__root__`?t:`${e}::${t}`}function createCompiledAgentManifest(e){return{...createCompiledAgentNodeManifest(e),kind:COMPILED_AGENT_MANIFEST_KIND,subagentEdges:[...e.subagentEdges??[]],subagents:[...e.subagents??[]],version:25}}function cloneCompiledRuntimeModelReference(e){return e.contextWindowTokens===void 0&&e.source===void 0&&e.providerOptions===void 0?{id:e.id}:e.source===void 0?e.providerOptions===void 0?{contextWindowTokens:e.contextWindowTokens,id:e.id}:{contextWindowTokens:e.contextWindowTokens,id:e.id,providerOptions:{...e.providerOptions}}:e.contextWindowTokens===void 0&&e.providerOptions===void 0?{id:e.id,source:{...e.source}}:{contextWindowTokens:e.contextWindowTokens,id:e.id,providerOptions:e.providerOptions===void 0?void 0:{...e.providerOptions},source:{...e.source}}}export{COMPILED_AGENT_MANIFEST_KIND,COMPILED_AGENT_MANIFEST_VERSION,ROOT_COMPILED_AGENT_NODE_ID,compiledAgentManifestSchema,createCompiledAgentManifest,createCompiledAgentNodeManifest,createCompiledSubagentNodeId,deriveResourceRootEntries};
@@ -1 +1 @@
1
- import{toErrorMessage}from"#shared/errors.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{parseJsonObject}from"#shared/json.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";var MissingAgentConfigModuleError=class extends Error{agentId;constructor(e){super(`Agent "${e}" does not have an agent.ts config module. The "model" field is required.`),this.name=`MissingAgentConfigModuleError`,this.agentId=e}};async function compileAgentConfig(e,n){if(e.configModule===void 0)throw new MissingAgentConfigModuleError(e.agentId);let r=normalizeAgentDefinition(await loadModuleBackedDefinition({agentRoot:e.agentRoot,kind:`agent config`,source:e.configModule}),`Expected the agent config export "${e.configModule.exportName??`default`}" from "${e.configModule.logicalPath}" to match the public Ash shape.`),a=await normalizeAuthoredModelReference({modelCatalog:n.modelCatalog,purpose:`the primary compaction trigger model`,contextWindowTokens:r.modelContextWindowTokens,providerOptions:r.modelOptions?.providerOptions,source:e.configModule,value:r.model}),o={},s={compaction:o,model:a,name:e.agentId};return r.description!==void 0&&(s.description=r.description),r.experimental?.codeMode!==void 0&&(s.experimental={codeMode:r.experimental.codeMode}),r.build!==void 0&&(s.build={externalDependencies:r.build.externalDependencies===void 0?void 0:[...r.build.externalDependencies]}),s.source={exportName:e.configModule.exportName,sourceKind:`module`,logicalPath:e.configModule.logicalPath,sourceId:e.configModule.sourceId},r.compaction?.model!==void 0&&(o.model=await normalizeAuthoredModelReference({modelCatalog:n.modelCatalog,purpose:`the compaction summary model`,contextWindowTokens:r.compaction.modelContextWindowTokens,providerOptions:r.modelOptions?.providerOptions,source:e.configModule,value:r.compaction.model})),r.compaction?.thresholdPercent!==void 0&&(o.thresholdPercent=r.compaction.thresholdPercent),s}async function normalizeAuthoredModelReference(e){if(typeof e.value==`string`)return await withCompiledRuntimeModelLimits({id:formatLanguageModelGatewayId(e.value),providerOptions:parseProviderOptionsRecord(e.providerOptions)},e);let t=e.source;if(t===void 0)throw Error(`Expected ${e.purpose} to provide a valid AI SDK language model reference.`);let r=e.value,i=r.specificationVersion;if(i!==`v2`&&i!==`v3`&&i!==`v4`||typeof r.provider!=`string`||typeof r.modelId!=`string`||typeof r.doGenerate!=`function`||typeof r.doStream!=`function`)throw Error(`Expected the authored agent config export "${t.exportName??`default`}" from "${t.logicalPath}" to provide a valid AI SDK language model.`);let a={id:formatLanguageModelGatewayId(r),source:{exportName:t.exportName,sourceKind:`module`,logicalPath:t.logicalPath,sourceId:t.sourceId},providerOptions:parseProviderOptionsRecord(e.providerOptions)};if(e.contextWindowTokens===void 0){let t=await e.modelCatalog.getByProviderModelId(r.provider,r.modelId);if(t)return{...a,id:t.slug,contextWindowTokens:t.limits.contextWindowTokens}}return await withCompiledRuntimeModelLimits(a,e)}async function withCompiledRuntimeModelLimits(t,n){if(n.contextWindowTokens!==void 0)return{...t,contextWindowTokens:n.contextWindowTokens};let r;try{r=await n.modelCatalog.getModelLimits(t.id)}catch(r){throw Error(`Failed to load AI Gateway model metadata for ${n.purpose} "${t.id}". ${toErrorMessage(r)}`)}if(r===null)throw Error(`Cannot compile agent compaction because ${n.purpose} "${t.id}" does not have known AI Gateway context window metadata.`);return{...t,contextWindowTokens:r.contextWindowTokens}}function parseProviderOptionsRecord(e){if(e===void 0)return;let t={};for(let[n,i]of Object.entries(e))t[n]=parseJsonObject(i);return t}export{MissingAgentConfigModuleError,compileAgentConfig};
1
+ import{toErrorMessage}from"#shared/errors.js";import{normalizeJsonSchemaDefinition}from"#shared/json-schema.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{parseJsonObject}from"#shared/json.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";var MissingAgentConfigModuleError=class extends Error{agentId;constructor(e){super(`Agent "${e}" does not have an agent.ts config module. The "model" field is required.`),this.name=`MissingAgentConfigModuleError`,this.agentId=e}};async function compileAgentConfig(e,r){if(e.configModule===void 0)throw new MissingAgentConfigModuleError(e.agentId);let i=normalizeAgentDefinition(await loadModuleBackedDefinition({agentRoot:e.agentRoot,kind:`agent config`,source:e.configModule}),`Expected the agent config export "${e.configModule.exportName??`default`}" from "${e.configModule.logicalPath}" to match the public Ash shape.`),o=await normalizeAuthoredModelReference({modelCatalog:r.modelCatalog,purpose:`the primary compaction trigger model`,contextWindowTokens:i.modelContextWindowTokens,providerOptions:i.modelOptions?.providerOptions,source:e.configModule,value:i.model}),s={},c={compaction:s,model:o,name:e.agentId};return i.description!==void 0&&(c.description=i.description),i.experimental?.codeMode!==void 0&&(c.experimental={codeMode:i.experimental.codeMode}),i.build!==void 0&&(c.build={externalDependencies:i.build.externalDependencies===void 0?void 0:[...i.build.externalDependencies]}),i.outputSchema!==void 0&&(c.outputSchema=normalizeJsonSchemaDefinition(i.outputSchema)),c.source={exportName:e.configModule.exportName,sourceKind:`module`,logicalPath:e.configModule.logicalPath,sourceId:e.configModule.sourceId},i.compaction?.model!==void 0&&(s.model=await normalizeAuthoredModelReference({modelCatalog:r.modelCatalog,purpose:`the compaction summary model`,contextWindowTokens:i.compaction.modelContextWindowTokens,providerOptions:i.modelOptions?.providerOptions,source:e.configModule,value:i.compaction.model})),i.compaction?.thresholdPercent!==void 0&&(s.thresholdPercent=i.compaction.thresholdPercent),c}async function normalizeAuthoredModelReference(e){if(typeof e.value==`string`)return await withCompiledRuntimeModelLimits({id:formatLanguageModelGatewayId(e.value),providerOptions:parseProviderOptionsRecord(e.providerOptions)},e);let t=e.source;if(t===void 0)throw Error(`Expected ${e.purpose} to provide a valid AI SDK language model reference.`);let n=e.value,i=n.specificationVersion;if(i!==`v2`&&i!==`v3`&&i!==`v4`||typeof n.provider!=`string`||typeof n.modelId!=`string`||typeof n.doGenerate!=`function`||typeof n.doStream!=`function`)throw Error(`Expected the authored agent config export "${t.exportName??`default`}" from "${t.logicalPath}" to provide a valid AI SDK language model.`);let a={id:formatLanguageModelGatewayId(n),source:{exportName:t.exportName,sourceKind:`module`,logicalPath:t.logicalPath,sourceId:t.sourceId},providerOptions:parseProviderOptionsRecord(e.providerOptions)};if(e.contextWindowTokens===void 0){let t=await e.modelCatalog.getByProviderModelId(n.provider,n.modelId);if(t)return{...a,id:t.slug,contextWindowTokens:t.limits.contextWindowTokens}}return await withCompiledRuntimeModelLimits(a,e)}async function withCompiledRuntimeModelLimits(t,n){if(n.contextWindowTokens!==void 0)return{...t,contextWindowTokens:n.contextWindowTokens};let r;try{r=await n.modelCatalog.getModelLimits(t.id)}catch(r){throw Error(`Failed to load AI Gateway model metadata for ${n.purpose} "${t.id}". ${toErrorMessage(r)}`)}if(r===null)throw Error(`Cannot compile agent compaction because ${n.purpose} "${t.id}" does not have known AI Gateway context window metadata.`);return{...t,contextWindowTokens:r.contextWindowTokens}}function parseProviderOptionsRecord(e){if(e===void 0)return;let t={};for(let[n,r]of Object.entries(e))t[n]=parseJsonObject(r);return t}export{MissingAgentConfigModuleError,compileAgentConfig};