big-tools 0.0.1

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.
Files changed (48) hide show
  1. package/LICENSE +26 -0
  2. package/PRIVACY.md +81 -0
  3. package/README.md +112 -0
  4. package/corpus/CONTRIBUTORS.md +35 -0
  5. package/corpus/LICENSE +22 -0
  6. package/dist/cli.js +100 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/between-sessions.js +10 -0
  9. package/dist/commands/between-sessions.js.map +1 -0
  10. package/dist/commands/config.js +54 -0
  11. package/dist/commands/config.js.map +1 -0
  12. package/dist/commands/delphi.js +10 -0
  13. package/dist/commands/delphi.js.map +1 -0
  14. package/dist/commands/discovery-actionability.js +15 -0
  15. package/dist/commands/discovery-actionability.js.map +1 -0
  16. package/dist/commands/easy-on-people.js +9 -0
  17. package/dist/commands/easy-on-people.js.map +1 -0
  18. package/dist/commands/ideawriting.js +7 -0
  19. package/dist/commands/ideawriting.js.map +1 -0
  20. package/dist/commands/ngt.js +49 -0
  21. package/dist/commands/ngt.js.map +1 -0
  22. package/dist/commands/paper-house.js +44 -0
  23. package/dist/commands/paper-house.js.map +1 -0
  24. package/dist/commands/selfish-explorer.js +9 -0
  25. package/dist/commands/selfish-explorer.js.map +1 -0
  26. package/dist/lib/big-template.js +165 -0
  27. package/dist/lib/big-template.js.map +1 -0
  28. package/dist/lib/config-store.js +64 -0
  29. package/dist/lib/config-store.js.map +1 -0
  30. package/dist/lib/corpus.js +21 -0
  31. package/dist/lib/corpus.js.map +1 -0
  32. package/dist/lib/format.js +14 -0
  33. package/dist/lib/format.js.map +1 -0
  34. package/dist/lib/plm-types.js +17 -0
  35. package/dist/lib/plm-types.js.map +1 -0
  36. package/dist/lib/provider.js +270 -0
  37. package/dist/lib/provider.js.map +1 -0
  38. package/dist/lib/queue.js +31 -0
  39. package/dist/lib/queue.js.map +1 -0
  40. package/dist/lib/resolve-provider.js +49 -0
  41. package/dist/lib/resolve-provider.js.map +1 -0
  42. package/dist/lib/retry.js +219 -0
  43. package/dist/lib/retry.js.map +1 -0
  44. package/dist/lib/style-audit.js +20 -0
  45. package/dist/lib/style-audit.js.map +1 -0
  46. package/dist/types.js +2 -0
  47. package/dist/types.js.map +1 -0
  48. package/package.json +44 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selfish-explorer.js","sourceRoot":"","sources":["../../src/commands/selfish-explorer.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,IAA4B;IAC9E,yFAAyF;IACzF,yEAAyE;IACzE,iEAAiE;IACjE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,kDAAkD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * BIG Idea Explorer template.
3
+ *
4
+ * Encodes Carl Moore's 1987 methodology (NGT, Ideawriting, Delphi, ISM)
5
+ * as a PLM template for structured ideation. Originally designed for
6
+ * Brown Practicum students.
7
+ *
8
+ * Four phases: Generate → Develop → Select → Promote
9
+ *
10
+ * Source: DEVO packages/plm/src/templates/big-idea-explorer.ts
11
+ * Canonical faculty-endorsed phase names from the 2026-04-06 M/V/V rework
12
+ * (see DevLex memory/project_brown_practicum.md lines 73-95).
13
+ */
14
+ export const bigIdeaExplorerTemplate = {
15
+ id: "big-idea-explorer",
16
+ name: "BIG Idea Explorer",
17
+ description: "Structured ideation using Carl Moore's BIG methodology (NGT, Ideawriting, Delphi, ISM). " +
18
+ "Four phases guide you from problem space mapping through idea development, evaluation, and presentation.",
19
+ category: "methodology",
20
+ seedMandate: {
21
+ description: "Explore and develop innovative ideas through structured ideation. " +
22
+ "Map the problem space, develop ideas with diverse perspectives, evaluate rigorously, and produce shareable artifacts.",
23
+ goals: [
24
+ "Map what I know, don't know, and am assuming about the problem space",
25
+ "Develop ideas through multi-perspective fireside chat exploration",
26
+ "Evaluate ideas by feasibility, novelty, and supporting evidence",
27
+ "Produce structured artifacts (hypothesis cards, evidence summaries) for sharing",
28
+ ],
29
+ },
30
+ interactionPatterns: [
31
+ {
32
+ id: "generate",
33
+ phase: "Generate",
34
+ name: "Problem Space Mapping",
35
+ description: "Silent generation + expansion, mirroring Nominal Group Technique (NGT). " +
36
+ "Systematically map what you know, don't know, and are assuming.",
37
+ prompts: [
38
+ "What do you already know about this problem space? List everything — facts, observations, prior experience.",
39
+ "What don't you know? What questions remain unanswered? What data is missing?",
40
+ "What are you assuming? Which of your 'knowns' might actually be assumptions?",
41
+ "Looking at your assumptions, which ones would change your approach most if they turned out to be wrong?",
42
+ ],
43
+ completionSignal: "Problem space mapped with knowns, unknowns, and assumptions identified",
44
+ activeAgents: ["corpus-search", "literature-review"],
45
+ },
46
+ {
47
+ id: "develop",
48
+ phase: "Develop",
49
+ name: "Fireside Chat",
50
+ description: "Multi-perspective idea development using a panel of personas. " +
51
+ "3 user-chosen + 2 AI-suggested domain experts explore the problem together.",
52
+ prompts: [
53
+ "Choose 3 perspectives you want at the table (e.g., 'skeptical engineer', 'end user', 'investor').",
54
+ "Based on your problem space, I suggest adding these 2 perspectives: [AI-generated based on domain].",
55
+ "Let's explore: each perspective shares their reaction to the problem space map.",
56
+ "What new connections emerged? What surprised you?",
57
+ ],
58
+ completionSignal: "Ideas developed through multi-perspective exploration",
59
+ activeAgents: ["multi-llm-consultation", "patent-search", "red-team"],
60
+ },
61
+ {
62
+ id: "select",
63
+ phase: "Select",
64
+ name: "Evaluate & Converge",
65
+ description: "Score ideas by feasibility, novelty, and evidence strength. " +
66
+ "Red-team promising ideas. Kill or promote.",
67
+ prompts: [
68
+ "Let's evaluate each idea. For each: how feasible? how novel? what evidence supports it?",
69
+ "Which ideas should we red-team? What's the strongest argument against each?",
70
+ "Based on evaluation, which ideas do we kill, which do we promote?",
71
+ ],
72
+ completionSignal: "Ideas evaluated and filtered — promoted ideas identified",
73
+ activeAgents: ["red-team", "corpus-search"],
74
+ },
75
+ {
76
+ id: "promote",
77
+ phase: "Promote",
78
+ name: "Share & Present",
79
+ description: "Generate structured artifacts for external presentation — " +
80
+ "hypothesis cards, evidence summaries, and presentation outlines.",
81
+ prompts: [
82
+ "For each promoted idea, let's create a hypothesis card: claim, evidence, confidence, next steps.",
83
+ "What's the narrative arc? How do these ideas connect into a compelling story?",
84
+ "Generate a shareable summary for your audience.",
85
+ ],
86
+ completionSignal: "Artifacts generated and ready for sharing",
87
+ activeAgents: ["corpus-search"],
88
+ },
89
+ ],
90
+ agentPresets: [
91
+ {
92
+ id: "patent-search",
93
+ name: "Patent Search",
94
+ role: "Prior art discovery",
95
+ description: "Searches patent databases for related innovations and prior art",
96
+ templateId: "patent-search-agent",
97
+ },
98
+ {
99
+ id: "multi-llm-consultation",
100
+ name: "Multi-LLM Consultation",
101
+ role: "Cross-model ideation",
102
+ description: "Consults multiple LLMs for diverse perspectives on the problem",
103
+ templateId: "multi-llm-agent",
104
+ },
105
+ {
106
+ id: "red-team",
107
+ name: "Red Team",
108
+ role: "Critical evaluation",
109
+ description: "Challenges ideas with counterarguments and identifies weaknesses",
110
+ templateId: "red-team-agent",
111
+ },
112
+ {
113
+ id: "corpus-search",
114
+ name: "Corpus Search",
115
+ role: "Knowledge retrieval",
116
+ description: "Searches the PLM's corpus for relevant prior knowledge and connections",
117
+ templateId: "corpus-search-agent",
118
+ },
119
+ {
120
+ id: "literature-review",
121
+ name: "Literature Review",
122
+ role: "Academic research",
123
+ description: "Searches academic databases for relevant research papers and findings",
124
+ templateId: "literature-review-agent",
125
+ },
126
+ ],
127
+ trailSeeds: [
128
+ "innovation methodology",
129
+ "problem framing techniques",
130
+ "idea evaluation criteria",
131
+ "structured ideation",
132
+ "design thinking",
133
+ ],
134
+ suggestedSources: [
135
+ {
136
+ name: "Google Scholar Alerts",
137
+ type: "rss",
138
+ config: { feedUrl: "" },
139
+ description: "Set up Google Scholar alerts for your research domain (configure after creation)",
140
+ },
141
+ {
142
+ name: "Industry Publications",
143
+ type: "rss",
144
+ config: { feedUrl: "" },
145
+ description: "Add RSS feeds from publications relevant to your problem domain",
146
+ },
147
+ ],
148
+ author: "Private Language",
149
+ version: "1.0.0",
150
+ tags: ["ideation", "big-methodology", "carl-moore", "ngt", "brown-practicum"],
151
+ };
152
+ /**
153
+ * Lookup helper — get one interaction pattern by phase id.
154
+ *
155
+ * Added for big-tools command layer: each CLI subcommand can fetch its
156
+ * phase-specific guided prompts without the caller iterating the array.
157
+ */
158
+ export function getPhase(phaseId) {
159
+ const pattern = bigIdeaExplorerTemplate.interactionPatterns.find((p) => p.id === phaseId);
160
+ if (!pattern) {
161
+ throw new Error(`BIG template missing phase: ${phaseId}`);
162
+ }
163
+ return pattern;
164
+ }
165
+ //# sourceMappingURL=big-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"big-template.js","sourceRoot":"","sources":["../../src/lib/big-template.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Config file I/O for big-tools.
3
+ *
4
+ * Owns ~/.config/big-tools/config.json (or XDG_CONFIG_HOME override).
5
+ * Atomic writes via tmp+rename. Mode 0o600 for API key safety.
6
+ */
7
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
8
+ import { homedir } from "node:os";
9
+ import { join } from "node:path";
10
+ /** Resolved directory for config files. Accepts override for testing. */
11
+ export function configDir(override) {
12
+ if (override)
13
+ return override;
14
+ const base = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
15
+ return join(base, "big-tools");
16
+ }
17
+ /** Full path to config.json. */
18
+ export function configPath(dirOverride) {
19
+ return join(configDir(dirOverride), "config.json");
20
+ }
21
+ /** Read the entire config. Returns {} if file does not exist. */
22
+ export function readConfig(dirOverride) {
23
+ const p = configPath(dirOverride);
24
+ if (!existsSync(p))
25
+ return {};
26
+ const raw = readFileSync(p, "utf-8");
27
+ try {
28
+ const parsed = JSON.parse(raw);
29
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
30
+ return parsed;
31
+ }
32
+ return {};
33
+ }
34
+ catch {
35
+ throw new Error(`Config file is not valid JSON: ${p}\n` +
36
+ `Delete it and re-run: big-tools config set <key> <value>`);
37
+ }
38
+ }
39
+ /** Write a single key. Creates directory + file if absent. Atomic rename. */
40
+ export function writeConfig(key, value, dirOverride) {
41
+ const dir = configDir(dirOverride);
42
+ const p = configPath(dirOverride);
43
+ const data = readConfig(dirOverride);
44
+ data[key] = value;
45
+ flush(p, dir, data);
46
+ }
47
+ /** Delete a key. No-op if key is absent. */
48
+ export function deleteConfig(key, dirOverride) {
49
+ const dir = configDir(dirOverride);
50
+ const p = configPath(dirOverride);
51
+ const data = readConfig(dirOverride);
52
+ if (!(key in data))
53
+ return;
54
+ delete data[key];
55
+ flush(p, dir, data);
56
+ }
57
+ /** Atomic write: tmp file → rename. */
58
+ function flush(filePath, dir, data) {
59
+ mkdirSync(dir, { recursive: true });
60
+ const tmp = filePath + ".tmp";
61
+ writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 0o600 });
62
+ renameSync(tmp, filePath);
63
+ }
64
+ //# sourceMappingURL=config-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-store.js","sourceRoot":"","sources":["../../src/lib/config-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ // Corpus loader — walks the shipped corpus/ directory and builds a searchable
2
+ // in-memory index via minisearch. Falls back to plain-text grep if minisearch
3
+ // unavailable.
4
+ //
5
+ // Each corpus file has YAML frontmatter with provenance metadata:
6
+ // author: string
7
+ // date_committed: YYYY-MM-DD
8
+ // license: string
9
+ // scope_tag: public | stephen-only | class-opt-in
10
+ //
11
+ // TODO (day 04-20): implement
12
+ // - walkCorpus(dir): CorpusEntry[]
13
+ // - buildIndex(entries): MiniSearch
14
+ // - search(query, opts): CorpusHit[]
15
+ export async function loadCorpus(_dir) {
16
+ throw new Error("loadCorpus not yet implemented");
17
+ }
18
+ export async function searchCorpus(_query, _limit = 5) {
19
+ throw new Error("searchCorpus not yet implemented");
20
+ }
21
+ //# sourceMappingURL=corpus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus.js","sourceRoot":"","sources":["../../src/lib/corpus.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8EAA8E;AAC9E,eAAe;AACf,EAAE;AACF,kEAAkE;AAClE,mBAAmB;AACnB,+BAA+B;AAC/B,oBAAoB;AACpB,oDAAoD;AACpD,EAAE;AACF,8BAA8B;AAC9B,qCAAqC;AACrC,sCAAsC;AACtC,uCAAuC;AAkBvC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc,EAAE,MAAM,GAAG,CAAC;IAC3D,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,14 @@
1
+ // Output formatting — human-readable text (default) or JSON (--json flag).
2
+ //
3
+ // Human mode uses Carl's vocabulary. JSON mode uses raw field names.
4
+ //
5
+ // TODO (day 04-17): implement
6
+ export function print(result, asJson) {
7
+ if (asJson) {
8
+ console.log(JSON.stringify(result, null, 2));
9
+ }
10
+ else {
11
+ console.log(result.output);
12
+ }
13
+ }
14
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/lib/format.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,qEAAqE;AACrE,EAAE;AACF,8BAA8B;AAI9B,MAAM,UAAU,KAAK,CAAC,MAAqB,EAAE,MAAe;IAC1D,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * PLM Product Layer Types
3
+ *
4
+ * Core type definitions for Private Language Models.
5
+ *
6
+ * Source: DEVO packages/plm/src/types.ts (verbatim copy)
7
+ * DEVO refs: ADR-029 (PLM Product Layer), ADR-030 (Source Connectors), ADR-031 (Templates).
8
+ */
9
+ /** Triage relevance thresholds. */
10
+ export const TRIAGE_THRESHOLDS = {
11
+ /** >= this score → auto-ingest */
12
+ autoIngest: 0.6,
13
+ /** >= this score → queue for review */
14
+ review: 0.3,
15
+ /** below review → discard */
16
+ };
17
+ //# sourceMappingURL=plm-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plm-types.js","sourceRoot":"","sources":["../../src/lib/plm-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkIH,mCAAmC;AACnC,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,kCAAkC;IAClC,UAAU,EAAE,GAAG;IACf,uCAAuC;IACvC,MAAM,EAAE,GAAG;IACX,6BAA6B;CACrB,CAAC"}
@@ -0,0 +1,270 @@
1
+ /**
2
+ * OpenRouter LLM Client
3
+ *
4
+ * Unified access to multiple LLM providers through OpenRouter.
5
+ * https://openrouter.ai/docs
6
+ *
7
+ * Includes exponential backoff retry for rate limits and transient errors.
8
+ *
9
+ * Source: DEVO packages/cortex/src/llm/openrouter.ts (adapted)
10
+ * Adaptations from DEVO:
11
+ * - Removed circuit breaker (not portable — lives in DEVO's @devo/cortex/reliability)
12
+ * - Removed rate limiter (same reason; big-tools handles parallel/serial in queue.ts)
13
+ * - Removed executeProtected() wrapper (was the circuit breaker + rate limiter hook)
14
+ * - Retry wrapping retained via local retry.ts (also copied from DEVO)
15
+ *
16
+ * Provider selection precedence (implemented at the selectProvider() level):
17
+ * 1. explicit model via --model flag
18
+ * 2. BIG_TOOLS_MODEL env var
19
+ * 3. ~/.config/big-tools/config.json model field
20
+ * 4. BYO detection: OPENROUTER_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY
21
+ * 5. OpenRouter free-tier default model (requires OPENROUTER_API_KEY)
22
+ */
23
+ import { withRetryThrow } from "./retry.js";
24
+ // =============================================================================
25
+ // Popular Models
26
+ // =============================================================================
27
+ export const MODELS = {
28
+ // OpenAI
29
+ GPT_4O: "openai/gpt-4o",
30
+ GPT_4O_MINI: "openai/gpt-4o-mini",
31
+ GPT_4_TURBO: "openai/gpt-4-turbo",
32
+ // Anthropic
33
+ CLAUDE_3_5_SONNET: "anthropic/claude-3.5-sonnet",
34
+ CLAUDE_3_5_HAIKU: "anthropic/claude-3-5-haiku",
35
+ CLAUDE_3_OPUS: "anthropic/claude-3-opus",
36
+ // Google
37
+ GEMINI_2_FLASH: "google/gemini-2.0-flash-001",
38
+ GEMINI_PRO_1_5: "google/gemini-pro-1.5",
39
+ GEMINI_FLASH_1_5: "google/gemini-flash-1.5",
40
+ // Meta
41
+ LLAMA_3_3_70B: "meta-llama/llama-3.3-70b-instruct",
42
+ LLAMA_3_1_405B: "meta-llama/llama-3.1-405b-instruct",
43
+ // Mistral
44
+ MISTRAL_LARGE: "mistralai/mistral-large-latest",
45
+ MIXTRAL_8X22B: "mistralai/mixtral-8x22b-instruct",
46
+ // DeepSeek
47
+ DEEPSEEK_CHAT: "deepseek/deepseek-chat",
48
+ DEEPSEEK_R1: "deepseek/deepseek-r1",
49
+ // Qwen
50
+ QWEN_2_5_72B: "qwen/qwen-2.5-72b-instruct",
51
+ };
52
+ /**
53
+ * OpenRouter free-tier model roster. The default model is whichever of
54
+ * these is currently available; fall back in order on first failure.
55
+ *
56
+ * Students without a paid key can use any of these without charge.
57
+ * The list is a config constant — update it when OpenRouter's free
58
+ * menu changes.
59
+ */
60
+ export const FREE_MODELS = [
61
+ "meta-llama/llama-3.1-8b-instruct:free",
62
+ "google/gemini-flash-1.5:free",
63
+ "mistralai/mistral-7b-instruct:free",
64
+ ];
65
+ export const DEFAULT_FREE_MODEL = FREE_MODELS[0];
66
+ // =============================================================================
67
+ // Client
68
+ // =============================================================================
69
+ const OPENROUTER_API_URL = "https://openrouter.ai/api/v1";
70
+ /** Default retry config for LLM calls. */
71
+ const DEFAULT_LLM_RETRY = {
72
+ maxRetries: 3,
73
+ initialDelayMs: 1000,
74
+ maxDelayMs: 60000, // LLM calls can have longer backoff
75
+ };
76
+ /**
77
+ * Custom error that includes HTTP status for retry logic.
78
+ */
79
+ class OpenRouterError extends Error {
80
+ status;
81
+ constructor(message, status) {
82
+ super(message);
83
+ this.status = status;
84
+ this.name = "OpenRouterError";
85
+ }
86
+ }
87
+ export class OpenRouterClient {
88
+ config;
89
+ retryConfig;
90
+ constructor(config) {
91
+ this.config = {
92
+ apiKey: config.apiKey,
93
+ defaultModel: config.defaultModel ?? DEFAULT_FREE_MODEL,
94
+ siteUrl: config.siteUrl,
95
+ siteName: config.siteName,
96
+ };
97
+ this.retryConfig = config.retry ?? DEFAULT_LLM_RETRY;
98
+ }
99
+ /** Get the default model */
100
+ get defaultModel() {
101
+ return this.config.defaultModel;
102
+ }
103
+ /**
104
+ * Create a chat completion.
105
+ */
106
+ async chat(request) {
107
+ const model = request.model ?? this.config.defaultModel;
108
+ const doChat = async () => {
109
+ const response = await fetch(`${OPENROUTER_API_URL}/chat/completions`, {
110
+ method: "POST",
111
+ headers: this.buildHeaders(),
112
+ body: JSON.stringify({
113
+ model,
114
+ messages: request.messages,
115
+ temperature: request.temperature,
116
+ max_tokens: request.maxTokens,
117
+ top_p: request.topP,
118
+ stream: false,
119
+ }),
120
+ });
121
+ if (!response.ok) {
122
+ const error = (await response.json().catch(() => ({})));
123
+ const nested = error.error;
124
+ throw new OpenRouterError(nested?.message ?? `OpenRouter API error: ${response.status}`, response.status);
125
+ }
126
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
+ const data = (await response.json());
128
+ const choice = data.choices[0];
129
+ return {
130
+ id: data.id,
131
+ model: data.model,
132
+ content: choice.message.content,
133
+ usage: {
134
+ promptTokens: data.usage?.prompt_tokens ?? 0,
135
+ completionTokens: data.usage?.completion_tokens ?? 0,
136
+ totalTokens: data.usage?.total_tokens ?? 0,
137
+ },
138
+ finishReason: choice.finish_reason,
139
+ };
140
+ };
141
+ if (this.retryConfig === false) {
142
+ return doChat();
143
+ }
144
+ return withRetryThrow(doChat, this.retryConfig);
145
+ }
146
+ /**
147
+ * Create a streaming chat completion.
148
+ *
149
+ * Note: Retry only applies to initial connection establishment.
150
+ * Once streaming begins, errors are not retried.
151
+ */
152
+ async *chatStream(request) {
153
+ const model = request.model ?? this.config.defaultModel;
154
+ const getResponse = async () => {
155
+ const response = await fetch(`${OPENROUTER_API_URL}/chat/completions`, {
156
+ method: "POST",
157
+ headers: this.buildHeaders(),
158
+ body: JSON.stringify({
159
+ model,
160
+ messages: request.messages,
161
+ temperature: request.temperature,
162
+ max_tokens: request.maxTokens,
163
+ top_p: request.topP,
164
+ stream: true,
165
+ }),
166
+ });
167
+ if (!response.ok) {
168
+ const error = (await response.json().catch(() => ({})));
169
+ const nested = error.error;
170
+ throw new OpenRouterError(nested?.message ?? `OpenRouter API error: ${response.status}`, response.status);
171
+ }
172
+ return response;
173
+ };
174
+ const response = this.retryConfig === false
175
+ ? await getResponse()
176
+ : await withRetryThrow(getResponse, this.retryConfig);
177
+ const reader = response.body?.getReader();
178
+ if (!reader)
179
+ throw new Error("No response body");
180
+ const decoder = new TextDecoder();
181
+ let buffer = "";
182
+ while (true) {
183
+ const { done, value } = await reader.read();
184
+ if (done)
185
+ break;
186
+ buffer += decoder.decode(value, { stream: true });
187
+ const lines = buffer.split("\n");
188
+ buffer = lines.pop() ?? "";
189
+ for (const line of lines) {
190
+ if (line.startsWith("data: ")) {
191
+ const data = line.slice(6);
192
+ if (data === "[DONE]")
193
+ return;
194
+ try {
195
+ const parsed = JSON.parse(data);
196
+ const delta = parsed.choices?.[0]?.delta;
197
+ if (delta?.content) {
198
+ yield {
199
+ content: delta.content,
200
+ finishReason: parsed.choices?.[0]?.finish_reason,
201
+ };
202
+ }
203
+ }
204
+ catch {
205
+ // Skip invalid JSON
206
+ }
207
+ }
208
+ }
209
+ }
210
+ }
211
+ /**
212
+ * Simple completion helper.
213
+ */
214
+ async complete(prompt, options) {
215
+ const messages = [];
216
+ if (options?.systemPrompt) {
217
+ messages.push({ role: "system", content: options.systemPrompt });
218
+ }
219
+ messages.push({ role: "user", content: prompt });
220
+ const response = await this.chat({
221
+ messages,
222
+ model: options?.model,
223
+ temperature: options?.temperature,
224
+ maxTokens: options?.maxTokens,
225
+ });
226
+ return response.content;
227
+ }
228
+ /**
229
+ * Get available models from OpenRouter.
230
+ */
231
+ async getModels() {
232
+ const doGetModels = async () => {
233
+ const response = await fetch(`${OPENROUTER_API_URL}/models`, {
234
+ headers: this.buildHeaders(),
235
+ });
236
+ if (!response.ok) {
237
+ throw new OpenRouterError(`Failed to fetch models: ${response.status}`, response.status);
238
+ }
239
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
240
+ const data = (await response.json());
241
+ return data.data;
242
+ };
243
+ if (this.retryConfig === false) {
244
+ return doGetModels();
245
+ }
246
+ return withRetryThrow(doGetModels, this.retryConfig);
247
+ }
248
+ buildHeaders() {
249
+ const headers = {
250
+ "Content-Type": "application/json",
251
+ Authorization: `Bearer ${this.config.apiKey}`,
252
+ };
253
+ if (this.config.siteUrl) {
254
+ headers["HTTP-Referer"] = this.config.siteUrl;
255
+ }
256
+ if (this.config.siteName) {
257
+ headers["X-Title"] = this.config.siteName;
258
+ }
259
+ return headers;
260
+ }
261
+ }
262
+ /**
263
+ * Create an LLM client (OpenRouter implementation).
264
+ *
265
+ * Returns LLMProvider interface to allow swapping implementations.
266
+ */
267
+ export function createLLMClient(config) {
268
+ return new OpenRouterClient(config);
269
+ }
270
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/lib/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ // Serial / parallel orchestrator for multi-call tools.
2
+ //
3
+ // OpenRouter retry is handled inside the provider (see ./provider.ts).
4
+ // This queue only controls *concurrency* for tools like NGT and Delphi
5
+ // that run N model calls against the same prompt and need to choose
6
+ // between serial (safe for free-tier rate limits) and parallel (fast,
7
+ // opt-in via --parallel flag).
8
+ //
9
+ // The goal is predictability under OpenRouter's free-tier limits:
10
+ // serial mode spaces requests out enough that a 5-call NGT run
11
+ // comfortably stays within per-minute limits; parallel mode is for
12
+ // users who have verified their rate budget and want speed.
13
+ export async function runQueue(tasks, opts) {
14
+ const total = tasks.length;
15
+ if (total === 0)
16
+ return [];
17
+ if (opts.parallel) {
18
+ return Promise.all(tasks.map((task, i) => {
19
+ opts.onProgress?.(i + 1, total);
20
+ return task();
21
+ }));
22
+ }
23
+ // Serial
24
+ const results = [];
25
+ for (let i = 0; i < tasks.length; i++) {
26
+ opts.onProgress?.(i + 1, total);
27
+ results.push(await tasks[i]());
28
+ }
29
+ return results;
30
+ }
31
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/lib/queue.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,uEAAuE;AACvE,uEAAuE;AACvE,oEAAoE;AACpE,sEAAsE;AACtE,+BAA+B;AAC/B,EAAE;AACF,kEAAkE;AAClE,+DAA+D;AAC/D,mEAAmE;AACnE,4DAA4D;AAQ5D,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,KAA8B,EAC9B,IAAkB;IAElB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAC3B,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE3B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;YACpB,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YAChC,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,SAAS;IACT,MAAM,OAAO,GAAQ,EAAE,CAAC;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}