experimental-ash 0.42.0 → 0.43.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.
- package/CHANGELOG.md +30 -0
- package/dist/docs/public/README.md +8 -8
- package/dist/docs/public/advanced/{auth-and-route-protection.md → auth-and-route-protection.mdx} +11 -0
- package/dist/docs/public/advanced/context-control.md +4 -4
- package/dist/docs/public/advanced/{evals.md → evals.mdx} +11 -1
- package/dist/docs/public/advanced/{hooks.md → hooks.mdx} +28 -40
- package/dist/docs/public/advanced/instrumentation.md +92 -3
- package/dist/docs/public/advanced/project-layout.md +5 -5
- package/dist/docs/public/advanced/runs-and-streaming.md +8 -2
- package/dist/docs/public/advanced/session-context.md +1 -1
- package/dist/docs/public/advanced/typescript-api.md +49 -6
- package/dist/docs/public/advanced/vercel-deployment.md +1 -1
- package/dist/docs/public/agent-ts.md +5 -5
- package/dist/docs/public/channels/{discord.md → discord.mdx} +11 -0
- package/dist/docs/public/channels/index.md +10 -10
- package/dist/docs/public/channels/{slack.md → slack.mdx} +11 -0
- package/dist/docs/public/channels/{teams.md → teams.mdx} +12 -0
- package/dist/docs/public/channels/{telegram.md → telegram.mdx} +11 -0
- package/dist/docs/public/channels/{twilio.md → twilio.mdx} +11 -0
- package/dist/docs/public/{connections.md → connections.mdx} +18 -6
- package/dist/docs/public/frontend/README.md +16 -0
- package/dist/docs/public/frontend/meta.json +3 -0
- package/dist/docs/public/frontend/nextjs.md +192 -0
- package/dist/docs/public/frontend/use-ash-agent.md +332 -0
- package/dist/docs/public/{getting-started.md → getting-started.mdx} +12 -1
- package/dist/docs/public/{human-in-the-loop.md → human-in-the-loop.mdx} +12 -1
- package/dist/docs/public/meta.json +1 -0
- package/dist/docs/public/sandbox.md +1 -1
- package/dist/docs/public/{schedules.md → schedules.mdx} +9 -0
- package/dist/docs/public/skills.md +2 -2
- package/dist/docs/public/{subagents.md → subagents.mdx} +10 -0
- package/dist/docs/public/{tools.md → tools.mdx} +41 -26
- package/dist/src/channel/adapter.d.ts +13 -0
- package/dist/src/channel/instrumentation.d.ts +10 -0
- package/dist/src/channel/instrumentation.js +1 -0
- package/dist/src/channel/send.js +1 -1
- package/dist/src/channel/types.d.ts +16 -0
- package/dist/src/cli/commands/channels.d.ts +2 -1
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/compiler/manifest.d.ts +13 -1
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/module-map.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/normalize-skill.d.ts +15 -2
- package/dist/src/compiler/normalize-skill.js +1 -1
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/dynamic-skill-lifecycle.d.ts +23 -0
- package/dist/src/context/dynamic-skill-lifecycle.js +1 -0
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +2 -0
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/context/hook-lifecycle.d.ts +4 -6
- package/dist/src/context/hook-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +6 -4
- package/dist/src/context/keys.js +1 -1
- package/dist/src/context/providers/connection.d.ts +9 -0
- package/dist/src/context/providers/connection.js +1 -1
- package/dist/src/context/providers/sandbox.js +1 -1
- package/dist/src/execution/ash-workflow-attributes.d.ts +118 -0
- package/dist/src/execution/ash-workflow-attributes.js +1 -0
- package/dist/src/execution/channel-context.d.ts +5 -0
- package/dist/src/execution/channel-context.js +1 -0
- package/dist/src/execution/create-session-step.d.ts +28 -1
- package/dist/src/execution/create-session-step.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/durable-session-store.d.ts +7 -0
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/sandbox/prewarm.js +1 -1
- package/dist/src/execution/session.d.ts +6 -0
- package/dist/src/execution/session.js +2 -2
- package/dist/src/execution/skills/instructions.d.ts +3 -2
- package/dist/src/execution/subagent-tool.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/code-mode.d.ts +0 -5
- package/dist/src/harness/code-mode.js +1 -1
- package/dist/src/harness/emission.d.ts +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/instrumentation-config.d.ts +1 -1
- package/dist/src/harness/instrumentation-metadata.d.ts +23 -0
- package/dist/src/harness/instrumentation-metadata.js +1 -0
- package/dist/src/harness/otel-integration.d.ts +2 -2
- package/dist/src/harness/otel-integration.js +1 -1
- package/dist/src/harness/step-hooks.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/turn-tag-state.d.ts +50 -0
- package/dist/src/harness/turn-tag-state.js +1 -0
- package/dist/src/harness/types.d.ts +11 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/schema-backed.d.ts +0 -1
- package/dist/src/internal/authored-definition/schema-backed.js +1 -1
- package/dist/src/internal/instrumentation.d.ts +39 -0
- package/dist/src/internal/instrumentation.js +1 -0
- package/dist/src/internal/workflow/builtins.d.ts +32 -0
- package/dist/src/internal/workflow/builtins.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +34 -0
- package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-transformer.js +1 -1
- package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
- package/dist/src/packages/ash-scaffold/src/steps/run-add-to-agent.js +2 -2
- package/dist/src/public/channels/slack/attachments.js +1 -1
- package/dist/src/public/channels/slack/index.d.ts +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +6 -0
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/index.d.ts +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +6 -0
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/definitions/defineChannel.d.ts +12 -2
- package/dist/src/public/definitions/defineChannel.js +1 -1
- package/dist/src/public/definitions/hook.d.ts +3 -11
- package/dist/src/public/definitions/instrumentation.d.ts +88 -2
- package/dist/src/public/definitions/skill.d.ts +5 -0
- package/dist/src/public/definitions/tool.d.ts +25 -66
- package/dist/src/public/definitions/tool.js +1 -1
- package/dist/src/public/instrumentation/index.d.ts +1 -4
- package/dist/src/public/instrumentation/index.js +1 -1
- package/dist/src/public/skills/index.d.ts +2 -0
- package/dist/src/public/skills/index.js +1 -1
- package/dist/src/public/tools/index.d.ts +2 -2
- package/dist/src/public/tools/index.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +4 -7
- package/dist/src/runtime/agent/mock-model-skill-selection.d.ts +9 -0
- package/dist/src/runtime/agent/mock-model-skill-selection.js +4 -0
- package/dist/src/runtime/attributes/emit.d.ts +73 -0
- package/dist/src/runtime/attributes/emit.js +1 -0
- package/dist/src/runtime/channels/registry.js +1 -1
- package/dist/src/runtime/connections/mcp-client.js +1 -1
- package/dist/src/runtime/framework-tools/code-mode-connection-auth.d.ts +2 -0
- package/dist/src/runtime/framework-tools/connection-search-dynamic.d.ts +34 -0
- package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -0
- package/dist/src/runtime/framework-tools/index.d.ts +7 -5
- package/dist/src/runtime/framework-tools/index.js +1 -1
- package/dist/src/runtime/prompt/connections.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/resolve-dynamic-skill.d.ts +8 -0
- package/dist/src/runtime/resolve-dynamic-skill.js +1 -0
- package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
- package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
- package/dist/src/runtime/sessions/runtime-context-keys.js +1 -1
- package/dist/src/runtime/types.d.ts +13 -4
- package/dist/src/shared/dynamic-tool-definition.d.ts +51 -76
- package/dist/src/shared/dynamic-tool-definition.js +1 -1
- package/dist/src/shared/guards.d.ts +14 -0
- package/dist/src/shared/guards.js +1 -1
- package/dist/src/shared/skill-definition.d.ts +5 -4
- package/dist/src/shared/tool-definition.d.ts +12 -0
- package/package.json +2 -1
- package/dist/src/runtime/framework-tools/connection-search.d.ts +0 -57
- package/dist/src/runtime/framework-tools/connection-search.js +0 -1
- package/dist/src/runtime/framework-tools/connection-tools.d.ts +0 -55
- package/dist/src/runtime/framework-tools/connection-tools.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# experimental-ash
|
|
2
2
|
|
|
3
|
+
## 0.43.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 52146a5: Migrate `connection_search` from a framework tool singleton to a dynamic tool resolver. Discovered connection tools are now derived from conversation history via `ctx.messages` — no `DiscoveredConnectionToolsKey` durable state or `onCompact` hook needed. Deletes `connection-tools.ts` and the old `connection-search.ts` implementation.
|
|
8
|
+
- 2469218: Unified dynamic tool API: `defineTools` and `defineTool({ events })` are replaced by `defineDynamic`, and the `tool()` entry wrapper is replaced by `defineTool`. Handlers return either a single `defineTool(...)` (named after the file slug) or a `Record<string, defineTool(...)>` (named `slug__key`). The `identity` field is removed from compiled manifests — single vs map detection is now runtime-based.
|
|
9
|
+
- 192a1eb: Add dynamic instrumentation metadata via `metadata["step.started"]`, with per-attempt session, turn, step, channel, and model-input access. The channel projection exposes `kind` (`channel:<filename>` for authored channels, or `http`/`schedule`/`subagent`), also emitted as the `ash.channel.kind` span attribute. Authored metadata is parsed defensively: resolver failures, thenables, reserved `ash.*` keys, and non-string values are dropped without interrupting the model call.
|
|
10
|
+
- d7de8e0: Clean up `DynamicToolResolveContext`: remove `__cache`, add `messages` for history access, add `toModelOutput` to `DynamicToolEntry`, and run the dynamic tool bundler transform on framework tools during the ash build.
|
|
11
|
+
- dc0db8e: Dynamic skills can now be authored with `defineDynamic` + `defineSkill` in `agent/skills/`, matching the `defineDynamic` + `defineTool` pattern for dynamic tools. Resolvers subscribe to lifecycle events (`session.started`, `turn.started`, `step.started`) and return branded `defineSkill(...)` entries that are materialized to the sandbox. Single returns use the file slug as the skill name; map returns use `slug__key`. Hook-contributed skills via `LifecycleHookResult.skills` continue to work but are deprecated in favor of this approach.
|
|
12
|
+
- 80b4c1d: Remove `LifecycleHookResult.skills` — lifecycle hooks can no longer contribute skills. Use `defineDynamic` + `defineSkill` in `agent/skills/` instead.
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 3df1814: Emit `$ash.*` workflow run attributes for agent run observability. Every
|
|
17
|
+
session, turn, and subagent run now tags itself with a small set of
|
|
18
|
+
reserved-namespace attributes (`$ash.type`, `$ash.parent`,
|
|
19
|
+
`$ash.root`, `$ash.subagent`, `$ash.trigger`, `$ash.title`,
|
|
20
|
+
`$ash.model`, `$ash.input_tokens`, `$ash.output_tokens`,
|
|
21
|
+
`$ash.cache_read_tokens`, `$ash.tool_count`) so the Vercel dashboard can
|
|
22
|
+
hydrate the Agent Runs view via the workflow runtime's
|
|
23
|
+
`workflow_run_attributes` table without scraping events.
|
|
24
|
+
|
|
25
|
+
Tag writes are best-effort — runtime failures are logged once per process
|
|
26
|
+
and swallowed so a broken attribute write can never break a session. No
|
|
27
|
+
public API changes; authored agent code never sees the `$ash.*` namespace.
|
|
28
|
+
See `research/active/workflow-run-attributes.md` for the full design.
|
|
29
|
+
|
|
30
|
+
- 70a2d17: Authenticate Slack Enterprise Grid file downloads so agents can read private attachments served from workspace `enterprise.slack.com` hosts.
|
|
31
|
+
- 08e2696: Deploy scaffolded Web Chat routes to Vercel when channel setup adds a deployable route.
|
|
32
|
+
|
|
3
33
|
## 0.42.0
|
|
4
34
|
|
|
5
35
|
### Minor Changes
|
|
@@ -15,24 +15,24 @@ Important naming note:
|
|
|
15
15
|
|
|
16
16
|
Read in this order:
|
|
17
17
|
|
|
18
|
-
1. [Getting Started](./getting-started.
|
|
18
|
+
1. [Getting Started](./getting-started.mdx)
|
|
19
19
|
2. [Project Layout](./advanced/project-layout.md)
|
|
20
20
|
3. [`agent.ts`](./agent-ts.md)
|
|
21
21
|
4. [TypeScript API](./advanced/typescript-api.md)
|
|
22
22
|
5. [Context Control](./advanced/context-control.md)
|
|
23
23
|
6. [Skills](./skills.md)
|
|
24
|
-
7. [Tools](./tools.
|
|
25
|
-
8. [Connections](./connections.
|
|
24
|
+
7. [Tools](./tools.mdx)
|
|
25
|
+
8. [Connections](./connections.mdx)
|
|
26
26
|
9. [Workspace](./advanced/workspace.md)
|
|
27
27
|
10. [Sandboxes](./sandbox.md)
|
|
28
28
|
11. [Channels](./channels/README.md)
|
|
29
|
-
12. [Human In The Loop](./human-in-the-loop.
|
|
29
|
+
12. [Human In The Loop](./human-in-the-loop.mdx)
|
|
30
30
|
13. [Session Context](./advanced/session-context.md)
|
|
31
31
|
14. [Sessions And Streaming](./advanced/runs-and-streaming.md)
|
|
32
|
-
15. [Subagents](./subagents.
|
|
33
|
-
16. [Schedules](./schedules.
|
|
34
|
-
17. [Evals](./advanced/evals.
|
|
35
|
-
18. [Auth And Route Protection](./advanced/auth-and-route-protection.
|
|
32
|
+
15. [Subagents](./subagents.mdx)
|
|
33
|
+
16. [Schedules](./schedules.mdx)
|
|
34
|
+
17. [Evals](./advanced/evals.mdx)
|
|
35
|
+
18. [Auth And Route Protection](./advanced/auth-and-route-protection.mdx)
|
|
36
36
|
19. [Vercel Deployment](./advanced/vercel-deployment.md)
|
|
37
37
|
20. [CLI, Build, And Debugging](./advanced/cli-build-and-debugging.md)
|
|
38
38
|
|
package/dist/docs/public/advanced/{auth-and-route-protection.md → auth-and-route-protection.mdx}
RENAMED
|
@@ -16,6 +16,17 @@ These settings apply to:
|
|
|
16
16
|
- `POST /ash/v1/session/:sessionId`
|
|
17
17
|
- `GET /ash/v1/session/:sessionId/stream`
|
|
18
18
|
|
|
19
|
+
<CopyPrompt text="Protect the user's Ash HTTP routes through the channel layer. In Ash, route auth and IP policy live on channel factories, usually agent/channels/ash.ts with ashChannel auth config, not in agent.ts. Inspect the existing channel file and app auth code, replace any generated exampleProductionAuth placeholder with the smallest AuthFn or helper composition, use helpers such as localDev, vercelOidc, none, httpBasic, jwtHmac, jwtEcdsa, or oidc as appropriate, keep secrets in environment variables, preserve localDev and vercelOidc behavior where useful, verify unauthenticated production browser requests are rejected with 401, and do not commit unless the user asks.">
|
|
20
|
+
Protect the user's Ash HTTP routes through the channel layer. In Ash, route auth and IP policy
|
|
21
|
+
live on channel factories, usually agent/channels/ash.ts with ashChannel auth config, not in
|
|
22
|
+
agent.ts. Inspect the existing channel file and app auth code, replace any generated
|
|
23
|
+
exampleProductionAuth placeholder with the smallest AuthFn or helper composition, use helpers such
|
|
24
|
+
as localDev, vercelOidc, none, httpBasic, jwtHmac, jwtEcdsa, or oidc as appropriate, keep secrets
|
|
25
|
+
in environment variables, preserve localDev and vercelOidc behavior where useful, verify
|
|
26
|
+
unauthenticated production browser requests are rejected with 401, and do not commit unless the
|
|
27
|
+
user asks.
|
|
28
|
+
</CopyPrompt>
|
|
29
|
+
|
|
19
30
|
## Generated Web Chat Auth
|
|
20
31
|
|
|
21
32
|
`pnpm create experimental-ash-agent` scaffolds `agent/channels/ash.ts` from the Web Chat example.
|
|
@@ -116,7 +116,7 @@ Subagents are a context-control tool too:
|
|
|
116
116
|
- they can have their own tools and their own sandbox
|
|
117
117
|
- they run inside their own delegated subagent context instead of extending the root agent inline
|
|
118
118
|
|
|
119
|
-
See [Subagents](./subagents.
|
|
119
|
+
See [Subagents](./subagents.mdx).
|
|
120
120
|
|
|
121
121
|
## Choosing The Right Lever
|
|
122
122
|
|
|
@@ -140,8 +140,8 @@ For most agents:
|
|
|
140
140
|
|
|
141
141
|
## What To Read Next
|
|
142
142
|
|
|
143
|
-
- [Tools](./tools.
|
|
144
|
-
- [Hooks](./hooks.
|
|
143
|
+
- [Tools](./tools.mdx)
|
|
144
|
+
- [Hooks](./hooks.mdx)
|
|
145
145
|
- [Skills](./skills.md)
|
|
146
146
|
- [Workspace](./workspace.md)
|
|
147
|
-
- [Subagents](./subagents.
|
|
147
|
+
- [Subagents](./subagents.mdx)
|
|
@@ -13,6 +13,16 @@ Use evals when you want to:
|
|
|
13
13
|
- compare output against expected text, JSON, SQL, or session behavior
|
|
14
14
|
- export results to Braintrust for review and comparison
|
|
15
15
|
|
|
16
|
+
<CopyPrompt text="Add repeatable Ash evals to the user's project. Ash eval suites live under the app root evals directory, use .eval.ts files, and export defineEvalSuite from experimental-ash/evals; suite identity is derived from the file path, not an authored id or name. Inspect existing evals and agent behavior, create a focused smoke suite with model, cases or load, and scores, prefer cheap scorers such as Run.didNotFail, Run.usedTool, Text.includes, Json.deepEqual, or Sql.exactNormalized before LLM judges, add fixture loading only if it helps, run ash eval with the relevant suite flags, and do not commit unless the user asks.">
|
|
17
|
+
Add repeatable Ash evals to the user's project. Ash eval suites live under the app root evals
|
|
18
|
+
directory, use .eval.ts files, and export defineEvalSuite from experimental-ash/evals; suite
|
|
19
|
+
identity is derived from the file path, not an authored id or name. Inspect existing evals and
|
|
20
|
+
agent behavior, create a focused smoke suite with model, cases or load, and scores, prefer cheap
|
|
21
|
+
scorers such as Run.didNotFail, Run.usedTool, Text.includes, Json.deepEqual, or
|
|
22
|
+
Sql.exactNormalized before LLM judges, add fixture loading only if it helps, run ash eval with the
|
|
23
|
+
relevant suite flags, and do not commit unless the user asks.
|
|
24
|
+
</CopyPrompt>
|
|
25
|
+
|
|
16
26
|
## Where Evals Live
|
|
17
27
|
|
|
18
28
|
Ash discovers eval suites under the app root `evals/` directory.
|
|
@@ -276,5 +286,5 @@ For most apps:
|
|
|
276
286
|
## What To Read Next
|
|
277
287
|
|
|
278
288
|
- [TypeScript API](./typescript-api.md)
|
|
279
|
-
- [Tools](./tools.
|
|
289
|
+
- [Tools](./tools.mdx)
|
|
280
290
|
- [Sessions And Streaming](./runs-and-streaming.md)
|
|
@@ -7,10 +7,24 @@ url: /hooks
|
|
|
7
7
|
Hooks are Ash's authored extension points for the per-turn lifecycle and
|
|
8
8
|
the runtime event stream.
|
|
9
9
|
|
|
10
|
+
This page is about `agent/hooks/*.ts` runtime hooks. For the React client hook,
|
|
11
|
+
see [`useAshAgent`](../frontend/use-ash-agent.md).
|
|
12
|
+
|
|
10
13
|
Use a hook when you want to run code **around** a turn (before the model
|
|
11
14
|
runs, around stream events) without writing a tool, a context provider,
|
|
12
15
|
or a channel adapter handler.
|
|
13
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.">
|
|
18
|
+
Add an Ash hook to the user's project. Ash hooks live under agent/hooks, use defineHook from
|
|
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.
|
|
26
|
+
</CopyPrompt>
|
|
27
|
+
|
|
14
28
|
## The Main API
|
|
15
29
|
|
|
16
30
|
`agent/hooks/audit.ts`
|
|
@@ -103,7 +117,7 @@ Lifecycle hooks share one signature:
|
|
|
103
117
|
```ts
|
|
104
118
|
type LifecycleHook = (
|
|
105
119
|
ctx: HookContext,
|
|
106
|
-
) => void | { modelContext?: readonly ModelMessage[]
|
|
120
|
+
) => void | { modelContext?: readonly ModelMessage[] } | Promise<…>;
|
|
107
121
|
```
|
|
108
122
|
|
|
109
123
|
Session and turn metadata are available on `ctx.session`. For example,
|
|
@@ -113,14 +127,16 @@ Session and turn metadata are available on `ctx.session`. For example,
|
|
|
113
127
|
model turn. `lifecycle.turn` runs **once per fresh delivery** — tool-loop
|
|
114
128
|
continuations and HITL resumes do not re-fire it.
|
|
115
129
|
|
|
116
|
-
Both keys may return `{ modelContext
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
130
|
+
Both keys may return `{ modelContext }`. `modelContext` contributions
|
|
131
|
+
are concatenated session-then-turn before the harness's next model
|
|
132
|
+
call, and are never written to durable history. Channels may also
|
|
133
|
+
contribute the same `modelContext` shape through `SendPayload`;
|
|
134
|
+
channel-provided messages appear before lifecycle hook messages.
|
|
135
|
+
|
|
136
|
+
Browser UIs can contribute one-turn page state through `useAshAgent()`
|
|
137
|
+
`prepareSend` and `clientContext`. That client context is merged before
|
|
138
|
+
runtime lifecycle hook context, so use it for page state and use runtime hooks
|
|
139
|
+
for server-side policy and durable context.
|
|
124
140
|
|
|
125
141
|
### Seed durable context
|
|
126
142
|
|
|
@@ -174,36 +190,6 @@ export default defineHook({
|
|
|
174
190
|
`modelContext` messages are appended in registry order and visible to
|
|
175
191
|
the next model call only — never persisted.
|
|
176
192
|
|
|
177
|
-
### Contribute dynamic skills
|
|
178
|
-
|
|
179
|
-
```ts
|
|
180
|
-
// agent/hooks/tenant-skills.ts
|
|
181
|
-
import { defineHook } from "experimental-ash/hooks";
|
|
182
|
-
|
|
183
|
-
export default defineHook({
|
|
184
|
-
lifecycle: {
|
|
185
|
-
async session(ctx) {
|
|
186
|
-
return {
|
|
187
|
-
skills: [
|
|
188
|
-
{
|
|
189
|
-
name: "tenant-policy",
|
|
190
|
-
description: "Apply tenant-specific policy before answering.",
|
|
191
|
-
markdown: "Read the policy reference before making a recommendation.",
|
|
192
|
-
files: {
|
|
193
|
-
"references/policy.md": "Policy body\n",
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
],
|
|
197
|
-
};
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Dynamic skills may be returned from `lifecycle.session` or
|
|
204
|
-
`lifecycle.turn`. They can update earlier dynamic skills with the same
|
|
205
|
-
name, but cannot replace authored skills discovered under `agent/skills/`.
|
|
206
|
-
|
|
207
193
|
### Once-per-session text
|
|
208
194
|
|
|
209
195
|
```ts
|
|
@@ -301,7 +287,9 @@ when both are registered.
|
|
|
301
287
|
|
|
302
288
|
## What to read next
|
|
303
289
|
|
|
304
|
-
- [
|
|
290
|
+
- [`useAshAgent`](../frontend/use-ash-agent.md)
|
|
291
|
+
- [Next.js](../frontend/nextjs.md)
|
|
292
|
+
- [Tools](./tools.mdx)
|
|
305
293
|
- [Context Control](./context-control.md)
|
|
306
294
|
- [Sessions And Streaming](./runs-and-streaming.md)
|
|
307
295
|
- [Session Context](./session-context.md)
|
|
@@ -52,7 +52,95 @@ These fields control what the AI SDK records inside OTel spans:
|
|
|
52
52
|
- `recordOutputs` -- record model outputs on spans (defaults to `true`). Set to `false` to disable
|
|
53
53
|
output recording.
|
|
54
54
|
- `functionId` -- override the function name on spans (defaults to the agent name)
|
|
55
|
-
- `metadata` --
|
|
55
|
+
- `metadata["step.started"]` -- a synchronous callback that returns key-value pairs for one
|
|
56
|
+
model-call attempt
|
|
57
|
+
|
|
58
|
+
## Metadata
|
|
59
|
+
|
|
60
|
+
Use `metadata["step.started"]` when the metadata depends on the current session, turn, step,
|
|
61
|
+
channel, or model input:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import type { SlackInstrumentationMetadata } from "experimental-ash/channels/slack";
|
|
65
|
+
|
|
66
|
+
// A Slack-backed channel authored at `agent/channels/support.ts` has kind
|
|
67
|
+
// `channel:support` (its filename).
|
|
68
|
+
declare module "experimental-ash/instrumentation" {
|
|
69
|
+
interface ChannelMetadataMap {
|
|
70
|
+
readonly "channel:support": SlackInstrumentationMetadata;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default defineInstrumentation({
|
|
75
|
+
metadata: {
|
|
76
|
+
"step.started"(input) {
|
|
77
|
+
if (input.channel.kind !== "channel:support") {
|
|
78
|
+
return {};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
"slack.channel_id": input.channel.metadata.channelId ?? "",
|
|
83
|
+
"slack.user_id": input.channel.metadata.triggeringUserId ?? "",
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The callback runs after Ash has assembled the model input for the attempt and before constructing
|
|
91
|
+
the AI SDK call. That timing lets the returned values attach to the AI SDK model-call span and its
|
|
92
|
+
child spans. It runs for each model-call attempt, including a retry of the same logical step when
|
|
93
|
+
Ash changes provider settings or instructions.
|
|
94
|
+
|
|
95
|
+
The callback receives:
|
|
96
|
+
|
|
97
|
+
- `session` -- the session id, current/initiator auth, and parent session lineage when this is a
|
|
98
|
+
child run
|
|
99
|
+
- `turn` -- the stream turn id and sequence, e.g. `turn_0`
|
|
100
|
+
- `step` -- the zero-based step index inside the turn
|
|
101
|
+
- `channel` -- the channel's `kind` and the metadata projected by the active channel
|
|
102
|
+
- `modelInput` -- the final instructions and messages passed to the model call
|
|
103
|
+
|
|
104
|
+
A channel exposes its identity through `kind`: the discriminant you narrow on. For authored
|
|
105
|
+
channels it is `channel:<name>`, where `<name>` is the channel's filename under
|
|
106
|
+
`agent/channels/` — `agent/channels/support.ts` is `channel:support`. Framework channels use
|
|
107
|
+
`http`, `schedule`, or `subagent`. It is also emitted as the `ash.channel.kind` span attribute.
|
|
108
|
+
|
|
109
|
+
Channel metadata is channel-owned. Built-in channels expose only the fields they choose to make
|
|
110
|
+
observable; for example, Slack projects `channelId`, `teamId`, `threadTs`, and `triggeringUserId`
|
|
111
|
+
from its durable channel state. User-authored channels expose their own projection by returning
|
|
112
|
+
`metadata(state)` from `defineChannel`. To make TypeScript narrow `input.channel.metadata`,
|
|
113
|
+
declaration-merge the same `channel:<name>` kind into `ChannelMetadataMap`:
|
|
114
|
+
|
|
115
|
+
`metadata(state)` must return an object composed of JSON primitives, arrays, and plain objects.
|
|
116
|
+
Ash omits `undefined` object properties and drops projections containing values such as `Date` or
|
|
117
|
+
`Map` with a warning.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { defineChannel } from "experimental-ash/channels";
|
|
121
|
+
|
|
122
|
+
declare module "experimental-ash/instrumentation" {
|
|
123
|
+
interface ChannelMetadataMap {
|
|
124
|
+
readonly "channel:support": {
|
|
125
|
+
readonly triggeringUserId: string | null;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export default defineChannel({
|
|
131
|
+
state: { triggeringUserId: null as string | null },
|
|
132
|
+
metadata(state) {
|
|
133
|
+
return { triggeringUserId: state.triggeringUserId };
|
|
134
|
+
},
|
|
135
|
+
routes: [],
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Metadata failures are non-destructive. If the callback throws, returns a non-record, or returns
|
|
140
|
+
non-string values, Ash logs a warning, drops the invalid metadata, and continues the model call.
|
|
141
|
+
Thenables are rejected; the callback is intentionally synchronous. Keys beginning with `ash.` are
|
|
142
|
+
reserved, so authored metadata cannot override framework metadata. Instrumentation projections
|
|
143
|
+
containing values outside the JSON shape, such as `Date` or `Map`, are dropped with a warning.
|
|
56
144
|
|
|
57
145
|
## Trace Hierarchy
|
|
58
146
|
|
|
@@ -70,8 +158,9 @@ ash.turn {ash.session.id, ash.turn.id}
|
|
|
70
158
|
```
|
|
71
159
|
|
|
72
160
|
Ash creates the `ash.turn` parent span per turn and passes enriched telemetry to the AI SDK so model
|
|
73
|
-
calls and tool executions are traced automatically. Session
|
|
74
|
-
`ash.
|
|
161
|
+
calls and tool executions are traced automatically. Session, turn, step, and channel context
|
|
162
|
+
(`ash.version`, `ash.session.id`, `ash.environment`, `ash.turn.id`, `ash.turn.sequence`,
|
|
163
|
+
`ash.step.index`, `ash.channel.kind`) is injected into span metadata.
|
|
75
164
|
|
|
76
165
|
## What To Read Next
|
|
77
166
|
|
|
@@ -39,7 +39,7 @@ my-agent/
|
|
|
39
39
|
| `instrumentation.ts` | Telemetry config | OTel exporter setup and AI SDK span settings; auto-discovered and run before agent code |
|
|
40
40
|
| `channels/` | HTTP or messaging entrypoints | Root-only today |
|
|
41
41
|
| `connections/` | External service connections (MCP) | Each file defines one connection; name derived from filename |
|
|
42
|
-
| `hooks/` | Lifecycle and stream-event subscribers | Module-backed only. Recursive directories supported. See [Hooks](./hooks.
|
|
42
|
+
| `hooks/` | Lifecycle and stream-event subscribers | Module-backed only. Recursive directories supported. See [Hooks](./hooks.mdx). |
|
|
43
43
|
| `skills/` | On-demand procedures and capability packs | Flat markdown, module-backed skills, or packaged skills |
|
|
44
44
|
| `lib/` | Shared authored helper code | Import-only source, not mounted into the workspace |
|
|
45
45
|
| `sandbox/` or `sandbox.ts` | The agent's single sandbox. Use top-level `sandbox.ts` for a definition-only override; use `sandbox/sandbox.ts` + optional `sandbox/workspace/**` when you also want seeded files. Framework default applies when neither is authored. | Supported on the root agent and local subagents |
|
|
@@ -156,15 +156,15 @@ Use:
|
|
|
156
156
|
- `channels/` for HTTP or messaging ingress and delivery
|
|
157
157
|
- `lib/` for shared helper modules imported by the slots above
|
|
158
158
|
|
|
159
|
-
See [Connections](./connections.
|
|
159
|
+
See [Connections](./connections.mdx) for the connection authorization shape, including the
|
|
160
160
|
`@vercel/connect/ash` helper for OAuth-backed connections.
|
|
161
161
|
|
|
162
162
|
## What To Read Next
|
|
163
163
|
|
|
164
164
|
- [`agent.ts`](./agent-ts.md)
|
|
165
165
|
- [Context Control](./context-control.md)
|
|
166
|
-
- [Connections](./connections.
|
|
167
|
-
- [Hooks](./hooks.
|
|
166
|
+
- [Connections](./connections.mdx)
|
|
167
|
+
- [Hooks](./hooks.mdx)
|
|
168
168
|
- [Skills](./skills.md)
|
|
169
|
-
- [Tools](./tools.
|
|
169
|
+
- [Tools](./tools.mdx)
|
|
170
170
|
- [Channels](./channels/README.md)
|
|
@@ -13,6 +13,10 @@ The key client model is:
|
|
|
13
13
|
- `POST /ash/v1/session/:sessionId` sends a follow-up message
|
|
14
14
|
- `GET /ash/v1/session/:sessionId/stream` lets you watch the session in real time
|
|
15
15
|
|
|
16
|
+
React apps can use [`useAshAgent()`](../frontend/use-ash-agent.md) instead of calling these
|
|
17
|
+
routes directly. Next.js apps can use [`withAsh()`](../frontend/nextjs.md) to proxy these
|
|
18
|
+
routes to the Ash runtime from the same origin.
|
|
19
|
+
|
|
16
20
|
Ash keeps those separate on purpose:
|
|
17
21
|
|
|
18
22
|
- channels own `continuationToken` as the resume handle
|
|
@@ -109,6 +113,8 @@ Important behavior:
|
|
|
109
113
|
|
|
110
114
|
## What To Read Next
|
|
111
115
|
|
|
116
|
+
- [`useAshAgent`](../frontend/use-ash-agent.md)
|
|
117
|
+
- [Next.js](../frontend/nextjs.md)
|
|
112
118
|
- [Session Context](./session-context.md)
|
|
113
|
-
- [Subagents](./subagents.
|
|
114
|
-
- [Schedules](./schedules.
|
|
119
|
+
- [Subagents](./subagents.mdx)
|
|
120
|
+
- [Schedules](./schedules.mdx)
|
|
@@ -14,6 +14,9 @@ Source of truth:
|
|
|
14
14
|
- tools subpath: [`../../packages/ash/src/public/tools/index.ts`](../../packages/ash/src/public/tools/index.ts)
|
|
15
15
|
- sandbox subpath: [`../../packages/ash/src/public/sandbox/index.ts`](../../packages/ash/src/public/sandbox/index.ts)
|
|
16
16
|
- channel subpaths: [`../../packages/ash/src/public/channels/index.ts`](../../packages/ash/src/public/channels/index.ts)
|
|
17
|
+
- Next.js subpath: [`../../packages/ash/src/public/next/index.ts`](../../packages/ash/src/public/next/index.ts)
|
|
18
|
+
- React subpath: [`../../packages/ash/src/react/index.ts`](../../packages/ash/src/react/index.ts)
|
|
19
|
+
- client subpath: [`../../packages/ash/src/client/index.ts`](../../packages/ash/src/client/index.ts)
|
|
17
20
|
- evals subpath: [`../../packages/ash/src/evals/index.ts`](../../packages/ash/src/evals/index.ts)
|
|
18
21
|
|
|
19
22
|
## Definition Helpers
|
|
@@ -69,6 +72,26 @@ Related exported types by subpath:
|
|
|
69
72
|
Ash also exports lower-level runtime primitives such as `createToolLoopHarness(...)`
|
|
70
73
|
and `createWorkflowRuntime(...)`.
|
|
71
74
|
|
|
75
|
+
Next.js helpers exported from `experimental-ash/next`:
|
|
76
|
+
|
|
77
|
+
- `withAsh(config, options?)` - wraps a Next.js config so same-origin Ash protocol routes proxy to an Ash service
|
|
78
|
+
- `ASH_NEXT_SERVICE_PREFIX` - default private Vercel service prefix for the Ash service
|
|
79
|
+
- `WithAshOptions` - options for `ashRoot`, `ashBuildCommand`, `configureVercelJson`, and `servicePrefix`
|
|
80
|
+
|
|
81
|
+
React helpers exported from `experimental-ash/react`:
|
|
82
|
+
|
|
83
|
+
- `useAshAgent(options?)` - React hook for sending turns, streaming events, projecting UI state, and tracking a session cursor
|
|
84
|
+
- `defaultMessageReducer()` - default chat-style event projection used by `useAshAgent()`
|
|
85
|
+
- `UseAshAgentOptions`, `UseAshAgentHelpers`, `UseAshAgentSnapshot`, `UseAshAgentStatus` - hook configuration and state types
|
|
86
|
+
- `AshMessageData`, `AshMessage`, `AshMessagePart`, `AshDynamicToolPart` - default message projection types
|
|
87
|
+
|
|
88
|
+
Client helpers exported from `experimental-ash/client`:
|
|
89
|
+
|
|
90
|
+
- `Client` - HTTP client for an Ash server
|
|
91
|
+
- `ClientSession` - one durable session cursor with `send(...)`, `sendMessage(...)`, and stream helpers
|
|
92
|
+
- `defaultMessageReducer()` - reducer shared with the React package
|
|
93
|
+
- `SessionState`, `SendTurnInput`, `SendMessageOptions`, `ClientOptions` - client request and session types
|
|
94
|
+
|
|
72
95
|
Channel and Slack types exported from `experimental-ash/channels/slack`:
|
|
73
96
|
|
|
74
97
|
- `slackChannel` - Slack channel factory; zero-config by default, accepts a `SlackChannelConfig`
|
|
@@ -231,7 +254,7 @@ import {
|
|
|
231
254
|
} from "experimental-ash/tools/defaults";
|
|
232
255
|
```
|
|
233
256
|
|
|
234
|
-
See [Tools](./tools.
|
|
257
|
+
See [Tools](./tools.mdx) for the full override patterns.
|
|
235
258
|
|
|
236
259
|
### Runtime Mode
|
|
237
260
|
|
|
@@ -239,6 +262,24 @@ See [Tools](./tools.md) for the full override patterns.
|
|
|
239
262
|
import type { RunMode } from "experimental-ash";
|
|
240
263
|
```
|
|
241
264
|
|
|
265
|
+
### Next.js Integration
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
import { withAsh } from "experimental-ash/next";
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### React Client
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
import { useAshAgent } from "experimental-ash/react";
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### HTTP Client
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
import { Client } from "experimental-ash/client";
|
|
281
|
+
```
|
|
282
|
+
|
|
242
283
|
### Eval Suite
|
|
243
284
|
|
|
244
285
|
```ts
|
|
@@ -252,14 +293,16 @@ import { Braintrust } from "experimental-ash/evals/reporters";
|
|
|
252
293
|
|
|
253
294
|
- `defineAgent` -> [`agent.ts`](./agent-ts.md)
|
|
254
295
|
- `defineChannel` and channel factories -> [Channels](./channels/README.md)
|
|
255
|
-
- `defineTool`, `disableTool`, `defineBashTool`, `defineReadFileTool`, `defineWriteFileTool`, and `experimental-ash/tools/defaults` -> [Tools](./tools.
|
|
256
|
-
- `defineHook`, `HookContext`, and lifecycle/event types -> [Hooks](./hooks.
|
|
296
|
+
- `defineTool`, `disableTool`, `defineBashTool`, `defineReadFileTool`, `defineWriteFileTool`, and `experimental-ash/tools/defaults` -> [Tools](./tools.mdx)
|
|
297
|
+
- `defineHook`, `HookContext`, and lifecycle/event types -> [Hooks](./hooks.mdx)
|
|
257
298
|
- `defineSandbox` and `ctx.getSandbox()` -> [Sandboxes](./sandbox.md)
|
|
258
299
|
- `defineSkill` and `ctx.getSkill()` -> [Skills](./skills.md)
|
|
259
300
|
- `ctx.session` -> [Session Context](./session-context.md)
|
|
260
|
-
-
|
|
261
|
-
- `
|
|
262
|
-
-
|
|
301
|
+
- `withAsh` -> [Next.js](../frontend/nextjs.md)
|
|
302
|
+
- `useAshAgent` -> [`useAshAgent`](../frontend/use-ash-agent.md)
|
|
303
|
+
- subagents (authored with `defineAgent` under `subagents/<id>/agent.ts`) -> [Subagents](./subagents.mdx)
|
|
304
|
+
- `defineSchedule` -> [Schedules](./schedules.mdx)
|
|
305
|
+
- `defineEvalSuite`, loaders, reporters, and scorers -> [Evals](./evals.mdx)
|
|
263
306
|
|
|
264
307
|
## Practical Advice
|
|
265
308
|
|
|
@@ -106,4 +106,4 @@ This is useful for smoke tests against preview or production environments.
|
|
|
106
106
|
|
|
107
107
|
- [Workspace](./workspace.md)
|
|
108
108
|
- [Sandboxes](./sandbox.md)
|
|
109
|
-
- [Auth And Route Protection](./auth-and-route-protection.
|
|
109
|
+
- [Auth And Route Protection](./auth-and-route-protection.mdx)
|
|
@@ -38,7 +38,7 @@ Use `agent.ts` for:
|
|
|
38
38
|
- provider-specific model options
|
|
39
39
|
|
|
40
40
|
Per-tool approval (formerly "human-in-the-loop policy") lives on each tool via `needsApproval`,
|
|
41
|
-
not in `agent.ts`. See [Human In The Loop](./human-in-the-loop.
|
|
41
|
+
not in `agent.ts`. See [Human In The Loop](./human-in-the-loop.mdx).
|
|
42
42
|
|
|
43
43
|
For OpenTelemetry configuration, use `instrumentation.ts` instead. See
|
|
44
44
|
[`instrumentation.ts`](./instrumentation.md).
|
|
@@ -135,7 +135,7 @@ The shared per-run workspace is configured on the sandbox, not on `agent.ts`. Se
|
|
|
135
135
|
## Human In The Loop
|
|
136
136
|
|
|
137
137
|
Approval policy lives on individual tools via `needsApproval` in `defineTool({...})`, not on
|
|
138
|
-
`agent.ts`. See [Human In The Loop](./human-in-the-loop.
|
|
138
|
+
`agent.ts`. See [Human In The Loop](./human-in-the-loop.mdx) for the runtime flow, `input.requested`
|
|
139
139
|
events, and HTTP response payloads.
|
|
140
140
|
|
|
141
141
|
## Telemetry
|
|
@@ -149,7 +149,7 @@ OpenTelemetry tracing is configured in `agent/instrumentation.ts`, not in `agent
|
|
|
149
149
|
|
|
150
150
|
Those concerns live on the HTTP channel layer instead. See:
|
|
151
151
|
|
|
152
|
-
- [Auth And Route Protection](./auth-and-route-protection.
|
|
152
|
+
- [Auth And Route Protection](./auth-and-route-protection.mdx)
|
|
153
153
|
- [Channels](./channels/README.md)
|
|
154
154
|
|
|
155
155
|
## A Good Default
|
|
@@ -169,6 +169,6 @@ That is enough to start. Add build and compaction settings only when you need th
|
|
|
169
169
|
## What To Read Next
|
|
170
170
|
|
|
171
171
|
- [Context Control](./context-control.md)
|
|
172
|
-
- [Human In The Loop](./human-in-the-loop.
|
|
172
|
+
- [Human In The Loop](./human-in-the-loop.mdx)
|
|
173
173
|
- [Workspace](./workspace.md)
|
|
174
|
-
- [Auth And Route Protection](./auth-and-route-protection.
|
|
174
|
+
- [Auth And Route Protection](./auth-and-route-protection.mdx)
|
|
@@ -9,6 +9,17 @@ The Discord channel accepts HTTP Interactions: slash/application commands, messa
|
|
|
9
9
|
modal submissions. It verifies Discord's Ed25519 signature headers before parsing the request,
|
|
10
10
|
acknowledges commands immediately, and continues Ash work in the background.
|
|
11
11
|
|
|
12
|
+
<CopyPrompt text="Add Discord support to the user's Ash project. Ash Discord channels are authored in agent/channels/discord.ts with discordChannel, verify Discord Ed25519 interaction signatures, mount POST /ash/v1/discord by default, defer command responses, deliver replies and HITL components, and can use proactive bot-token messages. Inspect existing channels and env conventions, add the channel file, configure DISCORD_PUBLIC_KEY, DISCORD_APPLICATION_ID, and DISCORD_BOT_TOKEN or equivalent config, set the Discord Interactions Endpoint URL, register or update an application command with a string message option, verify command delivery and HITL behavior, and do not commit unless the user asks.">
|
|
13
|
+
Add Discord support to the user's Ash project. Ash Discord channels are authored in
|
|
14
|
+
agent/channels/discord.ts with discordChannel, verify Discord Ed25519 interaction signatures,
|
|
15
|
+
mount POST /ash/v1/discord by default, defer command responses, deliver replies and HITL
|
|
16
|
+
components, and can use proactive bot-token messages. Inspect existing channels and env
|
|
17
|
+
conventions, add the channel file, configure DISCORD_PUBLIC_KEY, DISCORD_APPLICATION_ID, and
|
|
18
|
+
DISCORD_BOT_TOKEN or equivalent config, set the Discord Interactions Endpoint URL, register or
|
|
19
|
+
update an application command with a string message option, verify command delivery and HITL
|
|
20
|
+
behavior, and do not commit unless the user asks.
|
|
21
|
+
</CopyPrompt>
|
|
22
|
+
|
|
12
23
|
## Add The Channel
|
|
13
24
|
|
|
14
25
|
Create `agent/channels/discord.ts`:
|