experimental-ash 0.42.0 → 0.44.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 (184) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/bin/ash.js +1 -0
  3. package/dist/docs/internals/mechanical-invariants.md +16 -0
  4. package/dist/docs/public/README.md +8 -8
  5. package/dist/docs/public/advanced/{auth-and-route-protection.md → auth-and-route-protection.mdx} +11 -0
  6. package/dist/docs/public/advanced/context-control.md +4 -4
  7. package/dist/docs/public/advanced/{evals.md → evals.mdx} +11 -1
  8. package/dist/docs/public/advanced/{hooks.md → hooks.mdx} +28 -40
  9. package/dist/docs/public/advanced/instrumentation.md +142 -3
  10. package/dist/docs/public/advanced/project-layout.md +5 -5
  11. package/dist/docs/public/advanced/runs-and-streaming.md +8 -2
  12. package/dist/docs/public/advanced/session-context.md +1 -1
  13. package/dist/docs/public/advanced/typescript-api.md +50 -7
  14. package/dist/docs/public/advanced/vercel-deployment.md +1 -1
  15. package/dist/docs/public/agent-ts.md +5 -5
  16. package/dist/docs/public/channels/{discord.md → discord.mdx} +11 -0
  17. package/dist/docs/public/channels/index.md +10 -10
  18. package/dist/docs/public/channels/{slack.md → slack.mdx} +11 -0
  19. package/dist/docs/public/channels/{teams.md → teams.mdx} +12 -0
  20. package/dist/docs/public/channels/{telegram.md → telegram.mdx} +11 -0
  21. package/dist/docs/public/channels/{twilio.md → twilio.mdx} +11 -0
  22. package/dist/docs/public/{connections.md → connections.mdx} +18 -6
  23. package/dist/docs/public/frontend/README.md +16 -0
  24. package/dist/docs/public/frontend/meta.json +3 -0
  25. package/dist/docs/public/frontend/nextjs.md +192 -0
  26. package/dist/docs/public/frontend/use-ash-agent.md +332 -0
  27. package/dist/docs/public/{getting-started.md → getting-started.mdx} +12 -1
  28. package/dist/docs/public/{human-in-the-loop.md → human-in-the-loop.mdx} +12 -1
  29. package/dist/docs/public/meta.json +1 -0
  30. package/dist/docs/public/sandbox.md +39 -1
  31. package/dist/docs/public/{schedules.md → schedules.mdx} +9 -0
  32. package/dist/docs/public/skills.md +2 -2
  33. package/dist/docs/public/{subagents.md → subagents.mdx} +10 -0
  34. package/dist/docs/public/{tools.md → tools.mdx} +41 -26
  35. package/dist/src/channel/adapter.d.ts +13 -0
  36. package/dist/src/channel/compiled-channel.d.ts +4 -1
  37. package/dist/src/channel/compiled-channel.js +1 -1
  38. package/dist/src/channel/instrumentation.d.ts +10 -0
  39. package/dist/src/channel/instrumentation.js +1 -0
  40. package/dist/src/channel/routes.d.ts +8 -10
  41. package/dist/src/channel/send.js +1 -1
  42. package/dist/src/channel/types.d.ts +16 -0
  43. package/dist/src/cli/commands/channels.d.ts +2 -1
  44. package/dist/src/cli/commands/channels.js +1 -1
  45. package/dist/src/compiled/.vendor-stamp.json +1 -1
  46. package/dist/src/compiled/@vercel/sandbox/index.d.ts +12 -19
  47. package/dist/src/compiled/@vercel/sandbox/network-policy.d.ts +161 -0
  48. package/dist/src/compiled/just-bash/index.d.ts +15 -2
  49. package/dist/src/compiled/just-bash/network/types.d.ts +155 -0
  50. package/dist/src/compiler/artifacts.d.ts +1 -0
  51. package/dist/src/compiler/artifacts.js +1 -1
  52. package/dist/src/compiler/channel-instrumentation-types.d.ts +8 -0
  53. package/dist/src/compiler/channel-instrumentation-types.js +2 -0
  54. package/dist/src/compiler/manifest.d.ts +13 -1
  55. package/dist/src/compiler/manifest.js +1 -1
  56. package/dist/src/compiler/module-map.js +1 -1
  57. package/dist/src/compiler/normalize-manifest.js +1 -1
  58. package/dist/src/compiler/normalize-skill.d.ts +15 -2
  59. package/dist/src/compiler/normalize-skill.js +1 -1
  60. package/dist/src/compiler/normalize-tool.js +1 -1
  61. package/dist/src/context/dynamic-skill-lifecycle.d.ts +23 -0
  62. package/dist/src/context/dynamic-skill-lifecycle.js +1 -0
  63. package/dist/src/context/dynamic-tool-lifecycle.d.ts +2 -0
  64. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  65. package/dist/src/context/hook-lifecycle.d.ts +4 -6
  66. package/dist/src/context/hook-lifecycle.js +1 -1
  67. package/dist/src/context/keys.d.ts +6 -4
  68. package/dist/src/context/keys.js +1 -1
  69. package/dist/src/context/providers/connection.d.ts +9 -0
  70. package/dist/src/context/providers/connection.js +1 -1
  71. package/dist/src/context/providers/sandbox.js +1 -1
  72. package/dist/src/execution/ash-workflow-attributes.d.ts +118 -0
  73. package/dist/src/execution/ash-workflow-attributes.js +1 -0
  74. package/dist/src/execution/channel-context.d.ts +5 -0
  75. package/dist/src/execution/channel-context.js +1 -0
  76. package/dist/src/execution/create-session-step.d.ts +28 -1
  77. package/dist/src/execution/create-session-step.js +1 -1
  78. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  79. package/dist/src/execution/durable-session-store.d.ts +7 -0
  80. package/dist/src/execution/runtime-context.js +1 -1
  81. package/dist/src/execution/sandbox/bindings/local.js +1 -1
  82. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  83. package/dist/src/execution/sandbox/prewarm.js +1 -1
  84. package/dist/src/execution/sandbox/session.d.ts +6 -1
  85. package/dist/src/execution/sandbox/session.js +1 -1
  86. package/dist/src/execution/session.d.ts +6 -0
  87. package/dist/src/execution/session.js +2 -2
  88. package/dist/src/execution/skills/instructions.d.ts +3 -2
  89. package/dist/src/execution/subagent-tool.js +1 -1
  90. package/dist/src/execution/workflow-entry.js +1 -1
  91. package/dist/src/execution/workflow-steps.js +1 -1
  92. package/dist/src/harness/attachment-staging.js +1 -1
  93. package/dist/src/harness/code-mode.d.ts +0 -5
  94. package/dist/src/harness/code-mode.js +1 -1
  95. package/dist/src/harness/emission.d.ts +1 -1
  96. package/dist/src/harness/emission.js +1 -1
  97. package/dist/src/harness/instrumentation-config.d.ts +1 -1
  98. package/dist/src/harness/instrumentation-metadata.d.ts +23 -0
  99. package/dist/src/harness/instrumentation-metadata.js +1 -0
  100. package/dist/src/harness/otel-integration.d.ts +2 -2
  101. package/dist/src/harness/otel-integration.js +1 -1
  102. package/dist/src/harness/step-hooks.js +1 -1
  103. package/dist/src/harness/tool-loop.js +1 -1
  104. package/dist/src/harness/turn-tag-state.d.ts +50 -0
  105. package/dist/src/harness/turn-tag-state.js +1 -0
  106. package/dist/src/harness/types.d.ts +11 -2
  107. package/dist/src/internal/application/package.js +1 -1
  108. package/dist/src/internal/authored-definition/schema-backed.d.ts +0 -1
  109. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  110. package/dist/src/internal/instrumentation.d.ts +39 -0
  111. package/dist/src/internal/instrumentation.js +1 -0
  112. package/dist/src/internal/workflow/builtins.d.ts +32 -0
  113. package/dist/src/internal/workflow/builtins.js +1 -1
  114. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +1 -1
  115. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
  116. package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +34 -0
  117. package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
  118. package/dist/src/internal/workflow-bundle/workflow-transformer.js +1 -1
  119. package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
  120. package/dist/src/packages/ash-scaffold/src/steps/run-add-to-agent.js +2 -2
  121. package/dist/src/packages/ash-scaffold/src/web-template.js +1 -0
  122. package/dist/src/public/channels/discord/discordChannel.d.ts +5 -2
  123. package/dist/src/public/channels/index.d.ts +1 -1
  124. package/dist/src/public/channels/slack/attachments.js +1 -1
  125. package/dist/src/public/channels/slack/index.d.ts +1 -1
  126. package/dist/src/public/channels/slack/slackChannel.d.ts +12 -8
  127. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  128. package/dist/src/public/channels/teams/teamsChannel.d.ts +5 -2
  129. package/dist/src/public/channels/telegram/telegramChannel.d.ts +5 -2
  130. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  131. package/dist/src/public/channels/twilio/index.d.ts +1 -1
  132. package/dist/src/public/channels/twilio/twilioChannel.d.ts +12 -3
  133. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  134. package/dist/src/public/definitions/defineChannel.d.ts +17 -4
  135. package/dist/src/public/definitions/defineChannel.js +1 -1
  136. package/dist/src/public/definitions/hook.d.ts +3 -11
  137. package/dist/src/public/definitions/instrumentation.d.ts +1 -66
  138. package/dist/src/public/definitions/instrumentation.js +1 -1
  139. package/dist/src/public/definitions/skill.d.ts +5 -0
  140. package/dist/src/public/definitions/tool.d.ts +25 -66
  141. package/dist/src/public/definitions/tool.js +1 -1
  142. package/dist/src/public/instrumentation/index.d.ts +175 -1
  143. package/dist/src/public/instrumentation/index.js +1 -1
  144. package/dist/src/public/sandbox/index.d.ts +1 -0
  145. package/dist/src/public/skills/index.d.ts +2 -0
  146. package/dist/src/public/skills/index.js +1 -1
  147. package/dist/src/public/tools/index.d.ts +2 -2
  148. package/dist/src/public/tools/index.js +1 -1
  149. package/dist/src/runtime/agent/mock-model-adapter.js +4 -7
  150. package/dist/src/runtime/agent/mock-model-skill-selection.d.ts +9 -0
  151. package/dist/src/runtime/agent/mock-model-skill-selection.js +4 -0
  152. package/dist/src/runtime/attributes/emit.d.ts +73 -0
  153. package/dist/src/runtime/attributes/emit.js +1 -0
  154. package/dist/src/runtime/channels/registry.js +1 -1
  155. package/dist/src/runtime/connections/mcp-client.js +1 -1
  156. package/dist/src/runtime/framework-tools/code-mode-connection-auth.d.ts +2 -0
  157. package/dist/src/runtime/framework-tools/connection-search-dynamic.d.ts +34 -0
  158. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -0
  159. package/dist/src/runtime/framework-tools/index.d.ts +7 -5
  160. package/dist/src/runtime/framework-tools/index.js +1 -1
  161. package/dist/src/runtime/prompt/connections.js +1 -1
  162. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  163. package/dist/src/runtime/resolve-agent.js +1 -1
  164. package/dist/src/runtime/resolve-channel.js +1 -1
  165. package/dist/src/runtime/resolve-dynamic-skill.d.ts +8 -0
  166. package/dist/src/runtime/resolve-dynamic-skill.js +1 -0
  167. package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
  168. package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
  169. package/dist/src/runtime/sessions/runtime-context-keys.js +1 -1
  170. package/dist/src/runtime/types.d.ts +13 -4
  171. package/dist/src/shared/dynamic-tool-definition.d.ts +51 -76
  172. package/dist/src/shared/dynamic-tool-definition.js +1 -1
  173. package/dist/src/shared/guards.d.ts +14 -0
  174. package/dist/src/shared/guards.js +1 -1
  175. package/dist/src/shared/sandbox-network-policy.d.ts +23 -0
  176. package/dist/src/shared/sandbox-network-policy.js +1 -0
  177. package/dist/src/shared/sandbox-session.d.ts +15 -0
  178. package/dist/src/shared/skill-definition.d.ts +5 -4
  179. package/dist/src/shared/tool-definition.d.ts +12 -0
  180. package/package.json +2 -1
  181. package/dist/src/runtime/framework-tools/connection-search.d.ts +0 -57
  182. package/dist/src/runtime/framework-tools/connection-search.js +0 -1
  183. package/dist/src/runtime/framework-tools/connection-tools.d.ts +0 -55
  184. package/dist/src/runtime/framework-tools/connection-tools.js +0 -1
@@ -75,6 +75,8 @@ export interface FetchFileResult {
75
75
  readonly mediaType?: string;
76
76
  readonly filename?: string;
77
77
  }
78
+ export type ChannelInstrumentationMetadata = Readonly<Record<string, unknown>>;
79
+ export type ChannelInstrumentationMetadataProjector = (state: Record<string, unknown> | undefined) => ChannelInstrumentationMetadata;
78
80
  /**
79
81
  * Plain-object channel adapter with durable state, an optional inbound
80
82
  * delivery hook, event handlers, and optional attachment resolution.
@@ -122,6 +124,17 @@ export type ChannelAdapter<TCtx extends ChannelAdapterContext<any> = ChannelAdap
122
124
  * construction time.
123
125
  */
124
126
  readonly fetchFile?: (url: string) => Promise<Buffer | FetchFileResult | null>;
127
+ /**
128
+ * Framework-owned observability projection for the active channel.
129
+ *
130
+ * Channel implementations decide which state fields are safe and
131
+ * meaningful to expose to instrumentation callbacks. The harness reads
132
+ * the resulting projection through a seed context key rather than
133
+ * inspecting adapter state directly.
134
+ */
135
+ readonly instrumentation?: {
136
+ readonly metadata?: ChannelInstrumentationMetadataProjector;
137
+ };
125
138
  } & ChannelEventHandlers<TCtx>;
126
139
  /**
127
140
  * Produces the default {@link StepInput} when no custom adapter `deliver`
@@ -3,7 +3,7 @@ import type { RouteHandler, SendFn } from "#channel/routes.js";
3
3
  import type { Session } from "#channel/session.js";
4
4
  import type { SessionAuthContext } from "#channel/types.js";
5
5
  export declare const CHANNEL_SENTINEL: "ash:channel";
6
- export interface CompiledChannel<TState = undefined, TReceiveArgs = Record<string, unknown>> {
6
+ export interface CompiledChannel<TState = undefined, TReceiveArgs = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>> {
7
7
  readonly __kind: typeof CHANNEL_SENTINEL;
8
8
  readonly routes: readonly {
9
9
  method: string;
@@ -11,6 +11,7 @@ export interface CompiledChannel<TState = undefined, TReceiveArgs = Record<strin
11
11
  handler: RouteHandler<TState>;
12
12
  }[];
13
13
  readonly adapter: ChannelAdapter<any>;
14
+ readonly __metadata?: TMetadata;
14
15
  readonly receive?: (input: {
15
16
  readonly message: string;
16
17
  readonly args: Readonly<TReceiveArgs>;
@@ -20,3 +21,5 @@ export interface CompiledChannel<TState = undefined, TReceiveArgs = Record<strin
20
21
  }) => Promise<Session>;
21
22
  }
22
23
  export declare function isCompiledChannel(value: unknown): value is CompiledChannel;
24
+ export declare function getChannelInstrumentationKind(value: unknown): string | undefined;
25
+ export declare function setChannelInstrumentationKind(channel: CompiledChannel, kind: string): void;
@@ -1 +1 @@
1
- const CHANNEL_SENTINEL=`ash:channel`;function isCompiledChannel(e){return typeof e==`object`&&!!e&&e.__kind===`ash:channel`}export{CHANNEL_SENTINEL,isCompiledChannel};
1
+ const CHANNEL_SENTINEL=`ash:channel`,CHANNEL_INSTRUMENTATION_KIND=Symbol.for(`ash.channel.instrumentationKind`);function isCompiledChannel(e){return typeof e==`object`&&!!e&&e.__kind===`ash:channel`}function getChannelInstrumentationKind(e){if(!isCompiledChannel(e))return;let t=Reflect.get(e,CHANNEL_INSTRUMENTATION_KIND);if(typeof t==`string`&&t.length>0)return t;let n=e.adapter.kind;return typeof n==`string`&&n.startsWith(`channel:`)?n:void 0}function setChannelInstrumentationKind(e,t){Object.defineProperty(e,CHANNEL_INSTRUMENTATION_KIND,{configurable:!0,enumerable:!1,value:t})}export{CHANNEL_SENTINEL,getChannelInstrumentationKind,isCompiledChannel,setChannelInstrumentationKind};
@@ -0,0 +1,10 @@
1
+ import type { ChannelAdapter, ChannelInstrumentationMetadata } from "#channel/adapter.js";
2
+ export interface ChannelInstrumentationProjection {
3
+ readonly kind: string;
4
+ readonly metadata: ChannelInstrumentationMetadata;
5
+ }
6
+ export declare function buildChannelInstrumentationProjection(input: {
7
+ readonly adapter: ChannelAdapter;
8
+ readonly channelName?: string;
9
+ readonly existingKind?: string;
10
+ }): ChannelInstrumentationProjection;
@@ -0,0 +1 @@
1
+ import{createLogger}from"#internal/logging.js";import{getAdapterKind}from"#channel/adapter.js";import{isInstrumentationChannelKind,resolveInstrumentationProjection}from"#internal/instrumentation.js";const log=createLogger(`channel.instrumentation`);function buildChannelInstrumentationProjection(e){let{adapter:t,channelName:n,existingKind:r}=e;return{kind:resolveKind({adapter:t,channelName:n,existingKind:r}),metadata:resolveMetadata(t)}}function resolveKind(e){let{adapter:r,channelName:i,existingKind:a}=e;if(a!==void 0)return a;if(i!==void 0&&i.length>0)return`channel:${i}`;let o=getAdapterKind(r);return isInstrumentationChannelKind(o)?o:`channel:${o}`}function resolveMetadata(e){let n=e.instrumentation?.metadata;return n===void 0?{}:resolveInstrumentationProjection({invoke:()=>n(e.state),log,source:getAdapterKind(e)})??{}}export{buildChannelInstrumentationProjection};
@@ -32,6 +32,12 @@ export interface SendPayload {
32
32
  readonly modelContext?: readonly ModelMessage[];
33
33
  }
34
34
  export type SendFn<TState = undefined> = (input: string | UserContent | SendPayload, options: SendOptions<TState>) => Promise<Session>;
35
+ type BaseSendOptions = {
36
+ auth: SessionAuthContext | null;
37
+ callback?: SessionCallback;
38
+ continuationToken: string;
39
+ mode?: RunMode;
40
+ };
35
41
  /**
36
42
  * Options for {@link SendFn}. The channel owns its continuation-token
37
43
  * format — pass the channel-local raw token (the framework prepends
@@ -39,16 +45,7 @@ export type SendFn<TState = undefined> = (input: string | UserContent | SendPayl
39
45
  * state via {@link state}, which becomes the new session's `state`
40
46
  * on first `runtime.run()` and is ignored on subsequent `deliver`s.
41
47
  */
42
- export type SendOptions<TState = undefined> = TState extends undefined ? {
43
- auth: SessionAuthContext | null;
44
- callback?: SessionCallback;
45
- continuationToken: string;
46
- mode?: RunMode;
47
- } : {
48
- auth: SessionAuthContext | null;
49
- callback?: SessionCallback;
50
- continuationToken: string;
51
- mode?: RunMode;
48
+ export type SendOptions<TState = undefined> = [TState] extends [undefined] ? BaseSendOptions : BaseSendOptions & {
52
49
  state: TState;
53
50
  };
54
51
  export type GetSessionFn = (sessionId: string) => Session;
@@ -63,3 +60,4 @@ export declare function POST<TState = undefined>(path: string, handler: RouteHan
63
60
  export declare function PUT<TState = undefined>(path: string, handler: RouteHandler<TState>): RouteDefinition<TState>;
64
61
  export declare function PATCH<TState = undefined>(path: string, handler: RouteHandler<TState>): RouteDefinition<TState>;
65
62
  export declare function DELETE<TState = undefined>(path: string, handler: RouteHandler<TState>): RouteDefinition<TState>;
63
+ export {};
@@ -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,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,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};
@@ -5,6 +5,7 @@ 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
7
  export type { ContextAccessor } from "#context/key.js";
8
+ export type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
8
9
  /**
9
10
  * Identifies one turn within a session.
10
11
  */
@@ -15,8 +16,17 @@ export interface SessionTurn {
15
16
  /**
16
17
  * Stable lineage metadata describing the immediate Ash parent execution that
17
18
  * delegated the current session.
19
+ *
20
+ * `sessionId` and `turn` always describe the **immediate** parent — the
21
+ * agent that dispatched this child. `rootSessionId` denormalizes the top
22
+ * of the dispatch chain so descendants can identify the user-facing
23
+ * session without walking back up parent-by-parent. It is always
24
+ * populated at dispatch: a first-level child sets it to the top
25
+ * session's id (its immediate parent), and deeper descendants inherit
26
+ * the same root.
18
27
  */
19
28
  export interface SessionParent {
29
+ readonly rootSessionId: string;
20
30
  readonly sessionId: string;
21
31
  readonly turn: SessionTurn;
22
32
  }
@@ -162,6 +172,12 @@ export interface SessionCapabilities {
162
172
  */
163
173
  export interface RunInput {
164
174
  readonly adapter: ChannelAdapter<any>;
175
+ /**
176
+ * Registered channel name for root sessions started from an authored
177
+ * channel route. Framework runs omit this and use their framework
178
+ * adapter kind (`http`, `schedule`, `subagent`) directly.
179
+ */
180
+ readonly channelName?: string;
165
181
  /**
166
182
  * Authenticated caller principal for this session. `null` means the
167
183
  * request was accepted with no credentials.
@@ -1,4 +1,4 @@
1
- import { type RunAddToAgentOptions } from "@vercel/ash-scaffold/steps";
1
+ import { type DeployProjectOptions, type RunAddToAgentOptions } from "@vercel/ash-scaffold/steps";
2
2
  import { type ChannelAddPrompter } from "@vercel/ash-scaffold/cli";
3
3
  import { type DeploymentInfo } from "@vercel/ash-scaffold/primitives";
4
4
  export interface CliLogger {
@@ -11,6 +11,7 @@ export interface AddChannelCommandOptions {
11
11
  export interface ChannelsAddDependencies {
12
12
  createPrompter?: () => ChannelAddPrompter;
13
13
  detectDeployment(projectPath: string): Promise<DeploymentInfo>;
14
+ deployProject(options: DeployProjectOptions): Promise<void>;
14
15
  runAddToAgent(options: RunAddToAgentOptions): Promise<void>;
15
16
  }
16
17
  export declare function runChannelsAddCommand(logger: CliLogger, appRoot: string, args: {
@@ -1 +1 @@
1
- import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"./channel-add-conflicts.js";import{isAshProject}from"../../packages/ash-scaffold/src/project.js";import{listAuthoredChannels}from"../../packages/ash-scaffold/src/channels.js";import"../../packages/ash-scaffold/src/index.js";import{detectDeployment}from"../../packages/ash-scaffold/src/primitives/detect-deployment.js";import{createAddToAgentState,runAddToAgent}from"../../packages/ash-scaffold/src/steps/run-add-to-agent.js";import"../../packages/ash-scaffold/src/steps/index.js";import{ChannelAddCancelledError,createChannelAddPrompter}from"../../packages/ash-scaffold/src/cli/channel-add-prompter.js";import"../../packages/ash-scaffold/src/cli/index.js";import"../../packages/ash-scaffold/src/primitives/index.js";const NOT_AN_AGENT_MESSAGE="No Ash agent in this directory. Run `pnpm create experimental-ash-agent`, then run this command from inside the new project.",KNOWN_CHANNEL_KINDS=[`slack`,`web`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}const defaultChannelsAddDependencies={detectDeployment,runAddToAgent};async function runAddChannelsFlow(n,r,i,o){if(r===void 0&&(!process.stdin.isTTY||!process.stdout.isTTY))throw Error(`Pass a channel kind: \`ash channels add <${KNOWN_CHANNEL_KINDS.join(`|`)}>\`.`);let s=o.createPrompter?.()??createChannelAddPrompter();s.intro(`Add channels to your Ash agent`),s.log.message(`Checking the current Vercel project...`);let c=createAddToAgentState(await o.detectDeployment(n)),l;function inspectRegistrations(){return l===void 0&&(s.log.message(`Inspecting existing channel registrations...`),l=inspectExistingChannelRegistrations(n)),l}let u=r===void 0?(await inspectRegistrations()).disabledChannelReasons:void 0;await o.runAddToAgent({prompter:s,projectPath:n,state:c,presetChannels:r===void 0?void 0:[r],disabledChannelReasons:u,force:i.force,validateSelectedChannels:async t=>{!t.includes(`web`)&&!t.includes(`slack`)||assertCanAddSelectedChannels(t,await inspectRegistrations())}}),s.outro(c.channels.length===0?`No channels added.`:`Channels added.`)}async function runChannelsAddCommand(e,t,r,i=defaultChannelsAddDependencies){if(!await isAshProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{await runAddChannelsFlow(t,r.kind===void 0?void 0:parseChannelKind(r.kind),r.options,i)}catch(t){if(t instanceof ChannelAddCancelledError)return;e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}async function runChannelsListCommand(e,t,i){if(!await isAshProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let a=await listAuthoredChannels(t);if(i.json){e.log(JSON.stringify({channels:a},null,2));return}if(a.length===0){e.log("No channels defined. Run `ash channels add` to add one.");return}for(let t of a)e.log(t)}export{runChannelsAddCommand,runChannelsListCommand};
1
+ import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"./channel-add-conflicts.js";import{isAshProject}from"../../packages/ash-scaffold/src/project.js";import{listAuthoredChannels}from"../../packages/ash-scaffold/src/channels.js";import"../../packages/ash-scaffold/src/index.js";import{detectDeployment}from"../../packages/ash-scaffold/src/primitives/detect-deployment.js";import{createAddToAgentState,deployProject,runAddToAgent}from"../../packages/ash-scaffold/src/steps/run-add-to-agent.js";import"../../packages/ash-scaffold/src/steps/index.js";import{ChannelAddCancelledError,createChannelAddPrompter}from"../../packages/ash-scaffold/src/cli/channel-add-prompter.js";import"../../packages/ash-scaffold/src/cli/index.js";import"../../packages/ash-scaffold/src/primitives/index.js";const NOT_AN_AGENT_MESSAGE="No Ash agent in this directory. Run `pnpm create experimental-ash-agent`, then run this command from inside the new project.",KNOWN_CHANNEL_KINDS=[`slack`,`web`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}const defaultChannelsAddDependencies={detectDeployment,deployProject,runAddToAgent};async function runAddChannelsFlow(n,r,i,o){if(r===void 0&&(!process.stdin.isTTY||!process.stdout.isTTY))throw Error(`Pass a channel kind: \`ash channels add <${KNOWN_CHANNEL_KINDS.join(`|`)}>\`.`);let s=o.createPrompter?.()??createChannelAddPrompter();s.intro(`Add channels to your Ash agent`),s.log.message(`Checking the current Vercel project...`);let c=createAddToAgentState(await o.detectDeployment(n)),l;function inspectRegistrations(){return l===void 0&&(s.log.message(`Inspecting existing channel registrations...`),l=inspectExistingChannelRegistrations(n)),l}let u=r===void 0?(await inspectRegistrations()).disabledChannelReasons:void 0;await o.runAddToAgent({prompter:s,projectPath:n,state:c,presetChannels:r===void 0?void 0:[r],disabledChannelReasons:u,force:i.force,validateSelectedChannels:async t=>{!t.includes(`web`)&&!t.includes(`slack`)||assertCanAddSelectedChannels(t,await inspectRegistrations())}}),await o.deployProject({prompter:s,projectPath:n,vercelProjectId:c.vercelProjectId,state:c}),s.outro(c.channels.length===0?`No channels added.`:`Channels added.`)}async function runChannelsAddCommand(e,t,r,i=defaultChannelsAddDependencies){if(!await isAshProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{await runAddChannelsFlow(t,r.kind===void 0?void 0:parseChannelKind(r.kind),r.options,i)}catch(t){if(t instanceof ChannelAddCancelledError)return;e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}async function runChannelsListCommand(e,t,i){if(!await isAshProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let a=await listAuthoredChannels(t);if(i.json){e.log(JSON.stringify({channels:a},null,2));return}if(a.length===0){e.log("No channels defined. Run `ash channels add` to add one.");return}for(let t of a)e.log(t)}export{runChannelsAddCommand,runChannelsListCommand};
@@ -27,5 +27,5 @@
27
27
  "zod": "4.4.3",
28
28
  "zod-validation-error": "5.0.0"
29
29
  },
30
- "scriptHash": "27a236d633a4d9d7191418c0c9eb03158389a9de5ca9a6b54bd35b754147c7f6"
30
+ "scriptHash": "8ef773103edd72d1005178f52b446202a32dc5257541b1990f54dba807b3bbb5"
31
31
  }
@@ -1,23 +1,16 @@
1
- export interface NetworkTransformer {
2
- headers?: Record<string, string> | undefined;
3
- }
4
-
5
- export interface NetworkPolicyRule {
6
- transform?: NetworkTransformer[] | undefined;
7
- }
1
+ // The firewall network-policy types are copied verbatim from the installed
2
+ // `@vercel/sandbox` at vendor time (see scripts/vendor-compiled/@vercel/sandbox.mjs)
3
+ // so the credential-brokering surface never drifts from the SDK.
4
+ import type { NetworkPolicy } from "./network-policy.js";
8
5
 
9
- export type NetworkPolicy =
10
- | "allow-all"
11
- | "deny-all"
12
- | {
13
- allow?: string[] | Record<string, NetworkPolicyRule[]> | undefined;
14
- subnets?:
15
- | {
16
- allow?: string[] | undefined;
17
- deny?: string[] | undefined;
18
- }
19
- | undefined;
20
- };
6
+ export type {
7
+ NetworkPolicy,
8
+ NetworkPolicyKeyValueMatcher,
9
+ NetworkPolicyMatch,
10
+ NetworkPolicyMatcher,
11
+ NetworkPolicyRule,
12
+ NetworkTransformer,
13
+ } from "./network-policy.js";
21
14
 
22
15
  export interface SandboxKeepLastSnapshotsConfig {
23
16
  count: number;
@@ -0,0 +1,161 @@
1
+ //#region src/network-policy.d.ts
2
+ /**
3
+ * A transform applied to network requests matching a domain rule.
4
+ *
5
+ * @example
6
+ * {
7
+ * headers: { authorization: "Bearer sk-..." }
8
+ * }
9
+ */
10
+ type NetworkTransformer = {
11
+ /** Headers to set on the outgoing request. */
12
+ headers?: Record<string, string>;
13
+ };
14
+ /**
15
+ * Defines how a request value is matched.
16
+ */
17
+ type NetworkPolicyMatcher = {
18
+ /** Match the value exactly. */
19
+ exact?: string;
20
+ } | {
21
+ /** Match values that start with the provided prefix. */
22
+ startsWith?: string;
23
+ } | {
24
+ /** Match values against an RE2 regular expression. */
25
+ regex?: string;
26
+ };
27
+ /**
28
+ * Matcher for key/value request entries such as headers and query parameters.
29
+ */
30
+ type NetworkPolicyKeyValueMatcher = {
31
+ /** Matcher for the entry key. */
32
+ key?: NetworkPolicyMatcher;
33
+ /** Matcher for the entry value. */
34
+ value?: NetworkPolicyMatcher;
35
+ };
36
+ /**
37
+ * Request matcher for a network policy rule.
38
+ *
39
+ * All specified dimensions must match. Multiple methods are ORed; multiple
40
+ * header and query-string matchers are ANDed.
41
+ */
42
+ type NetworkPolicyMatch = {
43
+ /** Match on the request path. */
44
+ path?: NetworkPolicyMatcher;
45
+ /** Match on the HTTP method. */
46
+ method?: string[];
47
+ /** Match on query-string entries. */
48
+ queryString?: NetworkPolicyKeyValueMatcher[];
49
+ /** Match on request headers. */
50
+ headers?: NetworkPolicyKeyValueMatcher[];
51
+ };
52
+ /**
53
+ * A rule applied to requests matching a domain in the network policy.
54
+ */
55
+ type NetworkPolicyRule = {
56
+ /**
57
+ * Optional request matcher. When provided, transforms only apply to requests
58
+ * that match every specified dimension.
59
+ */
60
+ match?: NetworkPolicyMatch;
61
+ /**
62
+ * Transforms to apply to matching requests.
63
+ */
64
+ transform?: NetworkTransformer[];
65
+ /**
66
+ * HTTPS proxy URL to forward matching requests to. Must not include query string or fragment.
67
+ *
68
+ * You can use the `defineSandboxProxy` helper from `@vercel/sandbox/proxy` to implement the proxy handler
69
+ * automatically, which handles authorization and extracts metadata about the request and sandbox.
70
+ *
71
+ * @see https://vercel.com/docs/vercel-sandbox/concepts/firewall#requests-proxying
72
+ */
73
+ forwardURL?: string;
74
+ };
75
+ /**
76
+ * Network policy to define network restrictions for the sandbox.
77
+ *
78
+ * - `"allow-all"`: Full internet access (default). All traffic is allowed.
79
+ * - `"deny-all"`: No internet access. All traffic is denied.
80
+ * - Object: Custom access with explicit allow/deny lists.
81
+ *
82
+ * @example
83
+ * // Full internet access (default)
84
+ * "allow-all"
85
+ *
86
+ * @example
87
+ * // No external access
88
+ * "deny-all"
89
+ *
90
+ * @example
91
+ * // Custom access with specific domains (simple list)
92
+ * // All traffic not explicitly allowed is denied.
93
+ * {
94
+ * allow: ["*.npmjs.org", "github.com"],
95
+ * subnets: {
96
+ * allow: ["10.0.0.0/8"],
97
+ * deny: ["10.1.0.0/16"]
98
+ * }
99
+ * }
100
+ *
101
+ * @example
102
+ * // Custom access with specific domains (record form)
103
+ * {
104
+ * allow: {
105
+ * "*.npmjs.org": [],
106
+ * "github.com": [],
107
+ * }
108
+ * }
109
+ *
110
+ * @example
111
+ * // Custom access with request transformers
112
+ * {
113
+ * allow: {
114
+ * "ai-gateway.vercel.sh": [
115
+ * {
116
+ * match: {
117
+ * method: ["POST"],
118
+ * path: { startsWith: "/v1/" },
119
+ * headers: [
120
+ * { key: { exact: "x-api-key" }, value: { exact: "placeholder" } }
121
+ * ]
122
+ * },
123
+ * transform: [{
124
+ * headers: { authorization: "Bearer ..." }
125
+ * }]
126
+ * }
127
+ * ],
128
+ * "*": []
129
+ * }
130
+ * }
131
+ */
132
+ type NetworkPolicy = "allow-all" | "deny-all" | {
133
+ /**
134
+ * Domains to allow traffic to.
135
+ * Use "*" prefix for wildcard matching (e.g., "*.npmjs.org").
136
+ *
137
+ * Accepts either:
138
+ * - `string[]`: A simple list of domains to allow.
139
+ * - `Record<string, NetworkPolicyRule[]>`: A map of domains to rules.
140
+ * An empty array allows traffic with no additional rules.
141
+ */
142
+ allow?: string[] | Record<string, NetworkPolicyRule[]>;
143
+ /**
144
+ * Subnet-level access control using CIDR notation.
145
+ */
146
+ subnets?: {
147
+ /**
148
+ * List of CIDRs to allow traffic to.
149
+ * Traffic to these addresses will bypass the domain allowlist.
150
+ */
151
+ allow?: string[];
152
+ /**
153
+ * List of CIDRs to deny traffic to.
154
+ * These take precedence over allowed domains and CIDRs.
155
+ */
156
+ deny?: string[];
157
+ };
158
+ };
159
+ //#endregion
160
+ export { NetworkPolicy, NetworkPolicyKeyValueMatcher, NetworkPolicyMatch, NetworkPolicyMatcher, NetworkPolicyRule, NetworkTransformer };
161
+ //# sourceMappingURL=network-policy.d.ts.map
@@ -1,3 +1,16 @@
1
+ // The network-policy types are copied verbatim from the installed just-bash at
2
+ // vendor time (see scripts/vendor-compiled/just-bash.mjs) so the credential-
3
+ // brokering surface (allowedUrlPrefixes + header transforms) never drifts.
4
+ import type { NetworkConfig } from "./network/types.js";
5
+
6
+ export type {
7
+ AllowedUrl,
8
+ AllowedUrlEntry,
9
+ HttpMethod,
10
+ NetworkConfig,
11
+ RequestTransform,
12
+ } from "./network/types.js";
13
+
1
14
  export type InitialFileContent = string | Uint8Array;
2
15
  export type InitialFiles = Record<string, InitialFileContent>;
3
16
 
@@ -17,7 +30,7 @@ export interface BashOptions {
17
30
  cwd: string;
18
31
  env?: Readonly<Record<string, string>> | undefined;
19
32
  fs: IFileSystem;
20
- network?: { dangerouslyAllowFullInternetAccess?: boolean | undefined } | undefined;
33
+ network?: NetworkConfig | undefined;
21
34
  }
22
35
 
23
36
  export interface BashExecResult {
@@ -50,7 +63,7 @@ export interface SandboxOptions {
50
63
  cwd?: string | undefined;
51
64
  env?: Record<string, string> | undefined;
52
65
  fs?: IFileSystem | undefined;
53
- network?: { dangerouslyAllowFullInternetAccess?: boolean | undefined } | undefined;
66
+ network?: NetworkConfig | undefined;
54
67
  timeoutMs?: number | undefined;
55
68
  }
56
69
 
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Network configuration types
3
+ *
4
+ * Network access is disabled by default. To enable network access (e.g., for curl),
5
+ * you must explicitly configure allowed URLs.
6
+ */
7
+ /**
8
+ * DNS lookup result used for private IP resolution checks
9
+ */
10
+ export interface DnsLookupResult {
11
+ address: string;
12
+ family: number;
13
+ }
14
+ /**
15
+ * HTTP methods that can be allowed
16
+ */
17
+ export type HttpMethod = "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS";
18
+ /**
19
+ * Header transform applied at the fetch boundary.
20
+ * Headers specified here override any user-supplied headers with the same name.
21
+ */
22
+ export interface RequestTransform {
23
+ headers: Record<string, string>;
24
+ }
25
+ /**
26
+ * An allowed URL entry with optional header transforms.
27
+ * Transforms are applied at the fetch boundary so secrets never enter the sandbox.
28
+ */
29
+ export interface AllowedUrl {
30
+ url: string;
31
+ transform?: RequestTransform[];
32
+ }
33
+ /**
34
+ * An entry in the allowedUrlPrefixes list: either a plain URL string or
35
+ * an object with a URL and optional transforms.
36
+ */
37
+ export type AllowedUrlEntry = string | AllowedUrl;
38
+ /**
39
+ * Configuration for network access
40
+ */
41
+ export interface NetworkConfig {
42
+ /**
43
+ * List of allowed URL prefixes. Each entry must be a full origin (scheme + host),
44
+ * optionally followed by a path prefix:
45
+ * - An origin: "https://api.example.com" - allows all paths on this origin
46
+ * - An origin + path prefix: "https://api.example.com/v1/" - allows only paths starting with /v1/
47
+ *
48
+ * Entries can be plain strings or objects with transforms for credentials brokering:
49
+ * ```
50
+ * allowedUrlPrefixes: [
51
+ * "https://other-api.com",
52
+ * {
53
+ * url: "https://ai-gateway.vercel.sh",
54
+ * transform: [{ headers: { "Authorization": "Bearer secret" } }],
55
+ * },
56
+ * ]
57
+ * ```
58
+ *
59
+ * The check is performed on the full URL, so "https://api.example.com/v1" will allow:
60
+ * - https://api.example.com/v1
61
+ * - https://api.example.com/v1/users
62
+ * - https://api.example.com/v1/users/123
63
+ *
64
+ * But NOT:
65
+ * - https://api.example.com/v10
66
+ * - https://api.example.com/v1-admin
67
+ * - https://api.example.com/v2/users
68
+ * - https://api.example.org/v1/users (different origin)
69
+ * - URLs that rely on ambiguous encoded separators like %2f or %5c
70
+ *
71
+ * Invalid entries (missing scheme, missing host, relative paths) will throw an error.
72
+ */
73
+ allowedUrlPrefixes?: AllowedUrlEntry[];
74
+ /**
75
+ * List of allowed HTTP methods. Defaults to ["GET", "HEAD"] for safety.
76
+ * dangerouslyAllowFullInternetAccess to enables all methods.
77
+ */
78
+ allowedMethods?: HttpMethod[];
79
+ /**
80
+ * Bypass the allow-list and allow all URLs and methods.
81
+ * DANGEROUS: Only use this in trusted environments.
82
+ */
83
+ dangerouslyAllowFullInternetAccess?: boolean;
84
+ /**
85
+ * Maximum number of redirects to follow (default: 20)
86
+ */
87
+ maxRedirects?: number;
88
+ /**
89
+ * Request timeout in milliseconds (default: 30000)
90
+ */
91
+ timeoutMs?: number;
92
+ /**
93
+ * Maximum response body size in bytes (default: 10MB).
94
+ * Responses larger than this will be rejected with ResponseTooLargeError.
95
+ */
96
+ maxResponseSize?: number;
97
+ /**
98
+ * Reject URLs with private/loopback IP addresses as hostnames.
99
+ * Performs both lexical hostname checks and DNS resolution to catch
100
+ * domains that resolve to private IPs (e.g., DNS rebinding attacks).
101
+ * Useful for mitigating SSRF attacks. Default: false (opt-in).
102
+ *
103
+ * When enabled, the private IP check is enforced even when
104
+ * `dangerouslyAllowFullInternetAccess` is true, ensuring that
105
+ * internal/loopback addresses are never reachable.
106
+ */
107
+ denyPrivateRanges?: boolean;
108
+ /**
109
+ * @internal Override DNS resolution for testing.
110
+ * When set, used instead of the default `dns.lookup` for the
111
+ * denyPrivateRanges DNS rebinding check.
112
+ */
113
+ _dnsResolve?: (hostname: string) => Promise<DnsLookupResult[]>;
114
+ }
115
+ /**
116
+ * Result of a network fetch operation
117
+ */
118
+ export interface FetchResult {
119
+ status: number;
120
+ statusText: string;
121
+ headers: Record<string, string>;
122
+ /** Raw response bytes (never decoded as UTF-8 text). */
123
+ body: Uint8Array;
124
+ url: string;
125
+ }
126
+ /**
127
+ * Error thrown when a URL is not allowed
128
+ */
129
+ export declare class NetworkAccessDeniedError extends Error {
130
+ constructor(url: string, reason?: string);
131
+ }
132
+ /**
133
+ * Error thrown when too many redirects occur
134
+ */
135
+ export declare class TooManyRedirectsError extends Error {
136
+ constructor(maxRedirects: number);
137
+ }
138
+ /**
139
+ * Error thrown when a redirect target is not allowed
140
+ */
141
+ export declare class RedirectNotAllowedError extends Error {
142
+ constructor(url: string);
143
+ }
144
+ /**
145
+ * Error thrown when an HTTP method is not allowed
146
+ */
147
+ export declare class MethodNotAllowedError extends Error {
148
+ constructor(method: string, allowedMethods: string[]);
149
+ }
150
+ /**
151
+ * Error thrown when a response body exceeds the maximum allowed size
152
+ */
153
+ export declare class ResponseTooLargeError extends Error {
154
+ constructor(maxSize: number);
155
+ }
@@ -22,6 +22,7 @@ export declare const COMPILE_METADATA_VERSION = 5;
22
22
  */
23
23
  export interface CompilerArtifactPaths {
24
24
  appRoot: string;
25
+ channelInstrumentationTypesPath: string;
25
26
  compiledManifestPath: string;
26
27
  compileDirectoryPath: string;
27
28
  compileMetadataPath: string;
@@ -1 +1 @@
1
- import{join,relative,resolve}from"node:path";import{mkdir,writeFile}from"node:fs/promises";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createHash}from"node:crypto";import{summarizeDiscoverDiagnostics}from"#discover/diagnostics.js";import{normalizeLogicalPath}from"#discover/filesystem.js";import{createCompiledModuleMapSource}from"#compiler/module-map.js";import{compileAgentManifest}from"#compiler/normalize-manifest.js";import{materializeWorkspaceResources}from"#compiler/workspace-resources.js";const COMPILE_METADATA_KIND=`ash-compile-metadata`,COMPILE_METADATA_VERSION=5;function resolveCompilerArtifactPaths(t){let r=resolve(t),i=join(r,`.ash`,`discovery`),a=join(r,`.ash`,`compile`);return{appRoot:r,compiledManifestPath:join(a,`compiled-agent-manifest.json`),compileDirectoryPath:a,compileMetadataPath:join(a,`compile-metadata.json`),diagnosticsPath:join(i,`diagnostics.json`),discoveryManifestPath:join(i,`agent-discovery-manifest.json`),discoveryDirectoryPath:i,moduleMapPath:join(a,`module-map.mjs`)}}function createDiscoveryDiagnosticsArtifact(e){return{diagnostics:[...e],kind:`ash-discovery-diagnostics`,summary:summarizeDiscoverDiagnostics(e),version:1}}function createCompileMetadata(e){let t=resolveInstalledPackageInfo(),n=createContentHash(e.discoveryManifestJson),r=createContentHash(e.diagnosticsArtifactJson),i=createContentHash(e.moduleMapSource);return{compile:{moduleMap:{path:toArtifactRelativePath(e.appRoot,e.paths.moduleMapPath),sha256:i}},discovery:{diagnostics:{path:toArtifactRelativePath(e.appRoot,e.paths.diagnosticsPath),sha256:r},manifest:{path:toArtifactRelativePath(e.appRoot,e.paths.discoveryManifestPath),sha256:n},sourceGraphHash:createContentHash(`${n}:${r}:${i}`),summary:e.diagnosticsSummary},generator:{name:t.name,version:t.version},kind:COMPILE_METADATA_KIND,status:e.diagnosticsSummary.errors>0?`failed`:`ready`,version:5}}async function writeCompilerArtifacts(e){let t=resolveCompilerArtifactPaths(e.appRoot),n=createDiscoveryDiagnosticsArtifact(e.diagnostics),a=await materializeWorkspaceResources({compileDirectoryPath:t.compileDirectoryPath,manifest:await compileAgentManifest(e.manifest)}),o=serializeArtifactJson(a),s=serializeArtifactJson(e.manifest),c=serializeArtifactJson(n),l=createCompiledModuleMapSource({manifest:a,moduleMapPath:t.moduleMapPath}),u=createCompileMetadata({appRoot:e.appRoot,diagnosticsArtifactJson:c,diagnosticsSummary:n.summary,discoveryManifestJson:s,moduleMapSource:l,paths:t}),d=serializeArtifactJson(u);return await mkdir(t.discoveryDirectoryPath,{recursive:!0}),await mkdir(t.compileDirectoryPath,{recursive:!0}),await Promise.all([writeFile(t.compiledManifestPath,o),writeFile(t.diagnosticsPath,c),writeFile(t.discoveryManifestPath,s),writeFile(t.moduleMapPath,l),writeFile(t.compileMetadataPath,d)]),{compiledManifest:a,diagnosticsArtifact:n,metadata:u,moduleMapSource:l,paths:t}}function createContentHash(e){return createHash(`sha256`).update(e).digest(`hex`)}function serializeArtifactJson(e){return`${JSON.stringify(e,null,2)}\n`}function toArtifactRelativePath(e,r){return normalizeLogicalPath(relative(resolve(e),r))}export{COMPILE_METADATA_KIND,COMPILE_METADATA_VERSION,createCompileMetadata,resolveCompilerArtifactPaths,writeCompilerArtifacts};
1
+ import{join,relative,resolve}from"node:path";import{mkdir,writeFile}from"node:fs/promises";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createHash}from"node:crypto";import{summarizeDiscoverDiagnostics}from"#discover/diagnostics.js";import{normalizeLogicalPath}from"#discover/filesystem.js";import{CHANNEL_INSTRUMENTATION_TYPES_FILE_NAME,createChannelInstrumentationTypesSource}from"#compiler/channel-instrumentation-types.js";import{createCompiledModuleMapSource}from"#compiler/module-map.js";import{compileAgentManifest}from"#compiler/normalize-manifest.js";import{materializeWorkspaceResources}from"#compiler/workspace-resources.js";const COMPILE_METADATA_KIND=`ash-compile-metadata`,COMPILE_METADATA_VERSION=5;function resolveCompilerArtifactPaths(t){let r=resolve(t),i=join(r,`.ash`,`discovery`),a=join(r,`.ash`,`compile`);return{appRoot:r,channelInstrumentationTypesPath:join(a,CHANNEL_INSTRUMENTATION_TYPES_FILE_NAME),compiledManifestPath:join(a,`compiled-agent-manifest.json`),compileDirectoryPath:a,compileMetadataPath:join(a,`compile-metadata.json`),diagnosticsPath:join(i,`diagnostics.json`),discoveryManifestPath:join(i,`agent-discovery-manifest.json`),discoveryDirectoryPath:i,moduleMapPath:join(a,`module-map.mjs`)}}function createDiscoveryDiagnosticsArtifact(e){return{diagnostics:[...e],kind:`ash-discovery-diagnostics`,summary:summarizeDiscoverDiagnostics(e),version:1}}function createCompileMetadata(e){let t=resolveInstalledPackageInfo(),n=createContentHash(e.discoveryManifestJson),r=createContentHash(e.diagnosticsArtifactJson),i=createContentHash(e.moduleMapSource);return{compile:{moduleMap:{path:toArtifactRelativePath(e.appRoot,e.paths.moduleMapPath),sha256:i}},discovery:{diagnostics:{path:toArtifactRelativePath(e.appRoot,e.paths.diagnosticsPath),sha256:r},manifest:{path:toArtifactRelativePath(e.appRoot,e.paths.discoveryManifestPath),sha256:n},sourceGraphHash:createContentHash(`${n}:${r}:${i}`),summary:e.diagnosticsSummary},generator:{name:t.name,version:t.version},kind:COMPILE_METADATA_KIND,status:e.diagnosticsSummary.errors>0?`failed`:`ready`,version:5}}async function writeCompilerArtifacts(e){let t=resolveCompilerArtifactPaths(e.appRoot),n=createDiscoveryDiagnosticsArtifact(e.diagnostics),a=await materializeWorkspaceResources({compileDirectoryPath:t.compileDirectoryPath,manifest:await compileAgentManifest(e.manifest)}),o=serializeArtifactJson(a),s=serializeArtifactJson(e.manifest),c=serializeArtifactJson(n),l=createCompiledModuleMapSource({manifest:a,moduleMapPath:t.moduleMapPath}),u=createChannelInstrumentationTypesSource({manifest:a,typesPath:t.channelInstrumentationTypesPath}),d=createCompileMetadata({appRoot:e.appRoot,diagnosticsArtifactJson:c,diagnosticsSummary:n.summary,discoveryManifestJson:s,moduleMapSource:l,paths:t}),f=serializeArtifactJson(d);return await mkdir(t.discoveryDirectoryPath,{recursive:!0}),await mkdir(t.compileDirectoryPath,{recursive:!0}),await Promise.all([writeFile(t.compiledManifestPath,o),writeFile(t.diagnosticsPath,c),writeFile(t.discoveryManifestPath,s),writeFile(t.channelInstrumentationTypesPath,u),writeFile(t.moduleMapPath,l),writeFile(t.compileMetadataPath,f)]),{compiledManifest:a,diagnosticsArtifact:n,metadata:d,moduleMapSource:l,paths:t}}function createContentHash(e){return createHash(`sha256`).update(e).digest(`hex`)}function serializeArtifactJson(e){return`${JSON.stringify(e,null,2)}\n`}function toArtifactRelativePath(e,r){return normalizeLogicalPath(relative(resolve(e),r))}export{COMPILE_METADATA_KIND,COMPILE_METADATA_VERSION,createCompileMetadata,resolveCompilerArtifactPaths,writeCompilerArtifacts};
@@ -0,0 +1,8 @@
1
+ import type { CompiledAgentManifest } from "#compiler/manifest.js";
2
+ interface ChannelInstrumentationTypesSourceInput {
3
+ readonly manifest: CompiledAgentManifest;
4
+ readonly typesPath: string;
5
+ }
6
+ export declare const CHANNEL_INSTRUMENTATION_TYPES_FILE_NAME = "channel-instrumentation-types.d.ts";
7
+ export declare function createChannelInstrumentationTypesSource(input: ChannelInstrumentationTypesSourceInput): string;
8
+ export {};
@@ -0,0 +1,2 @@
1
+ import{dirname,join,relative}from"node:path";const CHANNEL_INSTRUMENTATION_TYPES_FILE_NAME=`channel-instrumentation-types.d.ts`;function createChannelInstrumentationTypesSource(e){let t=collectChannelInstrumentationDeclarations(e);return[`// Generated by Ash. Do not edit by hand.`,`import type { InferChannelMetadata } from "experimental-ash/channels";`,``,`declare module "experimental-ash/instrumentation" {`,...t.length===0?[` interface ChannelMetadataMap {}`,` interface ChannelReferenceMap {}`]:[` interface ChannelMetadataMap {`,...t.map(e=>` readonly ${JSON.stringify(e.kind)}: InferChannelMetadata<${renderImportedChannelType(e)}>;`),` }`,` interface ChannelReferenceMap {`,...t.map(e=>` readonly ${JSON.stringify(e.kind)}: ${renderImportedChannelType(e)};`),` }`],`}`,``].join(`
2
+ `)}function collectChannelInstrumentationDeclarations(t){let n=dirname(t.typesPath),r=new Map;for(let e of[...t.manifest.channels].filter(e=>e.kind===`channel`).sort(compareCompiledChannels)){let i=`channel:${e.name}`;r.has(i)||r.set(i,{exportName:e.exportName,importSpecifier:createChannelImportSpecifier({agentRoot:t.manifest.agentRoot,channel:e,fromDirectory:n}),kind:i})}return[...r.values()]}function compareCompiledChannels(e,t){return e.name.localeCompare(t.name)||e.logicalPath.localeCompare(t.logicalPath)||(e.exportName??``).localeCompare(t.exportName??``)||e.sourceId.localeCompare(t.sourceId)||e.method.localeCompare(t.method)||e.urlPath.localeCompare(t.urlPath)}function createChannelImportSpecifier(e){let r=join(e.agentRoot,toRuntimeImportLogicalPath(e.channel.logicalPath)),i=relative(e.fromDirectory,r).replaceAll(`\\`,`/`);return i.startsWith(`.`)?i:`./${i}`}function toRuntimeImportLogicalPath(e){return e.endsWith(`.mts`)?`${e.slice(0,-4)}.mjs`:e.endsWith(`.cts`)?`${e.slice(0,-4)}.cjs`:e.endsWith(`.ts`)?`${e.slice(0,-3)}.js`:e}function renderImportedChannelType(e){let t=e.exportName??`default`,n=`import(${JSON.stringify(e.importSpecifier)})`;return isIdentifierName(t)?`typeof ${n}.${t}`:`typeof ${n}[${JSON.stringify(t)}]`}function isIdentifierName(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}export{CHANNEL_INSTRUMENTATION_TYPES_FILE_NAME,createChannelInstrumentationTypesSource};