146 lines
4.1 KiB
TypeScript
146 lines
4.1 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { mkdtemp } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { resolve } from "node:path";
|
|
import { loadConfig } from "../src/config.js";
|
|
import type { ActorExecutionInput } from "../src/agents/pipeline.js";
|
|
import {
|
|
buildProviderRuntimeEnv,
|
|
createProviderRunRuntime,
|
|
parseActorExecutionResultFromModelOutput,
|
|
resolveProviderWorkingDirectory,
|
|
type ProviderRunRuntime,
|
|
} from "../src/ui/provider-executor.js";
|
|
|
|
test("parseActorExecutionResultFromModelOutput parses strict JSON payload", () => {
|
|
const parsed = parseActorExecutionResultFromModelOutput({
|
|
rawText: JSON.stringify({
|
|
status: "validation_fail",
|
|
payload: {
|
|
summary: "missing test",
|
|
},
|
|
stateFlags: {
|
|
needs_fix: true,
|
|
},
|
|
stateMetadata: {
|
|
stage: "qa",
|
|
},
|
|
events: [
|
|
{
|
|
type: "validation_failed",
|
|
payload: {
|
|
summary: "failed",
|
|
},
|
|
},
|
|
],
|
|
failureKind: "soft",
|
|
failureCode: "missing_test",
|
|
}),
|
|
});
|
|
|
|
assert.equal(parsed.status, "validation_fail");
|
|
assert.equal(parsed.payload?.summary, "missing test");
|
|
assert.equal(parsed.stateFlags?.needs_fix, true);
|
|
assert.equal(parsed.stateMetadata?.stage, "qa");
|
|
assert.equal(parsed.events?.[0]?.type, "validation_failed");
|
|
assert.equal(parsed.failureKind, "soft");
|
|
assert.equal(parsed.failureCode, "missing_test");
|
|
});
|
|
|
|
test("parseActorExecutionResultFromModelOutput parses fenced JSON", () => {
|
|
const parsed = parseActorExecutionResultFromModelOutput({
|
|
rawText: [
|
|
"Here is the result",
|
|
"```json",
|
|
JSON.stringify({
|
|
status: "success",
|
|
payload: {
|
|
code: "done",
|
|
},
|
|
}),
|
|
"```",
|
|
].join("\n"),
|
|
});
|
|
|
|
assert.equal(parsed.status, "success");
|
|
assert.equal(parsed.payload?.code, "done");
|
|
});
|
|
|
|
test("parseActorExecutionResultFromModelOutput falls back when response is not JSON", () => {
|
|
const parsed = parseActorExecutionResultFromModelOutput({
|
|
rawText: "Implemented update successfully.",
|
|
});
|
|
|
|
assert.equal(parsed.status, "success");
|
|
assert.equal(parsed.payload?.assistantResponse, "Implemented update successfully.");
|
|
});
|
|
|
|
test("resolveProviderWorkingDirectory reads cwd from actor execution context", () => {
|
|
const actorInput = {
|
|
executionContext: {
|
|
security: {
|
|
worktreePath: "/tmp/session/tasks/product-intake",
|
|
},
|
|
},
|
|
} as unknown as ActorExecutionInput;
|
|
|
|
assert.equal(
|
|
resolveProviderWorkingDirectory(actorInput),
|
|
"/tmp/session/tasks/product-intake",
|
|
);
|
|
});
|
|
|
|
test("buildProviderRuntimeEnv scopes AGENT_WORKTREE_PATH to actor worktree and filters undefined auth", () => {
|
|
const config = loadConfig({
|
|
CLAUDE_CODE_OAUTH_TOKEN: "oauth-token",
|
|
});
|
|
const runtime = {
|
|
provider: "claude",
|
|
config,
|
|
sharedEnv: {
|
|
PATH: "/usr/bin",
|
|
KEEP_ME: "1",
|
|
},
|
|
claudeObservability: {} as ProviderRunRuntime["claudeObservability"],
|
|
close: async () => {},
|
|
} satisfies ProviderRunRuntime;
|
|
const actorInput = {
|
|
executionContext: {
|
|
security: {
|
|
worktreePath: "/tmp/session/tasks/product-intake",
|
|
},
|
|
},
|
|
} as unknown as ActorExecutionInput;
|
|
|
|
const env = buildProviderRuntimeEnv({
|
|
runtime,
|
|
actorInput,
|
|
includeClaudeAuth: true,
|
|
});
|
|
|
|
assert.equal(env.AGENT_WORKTREE_PATH, "/tmp/session/tasks/product-intake");
|
|
assert.equal(env.CLAUDE_CODE_OAUTH_TOKEN, "oauth-token");
|
|
assert.equal("ANTHROPIC_API_KEY" in env, false);
|
|
assert.equal(env.KEEP_ME, "1");
|
|
});
|
|
|
|
test("createProviderRunRuntime does not require session context provisioning", async () => {
|
|
const observabilityRoot = await mkdtemp(resolve(tmpdir(), "ai-ops-provider-runtime-"));
|
|
const runtime = await createProviderRunRuntime({
|
|
provider: "claude",
|
|
config: loadConfig({}),
|
|
observabilityRootPath: observabilityRoot,
|
|
baseEnv: {
|
|
PATH: "/usr/bin",
|
|
},
|
|
});
|
|
|
|
try {
|
|
assert.equal(runtime.provider, "claude");
|
|
assert.equal(runtime.sharedEnv.PATH, "/usr/bin");
|
|
} finally {
|
|
await runtime.close();
|
|
}
|
|
});
|