@botbotgo/agent-harness 0.0.10 → 0.0.11

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 (2) hide show
  1. package/README.md +243 -0
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -83,6 +83,249 @@ There are two common ways to use the framework.
83
83
 
84
84
  Load a workspace from disk and run requests through the public API.
85
85
 
86
+ #### SDK Surface
87
+
88
+ The SDK is intentionally small:
89
+
90
+ - `createAgentHarness(...)`: load a workspace and initialize the runtime
91
+ - `run(...)`: start a new run or answer an approval request
92
+ - `subscribe(...)`: observe runtime events for logging or UI updates
93
+ - `getThread(...)`: fetch persisted thread state and messages
94
+ - `stop(...)`: release runtime resources when your process is done
95
+
96
+ #### Create A Harness From A Workspace Path
97
+
98
+ This is the standard entry point. Pass the workspace root and let the harness load `AGENTS.md`, `config/`, resource sources, skills, tools, and agent bindings from disk.
99
+
100
+ ```ts
101
+ import { createAgentHarness } from "@botbotgo/agent-harness";
102
+
103
+ const harness = await createAgentHarness("/absolute/path/to/workspace");
104
+ ```
105
+
106
+ If you omit the path, the SDK uses `process.cwd()`:
107
+
108
+ ```ts
109
+ const harness = await createAgentHarness();
110
+ ```
111
+
112
+ #### Create A Harness From A Prebuilt WorkspaceBundle
113
+
114
+ If your application already compiled a workspace, or you want tighter control in tests, you can pass a `WorkspaceBundle` directly instead of a filesystem path.
115
+
116
+ ```ts
117
+ import { createAgentHarness } from "@botbotgo/agent-harness";
118
+
119
+ const harness = await createAgentHarness(workspaceBundle);
120
+ ```
121
+
122
+ #### Run A Simple Request
123
+
124
+ Use `run(...)` with an `agentId` and plain-text `input`. The return value includes:
125
+
126
+ - `threadId`: stable conversation id
127
+ - `runId`: the current execution id
128
+ - `state`: final state such as `completed` or `waiting_for_approval`
129
+ - `output`: final visible model output
130
+
131
+ ```ts
132
+ import { createAgentHarness, run, stop } from "@botbotgo/agent-harness";
133
+
134
+ const harness = await createAgentHarness("/absolute/path/to/workspace");
135
+
136
+ try {
137
+ const result = await run(harness, {
138
+ agentId: "direct",
139
+ input: "Summarize what this workspace is for.",
140
+ });
141
+
142
+ console.log(result.threadId);
143
+ console.log(result.runId);
144
+ console.log(result.state);
145
+ console.log(result.output);
146
+ } finally {
147
+ await stop(harness);
148
+ }
149
+ ```
150
+
151
+ #### Let The Harness Choose The Host Agent
152
+
153
+ If your workspace defines runtime routing, use `agentId: "auto"` to let the harness choose between host agents such as `direct` and `orchestra`.
154
+
155
+ ```ts
156
+ const result = await run(harness, {
157
+ agentId: "auto",
158
+ input: "Inspect this repository and explain how the release flow works.",
159
+ });
160
+ ```
161
+
162
+ Use this mode when your application should not hardcode the host agent choice.
163
+
164
+ #### Stream Chunks And Runtime Events
165
+
166
+ `run(...)` accepts listeners for streamed output and runtime activity. This is the main SDK path for CLIs, chat UIs, and debug logging.
167
+
168
+ ```ts
169
+ const result = await run(harness, {
170
+ agentId: "orchestra",
171
+ input: "Inspect the workspace and explain the available agents.",
172
+ listeners: {
173
+ onChunk(chunk) {
174
+ process.stdout.write(chunk);
175
+ },
176
+ onEvent(event) {
177
+ console.log("event:", event.eventType, event.payload);
178
+ },
179
+ onStep(step) {
180
+ console.log("step:", step);
181
+ },
182
+ onToolResult(item) {
183
+ console.log("tool:", item.toolName, item.output);
184
+ },
185
+ },
186
+ });
187
+ ```
188
+
189
+ Listener usage by type:
190
+
191
+ - `onChunk`: streamed user-visible response text
192
+ - `onEvent`: raw runtime events
193
+ - `onStep`: higher-level execution step messages
194
+ - `onToolResult`: completed tool outputs
195
+ - `onReasoning`: reasoning-channel text when available from the runtime
196
+
197
+ #### Subscribe To Global Harness Events
198
+
199
+ Use `subscribe(...)` when you want a process-wide event feed rather than per-run listeners.
200
+
201
+ ```ts
202
+ import { subscribe } from "@botbotgo/agent-harness";
203
+
204
+ const unsubscribe = subscribe(harness, (event) => {
205
+ console.log(event.threadId, event.runId, event.eventType);
206
+ });
207
+
208
+ // later
209
+ unsubscribe();
210
+ ```
211
+
212
+ This is useful when one process is handling multiple runs or updating a central UI.
213
+
214
+ #### Continue An Existing Thread
215
+
216
+ Pass an existing `threadId` to keep the conversation on the same persisted thread.
217
+
218
+ ```ts
219
+ const first = await run(harness, {
220
+ agentId: "direct",
221
+ input: "Remember that the release branch is master.",
222
+ });
223
+
224
+ const second = await run(harness, {
225
+ agentId: "direct",
226
+ threadId: first.threadId,
227
+ input: "What did I just tell you about the release branch?",
228
+ });
229
+ ```
230
+
231
+ #### Read Back Thread State
232
+
233
+ Use `getThread(...)` to fetch persisted thread data after a run completes.
234
+
235
+ ```ts
236
+ import { getThread } from "@botbotgo/agent-harness";
237
+
238
+ const thread = await getThread(harness, result.threadId);
239
+
240
+ console.log(thread?.threadId);
241
+ console.log(thread?.messages.at(-1)?.content);
242
+ ```
243
+
244
+ Use this when your app needs to reopen a conversation, render history, or inspect the latest assistant message.
245
+
246
+ #### Handle Approval Or Interrupt Flows
247
+
248
+ Some runs can pause with `state: "waiting_for_approval"`. In that case, call `run(...)` again with the thread or approval decision payload instead of starting a new request.
249
+
250
+ ```ts
251
+ const pending = await run(harness, {
252
+ agentId: "orchestra",
253
+ input: "Run the protected action if approval is required.",
254
+ });
255
+
256
+ if (pending.state === "waiting_for_approval" && pending.approvalId) {
257
+ const resumed = await run(harness, {
258
+ threadId: pending.threadId,
259
+ runId: pending.runId,
260
+ approvalId: pending.approvalId,
261
+ decision: "approve",
262
+ });
263
+
264
+ console.log(resumed.output);
265
+ }
266
+ ```
267
+
268
+ Use `decision: "edit"` plus `editedInput` when your application exposes approval-time parameter editing.
269
+
270
+ #### Always Stop The Harness
271
+
272
+ Call `stop(...)` before process exit so the runtime can close adapters and flush state cleanly.
273
+
274
+ ```ts
275
+ await stop(harness);
276
+ ```
277
+
278
+ For most applications, the safe pattern is `try/finally`.
279
+
280
+ #### Complete SDK CLI Example
281
+
282
+ The following example shows a small CLI-style integration that:
283
+
284
+ - loads a workspace from disk
285
+ - starts a first run with streaming output
286
+ - continues the same thread
287
+ - reads the saved thread state back
288
+ - shuts the harness down cleanly
289
+
290
+ ```ts
291
+ import { createAgentHarness, getThread, run, stop } from "@botbotgo/agent-harness";
292
+
293
+ const workspaceRoot = "/absolute/path/to/workspace";
294
+ const harness = await createAgentHarness(workspaceRoot);
295
+
296
+ try {
297
+ const first = await run(harness, {
298
+ agentId: "auto",
299
+ input: "Explain what agents and tools are available in this workspace.",
300
+ listeners: {
301
+ onChunk(chunk) {
302
+ process.stdout.write(chunk);
303
+ },
304
+ onStep(step) {
305
+ console.log("\n[step]", step);
306
+ },
307
+ },
308
+ });
309
+
310
+ console.log("\nfirst run:", first.runId, first.state);
311
+
312
+ const second = await run(harness, {
313
+ agentId: "auto",
314
+ threadId: first.threadId,
315
+ input: "Now give me the shortest possible summary in 3 bullets.",
316
+ });
317
+
318
+ console.log("\nsecond run output:\n", second.output);
319
+
320
+ const thread = await getThread(harness, first.threadId);
321
+ console.log("\nthread message count:", thread?.messages.length ?? 0);
322
+ } finally {
323
+ await stop(harness);
324
+ }
325
+ ```
326
+
327
+ For a real CLI entrypoint, wrap this in an async `main()` and feed the prompt from `process.argv`.
328
+
86
329
  ```ts
87
330
  import { createAgentHarness, getThread, run, subscribe, stop } from "@botbotgo/agent-harness";
88
331
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "Agent Harness framework package",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.2",