experimental-ash 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +3 -4
  2. package/dist/docs/internals/discovery.md +2 -2
  3. package/dist/docs/internals/mechanical-invariants.md +1 -1
  4. package/dist/docs/internals/testing.md +1 -1
  5. package/dist/docs/public/README.md +1 -1
  6. package/dist/docs/public/agent-ts.md +2 -2
  7. package/dist/docs/public/channels/README.md +1 -1
  8. package/dist/docs/public/context-control.md +20 -20
  9. package/dist/docs/public/getting-started.md +1 -1
  10. package/dist/docs/public/project-layout.md +21 -21
  11. package/dist/docs/public/schedules.md +1 -1
  12. package/dist/docs/public/skills.md +3 -3
  13. package/dist/docs/public/subagents.md +3 -3
  14. package/dist/docs/public/typescript-api.md +2 -2
  15. package/dist/src/chunks/{dev-authored-source-watcher-Bk-ZWzF_.js → dev-authored-source-watcher-HzOplr1S.js} +1 -1
  16. package/dist/src/chunks/{host-CEiB9Ps8.js → host-Ca8xvEQ1.js} +2 -2
  17. package/dist/src/chunks/paths-BiY7uVwD.js +88 -0
  18. package/dist/src/chunks/{prewarm-BK_ZT4-w.js → prewarm-DiZ_sYLy.js} +1 -1
  19. package/dist/src/cli/commands/info.js +1 -1
  20. package/dist/src/cli/run.js +1 -1
  21. package/dist/src/cli/templates/init-app/package.json +1 -1
  22. package/dist/src/compiled/.vendor-stamp.json +2 -2
  23. package/dist/src/compiled/@ai-sdk/otel/index.js +3 -3
  24. package/dist/src/compiled/@ai-sdk/otel/package.json +1 -1
  25. package/dist/src/compiled/@vercel/sandbox/index.d.ts +1 -0
  26. package/dist/src/compiler/compile-agent.js +10 -0
  27. package/dist/src/compiler/manifest.d.ts +8 -7
  28. package/dist/src/compiler/manifest.js +5 -5
  29. package/dist/src/compiler/normalize-instructions.d.ts +12 -0
  30. package/dist/src/compiler/normalize-instructions.js +28 -0
  31. package/dist/src/compiler/normalize-manifest.js +3 -3
  32. package/dist/src/discover/discover-agent.d.ts +2 -2
  33. package/dist/src/discover/discover-agent.js +5 -5
  34. package/dist/src/discover/discover-subagent.js +4 -4
  35. package/dist/src/discover/filesystem.d.ts +4 -4
  36. package/dist/src/discover/filesystem.js +30 -0
  37. package/dist/src/discover/grammar.d.ts +21 -7
  38. package/dist/src/discover/grammar.js +79 -21
  39. package/dist/src/discover/manifest.d.ts +11 -8
  40. package/dist/src/discover/manifest.js +2 -2
  41. package/dist/src/evals/cli/eval.js +1 -1
  42. package/dist/src/execution/sandbox/bindings/local.js +32 -3
  43. package/dist/src/execution/sandbox/bindings/vercel.js +3 -2
  44. package/dist/src/execution/sandbox/session.d.ts +2 -2
  45. package/dist/src/execution/sandbox/session.js +2 -2
  46. package/dist/src/internal/application/package.js +1 -1
  47. package/dist/src/internal/authored-definition/core.d.ts +7 -6
  48. package/dist/src/internal/authored-definition/core.js +6 -5
  49. package/dist/src/internal/authored-definition/sandbox.d.ts +3 -10
  50. package/dist/src/internal/nitro/routes/home-page/build-home-page-response.d.ts +5 -5
  51. package/dist/src/internal/nitro/routes/home-page/build-home-page-response.js +16 -15
  52. package/dist/src/internal/nitro/routes/home-page/load-home-page-data.d.ts +2 -2
  53. package/dist/src/internal/nitro/routes/web-ui/assets/{index-z8flAc4k.js → index-BQa8fbHJ.js} +1 -1
  54. package/dist/src/internal/nitro/routes/web-ui/index.html +1 -1
  55. package/dist/src/public/channels/slack/slackChannel.d.ts +7 -0
  56. package/dist/src/public/channels/slack/slackChannel.js +5 -0
  57. package/dist/src/public/definitions/instructions.d.ts +29 -0
  58. package/dist/src/public/definitions/instructions.js +12 -0
  59. package/dist/src/public/definitions/sandbox-backend.d.ts +1 -123
  60. package/dist/src/public/definitions/sandbox.d.ts +6 -165
  61. package/dist/src/public/helpers/markdown.d.ts +5 -5
  62. package/dist/src/public/helpers/markdown.js +7 -7
  63. package/dist/src/public/instructions/index.d.ts +8 -0
  64. package/dist/src/public/instructions/index.js +6 -0
  65. package/dist/src/public/sandbox/index.d.ts +1 -1
  66. package/dist/src/runtime/agent/bootstrap.js +3 -3
  67. package/dist/src/runtime/prompt/compose.d.ts +5 -4
  68. package/dist/src/runtime/prompt/compose.js +6 -6
  69. package/dist/src/runtime/resolve-agent.js +10 -10
  70. package/dist/src/runtime/types.d.ts +15 -15
  71. package/dist/src/shared/sandbox-backend.d.ts +124 -0
  72. package/dist/src/shared/sandbox-backend.js +1 -0
  73. package/dist/src/shared/sandbox-definition.d.ts +72 -0
  74. package/dist/src/shared/sandbox-definition.js +1 -0
  75. package/dist/src/shared/sandbox-session.d.ts +95 -0
  76. package/dist/src/shared/sandbox-session.js +1 -0
  77. package/package.json +12 -7
  78. package/dist/src/chunks/paths-Dxh19LKr.js +0 -88
  79. package/dist/src/compiler/normalize-system.d.ts +0 -11
  80. package/dist/src/compiler/normalize-system.js +0 -27
  81. package/dist/src/public/definitions/system.d.ts +0 -16
  82. package/dist/src/public/definitions/system.js +0 -7
  83. package/dist/src/public/system/index.d.ts +0 -4
  84. package/dist/src/public/system/index.js +0 -4
  85. /package/dist/src/cli/templates/init-app/agent/{system.md → instructions.md} +0 -0
@@ -0,0 +1,124 @@
1
+ import type { SandboxBootstrapContext, SandboxSessionUseFn } from "#shared/sandbox-definition.js";
2
+ import type { SandboxSession } from "#shared/sandbox-session.js";
3
+ /**
4
+ * Live sandbox handle returned by a {@link SandboxBackend}.
5
+ *
6
+ * Wraps the public {@link SandboxSession} with lifecycle methods so the
7
+ * runtime orchestrator can persist reconnect metadata and release
8
+ * resources.
9
+ */
10
+ export interface SandboxBackendHandle<S extends SandboxSession = SandboxSession> {
11
+ readonly session: SandboxSession;
12
+ readonly useSessionFn: SandboxSessionUseFn<S>;
13
+ captureState(): Promise<SandboxBackendSessionState>;
14
+ dispose(): Promise<void>;
15
+ }
16
+ /**
17
+ * Serializable per-sandbox reconnect record stored on the harness session.
18
+ *
19
+ * `backendName` matches the {@link SandboxBackend.name} of the backend
20
+ * that produced this state, and is used by the runtime to decide whether
21
+ * a previously persisted handle is still compatible with the current
22
+ * backend.
23
+ */
24
+ export interface SandboxBackendSessionState {
25
+ readonly backendName: string;
26
+ readonly metadata: Record<string, unknown>;
27
+ readonly sessionKey: string;
28
+ }
29
+ /**
30
+ * One file written into a sandbox template before snapshot capture.
31
+ */
32
+ export interface SandboxSeedFile {
33
+ readonly path: string;
34
+ readonly content: string | Buffer;
35
+ }
36
+ /**
37
+ * Diagnostic tags attached to provider-owned sandbox resources.
38
+ *
39
+ * Built-in backends may forward these into their hosting platform's
40
+ * native tagging system. Ash supplies stable tags such as the active
41
+ * agent, channel, and session id so sandboxes can be found and
42
+ * attributed in provider dashboards.
43
+ */
44
+ export type SandboxBackendTags = Readonly<Record<string, string>>;
45
+ /**
46
+ * Framework-owned runtime context handed to a backend on every
47
+ * {@link SandboxBackend.create} call.
48
+ *
49
+ * Backends use this to derive any per-call state that depends on the
50
+ * surrounding application — for example, the local backend computes its
51
+ * cache directory from `appRoot`. Backends that don't need anything
52
+ * here may ignore the field entirely.
53
+ */
54
+ export interface SandboxBackendRuntimeContext {
55
+ readonly appRoot: string;
56
+ }
57
+ /**
58
+ * Input passed to {@link SandboxBackend.create} when the runtime needs a
59
+ * live sandbox session.
60
+ */
61
+ export interface SandboxBackendCreateInput {
62
+ readonly templateKey: string;
63
+ readonly sessionKey: string;
64
+ readonly existingMetadata?: Record<string, unknown>;
65
+ /**
66
+ * Runtime tags the backend should attach to sandbox resources when
67
+ * the underlying provider supports tags.
68
+ */
69
+ readonly tags?: SandboxBackendTags;
70
+ readonly runtimeContext: SandboxBackendRuntimeContext;
71
+ }
72
+ /**
73
+ * Input passed to {@link SandboxBackend.prewarm} when the build pipeline
74
+ * is preparing reusable templates.
75
+ *
76
+ * Every authored sandbox in the compiled graph receives exactly one
77
+ * `prewarm(...)` call before runtime opens its first session. The
78
+ * backend captures a reusable template snapshot from the supplied
79
+ * `bootstrap` hook and `seedFiles`, then `backend.create(...)` opens
80
+ * durable sessions from that snapshot.
81
+ */
82
+ export interface SandboxBackendPrewarmInput {
83
+ readonly templateKey: string;
84
+ readonly bootstrap?: (input: SandboxBootstrapContext) => void | Promise<void>;
85
+ readonly runtimeContext: SandboxBackendRuntimeContext;
86
+ readonly seedFiles: ReadonlyArray<SandboxSeedFile>;
87
+ }
88
+ /**
89
+ * Pluggable sandbox backend.
90
+ *
91
+ * A `SandboxBackend` is a value an author attaches to a
92
+ * {@link SandboxDefinition} to choose which underlying runtime hosts the
93
+ * sandbox. Ash ships two built-in backends — `vercelBackend()` and
94
+ * `localBackend()` — but the interface is public so authors can write
95
+ * their own.
96
+ *
97
+ * Each backend owns the full template-then-session lifecycle internally;
98
+ * callers only need a single `create` call.
99
+ */
100
+ export interface SandboxBackend<S extends SandboxSession = SandboxSession> {
101
+ /**
102
+ * Stable identifier for this backend implementation.
103
+ *
104
+ * Participates in cache-key derivation and the persisted reconnect
105
+ * state, so two backends that should not share template snapshots
106
+ * must use distinct names. Built-in backends use `"vercel"` and
107
+ * `"local"`. Custom backends pick a unique string.
108
+ */
109
+ readonly name: string;
110
+ /**
111
+ * Creates or reattaches one live sandbox session from a template
112
+ * previously captured by {@link SandboxBackend.prewarm}. Throws
113
+ * {@link SandboxTemplateNotProvisionedError} when the requested
114
+ * template is missing.
115
+ */
116
+ create(input: SandboxBackendCreateInput): Promise<SandboxBackendHandle<S>>;
117
+ /**
118
+ * Build-time prewarm hook. Ash invokes this for every authored
119
+ * sandbox in the compiled graph before serving traffic so the backend
120
+ * can capture a reusable template snapshot. Idempotent against an
121
+ * existing snapshot keyed by `templateKey`.
122
+ */
123
+ prewarm(input: SandboxBackendPrewarmInput): Promise<void>;
124
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,72 @@
1
+ import type { SandboxSession } from "#shared/sandbox-session.js";
2
+ import type { SandboxBackend } from "#shared/sandbox-backend.js";
3
+ /**
4
+ * A transform applied to network requests matching a domain rule.
5
+ */
6
+ export interface SandboxNetworkTransformer {
7
+ readonly headers?: Record<string, string>;
8
+ }
9
+ /**
10
+ * A rule applied to requests matching a domain in the network policy.
11
+ */
12
+ export interface SandboxNetworkPolicyRule {
13
+ readonly transform?: SandboxNetworkTransformer[];
14
+ }
15
+ /**
16
+ * Network policy to define network restrictions for the sandbox.
17
+ *
18
+ * - `"allow-all"`: Full internet access (default). All traffic is allowed.
19
+ * - `"deny-all"`: No internet access. All traffic is denied.
20
+ * - Object: Custom access with explicit allow/deny lists.
21
+ */
22
+ export type SandboxNetworkPolicy = "allow-all" | "deny-all" | {
23
+ readonly allow?: string[] | Readonly<Record<string, SandboxNetworkPolicyRule[]>>;
24
+ };
25
+ export interface SandboxBootstrapUseOptions {
26
+ readonly runtime?: string;
27
+ readonly ports?: number[];
28
+ readonly env?: Record<string, string>;
29
+ }
30
+ export interface SandboxSessionUseOptions {
31
+ readonly networkPolicy?: SandboxNetworkPolicy;
32
+ readonly resources?: {
33
+ vcpus?: number;
34
+ };
35
+ readonly timeout?: number;
36
+ readonly tags?: Record<string, string>;
37
+ }
38
+ export type SandboxBootstrapUseFn = (options?: SandboxBootstrapUseOptions) => Promise<SandboxSession>;
39
+ export type SandboxSessionUseFn<S extends SandboxSession = SandboxSession> = (options?: SandboxSessionUseOptions) => Promise<S>;
40
+ export interface SandboxBootstrapContext {
41
+ readonly use: SandboxBootstrapUseFn;
42
+ }
43
+ export interface SandboxSessionContext<S extends SandboxSession = SandboxSession> {
44
+ readonly use: SandboxSessionUseFn<S>;
45
+ }
46
+ /**
47
+ * Public sandbox definition authored in `agent/sandbox.ts` (shorthand)
48
+ * or `agent/sandbox/sandbox.ts` (folder layout, when paired with an
49
+ * authored `sandbox/workspace/` subtree).
50
+ *
51
+ * Each agent (and each subagent) owns exactly one sandbox. When the
52
+ * module file is absent the framework auto-provides a default sandbox
53
+ * via `defaultBackend()`. Authors override lifecycle and backend by
54
+ * creating `agent/sandbox.ts` (or `agent/sandbox/sandbox.ts` when they
55
+ * also want a workspace folder); subagents override independently via
56
+ * `subagents/<name>/sandbox.ts` (or the folder form) and do not inherit
57
+ * their parent's sandbox (skill seeds differ per agent).
58
+ */
59
+ export interface SandboxDefinition<S extends SandboxSession = SandboxSession> {
60
+ /**
61
+ * Backend that runs this sandbox.
62
+ *
63
+ * When this field is omitted, Ash substitutes `defaultBackend()` at
64
+ * runtime, which delegates to `vercelBackend()` on hosted Vercel
65
+ * (where `process.env.VERCEL` is set) and to `localBackend()`
66
+ * everywhere else. Set `backend` explicitly to pin the sandbox to a
67
+ * specific backend regardless of environment.
68
+ */
69
+ backend: SandboxBackend<S>;
70
+ bootstrap?(input: SandboxBootstrapContext): Promise<void> | void;
71
+ onSession?(input: SandboxSessionContext<S>): Promise<void> | void;
72
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,95 @@
1
+ import type { Sandbox as AiSdkSandbox } from "ai";
2
+ /**
3
+ * Options for running a sandbox command.
4
+ */
5
+ export type SandboxCommandOptions = Readonly<Omit<Parameters<AiSdkSandbox["executeCommand"]>[0], "command">>;
6
+ /**
7
+ * Serializable result returned after running one sandbox command.
8
+ */
9
+ export type SandboxCommandResult = Readonly<Awaited<ReturnType<AiSdkSandbox["executeCommand"]>>>;
10
+ /**
11
+ * Options for reading a text file from a sandbox with optional line ranges.
12
+ */
13
+ export interface SandboxReadFileOptions {
14
+ /**
15
+ * 1-based inclusive end line. When past the file's line count, the read
16
+ * returns through EOF without error.
17
+ */
18
+ readonly endLine?: number;
19
+ /**
20
+ * 1-based inclusive start line. Defaults to 1.
21
+ */
22
+ readonly startLine?: number;
23
+ }
24
+ /**
25
+ * Minimal Ash-owned sandbox session exposed to authored lifecycle hooks.
26
+ */
27
+ export interface SandboxSession {
28
+ /**
29
+ * Stable identifier for the backend session this handle wraps.
30
+ *
31
+ * Persists across reconnects to the same logical session: two calls
32
+ * that resume the same underlying backend sandbox observe the same
33
+ * `id`. Template sessions constructed during bootstrap expose the
34
+ * template key; live sessions expose the session key assigned by the
35
+ * runtime. Useful as a cache key for per-session state that must
36
+ * outlive individual step executions.
37
+ */
38
+ readonly id: string;
39
+ /**
40
+ * Reads one text file from the sandbox as UTF-8.
41
+ *
42
+ * Returns `null` when the file does not exist. Throws when the file
43
+ * contains invalid UTF-8.
44
+ *
45
+ * Relative paths resolve from `/workspace`, the live working directory
46
+ * for every backend. Absolute paths pass through unchanged.
47
+ *
48
+ * Line ranges are 1-based and inclusive. When `endLine` is past EOF the
49
+ * read returns through EOF without error.
50
+ */
51
+ readFile(path: string, options?: SandboxReadFileOptions): Promise<string | null>;
52
+ /**
53
+ * Reads one file from the sandbox as raw bytes.
54
+ *
55
+ * Returns `null` when the file does not exist. Unlike
56
+ * {@link SandboxSession.readFile}, this variant performs no UTF-8
57
+ * decoding and is safe for binary payloads (images, PDFs, archives,
58
+ * attachment bytes written by the framework at
59
+ * `/workspace/attachments/...`).
60
+ *
61
+ * Relative paths resolve from `/workspace`, the live working
62
+ * directory for every backend. Absolute paths pass through unchanged.
63
+ */
64
+ readFileBytes(path: string): Promise<Buffer | null>;
65
+ /**
66
+ * Anchors a sandbox-relative path to `/workspace` and returns the
67
+ * resulting absolute path.
68
+ *
69
+ * Relative paths resolve from `/workspace`; absolute paths pass through.
70
+ * `readFile(...)` and `writeFile(...)` already apply this internally.
71
+ */
72
+ resolvePath(path: string): string;
73
+ /**
74
+ * Runs one shell command inside the current sandbox session and returns the
75
+ * captured stdout, stderr, and exit code.
76
+ *
77
+ * Commands execute with `/workspace` as the working directory on every
78
+ * backend.
79
+ */
80
+ runCommand(command: string, options?: SandboxCommandOptions): Promise<SandboxCommandResult>;
81
+ /**
82
+ * Writes one file to the sandbox, creating parent directories
83
+ * recursively and overwriting any existing file.
84
+ *
85
+ * `content` accepts a UTF-8 `string` for text files or a `Buffer` for
86
+ * arbitrary bytes. The framework uses the `Buffer` overload to mount
87
+ * binary workspace assets (images under skill `assets/` directories,
88
+ * fixture payloads, and so on) through the same public surface authors
89
+ * use.
90
+ *
91
+ * Relative paths resolve from `/workspace`. Absolute paths pass through
92
+ * unchanged.
93
+ */
94
+ writeFile(path: string, content: string | Buffer): Promise<void>;
95
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "experimental-ash",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "bin": {
5
5
  "ash": "./bin/ash.js",
6
6
  "experimental-ash": "./bin/ash.js"
@@ -90,10 +90,15 @@
90
90
  "import": "./dist/src/public/skills/index.js",
91
91
  "default": "./dist/src/public/skills/index.js"
92
92
  },
93
+ "./instructions": {
94
+ "types": "./dist/src/public/instructions/index.d.ts",
95
+ "import": "./dist/src/public/instructions/index.js",
96
+ "default": "./dist/src/public/instructions/index.js"
97
+ },
93
98
  "./system": {
94
- "types": "./dist/src/public/system/index.d.ts",
95
- "import": "./dist/src/public/system/index.js",
96
- "default": "./dist/src/public/system/index.js"
99
+ "types": "./dist/src/public/instructions/index.d.ts",
100
+ "import": "./dist/src/public/instructions/index.js",
101
+ "default": "./dist/src/public/instructions/index.js"
97
102
  },
98
103
  "./context": {
99
104
  "types": "./dist/src/public/context/index.d.ts",
@@ -143,7 +148,7 @@
143
148
  "@ai-sdk/google": "4.0.0-canary.53",
144
149
  "@ai-sdk/mcp": "2.0.0-canary.41",
145
150
  "@ai-sdk/openai": "4.0.0-canary.49",
146
- "@ai-sdk/otel": "1.0.0-canary.67",
151
+ "@ai-sdk/otel": "1.0.0-canary.77",
147
152
  "@ai-sdk/provider": "4.0.0-canary.16",
148
153
  "@chat-adapter/slack": "^4.27.0",
149
154
  "@chat-adapter/state-memory": "^4.27.0",
@@ -154,7 +159,7 @@
154
159
  "@workflow/core": "5.0.0-beta.5",
155
160
  "@workflow/errors": "5.0.0-beta.2",
156
161
  "@workflow/world-local": "5.0.0-beta.4",
157
- "ai": "7.0.0-canary.121",
162
+ "ai": "7.0.0-canary.131",
158
163
  "autoevals": "^0.0.132",
159
164
  "chat": "^4.27.0",
160
165
  "chokidar": "^5.0.0",
@@ -170,7 +175,7 @@
170
175
  },
171
176
  "peerDependencies": {
172
177
  "@opentelemetry/api": "^1.9.0",
173
- "ai": "7.0.0-canary.121",
178
+ "ai": "7.0.0-canary.131",
174
179
  "braintrust": ">=3.0.0"
175
180
  },
176
181
  "peerDependenciesMeta": {