experimental-ash 0.2.0-alpha.20 → 0.2.0-alpha.21

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 (119) hide show
  1. package/dist/src/channel/slack-channel.d.ts +7 -14
  2. package/dist/src/channel/slack-channel.d.ts.map +1 -1
  3. package/dist/src/channel/slack-channel.js +11 -21
  4. package/dist/src/channel/slack-channel.js.map +1 -1
  5. package/dist/src/channel/types.d.ts +9 -6
  6. package/dist/src/channel/types.d.ts.map +1 -1
  7. package/dist/src/channel/types.js.map +1 -1
  8. package/dist/src/context/accessors.d.ts +13 -12
  9. package/dist/src/context/accessors.d.ts.map +1 -1
  10. package/dist/src/context/accessors.js +16 -17
  11. package/dist/src/context/accessors.js.map +1 -1
  12. package/dist/src/context/container.d.ts +17 -19
  13. package/dist/src/context/container.d.ts.map +1 -1
  14. package/dist/src/context/container.js +21 -14
  15. package/dist/src/context/container.js.map +1 -1
  16. package/dist/src/context/durable-context.d.ts +18 -0
  17. package/dist/src/context/durable-context.d.ts.map +1 -0
  18. package/dist/src/context/durable-context.js +49 -0
  19. package/dist/src/context/durable-context.js.map +1 -0
  20. package/dist/src/context/key.d.ts +34 -82
  21. package/dist/src/context/key.d.ts.map +1 -1
  22. package/dist/src/context/key.js +58 -80
  23. package/dist/src/context/key.js.map +1 -1
  24. package/dist/src/context/keys.d.ts +6 -6
  25. package/dist/src/context/keys.d.ts.map +1 -1
  26. package/dist/src/context/keys.js +8 -6
  27. package/dist/src/context/keys.js.map +1 -1
  28. package/dist/src/context/provider.d.ts +2 -2
  29. package/dist/src/context/provider.d.ts.map +1 -1
  30. package/dist/src/context/run-step.d.ts +6 -8
  31. package/dist/src/context/run-step.d.ts.map +1 -1
  32. package/dist/src/context/run-step.js +13 -17
  33. package/dist/src/context/run-step.js.map +1 -1
  34. package/dist/src/context/seed-keys.d.ts +7 -7
  35. package/dist/src/context/seed-keys.d.ts.map +1 -1
  36. package/dist/src/context/seed-keys.js +19 -7
  37. package/dist/src/context/seed-keys.js.map +1 -1
  38. package/dist/src/context/serialize.d.ts +8 -9
  39. package/dist/src/context/serialize.d.ts.map +1 -1
  40. package/dist/src/context/serialize.js +28 -16
  41. package/dist/src/context/serialize.js.map +1 -1
  42. package/dist/src/execution/continuous-entry.d.ts +6 -8
  43. package/dist/src/execution/continuous-entry.d.ts.map +1 -1
  44. package/dist/src/execution/continuous-entry.js +25 -21
  45. package/dist/src/execution/continuous-entry.js.map +1 -1
  46. package/dist/src/execution/continuous-runtime.d.ts.map +1 -1
  47. package/dist/src/execution/continuous-runtime.js +4 -1
  48. package/dist/src/execution/continuous-runtime.js.map +1 -1
  49. package/dist/src/execution/step-context.d.ts +27 -0
  50. package/dist/src/execution/step-context.d.ts.map +1 -0
  51. package/dist/src/execution/step-context.js +54 -0
  52. package/dist/src/execution/step-context.js.map +1 -0
  53. package/dist/src/execution/tool-compaction.d.ts +1 -3
  54. package/dist/src/execution/tool-compaction.d.ts.map +1 -1
  55. package/dist/src/execution/tool-compaction.js +6 -17
  56. package/dist/src/execution/tool-compaction.js.map +1 -1
  57. package/dist/src/execution/workflow-entry.d.ts +4 -5
  58. package/dist/src/execution/workflow-entry.d.ts.map +1 -1
  59. package/dist/src/execution/workflow-entry.js.map +1 -1
  60. package/dist/src/execution/workflow-runtime.d.ts.map +1 -1
  61. package/dist/src/execution/workflow-runtime.js +3 -2
  62. package/dist/src/execution/workflow-runtime.js.map +1 -1
  63. package/dist/src/execution/workflow-steps.d.ts +2 -2
  64. package/dist/src/execution/workflow-steps.d.ts.map +1 -1
  65. package/dist/src/execution/workflow-steps.js +12 -20
  66. package/dist/src/execution/workflow-steps.js.map +1 -1
  67. package/dist/src/harness/emission.d.ts +1 -1
  68. package/dist/src/harness/emission.js +3 -3
  69. package/dist/src/harness/emission.js.map +1 -1
  70. package/dist/src/harness/input-requests.d.ts +22 -1
  71. package/dist/src/harness/input-requests.d.ts.map +1 -1
  72. package/dist/src/harness/input-requests.js +36 -32
  73. package/dist/src/harness/input-requests.js.map +1 -1
  74. package/dist/src/harness/types.d.ts +15 -3
  75. package/dist/src/harness/types.d.ts.map +1 -1
  76. package/dist/src/harness/types.js +6 -1
  77. package/dist/src/harness/types.js.map +1 -1
  78. package/dist/src/internal/application/package.js +1 -1
  79. package/dist/src/internal/nitro/routes/runtime-stack.d.ts +3 -3
  80. package/dist/src/internal/nitro/routes/runtime-stack.js +3 -3
  81. package/dist/src/public/channels/slack/index.d.ts +5 -0
  82. package/dist/src/public/channels/slack/index.d.ts.map +1 -1
  83. package/dist/src/public/channels/slack/index.js.map +1 -1
  84. package/dist/src/public/definitions/tool.d.ts +3 -4
  85. package/dist/src/public/definitions/tool.d.ts.map +1 -1
  86. package/dist/src/public/definitions/tool.js.map +1 -1
  87. package/dist/src/public/index.d.ts +1 -1
  88. package/dist/src/public/index.d.ts.map +1 -1
  89. package/dist/src/public/index.js +1 -1
  90. package/dist/src/public/index.js.map +1 -1
  91. package/dist/src/public/tools/defaults.d.ts +4 -4
  92. package/dist/src/public/tools/defaults.js +4 -4
  93. package/dist/src/runtime/framework-tools/connection-search.d.ts +2 -2
  94. package/dist/src/runtime/framework-tools/connection-search.d.ts.map +1 -1
  95. package/dist/src/runtime/framework-tools/connection-search.js +2 -2
  96. package/dist/src/runtime/framework-tools/connection-search.js.map +1 -1
  97. package/dist/src/runtime/framework-tools/file-state.d.ts +5 -5
  98. package/dist/src/runtime/framework-tools/file-state.d.ts.map +1 -1
  99. package/dist/src/runtime/framework-tools/file-state.js +6 -8
  100. package/dist/src/runtime/framework-tools/file-state.js.map +1 -1
  101. package/dist/src/runtime/framework-tools/skill.d.ts.map +1 -1
  102. package/dist/src/runtime/framework-tools/skill.js +1 -3
  103. package/dist/src/runtime/framework-tools/skill.js.map +1 -1
  104. package/dist/src/runtime/framework-tools/todo.d.ts.map +1 -1
  105. package/dist/src/runtime/framework-tools/todo.js +2 -4
  106. package/dist/src/runtime/framework-tools/todo.js.map +1 -1
  107. package/dist/src/runtime/sessions/auth.d.ts +1 -1
  108. package/docs/internals/context.md +81 -231
  109. package/docs/public/README.md +19 -17
  110. package/docs/public/channels/README.md +4 -0
  111. package/docs/public/migration-guide.md +71 -0
  112. package/docs/public/session-context.md +46 -17
  113. package/docs/public/tools.md +18 -27
  114. package/docs/public/typescript-api.md +5 -1
  115. package/package.json +1 -1
  116. package/dist/src/context/state.d.ts +0 -27
  117. package/dist/src/context/state.d.ts.map +0 -1
  118. package/dist/src/context/state.js +0 -53
  119. package/dist/src/context/state.js.map +0 -1
@@ -36,8 +36,8 @@ exposed to the model as `get_weather`; a file at `agent/tools/get-weather.ts` is
36
36
  `get-weather`. You can override that by setting `name` in the tool definition.
37
37
 
38
38
  `defineTool`, `disableTool`, `defineBashTool`, `defineReadFileTool`, and `defineWriteFileTool` live on the `experimental-ash/tools` subpath.
39
- Runtime helpers like `getSession`, `getSandbox`, `getSkill`, `getState`, and `setState` stay on the
40
- main `experimental-ash` barrel.
39
+ Runtime helpers like `getSession`, `getContext`, `setContext`, `ensureContext`, `getSandbox`, and
40
+ `getSkill` stay on the main `experimental-ash` barrel.
41
41
 
42
42
  ## What A Tool Definition Needs
43
43
 
@@ -106,8 +106,8 @@ execution surface by itself; executable behavior still comes from the tools the
106
106
 
107
107
  `read_file` reads a text file from the sandbox filesystem with line-numbered output. `write_file`
108
108
  writes a complete file, enforcing read-before-write for existing files and detecting stale reads.
109
- Both target the framework default sandbox. Compaction clears the durable read-file state so the model
110
- must re-read files before overwriting after compaction.
109
+ Both target the framework default sandbox. Compaction clears the durable read-file context so the
110
+ model must re-read files before overwriting after compaction.
111
111
 
112
112
  Authors can wrap, replace, or disable these defaults from `agent/tools/`.
113
113
 
@@ -225,32 +225,23 @@ export default defineWriteFileTool({
225
225
  ```
226
226
 
227
227
  When replacing the framework `read_file`, the authored version inherits the same compaction
228
- state-reset behavior by default. Provide an explicit `onCompact` to override that.
228
+ context-reset behavior by default. Provide an explicit `onCompact` to override that.
229
229
 
230
- ### Replace A Default With Custom State
230
+ ### Replace A Default With Custom Context
231
231
 
232
- `agent/tools/todo.ts` - replace the framework `todo` tool with a custom stateful version. State is
233
- the replacement's responsibility. Declare your own `ContextKey` and use `getState` / `setState` to
234
- read and write it:
232
+ `agent/tools/todo.ts` - replace the framework `todo` tool with a custom durable-context version.
233
+ Declare your own `ContextKey` and use `ensureContext` / `setContext` to read and write it:
235
234
 
236
235
  ```ts
237
- import { ContextKey, getState, setState } from "experimental-ash";
236
+ import { ContextKey, ensureContext, setContext } from "experimental-ash";
238
237
  import { defineTool } from "experimental-ash/tools";
239
238
  import { z } from "zod";
240
239
 
241
- interface NoteListState {
240
+ interface NoteListContext {
242
241
  readonly notes: readonly string[];
243
242
  }
244
243
 
245
- const NoteListStateKey = new ContextKey<NoteListState>("myapp.notes", {
246
- initial: () => ({ notes: [] }),
247
- compact: (state) => ({
248
- summary:
249
- state.notes.length === 0
250
- ? undefined
251
- : `Notes (${state.notes.length}): ${state.notes.join("; ")}`,
252
- }),
253
- });
244
+ const NoteListContextKey = new ContextKey<NoteListContext>("myapp.notes");
254
245
 
255
246
  export default defineTool({
256
247
  description: "Append a note or read the running list of notes.",
@@ -259,12 +250,12 @@ export default defineTool({
259
250
  }),
260
251
  async execute(input) {
261
252
  if (typeof input.note === "string" && input.note.length > 0) {
262
- const next = input.note;
263
- setState(NoteListStateKey, (current) => ({
264
- notes: [...current.notes, next],
265
- }));
253
+ const current = ensureContext(NoteListContextKey, () => ({ notes: [] }));
254
+ setContext(NoteListContextKey, {
255
+ notes: [...current.notes, input.note],
256
+ });
266
257
  }
267
- return getState(NoteListStateKey);
258
+ return ensureContext(NoteListContextKey, () => ({ notes: [] }));
268
259
  },
269
260
  });
270
261
  ```
@@ -272,8 +263,8 @@ export default defineTool({
272
263
  ### Subtleties Worth Knowing
273
264
 
274
265
  - The filename is the default name. There is also an explicit `name` property when you need it.
275
- - State is owned by the replacement. Replacing `todo` with a fresh `defineTool` does not inherit the
276
- framework's state key.
266
+ - Durable context is owned by the replacement. Replacing `todo` with a fresh `defineTool` does not
267
+ inherit the framework's context key.
277
268
  - Authored-vs-authored collisions are impossible by construction. Two files cannot share a slug under
278
269
  the same `agent/tools/` directory.
279
270
 
@@ -41,9 +41,11 @@ Most apps use `defineAgent`, `defineTool`, and `defineSandbox` the most.
41
41
  ## Runtime Helpers
42
42
 
43
43
  - `getSession()` - current session, turn, auth, and optional parent lineage
44
+ - `getContext(key)` - read one durable authored context value
45
+ - `setContext(key, value)` - write one durable authored context value
46
+ - `ensureContext(key, valueOrFactory)` - read-or-create one durable context value
44
47
  - `getSandbox(name)` - live named sandbox session
45
48
  - `getSkill(identifier)` - handle for a named skill visible to the current agent
46
- - `getState(key)` / `setState(key)` - context-backed runtime state helpers
47
49
 
48
50
  Related exported types:
49
51
 
@@ -61,6 +63,8 @@ sessions must finish inside the current invocation.
61
63
 
62
64
  These helpers only work inside active authored runtime execution.
63
65
 
66
+ Breaking change details and before/after examples live in [`migration-guide.md`](./migration-guide.md).
67
+
64
68
  ## Markdown Helpers
65
69
 
66
70
  Ash also exports helpers for turning markdown into the same shapes as module-authored definitions:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "experimental-ash",
3
- "version": "0.2.0-alpha.20",
3
+ "version": "0.2.0-alpha.21",
4
4
  "type": "module",
5
5
  "main": "./dist/src/index.js",
6
6
  "types": "./dist/src/index.d.ts",
@@ -1,27 +0,0 @@
1
- import type { HarnessSession } from "../harness/types.js";
2
- import type { AshContext } from "./container.js";
3
- /**
4
- * Opaque snapshot returned by {@link hydrateStateKeys} and consumed by
5
- * {@link commitStateKeys} for reference-equality change detection.
6
- */
7
- export type StateSnapshot = ReadonlyMap<string, unknown>;
8
- /**
9
- * Hydrates all registered state keys onto the context from `session.state`.
10
- *
11
- * For each state key in the global registry:
12
- * - If `session.state[key.name]` exists, deserializes it (via codec if present).
13
- * - Otherwise, uses `key.initial()` to produce the default value.
14
- *
15
- * Returns an opaque snapshot used by {@link commitStateKeys} to detect which
16
- * keys were modified during the step.
17
- */
18
- export declare function hydrateStateKeys(ctx: AshContext, session: HarnessSession): Promise<StateSnapshot>;
19
- /**
20
- * Commits modified state keys back to `session.state`.
21
- *
22
- * Compares each state key's current context value against the snapshot taken
23
- * during hydration. Only keys whose value changed (reference inequality) are
24
- * written. Returns the session unchanged when nothing was modified.
25
- */
26
- export declare function commitStateKeys(ctx: AshContext, session: HarnessSession, snapshot: StateSnapshot): HarnessSession;
27
- //# sourceMappingURL=state.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/context/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAcxB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,aAAa,GACtB,cAAc,CAiBhB"}
@@ -1,53 +0,0 @@
1
- import { getStateKeys } from "./key.js";
2
- /**
3
- * Hydrates all registered state keys onto the context from `session.state`.
4
- *
5
- * For each state key in the global registry:
6
- * - If `session.state[key.name]` exists, deserializes it (via codec if present).
7
- * - Otherwise, uses `key.initial()` to produce the default value.
8
- *
9
- * Returns an opaque snapshot used by {@link commitStateKeys} to detect which
10
- * keys were modified during the step.
11
- */
12
- export async function hydrateStateKeys(ctx, session) {
13
- const snapshot = new Map();
14
- for (const key of getStateKeys()) {
15
- const raw = session.state?.[key.name];
16
- let value;
17
- if (raw !== undefined) {
18
- value = key.codec ? await key.codec.deserialize(raw, ctx) : raw;
19
- }
20
- else {
21
- value = key.initial?.();
22
- }
23
- ctx.set(key, value);
24
- snapshot.set(key.name, value);
25
- }
26
- return snapshot;
27
- }
28
- /**
29
- * Commits modified state keys back to `session.state`.
30
- *
31
- * Compares each state key's current context value against the snapshot taken
32
- * during hydration. Only keys whose value changed (reference inequality) are
33
- * written. Returns the session unchanged when nothing was modified.
34
- */
35
- export function commitStateKeys(ctx, session, snapshot) {
36
- let newState = null;
37
- for (const key of getStateKeys()) {
38
- if (ctx.has(key)) {
39
- const current = ctx.get(key);
40
- if (current !== snapshot.get(key.name)) {
41
- if (newState === null) {
42
- newState = { ...session.state };
43
- }
44
- newState[key.name] = key.codec ? key.codec.serialize(current) : current;
45
- }
46
- }
47
- }
48
- if (newState !== null) {
49
- return { ...session, state: newState };
50
- }
51
- return session;
52
- }
53
- //# sourceMappingURL=state.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/context/state.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAQxC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAe,EACf,OAAuB;IAEvB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC5C,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,KAAc,CAAC;QACnB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1B,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACpB,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAe,EACf,OAAuB,EACvB,QAAuB;IAEvB,IAAI,QAAQ,GAAmC,IAAI,CAAC;IACpD,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,EAAE,CAAC;QACjC,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC7B,IAAI,OAAO,KAAK,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;oBACtB,QAAQ,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;gBAClC,CAAC;gBACD,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC1E,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACzC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}