@kuralle-agents/core 0.5.0 → 0.6.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 (64) hide show
  1. package/README.md +1 -1
  2. package/dist/flow/nodeBuilders.d.ts +1 -1
  3. package/dist/flow/nodeBuilders.js +5 -3
  4. package/dist/index.d.ts +12 -4
  5. package/dist/index.js +7 -2
  6. package/dist/memory/blocks/FilePersistentMemoryStore.d.ts +1 -1
  7. package/dist/memory/blocks/FilePersistentMemoryStore.js +9 -0
  8. package/dist/memory/blocks/InMemoryPersistentMemoryStore.d.ts +8 -0
  9. package/dist/memory/blocks/InMemoryPersistentMemoryStore.js +25 -0
  10. package/dist/memory/blocks/RoutedPersistentMemoryStore.d.ts +18 -0
  11. package/dist/memory/blocks/RoutedPersistentMemoryStore.js +35 -0
  12. package/dist/memory/blocks/TieredPersistentMemoryStore.d.ts +10 -0
  13. package/dist/memory/blocks/TieredPersistentMemoryStore.js +30 -0
  14. package/dist/memory/blocks/memoryBlockTool.d.ts +5 -5
  15. package/dist/memory/blocks/testing.d.ts +11 -0
  16. package/dist/memory/blocks/testing.js +59 -0
  17. package/dist/memory/index.d.ts +4 -0
  18. package/dist/memory/index.js +3 -0
  19. package/dist/runtime/Runtime.d.ts +3 -0
  20. package/dist/runtime/Runtime.js +47 -5
  21. package/dist/runtime/agentReply.js +2 -1
  22. package/dist/runtime/channels/TextDriver.js +3 -2
  23. package/dist/runtime/channels/VoiceDriver.js +3 -3
  24. package/dist/runtime/channels/extractionTurn.js +1 -1
  25. package/dist/runtime/ctx.d.ts +2 -0
  26. package/dist/runtime/ctx.js +1 -0
  27. package/dist/runtime/grounding/defaultStoreRegistry.d.ts +3 -0
  28. package/dist/runtime/grounding/defaultStoreRegistry.js +10 -0
  29. package/dist/runtime/grounding/index.d.ts +1 -0
  30. package/dist/runtime/grounding/index.js +1 -0
  31. package/dist/runtime/grounding/workingMemory.d.ts +19 -0
  32. package/dist/runtime/grounding/workingMemory.js +80 -0
  33. package/dist/runtime/resolveAgentWorkspace.d.ts +10 -0
  34. package/dist/runtime/resolveAgentWorkspace.js +9 -0
  35. package/dist/skills/SkillsCapability.d.ts +10 -0
  36. package/dist/skills/SkillsCapability.js +52 -0
  37. package/dist/skills/collectSkills.d.ts +17 -0
  38. package/dist/skills/collectSkills.js +56 -0
  39. package/dist/skills/index.d.ts +5 -0
  40. package/dist/skills/index.js +4 -0
  41. package/dist/skills/inlineSkillStore.d.ts +9 -0
  42. package/dist/skills/inlineSkillStore.js +37 -0
  43. package/dist/skills/wireAgentSkills.d.ts +10 -0
  44. package/dist/skills/wireAgentSkills.js +25 -0
  45. package/dist/tools/effect/defineTool.js +1 -1
  46. package/dist/tools/effect/index.d.ts +1 -0
  47. package/dist/tools/effect/index.js +1 -0
  48. package/dist/tools/effect/wrapAiSdkTool.d.ts +3 -0
  49. package/dist/tools/effect/wrapAiSdkTool.js +12 -0
  50. package/dist/tools/fs/createFsTool.d.ts +30 -0
  51. package/dist/tools/fs/createFsTool.js +200 -0
  52. package/dist/types/agentConfig.d.ts +16 -3
  53. package/dist/types/filesystem.d.ts +85 -0
  54. package/dist/types/filesystem.js +6 -0
  55. package/dist/types/grounding.d.ts +12 -0
  56. package/dist/types/index.d.ts +2 -0
  57. package/dist/types/index.js +2 -0
  58. package/dist/types/run-context.d.ts +11 -2
  59. package/dist/types/skills.d.ts +19 -0
  60. package/dist/types/skills.js +1 -0
  61. package/guides/AGENTS.md +2 -3
  62. package/guides/FLOWS.md +2 -2
  63. package/guides/TOOLS.md +69 -2
  64. package/package.json +12 -3
@@ -1,4 +1,4 @@
1
- import type { LanguageModel, ToolSet } from 'ai';
1
+ import type { LanguageModel } from 'ai';
2
2
  import type { AgentPrompt } from '../prompts/AgentPrompt.js';
3
3
  import type { Flow } from './flow.js';
4
4
  import type { Route, RoutingPolicy } from './route.js';
@@ -7,6 +7,12 @@ import type { AgentKnowledge, AgentMemory } from './grounding.js';
7
7
  import type { RefinementCapability } from '../capabilities/RefinementCapability.js';
8
8
  import type { ValidationCapability } from '../capabilities/ValidationCapability.js';
9
9
  import type { AnyTool } from './effectTool.js';
10
+ import type { FileSystem } from './filesystem.js';
11
+ import type { SkillSource } from './skills.js';
12
+ export type AgentWorkspaceConfig = FileSystem | {
13
+ fs: FileSystem;
14
+ readOnly?: boolean;
15
+ };
10
16
  export type Instructions = string | AgentPrompt | ((ctx: {
11
17
  state: Record<string, unknown>;
12
18
  }) => Instructions | Promise<Instructions>);
@@ -20,8 +26,8 @@ export interface AgentConfig {
20
26
  * temperature 0 for determinism. Defaults to `model` (the speaker) when unset.
21
27
  * Set this to pin control to a reliable provider independent of the speaker. */
22
28
  controlModel?: LanguageModel;
23
- tools?: ToolSet;
24
- effectTools?: Record<string, AnyTool>;
29
+ /** Durable, model-callable effect tools (exactly-once on replay). Wrap raw AI SDK tools with wrapAiSdkTool(). */
30
+ tools?: Record<string, AnyTool>;
25
31
  /** Safe, always-available tools made model-visible in EVERY speaking node turn
26
32
  * (the agent "base layer", ADR 0001) — e.g. a returns/FAQ knowledge-base
27
33
  * lookup the user might ask for mid-flow. This is an explicit allow-list:
@@ -45,5 +51,12 @@ export interface AgentConfig {
45
51
  /** Flow reply nodes: silo flow-transition control tools + deterministic evaluator (ADR 0003 H1). Default OFF. */
46
52
  outOfBandControl?: boolean;
47
53
  };
54
+ /** Portable workspace filesystem; auto-registers the durable `workspace` tool when set.
55
+ * Defaults to read-only; pass `{ fs, readOnly: false }` for write/edit. Read-only workspaces
56
+ * are exposed in globalTools (ADR 0001); read-write ones are executor-only. */
57
+ workspace?: AgentWorkspaceConfig;
58
+ /** Bundled procedural skills (Anthropic Agent Skill model): Level-1 name+description in prompt,
59
+ * body via `load_skill`, resources via `read_skill_resource`. Scripts = `allowedTools` only. */
60
+ skills?: SkillSource;
48
61
  }
49
62
  export declare function defineAgent(config: AgentConfig): AgentConfig;
@@ -0,0 +1,85 @@
1
+ export type FileSystemEntryType = 'file' | 'directory' | 'symlink';
2
+ export type BufferEncoding = 'utf8' | 'utf-8' | 'ascii' | 'binary' | 'base64' | 'hex' | 'latin1';
3
+ export type FileContent = string | Uint8Array;
4
+ export interface FsStat {
5
+ type: FileSystemEntryType;
6
+ size: number;
7
+ mtime: Date;
8
+ mode?: number;
9
+ }
10
+ export interface FileSystemDirent {
11
+ name: string;
12
+ type: FileSystemEntryType;
13
+ }
14
+ export interface MkdirOptions {
15
+ recursive?: boolean;
16
+ }
17
+ export interface RmOptions {
18
+ recursive?: boolean;
19
+ force?: boolean;
20
+ }
21
+ export interface CpOptions {
22
+ recursive?: boolean;
23
+ }
24
+ export interface FileSystem {
25
+ readFile(path: string): Promise<string>;
26
+ readFileBytes(path: string): Promise<Uint8Array>;
27
+ writeFile(path: string, content: string): Promise<void>;
28
+ writeFileBytes(path: string, content: Uint8Array): Promise<void>;
29
+ appendFile(path: string, content: string | Uint8Array): Promise<void>;
30
+ exists(path: string): Promise<boolean>;
31
+ stat(path: string): Promise<FsStat>;
32
+ lstat(path: string): Promise<FsStat>;
33
+ mkdir(path: string, options?: MkdirOptions): Promise<void>;
34
+ readdir(path: string): Promise<string[]>;
35
+ readdirWithFileTypes(path: string): Promise<FileSystemDirent[]>;
36
+ rm(path: string, options?: RmOptions): Promise<void>;
37
+ cp(src: string, dest: string, options?: CpOptions): Promise<void>;
38
+ mv(src: string, dest: string): Promise<void>;
39
+ symlink(target: string, linkPath: string): Promise<void>;
40
+ readlink(path: string): Promise<string>;
41
+ realpath(path: string): Promise<string>;
42
+ resolvePath(base: string, path: string): string;
43
+ glob(pattern: string): Promise<string[]>;
44
+ }
45
+ export interface ReadFileOptions {
46
+ encoding?: BufferEncoding | null;
47
+ }
48
+ export interface WriteFileOptions {
49
+ encoding?: BufferEncoding;
50
+ }
51
+ export interface FileEntry {
52
+ type: 'file';
53
+ content: string | Uint8Array;
54
+ mode: number;
55
+ mtime: Date;
56
+ }
57
+ export interface DirectoryEntry {
58
+ type: 'directory';
59
+ mode: number;
60
+ mtime: Date;
61
+ }
62
+ export interface SymlinkEntry {
63
+ type: 'symlink';
64
+ target: string;
65
+ mode: number;
66
+ mtime: Date;
67
+ }
68
+ export interface LazyFileEntry {
69
+ type: 'file';
70
+ lazy: () => string | Uint8Array | Promise<string | Uint8Array>;
71
+ mode: number;
72
+ mtime: Date;
73
+ }
74
+ export type FsEntry = FileEntry | LazyFileEntry | DirectoryEntry | SymlinkEntry;
75
+ export interface FileInit {
76
+ content: FileContent;
77
+ mode?: number;
78
+ mtime?: Date;
79
+ }
80
+ export type LazyFileProvider = () => string | Uint8Array | Promise<string | Uint8Array>;
81
+ export type InitialFiles = Record<string, FileContent | FileInit | LazyFileProvider>;
82
+ export interface FsError extends Error {
83
+ code?: string;
84
+ }
85
+ export declare function fsErrorCode(err: unknown): string | undefined;
@@ -0,0 +1,6 @@
1
+ export function fsErrorCode(err) {
2
+ if (!(err instanceof Error))
3
+ return undefined;
4
+ const match = err.message.match(/^([A-Z]+):/);
5
+ return match?.[1];
6
+ }
@@ -1,7 +1,17 @@
1
+ import type { MemoryBlockScope, PersistentMemoryConfig } from '../memory/blocks/types.js';
1
2
  export interface AgentKnowledge {
2
3
  autoRetrieve?: boolean;
3
4
  sources?: string[];
4
5
  }
6
+ export interface WorkingMemoryBlockSpec {
7
+ scope: MemoryBlockScope;
8
+ key: string;
9
+ /** Seed content when the block is missing or empty (persisted on first write, not on read). */
10
+ template?: string;
11
+ }
12
+ export interface WorkingMemoryConfig extends Omit<PersistentMemoryConfig, 'autoLoad'> {
13
+ autoLoad?: WorkingMemoryBlockSpec[];
14
+ }
5
15
  export interface AgentMemory {
6
16
  preload?: {
7
17
  enabled?: boolean;
@@ -10,4 +20,6 @@ export interface AgentMemory {
10
20
  ingest?: {
11
21
  enabled?: boolean;
12
22
  };
23
+ /** Persistent markdown blocks (USER/MEMORY) loaded at session start and editable via memory_block. */
24
+ workingMemory?: WorkingMemoryConfig;
13
25
  }
@@ -2,6 +2,8 @@ export * from './selection.js';
2
2
  export * from './telemetry.js';
3
3
  export * from './processors.js';
4
4
  export * from './agentConfig.js';
5
+ export * from './filesystem.js';
6
+ export * from './skills.js';
5
7
  export * from './flow.js';
6
8
  export * from './session.js';
7
9
  export * from './tool.js';
@@ -2,6 +2,8 @@ export * from './selection.js';
2
2
  export * from './telemetry.js';
3
3
  export * from './processors.js';
4
4
  export * from './agentConfig.js';
5
+ export * from './filesystem.js';
6
+ export * from './skills.js';
5
7
  export * from './flow.js';
6
8
  export * from './session.js';
7
9
  export * from './tool.js';
@@ -8,6 +8,7 @@ import type { RefinementCapability } from '../capabilities/RefinementCapability.
8
8
  import type { ValidationCapability } from '../capabilities/ValidationCapability.js';
9
9
  import type { Limits } from './guardrails.js';
10
10
  import type { AnyTool } from './effectTool.js';
11
+ import type { FileSystem } from './filesystem.js';
11
12
  import type { Instructions } from './agentConfig.js';
12
13
  import type { AgentKnowledgeOverrides, SourceRef } from './voice.js';
13
14
  export interface GatherScope {
@@ -85,6 +86,14 @@ export interface RunContext {
85
86
  * in every speaking turn. */
86
87
  baseInstructions?: Instructions;
87
88
  globalTools?: Record<string, AnyTool>;
89
+ /** Level-1 skill metadata injected by `SkillsCapability` when `AgentConfig.skills` is set. */
90
+ skillPrompt?: string;
91
+ /** Frozen persistent memory blocks loaded at session start (`AgentMemory.workingMemory`). */
92
+ workingMemoryPrompt?: string;
93
+ /** Model-visible tools from working memory wiring (not in globalTools — mutating but scoped). */
94
+ workingMemoryTools?: Record<string, AnyTool>;
95
+ /** Agent workspace filesystem (same instance as `AgentConfig.workspace`). */
96
+ fs?: FileSystem;
88
97
  tool(name: string, args: unknown, options?: {
89
98
  toolCallId?: string;
90
99
  def?: AnyTool;
@@ -104,6 +113,6 @@ export interface RunContext {
104
113
  now(): Promise<number>;
105
114
  uuid(): Promise<string>;
106
115
  }
107
- export type ActionContext = Pick<RunContext, 'tool' | 'approve' | 'signal' | 'now' | 'uuid' | 'emit'>;
108
- export type ToolContext = Pick<RunContext, 'session' | 'runState' | 'tool' | 'now' | 'uuid' | 'emit'>;
116
+ export type ActionContext = Pick<RunContext, 'tool' | 'approve' | 'signal' | 'now' | 'uuid' | 'emit' | 'fs'>;
117
+ export type ToolContext = Pick<RunContext, 'session' | 'runState' | 'tool' | 'now' | 'uuid' | 'emit' | 'fs'>;
109
118
  export type { ModelMessage };
@@ -0,0 +1,19 @@
1
+ export interface SkillMeta {
2
+ name: string;
3
+ description: string;
4
+ }
5
+ export interface SkillLike {
6
+ name: string;
7
+ description: string;
8
+ body: string;
9
+ resources?: Record<string, string | Uint8Array>;
10
+ allowedTools?: string[];
11
+ }
12
+ export interface SkillStoreLike {
13
+ list(): Promise<SkillMeta[]>;
14
+ loadBody(name: string): Promise<string>;
15
+ loadResource(name: string, path: string): Promise<string | Uint8Array>;
16
+ getAllSkills?(): SkillLike[] | Promise<SkillLike[]>;
17
+ loadAllSkills?(): Promise<SkillLike[]>;
18
+ }
19
+ export type SkillSource = SkillLike | SkillLike[] | SkillStoreLike;
@@ -0,0 +1 @@
1
+ export {};
package/guides/AGENTS.md CHANGED
@@ -16,7 +16,7 @@ const model = openai('gpt-4o-mini');
16
16
  | Fields | Effect |
17
17
  |--------|--------|
18
18
  | `id`, `model`, `instructions` | Base conversational agent |
19
- | `tools`, `effectTools` | Tool access during free conversation and flow nodes |
19
+ | `tools`, `globalTools` | Durable tool access during free conversation and flow nodes |
20
20
  | `flows` | Structured multi-step SOPs (`defineFlow` + node builders) |
21
21
  | `routes`, `routing` | Route to flows or specialist agents |
22
22
  | `agents` | Nested sub-agent configs for composition |
@@ -210,8 +210,7 @@ const lead = defineAgent({
210
210
  instructions:
211
211
  'Research assistant. Use consult_weather for weather and consult_news for news. Combine answers clearly.',
212
212
  model,
213
- tools: buildToolSet(tools),
214
- effectTools: tools,
213
+ tools: tools,
215
214
  });
216
215
 
217
216
  const runtime = createRuntime({
package/guides/FLOWS.md CHANGED
@@ -29,7 +29,7 @@ const collectDate = defineTool({
29
29
  const greeting = reply({
30
30
  id: 'greeting',
31
31
  instructions: 'Welcome. What date would you like to book?',
32
- tools: { collect_date: collectDate }, // wire via effectTools + ToolSet in production
32
+ tools: { collect_date: collectDate }, // wire via tools + ToolSet in production
33
33
  next: (turn) => {
34
34
  const r = turn.toolResults.find((t) => t.name === 'collect_date');
35
35
  return r?.result ? { goto: confirm, data: r.result as Record<string, unknown> } : 'stay';
@@ -46,7 +46,7 @@ const agent = defineAgent({
46
46
  id: 'booking',
47
47
  instructions: 'You are a booking assistant.',
48
48
  model,
49
- effectTools: { collect_date: collectDate },
49
+ tools: { collect_date: collectDate },
50
50
  flows: [
51
51
  defineFlow({
52
52
  name: 'booking',
package/guides/TOOLS.md CHANGED
@@ -2,6 +2,74 @@
2
2
 
3
3
  Kuralle tools use the Vercel AI SDK `tool(...)` API. Tools are how agents read data, write state, and trigger flow transitions.
4
4
 
5
+ ## Durable agent tools
6
+
7
+ Agent-level `tools` is a `Record<string, AnyTool>` from `defineTool` — every call is journaled (exactly-once on replay). Flow nodes use `buildToolSet({ ... })` for model-visible schema; executors come from the agent registry and flow-local tools.
8
+
9
+ For third-party AI SDK tools, use `wrapAiSdkTool(name, aiTool)` — it captures `execute` and routes through the same journal:
10
+
11
+ ```ts
12
+ import { defineTool, wrapAiSdkTool } from '@kuralle-agents/core';
13
+ import { tool } from 'ai';
14
+
15
+ const native = defineTool({ name: 'lookup', description: '...', input: z.object({ id: z.string() }), execute: async ({ id }) => ({ id }) });
16
+
17
+ const sdk = tool({ description: 'Legacy SDK tool', inputSchema: z.object({ id: z.string() }), execute: async ({ id }) => ({ id }) });
18
+
19
+ const agent = defineAgent({
20
+ id: 'a',
21
+ model,
22
+ tools: { lookup: native, legacy: wrapAiSdkTool('legacy', sdk) },
23
+ });
24
+ ```
25
+
26
+ ## Agent workspace
27
+
28
+ Set `workspace` to a portable `FileSystem` (from `@kuralle-agents/fs`) to auto-register the durable `workspace` tool (`ls`, `cat`, `grep`, `find`, `read`, `write`, `edit`). The same instance is exposed on `RunContext.fs` for flow `action` nodes.
29
+
30
+ **Read-only by default** (ADR 0006): a bare `FileSystem` is mounted read-only and exposed in `globalTools` (safe for every speaking turn). Pass `{ fs, readOnly: false }` for a writable scratchpad — the executor is registered, but the tool is **not** auto-added to `globalTools` (mutating tools stay flow-gated).
31
+
32
+ ```ts
33
+ import { InMemoryFs } from '@kuralle-agents/fs';
34
+
35
+ const agent = defineAgent({
36
+ id: 'kb',
37
+ model,
38
+ workspace: new InMemoryFs({ '/docs/faq.md': '# FAQ' }),
39
+ });
40
+
41
+ // Writable scratchpad (not in globalTools):
42
+ // workspace: { fs: new InMemoryFs({ '/scratch': '' }), readOnly: false },
43
+ ```
44
+
45
+ Requires `@kuralle-agents/fs` when using `workspace`.
46
+
47
+ ## Working memory blocks
48
+
49
+ Cross-session markdown blocks (`USER`, `MEMORY`, …) via `agent.memory.workingMemory`. Blocks load at session start, inject into the system prompt, and are editable with the auto-registered `memory_block` tool.
50
+
51
+ ```ts
52
+ import { defineAgent, FilePersistentMemoryStore } from '@kuralle-agents/core';
53
+
54
+ const agent = defineAgent({
55
+ id: 'support',
56
+ model,
57
+ memory: {
58
+ workingMemory: {
59
+ store: new FilePersistentMemoryStore(),
60
+ autoLoad: [
61
+ { scope: 'user', key: 'USER', template: 'name:\npreferences:' },
62
+ { scope: 'agent', key: 'MEMORY' },
63
+ ],
64
+ },
65
+ },
66
+ });
67
+ ```
68
+
69
+ On Workers, pass an explicit `store` (or `HarnessConfig.defaultWorkingMemoryStore`). Semantic recall (`preload` / `ingest`) is unchanged — working memory is an additional axis.
70
+
71
+ See [examples/agents/working-memory.ts](../examples/agents/working-memory.ts) for a live cross-session demo.
72
+
5
73
  ## Tool Basics
6
74
 
7
75
  ```ts
@@ -70,8 +138,7 @@ const lead = defineAgent({
70
138
  instructions:
71
139
  'Research assistant. Use consult_weather for weather questions. Combine answers clearly.',
72
140
  model,
73
- tools: buildToolSet({ consult_weather: consultWeather }),
74
- effectTools: { consult_weather: consultWeather },
141
+ tools: { consult_weather: consultWeather },
75
142
  });
76
143
 
77
144
  const runtime = createRuntime({
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "git+https://github.com/kuralle/kuralle-agents.git",
7
7
  "directory": "packages/kuralle-core"
8
8
  },
9
- "version": "0.5.0",
9
+ "version": "0.6.0",
10
10
  "description": "A framework for structured conversational AI agents",
11
11
  "publishConfig": {
12
12
  "access": "public"
@@ -72,6 +72,10 @@
72
72
  "types": "./dist/memory/index.d.ts",
73
73
  "default": "./dist/memory/index.js"
74
74
  },
75
+ "./memory/testing": {
76
+ "types": "./dist/memory/blocks/testing.d.ts",
77
+ "default": "./dist/memory/blocks/testing.js"
78
+ },
75
79
  "./foundation": {
76
80
  "types": "./dist/foundation/index.d.ts",
77
81
  "default": "./dist/foundation/index.js"
@@ -90,14 +94,16 @@
90
94
  "zod": "^3.0.0"
91
95
  },
92
96
  "devDependencies": {
97
+ "@cloudflare/vitest-pool-workers": "^0.12.7",
93
98
  "@ai-sdk/openai": "^3.0.0",
94
99
  "@types/node": "^20.11.0",
95
100
  "ai": "^6.0.0",
96
101
  "bun-types": "^1.3.0",
97
102
  "dotenv": "^16.4.0",
98
103
  "typescript": "^5.3.0",
104
+ "vitest": "^3.2.4",
99
105
  "zod": "^3.23.0",
100
- "@kuralle-agents/realtime-audio": "0.5.0"
106
+ "@kuralle-agents/realtime-audio": "0.6.0"
101
107
  },
102
108
  "dependencies": {
103
109
  "chrono-node": "^2.6.0",
@@ -108,7 +114,10 @@
108
114
  "build": "tsc -p tsconfig.json",
109
115
  "typecheck:examples": "tsc --noEmit -p tsconfig.examples.json",
110
116
  "clean": "rm -rf dist",
111
- "test": "bun test test",
117
+ "test": "bun test ./test && vitest run --config vitest.config.ts",
118
+ "test:journal-key-workers": "vitest run --config vitest.config.ts",
119
+ "test:workspace-autoregister": "bun test ./test/core-workspace/workspace-autoregister.test.ts",
120
+ "test:skill-wire": "bun test ./test/core-skills/skill-wire.test.ts",
112
121
  "smoke:textdriver": "bun test ./test/core-channel/textdriver.smoke.ts",
113
122
  "smoke:flow": "bun test ./test/core-flow/flow.smoke.ts",
114
123
  "smoke:agent": "bun test ./test/core-agent/agent.smoke.ts",