experimental-ash 0.40.1 → 0.42.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 +20 -0
- package/dist/docs/internals/hooks.md +53 -11
- package/dist/docs/public/advanced/hooks.md +9 -6
- package/dist/docs/public/tools.md +176 -0
- package/dist/src/compiler/manifest.d.ts +16 -2
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/module-map.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/normalize-tool.d.ts +7 -3
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +29 -0
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -0
- package/dist/src/context/hook-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +36 -0
- package/dist/src/context/keys.js +1 -1
- package/dist/src/context/providers/sandbox.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/node-step.d.ts +2 -2
- package/dist/src/execution/node-step.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 +1 -1
- package/dist/src/harness/code-mode.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/types.d.ts +17 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/authored-definition/schema-backed.d.ts +9 -3
- package/dist/src/internal/authored-definition/schema-backed.js +1 -1
- package/dist/src/internal/authored-module.d.ts +4 -0
- package/dist/src/internal/authored-module.js +1 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +39 -0
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +4 -0
- package/dist/src/packages/ash-scaffold/src/channels.js +1 -1
- package/dist/src/public/definitions/agent.d.ts +1 -1
- package/dist/src/public/definitions/defineChannel.js +1 -1
- package/dist/src/public/definitions/tool.d.ts +67 -0
- package/dist/src/public/definitions/tool.js +1 -1
- package/dist/src/public/index.d.ts +1 -1
- package/dist/src/public/tools/index.d.ts +2 -1
- package/dist/src/public/tools/index.js +1 -1
- package/dist/src/runtime/framework-tools/connection-search.js +1 -1
- package/dist/src/runtime/framework-tools/connection-tools.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-tool.d.ts +12 -0
- package/dist/src/runtime/resolve-dynamic-tool.js +1 -0
- package/dist/src/runtime/types.d.ts +12 -0
- package/dist/src/shared/agent-definition.d.ts +25 -0
- package/dist/src/shared/code-mode.d.ts +14 -1
- package/dist/src/shared/code-mode.js +1 -1
- package/dist/src/shared/dynamic-tool-definition.d.ts +134 -0
- package/dist/src/shared/dynamic-tool-definition.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# experimental-ash
|
|
2
2
|
|
|
3
|
+
## 0.42.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- edce3c9: Unified event dispatch: single `handleEvent` pipeline for all event-based handlers (channels, hooks, dynamic tools). Dynamic tool entries now require the `tool()` wrapper — the bundler transform only matches `execute` inside `tool()` calls.
|
|
8
|
+
|
|
9
|
+
## 0.41.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- d4dd396: Move code mode from the `CODE_MODE` environment variable to a per-agent
|
|
14
|
+
`experimental.codeMode` flag on `defineAgent({ experimental: { codeMode: true } })`.
|
|
15
|
+
Each agent and subagent can now opt in independently. For backwards
|
|
16
|
+
compatibility, agents that omit the flag fall back to the
|
|
17
|
+
`ASH_EXPERIMENTAL_CODE_MODE` environment variable (`"1"` enables it); the
|
|
18
|
+
previous `CODE_MODE` variable is no longer read.
|
|
19
|
+
- 09beab5: Add `defineTools` and `defineTool` dynamic overloads for runtime tool resolution.
|
|
20
|
+
|
|
21
|
+
Tools can now be resolved dynamically at runtime based on session context via `defineTools({ events: { "session.started": handler } })` and `defineTool({ events: { "session.started": handler } })`. Session-scoped resolvers run once and are cached; step-scoped resolvers re-resolve before every model call. Dynamic tools appear in the model's tool list identically to static tools.
|
|
22
|
+
|
|
3
23
|
## 0.40.1
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -124,13 +124,35 @@ itself throws while the dispatcher is emitting the recoverable
|
|
|
124
124
|
`session.failed` instead. This is the bounded second-order behavior
|
|
125
125
|
when both a `lifecycle.turn` and a `turn.failed` event hook fail.
|
|
126
126
|
|
|
127
|
-
Stream
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
### Stream event dispatch (`handleEvent`)
|
|
128
|
+
|
|
129
|
+
Every stream event passes through one `handleEvent` function
|
|
130
|
+
(`execution/workflow-steps.ts`) that coordinates three stages:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
handleEvent(event):
|
|
134
|
+
1. emit(event) — channel adapter handler + durable stream write
|
|
135
|
+
2. dispatchStreamEventHooks — typed bucket, then wildcard bucket
|
|
136
|
+
3. dispatchDynamicToolEvent — resolvers subscribed to event.type
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`emit` handles the channel adapter's event handler (can mutate
|
|
140
|
+
adapter state, can transform the event) and writes the (possibly
|
|
141
|
+
transformed) event to the durable stream. The durable record is
|
|
142
|
+
consistent with what was written even if a downstream handler throws.
|
|
143
|
+
|
|
144
|
+
`dispatchStreamEventHooks` reads the typed bucket
|
|
130
145
|
(`registry.streamEventsByType.get(eventType)`) followed by the flat
|
|
131
|
-
wildcard bucket (`registry.streamEventsWildcard`)
|
|
132
|
-
propagate through the
|
|
133
|
-
|
|
146
|
+
wildcard bucket (`registry.streamEventsWildcard`). Thrown errors
|
|
147
|
+
propagate through the handler; the existing harness error path catches
|
|
148
|
+
them and emits the recoverable `turn.failed` cascade.
|
|
149
|
+
|
|
150
|
+
`dispatchDynamicToolEvent` (`context/dynamic-tool-lifecycle.ts`) runs
|
|
151
|
+
dynamic tool resolvers subscribed to the event type and merges
|
|
152
|
+
resolved tools into `DynamicToolsKey`. The tool-loop reads this key
|
|
153
|
+
right before each model call. See the [event dispatch
|
|
154
|
+
doc](../../research/active/unified-event-dispatch.md) for the full
|
|
155
|
+
design.
|
|
134
156
|
|
|
135
157
|
## `SessionPreparedKey`
|
|
136
158
|
|
|
@@ -162,11 +184,31 @@ The `discover/discover-subagent.ts` path walks each local subagent's
|
|
|
162
184
|
| `lifecycle.turn` | Caught by dispatcher → recoverable `turn.failed` cascade emitted |
|
|
163
185
|
| Stream-event hooks | Propagated through the emit composer → existing harness error path emits `turn.failed` |
|
|
164
186
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
187
|
+
### Full per-turn execution order
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
dispatchHookLifecycle():
|
|
191
|
+
lifecycle.session hooks (once per session, produce modelContext)
|
|
192
|
+
lifecycle.turn hooks (once per turn, produce modelContext)
|
|
193
|
+
|
|
194
|
+
emitTurnPreamble() via handleEvent:
|
|
195
|
+
handleEvent(session.started) → emit, hooks, dynamic tool resolvers
|
|
196
|
+
handleEvent(turn.started) → emit, hooks, dynamic tool resolvers
|
|
197
|
+
handleEvent(message.received) → emit, hooks
|
|
198
|
+
|
|
199
|
+
emitStepStarted() via handleEvent:
|
|
200
|
+
handleEvent(step.started) → emit, hooks, dynamic tool resolvers
|
|
201
|
+
|
|
202
|
+
runOneModelCall():
|
|
203
|
+
read DynamicToolsKey (current tools from all prior events)
|
|
204
|
+
build effective toolset (static + dynamic + connections)
|
|
205
|
+
model.stream()
|
|
206
|
+
|
|
207
|
+
emitStepActions() via handleEvent:
|
|
208
|
+
handleEvent(actions.requested) → emit, hooks, dynamic tool resolvers
|
|
209
|
+
handleEvent(action.result) × N → emit, hooks, dynamic tool resolvers
|
|
210
|
+
handleEvent(step.completed) → emit, hooks
|
|
211
|
+
```
|
|
170
212
|
|
|
171
213
|
## Testing Strategy
|
|
172
214
|
|
|
@@ -229,7 +229,7 @@ export default defineHook({
|
|
|
229
229
|
The session contribution lands in `modelContext` for the **first** model
|
|
230
230
|
call only. Subsequent turns proceed without it.
|
|
231
231
|
|
|
232
|
-
## Stream
|
|
232
|
+
## Stream Events
|
|
233
233
|
|
|
234
234
|
Side-effect-only handlers for accepted runtime events. Subscribe by
|
|
235
235
|
event type, or use `*` for every event:
|
|
@@ -255,12 +255,15 @@ export default defineHook({
|
|
|
255
255
|
});
|
|
256
256
|
```
|
|
257
257
|
|
|
258
|
-
|
|
258
|
+
### Execution order
|
|
259
259
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
260
|
+
When a stream event fires, three things happen in order:
|
|
261
|
+
|
|
262
|
+
1. **Emit** — the channel adapter handler runs, then the event is written to the durable stream.
|
|
263
|
+
2. **Hooks** — stream event hooks fire (typed handlers first, then `*` wildcard). Return values are ignored.
|
|
264
|
+
3. **Dynamic tool resolvers** — resolvers subscribed to the event type run and update the tool set.
|
|
265
|
+
|
|
266
|
+
Hooks always run **after** the event is durably recorded — if a hook throws, the stream is consistent.
|
|
264
267
|
|
|
265
268
|
## Errors
|
|
266
269
|
|
|
@@ -368,6 +368,182 @@ full API.
|
|
|
368
368
|
Note: `retentionPolicy` and `onCompact` operate on the projected output (what the model sees),
|
|
369
369
|
not the full `execute` return.
|
|
370
370
|
|
|
371
|
+
## Dynamic Tools
|
|
372
|
+
|
|
373
|
+
Dynamic tools resolve at runtime based on session context — tenant configuration, feature flags, user roles, or external data. Use `defineTools` with an `events` object to produce tools dynamically.
|
|
374
|
+
|
|
375
|
+
### Single Dynamic Tool
|
|
376
|
+
|
|
377
|
+
`agent/tools/analytics.ts`
|
|
378
|
+
|
|
379
|
+
```ts
|
|
380
|
+
import { defineTool, tool } from "experimental-ash/tools";
|
|
381
|
+
import { z } from "zod";
|
|
382
|
+
|
|
383
|
+
export default defineTool({
|
|
384
|
+
events: {
|
|
385
|
+
"session.started": async (event, ctx) => {
|
|
386
|
+
const flags = await fetchFeatureFlags(ctx.session.id);
|
|
387
|
+
if (!flags.advancedAnalytics) return null;
|
|
388
|
+
|
|
389
|
+
return tool({
|
|
390
|
+
description: "Run an advanced analytics query.",
|
|
391
|
+
inputSchema: z.object({ query: z.string() }),
|
|
392
|
+
async execute(input) {
|
|
393
|
+
return runAnalytics(input.query);
|
|
394
|
+
},
|
|
395
|
+
});
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Return `null` to produce no tool. The tool name is the file slug (`analytics`), identical to a static `defineTool`. Entries must be wrapped with `tool()` — this stamps the entry for the bundler transform so `execute` functions survive workflow step boundaries.
|
|
402
|
+
|
|
403
|
+
### Multiple Dynamic Tools
|
|
404
|
+
|
|
405
|
+
`agent/tools/tenant.ts`
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
import { defineTools, tool } from "experimental-ash/tools";
|
|
409
|
+
import { z } from "zod";
|
|
410
|
+
|
|
411
|
+
export default defineTools({
|
|
412
|
+
events: {
|
|
413
|
+
"session.started": async (event, ctx) => {
|
|
414
|
+
const tenant = await fetchTenant(ctx.session.id);
|
|
415
|
+
if (!tenant) return null;
|
|
416
|
+
|
|
417
|
+
return {
|
|
418
|
+
export: tool({
|
|
419
|
+
description: `Export ${tenant.name} data`,
|
|
420
|
+
inputSchema: z.object({ format: z.enum(["csv", "json"]) }),
|
|
421
|
+
async execute(input) {
|
|
422
|
+
// input.format is typed as "csv" | "json"
|
|
423
|
+
return callTenantApi(tenant.apiUrl, "export", input.format);
|
|
424
|
+
},
|
|
425
|
+
}),
|
|
426
|
+
query: tool({
|
|
427
|
+
description: `Query ${tenant.name} data`,
|
|
428
|
+
inputSchema: z.object({ sql: z.string() }),
|
|
429
|
+
async execute(input) {
|
|
430
|
+
// input.sql is typed as string
|
|
431
|
+
return callTenantApi(tenant.apiUrl, "query", input.sql);
|
|
432
|
+
},
|
|
433
|
+
}),
|
|
434
|
+
};
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
});
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Each entry must be wrapped with `tool()` — it captures the schema type so `execute(input)` is inferred from `inputSchema`, matching the AI SDK's `tool()` pattern.
|
|
441
|
+
|
|
442
|
+
### Tool Naming
|
|
443
|
+
|
|
444
|
+
Dynamic tool names are derived from the file path and the definition function:
|
|
445
|
+
|
|
446
|
+
| Definition | File | Entry keys | Tool name(s) |
|
|
447
|
+
| ------------- | -------------------------- | ----------------- | --------------------------------- |
|
|
448
|
+
| `defineTool` | `agent/tools/analytics.ts` | _(single entry)_ | `analytics` |
|
|
449
|
+
| `defineTools` | `agent/tools/tenant.ts` | `export`, `query` | `tenant__export`, `tenant__query` |
|
|
450
|
+
| `defineTools` | `agent/tools/search.ts` | `run` | `search__run` |
|
|
451
|
+
|
|
452
|
+
`defineTool` always produces one tool named after the file slug — identical to static tools. `defineTools` always uses `slug__key`, even when the resolver returns a single entry. This keeps names stable: adding a second entry to a `defineTools` file does not rename the first.
|
|
453
|
+
|
|
454
|
+
### Events
|
|
455
|
+
|
|
456
|
+
The `events` object supports three event types:
|
|
457
|
+
|
|
458
|
+
| Event | When the resolver runs | Tools available for |
|
|
459
|
+
| ----------------- | ---------------------- | ------------------------------- |
|
|
460
|
+
| `session.started` | Once per session | Every model call in the session |
|
|
461
|
+
| `turn.started` | Once per turn | Every model call in the turn |
|
|
462
|
+
| `step.started` | Before each model call | That model call |
|
|
463
|
+
|
|
464
|
+
The bundler transform ensures resolvers survive workflow step boundaries — subsequent steps reconstruct execute functions from stored closure variables without re-running the resolver. Resolvers run concurrently — if multiple dynamic tool files declare the same event, their I/O overlaps.
|
|
465
|
+
|
|
466
|
+
### Execution Order
|
|
467
|
+
|
|
468
|
+
When a stream event fires, three things happen in order:
|
|
469
|
+
|
|
470
|
+
1. **Emit** — the channel adapter handler runs (can transform the event), then the event is written to the durable stream.
|
|
471
|
+
2. **Hooks** — stream event hooks fire (typed handlers first, then `*` wildcard).
|
|
472
|
+
3. **Dynamic tool resolvers** — resolvers subscribed to the event type run and update the tool set.
|
|
473
|
+
|
|
474
|
+
The tool-loop reads the current tool set right before each model call. If an event updated tools since the last read, the model sees the updated set.
|
|
475
|
+
|
|
476
|
+
### Multiple Events
|
|
477
|
+
|
|
478
|
+
A single file can declare handlers for multiple events. The result of the most recently fired handler owns the tool set for that file:
|
|
479
|
+
|
|
480
|
+
```ts
|
|
481
|
+
import { defineTools, tool } from "experimental-ash/tools";
|
|
482
|
+
|
|
483
|
+
export default defineTools({
|
|
484
|
+
events: {
|
|
485
|
+
"session.started": async (event, ctx) => {
|
|
486
|
+
return { query: tool({ description: "Query", inputSchema: {}, execute: async () => {} }) };
|
|
487
|
+
},
|
|
488
|
+
"turn.started": async (event, ctx) => {
|
|
489
|
+
// On each turn, re-resolve tools. Replaces this file's
|
|
490
|
+
// session.started tools for subsequent calls.
|
|
491
|
+
return { search: tool({ description: "Search", inputSchema: {}, execute: async () => {} }) };
|
|
492
|
+
},
|
|
493
|
+
},
|
|
494
|
+
});
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Type Inference
|
|
498
|
+
|
|
499
|
+
`inputSchema` accepts Zod, Standard Schema, or plain JSON Schema — same as static `defineTool`. When using Zod, the `tool()` wrapper infers the `execute` input type automatically:
|
|
500
|
+
|
|
501
|
+
```ts
|
|
502
|
+
return {
|
|
503
|
+
query: tool({
|
|
504
|
+
inputSchema: z.object({ city: z.string() }),
|
|
505
|
+
async execute(input) {
|
|
506
|
+
// input.city is typed as string
|
|
507
|
+
return fetchWeather(input.city);
|
|
508
|
+
},
|
|
509
|
+
}),
|
|
510
|
+
};
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
The `execute` signature matches static tools: `execute(input: TInput, ctx: ToolContext)`.
|
|
514
|
+
|
|
515
|
+
### Helper Functions
|
|
516
|
+
|
|
517
|
+
`execute` can live inside helper functions, `.map()` callbacks, or IIFEs — the bundler transform follows nested scopes and captures all referenced variables:
|
|
518
|
+
|
|
519
|
+
```ts
|
|
520
|
+
import { defineTools, tool } from "experimental-ash/tools";
|
|
521
|
+
import { z } from "zod";
|
|
522
|
+
|
|
523
|
+
export default defineTools({
|
|
524
|
+
events: {
|
|
525
|
+
"session.started": async (event, ctx) => {
|
|
526
|
+
const tenant = await fetchTenant(ctx.session.id);
|
|
527
|
+
|
|
528
|
+
function buildTool(action: string) {
|
|
529
|
+
const endpoint = `${tenant.apiUrl}/${action}`;
|
|
530
|
+
return tool({
|
|
531
|
+
description: `${action} for ${tenant.name}`,
|
|
532
|
+
inputSchema: z.object({ query: z.string() }),
|
|
533
|
+
async execute(input) {
|
|
534
|
+
return callApi(endpoint, input.query);
|
|
535
|
+
},
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
return { query: buildTool("query"), export: buildTool("export") };
|
|
540
|
+
},
|
|
541
|
+
},
|
|
542
|
+
});
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
**Limitation:** `execute` must be an inline function — a function expression, arrow function, or method shorthand written directly as the property value. Assigning a variable (`execute: myFn`) or a call result (`execute: makeFn()`) is not detected by the transform; the tool will work on the first workflow step but will not survive replay across step boundaries.
|
|
546
|
+
|
|
371
547
|
## What To Read Next
|
|
372
548
|
|
|
373
549
|
- [Session Context](./session-context.md)
|
|
@@ -18,7 +18,7 @@ export declare const ROOT_COMPILED_AGENT_NODE_ID = "__root__";
|
|
|
18
18
|
/**
|
|
19
19
|
* Current compiled manifest schema version.
|
|
20
20
|
*/
|
|
21
|
-
export declare const COMPILED_AGENT_MANIFEST_VERSION =
|
|
21
|
+
export declare const COMPILED_AGENT_MANIFEST_VERSION = 25;
|
|
22
22
|
/**
|
|
23
23
|
* Compiled channel entry preserved in the compiled manifest.
|
|
24
24
|
*/
|
|
@@ -100,6 +100,16 @@ export type CompiledConnectionDefinition = z.infer<typeof compiledConnectionDefi
|
|
|
100
100
|
* Normalized authored tool metadata preserved in the compiled manifest.
|
|
101
101
|
*/
|
|
102
102
|
export type CompiledToolDefinition = InternalToolDefinition & ModuleSourceRef;
|
|
103
|
+
/**
|
|
104
|
+
* Compiled dynamic tool resolver entry. The resolver function lives in the
|
|
105
|
+
* compiled module map; the manifest entry carries only the metadata needed
|
|
106
|
+
* to load and invoke it at runtime.
|
|
107
|
+
*/
|
|
108
|
+
export interface CompiledDynamicToolDefinition extends ModuleSourceRef {
|
|
109
|
+
readonly slug: string;
|
|
110
|
+
readonly identity: "single" | "multi";
|
|
111
|
+
readonly eventNames: readonly string[];
|
|
112
|
+
}
|
|
103
113
|
/**
|
|
104
114
|
* Normalized authored hook entry preserved in the compiled manifest.
|
|
105
115
|
*
|
|
@@ -213,6 +223,7 @@ declare const compiledAgentNodeManifestSchema: z.ZodObject<{
|
|
|
213
223
|
warnings: z.ZodNumber;
|
|
214
224
|
}, z.core.$strict>;
|
|
215
225
|
disabledFrameworkTools: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
226
|
+
dynamicTools: z.ZodDefault<z.ZodArray<z.ZodType<CompiledDynamicToolDefinition, unknown, z.core.$ZodTypeInternals<CompiledDynamicToolDefinition, unknown>>>>;
|
|
216
227
|
hooks: z.ZodArray<z.ZodType<CompiledHookDefinition, unknown, z.core.$ZodTypeInternals<CompiledHookDefinition, unknown>>>;
|
|
217
228
|
sandbox: z.ZodNullable<z.ZodObject<{
|
|
218
229
|
description: z.ZodOptional<z.ZodString>;
|
|
@@ -298,6 +309,7 @@ export declare const compiledAgentManifestSchema: z.ZodObject<{
|
|
|
298
309
|
warnings: z.ZodNumber;
|
|
299
310
|
}, z.core.$strict>;
|
|
300
311
|
disabledFrameworkTools: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
312
|
+
dynamicTools: z.ZodDefault<z.ZodArray<z.ZodType<CompiledDynamicToolDefinition, unknown, z.core.$ZodTypeInternals<CompiledDynamicToolDefinition, unknown>>>>;
|
|
301
313
|
hooks: z.ZodArray<z.ZodType<CompiledHookDefinition, unknown, z.core.$ZodTypeInternals<CompiledHookDefinition, unknown>>>;
|
|
302
314
|
kind: z.ZodLiteral<"ash-agent-compiled-manifest">;
|
|
303
315
|
remoteAgents: z.ZodArray<z.ZodType<Readonly<ModuleSourceRef & Node & {
|
|
@@ -368,7 +380,7 @@ export declare const compiledAgentManifestSchema: z.ZodObject<{
|
|
|
368
380
|
sourceId: z.ZodString;
|
|
369
381
|
sourceKind: z.ZodLiteral<"module">;
|
|
370
382
|
}, z.core.$strict>>;
|
|
371
|
-
version: z.ZodLiteral<
|
|
383
|
+
version: z.ZodLiteral<25>;
|
|
372
384
|
workspaceResourceRoot: z.ZodObject<{
|
|
373
385
|
logicalPath: z.ZodString;
|
|
374
386
|
rootEntries: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
@@ -385,6 +397,7 @@ export declare function createCompiledAgentNodeManifest(input: {
|
|
|
385
397
|
readonly connections?: readonly CompiledConnectionDefinition[];
|
|
386
398
|
readonly diagnosticsSummary?: DiscoverDiagnosticsSummary;
|
|
387
399
|
readonly disabledFrameworkTools?: readonly string[];
|
|
400
|
+
readonly dynamicTools?: readonly CompiledDynamicToolDefinition[];
|
|
388
401
|
readonly hooks?: readonly CompiledHookDefinition[];
|
|
389
402
|
readonly remoteAgents?: readonly CompiledRemoteAgentNode[];
|
|
390
403
|
readonly sandbox?: CompiledSandboxDefinition | null;
|
|
@@ -423,6 +436,7 @@ export declare function createCompiledAgentManifest(input: {
|
|
|
423
436
|
readonly connections?: readonly CompiledConnectionDefinition[];
|
|
424
437
|
readonly diagnosticsSummary?: DiscoverDiagnosticsSummary;
|
|
425
438
|
readonly disabledFrameworkTools?: readonly string[];
|
|
439
|
+
readonly dynamicTools?: readonly CompiledDynamicToolDefinition[];
|
|
426
440
|
readonly hooks?: readonly CompiledHookDefinition[];
|
|
427
441
|
readonly remoteAgents?: readonly CompiledRemoteAgentNode[];
|
|
428
442
|
readonly sandbox?: CompiledSandboxDefinition | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";import{discoverDiagnosticsSummarySchema}from"#discover/diagnostics.js";import{compiledRemoteAgentNodeSchema}from"#compiler/remote-agent-node.js";import{jsonObjectSchema}from"#shared/json-schemas.js";const COMPILED_AGENT_MANIFEST_KIND=`ash-agent-compiled-manifest`,ROOT_COMPILED_AGENT_NODE_ID=`__root__`,COMPILED_AGENT_MANIFEST_VERSION=
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{discoverDiagnosticsSummarySchema}from"#discover/diagnostics.js";import{compiledRemoteAgentNodeSchema}from"#compiler/remote-agent-node.js";import{jsonObjectSchema}from"#shared/json-schemas.js";const COMPILED_AGENT_MANIFEST_KIND=`ash-agent-compiled-manifest`,ROOT_COMPILED_AGENT_NODE_ID=`__root__`,COMPILED_AGENT_MANIFEST_VERSION=25,moduleSourceRefSchema=z.object({exportName:z.string().optional(),sourceKind:z.literal(`module`),logicalPath:z.string(),sourceId:z.string()}).strict(),channelMethodSchema=z.union([z.literal(`GET`),z.literal(`POST`),z.literal(`PUT`),z.literal(`PATCH`),z.literal(`DELETE`)]),compiledChannelDefinitionSchema=z.object({kind:z.literal(`channel`),name:z.string(),logicalPath:z.string(),method:channelMethodSchema,urlPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),exportName:z.string().optional(),adapterKind:z.string().optional()}).strict(),disabledCompiledChannelEntrySchema=z.object({kind:z.literal(`disabled`),name:z.string(),logicalPath:z.string()}).strict(),compiledChannelEntrySchema=z.union([compiledChannelDefinitionSchema,disabledCompiledChannelEntrySchema]),compiledRuntimeModelReferenceSchema=z.object({contextWindowTokens:z.number().int().positive().optional(),id:z.string(),source:moduleSourceRefSchema.optional(),providerOptions:z.record(z.string(),jsonObjectSchema).optional()}).strict(),compiledAgentBuildDefinitionSchema=z.object({externalDependencies:z.array(z.string()).optional()}).strict(),compiledAgentCompactionDefinitionSchema=z.object({model:compiledRuntimeModelReferenceSchema.optional(),thresholdPercent:z.number().finite().min(0).max(1).optional()}).strict(),compiledAgentConfigSchema=z.object({build:compiledAgentBuildDefinitionSchema.optional(),compaction:compiledAgentCompactionDefinitionSchema.optional(),description:z.string().optional(),experimental:z.object({codeMode:z.boolean().optional()}).strict().optional(),model:compiledRuntimeModelReferenceSchema,name:z.string(),source:moduleSourceRefSchema.optional()}).strict(),compiledInstructionsSchema=z.object({name:z.string(),logicalPath:z.string(),markdown:z.string(),sourceId:z.string(),sourceKind:z.union([z.literal(`markdown`),z.literal(`module`)])}).strict(),compiledSkillBaseFields={name:z.string(),description:z.string(),license:z.string().optional(),markdown:z.string(),metadata:z.record(z.string(),z.string()).optional(),sourceId:z.string(),logicalPath:z.string()},compiledSkillSourceSchema=z.discriminatedUnion(`sourceKind`,[z.object({...compiledSkillBaseFields,sourceKind:z.literal(`markdown`)}).strict(),z.object({...compiledSkillBaseFields,sourceKind:z.literal(`module`),exportName:z.string().optional()}).strict(),z.object({...compiledSkillBaseFields,sourceKind:z.literal(`skill-package`),skillId:z.string(),skillFilePath:z.string(),rootPath:z.string(),assetsPath:z.string().optional(),referencesPath:z.string().optional(),scriptsPath:z.string().optional()}).strict()]),compiledScheduleDefinitionSchema=z.object({cron:z.string(),hasRun:z.boolean(),name:z.string(),logicalPath:z.string(),markdown:z.string().optional(),sourceId:z.string(),sourceKind:z.union([z.literal(`markdown`),z.literal(`module`)])}).strict(),compiledSandboxDefinitionSchema=z.object({description:z.string().optional(),exportName:z.string().optional(),logicalPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledSandboxWorkspaceSchema=z.object({logicalPath:z.string(),rootEntries:z.array(z.string()).readonly(),sourceId:z.string(),sourcePath:z.string()}).strict(),compiledWorkspaceResourceRootSchema=z.object({logicalPath:z.string(),rootEntries:z.array(z.string()).readonly()}).strict(),compiledConnectionDefinitionSchema=z.object({connectionName:z.string(),description:z.string(),exportName:z.string().optional(),logicalPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),url:z.string(),vercelConnect:z.object({connector:z.string()}).strict().optional()}).strict(),compiledToolDefinitionSchema=z.object({description:z.string(),exportName:z.string().optional(),inputSchema:jsonObjectSchema.nullable(),logicalPath:z.string(),name:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledDynamicToolDefinitionSchema=z.object({eventNames:z.array(z.string()).readonly(),exportName:z.string().optional(),identity:z.enum([`single`,`multi`]),logicalPath:z.string(),slug:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledHookDefinitionSchema=z.object({exportName:z.string().optional(),logicalPath:z.string(),slug:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`)}).strict(),compiledAgentNodeManifestSchema=z.object({agentRoot:z.string(),appRoot:z.string(),channels:z.array(compiledChannelEntrySchema),config:compiledAgentConfigSchema,connections:z.array(compiledConnectionDefinitionSchema),diagnosticsSummary:discoverDiagnosticsSummarySchema,disabledFrameworkTools:z.array(z.string()).readonly(),dynamicTools:z.array(compiledDynamicToolDefinitionSchema).default([]),hooks:z.array(compiledHookDefinitionSchema),sandbox:compiledSandboxDefinitionSchema.nullable(),sandboxWorkspaces:z.array(compiledSandboxWorkspaceSchema),schedules:z.array(compiledScheduleDefinitionSchema),remoteAgents:z.array(compiledRemoteAgentNodeSchema),skills:z.array(compiledSkillSourceSchema).readonly(),instructions:compiledInstructionsSchema.optional(),tools:z.array(compiledToolDefinitionSchema),workspaceResourceRoot:compiledWorkspaceResourceRootSchema}).strict(),compiledSubagentNodeSchema=z.object({agent:compiledAgentNodeManifestSchema,description:z.string(),entryPath:z.string(),logicalPath:z.string(),name:z.string(),nodeId:z.string(),rootPath:z.string(),sourceId:z.string(),sourceKind:z.literal(`module`),exportName:z.string().optional()}).strict(),compiledSubagentEdgeSchema=z.object({childNodeId:z.string(),parentNodeId:z.string()}).strict(),compiledAgentManifestSchema=z.object({agentRoot:z.string(),appRoot:z.string(),channels:z.array(compiledChannelEntrySchema),config:compiledAgentConfigSchema,connections:z.array(compiledConnectionDefinitionSchema),diagnosticsSummary:discoverDiagnosticsSummarySchema,disabledFrameworkTools:z.array(z.string()).readonly(),dynamicTools:z.array(compiledDynamicToolDefinitionSchema).default([]),hooks:z.array(compiledHookDefinitionSchema),kind:z.literal(COMPILED_AGENT_MANIFEST_KIND),remoteAgents:z.array(compiledRemoteAgentNodeSchema),sandbox:compiledSandboxDefinitionSchema.nullable(),sandboxWorkspaces:z.array(compiledSandboxWorkspaceSchema),schedules:z.array(compiledScheduleDefinitionSchema),skills:z.array(compiledSkillSourceSchema).readonly(),subagentEdges:z.array(compiledSubagentEdgeSchema),subagents:z.array(compiledSubagentNodeSchema),instructions:compiledInstructionsSchema.optional(),tools:z.array(compiledToolDefinitionSchema),version:z.literal(25),workspaceResourceRoot:compiledWorkspaceResourceRootSchema}).strict();function createCompiledAgentNodeManifest(e){let t={agentRoot:e.agentRoot,appRoot:e.appRoot,channels:[...e.channels??[]],connections:[...e.connections??[]],config:{build:e.config.build===void 0?void 0:{externalDependencies:e.config.build.externalDependencies===void 0?void 0:[...e.config.build.externalDependencies]},compaction:{model:e.config.compaction?.model===void 0?void 0:cloneCompiledRuntimeModelReference(e.config.compaction.model),thresholdPercent:e.config.compaction?.thresholdPercent},description:e.config.description,experimental:e.config.experimental===void 0?void 0:{codeMode:e.config.experimental.codeMode},model:cloneCompiledRuntimeModelReference(e.config.model),name:e.config.name,source:e.config.source===void 0?void 0:{...e.config.source}},diagnosticsSummary:e.diagnosticsSummary??{errors:0,warnings:0},disabledFrameworkTools:[...e.disabledFrameworkTools??[]],dynamicTools:[...e.dynamicTools??[]],hooks:[...e.hooks??[]],remoteAgents:[...e.remoteAgents??[]],sandbox:e.sandbox??null,sandboxWorkspaces:[...e.sandboxWorkspaces??[]],schedules:[...e.schedules??[]],skills:[...e.skills??[]],tools:[...e.tools??[]],workspaceResourceRoot:e.workspaceResourceRoot??{logicalPath:``,rootEntries:deriveResourceRootEntries({sandboxWorkspaces:e.sandboxWorkspaces,skills:e.skills})}};return e.instructions!==void 0&&(t.instructions=e.instructions),t}function deriveResourceRootEntries(e){let t=new Set;(e.skills??[]).length>0&&t.add(`skills/`);for(let n of e.sandboxWorkspaces??[])for(let e of n.rootEntries)t.add(e);return[...t].sort((e,t)=>e.localeCompare(t))}function createCompiledSubagentNodeId(e,t){return e===`__root__`?t:`${e}::${t}`}function createCompiledAgentManifest(e){return{...createCompiledAgentNodeManifest(e),kind:COMPILED_AGENT_MANIFEST_KIND,subagentEdges:[...e.subagentEdges??[]],subagents:[...e.subagents??[]],version:25}}function cloneCompiledRuntimeModelReference(e){return e.contextWindowTokens===void 0&&e.source===void 0&&e.providerOptions===void 0?{id:e.id}:e.source===void 0?e.providerOptions===void 0?{contextWindowTokens:e.contextWindowTokens,id:e.id}:{contextWindowTokens:e.contextWindowTokens,id:e.id,providerOptions:{...e.providerOptions}}:e.contextWindowTokens===void 0&&e.providerOptions===void 0?{id:e.id,source:{...e.source}}:{contextWindowTokens:e.contextWindowTokens,id:e.id,providerOptions:e.providerOptions===void 0?void 0:{...e.providerOptions},source:{...e.source}}}export{COMPILED_AGENT_MANIFEST_KIND,COMPILED_AGENT_MANIFEST_VERSION,ROOT_COMPILED_AGENT_NODE_ID,compiledAgentManifestSchema,createCompiledAgentManifest,createCompiledAgentNodeManifest,createCompiledSubagentNodeId,deriveResourceRootEntries};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{z}from"#compiled/zod/index.js";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{normalizeEsmImportSpecifier}from"#internal/application/import-specifier.js";const compiledModuleNodeScopeSchema=z.object({modules:z.record(z.string(),z.object({}).passthrough())}).strict(),compiledModuleMapSchema=z.object({nodes:z.record(z.string(),compiledModuleNodeScopeSchema)}).strict();function createCompiledModuleMapSource(e){let n=dirnameFilesystemPath(e.moduleMapPath),r=e.importSpecifierStyle??`relative`,i=0,a=[collectModuleNodeScope({agentRoot:e.manifest.agentRoot,importSpecifierStyle:r,manifest:e.manifest,moduleMapDirectory:n,nextBindingName(){return`module_${i++}`},nodeId:ROOT_COMPILED_AGENT_NODE_ID}),...[...e.manifest.subagents].sort((e,t)=>e.nodeId.localeCompare(t.nodeId)).map(e=>collectModuleNodeScope({agentRoot:e.agent.agentRoot,importSpecifierStyle:r,manifest:e.agent,moduleMapDirectory:n,nextBindingName(){return`module_${i++}`},nodeId:e.nodeId}))],o=a.flatMap(e=>e.modules.map(e=>`import * as ${e.bindingName} from ${JSON.stringify(e.importSpecifier)};`));return[`// Generated by Ash. Do not edit by hand.`,``,...o,...o.length>0?[``]:[],`export const moduleMap = ${renderModuleMap(a)};`,``,`export default moduleMap;`,``].join(`
|
|
2
|
-
`)}function collectModuleNodeScope(e){return{modules:collectModuleRefsForManifest(e.manifest).sort((e,t)=>e.sourceId.localeCompare(t.sourceId)).map(t=>({bindingName:e.nextBindingName(),importSpecifier:createImportSpecifier({fromDirectory:e.moduleMapDirectory,importSpecifierStyle:e.importSpecifierStyle,targetPath:joinFilesystemPath(e.agentRoot,t.logicalPath)}),sourceId:t.sourceId})),nodeId:e.nodeId}}function collectModuleRefsForManifest(e){let t=new Map;e.config.source!==void 0&&t.set(e.config.source.sourceId,e.config.source),e.config.model.source!==void 0&&t.set(e.config.model.source.sourceId,e.config.model.source);for(let n of e.channels)n.kind!==`disabled`&&t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.connections)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.tools)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.remoteAgents)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.hooks)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.schedules)n.sourceKind!==`module`||!n.hasRun||t.set(n.sourceId,{sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});return e.sandbox!==null&&t.set(e.sandbox.sourceId,{exportName:e.sandbox.exportName,sourceKind:`module`,logicalPath:e.sandbox.logicalPath,sourceId:e.sandbox.sourceId}),[...t.values()]}function createImportSpecifier(e){if(e.importSpecifierStyle===`absolute`)return normalizeEsmImportSpecifier(normalizeFilesystemPath(e.targetPath));let t=relativeFilesystemPath(e.fromDirectory,e.targetPath);return t.startsWith(`.`)?t:`./${t}`}function renderModuleMap(e){return renderFrozenObject([{key:`nodes`,value:renderFrozenObject(e.map(e=>({key:e.nodeId,value:renderFrozenObject([{key:`modules`,value:renderFrozenObject(e.modules.map(e=>({key:e.sourceId,value:e.bindingName})))}],3)})))}],0)}function renderFrozenObject(e,t=1){if(e.length===0)return`Object.freeze({})`;let n=` `.repeat(t),r=` `.repeat(t+1);return[`Object.freeze({`,e.map(e=>`${r}${JSON.stringify(e.key)}: ${e.value.replaceAll(`
|
|
2
|
+
`)}function collectModuleNodeScope(e){return{modules:collectModuleRefsForManifest(e.manifest).sort((e,t)=>e.sourceId.localeCompare(t.sourceId)).map(t=>({bindingName:e.nextBindingName(),importSpecifier:createImportSpecifier({fromDirectory:e.moduleMapDirectory,importSpecifierStyle:e.importSpecifierStyle,targetPath:joinFilesystemPath(e.agentRoot,t.logicalPath)}),sourceId:t.sourceId})),nodeId:e.nodeId}}function collectModuleRefsForManifest(e){let t=new Map;e.config.source!==void 0&&t.set(e.config.source.sourceId,e.config.source),e.config.model.source!==void 0&&t.set(e.config.model.source.sourceId,e.config.model.source);for(let n of e.channels)n.kind!==`disabled`&&t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.connections)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.tools)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.dynamicTools)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.remoteAgents)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.hooks)t.set(n.sourceId,{exportName:n.exportName,sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});for(let n of e.schedules)n.sourceKind!==`module`||!n.hasRun||t.set(n.sourceId,{sourceKind:`module`,logicalPath:n.logicalPath,sourceId:n.sourceId});return e.sandbox!==null&&t.set(e.sandbox.sourceId,{exportName:e.sandbox.exportName,sourceKind:`module`,logicalPath:e.sandbox.logicalPath,sourceId:e.sandbox.sourceId}),[...t.values()]}function createImportSpecifier(e){if(e.importSpecifierStyle===`absolute`)return normalizeEsmImportSpecifier(normalizeFilesystemPath(e.targetPath));let t=relativeFilesystemPath(e.fromDirectory,e.targetPath);return t.startsWith(`.`)?t:`./${t}`}function renderModuleMap(e){return renderFrozenObject([{key:`nodes`,value:renderFrozenObject(e.map(e=>({key:e.nodeId,value:renderFrozenObject([{key:`modules`,value:renderFrozenObject(e.modules.map(e=>({key:e.sourceId,value:e.bindingName})))}],3)})))}],0)}function renderFrozenObject(e,t=1){if(e.length===0)return`Object.freeze({})`;let n=` `.repeat(t),r=` `.repeat(t+1);return[`Object.freeze({`,e.map(e=>`${r}${JSON.stringify(e.key)}: ${e.value.replaceAll(`
|
|
3
3
|
`,`\n${r}`)}`).join(`,
|
|
4
4
|
`),`${n}})`].join(`
|
|
5
5
|
`)}function dirnameFilesystemPath(e){let t=splitFilesystemPath(e);return t.segments.length===0?t.root.length===0?`.`:t.root:createFilesystemPath(t.root,t.segments.slice(0,-1))}function joinFilesystemPath(e,t){let n=splitFilesystemPath(e),r=splitFilesystemPath(t);return r.root.length>0?createFilesystemPath(r.root,r.segments):createFilesystemPath(n.root,[...n.segments,...r.segments])}function relativeFilesystemPath(e,t){let n=splitFilesystemPath(e),r=splitFilesystemPath(t);if(n.root!==r.root)return normalizeFilesystemPath(t);let i=0;for(;i<n.segments.length&&i<r.segments.length&&n.segments[i]===r.segments[i];)i+=1;let a=[...Array.from({length:n.segments.length-i},()=>`..`),...r.segments.slice(i)];return a.length===0?`.`:a.join(`/`)}function normalizeFilesystemPath(e){let t=splitFilesystemPath(e);return createFilesystemPath(t.root,t.segments)}function splitFilesystemPath(e){let t=e.replaceAll(`\\`,`/`),n=``,r=t,i=t.match(/^[A-Za-z]:/);i===null?t.startsWith(`/`)&&(n=`/`,r=t.slice(1)):(n=i[0],r=t.slice(n.length),r.startsWith(`/`)&&(n=`${n}/`,r=r.slice(1)));let a=[];for(let e of r.split(`/`))if(!(e.length===0||e===`.`)){if(e===`..`){if(a.length>0&&a[a.length-1]!==`..`){a.pop();continue}n.length===0&&a.push(e);continue}a.push(e)}return{root:n,segments:a}}function createFilesystemPath(e,t){return e===`/`?t.length===0?`/`:`/${t.join(`/`)}`:e.endsWith(`/`)?t.length===0?e:`${e}${t.join(`/`)}`:e.length>0?t.length===0?e:`${e}/${t.join(`/`)}`:t.length===0?`.`:t.join(`/`)}export{collectModuleRefsForManifest,compiledModuleMapSchema,createCompiledModuleMapSource};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{toErrorMessage}from"#shared/errors.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{parseJsonObject}from"#shared/json.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";var MissingAgentConfigModuleError=class extends Error{agentId;constructor(e){super(`Agent "${e}" does not have an agent.ts config module. The "model" field is required.`),this.name=`MissingAgentConfigModuleError`,this.agentId=e}};async function compileAgentConfig(e,n){if(e.configModule===void 0)throw new MissingAgentConfigModuleError(e.agentId);let r=normalizeAgentDefinition(await loadModuleBackedDefinition({agentRoot:e.agentRoot,kind:`agent config`,source:e.configModule}),`Expected the agent config export "${e.configModule.exportName??`default`}" from "${e.configModule.logicalPath}" to match the public Ash shape.`),a=await normalizeAuthoredModelReference({modelCatalog:n.modelCatalog,purpose:`the primary compaction trigger model`,contextWindowTokens:r.modelContextWindowTokens,providerOptions:r.modelOptions?.providerOptions,source:e.configModule,value:r.model}),o={},s={compaction:o,model:a,name:e.agentId};return r.description!==void 0&&(s.description=r.description),r.build!==void 0&&(s.build={externalDependencies:r.build.externalDependencies===void 0?void 0:[...r.build.externalDependencies]}),s.source={exportName:e.configModule.exportName,sourceKind:`module`,logicalPath:e.configModule.logicalPath,sourceId:e.configModule.sourceId},r.compaction?.model!==void 0&&(o.model=await normalizeAuthoredModelReference({modelCatalog:n.modelCatalog,purpose:`the compaction summary model`,contextWindowTokens:r.compaction.modelContextWindowTokens,providerOptions:r.modelOptions?.providerOptions,source:e.configModule,value:r.compaction.model})),r.compaction?.thresholdPercent!==void 0&&(o.thresholdPercent=r.compaction.thresholdPercent),s}async function normalizeAuthoredModelReference(e){if(typeof e.value==`string`)return await withCompiledRuntimeModelLimits({id:formatLanguageModelGatewayId(e.value),providerOptions:parseProviderOptionsRecord(e.providerOptions)},e);let t=e.source;if(t===void 0)throw Error(`Expected ${e.purpose} to provide a valid AI SDK language model reference.`);let r=e.value,i=r.specificationVersion;if(i!==`v2`&&i!==`v3`&&i!==`v4`||typeof r.provider!=`string`||typeof r.modelId!=`string`||typeof r.doGenerate!=`function`||typeof r.doStream!=`function`)throw Error(`Expected the authored agent config export "${t.exportName??`default`}" from "${t.logicalPath}" to provide a valid AI SDK language model.`);let a={id:formatLanguageModelGatewayId(r),source:{exportName:t.exportName,sourceKind:`module`,logicalPath:t.logicalPath,sourceId:t.sourceId},providerOptions:parseProviderOptionsRecord(e.providerOptions)};if(e.contextWindowTokens===void 0){let t=await e.modelCatalog.getByProviderModelId(r.provider,r.modelId);if(t)return{...a,id:t.slug,contextWindowTokens:t.limits.contextWindowTokens}}return await withCompiledRuntimeModelLimits(a,e)}async function withCompiledRuntimeModelLimits(t,n){if(n.contextWindowTokens!==void 0)return{...t,contextWindowTokens:n.contextWindowTokens};let r;try{r=await n.modelCatalog.getModelLimits(t.id)}catch(r){throw Error(`Failed to load AI Gateway model metadata for ${n.purpose} "${t.id}". ${toErrorMessage(r)}`)}if(r===null)throw Error(`Cannot compile agent compaction because ${n.purpose} "${t.id}" does not have known AI Gateway context window metadata.`);return{...t,contextWindowTokens:r.contextWindowTokens}}function parseProviderOptionsRecord(e){if(e===void 0)return;let t={};for(let[n,i]of Object.entries(e))t[n]=parseJsonObject(i);return t}export{MissingAgentConfigModuleError,compileAgentConfig};
|
|
1
|
+
import{toErrorMessage}from"#shared/errors.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{parseJsonObject}from"#shared/json.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";var MissingAgentConfigModuleError=class extends Error{agentId;constructor(e){super(`Agent "${e}" does not have an agent.ts config module. The "model" field is required.`),this.name=`MissingAgentConfigModuleError`,this.agentId=e}};async function compileAgentConfig(e,n){if(e.configModule===void 0)throw new MissingAgentConfigModuleError(e.agentId);let r=normalizeAgentDefinition(await loadModuleBackedDefinition({agentRoot:e.agentRoot,kind:`agent config`,source:e.configModule}),`Expected the agent config export "${e.configModule.exportName??`default`}" from "${e.configModule.logicalPath}" to match the public Ash shape.`),a=await normalizeAuthoredModelReference({modelCatalog:n.modelCatalog,purpose:`the primary compaction trigger model`,contextWindowTokens:r.modelContextWindowTokens,providerOptions:r.modelOptions?.providerOptions,source:e.configModule,value:r.model}),o={},s={compaction:o,model:a,name:e.agentId};return r.description!==void 0&&(s.description=r.description),r.experimental?.codeMode!==void 0&&(s.experimental={codeMode:r.experimental.codeMode}),r.build!==void 0&&(s.build={externalDependencies:r.build.externalDependencies===void 0?void 0:[...r.build.externalDependencies]}),s.source={exportName:e.configModule.exportName,sourceKind:`module`,logicalPath:e.configModule.logicalPath,sourceId:e.configModule.sourceId},r.compaction?.model!==void 0&&(o.model=await normalizeAuthoredModelReference({modelCatalog:n.modelCatalog,purpose:`the compaction summary model`,contextWindowTokens:r.compaction.modelContextWindowTokens,providerOptions:r.modelOptions?.providerOptions,source:e.configModule,value:r.compaction.model})),r.compaction?.thresholdPercent!==void 0&&(o.thresholdPercent=r.compaction.thresholdPercent),s}async function normalizeAuthoredModelReference(e){if(typeof e.value==`string`)return await withCompiledRuntimeModelLimits({id:formatLanguageModelGatewayId(e.value),providerOptions:parseProviderOptionsRecord(e.providerOptions)},e);let t=e.source;if(t===void 0)throw Error(`Expected ${e.purpose} to provide a valid AI SDK language model reference.`);let r=e.value,i=r.specificationVersion;if(i!==`v2`&&i!==`v3`&&i!==`v4`||typeof r.provider!=`string`||typeof r.modelId!=`string`||typeof r.doGenerate!=`function`||typeof r.doStream!=`function`)throw Error(`Expected the authored agent config export "${t.exportName??`default`}" from "${t.logicalPath}" to provide a valid AI SDK language model.`);let a={id:formatLanguageModelGatewayId(r),source:{exportName:t.exportName,sourceKind:`module`,logicalPath:t.logicalPath,sourceId:t.sourceId},providerOptions:parseProviderOptionsRecord(e.providerOptions)};if(e.contextWindowTokens===void 0){let t=await e.modelCatalog.getByProviderModelId(r.provider,r.modelId);if(t)return{...a,id:t.slug,contextWindowTokens:t.limits.contextWindowTokens}}return await withCompiledRuntimeModelLimits(a,e)}async function withCompiledRuntimeModelLimits(t,n){if(n.contextWindowTokens!==void 0)return{...t,contextWindowTokens:n.contextWindowTokens};let r;try{r=await n.modelCatalog.getModelLimits(t.id)}catch(r){throw Error(`Failed to load AI Gateway model metadata for ${n.purpose} "${t.id}". ${toErrorMessage(r)}`)}if(r===null)throw Error(`Cannot compile agent compaction because ${n.purpose} "${t.id}" does not have known AI Gateway context window metadata.`);return{...t,contextWindowTokens:r.contextWindowTokens}}function parseProviderOptionsRecord(e){if(e===void 0)return;let t={};for(let[n,i]of Object.entries(e))t[n]=parseJsonObject(i);return t}export{MissingAgentConfigModuleError,compileAgentConfig};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{compileChannelDefinition}from"#compiler/normalize-channel.js";import{ROOT_COMPILED_AGENT_NODE_ID,createCompiledAgentManifest,createCompiledAgentNodeManifest}from"#compiler/manifest.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{compileAgentConfig}from"#compiler/normalize-agent-config.js";import{compileConnectionDefinition}from"#compiler/normalize-connection.js";import{compileHookEntry}from"#compiler/normalize-hook.js";import{compileSandboxDefinition}from"#compiler/normalize-sandbox.js";import{compileInstructions}from"#compiler/normalize-instructions.js";import{compileScheduleDefinition}from"#compiler/normalize-schedule.js";import{compileSkillSource}from"#compiler/normalize-skill.js";import{compileSubagentGraph}from"#compiler/normalize-subagent.js";import{compileToolEntry}from"#compiler/normalize-tool.js";async function compileAgentManifest(e){let r={modelCatalog:createCompiledRuntimeModelCatalogLoader(e.appRoot)},[a,o]=await Promise.all([compileAgentNodeManifest(e,r),compileSubagentGraph({appRoot:e.appRoot,compileAgentNodeManifest,context:r,parentNodeId:ROOT_COMPILED_AGENT_NODE_ID,subagents:e.subagents})]);return createCompiledAgentManifest({...a,remoteAgents:o.remoteAgents,subagentEdges:o.edges,subagents:o.nodes})}async function compileAgentNodeManifest(t,n){let i=await Promise.all(t.tools.map(e=>compileToolEntry(t.agentRoot,e))),s=[],c=[];for(let e of i)e.kind===`tool`?s.push(e.definition):c.push(e.name);let
|
|
1
|
+
import{compileChannelDefinition}from"#compiler/normalize-channel.js";import{ROOT_COMPILED_AGENT_NODE_ID,createCompiledAgentManifest,createCompiledAgentNodeManifest}from"#compiler/manifest.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{compileAgentConfig}from"#compiler/normalize-agent-config.js";import{compileConnectionDefinition}from"#compiler/normalize-connection.js";import{compileHookEntry}from"#compiler/normalize-hook.js";import{compileSandboxDefinition}from"#compiler/normalize-sandbox.js";import{compileInstructions}from"#compiler/normalize-instructions.js";import{compileScheduleDefinition}from"#compiler/normalize-schedule.js";import{compileSkillSource}from"#compiler/normalize-skill.js";import{compileSubagentGraph}from"#compiler/normalize-subagent.js";import{compileToolEntry}from"#compiler/normalize-tool.js";async function compileAgentManifest(e){let r={modelCatalog:createCompiledRuntimeModelCatalogLoader(e.appRoot)},[a,o]=await Promise.all([compileAgentNodeManifest(e,r),compileSubagentGraph({appRoot:e.appRoot,compileAgentNodeManifest,context:r,parentNodeId:ROOT_COMPILED_AGENT_NODE_ID,subagents:e.subagents})]);return createCompiledAgentManifest({...a,remoteAgents:o.remoteAgents,subagentEdges:o.edges,subagents:o.nodes})}async function compileAgentNodeManifest(t,n){let i=await Promise.all(t.tools.map(e=>compileToolEntry(t.agentRoot,e))),s=[],c=[],l=[];for(let e of i)e.kind===`tool`?s.push(e.definition):e.kind===`dynamic-tool`?c.push(e.definition):l.push(e.name);let u=(await Promise.all(t.channels.map(n=>compileChannelDefinition(t.agentRoot,n)))).flat();return createCompiledAgentNodeManifest({agentRoot:t.agentRoot,appRoot:t.appRoot,channels:u,config:await compileAgentConfig(t,n),connections:await Promise.all(t.connections.map(e=>compileConnectionDefinition(t.agentRoot,e))),diagnosticsSummary:t.diagnosticsSummary,disabledFrameworkTools:l,dynamicTools:c,hooks:t.hooks.map(e=>compileHookEntry(e)),sandbox:t.sandbox===null?null:await compileSandboxDefinition(t.agentRoot,t.sandbox),sandboxWorkspaces:t.sandboxWorkspaces.map(e=>({logicalPath:e.logicalPath,rootEntries:[...e.rootEntries],sourceId:e.sourceId,sourcePath:e.sourcePath})),schedules:await Promise.all(t.schedules.map(e=>compileScheduleDefinition(t.agentRoot,e))),skills:await Promise.all(t.skills.map(e=>compileSkillSource(t.agentRoot,e))),instructions:t.instructions===void 0?void 0:await compileInstructions(t.agentRoot,t.instructions),tools:s})}export{compileAgentManifest};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { ModuleSourceRef } from "#shared/source-ref.js";
|
|
2
|
-
import type { CompiledToolDefinition } from "#compiler/manifest.js";
|
|
2
|
+
import type { CompiledToolDefinition, CompiledDynamicToolDefinition } from "#compiler/manifest.js";
|
|
3
3
|
/**
|
|
4
4
|
* Compiled tool entry produced from one authored `tools/*.ts` file.
|
|
5
5
|
*
|
|
6
|
-
* Either a real tool definition
|
|
7
|
-
* named framework default during graph resolution
|
|
6
|
+
* Either a real tool definition, a `disabled` marker that removes the
|
|
7
|
+
* named framework default during graph resolution, or a dynamic tool
|
|
8
|
+
* resolver that produces tools at runtime.
|
|
8
9
|
*/
|
|
9
10
|
export type CompiledToolEntry = {
|
|
10
11
|
readonly kind: "tool";
|
|
@@ -12,6 +13,9 @@ export type CompiledToolEntry = {
|
|
|
12
13
|
} | {
|
|
13
14
|
readonly kind: "disabled";
|
|
14
15
|
readonly name: string;
|
|
16
|
+
} | {
|
|
17
|
+
readonly kind: "dynamic-tool";
|
|
18
|
+
readonly definition: CompiledDynamicToolDefinition;
|
|
15
19
|
};
|
|
16
20
|
/**
|
|
17
21
|
* Compiles one authored tool module into the normalized tool entry
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{stripLogicalPathExtension}from"#discover/filesystem.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";import{normalizeToolDefinition}from"#internal/authored-definition/schema-backed.js";async function compileToolEntry(e,t){let n=normalizeToolDefinition(await loadModuleBackedDefinition({agentRoot:e,kind:`tool`,source:t}),`Expected the tool export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`),r=stripLogicalPathExtension(t.logicalPath).replace(/^tools\//,``).replaceAll(`/`,`-`);return n.kind===`disabled`?{kind:`disabled`,name:r}:{kind:`tool`,definition:{description:n.definition.description,exportName:t.exportName,inputSchema:n.definition.inputSchema??null,logicalPath:t.logicalPath,name:r,sourceId:t.sourceId,sourceKind:`module`}}}export{compileToolEntry};
|
|
1
|
+
import{stripLogicalPathExtension}from"#discover/filesystem.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";import{normalizeToolDefinition}from"#internal/authored-definition/schema-backed.js";async function compileToolEntry(e,t){let n=normalizeToolDefinition(await loadModuleBackedDefinition({agentRoot:e,kind:`tool`,source:t}),`Expected the tool export "${t.exportName??`default`}" from "${t.logicalPath}" to match the public Ash shape.`),r=stripLogicalPathExtension(t.logicalPath).replace(/^tools\//,``).replaceAll(`/`,`-`);return n.kind===`disabled`?{kind:`disabled`,name:r}:n.kind===`dynamic-tool`?{kind:`dynamic-tool`,definition:{eventNames:[...n.eventNames],exportName:t.exportName,identity:n.identity,logicalPath:t.logicalPath,slug:r,sourceId:t.sourceId,sourceKind:`module`}}:{kind:`tool`,definition:{description:n.definition.description,exportName:t.exportName,inputSchema:n.definition.inputSchema??null,logicalPath:t.logicalPath,name:r,sourceId:t.sourceId,sourceKind:`module`}}}export{compileToolEntry};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { HarnessToolDefinition } from "#harness/execute-tool.js";
|
|
2
|
+
import type { HandleMessageStreamEvent } from "#protocol/message.js";
|
|
3
|
+
import type { ResolvedDynamicToolResolver } from "#runtime/types.js";
|
|
4
|
+
import type { ContextContainer } from "#context/container.js";
|
|
5
|
+
import type { DurableDynamicToolMetadata } from "#context/keys.js";
|
|
6
|
+
/**
|
|
7
|
+
* Reconstructs tool definitions from durable metadata using
|
|
8
|
+
* registered step functions. No resolver re-invocation — the
|
|
9
|
+
* execute function is looked up by step ID and called with stored
|
|
10
|
+
* closure vars.
|
|
11
|
+
*/
|
|
12
|
+
export declare function replayDynamicSessionTools(metadata: readonly DurableDynamicToolMetadata[], _resolvers: readonly ResolvedDynamicToolResolver[]): readonly HarnessToolDefinition[];
|
|
13
|
+
/**
|
|
14
|
+
* Unified dynamic tool event dispatch. Called by `handleEvent` for
|
|
15
|
+
* every stream event. Two phases:
|
|
16
|
+
*
|
|
17
|
+
* 1. **Build phase**: reconstruct tools from durable metadata when
|
|
18
|
+
* the virtual key is empty (workflow step boundary crossed).
|
|
19
|
+
* 2. **Resolve phase**: run resolver handlers for the current event,
|
|
20
|
+
* capture closures as durable metadata, produce live tools.
|
|
21
|
+
*
|
|
22
|
+
* The tool-loop reads {@link DynamicToolsKey} right before each model
|
|
23
|
+
* call. Events update it; the tool-loop picks up whatever is current.
|
|
24
|
+
*/
|
|
25
|
+
export declare function dispatchDynamicToolEvent(input: {
|
|
26
|
+
readonly ctx: ContextContainer;
|
|
27
|
+
readonly resolvers: readonly ResolvedDynamicToolResolver[];
|
|
28
|
+
readonly event: HandleMessageStreamEvent;
|
|
29
|
+
}): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{AuthKey,ContinuationTokenKey,DynamicSessionToolMetadataKey,DynamicToolResolverCacheKey,DynamicToolsKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{jsonSchema,zodSchema}from"ai";import{ALLOWED_DYNAMIC_TOOL_EVENTS}from"#shared/dynamic-tool-definition.js";import{normalizeJsonSchemaDefinition}from"#internal/json-schema.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getAdapterKind}from"#channel/adapter.js";const log=createLogger(`dynamic-tools`);function buildResolveContext(e,r,a){let c=e.get(SessionIdKey)??``,l=e.get(AuthKey)??null,u=e.get(InitiatorAuthKey)??null,d=e.get(ChannelKey),f=e.get(ContinuationTokenKey);return{session:{id:c,auth:{current:l,initiator:u}},channel:{kind:d===void 0?void 0:getAdapterKind(d),continuationToken:f},async __cache(t,n){let o=`${r}:${t}`,s=e.get(DynamicToolResolverCacheKey)??{};if(o in s)return s[o];let c=await n();if(a){let e={...s,[o]:c};a.set(DynamicToolResolverCacheKey,e)}return c}}}function toHarnessToolDefinition(e,t){return{description:t.description,execute:e=>t.execute(e,buildCallbackContext()),inputSchema:convertInputSchema(t.inputSchema),name:e}}function convertInputSchema(e){return typeof e==`object`&&e&&`~standard`in e?zodSchema(e):jsonSchema(e)}function qualifyDynamicToolNames(e,t,n){let r=Object.keys(n),i=[];if(r.length===0)return i;if(t===`single`)return i.push({name:e,entryKey:r[0],entry:n[r[0]]}),i;for(let t of r)i.push({name:`${e}__${t}`,entryKey:t,entry:n[t]});return i}function replayDynamicSessionTools(e,t){let n=[];for(let t of e){if(!t.executeStepFnName||!t.closureVars){log.warn(`Dynamic tool "${t.name}" has no registered step function — skipping on this step. The bundler transform may not have processed this tool file.`);continue}let e=lookupStepFunction(t.executeStepFnName);if(!e){log.warn(`Dynamic tool "${t.name}" references step function "${t.executeStepFnName}" which is not registered — skipping on this step.`);continue}n.push({description:t.description,execute:n=>e(t.closureVars,n,buildCallbackContext()),inputSchema:jsonSchema(t.inputSchema),name:t.name})}return n}function lookupStepFunction(e){try{let t=globalThis[Symbol.for(`@workflow/core//registeredSteps`)];return t===void 0?null:t.get(e)||null}catch{return null}}function safeSerialize(e){try{return JSON.parse(JSON.stringify(e))}catch{return{}}}function matchesAnySlug(e,t){for(let n of t)if(e===n||e.startsWith(`${n}__`))return!0;return!1}async function resolveToolsFromEvent(e,t,n){let i=await Promise.allSettled(t.map(async t=>{let r=t.events[n.type];if(r===void 0)return null;let i=await r(n,buildResolveContext(e,t.slug,e));return i==null?null:{resolver:t,result:i}})),a=[],o=[];for(let e of i){if(e.status===`rejected`){log.error(`Dynamic tool resolver (${n.type}) threw — skipping.`,{error:toErrorMessage(e.reason)});continue}if(e.value===null)continue;let{resolver:t,result:r}=e.value,i=qualifyDynamicToolNames(t.slug,t.identity,r);for(let{name:e,entryKey:n,entry:r}of i){a.push(toHarnessToolDefinition(e,r));let i=`__executeStepFn`in r?r.__executeStepFn:void 0,s=`__closureVars`in r?r.__closureVars:void 0;o.push({name:e,description:r.description,inputSchema:normalizeJsonSchemaDefinition(r.inputSchema),resolverSlug:t.slug,entryKey:n,executeStepFnName:i?.stepId,closureVars:s===void 0?void 0:safeSerialize(s)})}}if(o.length>0){let t=e.get(DynamicSessionToolMetadataKey)??[],n=new Set(o.map(e=>e.resolverSlug)),i=t.filter(e=>!n.has(e.resolverSlug));e.set(DynamicSessionToolMetadataKey,[...i,...o])}return a}async function dispatchDynamicToolEvent(e){let{ctx:t,resolvers:n,event:i}=e;if(t.get(DynamicToolsKey)===void 0){let e=t.get(DynamicSessionToolMetadataKey);if(e!==void 0&&e.length>0){let r=replayDynamicSessionTools(e,n);r.length>0&&t.setVirtualContext(DynamicToolsKey,[...r])}}if(!ALLOWED_DYNAMIC_TOOL_EVENTS.has(i.type))return;let o=n.filter(e=>e.eventNames.includes(i.type));if(o.length===0)return;let s=await resolveToolsFromEvent(t,o,i);if(s.length===0)return;let c=new Set(o.map(e=>e.slug)),l=(t.get(DynamicToolsKey)??[]).filter(e=>!matchesAnySlug(e.name,c));t.setVirtualContext(DynamicToolsKey,[...l,...s])}export{dispatchDynamicToolEvent,replayDynamicSessionTools};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ContinuationTokenKey,SandboxKey,SessionPreparedKey}from"./keys.js";import{createLogger}from"#internal/logging.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeSkillPackage,writeSkillPackageToSandbox}from"#shared/skill-package.js";import{
|
|
1
|
+
import{ContinuationTokenKey,SandboxKey,SessionPreparedKey}from"./keys.js";import{createLogger}from"#internal/logging.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeSkillPackage,writeSkillPackageToSandbox}from"#shared/skill-package.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getAdapterKind}from"#channel/adapter.js";import{emitRecoverableFailedTurn,emitTurnPreamble,getHarnessEmissionState,setHarnessEmissionState}from"#harness/emission.js";import{formatAvailableSkillsSection}from"#execution/skills/instructions.js";const log=createLogger(`hooks.lifecycle`);async function dispatchHookLifecycle(e){let{ctx:t,registry:r,emit:a}=e,o=getHarnessEmissionState(e.session.state),s=buildHookContext(t),c=[],l=e.session;if(r.session.length>0&&t.get(SessionPreparedKey)!==!0){t.set(SessionPreparedKey,!0);let e=[];for(let n of r.session){let r=await n.handler(s);r?.modelContext!==void 0&&r.modelContext.length>0&&c.push(...r.modelContext),e.push(...normalizeLifecycleSkillResults(t,r))}l=await materializeLifecycleSkills(t,l,e)}let u=!1,d=o;try{let e=[];for(let n of r.turn){let r=await n.handler(s);r?.modelContext!==void 0&&r.modelContext.length>0&&c.push(...r.modelContext),e.push(...normalizeLifecycleSkillResults(t,r))}l=await materializeLifecycleSkills(t,l,e)}catch(t){let n=toErrorMessage(t);try{u||=(d=await emitTurnPreamble(a,{message:e.input.message},o,e.runtimeIdentity),!0);let t=await emitRecoverableFailedTurn(a,d,{code:`HOOK_TURN_FAILED`,message:n});return{kind:`turn-failed`,message:n,nextSession:setHarnessEmissionState(l,t)}}catch(e){throw log.error(`Event hook threw while emitting the turn.failed cascade for a lifecycle.turn failure — escalating to session.failed.`,{error:toErrorMessage(e)}),e}}let f=e.input.modelContext??[],p=f.length===0?c:[...f,...c];return{kind:`proceed`,input:p.length>0?{...e.input,modelContext:p}:e.input,nextSession:l}}function normalizeLifecycleSkillResults(e,t){if(t?.skills===void 0||t.skills.length===0)return[];let n=new Set(e.require(BundleKey).resolvedAgent.skills.map(e=>e.name)),r=new Map;for(let e of t.skills){let t=normalizeSkillPackage(e);if(n.has(t.name))throw Error(`Hook-contributed skill "${t.name}" conflicts with an authored skill.`);r.set(t.name,t)}return[...r.values()]}async function materializeLifecycleSkills(e,n,r){if(r.length===0)return n;let i=new Map(r.map(e=>[e.name,e])),a=await e.require(SandboxKey).get();if(a===null)throw Error(`Dynamic skills require a sandbox for the current agent.`);for(let e of i.values())await writeSkillPackageToSandbox({sandbox:a,skill:e});let s=formatAvailableSkillsSection([...i.values()]);return s===null?n:{...n,history:[...n.history,{role:`system`,content:s}]}}async function dispatchStreamEventHooks(e){let t=e.registry.streamEventsByType.get(e.event.type)??[],n=e.registry.streamEventsWildcard;if(t.length===0&&n.length===0)return;let r=buildHookContext(e.ctx);for(let n of t)await n.handler(e.event,r);for(let t of n)await t.handler(e.event,r)}function buildHookContext(t){let n=t.require(BundleKey),r=t.get(ChannelKey),i=t.get(ContinuationTokenKey),a=r===void 0?void 0:getAdapterKind(r);return{...buildCallbackContext(),agent:{name:n.resolvedAgent.config.name??`agent`,nodeId:n.nodeId},channel:{kind:a,continuationToken:i}}}async function runHookLifecycleStep(e,t){let n=await dispatchHookLifecycle(e);return n.kind===`turn-failed`?{next:e.mode===`conversation`?null:{done:!0,output:n.message},session:n.nextSession}:t(n.nextSession,n.input)}export{dispatchHookLifecycle,dispatchStreamEventHooks,runHookLifecycleStep};
|
|
@@ -55,3 +55,39 @@ export declare const SessionCallbackKey: ContextKey<SessionCallback>;
|
|
|
55
55
|
export declare const SessionPreparedKey: ContextKey<boolean>;
|
|
56
56
|
export declare const SessionKey: ContextKey<Session>;
|
|
57
57
|
export declare const SandboxKey: ContextKey<SandboxAccess>;
|
|
58
|
+
/**
|
|
59
|
+
* Virtual (non-serialized) live dynamic tool definitions. Updated by
|
|
60
|
+
* {@link dispatchDynamicToolEvent} whenever a subscribed stream event
|
|
61
|
+
* fires. Read by the tool-loop when building the effective toolset.
|
|
62
|
+
*/
|
|
63
|
+
export declare const DynamicToolsKey: ContextKey<import("#harness/execute-tool.js").HarnessToolDefinition[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Durable (serialized) metadata for session-scoped dynamic tools.
|
|
66
|
+
* Set on the first step when resolvers run. Read on subsequent steps
|
|
67
|
+
* to reconstruct tool definitions with lazy execute wrappers.
|
|
68
|
+
*/
|
|
69
|
+
export interface DurableDynamicToolMetadata {
|
|
70
|
+
readonly name: string;
|
|
71
|
+
readonly description: string;
|
|
72
|
+
readonly inputSchema: import("#shared/json.js").JsonObject;
|
|
73
|
+
readonly resolverSlug: string;
|
|
74
|
+
readonly entryKey: string;
|
|
75
|
+
/**
|
|
76
|
+
* Name of the hoisted execute step function (e.g.
|
|
77
|
+
* `__ash_dynamic_exec_0`). Used to look up the registered step
|
|
78
|
+
* function via `getStepFunction` on replay.
|
|
79
|
+
*/
|
|
80
|
+
readonly executeStepFnName?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Serialized closure variables captured from the resolver scope on
|
|
83
|
+
* the first run. Passed as the `__vars` parameter to the hoisted
|
|
84
|
+
* step function on replay.
|
|
85
|
+
*/
|
|
86
|
+
readonly closureVars?: Record<string, unknown>;
|
|
87
|
+
}
|
|
88
|
+
export declare const DynamicSessionToolMetadataKey: ContextKey<readonly DurableDynamicToolMetadata[]>;
|
|
89
|
+
/**
|
|
90
|
+
* Durable cache for resolver I/O results. Keyed by resolver slug +
|
|
91
|
+
* await index. Populated on first resolver run, read on replay.
|
|
92
|
+
*/
|
|
93
|
+
export declare const DynamicToolResolverCacheKey: ContextKey<Record<string, unknown>>;
|
package/dist/src/context/keys.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ContextKey}from"#context/key.js";const AuthKey=new ContextKey(`ash.auth`),InitiatorAuthKey=new ContextKey(`ash.initiatorAuth`),SessionIdKey=new ContextKey(`ash.sessionId`),ContinuationTokenKey=new ContextKey(`ash.continuationToken`),ModeKey=new ContextKey(`ash.mode`),ParentSessionKey=new ContextKey(`ash.parentSession`),CapabilitiesKey=new ContextKey(`ash.capabilities`),SessionCallbackKey=new ContextKey(`ash.sessionCallback`),SessionPreparedKey=new ContextKey(`ash.sessionPrepared`),SessionKey=new ContextKey(`ash.session`),SandboxKey=new ContextKey(`ash.sandbox`);export{AuthKey,CapabilitiesKey,ContinuationTokenKey,InitiatorAuthKey,ModeKey,ParentSessionKey,SandboxKey,SessionCallbackKey,SessionIdKey,SessionKey,SessionPreparedKey};
|
|
1
|
+
import{ContextKey}from"#context/key.js";const AuthKey=new ContextKey(`ash.auth`),InitiatorAuthKey=new ContextKey(`ash.initiatorAuth`),SessionIdKey=new ContextKey(`ash.sessionId`),ContinuationTokenKey=new ContextKey(`ash.continuationToken`),ModeKey=new ContextKey(`ash.mode`),ParentSessionKey=new ContextKey(`ash.parentSession`),CapabilitiesKey=new ContextKey(`ash.capabilities`),SessionCallbackKey=new ContextKey(`ash.sessionCallback`),SessionPreparedKey=new ContextKey(`ash.sessionPrepared`),SessionKey=new ContextKey(`ash.session`),SandboxKey=new ContextKey(`ash.sandbox`),DynamicToolsKey=new ContextKey(`ash.dynamicTools`),DynamicSessionToolMetadataKey=new ContextKey(`ash.dynamicSessionToolMetadata`),DynamicToolResolverCacheKey=new ContextKey(`ash.dynamicToolResolverCache`);export{AuthKey,CapabilitiesKey,ContinuationTokenKey,DynamicSessionToolMetadataKey,DynamicToolResolverCacheKey,DynamicToolsKey,InitiatorAuthKey,ModeKey,ParentSessionKey,SandboxKey,SessionCallbackKey,SessionIdKey,SessionKey,SessionPreparedKey};
|