experimental-ash 0.55.3 → 0.57.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/LICENSE +202 -0
- package/dist/docs/internals/compiler-and-artifacts.md +1 -1
- package/dist/docs/internals/context.md +3 -3
- package/dist/docs/public/advanced/typescript-api.md +19 -0
- package/dist/docs/public/advanced/vercel-deployment.md +2 -1
- package/dist/docs/public/channels/github.md +145 -0
- package/dist/docs/public/channels/index.md +23 -2
- package/dist/docs/public/meta.json +1 -0
- package/dist/docs/public/onboarding.md +7 -5
- package/dist/docs/public/sandbox.md +18 -3
- package/dist/docs/public/subagents.mdx +7 -2
- package/dist/docs/public/tools.mdx +10 -2
- package/dist/skills/agent/SKILL.md +169 -0
- package/dist/skills/agent/references/deployment.md +35 -0
- package/dist/skills/agent/references/getting-started.md +58 -0
- package/dist/skills/agent/references/project-layout.md +35 -0
- package/dist/skills/agent/references/runtime-model.md +24 -0
- package/dist/skills/agent/references/skills.md +26 -0
- package/dist/skills/agent/scripts/add-to-existing-project.sh +12 -0
- package/dist/skills/agent/scripts/bootstrap-from-npm.sh +9 -0
- package/dist/skills/agent/scripts/verify-local-agent.sh +16 -0
- package/dist/skills/ash-add-agent/SKILL.md +166 -0
- package/dist/skills/ash-add-next/SKILL.md +137 -0
- package/dist/skills/framework/SKILL.md +93 -0
- package/dist/skills/framework/references/architecture.md +14 -0
- package/dist/skills/framework/references/discovery-and-compilation.md +15 -0
- package/dist/skills/framework/references/quality-gates.md +13 -0
- package/dist/skills/framework/references/runtime-model.md +12 -0
- package/dist/skills/framework/references/workspace-and-sandbox.md +25 -0
- package/dist/skills/framework/scripts/framework-review-checklist.sh +13 -0
- package/dist/skills/framework/scripts/run-framework-gates.sh +8 -0
- package/dist/src/client/output-schema.js +1 -1
- package/dist/src/compiler/compile-from-memory.d.ts +2 -0
- package/dist/src/compiler/compile-from-memory.js +1 -1
- package/dist/src/compiler/manifest.d.ts +10 -2
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/compiler/normalize-sandbox.js +1 -1
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/build-dynamic-tools.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +1 -0
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/session.js +1 -1
- package/dist/src/execution/subagent-tool.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/harness/code-mode.js +1 -1
- package/dist/src/harness/execute-tool.d.ts +1 -0
- package/dist/src/harness/provider-tools.d.ts +7 -1
- package/dist/src/harness/provider-tools.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/tools.d.ts +2 -0
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/sandbox.d.ts +2 -1
- package/dist/src/internal/authored-definition/sandbox.js +1 -1
- package/dist/src/internal/authored-definition/schema-backed.js +1 -1
- package/dist/src/packages/ash-scaffold/src/channels.js +2 -2
- package/dist/src/packages/ash-scaffold/src/steps/run-add-to-agent.js +1 -1
- package/dist/src/packages/ash-scaffold/src/web-template.js +2 -2
- package/dist/src/public/channels/github/api.d.ts +166 -0
- package/dist/src/public/channels/github/api.js +1 -0
- package/dist/src/public/channels/github/auth.d.ts +83 -0
- package/dist/src/public/channels/github/auth.js +2 -0
- package/dist/src/public/channels/github/binding.d.ts +49 -0
- package/dist/src/public/channels/github/binding.js +1 -0
- package/dist/src/public/channels/github/checkout.d.ts +48 -0
- package/dist/src/public/channels/github/checkout.js +1 -0
- package/dist/src/public/channels/github/constants.d.ts +2 -0
- package/dist/src/public/channels/github/constants.js +1 -0
- package/dist/src/public/channels/github/defaults.d.ts +21 -0
- package/dist/src/public/channels/github/defaults.js +3 -0
- package/dist/src/public/channels/github/dispatch.d.ts +34 -0
- package/dist/src/public/channels/github/dispatch.js +1 -0
- package/dist/src/public/channels/github/githubChannel.d.ts +109 -0
- package/dist/src/public/channels/github/githubChannel.js +1 -0
- package/dist/src/public/channels/github/inbound.d.ts +183 -0
- package/dist/src/public/channels/github/inbound.js +2 -0
- package/dist/src/public/channels/github/index.d.ts +9 -0
- package/dist/src/public/channels/github/index.js +1 -0
- package/dist/src/public/channels/github/limits.d.ts +4 -0
- package/dist/src/public/channels/github/limits.js +2 -0
- package/dist/src/public/channels/github/pr-context.d.ts +45 -0
- package/dist/src/public/channels/github/pr-context.js +5 -0
- package/dist/src/public/channels/github/state.d.ts +48 -0
- package/dist/src/public/channels/github/state.js +1 -0
- package/dist/src/public/channels/github/verify.d.ts +35 -0
- package/dist/src/public/channels/github/verify.js +1 -0
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/definitions/sandbox.d.ts +3 -3
- package/dist/src/public/definitions/tool.d.ts +21 -1
- package/dist/src/public/sandbox/index.d.ts +1 -1
- package/dist/src/public/tools/define-bash-tool.js +1 -1
- package/dist/src/public/tools/define-glob-tool.js +1 -1
- package/dist/src/public/tools/define-grep-tool.js +1 -1
- package/dist/src/public/tools/define-read-file-tool.js +1 -1
- package/dist/src/public/tools/define-write-file-tool.js +1 -1
- package/dist/src/public/tools/internal.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
- package/dist/src/runtime/connections/authorization-tokens.d.ts +8 -0
- package/dist/src/runtime/connections/authorization-tokens.js +1 -1
- package/dist/src/runtime/connections/mcp-client.d.ts +14 -0
- package/dist/src/runtime/connections/mcp-client.js +1 -1
- package/dist/src/runtime/connections/types.d.ts +1 -0
- package/dist/src/runtime/framework-tools/ask-question.d.ts +4 -0
- package/dist/src/runtime/framework-tools/ask-question.js +1 -1
- package/dist/src/runtime/framework-tools/bash.d.ts +5 -0
- package/dist/src/runtime/framework-tools/bash.js +1 -1
- package/dist/src/runtime/framework-tools/connection-search-dynamic.d.ts +1 -0
- package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -1
- package/dist/src/runtime/framework-tools/final-output.js +1 -1
- package/dist/src/runtime/framework-tools/glob.d.ts +5 -0
- package/dist/src/runtime/framework-tools/glob.js +2 -2
- package/dist/src/runtime/framework-tools/grep.d.ts +5 -0
- package/dist/src/runtime/framework-tools/grep.js +2 -2
- package/dist/src/runtime/framework-tools/read-file.d.ts +5 -0
- package/dist/src/runtime/framework-tools/read-file.js +2 -2
- package/dist/src/runtime/framework-tools/skill.d.ts +2 -0
- package/dist/src/runtime/framework-tools/skill.js +1 -1
- package/dist/src/runtime/framework-tools/todo.d.ts +2 -0
- package/dist/src/runtime/framework-tools/todo.js +2 -2
- package/dist/src/runtime/framework-tools/web-fetch.d.ts +3 -0
- package/dist/src/runtime/framework-tools/web-fetch.js +2 -2
- package/dist/src/runtime/framework-tools/web-search.d.ts +17 -0
- package/dist/src/runtime/framework-tools/web-search.js +1 -1
- package/dist/src/runtime/framework-tools/write-file.d.ts +5 -0
- package/dist/src/runtime/framework-tools/write-file.js +2 -2
- package/dist/src/runtime/resolve-sandbox.js +1 -1
- package/dist/src/runtime/resolve-tool.js +1 -1
- package/dist/src/runtime/sandbox/keys.js +1 -1
- package/dist/src/runtime/sandbox/template-plan.d.ts +5 -0
- package/dist/src/runtime/sandbox/template-plan.js +1 -1
- package/dist/src/runtime/subagents/registry.js +1 -1
- package/dist/src/runtime/tools/registry.js +1 -1
- package/dist/src/runtime/types.d.ts +11 -2
- package/dist/src/shared/dynamic-tool-definition.d.ts +2 -1
- package/dist/src/shared/json-schema.d.ts +3 -1
- package/dist/src/shared/json-schema.js +1 -1
- package/dist/src/shared/sandbox-definition.d.ts +22 -2
- package/dist/src/shared/tool-definition.d.ts +10 -2
- package/package.json +25 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# experimental-ash
|
|
2
2
|
|
|
3
|
+
## 0.57.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b4d3ff0: Sandbox definitions with `bootstrap()` may now provide an optional build-time `revalidationKey()` function. Resolved revalidation keys and authored sandbox source hashes are stored in compiled artifacts so bootstrap templates can reuse stable snapshots across deploys when the revalidation key, sandbox source, and seed content match.
|
|
8
|
+
- ad9c3c5: Add the native GitHub channel (`experimental-ash/channels/github`). Verifies GitHub App webhooks, derives session auth from the GitHub actor, and dispatches `@mention` turns from issue comments, PR timeline comments, and inline review threads. Replies land on the native surface (timeline comment or inline review-thread reply) and acknowledge with an `eyes` reaction. Pull-request turns always inject the PR diff (with noisy files like lock files excluded from the prompt) and always check out the triggering ref into the sandbox so the built-in filesystem tools operate on the real tree. Checkout is incremental — because the sandbox persists for the session, a turn whose target commit the workspace is already on skips the fetch entirely — and brokers the installation token at the sandbox firewall (so it never enters the sandbox process) rather than embedding it in the git remote URL. Supports opt-in `onIssue`/`onPullRequest` automation hooks, an `onComment` override, a generic `ctx.github.request()` escape hatch, and proactive `receive()` sessions.
|
|
9
|
+
- ad9c3c5: Add `credentials.webhookVerifier` to the GitHub channel, matching the other native channels. When supplied, it replaces the built-in `X-Hub-Signature-256` HMAC check (the `GITHUB_WEBHOOK_SECRET` fallback is skipped), letting integrations like Vercel Connect authenticate forwarded webhooks out-of-band (e.g. with Vercel OIDC). Combined with the existing function-form `appId`/`privateKey`/`webhookSecret` credentials, the GitHub channel now has the same Connect integration surface as Slack, Teams, Telegram, and Discord.
|
|
10
|
+
- 4de5be3: Add optional `outputSchema` to subagent tool input schema for structured output. When a parent agent passes `outputSchema` to a subagent tool call, the child runs in task mode and must produce structured output matching the schema via the `final_output` tool.
|
|
11
|
+
|
|
12
|
+
## 0.56.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- e5f2d97: Ship the root Ash skill packages inside the npm package under `dist/skills`. The docs site now renders those canonical `SKILL.md` files directly as skill reference pages, avoiding duplicated skill documentation.
|
|
17
|
+
- 80ca852: Add optional `outputSchema` support to `defineTool` and propagate tool output schemas into code mode host tools. Framework tools with fixed result shapes now declare output schemas, provider-managed `web_search` injects the selected provider's output schema at runtime, and code mode logs a warning when an exposed host tool has no output schema.
|
|
18
|
+
|
|
19
|
+
Use deterministic per-turn completion hook tokens in the workflow driver so fast subagent resumes cannot collide with a prior turn's completion hook while the Workflow SDK is still persisting disposal.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- bdf208a: Connections now recover when the remote server rejects an already-issued
|
|
24
|
+
token. An MCP `401` (the bearer was revoked or expired out of band) is
|
|
25
|
+
classified as authorization-required: Ash evicts the stale cached token,
|
|
26
|
+
tears down the connection, and re-enters the sign-in flow instead of
|
|
27
|
+
narrating an opaque transport error. A loop guard fails the connection
|
|
28
|
+
terminally if a freshly authorized token is still rejected, so a broken
|
|
29
|
+
grant cannot trigger an endless re-authorization loop.
|
|
30
|
+
- f158cb2: Drop verified Slack `http_timeout` retry deliveries so delayed acknowledgements do not start duplicate sessions.
|
|
31
|
+
- 4d59025: Add Apache-2.0 license metadata, a root license file, and publish-time package license copies along with clearer package descriptions and discovery keywords.
|
|
32
|
+
|
|
3
33
|
## 0.55.3
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
package/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
|
@@ -33,7 +33,7 @@ Discovery avoids executing authored code. The module map is the handoff — it s
|
|
|
33
33
|
|
|
34
34
|
**`compiled-agent-manifest.json`** — the normalized runtime-facing manifest. Preserves config, prompt, skill, sandbox, schedule, and tool metadata; flattened subagent nodes with explicit `subagentEdges`; manifest kind and version. `sandbox` is `null` or one entry, and `sandboxWorkspaces` is an array of size 0 or 1 (single-sandbox model).
|
|
35
35
|
|
|
36
|
-
**`compile-metadata.json`** — artifact paths, SHA-256 digests, diagnostics summary, compile status, generator version, and `sourceGraphHash`.
|
|
36
|
+
**`compile-metadata.json`** — artifact paths, SHA-256 digests, diagnostics summary, compile status, generator version, and `sourceGraphHash`. Runtime and Vercel build-time prewarm derive sandbox template keys from compiled artifacts: seed-only templates use workspace content hashes, bootstrap templates use the optional resolved authored `revalidationKey()` plus authored sandbox source and workspace content, and source-graph fallback paths use `sourceGraphHash`.
|
|
37
37
|
|
|
38
38
|
**`module-map.mjs`** — frozen object keyed by `(nodeId, sourceId)`. Authored sandbox modules are indexed directly (runtime needs their lifecycle hooks); `lib/` modules come in transitively.
|
|
39
39
|
|
|
@@ -80,9 +80,9 @@ Authored hook stream-event dispatch runs inside step (4)'s ALS scope.
|
|
|
80
80
|
Event hooks receive `(event, ctx)`. See [Hooks](./hooks.md) for the
|
|
81
81
|
full pipeline.
|
|
82
82
|
|
|
83
|
-
`StepInput.
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
`StepInput.context` is provided by channels through `SendPayload.context`.
|
|
84
|
+
Each entry is appended as a `role: "user"` message to durable session
|
|
85
|
+
history before the delivery message.
|
|
86
86
|
|
|
87
87
|
## Channel Context
|
|
88
88
|
|
|
@@ -118,6 +118,24 @@ Channel and Slack types exported from `experimental-ash/channels/slack`:
|
|
|
118
118
|
- `Card`, `Button`, `Actions`, `Section`, `Modal`, `Table`, etc. - card builders re-exported for
|
|
119
119
|
rendering Slack messages
|
|
120
120
|
|
|
121
|
+
Channel and GitHub types exported from `experimental-ash/channels/github`:
|
|
122
|
+
|
|
123
|
+
- `githubChannel` - GitHub App webhook channel factory for issue/PR comments, review comments,
|
|
124
|
+
and opt-in issue/pull-request hooks
|
|
125
|
+
- `GitHubChannelConfig` - config type for credentials, route, bot mention trigger, PR diff
|
|
126
|
+
exclusions, reaction acknowledgement, and the `onComment`/`onIssue`/`onPullRequest` handlers
|
|
127
|
+
- `GitHubInboundContext` - pre-dispatch context for inbound hooks (`thread`, `github`,
|
|
128
|
+
`repository`, `sender`, `delivery`)
|
|
129
|
+
- `GitHubEventContext` - event-handler context (`thread`, `github`, mutable `state`,
|
|
130
|
+
repository/conversation metadata, and channel session operations)
|
|
131
|
+
- `GitHubHandle` - GitHub helper handle: `request()` plus `installationId` and `repository`
|
|
132
|
+
- `GitHubThread` - conversation-scoped operations: `post` and `react`
|
|
133
|
+
- `GitHubComment`, `GitHubIssueEvent`, and `GitHubPullRequestEvent` - parsed inbound payload types
|
|
134
|
+
- `GitHubIssueAction` / `GitHubPullRequestAction` - typed webhook action unions
|
|
135
|
+
- `GitHubPullRequestContextConfig` - PR diff exclusion config (`excludedFiles`)
|
|
136
|
+
- `GitHubReceiveTarget` - target accepted by proactive `receive(github, ...)`
|
|
137
|
+
- `defaultGitHubAuth` - default GitHub actor-to-session-auth projection
|
|
138
|
+
|
|
121
139
|
Channel and Twilio types exported from `experimental-ash/channels/twilio`:
|
|
122
140
|
|
|
123
141
|
- `twilioChannel` - Twilio channel factory for SMS and speech-transcribed voice webhooks
|
|
@@ -203,6 +221,7 @@ import { defineAgent } from "experimental-ash";
|
|
|
203
221
|
import { defineChannel, POST, GET } from "experimental-ash/channels";
|
|
204
222
|
import { ashChannel } from "experimental-ash/channels/ash";
|
|
205
223
|
import { vercelOidc } from "experimental-ash/channels/auth";
|
|
224
|
+
import { githubChannel } from "experimental-ash/channels/github";
|
|
206
225
|
import { slackChannel } from "experimental-ash/channels/slack";
|
|
207
226
|
import { telegramChannel } from "experimental-ash/channels/telegram";
|
|
208
227
|
```
|
|
@@ -63,7 +63,8 @@ Important behavior:
|
|
|
63
63
|
- Ash skips prewarm for sandboxes with no `bootstrap()` and no workspace seed files
|
|
64
64
|
- seed-only templates are keyed by skills and workspace file contents, so unchanged seeds can reuse
|
|
65
65
|
a template across deploys
|
|
66
|
-
- sandboxes with `bootstrap()`
|
|
66
|
+
- sandboxes with `bootstrap()` are keyed by the optional resolved `revalidationKey()` value plus
|
|
67
|
+
authored sandbox source and seed contents, so matching inputs can reuse a template across deploys
|
|
67
68
|
- the build log labels each template `reused cached` or `built`, so a reuse across deploys is visible
|
|
68
69
|
- `onSession()` still runs later at runtime
|
|
69
70
|
- if build-time prewarm fails, the build fails
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "GitHub channel setup"
|
|
3
|
+
description: "Create a GitHub App-backed Ash channel with automatic PR context and sandbox checkout."
|
|
4
|
+
type: integration
|
|
5
|
+
related:
|
|
6
|
+
- /channels
|
|
7
|
+
- /sandbox
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Ash GitHub channels receive GitHub App webhooks at `/ash/v1/github`, verify the webhook signature,
|
|
11
|
+
derive auth from the GitHub actor, and deliver responses back to the native GitHub surface.
|
|
12
|
+
|
|
13
|
+
## Add The Channel File
|
|
14
|
+
|
|
15
|
+
Create `agent/channels/github.ts`:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { githubChannel } from "experimental-ash/channels/github";
|
|
19
|
+
|
|
20
|
+
export default githubChannel({
|
|
21
|
+
botName: "my-agent",
|
|
22
|
+
credentials: {
|
|
23
|
+
appId: process.env.GITHUB_APP_ID,
|
|
24
|
+
privateKey: process.env.GITHUB_APP_PRIVATE_KEY,
|
|
25
|
+
webhookSecret: process.env.GITHUB_WEBHOOK_SECRET,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Configure the GitHub App webhook URL to `https://<deployment>/ash/v1/github`. Subscribe to
|
|
31
|
+
`issue_comment` and `pull_request_review_comment` for mention-driven turns. Subscribe to `issues`
|
|
32
|
+
and `pull_request` when you configure their opt-in hooks.
|
|
33
|
+
|
|
34
|
+
The agent starts a turn whenever a comment or inline review comment `@mention`s `botName`.
|
|
35
|
+
|
|
36
|
+
Each field has an environment-variable fallback, so the `credentials` block above is optional when
|
|
37
|
+
those variables are set: `appId` reads `GITHUB_APP_ID`, `privateKey` reads `GITHUB_APP_PRIVATE_KEY`,
|
|
38
|
+
`webhookSecret` reads `GITHUB_WEBHOOK_SECRET`, and `botName` reads `GITHUB_APP_SLUG`. `appId`,
|
|
39
|
+
`privateKey`, and `webhookSecret` also accept a function that resolves the value lazily (e.g. from a
|
|
40
|
+
secret manager).
|
|
41
|
+
|
|
42
|
+
## Acknowledgement & Replies
|
|
43
|
+
|
|
44
|
+
The channel manages the GitHub-native side of a turn for you:
|
|
45
|
+
|
|
46
|
+
- When a turn starts it adds an `eyes` reaction to the triggering comment so the user knows the agent
|
|
47
|
+
picked it up. Disable the reaction with `progress: { reactions: false }`.
|
|
48
|
+
- The agent's reply is posted back to the conversation as a comment (issue/PR timeline comments reply
|
|
49
|
+
on the issue or PR; inline review comments reply in the review thread). Long replies are split
|
|
50
|
+
across multiple comments to stay within GitHub's size limit.
|
|
51
|
+
- If a turn or session fails, the channel posts a short error comment with an error id instead of
|
|
52
|
+
going silent.
|
|
53
|
+
|
|
54
|
+
## Pull Request Context
|
|
55
|
+
|
|
56
|
+
When the agent is summoned on a pull request, it always sees the PR. The channel injects PR metadata
|
|
57
|
+
and the changed-file diff as `context` strings appended to the turn before the comment. There is no
|
|
58
|
+
flag to disable it — seeing the diff is the point.
|
|
59
|
+
|
|
60
|
+
Large, generated files (lock files, minified bundles, source maps, snapshots) are excluded from the
|
|
61
|
+
diff loaded into the prompt: they are still listed with their stats, but their patch body is omitted.
|
|
62
|
+
Add your own globs with `excludedFiles` (they extend the built-in list):
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
export default githubChannel({
|
|
66
|
+
botName: "my-agent",
|
|
67
|
+
pullRequestContext: {
|
|
68
|
+
excludedFiles: ["**/*.generated.ts", "docs/**/*.svg"],
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Excluded files are still on disk via the checkout, so the agent can `read_file` one if it needs the
|
|
74
|
+
contents. Custom inbound hooks can also return their own `context`; Ash prepends the
|
|
75
|
+
channel-generated PR diff first, then your hook context.
|
|
76
|
+
|
|
77
|
+
## Sandbox Checkout
|
|
78
|
+
|
|
79
|
+
Every triggered turn checks out the relevant ref into the sandbox before the first model call, so the
|
|
80
|
+
built-in `read_file`, `glob`, `grep`, and `bash` tools operate on the real tree:
|
|
81
|
+
|
|
82
|
+
- issue comments and `onIssue` turns check out the repository default branch.
|
|
83
|
+
- PR comments, inline review comments, and `onPullRequest` turns check out the PR head, and also
|
|
84
|
+
fetch the base ref so `git diff <base>...HEAD` works.
|
|
85
|
+
|
|
86
|
+
Checkout brokers a fresh installation token at the sandbox firewall: `git` fetches a clean,
|
|
87
|
+
token-free URL and the platform injects an `Authorization` header on egress to `github.com`, so the
|
|
88
|
+
token never enters the sandbox process. This requires a firewall-capable backend (the Vercel
|
|
89
|
+
backend); the local backend cannot broker, so checkout is skipped there (the failure is logged and
|
|
90
|
+
the turn proceeds with the PR diff still in context).
|
|
91
|
+
|
|
92
|
+
The sandbox persists for the life of the session, so checkout is incremental: when a later turn in
|
|
93
|
+
the same session targets a commit the workspace is already on, the turn skips the fetch entirely
|
|
94
|
+
(no installation token is minted and nothing is downloaded).
|
|
95
|
+
|
|
96
|
+
## Inbound Hooks
|
|
97
|
+
|
|
98
|
+
Three optional hooks let you customize dispatch. Each returns `{ auth }` to dispatch or `null` to
|
|
99
|
+
ignore.
|
|
100
|
+
|
|
101
|
+
Derive session auth from the GitHub actor with `defaultGitHubAuth(ctx)`.
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { defaultGitHubAuth, githubChannel } from "experimental-ash/channels/github";
|
|
105
|
+
|
|
106
|
+
export default githubChannel({
|
|
107
|
+
botName: "my-agent",
|
|
108
|
+
|
|
109
|
+
// Replaces the default `@mention` gate for issue/PR/review comments.
|
|
110
|
+
// ctx.conversation.kind is "issue" | "pull_request" | "review_thread".
|
|
111
|
+
async onComment(ctx, comment) {
|
|
112
|
+
const context: string[] | undefined = comment.body.includes("/grammar")
|
|
113
|
+
? ["Review only prose, comments, and documentation."]
|
|
114
|
+
: undefined;
|
|
115
|
+
return { auth: defaultGitHubAuth(ctx), context };
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// Opt in to act on issues. There is no default dispatch on this event.
|
|
119
|
+
onIssue(ctx, issue) {
|
|
120
|
+
if (issue.action !== "opened") return null;
|
|
121
|
+
return { auth: defaultGitHubAuth(ctx) };
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
// Opt in to act on pull requests. There is no default dispatch on this event.
|
|
125
|
+
onPullRequest(ctx, pullRequest) {
|
|
126
|
+
if (pullRequest.action !== "opened") return null;
|
|
127
|
+
return { auth: defaultGitHubAuth(ctx) };
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`issue.action` and `pullRequest.action` are typed unions of the common GitHub webhook actions
|
|
133
|
+
(`opened`, `closed`, `edited`, `synchronize`, …) and stay open to any action GitHub sends.
|
|
134
|
+
|
|
135
|
+
## Arbitrary GitHub API Calls
|
|
136
|
+
|
|
137
|
+
For anything the channel does not wrap, use `ctx.github.request()` with installation-token auth:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
await ctx.github.request({
|
|
141
|
+
method: "POST",
|
|
142
|
+
path: `/repos/${ctx.repository.fullName}/issues/${issueNumber}/labels`,
|
|
143
|
+
body: { labels: ["triaged"] },
|
|
144
|
+
});
|
|
145
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Channels"
|
|
3
|
-
description: "Deliver your agent over HTTP, Slack, Discord, Twilio, Telegram, Microsoft Teams, and custom transports."
|
|
3
|
+
description: "Deliver your agent over HTTP, Slack, GitHub, Discord, Twilio, Telegram, Microsoft Teams, and custom transports."
|
|
4
4
|
url: /channels
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -23,7 +23,7 @@ Ash ships the public HTTP protocol as channels:
|
|
|
23
23
|
- `ashChannel({ auth })` for the built-in Ash protocol channel
|
|
24
24
|
|
|
25
25
|
Ash also supports authored channels under `agent/channels/` for platform-specific integrations such
|
|
26
|
-
as Slack, Discord, Twilio, Telegram, Microsoft Teams, or custom webhooks.
|
|
26
|
+
as Slack, GitHub, Discord, Twilio, Telegram, Microsoft Teams, or custom webhooks.
|
|
27
27
|
|
|
28
28
|
## Filesystem Shape
|
|
29
29
|
|
|
@@ -283,6 +283,26 @@ dispatch for app mentions, direct messages, and interactions.
|
|
|
283
283
|
For a Slack app backed by Vercel Connect, see [Slack channel setup](./slack.mdx) to create the Connect client
|
|
284
284
|
and channel file.
|
|
285
285
|
|
|
286
|
+
## GitHub Channels
|
|
287
|
+
|
|
288
|
+
GitHub channels are authored with `githubChannel()`:
|
|
289
|
+
|
|
290
|
+
```ts
|
|
291
|
+
import { githubChannel } from "experimental-ash/channels/github";
|
|
292
|
+
|
|
293
|
+
export default githubChannel({
|
|
294
|
+
botName: "my-agent",
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
The channel verifies GitHub App webhooks at `/ash/v1/github`, dispatches bot-directed issue/PR
|
|
299
|
+
comments and pull-request review comments, can opt into issue and pull-request hooks, exposes
|
|
300
|
+
GitHub-native issue, PR, reaction, and checkout helpers, and injects bounded PR metadata,
|
|
301
|
+
file lists, and patch text as turn `context`.
|
|
302
|
+
|
|
303
|
+
See [GitHub channel setup](./github.md) for GitHub App permissions, PR context, checkout, and
|
|
304
|
+
custom inbound hooks.
|
|
305
|
+
|
|
286
306
|
## Discord Channels
|
|
287
307
|
|
|
288
308
|
Discord channels are authored with `discordChannel()`:
|
|
@@ -632,6 +652,7 @@ See [Channel file uploads](./attachments.md) for the full guide.
|
|
|
632
652
|
## What To Read Next
|
|
633
653
|
|
|
634
654
|
- [Slack channel setup](./slack.mdx)
|
|
655
|
+
- [GitHub channel setup](./github.md)
|
|
635
656
|
- [Telegram channel setup](./telegram.mdx)
|
|
636
657
|
- [Channel file uploads](./attachments.md)
|
|
637
658
|
- [Project Layout](../project-layout.md)
|
|
@@ -28,8 +28,8 @@ Collect these up front. A capable agent should use a structured question UI (suc
|
|
|
28
28
|
4. **Model provider** — how the agent reaches a model:
|
|
29
29
|
- Vercel project (default) — create a project, or pass `--project <slug>` to link an existing one, and use AI Gateway via OIDC.
|
|
30
30
|
- API key override — pass `--gateway-api-key <key>` to write `AI_GATEWAY_API_KEY` to `.env.local`.
|
|
31
|
-
-
|
|
32
|
-
5. **Deploy** — whether to deploy to Vercel production now. Required for Slack to receive events; pass `--
|
|
31
|
+
- Skip Vercel — pass `--skip-vercel` for web/REPL-only setups that should scaffold without a Vercel project or Vercel Services config; the agent will not reach a model until you add a provider. Slack still requires a Vercel project.
|
|
32
|
+
5. **Deploy** — whether to deploy to Vercel production now. Required for Slack to receive events; pass `--skip-deploy` to skip only the final deployment.
|
|
33
33
|
|
|
34
34
|
## Step 1 — Scaffold (non-interactive)
|
|
35
35
|
|
|
@@ -42,13 +42,15 @@ npx create-experimental-ash-agent@latest <name> \
|
|
|
42
42
|
[--team <slug>] \
|
|
43
43
|
[--project <slug>] \
|
|
44
44
|
[--gateway-api-key <key>] \
|
|
45
|
-
[--
|
|
46
|
-
[--
|
|
45
|
+
[--skip-vercel] \
|
|
46
|
+
[--skip-deploy] \
|
|
47
47
|
--target-dir <parent-dir> \
|
|
48
48
|
--yes --json
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
By default the CLI creates a Vercel project named `<name>`, links it non-interactively, and pulls the project's AI Gateway environment. Use `--project <slug>` when the user picked an existing project, `--team <slug>` when they picked a non-current Vercel team, `--gateway-api-key <key>` when they want a pasted key in `.env.local`, and `--
|
|
51
|
+
By default the CLI creates a Vercel project named `<name>`, links it non-interactively, and pulls the project's AI Gateway environment. Use `--project <slug>` when the user picked an existing project, `--team <slug>` when they picked a non-current Vercel team, `--gateway-api-key <key>` when they want a pasted key in `.env.local`, and `--skip-vercel` only for web/REPL-only setups where they explicitly do not want Vercel provisioning or Vercel Services config.
|
|
52
|
+
|
|
53
|
+
To scaffold into an existing directory instead of creating `<parent-dir>/<name>`, omit `<name>` and pass `--in-place --target-dir <dir>`. Add `-y` / `--yes` only when replacing existing Ash scaffold files is intended; the CLI logs every overwritten file.
|
|
52
54
|
|
|
53
55
|
The CLI advances as far as it can without human input. When it reaches a login or browser step, it emits an `action-required` record and exits cleanly instead of blocking on a prompt:
|
|
54
56
|
|
|
@@ -29,6 +29,7 @@ author a sandbox definition module:
|
|
|
29
29
|
import { defineSandbox } from "experimental-ash/sandbox";
|
|
30
30
|
|
|
31
31
|
export default defineSandbox({
|
|
32
|
+
revalidationKey: () => "jq-bootstrap-v1",
|
|
32
33
|
async bootstrap({ use }) {
|
|
33
34
|
const sandbox = await use();
|
|
34
35
|
await sandbox.run({ command: "apt-get install -y jq" });
|
|
@@ -52,6 +53,9 @@ The public lifecycle surface is intentionally small:
|
|
|
52
53
|
|
|
53
54
|
- `bootstrap({ use })` — template-scoped setup (runs once when the template is built). Call `use()`
|
|
54
55
|
to get a `SandboxSession` for filesystem setup. Only filesystem state survives snapshotting.
|
|
56
|
+
- `revalidationKey()` — optional build-time function for external inputs that affect
|
|
57
|
+
`bootstrap()` output. Authored sandbox source and framework-managed seed contents are included
|
|
58
|
+
automatically.
|
|
55
59
|
- `onSession({ use })` — durable-session-scoped setup (runs once per session). Call `use(opts?)` to
|
|
56
60
|
get a `SandboxSession`; `opts` are forwarded to the backend's update path (the Vercel SDK's
|
|
57
61
|
`sandbox.update(...)`) before the session is returned. `onSession`'s `use()` never creates a
|
|
@@ -190,6 +194,13 @@ Inside a subagent's authored code, `ctx.getSandbox()` binds to the subagent's ow
|
|
|
190
194
|
Call `use()` to get a `SandboxSession`. Only filesystem state survives — configuration changes
|
|
191
195
|
like network policy or resource allocation do not persist into the snapshot.
|
|
192
196
|
|
|
197
|
+
When external inputs can change `bootstrap()` output, define
|
|
198
|
+
`revalidationKey: () => string | Promise<string>`. Ash evaluates `revalidationKey()` during
|
|
199
|
+
compile/build, stores the resolved string in compiled artifacts, and uses that frozen value for both
|
|
200
|
+
build-time prewarm and runtime session creation. Authored sandbox source and framework-managed seed
|
|
201
|
+
contents are included automatically, so use `revalidationKey()` only for inputs outside that source,
|
|
202
|
+
such as a git commit, lockfile hash, base snapshot version, or daily rotation string.
|
|
203
|
+
|
|
193
204
|
Framework-managed seed files (compiled skills, authored `workspace/` entries) are written into the
|
|
194
205
|
template before the authored `bootstrap` runs, so your bootstrap can read them.
|
|
195
206
|
|
|
@@ -246,6 +257,7 @@ import { defineSandbox, vercelBackend } from "experimental-ash/sandbox";
|
|
|
246
257
|
|
|
247
258
|
export default defineSandbox({
|
|
248
259
|
backend: vercelBackend({ runtime: "node24", resources: { vcpus: 2 } }),
|
|
260
|
+
revalidationKey: () => "repo-bootstrap-v1",
|
|
249
261
|
async bootstrap({ use }) {
|
|
250
262
|
const sandbox = await use();
|
|
251
263
|
await sandbox.run({ command: "git clone https://example.com/repo.git repo" });
|
|
@@ -322,8 +334,8 @@ also work and follow the same rules. When `source.type === "snapshot"`, the Verc
|
|
|
322
334
|
`runtime`, and TypeScript enforces that at the factory call site.
|
|
323
335
|
|
|
324
336
|
Ash does not detect changes to an external snapshot. If you rebuild your snapshot and want Ash to
|
|
325
|
-
pick it up, force a template rebuild
|
|
326
|
-
template
|
|
337
|
+
pick it up, force a template rebuild by changing the `revalidationKey()` value used by your
|
|
338
|
+
bootstrap template.
|
|
327
339
|
|
|
328
340
|
### Deferring Backend Construction
|
|
329
341
|
|
|
@@ -473,7 +485,10 @@ On hosted Vercel builds, Ash can prewarm the authored sandbox template during `a
|
|
|
473
485
|
|
|
474
486
|
Ash skips template prewarm for sandboxes that have no `bootstrap()` and no workspace seed files.
|
|
475
487
|
Seed-only sandboxes use a content-addressed template key, so matching skills and workspace files can
|
|
476
|
-
reuse an existing template across deploys. Sandboxes with `bootstrap()`
|
|
488
|
+
reuse an existing template across deploys. Sandboxes with `bootstrap()` use the optional resolved
|
|
489
|
+
`revalidationKey` plus authored sandbox source and workspace seed content, so matching inputs can
|
|
490
|
+
reuse an existing template across deploys. Changing `revalidationKey()` or sandbox source only takes
|
|
491
|
+
effect after rebuilding compiled artifacts.
|
|
477
492
|
|
|
478
493
|
Important behavior:
|
|
479
494
|
|
|
@@ -74,7 +74,7 @@ export default defineRemoteAgent({
|
|
|
74
74
|
});
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
Remote agents use the same lowered `{ message
|
|
77
|
+
Remote agents use the same lowered `{ message, outputSchema? }` tool shape as local subagents. The
|
|
78
78
|
difference is dispatch: the parent starts a task-mode session on the remote agent's
|
|
79
79
|
`POST /ash/v1/session`, passes a framework callback URL, parks the parent turn, and resumes when
|
|
80
80
|
the remote agent posts a terminal callback back to the parent. The parent sees the same
|
|
@@ -98,11 +98,12 @@ owns redelivery instead of marking the remote task complete.
|
|
|
98
98
|
|
|
99
99
|
Ash lowers every subagent into a model-visible tool on the parent agent.
|
|
100
100
|
|
|
101
|
-
The lowered tool
|
|
101
|
+
The lowered tool exposes:
|
|
102
102
|
|
|
103
103
|
```ts
|
|
104
104
|
{
|
|
105
105
|
message: string;
|
|
106
|
+
outputSchema?: object;
|
|
106
107
|
}
|
|
107
108
|
```
|
|
108
109
|
|
|
@@ -110,6 +111,10 @@ The parent fills `message` with everything the subagent needs to run the task
|
|
|
110
111
|
not see the parent's history. This mirrors the public message API used to invoke the parent agent
|
|
111
112
|
itself, so prompt-engineering a delegation feels the same as prompt-engineering an initial run.
|
|
112
113
|
|
|
114
|
+
When `outputSchema` is provided, the subagent runs in task mode and must produce structured output
|
|
115
|
+
matching the given JSON Schema via the `final_output` tool. The structured output becomes the tool
|
|
116
|
+
result returned to the parent.
|
|
117
|
+
|
|
113
118
|
## What The Subagent Gets
|
|
114
119
|
|
|
115
120
|
Subagent execution gets:
|