Files
united-workforce/packages/workflow-util-role/__tests__/extract-meta.test.ts
T
xiaoju c04e7c31af refactor: move llmExtract, extractMeta, buildDescriptor, types to workflow-util-role
workflow-role-llm now only contains LLM-as-agent specifics:
  - createRole (wires agent + extract)
  - createLlmAdapter (OpenAI chat completions agent)

workflow-util-role now provides all role infrastructure:
  - decorators (decorateRole, withDryRun, onFail)
  - llmExtract / extractMetaOrThrow (structured extraction)
  - buildDescriptorFromRoles (zod → JSON Schema)
  - LlmProvider, LlmMessage types
2026-05-06 08:13:27 +00:00

103 lines
2.7 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import * as z from "zod/v4";
import { extractMetaOrThrow } from "../src/extract-meta.js";
const provider = {
baseUrl: "https://example.com/v1",
apiKey: "k",
model: "m",
};
describe("extractMetaOrThrow", () => {
const originalFetch = globalThis.fetch;
test("dryRun returns dryRunMeta without calling fetch", async () => {
let calls = 0;
globalThis.fetch = () => {
calls += 1;
return Promise.resolve(new Response("{}", { status: 200 }));
};
const schema = z.object({ n: z.number() });
const out = await extractMetaOrThrow("r", "raw", schema, {
provider,
dryRun: true,
dryRunMeta: { n: 7 },
});
globalThis.fetch = originalFetch;
expect(calls).toBe(0);
expect(out).toEqual({ n: 7 });
});
test("throws when extraction fails after retry", async () => {
globalThis.fetch = () =>
Promise.resolve(
new Response(
JSON.stringify({
choices: [
{
message: {
tool_calls: [
{ function: { name: "extract", arguments: JSON.stringify({ n: "bad" }) } },
],
},
},
],
}),
{ status: 200, headers: { "Content-Type": "application/json" } },
),
);
const schema = z.object({ n: z.number() });
await expect(
extractMetaOrThrow("plan", "text", schema, { provider, dryRun: false, dryRunMeta: { n: 0 } }),
).rejects.toThrow(/structured extraction failed after retry/);
globalThis.fetch = originalFetch;
});
test("returns validated meta on successful tool call", async () => {
globalThis.fetch = () =>
Promise.resolve(
new Response(
JSON.stringify({
choices: [
{
message: {
tool_calls: [
{
function: {
name: "extract",
arguments: JSON.stringify({ branch: "feat/x", message: "feat: y" }),
},
},
],
},
},
],
}),
{ status: 200, headers: { "Content-Type": "application/json" } },
),
);
const schema = z.object({
branch: z.string(),
message: z.string(),
});
const out = await extractMetaOrThrow("committer-plan", "plan text", schema, {
provider,
dryRun: false,
dryRunMeta: { branch: "", message: "" },
});
globalThis.fetch = originalFetch;
expect(out).toEqual({ branch: "feat/x", message: "feat: y" });
});
});