Repository navigation
Expand file tree
/
Copy pathbasic.ts
More file actions
86 lines (82 loc) · 2.82 KB
/
Copy pathbasic.ts
File metadata and controls
86 lines (82 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { braid, type BraidInput, type ModelRunner } from "../src/index.js";
import { createOpenAICompatibleRunner } from "../src/adapters/openai.js";
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
const input: BraidInput = {
goal: "Compare the benefits and risks of adopting a four-day work week.",
nodes: [
{
type: "decision",
id: "route",
prompt: "Choose whether this goal needs a comparison or a short answer.",
choices: ["compare", "brief"],
},
{
type: "execute",
id: "benefits",
prompt: "Explain the main potential benefits.",
},
{
type: "execute",
id: "risks",
prompt: "Explain the main risks and uncertainties.",
},
{
type: "execute",
id: "answer",
prompt: "Synthesize both perspectives into a balanced recommendation.",
},
{
type: "execute",
id: "brief",
prompt: "Give a concise answer to the goal.",
},
],
edges: [
{ from: "route", to: "benefits", choice: "compare" },
{ from: "route", to: "risks", choice: "compare" },
{ from: "benefits", to: "answer" },
{ from: "risks", to: "answer" },
{ from: "route", to: "brief", choice: "brief" },
],
};
// Deterministic stand-in for a provider. No network calls or token estimates.
let runner: ModelRunner = async (request) => {
if (request.decide) {
request.decide("compare");
return { output: "A comparison needs both benefits and risks." };
}
if (request.node.id === "benefits")
return { output: "A shorter week may improve work-life balance." };
if (request.node.id === "risks")
return { output: "Coverage and workload compression need evaluation." };
return {
output:
request.predecessors
.map((item) => `[${item.nodeId}] ${item.output}`)
.join("\n") +
"\nRecommendation: test a time-limited pilot with explicit success criteria.",
};
};
let defaultModel = "demo";
// Live calls are opt-in: OPENAI_API_KEY=... BRAID_MODEL=... npm run demo -- --live
if (process.argv.includes("--live")) {
const apiKey = process.env.OPENAI_API_KEY;
const model = process.env.BRAID_MODEL;
const baseURL = process.env.OPENAI_BASE_URL;
if (!apiKey || !model)
throw new Error("--live requires OPENAI_API_KEY and BRAID_MODEL");
defaultModel = model;
runner = createOpenAICompatibleRunner({
apiKey,
...(baseURL ? { baseURL } : {}),
});
}
// This text-only demo runs outside Git and needs no repository workspaces.
const cwd = await mkdtemp(join(tmpdir(), "braid-demo-"));
try {
const result = await braid(input, { cwd, runner, defaultModel, maxConcurrency: 2 });
console.log(JSON.stringify(result, null, 2));
if (result.status === "failed") process.exitCode = 1;
} finally { await rm(cwd, { recursive: true, force: true }); }