dbx/tests/aiAgentStepPresentation.tes...

149 lines
4.8 KiB
TypeScript

import { strict as assert } from "node:assert";
import test from "node:test";
import { buildAiAgentStepItems } from "../src/lib/aiAgentStepPresentation.ts";
import type { AiAgentPlan } from "../src/lib/aiAgentPlan.ts";
test("presents auto-execute agent plans as completed generation, safety, and execution steps", () => {
const plan: AiAgentPlan = {
executableSql: "SELECT count(*) FROM users",
handoffSql: "SELECT count(*) FROM users",
steps: [
{ kind: "generate_sql", status: "done", sql: "SELECT count(*) FROM users" },
{
kind: "risk_check",
status: "done",
action: "auto_execute",
environment: "non_production",
category: "read",
reasons: [],
},
{ kind: "execute_sql", status: "pending", sql: "SELECT count(*) FROM users" },
],
};
assert.deepEqual(buildAiAgentStepItems(plan), [
{ key: "generated", labelKey: "ai.agentSteps.generated", tone: "success" },
{
key: "safe",
labelKey: "ai.agentSteps.safe",
titleKey: "ai.agentStepTitles.riskCheck",
titleParams: { action: "auto_execute", category: "read", environment: "non_production", reasons: "-" },
tone: "success",
},
{ key: "autoExecute", labelKey: "ai.agentSteps.autoExecute", tone: "active" },
]);
});
test("presents blocked and confirmation plans with warning tones", () => {
const blocked: AiAgentPlan = {
handoffSql: "DROP TABLE users",
steps: [
{ kind: "generate_sql", status: "done", sql: "DROP TABLE users" },
{
kind: "risk_check",
status: "done",
action: "block",
environment: "non_production",
category: "dangerous",
reasons: [],
},
{ kind: "execute_sql", status: "skipped", reason: "blocked_by_policy" },
],
};
const confirm: AiAgentPlan = {
handoffSql: "INSERT INTO users(name) VALUES ('a')",
steps: [
{ kind: "generate_sql", status: "done", sql: "INSERT INTO users(name) VALUES ('a')" },
{
kind: "risk_check",
status: "done",
action: "confirm",
environment: "production",
category: "low_risk_write",
reasons: [],
},
{ kind: "execute_sql", status: "skipped", reason: "requires_confirmation" },
],
};
assert.deepEqual(
buildAiAgentStepItems(blocked).map((item) => [item.labelKey, item.tone, item.titleKey, item.titleParams]),
[
["ai.agentSteps.generated", "success", undefined, undefined],
[
"ai.agentSteps.blocked",
"danger",
"ai.agentStepTitles.riskCheck",
{ action: "block", category: "dangerous", environment: "non_production", reasons: "-" },
],
["ai.agentSteps.skipped", "muted", "ai.agentStepTitles.blocked", undefined],
],
);
assert.deepEqual(
buildAiAgentStepItems(confirm).map((item) => [item.labelKey, item.tone, item.titleKey, item.titleParams]),
[
["ai.agentSteps.generated", "success", undefined, undefined],
[
"ai.agentSteps.needsConfirm",
"warning",
"ai.agentStepTitles.riskCheck",
{ action: "confirm", category: "low_risk_write", environment: "production", reasons: "-" },
],
["ai.agentSteps.skipped", "muted", "ai.agentStepTitles.requiresConfirmation", undefined],
],
);
});
test("includes risk reasons in risk check titles", () => {
const plan: AiAgentPlan = {
handoffSql: "INSERT INTO users(name) VALUES ('a'); UPDATE users SET name='b' WHERE id=1",
steps: [
{
kind: "risk_check",
status: "done",
action: "confirm",
environment: "non_production",
category: "write",
reasons: ["multi_statement"],
},
],
};
assert.deepEqual(buildAiAgentStepItems(plan)[0], {
key: "needsConfirm",
labelKey: "ai.agentSteps.needsConfirm",
titleKey: "ai.agentStepTitles.riskCheck",
titleParams: {
action: "confirm",
category: "write",
environment: "non_production",
reasons: "multi_statement",
},
tone: "warning",
});
});
test("presents no-sql and no-intent plans as muted skipped states", () => {
const noSql: AiAgentPlan = {
steps: [
{ kind: "generate_sql", status: "skipped", reason: "no_sql" },
{ kind: "execute_sql", status: "skipped", reason: "no_sql" },
],
};
const noIntent: AiAgentPlan = {
steps: [
{ kind: "generate_sql", status: "done", sql: "SELECT count(*) FROM users" },
{ kind: "execute_sql", status: "skipped", reason: "no_execution_intent" },
],
};
assert.deepEqual(
buildAiAgentStepItems(noSql).map((item) => item.labelKey),
["ai.agentSteps.noSql", "ai.agentSteps.skipped"],
);
assert.deepEqual(
buildAiAgentStepItems(noIntent).map((item) => item.labelKey),
["ai.agentSteps.generated", "ai.agentSteps.notRequested"],
);
});