agentic-engineering-harness 0.6.29 → 0.7.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.
- package/dist/agents/permissions.js +4 -3
- package/dist/agents/permissions.js.map +1 -1
- package/dist/cli.js +23 -1
- package/dist/cli.js.map +1 -1
- package/dist/context/compression/headroom.d.ts +6 -1
- package/dist/context/compression/headroom.js +60 -15
- package/dist/context/compression/headroom.js.map +1 -1
- package/dist/context/compression/types.d.ts +1 -0
- package/dist/context/gateway.d.ts +1 -0
- package/dist/context/gateway.js +58 -44
- package/dist/context/gateway.js.map +1 -1
- package/dist/context/repository/serena.d.ts +1 -1
- package/dist/context/repository/serena.js +2 -1
- package/dist/context/repository/serena.js.map +1 -1
- package/dist/context/transport.d.ts +33 -0
- package/dist/context/transport.js +63 -0
- package/dist/context/transport.js.map +1 -0
- package/dist/core/config.js +1 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/init.js +2 -1
- package/dist/core/init.js.map +1 -1
- package/dist/core/run.js +6 -2
- package/dist/core/run.js.map +1 -1
- package/dist/core/types.d.ts +25 -0
- package/dist/core/verify.js +2 -1
- package/dist/core/verify.js.map +1 -1
- package/dist/evals/fullStack.d.ts +10 -7
- package/dist/evals/fullStack.js +132 -36
- package/dist/evals/fullStack.js.map +1 -1
- package/dist/evidence/graph.js +24 -7
- package/dist/evidence/graph.js.map +1 -1
- package/dist/memory/candidates.d.ts +29 -0
- package/dist/memory/candidates.js +31 -0
- package/dist/memory/candidates.js.map +1 -0
- package/dist/paseo/launchSpec.js +4 -4
- package/dist/paseo/launchSpec.js.map +1 -1
- package/dist/provenance/generate.d.ts +15 -0
- package/dist/provenance/generate.js +150 -68
- package/dist/provenance/generate.js.map +1 -1
- package/dist/providers/engram.d.ts +1 -0
- package/dist/providers/engram.js +40 -8
- package/dist/providers/engram.js.map +1 -1
- package/dist/providers/graphify.d.ts +20 -1
- package/dist/providers/graphify.js +106 -26
- package/dist/providers/graphify.js.map +1 -1
- package/dist/providers/serenaMcp.d.ts +7 -0
- package/dist/providers/serenaMcp.js +77 -0
- package/dist/providers/serenaMcp.js.map +1 -0
- package/dist/providers/versions.d.ts +10 -0
- package/dist/providers/versions.js +3 -0
- package/dist/providers/versions.js.map +1 -0
- package/dist/telemetry/events.js +36 -37
- package/dist/telemetry/events.js.map +1 -1
- package/dist/telemetry/otlp.d.ts +2 -1
- package/dist/telemetry/otlp.js +20 -41
- package/dist/telemetry/otlp.js.map +1 -1
- package/dist/telemetry/tracing.d.ts +19 -0
- package/dist/telemetry/tracing.js +141 -0
- package/dist/telemetry/tracing.js.map +1 -0
- package/dist/toolchain/config.js +3 -2
- package/dist/toolchain/config.js.map +1 -1
- package/dist/validators/external.js +6 -5
- package/dist/validators/external.js.map +1 -1
- package/dist/validators/toolEvidence.d.ts +2 -22
- package/dist/validators/toolEvidence.js +36 -3
- package/dist/validators/toolEvidence.js.map +1 -1
- package/dist/workers/agentPrompt.js +5 -3
- package/dist/workers/agentPrompt.js.map +1 -1
- package/docs/COMPONENT_MATURITY.md +15 -11
- package/docs/component-maturity.json +34 -0
- package/package.json +7 -1
- package/schemas/project.schema.json +1 -1
- package/schemas/validation-report.schema.json +2 -1
- package/scripts/headroom-bridge.py +88 -0
- package/templates/provider-versions.json +10 -0
- package/templates/toolchain.yaml +12 -4
|
@@ -1,46 +1,126 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
1
4
|
import { commandExists, runProcess } from "../utils/process.js";
|
|
2
5
|
import { loadCanonicalGraph } from "./graphifyModel.js";
|
|
6
|
+
import { providerVersions } from "./versions.js";
|
|
7
|
+
const GRAPHIFY_COMMAND = "graphify";
|
|
8
|
+
export const GRAPHIFY_VERSION = providerVersions.graphify;
|
|
9
|
+
/** Graphify owns generation/freshness; all consumers use graphifyModel.ts. */
|
|
3
10
|
export class GraphifyCodeIntelligenceProvider {
|
|
4
11
|
config;
|
|
12
|
+
executor;
|
|
5
13
|
name = "graphify";
|
|
6
|
-
constructor(config) {
|
|
14
|
+
constructor(config, executor = runProcess) {
|
|
7
15
|
this.config = config;
|
|
16
|
+
this.executor = executor;
|
|
8
17
|
}
|
|
9
18
|
async doctor(root) {
|
|
10
|
-
const cli = await commandExists(
|
|
19
|
+
const cli = await commandExists(GRAPHIFY_COMMAND, root);
|
|
11
20
|
const graph = await this.load(root);
|
|
12
|
-
|
|
13
|
-
ok:
|
|
14
|
-
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
async build(root) { await this.refresh(root); }
|
|
18
|
-
async refresh(root) {
|
|
19
|
-
const command = this.config?.codeIntelligence?.refreshCommand;
|
|
20
|
-
if (command) {
|
|
21
|
-
const result = await runProcess(command, { cwd: root, timeoutMs: 300_000 });
|
|
22
|
-
if (result.exitCode !== 0)
|
|
23
|
-
throw new Error(`Graphify refresh failed: ${result.stderr || result.stdout}`);
|
|
24
|
-
}
|
|
25
|
-
if (!(await this.load(root)))
|
|
26
|
-
throw new Error("Graphify graph is unavailable after refresh. Configure codeIntelligence.refreshCommand or generate the configured graph path.");
|
|
27
|
-
}
|
|
28
|
-
async update(root) { await this.refresh(root); }
|
|
29
|
-
async load(root) {
|
|
30
|
-
return loadCanonicalGraph(root, this.config?.codeIntelligence?.graphPath ?? "graphify-out/graph.json");
|
|
21
|
+
if (!cli && !graph)
|
|
22
|
+
return { ok: false, message: "Graphify CLI and canonical graph are unavailable." };
|
|
23
|
+
const version = cli ? await this.providerVersion(root).catch(() => undefined) : undefined;
|
|
24
|
+
return { ok: true, message: graph ? `Graphify canonical graph is readable${version ? ` (${version})` : ""}; freshness is repository-state bound.` : `Graphify CLI detected${version ? ` (${version})` : ""}; provider generation is available.` };
|
|
31
25
|
}
|
|
26
|
+
async build(root) { await this.generate(root, false); }
|
|
27
|
+
async refresh(root) { await this.generate(root, false); }
|
|
28
|
+
async update(root) { await this.generate(root, true); }
|
|
29
|
+
async load(root) { return loadCanonicalGraph(root, this.graphPath()); }
|
|
32
30
|
async isFresh(root) {
|
|
33
31
|
const graph = await this.load(root);
|
|
34
|
-
|
|
32
|
+
const metadata = await this.readMetadata(root);
|
|
33
|
+
if (!graph || !metadata || metadata.provider !== "graphify")
|
|
35
34
|
return false;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// conservative for callers that need a readiness decision.
|
|
39
|
-
return Boolean(graph.generatedAt);
|
|
35
|
+
const current = await sourceFingerprint(root);
|
|
36
|
+
return metadata.sourceFingerprint === current.sourceFingerprint && metadata.gitCommit === current.gitCommit && metadata.graphSha256 === graph.sourceHash && metadata.providerVersion.length > 0;
|
|
40
37
|
}
|
|
41
38
|
async impact(root) {
|
|
42
39
|
const graph = await this.load(root);
|
|
43
40
|
return { provider: this.name, affectedNodes: graph?.nodes ?? [], affectedCommunities: [...new Set(Object.values(graph?.communities ?? {}))] };
|
|
44
41
|
}
|
|
42
|
+
async generate(root, incremental) {
|
|
43
|
+
const override = this.config?.codeIntelligence?.refreshCommand?.trim();
|
|
44
|
+
if (override) {
|
|
45
|
+
const result = await this.executor(override, { cwd: root, timeoutMs: 300_000 });
|
|
46
|
+
if (result.exitCode !== 0)
|
|
47
|
+
throw new Error(`GRAPHIFY_REFRESH_FAILED: ${result.stderr || result.stdout}`);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
if (!(await commandExists(GRAPHIFY_COMMAND, root)))
|
|
51
|
+
throw new Error("GRAPHIFY_UNAVAILABLE: Graphify CLI is not installed.");
|
|
52
|
+
const args = [GRAPHIFY_COMMAND, ".", ...(incremental ? ["--update"] : []), ...(this.config?.codeIntelligence?.codeOnly ? ["--code-only"] : []), "--no-viz"];
|
|
53
|
+
const result = await this.executor(args.map(quote).join(" "), { cwd: root, timeoutMs: 300_000 });
|
|
54
|
+
if (result.exitCode !== 0)
|
|
55
|
+
throw new Error(`GRAPHIFY_REFRESH_FAILED: ${result.stderr || result.stdout}`);
|
|
56
|
+
}
|
|
57
|
+
await this.targetConfiguredGraph(root);
|
|
58
|
+
const graphFile = path.resolve(root, this.graphPath());
|
|
59
|
+
const raw = await fs.readFile(graphFile, "utf8").catch(() => undefined);
|
|
60
|
+
if (!raw)
|
|
61
|
+
throw new Error("GRAPHIFY_OUTPUT_MISSING: Graphify completed without a readable configured graph output.");
|
|
62
|
+
if (!(await this.load(root)))
|
|
63
|
+
throw new Error("GRAPHIFY_OUTPUT_INVALID: configured graph output is not valid through the canonical AEH model.");
|
|
64
|
+
const fingerprint = await sourceFingerprint(root);
|
|
65
|
+
const metadata = { version: 1, provider: "graphify", providerVersion: override ? "override" : await this.providerVersion(root), gitCommit: fingerprint.gitCommit, sourceFingerprint: fingerprint.sourceFingerprint, graphSha256: crypto.createHash("sha256").update(raw).digest("hex"), generatedAt: new Date().toISOString() };
|
|
66
|
+
const file = this.metadataPath(root);
|
|
67
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
68
|
+
await fs.writeFile(file, `${JSON.stringify(metadata, null, 2)}\n`, "utf8");
|
|
69
|
+
}
|
|
70
|
+
async targetConfiguredGraph(root) {
|
|
71
|
+
if (this.config?.codeIntelligence?.refreshCommand?.trim())
|
|
72
|
+
return;
|
|
73
|
+
const target = path.resolve(root, this.graphPath());
|
|
74
|
+
if (target === path.resolve(root, "graphify-out/graph.json"))
|
|
75
|
+
return;
|
|
76
|
+
const generated = await fs.readFile(path.resolve(root, "graphify-out/graph.json"), "utf8").catch(() => undefined);
|
|
77
|
+
if (!generated)
|
|
78
|
+
return;
|
|
79
|
+
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
80
|
+
await fs.writeFile(target, generated, "utf8");
|
|
81
|
+
}
|
|
82
|
+
graphPath() { return this.config?.codeIntelligence?.graphPath ?? "graphify-out/graph.json"; }
|
|
83
|
+
metadataPath(root) { return path.resolve(root, this.config?.codeIntelligence?.snapshotDir ?? ".harness/graphify", "generation.json"); }
|
|
84
|
+
async readMetadata(root) { try {
|
|
85
|
+
return JSON.parse(await fs.readFile(this.metadataPath(root), "utf8"));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return undefined;
|
|
89
|
+
} }
|
|
90
|
+
async providerVersion(root) {
|
|
91
|
+
const result = await this.executor(`${quote(GRAPHIFY_COMMAND)} --version`, { cwd: root, timeoutMs: 30_000 });
|
|
92
|
+
if (result.exitCode !== 0)
|
|
93
|
+
throw new Error(`Graphify version check failed: ${result.stderr || result.stdout}`);
|
|
94
|
+
const version = (result.stdout || result.stderr).trim().split(/\r?\n/).at(0)?.trim();
|
|
95
|
+
if (!version)
|
|
96
|
+
throw new Error("Graphify version check returned no version.");
|
|
97
|
+
return version;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function sourceFingerprint(root) {
|
|
101
|
+
const filesResult = await runProcess("git ls-files -co --exclude-standard", { cwd: root, timeoutMs: 30_000 });
|
|
102
|
+
const names = filesResult.exitCode === 0 ? filesResult.stdout.split(/\r?\n/).map((item) => item.trim()).filter((item) => item && !excluded(item)) : await fallbackSourceFiles(root);
|
|
103
|
+
const hash = crypto.createHash("sha256");
|
|
104
|
+
for (const name of [...new Set(names)].sort())
|
|
105
|
+
hash.update(name).update("\0").update(await fs.readFile(path.resolve(root, name)).catch(() => Buffer.from(""))).update("\0");
|
|
106
|
+
const commitResult = await runProcess("git rev-parse HEAD", { cwd: root, timeoutMs: 30_000 });
|
|
107
|
+
return { sourceFingerprint: hash.digest("hex"), gitCommit: commitResult.exitCode === 0 ? commitResult.stdout.trim() : undefined };
|
|
108
|
+
}
|
|
109
|
+
async function fallbackSourceFiles(root) {
|
|
110
|
+
const result = [];
|
|
111
|
+
const visit = async (directory) => {
|
|
112
|
+
for (const entry of await fs.readdir(directory, { withFileTypes: true }).catch(() => [])) {
|
|
113
|
+
const absolute = path.join(directory, entry.name);
|
|
114
|
+
const relative = path.relative(root, absolute).replaceAll("\\", "/");
|
|
115
|
+
if (entry.isDirectory() && !excluded(relative))
|
|
116
|
+
await visit(absolute);
|
|
117
|
+
else if (entry.isFile() && !excluded(relative))
|
|
118
|
+
result.push(relative);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
await visit(root);
|
|
122
|
+
return result;
|
|
45
123
|
}
|
|
124
|
+
function excluded(relative) { return relative === ".git" || relative.startsWith(".git/") || relative === "node_modules" || relative.startsWith("node_modules/") || relative === ".harness" || relative.startsWith(".harness/") || relative === "graphify-out" || relative.startsWith("graphify-out/"); }
|
|
125
|
+
function quote(value) { return `'${value.replaceAll("'", "'\\''")}'`; }
|
|
46
126
|
//# sourceMappingURL=graphify.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../src/providers/graphify.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../src/providers/graphify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import readline from "node:readline";
|
|
3
|
+
export async function runSerenaMcpContract(root, command = "serena") {
|
|
4
|
+
const child = spawn(command, ["start-mcp-server", "--context", "ide-assistant", "--project", root], { cwd: root, stdio: ["pipe", "pipe", "pipe"] });
|
|
5
|
+
const pending = new Map();
|
|
6
|
+
let nextId = 1;
|
|
7
|
+
const lineReader = readline.createInterface({ input: child.stdout });
|
|
8
|
+
lineReader.on("line", (line) => {
|
|
9
|
+
try {
|
|
10
|
+
const message = JSON.parse(line);
|
|
11
|
+
if (typeof message.id !== "number")
|
|
12
|
+
return;
|
|
13
|
+
const request = pending.get(message.id);
|
|
14
|
+
if (!request)
|
|
15
|
+
return;
|
|
16
|
+
pending.delete(message.id);
|
|
17
|
+
if (message.error)
|
|
18
|
+
request.reject(new Error(message.error.message ?? "Serena MCP request failed"));
|
|
19
|
+
else
|
|
20
|
+
request.resolve(message.result);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Serena diagnostics belong on stderr; malformed stdout is handled by
|
|
24
|
+
// the request timeout rather than being treated as a valid response.
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
child.on("error", (error) => {
|
|
28
|
+
for (const request of pending.values())
|
|
29
|
+
request.reject(error instanceof Error ? error : new Error(String(error)));
|
|
30
|
+
pending.clear();
|
|
31
|
+
});
|
|
32
|
+
try {
|
|
33
|
+
const initialized = await request(child, pending, nextId++, "initialize", { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "aeh-provider-contract", version: "1" } });
|
|
34
|
+
child.stdin.write(JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized", params: {} }) + "\n");
|
|
35
|
+
const listed = await request(child, pending, nextId++, "tools/list", {});
|
|
36
|
+
const tools = Array.isArray(listed?.tools) ? listed.tools : [];
|
|
37
|
+
const toolNames = tools.flatMap((tool) => typeof tool.name === "string" ? [tool.name] : []);
|
|
38
|
+
const semanticTool = ["get_symbols_overview", "find_symbol", "find_referencing_symbols"].find((name) => toolNames.includes(name));
|
|
39
|
+
if (!semanticTool)
|
|
40
|
+
throw new Error("Serena MCP did not expose a semantic read-only tool.");
|
|
41
|
+
const args = semanticTool === "get_symbols_overview"
|
|
42
|
+
? { relative_path: "src/serena-fixture.ts", max_answer_chars: 4_000 }
|
|
43
|
+
: { name_path_pattern: "SerenaFixtureSymbol", relative_path: "src/serena-fixture.ts", max_matches: 5 };
|
|
44
|
+
const called = await request(child, pending, nextId++, "tools/call", { name: semanticTool, arguments: args });
|
|
45
|
+
const retrievalText = JSON.stringify(called);
|
|
46
|
+
if (!retrievalText.includes("SerenaFixtureSymbol"))
|
|
47
|
+
throw new Error("Serena semantic retrieval did not return the fixture symbol.");
|
|
48
|
+
return { initialized: Boolean(initialized), toolNames, semanticTool, retrievalText };
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
lineReader.close();
|
|
52
|
+
child.stdin.end();
|
|
53
|
+
await stop(child);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function request(child, pending, id, method, params) {
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
const timer = setTimeout(() => {
|
|
59
|
+
pending.delete(id);
|
|
60
|
+
reject(new Error("Serena MCP request '" + method + "' timed out."));
|
|
61
|
+
}, 45_000);
|
|
62
|
+
pending.set(id, {
|
|
63
|
+
resolve: (value) => { clearTimeout(timer); resolve(value); },
|
|
64
|
+
reject: (error) => { clearTimeout(timer); reject(error); }
|
|
65
|
+
});
|
|
66
|
+
child.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
async function stop(child) {
|
|
70
|
+
if (child.exitCode !== null)
|
|
71
|
+
return;
|
|
72
|
+
await new Promise((resolve) => {
|
|
73
|
+
const timer = setTimeout(() => { child.kill("SIGTERM"); resolve(); }, 5_000);
|
|
74
|
+
child.once("exit", () => { clearTimeout(timer); resolve(); });
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=serenaMcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serenaMcp.js","sourceRoot":"","sources":["../../src/providers/serenaMcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versions.js","sourceRoot":"","sources":["../../src/providers/versions.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,wCAAwC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEpF,MAAM,CAAC,MAAM,gBAAgB,GAAG,QAS/B,CAAC"}
|
package/dist/telemetry/events.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
1
|
import fs from "node:fs/promises";
|
|
3
2
|
import path from "node:path";
|
|
4
|
-
import { trace } from "@opentelemetry/api";
|
|
5
3
|
import { updateCurrentOperationPhase } from "../operations/state.js";
|
|
6
|
-
import {
|
|
7
|
-
|
|
4
|
+
import { finishPhase, finishTracing, markSpanError, safeAttributes, startEventSpan } from "./tracing.js";
|
|
5
|
+
import { SpanStatusCode } from "@opentelemetry/api";
|
|
8
6
|
export async function recordEvent(root, config, name, attributes) {
|
|
9
7
|
const phase = operationPhaseForEvent(name);
|
|
10
8
|
if (phase)
|
|
@@ -13,45 +11,31 @@ export async function recordEvent(root, config, name, attributes) {
|
|
|
13
11
|
return;
|
|
14
12
|
const at = new Date();
|
|
15
13
|
const operationId = typeof attributes.operationId === "string" ? attributes.operationId : typeof attributes.taskId === "string" ? attributes.taskId : undefined;
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
await fs.mkdir(path.dirname(
|
|
27
|
-
await fs.appendFile(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (config.telemetry?.required)
|
|
33
|
-
throw error;
|
|
34
|
-
await fs.appendFile(file, `${JSON.stringify({ at: new Date().toISOString(), name: "harness.telemetry.export.error", attributes: { sourceEvent: name, error: String(error) } })}\n`);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
export function resetOperationTrace(operationId) { if (operationId)
|
|
38
|
-
operationTraces.delete(operationId);
|
|
39
|
-
else
|
|
40
|
-
operationTraces.clear(); }
|
|
41
|
-
function traceFor(operationId, name) {
|
|
42
|
-
const existing = operationTraces.get(operationId);
|
|
43
|
-
const root = !existing || /(?:operation|run|audit)\.start$/.test(name);
|
|
44
|
-
const traceId = root ? crypto.randomBytes(16).toString("hex") : existing.traceId;
|
|
45
|
-
const parentSpanId = root ? undefined : existing.lastSpanId;
|
|
46
|
-
const spanId = crypto.randomBytes(8).toString("hex");
|
|
47
|
-
operationTraces.set(operationId, { traceId, lastSpanId: spanId });
|
|
48
|
-
return { traceId, parentSpanId, spanId };
|
|
14
|
+
const localFile = path.resolve(root, config.telemetry?.localEventsFile ?? ".harness/telemetry/events.ndjson");
|
|
15
|
+
const safe = safeAttributes(attributes);
|
|
16
|
+
const started = startEventSpan(config, operationId, name, phase, { ...safe, "aeh.local_file": localFile });
|
|
17
|
+
const failed = attributes.status === "FAIL" || attributes.status === "FAILED" || typeof attributes.error === "string";
|
|
18
|
+
if (failed)
|
|
19
|
+
markSpanError(started.span, typeof attributes.error === "string" ? attributes.error : undefined);
|
|
20
|
+
else
|
|
21
|
+
started.span.setStatus({ code: SpanStatusCode.OK });
|
|
22
|
+
const spanContext = started.span.spanContext();
|
|
23
|
+
started.span.end();
|
|
24
|
+
await fs.mkdir(path.dirname(localFile), { recursive: true });
|
|
25
|
+
await fs.appendFile(localFile, `${JSON.stringify({ at: at.toISOString(), name, traceId: spanContext.traceId, spanId: spanContext.spanId, parentSpanId: started.parentSpanId, status: failed ? "ERROR" : "OK", attributes: safe })}\n`);
|
|
26
|
+
if (operationId && isPhaseTerminal(name, phase))
|
|
27
|
+
finishPhase(operationId, phase);
|
|
28
|
+
if (operationId && isOperationTerminal(name))
|
|
29
|
+
await finishTracing(config, operationId);
|
|
49
30
|
}
|
|
31
|
+
export function resetOperationTrace(operationId) { void operationId; /* SDK context owns propagation; retained for API compatibility. */ }
|
|
50
32
|
function operationPhaseForEvent(name) {
|
|
51
33
|
if (name === "harness.run.start")
|
|
52
34
|
return "executing";
|
|
53
35
|
if (name.includes("planner") || name.includes("wave"))
|
|
54
36
|
return "planning";
|
|
37
|
+
if (name.includes("verify") || name.includes("validation") || name.includes("graphify"))
|
|
38
|
+
return "validation";
|
|
55
39
|
if (name === "harness.repair.start" || name.includes("remediation"))
|
|
56
40
|
return "remediation";
|
|
57
41
|
if (name.includes("review"))
|
|
@@ -60,6 +44,21 @@ function operationPhaseForEvent(name) {
|
|
|
60
44
|
return "delivery";
|
|
61
45
|
if (name === "harness.audit.start")
|
|
62
46
|
return "preparing-audit";
|
|
47
|
+
if (name.includes("context"))
|
|
48
|
+
return "context";
|
|
49
|
+
if (name.includes("provenance"))
|
|
50
|
+
return "provenance";
|
|
63
51
|
return undefined;
|
|
64
52
|
}
|
|
53
|
+
function isPhaseTerminal(name, phase) {
|
|
54
|
+
if (!phase)
|
|
55
|
+
return false;
|
|
56
|
+
return (phase === "validation" && name === "harness.verify.finish") ||
|
|
57
|
+
(phase === "review" && name === "harness.review.finish") ||
|
|
58
|
+
(phase === "delivery" && name === "harness.delivery.finalize") ||
|
|
59
|
+
(phase === "planning" && name === "harness.plan.ready");
|
|
60
|
+
}
|
|
61
|
+
function isOperationTerminal(name) {
|
|
62
|
+
return new Set(["harness.run.finish", "harness.audit.finish", "harness.change.finish", "harness.quick.finish", "operation.finish", "operation.completed", "operation.failed"]).has(name);
|
|
63
|
+
}
|
|
65
64
|
//# sourceMappingURL=events.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/telemetry/events.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/telemetry/events.ts"],"names":[],"mappings":"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"}
|
package/dist/telemetry/otlp.d.ts
CHANGED
|
@@ -4,5 +4,6 @@ export interface TraceContext {
|
|
|
4
4
|
parentSpanId?: string;
|
|
5
5
|
spanId: string;
|
|
6
6
|
}
|
|
7
|
-
|
|
7
|
+
/** Compatibility entry point backed by the official OpenTelemetry SDK. */
|
|
8
|
+
export declare function exportEventSpan(config: HarnessProjectConfig, name: string, attributes: Record<string, unknown>, _at?: Date, parent?: TraceContext): Promise<void>;
|
|
8
9
|
export declare function resolveEndpoint(config: HarnessProjectConfig): string | undefined;
|
package/dist/telemetry/otlp.js
CHANGED
|
@@ -1,33 +1,26 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { context, trace } from "@opentelemetry/api";
|
|
2
|
+
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
3
|
+
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
4
|
+
import { AlwaysOnSampler, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
5
|
+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
6
|
+
/** Compatibility entry point backed by the official OpenTelemetry SDK. */
|
|
7
|
+
export async function exportEventSpan(config, name, attributes, _at = new Date(), parent) {
|
|
3
8
|
if (config.telemetry?.exporter !== "otlp-http-json")
|
|
4
9
|
return;
|
|
5
10
|
const endpoint = resolveEndpoint(config);
|
|
6
11
|
if (!endpoint)
|
|
7
12
|
throw new Error("OTLP exporter is enabled but no endpoint is configured.");
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
scopeSpans: [{
|
|
13
|
-
scope: { name: "agentic-engineering-harness", version: "0.3.0" },
|
|
14
|
-
spans: [{
|
|
15
|
-
traceId: context?.traceId ?? crypto.randomBytes(16).toString("hex"), spanId: context?.spanId ?? crypto.randomBytes(8).toString("hex"), ...(context?.parentSpanId ? { parentSpanId: context.parentSpanId } : {}), name, kind: 1,
|
|
16
|
-
startTimeUnixNano: nanos, endTimeUnixNano: nanos,
|
|
17
|
-
attributes: Object.entries(attributes).flatMap(([key, value]) => value === undefined || value === null ? [] : [attribute(key, value)]),
|
|
18
|
-
status: { code: 1 }
|
|
19
|
-
}]
|
|
20
|
-
}]
|
|
21
|
-
}]
|
|
22
|
-
};
|
|
23
|
-
const response = await fetch(endpoint, {
|
|
24
|
-
method: "POST",
|
|
25
|
-
headers: { "content-type": "application/json", ...environmentHeaders(), ...(config.telemetry?.headers ?? {}) },
|
|
26
|
-
body: JSON.stringify(payload),
|
|
27
|
-
signal: AbortSignal.timeout(10_000)
|
|
13
|
+
const provider = new NodeTracerProvider({
|
|
14
|
+
sampler: new AlwaysOnSampler(),
|
|
15
|
+
resource: resourceFromAttributes({ "service.name": config.telemetry?.serviceName ?? process.env.OTEL_SERVICE_NAME ?? config.project.name }),
|
|
16
|
+
spanProcessors: [new SimpleSpanProcessor(new OTLPTraceExporter({ url: endpoint, headers: config.telemetry.headers }))]
|
|
28
17
|
});
|
|
29
|
-
|
|
30
|
-
|
|
18
|
+
const parentContext = parent ? trace.setSpanContext(context.active(), spanContext(parent)) : context.active();
|
|
19
|
+
const span = provider.getTracer("agentic-engineering-harness").startSpan(name, { attributes: safeAttributes(attributes) }, parentContext);
|
|
20
|
+
span.setStatus({ code: 1 });
|
|
21
|
+
span.end();
|
|
22
|
+
await provider.forceFlush();
|
|
23
|
+
await provider.shutdown();
|
|
31
24
|
}
|
|
32
25
|
export function resolveEndpoint(config) {
|
|
33
26
|
const signal = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;
|
|
@@ -36,22 +29,8 @@ export function resolveEndpoint(config) {
|
|
|
36
29
|
const configured = config.telemetry?.endpoint ?? process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
37
30
|
if (!configured)
|
|
38
31
|
return undefined;
|
|
39
|
-
return `${configured.replace(/\/$/, "")}/v1/traces`;
|
|
40
|
-
}
|
|
41
|
-
function attribute(key, value) {
|
|
42
|
-
if (typeof value === "boolean")
|
|
43
|
-
return { key, value: { boolValue: value } };
|
|
44
|
-
if (typeof value === "number")
|
|
45
|
-
return Number.isInteger(value) ? { key, value: { intValue: String(value) } } : { key, value: { doubleValue: String(value) } };
|
|
46
|
-
return { key, value: { stringValue: typeof value === "string" ? value : JSON.stringify(value) } };
|
|
47
|
-
}
|
|
48
|
-
function environmentHeaders() {
|
|
49
|
-
const raw = process.env.OTEL_EXPORTER_OTLP_TRACES_HEADERS ?? process.env.OTEL_EXPORTER_OTLP_HEADERS;
|
|
50
|
-
if (!raw)
|
|
51
|
-
return {};
|
|
52
|
-
return Object.fromEntries(raw.split(",").map((part) => part.trim()).filter(Boolean).map((part) => {
|
|
53
|
-
const index = part.indexOf("=");
|
|
54
|
-
return index < 0 ? [part, ""] : [part.slice(0, index), part.slice(index + 1)];
|
|
55
|
-
}));
|
|
32
|
+
return configured.endsWith("/v1/traces") ? configured : `${configured.replace(/\/$/, "")}/v1/traces`;
|
|
56
33
|
}
|
|
34
|
+
function spanContext(value) { return { traceId: value.traceId, spanId: value.parentSpanId ?? value.spanId, traceFlags: 1, isRemote: true }; }
|
|
35
|
+
function safeAttributes(attributes) { return Object.fromEntries(Object.entries(attributes).filter(([, value]) => ["string", "number", "boolean"].includes(typeof value)).map(([key, value]) => [key, typeof value === "string" ? value.slice(0, 500) : value])); }
|
|
57
36
|
//# sourceMappingURL=otlp.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../src/telemetry/otlp.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../src/telemetry/otlp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Context, type Span } from "@opentelemetry/api";
|
|
2
|
+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
3
|
+
import type { HarnessProjectConfig } from "../core/types.js";
|
|
4
|
+
export declare function ensureTracing(config: HarnessProjectConfig): NodeTracerProvider;
|
|
5
|
+
export declare function tracer(config: HarnessProjectConfig): import("@opentelemetry/api").Tracer;
|
|
6
|
+
export declare function startOperationSpan(config: HarnessProjectConfig, operationId: string, attributes: Record<string, unknown>): {
|
|
7
|
+
span: Span;
|
|
8
|
+
context: Context;
|
|
9
|
+
};
|
|
10
|
+
export declare function startEventSpan(config: HarnessProjectConfig, operationId: string | undefined, name: string, phase: string | undefined, attributes: Record<string, unknown>): {
|
|
11
|
+
span: Span;
|
|
12
|
+
parentSpanId?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function finishPhase(operationId: string, phase: string): void;
|
|
15
|
+
export declare function finishTracing(config: HarnessProjectConfig, operationId?: string): Promise<void>;
|
|
16
|
+
export declare function resetTracing(): void;
|
|
17
|
+
export declare function markSpanError(span: Span, error?: unknown): void;
|
|
18
|
+
export declare function safeAttributes(attributes: Record<string, unknown>): Record<string, string | number | boolean | string[]>;
|
|
19
|
+
export declare function configuredTelemetry(): HarnessProjectConfig | undefined;
|