coding-agent-forge 0.1.1 → 1.0.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 (73) hide show
  1. package/README.md +130 -11
  2. package/agent-forge.yaml +19 -0
  3. package/dist/agent/agent.d.ts +11 -0
  4. package/dist/agent/agent.d.ts.map +1 -0
  5. package/dist/agent/agent.js +13 -0
  6. package/dist/agent/agent.js.map +1 -0
  7. package/dist/agent/config.d.ts +15 -0
  8. package/dist/agent/config.d.ts.map +1 -0
  9. package/dist/agent/config.js +49 -0
  10. package/dist/agent/config.js.map +1 -0
  11. package/dist/agent/factories.d.ts +5 -0
  12. package/dist/agent/factories.d.ts.map +1 -0
  13. package/dist/agent/factories.js +5 -0
  14. package/dist/agent/factories.js.map +1 -0
  15. package/dist/agent/index.d.ts +10 -0
  16. package/dist/agent/index.d.ts.map +1 -0
  17. package/dist/agent/index.js +6 -0
  18. package/dist/agent/index.js.map +1 -0
  19. package/dist/agent/team.d.ts +19 -0
  20. package/dist/agent/team.d.ts.map +1 -0
  21. package/dist/agent/team.js +81 -0
  22. package/dist/agent/team.js.map +1 -0
  23. package/dist/agent/template.d.ts +12 -0
  24. package/dist/agent/template.d.ts.map +1 -0
  25. package/dist/agent/template.js +37 -0
  26. package/dist/agent/template.js.map +1 -0
  27. package/dist/cli.js +35 -21
  28. package/dist/cli.js.map +1 -1
  29. package/dist/config.d.ts +6 -0
  30. package/dist/config.d.ts.map +1 -0
  31. package/dist/config.js +22 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/index.d.ts +3 -8
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +3 -6
  36. package/dist/index.js.map +1 -1
  37. package/dist/runtime/claude.d.ts +3 -1
  38. package/dist/runtime/claude.d.ts.map +1 -1
  39. package/dist/runtime/claude.js +9 -8
  40. package/dist/runtime/claude.js.map +1 -1
  41. package/dist/runtime/codex.d.ts +1 -1
  42. package/dist/runtime/codex.d.ts.map +1 -1
  43. package/dist/runtime/codex.js +4 -15
  44. package/dist/runtime/codex.js.map +1 -1
  45. package/dist/runtime/config.d.ts +19 -12
  46. package/dist/runtime/config.d.ts.map +1 -1
  47. package/dist/runtime/config.js +55 -45
  48. package/dist/runtime/config.js.map +1 -1
  49. package/dist/runtime/format.d.ts +4 -0
  50. package/dist/runtime/format.d.ts.map +1 -0
  51. package/dist/runtime/format.js +16 -0
  52. package/dist/runtime/format.js.map +1 -0
  53. package/dist/runtime/index.d.ts +4 -4
  54. package/dist/runtime/index.d.ts.map +1 -1
  55. package/dist/runtime/index.js +2 -19
  56. package/dist/runtime/index.js.map +1 -1
  57. package/dist/runtime/opencode.d.ts +1 -1
  58. package/dist/runtime/opencode.d.ts.map +1 -1
  59. package/dist/runtime/opencode.js +4 -8
  60. package/dist/runtime/opencode.js.map +1 -1
  61. package/dist/runtime/qwen.d.ts +4 -3
  62. package/dist/runtime/qwen.d.ts.map +1 -1
  63. package/dist/runtime/qwen.js +11 -8
  64. package/dist/runtime/qwen.js.map +1 -1
  65. package/dist/runtime/types.d.ts +46 -36
  66. package/dist/runtime/types.d.ts.map +1 -1
  67. package/dist/runtime/types.js +10 -0
  68. package/dist/runtime/types.js.map +1 -1
  69. package/dist/utils/object.d.ts +4 -0
  70. package/dist/utils/object.d.ts.map +1 -0
  71. package/dist/utils/object.js +17 -0
  72. package/dist/utils/object.js.map +1 -0
  73. package/package.json +10 -2
package/README.md CHANGED
@@ -11,11 +11,15 @@ SDK.
11
11
  - `qwen`: wraps `@qwen-code/sdk`
12
12
  - `opencode`: wraps `@opencode-ai/sdk`
13
13
 
14
- The workflow layer gets records with a `runtime` marker added:
14
+ The workflow layer gets `RuntimeRecord` values with a `runtime` marker added:
15
15
  `{ runtime: "codex", input }`, `{ runtime: "codex", event }`,
16
16
  `{ runtime: "claude", message }`, `{ runtime: "qwen", message }`,
17
17
  `{ runtime: "opencode", request }`, or `{ runtime: "opencode", event }`.
18
18
 
19
+ On top of runtimes and threads, the `agent` layer lets each agent accept prompt
20
+ variables, combine them with static prompt constants, build a prompt internally,
21
+ and pass that prompt to the underlying thread.
22
+
19
23
  ## Install
20
24
 
21
25
  ```bash
@@ -46,40 +50,155 @@ threads:
46
50
  options:
47
51
  model: gpt-5.4
48
52
  workingDirectory: .
53
+
54
+ agents:
55
+ reviewer:
56
+ kind: prompt-template
57
+ thread: runner
58
+ constants:
59
+ template: |
60
+ Review this task in {{ language }}.
61
+
62
+ {{ prompt }}
63
+ language: Chinese
64
+ ```
65
+
66
+ For `claude` and `qwen` runtimes, `runtime.options` uses the same shape as
67
+ `thread.options`. These options are not SDK client or server initialization
68
+ parameters; they are default query options for every thread started from that
69
+ runtime. A thread's own `options` are merged over the runtime defaults.
70
+
71
+ ```yaml
72
+ runtimes:
73
+ claude-main:
74
+ kind: claude
75
+ options:
76
+ model: claude-sonnet-4-5
77
+ permissionMode: acceptEdits
78
+
79
+ threads:
80
+ review:
81
+ runtime: claude-main
82
+ options:
83
+ maxTurns: 10
49
84
  ```
50
85
 
86
+ In this example, the `review` thread runs with `model`, `permissionMode`, and
87
+ `maxTurns`; if both levels define the same option, the thread-level value wins.
88
+
51
89
  Put private provider credentials in `secret.yaml` and pass it after the base
52
90
  config so it can override sensitive fields locally.
53
91
 
54
92
  ## Library usage
55
93
 
56
94
  ```ts
57
- import { createRuntime, loadConfig, startThread } from "coding-agent-forge";
95
+ import { loadConfig } from "coding-agent-forge";
96
+ import { Agent } from "coding-agent-forge/agent";
97
+ import { createRuntime, startThread } from "coding-agent-forge/runtime";
98
+
99
+ type ReviewVariables = {
100
+ task: string;
101
+ focus: string;
102
+ };
103
+
104
+ type ReviewConstants = {
105
+ language: string;
106
+ prefix: string;
107
+ };
108
+
109
+ class ReviewAgent extends Agent<ReviewVariables, ReviewConstants> {
110
+ protected buildPrompt(
111
+ variables: Readonly<ReviewVariables>,
112
+ constants: Readonly<ReviewConstants>,
113
+ ): string {
114
+ return `${constants.prefix}\nLanguage: ${constants.language}\n${variables.task}\n\nFocus: ${variables.focus}`;
115
+ }
116
+ }
58
117
 
59
118
  const config = await loadConfig("agent-forge.yaml");
60
119
  const threadDefinition = config.threads.runner;
120
+ if (!threadDefinition) {
121
+ throw new Error("Unknown thread: runner");
122
+ }
61
123
  const runtimeDefinition = config.runtimes[threadDefinition.runtime];
124
+ if (!runtimeDefinition) {
125
+ throw new Error(`Unknown runtime: ${threadDefinition.runtime}`);
126
+ }
62
127
  const runtime = createRuntime(runtimeDefinition);
63
- const thread = await startThread(runtime, threadDefinition);
128
+ const thread = await startThread(runtime, threadDefinition.options);
129
+ const agent = new ReviewAgent(thread, {
130
+ language: "Chinese",
131
+ prefix: "Review this task.",
132
+ });
64
133
 
65
- const finalResponse = await thread.runStreamed("Inspect this repo.", (event) => {
66
- console.log(event);
134
+ const finalResponse = await agent.runStreamed({
135
+ task: "Inspect this repo.",
136
+ focus: "Public APIs.",
67
137
  });
68
138
 
69
139
  console.log(finalResponse);
70
140
  await runtime.close();
71
141
  ```
72
142
 
143
+ Custom agents extend `Agent` and implement `buildPrompt`. Per-call `variables`
144
+ and constructor-time `constants` are both string-valued objects, but they represent
145
+ different data and are typed separately.
146
+
147
+ `AgentVariablesByName` is a caller-provided type witness for the variables each
148
+ registered agent accepts. Keep it aligned with the factories you register and
149
+ the agents in your config.
150
+
151
+ `PromptTemplateAgent` is the default agent implementation. It expects a
152
+ `template` constant and formats `{{ variable }}` placeholders using constants
153
+ merged with the variables passed to `runStreamed`. Per-call variables override
154
+ same-named constants.
155
+
156
+ `AgentTeam` receives an `AgentFactoryMap` keyed by agent `kind`. Each factory gets
157
+ the agent name, thread, and constants, then decides which concrete `Agent` to
158
+ return. Validate constants inside the factory when an agent requires specific
159
+ constant keys.
160
+
161
+ For TypeScript-authored configuration, use `defineConfig` to keep thread options
162
+ bound to the runtime kind selected by each named runtime. Agent thread names are
163
+ checked against the configured threads.
164
+
165
+ ```ts
166
+ import { defineConfig } from "coding-agent-forge";
167
+
168
+ export default defineConfig({
169
+ runtimes: {
170
+ runner: { kind: "codex" },
171
+ },
172
+ threads: {
173
+ main: {
174
+ runtime: "runner",
175
+ options: { model: "gpt-5.3-codex" },
176
+ },
177
+ },
178
+ agents: {
179
+ reviewer: {
180
+ kind: "prompt-template",
181
+ thread: "main",
182
+ constants: {
183
+ template: "Review this task in {{ language }}.\n\n{{ prompt }}",
184
+ language: "Chinese",
185
+ },
186
+ },
187
+ },
188
+ });
189
+ ```
190
+
73
191
  ## CLI
74
192
 
75
193
  ```bash
76
- npm run dev -- --config agent-forge.yaml --config secret.yaml --thread codex-runner "Inspect this repo" "What did you just do? Is this a new conversation?"
194
+ npm run dev -- --config agent-forge.yaml --config secret.yaml --agent codex-agent "{ prompt: Inspect this repo }" "{ prompt: What did you just do? Is this a new conversation? }"
77
195
  ```
78
196
 
79
197
  Pass multiple `--config` files to merge them in order; object fields in later
80
- files are merged into earlier files. Omit `--thread` to run the first thread in
81
- the merged config. Pass multiple quoted prompts to run a multi-turn conversation
82
- on the same thread.
198
+ files are merged into earlier files. Omit `--agent` to run the first agent in
199
+ the merged config. Each positional argument is parsed as a YAML object whose
200
+ values must be strings. Pass multiple YAML objects to run multiple turns on the
201
+ same agent thread.
83
202
 
84
- The CLI prints one JSON event per line, followed by the final response text for
85
- each prompt.
203
+ The CLI prints runtime records to stderr and writes each final response to
204
+ stdout.
package/agent-forge.yaml CHANGED
@@ -50,3 +50,22 @@ threads:
50
50
  OPENAI_BASE_URL: https://api.deepseek.com
51
51
  OPENAI_MODEL: deepseek-reasoner
52
52
  OPENAI_REASONING_EFFORT: high
53
+
54
+ agents:
55
+ codex-agent:
56
+ kind: prompt-template
57
+ thread: codex-runner
58
+ constants:
59
+ template: "{{ prompt }}"
60
+
61
+ opencode-agent:
62
+ kind: prompt-template
63
+ thread: opencode-runner
64
+ constants:
65
+ template: "{{ prompt }}"
66
+
67
+ qwen-agent:
68
+ kind: prompt-template
69
+ thread: qwen-runner
70
+ constants:
71
+ template: "{{ prompt }}"
@@ -0,0 +1,11 @@
1
+ import type { RecordCallback, Thread } from "../runtime/index.js";
2
+ export type PromptConstants = Record<string, string>;
3
+ export type PromptVariables = Record<string, string>;
4
+ export declare abstract class Agent<Variables extends PromptVariables = PromptVariables, Constants extends PromptConstants = PromptConstants> {
5
+ #private;
6
+ protected readonly thread: Thread;
7
+ constructor(thread: Thread, constants: Readonly<Constants>);
8
+ protected abstract buildPrompt(variables: Readonly<Variables>, constants: Readonly<Constants>): string;
9
+ runStreamed(variables: Variables, onRecord?: RecordCallback): Promise<string>;
10
+ }
11
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/agent/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErD,8BAAsB,KAAK,CACzB,SAAS,SAAS,eAAe,GAAG,eAAe,EACnD,SAAS,SAAS,eAAe,GAAG,eAAe;;IAKjD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EACjC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC;IAKhC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAC5B,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC9B,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,GAC7B,MAAM;IAET,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;CAI9E"}
@@ -0,0 +1,13 @@
1
+ export class Agent {
2
+ thread;
3
+ #constants;
4
+ constructor(thread, constants) {
5
+ this.thread = thread;
6
+ this.#constants = Object.freeze({ ...constants });
7
+ }
8
+ runStreamed(variables, onRecord) {
9
+ const prompt = this.buildPrompt(variables, this.#constants);
10
+ return this.thread.runStreamed(prompt, onRecord);
11
+ }
12
+ }
13
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/agent/agent.ts"],"names":[],"mappings":"AAKA,MAAM,OAAgB,KAAK;IAOJ;IAHZ,UAAU,CAAsB;IAEzC,YACqB,MAAc,EACjC,SAA8B;QADX,WAAM,GAAN,MAAM,CAAQ;QAGjC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;IACpD,CAAC;IAOD,WAAW,CAAC,SAAoB,EAAE,QAAyB;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import type { RuntimeDefinitions, RuntimeThreadConfig, ThreadDefinitions } from "../runtime/config.js";
2
+ import { type PlainObject } from "../utils/object.js";
3
+ import type { PromptConstants } from "./agent.js";
4
+ export type AgentDefinition<Constants extends PromptConstants = PromptConstants, ThreadName extends string = string, Kind extends string = string> = {
5
+ kind: Kind;
6
+ thread: ThreadName;
7
+ constants?: Constants;
8
+ };
9
+ export type AgentDefinitions<ThreadName extends string = string> = Record<string, AgentDefinition<PromptConstants, ThreadName>>;
10
+ export declare function loadAgentDefinitions(value: object, threads: Record<string, unknown>): AgentDefinitions;
11
+ export type RuntimeThreadAgentConfig<Runtimes extends RuntimeDefinitions = RuntimeDefinitions, Threads extends ThreadDefinitions<Runtimes> = ThreadDefinitions<Runtimes>, Agents extends AgentDefinitions<keyof Threads & string> = AgentDefinitions<keyof Threads & string>> = RuntimeThreadConfig<Runtimes, Threads> & {
12
+ agents: Agents;
13
+ };
14
+ export declare function loadRuntimeThreadAgentConfig(config: PlainObject): RuntimeThreadAgentConfig;
15
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/agent/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,eAAe,CACzB,SAAS,SAAS,eAAe,GAAG,eAAe,EACnD,UAAU,SAAS,MAAM,GAAG,MAAM,EAClC,IAAI,SAAS,MAAM,GAAG,MAAM,IAC1B;IACF,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,UAAU,SAAS,MAAM,GAAG,MAAM,IAAI,MAAM,CACvE,MAAM,EACN,eAAe,CAAC,eAAe,EAAE,UAAU,CAAC,CAC7C,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,gBAAgB,CA0ClB;AAED,MAAM,MAAM,wBAAwB,CAClC,QAAQ,SAAS,kBAAkB,GAAG,kBAAkB,EACxD,OAAO,SAAS,iBAAiB,CAAC,QAAQ,CAAC,GAAG,iBAAiB,CAAC,QAAQ,CAAC,EACzE,MAAM,SAAS,gBAAgB,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,gBAAgB,CACxE,MAAM,OAAO,GAAG,MAAM,CACvB,IACC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG;IAC3C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,WAAW,GAAG,wBAAwB,CAS1F"}
@@ -0,0 +1,49 @@
1
+ import { loadRuntimeThreadConfig } from "../runtime/config.js";
2
+ import { isPlainObject } from "../utils/object.js";
3
+ export function loadAgentDefinitions(value, threads) {
4
+ if (Object.keys(value).length === 0) {
5
+ throw new Error("Config must define at least one agent");
6
+ }
7
+ const agents = {};
8
+ for (const [name, agent] of Object.entries(value)) {
9
+ if (!isPlainObject(agent)) {
10
+ throw new Error(`Agent ${name} must be an object`);
11
+ }
12
+ if (typeof agent.kind !== "string") {
13
+ throw new Error(`Agent ${name} must define a kind`);
14
+ }
15
+ if (typeof agent.thread !== "string") {
16
+ throw new Error(`Agent ${name} must define a thread`);
17
+ }
18
+ if (!Object.hasOwn(threads, agent.thread)) {
19
+ throw new Error(`Unknown thread for agent ${name}: ${agent.thread}`);
20
+ }
21
+ let constants;
22
+ if (agent.constants !== undefined) {
23
+ if (!isPlainObject(agent.constants)) {
24
+ throw new Error(`Agent ${name} constants must be an object`);
25
+ }
26
+ constants = {};
27
+ for (const [entryKey, entryValue] of Object.entries(agent.constants)) {
28
+ if (typeof entryValue !== "string") {
29
+ throw new Error(`Agent ${name} constants.${entryKey} must be a string`);
30
+ }
31
+ constants[entryKey] = entryValue;
32
+ }
33
+ }
34
+ agents[name] =
35
+ constants === undefined
36
+ ? { kind: agent.kind, thread: agent.thread }
37
+ : { kind: agent.kind, thread: agent.thread, constants };
38
+ }
39
+ return agents;
40
+ }
41
+ export function loadRuntimeThreadAgentConfig(config) {
42
+ if (!isPlainObject(config.agents)) {
43
+ throw new Error("Config must define an agents object");
44
+ }
45
+ const { runtimes, threads } = loadRuntimeThreadConfig(config);
46
+ const agents = loadAgentDefinitions(config.agents, threads);
47
+ return { runtimes, threads, agents };
48
+ }
49
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/agent/config.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAoB,MAAM,oBAAoB,CAAC;AAkBrE,MAAM,UAAU,oBAAoB,CAClC,KAAa,EACb,OAAgC;IAEhC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,oBAAoB,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,qBAAqB,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,uBAAuB,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,SAAsC,CAAC;QAC3C,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAClC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,8BAA8B,CAAC,CAAC;YAC/D,CAAC;YAED,SAAS,GAAG,EAAE,CAAC;YACf,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBACrE,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;oBACnC,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,cAAc,QAAQ,mBAAmB,CAAC,CAAC;gBAC1E,CAAC;gBACD,SAAS,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC;YACnC,CAAC;QACH,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;YACV,SAAS,KAAK,SAAS;gBACrB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;gBAC5C,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;IAC9D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAYD,MAAM,UAAU,4BAA4B,CAAC,MAAmB;IAC9D,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE5D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { PromptTemplateAgent } from "./template.js";
2
+ export declare const defaultAgentFactories: {
3
+ "prompt-template": (name: string, thread: import("../index.js").Thread<keyof import("../index.js").RuntimeSpec>, constants: Readonly<import("./agent.js").PromptConstants>) => PromptTemplateAgent<import("./agent.js").PromptVariables>;
4
+ };
5
+ //# sourceMappingURL=factories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../../src/agent/factories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpD,eAAO,MAAM,qBAAqB;;CAEP,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { PromptTemplateAgent } from "./template.js";
2
+ export const defaultAgentFactories = {
3
+ "prompt-template": (name, thread, constants) => new PromptTemplateAgent(name, thread, constants),
4
+ };
5
+ //# sourceMappingURL=factories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factories.js","sourceRoot":"","sources":["../../src/agent/factories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpD,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC;CACvE,CAAC"}
@@ -0,0 +1,10 @@
1
+ export { Agent } from "./agent.js";
2
+ export type { PromptVariables, PromptConstants } from "./agent.js";
3
+ export type { AgentDefinition, AgentDefinitions, RuntimeThreadAgentConfig } from "./config.js";
4
+ export { loadAgentDefinitions, loadRuntimeThreadAgentConfig } from "./config.js";
5
+ export { AgentTeam } from "./team.js";
6
+ export type { AgentFactory, AgentFactoryMap, AgentVariablesByName } from "./team.js";
7
+ export { PromptTemplateAgent, formatPromptTemplate } from "./template.js";
8
+ export type { PromptTemplateConstants } from "./template.js";
9
+ export { defaultAgentFactories } from "./factories.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1E,YAAY,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { Agent } from "./agent.js";
2
+ export { loadAgentDefinitions, loadRuntimeThreadAgentConfig } from "./config.js";
3
+ export { AgentTeam } from "./team.js";
4
+ export { PromptTemplateAgent, formatPromptTemplate } from "./template.js";
5
+ export { defaultAgentFactories } from "./factories.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { RecordCallback, Thread } from "../runtime/index.js";
2
+ import type { Agent, PromptConstants, PromptVariables } from "./agent.js";
3
+ import type { RuntimeThreadAgentConfig } from "./config.js";
4
+ export type AgentFactory = (name: string, thread: Thread, constants: Readonly<PromptConstants>) => Agent;
5
+ export type AgentFactoryMap = Record<string, AgentFactory>;
6
+ export type AgentVariablesByName = Record<string, PromptVariables>;
7
+ export declare class AgentTeam<VariablesByName extends AgentVariablesByName = AgentVariablesByName> {
8
+ #private;
9
+ private readonly config;
10
+ private readonly factories;
11
+ constructor(config: RuntimeThreadAgentConfig, factories: AgentFactoryMap);
12
+ private getRuntime;
13
+ private getThread;
14
+ private createAgent;
15
+ getAgent<Name extends keyof VariablesByName & string>(name: Name): Promise<Agent<VariablesByName[Name]>>;
16
+ runStreamed<Name extends keyof VariablesByName & string>(name: Name, variables: VariablesByName[Name], onRecord?: RecordCallback): Promise<string>;
17
+ close(): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=team.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.d.ts","sourceRoot":"","sources":["../../src/agent/team.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAW,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,QAAQ,CAAC,eAAe,CAAC,KACjC,KAAK,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAE3D,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAEnE,qBAAa,SAAS,CAAC,eAAe,SAAS,oBAAoB,GAAG,oBAAoB;;IAMtF,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,MAAM,EAAE,wBAAwB,EAChC,SAAS,EAAE,eAAe;IAG7C,OAAO,CAAC,UAAU;YAgBJ,SAAS;YAoBT,WAAW;IAenB,QAAQ,CAAC,IAAI,SAAS,MAAM,eAAe,GAAG,MAAM,EACxD,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IAiBlC,WAAW,CAAC,IAAI,SAAS,MAAM,eAAe,GAAG,MAAM,EAC3D,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,EAChC,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,MAAM,CAAC;IAKZ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
@@ -0,0 +1,81 @@
1
+ import { createRuntime, startThread } from "../runtime/config.js";
2
+ export class AgentTeam {
3
+ config;
4
+ factories;
5
+ #agents = new Map();
6
+ #runtimes = new Map();
7
+ #threads = new Map();
8
+ constructor(config, factories) {
9
+ this.config = config;
10
+ this.factories = factories;
11
+ }
12
+ getRuntime(name) {
13
+ const cachedRuntime = this.#runtimes.get(name);
14
+ if (cachedRuntime) {
15
+ return cachedRuntime;
16
+ }
17
+ const runtimeDefinition = this.config.runtimes[name];
18
+ if (!runtimeDefinition) {
19
+ throw new Error(`Unknown runtime: ${name}`);
20
+ }
21
+ const runtime = createRuntime(runtimeDefinition);
22
+ this.#runtimes.set(name, runtime);
23
+ return runtime;
24
+ }
25
+ async getThread(name) {
26
+ const cachedThread = this.#threads.get(name);
27
+ if (cachedThread) {
28
+ return await cachedThread;
29
+ }
30
+ const threadDefinition = this.config.threads[name];
31
+ if (!threadDefinition) {
32
+ throw new Error(`Unknown thread: ${name}`);
33
+ }
34
+ const runtime = this.getRuntime(threadDefinition.runtime);
35
+ const thread = startThread(runtime, threadDefinition.options).catch((error) => {
36
+ this.#threads.delete(name);
37
+ throw error;
38
+ });
39
+ this.#threads.set(name, thread);
40
+ return await thread;
41
+ }
42
+ async createAgent(name) {
43
+ const agentDefinition = this.config.agents[name];
44
+ if (!agentDefinition) {
45
+ throw new Error(`Unknown agent: ${name}`);
46
+ }
47
+ const constants = agentDefinition.constants ?? {};
48
+ const factory = this.factories[agentDefinition.kind];
49
+ if (!factory) {
50
+ throw new Error(`Unknown agent kind for ${name}: ${agentDefinition.kind}`);
51
+ }
52
+ return factory(name, await this.getThread(agentDefinition.thread), constants);
53
+ }
54
+ async getAgent(name) {
55
+ // VariablesByName is a caller-provided type witness; factories are validated at runtime only by name.
56
+ const cachedAgent = this.#agents.get(name);
57
+ if (cachedAgent) {
58
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- Keep the caller-provided variable type visible at the boundary.
59
+ return (await cachedAgent);
60
+ }
61
+ const agent = this.createAgent(name).catch((error) => {
62
+ this.#agents.delete(name);
63
+ throw error;
64
+ });
65
+ this.#agents.set(name, agent);
66
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- Keep the caller-provided variable type visible at the boundary.
67
+ return (await agent);
68
+ }
69
+ async runStreamed(name, variables, onRecord) {
70
+ const agent = await this.getAgent(name);
71
+ return await agent.runStreamed(variables, onRecord);
72
+ }
73
+ async close() {
74
+ const runtimes = [...this.#runtimes.values()];
75
+ this.#agents.clear();
76
+ this.#threads.clear();
77
+ this.#runtimes.clear();
78
+ await Promise.all(runtimes.map((runtime) => runtime.close()));
79
+ }
80
+ }
81
+ //# sourceMappingURL=team.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.js","sourceRoot":"","sources":["../../src/agent/team.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Thread } from "../runtime/index.js";
2
+ import { Agent, type PromptConstants, type PromptVariables } from "./agent.js";
3
+ export type PromptTemplateConstants = PromptConstants & {
4
+ template: string;
5
+ };
6
+ export declare function formatPromptTemplate(template: string, variables: Readonly<PromptVariables>): string;
7
+ export declare function mergePromptTemplateVariables(constants: Readonly<PromptTemplateConstants>, variables: Readonly<PromptVariables>, exceptConstants?: readonly string[]): PromptVariables;
8
+ export declare class PromptTemplateAgent<Variables extends PromptVariables = PromptVariables> extends Agent<Variables, PromptTemplateConstants> {
9
+ constructor(agentName: string, thread: Thread, constants: Readonly<PromptConstants>);
10
+ protected buildPrompt(variables: Readonly<Variables>, constants: Readonly<PromptTemplateConstants>): string;
11
+ }
12
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/agent/template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAE/E,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG;IACtD,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,QAAQ,CAAC,eAAe,CAAC,GACnC,MAAM,CAeR;AAED,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,QAAQ,CAAC,uBAAuB,CAAC,EAC5C,SAAS,EAAE,QAAQ,CAAC,eAAe,CAAC,EACpC,eAAe,GAAE,SAAS,MAAM,EAAO,GACtC,eAAe,CASjB;AAED,qBAAa,mBAAmB,CAAC,SAAS,SAAS,eAAe,GAAG,eAAe,CAAE,SAAQ,KAAK,CACjG,SAAS,EACT,uBAAuB,CACxB;gBACa,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,eAAe,CAAC;IASnF,SAAS,CAAC,WAAW,CACnB,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC9B,SAAS,EAAE,QAAQ,CAAC,uBAAuB,CAAC,GAC3C,MAAM;CAMV"}
@@ -0,0 +1,37 @@
1
+ import { Agent } from "./agent.js";
2
+ export function formatPromptTemplate(template, variables) {
3
+ let prompt = template;
4
+ for (const [name, value] of Object.entries(variables)) {
5
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
6
+ throw new Error(`Invalid prompt template variable name: ${name}`);
7
+ }
8
+ prompt = prompt.replace(new RegExp(`\\{\\{\\s*${name}\\s*\\}\\}`, "g"), () => value);
9
+ }
10
+ const remainingPlaceholder = /\{\{\s*[^{}]*\S[^{}]*\s*\}\}/.exec(prompt);
11
+ if (remainingPlaceholder) {
12
+ throw new Error(`Missing prompt template variable: ${remainingPlaceholder[0]}`);
13
+ }
14
+ return prompt;
15
+ }
16
+ export function mergePromptTemplateVariables(constants, variables, exceptConstants = []) {
17
+ const constantVariables = {};
18
+ for (const [key, value] of Object.entries(constants)) {
19
+ if (!exceptConstants.includes(key)) {
20
+ constantVariables[key] = value;
21
+ }
22
+ }
23
+ return { ...constantVariables, ...variables };
24
+ }
25
+ export class PromptTemplateAgent extends Agent {
26
+ constructor(agentName, thread, constants) {
27
+ const template = constants.template;
28
+ if (template === undefined) {
29
+ throw new Error(`Agent ${agentName} constants must define template`);
30
+ }
31
+ super(thread, { ...constants, template });
32
+ }
33
+ buildPrompt(variables, constants) {
34
+ return formatPromptTemplate(constants.template, mergePromptTemplateVariables(constants, variables, ["template"]));
35
+ }
36
+ }
37
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/agent/template.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAA8C,MAAM,YAAY,CAAC;AAM/E,MAAM,UAAU,oBAAoB,CAClC,QAAgB,EAChB,SAAoC;IAEpC,IAAI,MAAM,GAAG,QAAQ,CAAC;IACtB,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACtD,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,aAAa,IAAI,YAAY,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,oBAAoB,GAAG,8BAA8B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzE,IAAI,oBAAoB,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,qCAAqC,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,SAA4C,EAC5C,SAAoC,EACpC,kBAAqC,EAAE;IAEvC,MAAM,iBAAiB,GAAoB,EAAE,CAAC;IAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,iBAAiB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,GAAG,iBAAiB,EAAE,GAAG,SAAS,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,OAAO,mBAAyE,SAAQ,KAG7F;IACC,YAAY,SAAiB,EAAE,MAAc,EAAE,SAAoC;QACjF,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;QACpC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,SAAS,SAAS,iCAAiC,CAAC,CAAC;QACvE,CAAC;QAED,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5C,CAAC;IAES,WAAW,CACnB,SAA8B,EAC9B,SAA4C;QAE5C,OAAO,oBAAoB,CACzB,SAAS,CAAC,QAAQ,EAClB,4BAA4B,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,UAAU,CAAC,CAAC,CACjE,CAAC;IACJ,CAAC;CACF"}
package/dist/cli.js CHANGED
@@ -1,39 +1,53 @@
1
1
  #!/usr/bin/env node
2
2
  import { parseArgs } from "node:util";
3
- import { createRuntime, loadConfig, startThread } from "./index.js";
4
- const { values, positionals: prompts } = parseArgs({
3
+ import { parse } from "yaml";
4
+ import { AgentTeam, defaultAgentFactories } from "./agent/index.js";
5
+ import { loadConfig } from "./config.js";
6
+ import { isPlainObject } from "./utils/object.js";
7
+ function parseVariables(entry) {
8
+ const value = parse(entry);
9
+ if (!isPlainObject(value)) {
10
+ throw new Error("Variables must be a YAML object");
11
+ }
12
+ const variables = {};
13
+ for (const [key, entryValue] of Object.entries(value)) {
14
+ if (typeof entryValue !== "string") {
15
+ throw new Error(`Variable ${key} must be a string`);
16
+ }
17
+ variables[key] = entryValue;
18
+ }
19
+ return variables;
20
+ }
21
+ const { values, positionals: variableGroups } = parseArgs({
5
22
  args: process.argv.slice(2),
6
23
  options: {
7
24
  config: { type: "string", multiple: true },
8
- thread: { type: "string" },
25
+ agent: { type: "string" },
9
26
  },
10
27
  allowPositionals: true,
11
28
  });
12
- const configPaths = values.config ?? [];
13
- if (prompts.length === 0) {
14
- console.error('Usage: agent-forge --config base.yaml [--config override.yaml] [--thread runner] "prompt" ["follow up"]');
29
+ const configPaths = values.config && values.config.length > 0 ? values.config : ["agent-forge.yaml"];
30
+ if (variableGroups.length === 0) {
31
+ console.error('Usage: agent-forge --config base.yaml [--config override.yaml] [--agent reviewer] "{ prompt: Inspect this repo }" "{ prompt: What did you just do? Is this a new conversation? }"');
15
32
  process.exit(1);
16
33
  }
17
- const config = await loadConfig(...(configPaths.length > 0 ? configPaths : ["agent-forge.yaml"]));
18
- const [defaultThreadName = ""] = Object.keys(config.threads);
19
- const threadName = values.thread ?? defaultThreadName;
20
- const threadDefinition = config.threads[threadName];
21
- if (!threadDefinition) {
22
- throw new Error(`Unknown thread: ${threadName}`);
23
- }
24
- const runtimeDefinition = config.runtimes[threadDefinition.runtime];
25
- if (!runtimeDefinition) {
26
- throw new Error(`Unknown runtime for thread ${threadName}: ${threadDefinition.runtime}`);
34
+ const config = await loadConfig(...configPaths);
35
+ const [defaultAgentName = ""] = Object.keys(config.agents);
36
+ const agentName = values.agent ?? defaultAgentName;
37
+ if (!config.agents[agentName]) {
38
+ throw new Error(`Unknown agent: ${agentName}`);
27
39
  }
28
- const runtime = createRuntime(runtimeDefinition);
40
+ const team = new AgentTeam(config, defaultAgentFactories);
29
41
  try {
30
- const thread = await startThread(runtime, threadDefinition);
31
- for (const prompt of prompts) {
32
- const response = await thread.runStreamed(prompt);
42
+ const logRecord = (thread, record) => {
43
+ process.stderr.write(`${thread.recordToPrettyString(record)}\n`);
44
+ };
45
+ for (const variableGroup of variableGroups) {
46
+ const response = await team.runStreamed(agentName, parseVariables(variableGroup), logRecord);
33
47
  process.stdout.write(`${response}\n`);
34
48
  }
35
49
  }
36
50
  finally {
37
- await runtime.close();
51
+ await team.close();
38
52
  }
39
53
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;IACjD,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3B,OAAO,EAAE;QACP,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC1C,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC3B;IACD,gBAAgB,EAAE,IAAI;CACvB,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;AAExC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IACzB,OAAO,CAAC,KAAK,CACX,yGAAyG,CAC1G,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AAClG,MAAM,CAAC,iBAAiB,GAAG,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,IAAI,iBAAiB,CAAC;AAEtD,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AACpD,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACtB,MAAM,IAAI,KAAK,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,iBAAiB,GAAG,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AACpE,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACvB,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,KAAK,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,OAAO,GAAG,aAAa,CAAC,iBAAiB,CAAC,CAAC;AAEjD,IAAI,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAE5D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;QAAS,CAAC;IACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}