@botbotgo/agent-harness 0.0.288 → 0.0.290

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.
@@ -708,22 +708,8 @@ export type RuntimeArtifactWriteInput = {
708
708
  artifactId?: string;
709
709
  createdAt?: string;
710
710
  };
711
- export type RuntimeEvaluationArtifactFormat = "json" | "markdown" | "text" | "unknown";
712
- export type RuntimeEvaluationArtifactRole = "product-spec" | "sprint-contract" | "qa-report" | "handoff" | "other";
713
711
  export type RuntimeEvaluationArtifact = ArtifactRecord & {
714
712
  content?: unknown;
715
- format: RuntimeEvaluationArtifactFormat;
716
- role: RuntimeEvaluationArtifactRole;
717
- };
718
- export type RuntimeEvaluationArtifactSummary = {
719
- productSpecPaths: string[];
720
- sprintContractPaths: string[];
721
- qaReportPaths: string[];
722
- handoffPaths: string[];
723
- qaVerdicts: Array<{
724
- path: string;
725
- verdict: string;
726
- }>;
727
713
  };
728
714
  export type RuntimeEvaluationExport = {
729
715
  session: SessionRecord | null;
@@ -737,7 +723,6 @@ export type RuntimeEvaluationExport = {
737
723
  transcript: TranscriptMessage[];
738
724
  events: HarnessEvent[];
739
725
  artifacts: RuntimeEvaluationArtifact[];
740
- artifactSummary: RuntimeEvaluationArtifactSummary;
741
726
  runtimeHealth: RuntimeHealthSnapshot;
742
727
  expectedOutput?: string;
743
728
  rubric: string[];
@@ -1 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.287";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.289";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.287";
1
+ export const AGENT_HARNESS_VERSION = "0.0.289";
@@ -0,0 +1 @@
1
+ export declare function normalizeRecordedArtifactPath(input: string): string;
@@ -0,0 +1,15 @@
1
+ import path from "node:path";
2
+ export function normalizeRecordedArtifactPath(input) {
3
+ const trimmed = input.trim().replaceAll("\\", "/").replace(/^\.\/+/, "");
4
+ if (!trimmed) {
5
+ throw new Error("Artifact path must be a non-empty relative path.");
6
+ }
7
+ if (trimmed.startsWith("/") || /^[a-z]:\//i.test(trimmed)) {
8
+ throw new Error("Artifact path must stay relative to the persisted run artifact directory.");
9
+ }
10
+ const normalized = path.posix.normalize(trimmed);
11
+ if (normalized === "." || normalized.startsWith("../") || normalized.includes("/../")) {
12
+ throw new Error("Artifact path must stay inside the persisted run artifact directory.");
13
+ }
14
+ return normalized;
15
+ }
@@ -3,7 +3,7 @@ import { SqlitePersistence } from "../persistence/sqlite-store.js";
3
3
  import { createPersistentId } from "../utils/id.js";
4
4
  import { extractMessageText } from "../utils/message-content.js";
5
5
  import { AgentRuntimeAdapter } from "./agent-runtime-adapter.js";
6
- import { enrichEvaluationArtifact, normalizeRecordedArtifactPath, summarizeEvaluationArtifacts, } from "./harness/run/evaluation-artifacts.js";
6
+ import { normalizeRecordedArtifactPath } from "./harness/run/artifact-paths.js";
7
7
  import { EventBus } from "./harness/events/event-bus.js";
8
8
  import { createBackgroundEventRuntime } from "./harness/background-runtime.js";
9
9
  import { PolicyEngine } from "./harness/system/policy-engine.js";
@@ -672,7 +672,7 @@ export class AgentHarnessRuntime {
672
672
  const artifactsListing = input.includeArtifacts === false
673
673
  ? { items: [] }
674
674
  : await this.persistence.listArtifacts(input.sessionId, input.requestId);
675
- const artifacts = await Promise.all(artifactsListing.items.map(async (artifact) => enrichEvaluationArtifact({
675
+ const artifacts = await Promise.all(artifactsListing.items.map(async (artifact) => ({
676
676
  ...artifact,
677
677
  ...(input.includeArtifactContents === true
678
678
  ? { content: await this.persistence.readArtifact(input.sessionId, input.requestId, artifact.path) }
@@ -749,12 +749,10 @@ export class AgentHarnessRuntime {
749
749
  ? { items: [] }
750
750
  : await this.persistence.listArtifacts(input.sessionId, input.requestId);
751
751
  const artifacts = await Promise.all(artifactsListing.items.map(async (artifact) => ({
752
- ...enrichEvaluationArtifact({
753
- ...artifact,
754
- ...(input.includeArtifactContents === true
755
- ? { content: await this.persistence.readArtifact(input.sessionId, input.requestId, artifact.path) }
756
- : {}),
757
- }),
752
+ ...artifact,
753
+ ...(input.includeArtifactContents === true
754
+ ? { content: await this.persistence.readArtifact(input.sessionId, input.requestId, artifact.path) }
755
+ : {}),
758
756
  })));
759
757
  return {
760
758
  session: thread ? toSessionRecord(thread) : null,
@@ -770,7 +768,6 @@ export class AgentHarnessRuntime {
770
768
  transcript,
771
769
  events,
772
770
  artifacts,
773
- artifactSummary: summarizeEvaluationArtifacts(artifacts),
774
771
  runtimeHealth,
775
772
  ...(typeof input.expectedOutput === "string" && input.expectedOutput.trim().length > 0
776
773
  ? { expectedOutput: input.expectedOutput.trim() }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.288",
3
+ "version": "0.0.290",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,8 +0,0 @@
1
- import type { RuntimeEvaluationArtifact, RuntimeEvaluationArtifactSummary } from "../../../contracts/types.js";
2
- export declare function normalizeRecordedArtifactPath(input: string): string;
3
- export declare function enrichEvaluationArtifact<T extends {
4
- path: string;
5
- kind: string;
6
- content?: unknown;
7
- }>(artifact: T): T & Pick<RuntimeEvaluationArtifact, "format" | "role">;
8
- export declare function summarizeEvaluationArtifacts(artifacts: RuntimeEvaluationArtifact[]): RuntimeEvaluationArtifactSummary;
@@ -1,108 +0,0 @@
1
- import path from "node:path";
2
- function isObject(value) {
3
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4
- }
5
- function inferArtifactFormat(artifactPath, content) {
6
- const normalized = artifactPath.toLowerCase();
7
- if (normalized.endsWith(".json")) {
8
- return "json";
9
- }
10
- if (normalized.endsWith(".md") || normalized.endsWith(".markdown")) {
11
- return "markdown";
12
- }
13
- if (normalized.endsWith(".txt")) {
14
- return "text";
15
- }
16
- if (typeof content === "string") {
17
- return content.includes("#") || content.includes("##") ? "markdown" : "text";
18
- }
19
- if (content !== undefined) {
20
- return "json";
21
- }
22
- return "unknown";
23
- }
24
- function inferArtifactRole(artifactPath, kind, content) {
25
- const normalized = artifactPath.toLowerCase();
26
- const loweredKind = kind.toLowerCase();
27
- const contentObject = isObject(content) ? content : null;
28
- if (normalized.includes("product-spec") || normalized.endsWith("/spec.md") || loweredKind === "product-spec") {
29
- return "product-spec";
30
- }
31
- if (normalized.includes("sprint-contract")
32
- || loweredKind === "sprint-contract"
33
- || (contentObject && Array.isArray(contentObject.acceptanceCriteria))) {
34
- return "sprint-contract";
35
- }
36
- if (normalized.includes("qa-report")
37
- || loweredKind === "qa-report"
38
- || (contentObject && (typeof contentObject.verdict === "string" || typeof contentObject.status === "string"))) {
39
- return "qa-report";
40
- }
41
- if (normalized.includes("handoff") || loweredKind === "handoff") {
42
- return "handoff";
43
- }
44
- return "other";
45
- }
46
- function extractQaVerdict(content) {
47
- if (!isObject(content)) {
48
- return null;
49
- }
50
- for (const key of ["verdict", "status", "decision"]) {
51
- if (typeof content[key] === "string" && String(content[key]).trim().length > 0) {
52
- return String(content[key]).trim();
53
- }
54
- }
55
- return null;
56
- }
57
- export function normalizeRecordedArtifactPath(input) {
58
- const trimmed = input.trim().replaceAll("\\", "/").replace(/^\.\/+/, "");
59
- if (!trimmed) {
60
- throw new Error("Artifact path must be a non-empty relative path.");
61
- }
62
- if (trimmed.startsWith("/") || /^[a-z]:\//i.test(trimmed)) {
63
- throw new Error("Artifact path must stay relative to the persisted run artifact directory.");
64
- }
65
- const normalized = path.posix.normalize(trimmed);
66
- if (normalized === "." || normalized.startsWith("../") || normalized.includes("/../")) {
67
- throw new Error("Artifact path must stay inside the persisted run artifact directory.");
68
- }
69
- return normalized;
70
- }
71
- export function enrichEvaluationArtifact(artifact) {
72
- return {
73
- ...artifact,
74
- format: inferArtifactFormat(artifact.path, artifact.content),
75
- role: inferArtifactRole(artifact.path, artifact.kind, artifact.content),
76
- };
77
- }
78
- export function summarizeEvaluationArtifacts(artifacts) {
79
- const summary = {
80
- productSpecPaths: [],
81
- sprintContractPaths: [],
82
- qaReportPaths: [],
83
- handoffPaths: [],
84
- qaVerdicts: [],
85
- };
86
- for (const artifact of artifacts) {
87
- if (artifact.role === "product-spec") {
88
- summary.productSpecPaths.push(artifact.path);
89
- continue;
90
- }
91
- if (artifact.role === "sprint-contract") {
92
- summary.sprintContractPaths.push(artifact.path);
93
- continue;
94
- }
95
- if (artifact.role === "qa-report") {
96
- summary.qaReportPaths.push(artifact.path);
97
- const verdict = extractQaVerdict(artifact.content);
98
- if (verdict) {
99
- summary.qaVerdicts.push({ path: artifact.path, verdict });
100
- }
101
- continue;
102
- }
103
- if (artifact.role === "handoff") {
104
- summary.handoffPaths.push(artifact.path);
105
- }
106
- }
107
- return summary;
108
- }