@botbotgo/agent-harness 0.0.65 → 0.0.66

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/README.md CHANGED
@@ -207,6 +207,8 @@ const result = await run(runtime, {
207
207
 
208
208
  `run(runtime, { ... })` creates or continues a persisted thread and returns `threadId`, `runId`, `state`, and compact text `output`. Richer upstream result shapes stay available through `outputContent`, `contentBlocks`, and `structuredResponse`.
209
209
 
210
+ Use `listRuns(runtime)` and `getRun(runtime, runId)` when a product needs a run-centric operations surface such as a review queue or execution dashboard.
211
+
210
212
  Use `invocation` as the runtime-facing request envelope:
211
213
 
212
214
  - `invocation.context` for request-scoped execution context
@@ -575,6 +577,8 @@ Primary exports:
575
577
  - `run`
576
578
  - `resolveApproval`
577
579
  - `subscribe`
580
+ - `listRuns`
581
+ - `getRun`
578
582
  - `listThreads`
579
583
  - `getThread`
580
584
  - `deleteThread`
package/README.zh.md CHANGED
@@ -206,6 +206,8 @@ const result = await run(runtime, {
206
206
 
207
207
  `run(runtime, { ... })` 会创建或延续持久化线程,并返回 `threadId`、`runId`、`state` 以及紧凑文本 `output`。更丰富的上游结果形态仍可通过 `outputContent`、`contentBlocks`、`structuredResponse` 等获得。
208
208
 
209
+ 如果产品需要 run 视角的操作界面,例如 review queue 或执行看板,可使用 `listRuns(runtime)` 与 `getRun(runtime, runId)`。
210
+
209
211
  将 `invocation` 作为面向运行时的请求信封:
210
212
 
211
213
  - `invocation.context`:请求级执行上下文
@@ -567,6 +569,8 @@ spec:
567
569
  - `run`
568
570
  - `resolveApproval`
569
571
  - `subscribe`
572
+ - `listRuns`
573
+ - `getRun`
570
574
  - `listThreads`
571
575
  - `getThread`
572
576
  - `deleteThread`
package/dist/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ApprovalRecord, RunOptions, ResumeOptions, RuntimeAdapterOptions, ThreadSummary, ThreadRecord, WorkspaceLoadOptions } from "./contracts/types.js";
1
+ import type { ApprovalRecord, RunRecord, RunOptions, RunSummary, ResumeOptions, RuntimeAdapterOptions, ThreadSummary, ThreadRecord, WorkspaceLoadOptions } from "./contracts/types.js";
2
2
  import { AgentHarnessRuntime } from "./runtime/harness.js";
3
3
  import type { InventoryAgentRecord, InventorySkillRecord } from "./runtime/inventory.js";
4
4
  import type { RequirementAssessmentOptions } from "./runtime/skill-requirements.js";
@@ -13,7 +13,9 @@ export declare function createAgentHarness(workspaceRoot: string, options?: Crea
13
13
  export declare function run(runtime: AgentHarnessRuntime, options: RunOptions): Promise<import("./contracts/types.js").RunResult>;
14
14
  export declare function subscribe(runtime: AgentHarnessRuntime, listener: Parameters<AgentHarnessRuntime["subscribe"]>[0]): () => void;
15
15
  export declare function listThreads(runtime: AgentHarnessRuntime, filter?: Parameters<AgentHarnessRuntime["listThreads"]>[0]): Promise<ThreadSummary[]>;
16
+ export declare function listRuns(runtime: AgentHarnessRuntime, filter?: Parameters<AgentHarnessRuntime["listRuns"]>[0]): Promise<RunSummary[]>;
16
17
  export declare function getThread(runtime: AgentHarnessRuntime, threadId: string): Promise<ThreadRecord | null>;
18
+ export declare function getRun(runtime: AgentHarnessRuntime, runId: string): Promise<RunRecord | null>;
17
19
  export declare function deleteThread(runtime: AgentHarnessRuntime, threadId: string): Promise<boolean>;
18
20
  export declare function listApprovals(runtime: AgentHarnessRuntime, filter?: Parameters<AgentHarnessRuntime["listApprovals"]>[0]): Promise<ApprovalRecord[]>;
19
21
  export declare function getApproval(runtime: AgentHarnessRuntime, approvalId: string): Promise<ApprovalRecord | null>;
package/dist/api.js CHANGED
@@ -16,9 +16,15 @@ export function subscribe(runtime, listener) {
16
16
  export async function listThreads(runtime, filter) {
17
17
  return runtime.listThreads(filter);
18
18
  }
19
+ export async function listRuns(runtime, filter) {
20
+ return runtime.listRuns(filter);
21
+ }
19
22
  export async function getThread(runtime, threadId) {
20
23
  return runtime.getThread(threadId);
21
24
  }
25
+ export async function getRun(runtime, runId) {
26
+ return runtime.getRun(runId);
27
+ }
22
28
  export async function deleteThread(runtime, threadId) {
23
29
  return runtime.deleteThread(threadId);
24
30
  }
@@ -361,6 +361,7 @@ export type TranscriptMessage = {
361
361
  };
362
362
  export type ThreadRunRecord = {
363
363
  runId: string;
364
+ threadId: string;
364
365
  agentId: string;
365
366
  executionMode: string;
366
367
  adapterKind?: string;
@@ -370,6 +371,8 @@ export type ThreadRunRecord = {
370
371
  checkpointRef: string | null;
371
372
  resumable: boolean;
372
373
  };
374
+ export type RunSummary = ThreadRunRecord;
375
+ export type RunRecord = RunSummary;
373
376
  export type ThreadRecord = {
374
377
  threadId: string;
375
378
  entryAgentId: string;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { AgentHarnessRuntime, createAgentHarness, createToolMcpServer, deleteThread, describeInventory, getApproval, getThread, listAgentSkills, listApprovals, listThreads, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
1
+ export { AgentHarnessRuntime, createAgentHarness, createToolMcpServer, deleteThread, describeInventory, getApproval, getRun, getThread, listAgentSkills, listApprovals, listRuns, listThreads, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
2
2
  export type { ToolMcpServerOptions } from "./mcp.js";
3
3
  export { tool } from "./tools.js";
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { AgentHarnessRuntime, createAgentHarness, createToolMcpServer, deleteThread, describeInventory, getApproval, getThread, listAgentSkills, listApprovals, listThreads, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
1
+ export { AgentHarnessRuntime, createAgentHarness, createToolMcpServer, deleteThread, describeInventory, getApproval, getRun, getThread, listAgentSkills, listApprovals, listRuns, listThreads, resolveApproval, run, serveToolsOverStdio, subscribe, stop, } from "./api.js";
2
2
  export { tool } from "./tools.js";
@@ -1 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.64";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.65";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.64";
1
+ export const AGENT_HARNESS_VERSION = "0.0.65";
@@ -1,4 +1,4 @@
1
- import type { ArtifactListing, ArtifactRecord, DelegationRecord, HarnessEvent, InternalApprovalRecord, InvocationEnvelope, MessageContent, RunState, ThreadSummary, ThreadRunRecord, TranscriptMessage } from "../contracts/types.js";
1
+ import type { ArtifactListing, ArtifactRecord, DelegationRecord, HarnessEvent, InternalApprovalRecord, InvocationEnvelope, MessageContent, RunSummary, RunState, ThreadSummary, ThreadRunRecord, TranscriptMessage } from "../contracts/types.js";
2
2
  type ThreadMeta = {
3
3
  threadId: string;
4
4
  workspaceId: string;
@@ -73,6 +73,9 @@ export declare class FilePersistence {
73
73
  appendEvent(event: HarnessEvent): Promise<void>;
74
74
  listSessions(): Promise<ThreadSummary[]>;
75
75
  listRunIndexes(): Promise<RunIndexRecord[]>;
76
+ private readRunSummary;
77
+ listRuns(): Promise<RunSummary[]>;
78
+ getRun(runId: string): Promise<RunSummary | null>;
76
79
  getSession(threadId: string): Promise<ThreadSummary | null>;
77
80
  getThreadMeta(threadId: string): Promise<ThreadMeta | null>;
78
81
  listThreadRuns(threadId: string): Promise<ThreadRunRecord[]>;
@@ -190,6 +190,38 @@ export class FilePersistence {
190
190
  const entries = (await readdir(runIndexDir)).sort();
191
191
  return Promise.all(entries.map((entry) => readJson(path.join(runIndexDir, entry))));
192
192
  }
193
+ async readRunSummary(threadId, runId) {
194
+ const runDir = this.runDir(threadId, runId);
195
+ const [meta, lifecycle] = await Promise.all([
196
+ readJson(path.join(runDir, "meta.json")),
197
+ readJson(path.join(runDir, "lifecycle.json")),
198
+ ]);
199
+ return {
200
+ runId: meta.runId,
201
+ threadId: meta.threadId,
202
+ agentId: meta.agentId,
203
+ executionMode: meta.executionMode,
204
+ adapterKind: meta.adapterKind ?? meta.executionMode,
205
+ createdAt: meta.createdAt,
206
+ updatedAt: meta.updatedAt,
207
+ state: lifecycle.state,
208
+ checkpointRef: lifecycle.checkpointRef,
209
+ resumable: lifecycle.resumable,
210
+ };
211
+ }
212
+ async listRuns() {
213
+ const indexes = await this.listRunIndexes();
214
+ const runs = await Promise.all(indexes.map((record) => this.readRunSummary(record.threadId, record.runId)));
215
+ return runs.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
216
+ }
217
+ async getRun(runId) {
218
+ const indexPath = this.runIndexPath(runId);
219
+ if (!(await fileExists(indexPath))) {
220
+ return null;
221
+ }
222
+ const index = await readJson(indexPath);
223
+ return this.readRunSummary(index.threadId, index.runId);
224
+ }
193
225
  async getSession(threadId) {
194
226
  const filePath = path.join(this.runRoot, "indexes", "threads", `${threadId}.json`);
195
227
  if (!(await fileExists(filePath))) {
@@ -221,24 +253,7 @@ export class FilePersistence {
221
253
  return [];
222
254
  }
223
255
  const runIds = (await readdir(runsDir)).sort();
224
- const runs = await Promise.all(runIds.map(async (runId) => {
225
- const runDir = this.runDir(threadId, runId);
226
- const [meta, lifecycle] = await Promise.all([
227
- readJson(path.join(runDir, "meta.json")),
228
- readJson(path.join(runDir, "lifecycle.json")),
229
- ]);
230
- return {
231
- runId: meta.runId,
232
- agentId: meta.agentId,
233
- executionMode: meta.executionMode,
234
- adapterKind: meta.adapterKind ?? meta.executionMode,
235
- createdAt: meta.createdAt,
236
- updatedAt: meta.updatedAt,
237
- state: lifecycle.state,
238
- checkpointRef: lifecycle.checkpointRef,
239
- resumable: lifecycle.resumable,
240
- };
241
- }));
256
+ const runs = await Promise.all(runIds.map(async (runId) => this.readRunSummary(threadId, runId)));
242
257
  return runs.sort((left, right) => right.createdAt.localeCompare(left.createdAt));
243
258
  }
244
259
  async listRunEvents(threadId, runId) {
@@ -1,4 +1,4 @@
1
- import type { ApprovalRecord, HarnessEvent, HarnessStreamItem, MessageContent, RunStartOptions, RestartConversationOptions, RuntimeAdapterOptions, ResumeOptions, RunOptions, RunResult, ThreadSummary, ThreadRecord, WorkspaceBundle } from "../contracts/types.js";
1
+ import type { ApprovalRecord, HarnessEvent, HarnessStreamItem, MessageContent, RunRecord, RunStartOptions, RestartConversationOptions, RuntimeAdapterOptions, ResumeOptions, RunOptions, RunResult, RunSummary, ThreadSummary, ThreadRecord, WorkspaceBundle } from "../contracts/types.js";
2
2
  import { type ToolMcpServerOptions } from "../mcp.js";
3
3
  import { type InventoryAgentRecord, type InventorySkillRecord } from "./inventory.js";
4
4
  import type { RequirementAssessmentOptions } from "./skill-requirements.js";
@@ -49,6 +49,12 @@ export declare class AgentHarnessRuntime {
49
49
  listThreads(filter?: {
50
50
  agentId?: string;
51
51
  }): Promise<ThreadSummary[]>;
52
+ listRuns(filter?: {
53
+ agentId?: string;
54
+ threadId?: string;
55
+ state?: RunSummary["state"];
56
+ }): Promise<RunSummary[]>;
57
+ getRun(runId: string): Promise<RunRecord | null>;
52
58
  private getSession;
53
59
  getThread(threadId: string): Promise<ThreadRecord | null>;
54
60
  listApprovals(filter?: {
@@ -234,6 +234,24 @@ export class AgentHarnessRuntime {
234
234
  }
235
235
  return threadSummaries.filter((thread) => thread.agentId === filter.agentId);
236
236
  }
237
+ async listRuns(filter) {
238
+ const runs = await this.persistence.listRuns();
239
+ return runs.filter((run) => {
240
+ if (filter?.agentId && run.agentId !== filter.agentId) {
241
+ return false;
242
+ }
243
+ if (filter?.threadId && run.threadId !== filter.threadId) {
244
+ return false;
245
+ }
246
+ if (filter?.state && run.state !== filter.state) {
247
+ return false;
248
+ }
249
+ return true;
250
+ });
251
+ }
252
+ async getRun(runId) {
253
+ return this.persistence.getRun(runId);
254
+ }
237
255
  async getSession(threadId) {
238
256
  return this.persistence.getSession(threadId);
239
257
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.65",
3
+ "version": "0.0.66",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.2",