@nanonets/graft 0.13.0 → 0.16.0
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.
- package/README.md +26 -10
- package/dist/ai/crux.d.ts +14 -1
- package/dist/ai/crux.d.ts.map +1 -1
- package/dist/ai/crux.js +39 -51
- package/dist/ai/crux.js.map +1 -1
- package/dist/ai/failure.d.ts +13 -2
- package/dist/ai/failure.d.ts.map +1 -1
- package/dist/ai/failure.js +16 -4
- package/dist/ai/failure.js.map +1 -1
- package/dist/ai/llm/factory.d.ts +10 -1
- package/dist/ai/llm/factory.d.ts.map +1 -1
- package/dist/ai/llm/factory.js +16 -0
- package/dist/ai/llm/factory.js.map +1 -1
- package/dist/ai/llm/litellm.d.ts +34 -0
- package/dist/ai/llm/litellm.d.ts.map +1 -0
- package/dist/ai/llm/litellm.js +45 -0
- package/dist/ai/llm/litellm.js.map +1 -0
- package/dist/ai/llm/openai.d.ts.map +1 -1
- package/dist/ai/llm/openai.js +66 -7
- package/dist/ai/llm/openai.js.map +1 -1
- package/dist/ai/llm/orcarouter.d.ts +34 -0
- package/dist/ai/llm/orcarouter.d.ts.map +1 -0
- package/dist/ai/llm/orcarouter.js +45 -0
- package/dist/ai/llm/orcarouter.js.map +1 -0
- package/dist/ai/llm/recover-tool.d.ts +19 -0
- package/dist/ai/llm/recover-tool.d.ts.map +1 -0
- package/dist/ai/llm/recover-tool.js +109 -0
- package/dist/ai/llm/recover-tool.js.map +1 -0
- package/dist/ai/providers.d.ts.map +1 -1
- package/dist/ai/providers.js +15 -3
- package/dist/ai/providers.js.map +1 -1
- package/dist/ai/synthesize.d.ts.map +1 -1
- package/dist/ai/synthesize.js +19 -5
- package/dist/ai/synthesize.js.map +1 -1
- package/dist/app/checkout.d.ts +28 -0
- package/dist/app/checkout.d.ts.map +1 -0
- package/dist/app/checkout.js +100 -0
- package/dist/app/checkout.js.map +1 -0
- package/dist/app/events.d.ts +37 -0
- package/dist/app/events.d.ts.map +1 -0
- package/dist/app/events.js +59 -0
- package/dist/app/events.js.map +1 -0
- package/dist/app/identity.d.ts +54 -0
- package/dist/app/identity.d.ts.map +1 -0
- package/dist/app/identity.js +96 -0
- package/dist/app/identity.js.map +1 -0
- package/dist/app/main.d.ts +2 -0
- package/dist/app/main.d.ts.map +1 -0
- package/dist/app/main.js +56 -0
- package/dist/app/main.js.map +1 -0
- package/dist/app/pages.d.ts +39 -0
- package/dist/app/pages.d.ts.map +1 -0
- package/dist/app/pages.js +86 -0
- package/dist/app/pages.js.map +1 -0
- package/dist/app/queue.d.ts +40 -0
- package/dist/app/queue.d.ts.map +1 -0
- package/dist/app/queue.js +68 -0
- package/dist/app/queue.js.map +1 -0
- package/dist/app/review.d.ts +23 -0
- package/dist/app/review.d.ts.map +1 -0
- package/dist/app/review.js +139 -0
- package/dist/app/review.js.map +1 -0
- package/dist/app/server.d.ts +40 -0
- package/dist/app/server.d.ts.map +1 -0
- package/dist/app/server.js +117 -0
- package/dist/app/server.js.map +1 -0
- package/dist/ask/ask.d.ts +35 -0
- package/dist/ask/ask.d.ts.map +1 -1
- package/dist/ask/ask.js +427 -63
- package/dist/ask/ask.js.map +1 -1
- package/dist/ask/file-rank.d.ts +72 -0
- package/dist/ask/file-rank.d.ts.map +1 -0
- package/dist/ask/file-rank.js +160 -0
- package/dist/ask/file-rank.js.map +1 -0
- package/dist/ask/file-selection.d.ts +4 -0
- package/dist/ask/file-selection.d.ts.map +1 -1
- package/dist/ask/file-selection.js +25 -0
- package/dist/ask/file-selection.js.map +1 -1
- package/dist/ask/fuse.d.ts +16 -0
- package/dist/ask/fuse.d.ts.map +1 -1
- package/dist/ask/fuse.js +21 -4
- package/dist/ask/fuse.js.map +1 -1
- package/dist/ask/graphrank.d.ts +18 -0
- package/dist/ask/graphrank.d.ts.map +1 -1
- package/dist/ask/graphrank.js +65 -19
- package/dist/ask/graphrank.js.map +1 -1
- package/dist/blast/blast-cli.d.ts +5 -0
- package/dist/blast/blast-cli.d.ts.map +1 -1
- package/dist/blast/blast-cli.js +21 -30
- package/dist/blast/blast-cli.js.map +1 -1
- package/dist/blast/blast.d.ts +9 -0
- package/dist/blast/blast.d.ts.map +1 -1
- package/dist/blast/blast.js.map +1 -1
- package/dist/blast/name.d.ts +13 -0
- package/dist/blast/name.d.ts.map +1 -1
- package/dist/blast/name.js +36 -0
- package/dist/blast/name.js.map +1 -1
- package/dist/blast/owners.d.ts +85 -0
- package/dist/blast/owners.d.ts.map +1 -0
- package/dist/blast/owners.js +272 -0
- package/dist/blast/owners.js.map +1 -0
- package/dist/blast/render.d.ts.map +1 -1
- package/dist/blast/render.js +105 -0
- package/dist/blast/render.js.map +1 -1
- package/dist/blast/viz.d.ts.map +1 -1
- package/dist/blast/viz.js +10 -0
- package/dist/blast/viz.js.map +1 -1
- package/dist/claude/format.js +1 -1
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +132 -22
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/init.d.ts +1 -0
- package/dist/claude/init.d.ts.map +1 -1
- package/dist/claude/init.js +1 -1
- package/dist/claude/init.js.map +1 -1
- package/dist/claude/session-metrics.d.ts +63 -0
- package/dist/claude/session-metrics.d.ts.map +1 -0
- package/dist/claude/session-metrics.js +181 -0
- package/dist/claude/session-metrics.js.map +1 -0
- package/dist/claude/settings-merge.d.ts +18 -1
- package/dist/claude/settings-merge.d.ts.map +1 -1
- package/dist/claude/settings-merge.js +70 -27
- package/dist/claude/settings-merge.js.map +1 -1
- package/dist/claude/state.d.ts +25 -0
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js +14 -1
- package/dist/claude/state.js.map +1 -1
- package/dist/claude/statusline.d.ts +5 -3
- package/dist/claude/statusline.d.ts.map +1 -1
- package/dist/claude/statusline.js +6 -4
- package/dist/claude/statusline.js.map +1 -1
- package/dist/claude/tally.d.ts +23 -0
- package/dist/claude/tally.d.ts.map +1 -0
- package/dist/claude/tally.js +138 -0
- package/dist/claude/tally.js.map +1 -0
- package/dist/cli.js +145 -4
- package/dist/cli.js.map +1 -1
- package/dist/context/build.d.ts +11 -0
- package/dist/context/build.d.ts.map +1 -1
- package/dist/context/build.js +49 -9
- package/dist/context/build.js.map +1 -1
- package/dist/context/check.d.ts.map +1 -1
- package/dist/context/check.js +5 -12
- package/dist/context/check.js.map +1 -1
- package/dist/context/node-file.d.ts +2 -1
- package/dist/context/node-file.d.ts.map +1 -1
- package/dist/context/node-file.js +70 -3
- package/dist/context/node-file.js.map +1 -1
- package/dist/context/savings.d.ts +8 -0
- package/dist/context/savings.d.ts.map +1 -1
- package/dist/context/savings.js +14 -0
- package/dist/context/savings.js.map +1 -1
- package/dist/engine.d.ts +4 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +2 -0
- package/dist/engine.js.map +1 -1
- package/dist/graph/bindings.d.ts +6 -5
- package/dist/graph/bindings.d.ts.map +1 -1
- package/dist/graph/bindings.js +117 -5
- package/dist/graph/bindings.js.map +1 -1
- package/dist/graph/build.d.ts +4 -0
- package/dist/graph/build.d.ts.map +1 -1
- package/dist/graph/build.js +7 -4
- package/dist/graph/build.js.map +1 -1
- package/dist/graph/cards.d.ts +4 -3
- package/dist/graph/cards.d.ts.map +1 -1
- package/dist/graph/cards.js +34 -6
- package/dist/graph/cards.js.map +1 -1
- package/dist/graph/check.d.ts.map +1 -1
- package/dist/graph/check.js +36 -6
- package/dist/graph/check.js.map +1 -1
- package/dist/graph/enrich.d.ts +4 -4
- package/dist/graph/enrich.d.ts.map +1 -1
- package/dist/graph/enrich.js +32 -6
- package/dist/graph/enrich.js.map +1 -1
- package/dist/graph/extract.d.ts +9 -2
- package/dist/graph/extract.d.ts.map +1 -1
- package/dist/graph/extract.js +356 -12
- package/dist/graph/extract.js.map +1 -1
- package/dist/graph/fingerprint.d.ts +6 -1
- package/dist/graph/fingerprint.d.ts.map +1 -1
- package/dist/graph/fingerprint.js +7 -3
- package/dist/graph/fingerprint.js.map +1 -1
- package/dist/graph/generic.d.ts +10 -0
- package/dist/graph/generic.d.ts.map +1 -1
- package/dist/graph/generic.js +20 -3
- package/dist/graph/generic.js.map +1 -1
- package/dist/graph/invariants.d.ts +3 -2
- package/dist/graph/invariants.d.ts.map +1 -1
- package/dist/graph/invariants.js +6 -3
- package/dist/graph/invariants.js.map +1 -1
- package/dist/graph/refresh.d.ts.map +1 -1
- package/dist/graph/refresh.js +6 -2
- package/dist/graph/refresh.js.map +1 -1
- package/dist/graph/resolve.d.ts +1 -1
- package/dist/graph/resolve.d.ts.map +1 -1
- package/dist/graph/resolve.js +106 -5
- package/dist/graph/resolve.js.map +1 -1
- package/dist/graph/scopes.d.ts.map +1 -1
- package/dist/graph/scopes.js +2 -1
- package/dist/graph/scopes.js.map +1 -1
- package/dist/graph/source-files.d.ts +7 -2
- package/dist/graph/source-files.d.ts.map +1 -1
- package/dist/graph/source-files.js +19 -6
- package/dist/graph/source-files.js.map +1 -1
- package/dist/graph/workspace-cli.d.ts +2 -0
- package/dist/graph/workspace-cli.d.ts.map +1 -1
- package/dist/graph/workspace-cli.js +3 -0
- package/dist/graph/workspace-cli.js.map +1 -1
- package/dist/graph/workspace.d.ts +2 -0
- package/dist/graph/workspace.d.ts.map +1 -1
- package/dist/graph/workspace.js +173 -6
- package/dist/graph/workspace.js.map +1 -1
- package/dist/hosts/antigravity.d.ts +2 -2
- package/dist/hosts/antigravity.d.ts.map +1 -1
- package/dist/hosts/codex-hooks.d.ts +2 -6
- package/dist/hosts/codex-hooks.d.ts.map +1 -1
- package/dist/hosts/codex-hooks.js +7 -30
- package/dist/hosts/codex-hooks.js.map +1 -1
- package/dist/hosts/config-write.d.ts +36 -0
- package/dist/hosts/config-write.d.ts.map +1 -0
- package/dist/hosts/config-write.js +63 -0
- package/dist/hosts/config-write.js.map +1 -0
- package/dist/hosts/cursor-hooks.d.ts +18 -0
- package/dist/hosts/cursor-hooks.d.ts.map +1 -0
- package/dist/hosts/cursor-hooks.js +100 -0
- package/dist/hosts/cursor-hooks.js.map +1 -0
- package/dist/hosts/init.d.ts +2 -2
- package/dist/hosts/init.d.ts.map +1 -1
- package/dist/hosts/init.js +8 -2
- package/dist/hosts/init.js.map +1 -1
- package/dist/hosts/mcp-config.d.ts +15 -5
- package/dist/hosts/mcp-config.d.ts.map +1 -1
- package/dist/hosts/mcp-config.js +51 -15
- package/dist/hosts/mcp-config.js.map +1 -1
- package/dist/hosts/plan.d.ts.map +1 -1
- package/dist/hosts/plan.js +2 -0
- package/dist/hosts/plan.js.map +1 -1
- package/dist/hosts/retract.d.ts +47 -0
- package/dist/hosts/retract.d.ts.map +1 -0
- package/dist/hosts/retract.js +473 -0
- package/dist/hosts/retract.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/ingest/fs.d.ts +39 -5
- package/dist/ingest/fs.d.ts.map +1 -1
- package/dist/ingest/fs.js +104 -11
- package/dist/ingest/fs.js.map +1 -1
- package/dist/mcp/tool-names.d.ts +20 -0
- package/dist/mcp/tool-names.d.ts.map +1 -0
- package/dist/mcp/tool-names.js +36 -0
- package/dist/mcp/tool-names.js.map +1 -0
- package/dist/mcp/tools.d.ts +11 -2
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +9 -21
- package/dist/mcp/tools.js.map +1 -1
- package/dist/telemetry/contract.d.ts.map +1 -1
- package/dist/telemetry/contract.js +17 -3
- package/dist/telemetry/contract.js.map +1 -1
- package/dist/telemetry/flush.d.ts.map +1 -1
- package/dist/telemetry/flush.js +1 -0
- package/dist/telemetry/flush.js.map +1 -1
- package/dist/telemetry/identity.d.ts +7 -0
- package/dist/telemetry/identity.d.ts.map +1 -1
- package/dist/telemetry/identity.js.map +1 -1
- package/dist/telemetry/index.d.ts +2 -2
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +2 -2
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/sessions.d.ts +19 -2
- package/dist/telemetry/sessions.d.ts.map +1 -1
- package/dist/telemetry/sessions.js +57 -34
- package/dist/telemetry/sessions.js.map +1 -1
- package/dist/telemetry/track.d.ts +22 -3
- package/dist/telemetry/track.d.ts.map +1 -1
- package/dist/telemetry/track.js +34 -5
- package/dist/telemetry/track.js.map +1 -1
- package/dist/upkeep-run.js +1 -1
- package/dist/upkeep-run.js.map +1 -1
- package/dist/upkeep.d.ts +7 -4
- package/dist/upkeep.d.ts.map +1 -1
- package/dist/upkeep.js +2 -1
- package/dist/upkeep.js.map +1 -1
- package/dist/util/state.d.ts +12 -2
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js +4 -0
- package/dist/util/state.js.map +1 -1
- package/dist/viewer/app.js +2 -1
- package/dist/viewer/style.css +14 -0
- package/dist/viz/assemble.d.ts +17 -0
- package/dist/viz/assemble.d.ts.map +1 -1
- package/dist/viz/assemble.js.map +1 -1
- package/package.json +12 -4
- package/scripts/graph-quality.mjs +3 -3
- package/scripts/postinstall.mjs +42 -3
- package/scripts/run-tests.mjs +14 -0
- package/scripts/tally-audit.mjs +140 -0
- package/dist/ai/llm/claude-cli.d.ts +0 -60
- package/dist/ai/llm/claude-cli.d.ts.map +0 -1
- package/dist/ai/llm/claude-cli.js +0 -417
- package/dist/ai/llm/claude-cli.js.map +0 -1
- package/dist/util/num.d.ts +0 -3
- package/dist/util/num.d.ts.map +0 -1
- package/dist/util/num.js +0 -20
- package/dist/util/num.js.map +0 -1
package/dist/ai/llm/openai.js
CHANGED
|
@@ -62,6 +62,42 @@ function isRejectedObjectToolChoice(err) {
|
|
|
62
62
|
err.status === 400 &&
|
|
63
63
|
/tool_choice/i.test(String(err.message ?? "")));
|
|
64
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Newer reasoning-family models (o1/o3/o4, the gpt-5.x line, …) reject the
|
|
67
|
+
* classic `max_tokens` param outright and require `max_completion_tokens`
|
|
68
|
+
* instead, even though both are still in wide use across OpenAI-compatible
|
|
69
|
+
* servers. Detect the specific 400 rather than guessing from the model name,
|
|
70
|
+
* so older endpoints that still expect `max_tokens` are untouched.
|
|
71
|
+
*/
|
|
72
|
+
function isRejectedMaxTokens(err) {
|
|
73
|
+
return (err instanceof OpenAI.APIError &&
|
|
74
|
+
err.status === 400 &&
|
|
75
|
+
/max_tokens.*not supported.*max_completion_tokens/i.test(String(err.message ?? "")));
|
|
76
|
+
}
|
|
77
|
+
/** Same reasoning-family models: temperature is fixed at 1, not caller-settable. */
|
|
78
|
+
function isRejectedTemperature(err) {
|
|
79
|
+
return (err instanceof OpenAI.APIError &&
|
|
80
|
+
err.status === 400 &&
|
|
81
|
+
/temperature.*does not support/i.test(String(err.message ?? "")));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Same models again: function tools are rejected on /v1/chat/completions while
|
|
85
|
+
* the model's default reasoning effort is active. The API's own error message
|
|
86
|
+
* names the fix — `reasoning_effort: "none"` — so apply exactly that.
|
|
87
|
+
*
|
|
88
|
+
* DeepSeek's v4 line refuses the same combination ("Thinking mode does not
|
|
89
|
+
* support this tool_choice") for every tool_choice except "auto", and accepts
|
|
90
|
+
* the identical `reasoning_effort: "none"` remedy. Matching both phrasings here
|
|
91
|
+
* keeps a forced tool_choice working rather than degrading it to "auto", which
|
|
92
|
+
* would leave the model free not to call the tool the caller asked for.
|
|
93
|
+
*/
|
|
94
|
+
function isRejectedToolsWithReasoning(err) {
|
|
95
|
+
const message = String(err.message ?? "");
|
|
96
|
+
return (err instanceof OpenAI.APIError &&
|
|
97
|
+
err.status === 400 &&
|
|
98
|
+
(/function tools with reasoning_effort/i.test(message) ||
|
|
99
|
+
/thinking mode does not support this tool_choice/i.test(message)));
|
|
100
|
+
}
|
|
65
101
|
export class OpenAIChatModel {
|
|
66
102
|
label;
|
|
67
103
|
client;
|
|
@@ -117,15 +153,38 @@ export class OpenAIChatModel {
|
|
|
117
153
|
* automatically.
|
|
118
154
|
*/
|
|
119
155
|
async createChatCompletion(params) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
156
|
+
let attempt = params;
|
|
157
|
+
// Bounded: one retry per known incompatibility below, never an open loop.
|
|
158
|
+
for (let i = 0; i < 4; i++) {
|
|
159
|
+
try {
|
|
160
|
+
return await this.client.chat.completions.create(attempt);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
// Checked before the tool_choice fallback below: a reasoning refusal
|
|
164
|
+
// also names tool_choice, and turning reasoning off keeps the caller's
|
|
165
|
+
// chosen tool instead of loosening the choice to work around it.
|
|
166
|
+
if (isRejectedToolsWithReasoning(err) && attempt.reasoning_effort === undefined) {
|
|
167
|
+
attempt = { ...attempt, reasoning_effort: "none" };
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (isRejectedObjectToolChoice(err) && typeof attempt.tool_choice === "object" && attempt.tools?.length === 1) {
|
|
171
|
+
attempt = { ...attempt, tool_choice: "required" };
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (isRejectedMaxTokens(err) && attempt.max_tokens !== undefined) {
|
|
175
|
+
const { max_tokens, ...rest } = attempt;
|
|
176
|
+
attempt = { ...rest, max_completion_tokens: max_tokens };
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (isRejectedTemperature(err) && attempt.temperature !== undefined) {
|
|
180
|
+
const { temperature, ...rest } = attempt;
|
|
181
|
+
attempt = rest;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
throw err;
|
|
126
185
|
}
|
|
127
|
-
throw err;
|
|
128
186
|
}
|
|
187
|
+
return this.client.chat.completions.create(attempt);
|
|
129
188
|
}
|
|
130
189
|
fromResponse(resp, format) {
|
|
131
190
|
const choice = resp.choices[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/ai/llm/openai.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/ai/llm/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OrcaRouter transport. The OrcaRouter gateway speaks the OpenAI-compatible
|
|
3
|
+
* wire format, so this reuses the OpenAI adapter's request/response translation
|
|
4
|
+
* and simply points it at the gateway. The value over a bare `openai` provider +
|
|
5
|
+
* `baseUrl` is a first-class, self-describing provider: a sensible default
|
|
6
|
+
* gateway address and `/v1/models` auto-discovery (see {@link listOrcaRouterModels}),
|
|
7
|
+
* so callers can enumerate whatever upstream models the gateway routes to —
|
|
8
|
+
* reaching 150+ models from OpenAI, Anthropic, Google, DeepSeek, Qwen, and more
|
|
9
|
+
* through one endpoint without a per-vendor code path.
|
|
10
|
+
*/
|
|
11
|
+
import OpenAI from "openai";
|
|
12
|
+
import { OpenAIChatModel, type OpenAIChatModelOptions } from "./openai.js";
|
|
13
|
+
/** Public endpoint of the OrcaRouter AI gateway. */
|
|
14
|
+
export declare const DEFAULT_ORCAROUTER_BASE_URL = "https://api.orcarouter.ai/v1";
|
|
15
|
+
export type OrcaRouterChatModelOptions = OpenAIChatModelOptions;
|
|
16
|
+
/**
|
|
17
|
+
* ChatModel backed by the OrcaRouter gateway. Inherits every translation detail
|
|
18
|
+
* from {@link OpenAIChatModel} (the gateway is OpenAI-compatible) and only
|
|
19
|
+
* changes the defaults: the gateway base URL and an `orcarouter:<model>` label.
|
|
20
|
+
*/
|
|
21
|
+
export declare class OrcaRouterChatModel extends OpenAIChatModel {
|
|
22
|
+
constructor(opts: OrcaRouterChatModelOptions);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Auto-discover the models the OrcaRouter gateway can route to via `GET
|
|
26
|
+
* /v1/models`. Returns the model ids so a caller can present/validate them
|
|
27
|
+
* instead of hardcoding a model string. A stub `client` may be injected for tests.
|
|
28
|
+
*/
|
|
29
|
+
export declare function listOrcaRouterModels(opts: {
|
|
30
|
+
apiKey: string;
|
|
31
|
+
baseUrl?: string;
|
|
32
|
+
client?: OpenAI;
|
|
33
|
+
}): Promise<string[]>;
|
|
34
|
+
//# sourceMappingURL=orcarouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orcarouter.d.ts","sourceRoot":"","sources":["../../../src/ai/llm/orcarouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAG3E,oDAAoD;AACpD,eAAO,MAAM,2BAA2B,iCAAiC,CAAC;AAE1E,MAAM,MAAM,0BAA0B,GAAG,sBAAsB,CAAC;AAEhE;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,eAAe;gBAC1C,IAAI,EAAE,0BAA0B;CAO7C;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAUpB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OrcaRouter transport. The OrcaRouter gateway speaks the OpenAI-compatible
|
|
3
|
+
* wire format, so this reuses the OpenAI adapter's request/response translation
|
|
4
|
+
* and simply points it at the gateway. The value over a bare `openai` provider +
|
|
5
|
+
* `baseUrl` is a first-class, self-describing provider: a sensible default
|
|
6
|
+
* gateway address and `/v1/models` auto-discovery (see {@link listOrcaRouterModels}),
|
|
7
|
+
* so callers can enumerate whatever upstream models the gateway routes to —
|
|
8
|
+
* reaching 150+ models from OpenAI, Anthropic, Google, DeepSeek, Qwen, and more
|
|
9
|
+
* through one endpoint without a per-vendor code path.
|
|
10
|
+
*/
|
|
11
|
+
import OpenAI from "openai";
|
|
12
|
+
import { OpenAIChatModel } from "./openai.js";
|
|
13
|
+
import { transportRetries } from "./types.js";
|
|
14
|
+
/** Public endpoint of the OrcaRouter AI gateway. */
|
|
15
|
+
export const DEFAULT_ORCAROUTER_BASE_URL = "https://api.orcarouter.ai/v1";
|
|
16
|
+
/**
|
|
17
|
+
* ChatModel backed by the OrcaRouter gateway. Inherits every translation detail
|
|
18
|
+
* from {@link OpenAIChatModel} (the gateway is OpenAI-compatible) and only
|
|
19
|
+
* changes the defaults: the gateway base URL and an `orcarouter:<model>` label.
|
|
20
|
+
*/
|
|
21
|
+
export class OrcaRouterChatModel extends OpenAIChatModel {
|
|
22
|
+
constructor(opts) {
|
|
23
|
+
super({
|
|
24
|
+
...opts,
|
|
25
|
+
baseUrl: opts.baseUrl ?? DEFAULT_ORCAROUTER_BASE_URL,
|
|
26
|
+
label: opts.label ?? `orcarouter:${opts.model}`,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Auto-discover the models the OrcaRouter gateway can route to via `GET
|
|
32
|
+
* /v1/models`. Returns the model ids so a caller can present/validate them
|
|
33
|
+
* instead of hardcoding a model string. A stub `client` may be injected for tests.
|
|
34
|
+
*/
|
|
35
|
+
export async function listOrcaRouterModels(opts) {
|
|
36
|
+
const client = opts.client ??
|
|
37
|
+
new OpenAI({
|
|
38
|
+
apiKey: opts.apiKey,
|
|
39
|
+
baseURL: opts.baseUrl ?? DEFAULT_ORCAROUTER_BASE_URL,
|
|
40
|
+
maxRetries: transportRetries(),
|
|
41
|
+
});
|
|
42
|
+
const res = await client.models.list();
|
|
43
|
+
return res.data.map((m) => m.id);
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=orcarouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orcarouter.js","sourceRoot":"","sources":["../../../src/ai/llm/orcarouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,eAAe,EAA+B,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,oDAAoD;AACpD,MAAM,CAAC,MAAM,2BAA2B,GAAG,8BAA8B,CAAC;AAI1E;;;;GAIG;AACH,MAAM,OAAO,mBAAoB,SAAQ,eAAe;IACtD,YAAY,IAAgC;QAC1C,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,2BAA2B;YACpD,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,cAAc,IAAI,CAAC,KAAK,EAAE;SAChD,CAAC,CAAC;IACL,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAI1C;IACC,MAAM,MAAM,GACV,IAAI,CAAC,MAAM;QACX,IAAI,MAAM,CAAC;YACT,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,2BAA2B;YACpD,UAAU,EAAE,gBAAgB,EAAE;SAC/B,CAAC,CAAC;IACL,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACvC,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recover a forced-tool payload from assistant `content` when a gateway ignored
|
|
3
|
+
* `tool_choice` and wrote JSON text instead of `tool_calls` (#129).
|
|
4
|
+
*
|
|
5
|
+
* Conservative: only succeeds when `text` parses as JSON matching one of:
|
|
6
|
+
* - `[{ name, parameters|arguments|args }]`
|
|
7
|
+
* - `{ name, parameters|arguments|args }`
|
|
8
|
+
* - a fenced ```json block wrapping either
|
|
9
|
+
* - a bare object whose `payloadKey` is an array
|
|
10
|
+
* Anything else (prose, truncated JSON, a guessed shape) returns undefined.
|
|
11
|
+
* Callers MUST run the same schema validation they use for real tool calls.
|
|
12
|
+
*/
|
|
13
|
+
export declare function recoverToolArgsFromContent(text: string, opts: {
|
|
14
|
+
toolNames: readonly string[];
|
|
15
|
+
payloadKey: string;
|
|
16
|
+
}): Record<string, unknown> | undefined;
|
|
17
|
+
/** One stderr line when a structured op got neither a tool call nor recoverable JSON. */
|
|
18
|
+
export declare function warnToolChoiceIgnored(op: string, reason: "empty" | "unparsed"): void;
|
|
19
|
+
//# sourceMappingURL=recover-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recover-tool.d.ts","sourceRoot":"","sources":["../../../src/ai/llm/recover-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACzD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAiErC;AAED,yFAAyF;AACzF,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAMpF"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recover a forced-tool payload from assistant `content` when a gateway ignored
|
|
3
|
+
* `tool_choice` and wrote JSON text instead of `tool_calls` (#129).
|
|
4
|
+
*
|
|
5
|
+
* Conservative: only succeeds when `text` parses as JSON matching one of:
|
|
6
|
+
* - `[{ name, parameters|arguments|args }]`
|
|
7
|
+
* - `{ name, parameters|arguments|args }`
|
|
8
|
+
* - a fenced ```json block wrapping either
|
|
9
|
+
* - a bare object whose `payloadKey` is an array
|
|
10
|
+
* Anything else (prose, truncated JSON, a guessed shape) returns undefined.
|
|
11
|
+
* Callers MUST run the same schema validation they use for real tool calls.
|
|
12
|
+
*/
|
|
13
|
+
/** Leading/trailing ```json fence, linear in `raw.length` — no quantified-whitespace regex. */
|
|
14
|
+
function unwrapMarkdownFence(raw) {
|
|
15
|
+
let s = raw;
|
|
16
|
+
if (s.startsWith("```")) {
|
|
17
|
+
s = s.slice(3);
|
|
18
|
+
if (s.length >= 4 && s.slice(0, 4).toLowerCase() === "json")
|
|
19
|
+
s = s.slice(4);
|
|
20
|
+
s = s.trimStart();
|
|
21
|
+
}
|
|
22
|
+
if (s.endsWith("```"))
|
|
23
|
+
s = s.slice(0, -3).trimEnd();
|
|
24
|
+
return s.trim();
|
|
25
|
+
}
|
|
26
|
+
export function recoverToolArgsFromContent(text, opts) {
|
|
27
|
+
const raw = text?.trim();
|
|
28
|
+
if (!raw)
|
|
29
|
+
return undefined;
|
|
30
|
+
const stripped = unwrapMarkdownFence(raw);
|
|
31
|
+
const accepted = new Set(opts.toolNames);
|
|
32
|
+
const asPayload = (value) => {
|
|
33
|
+
if (!value || typeof value !== "object")
|
|
34
|
+
return undefined;
|
|
35
|
+
if (Array.isArray(value)) {
|
|
36
|
+
for (const item of value) {
|
|
37
|
+
const hit = asPayload(item);
|
|
38
|
+
if (hit)
|
|
39
|
+
return hit;
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
const obj = value;
|
|
44
|
+
const wrapped = typeof obj.name === "string" || "parameters" in obj || "arguments" in obj || "args" in obj;
|
|
45
|
+
if (wrapped) {
|
|
46
|
+
const name = typeof obj.name === "string" ? obj.name : "";
|
|
47
|
+
if (name && !accepted.has(name))
|
|
48
|
+
return undefined;
|
|
49
|
+
let params = obj.parameters ?? obj.arguments ?? obj.args;
|
|
50
|
+
if (typeof params === "string") {
|
|
51
|
+
try {
|
|
52
|
+
params = JSON.parse(params);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const hit = asPayload(params);
|
|
59
|
+
if (hit)
|
|
60
|
+
return hit;
|
|
61
|
+
// `{ name, nodes: [...] }` — payload at the same level as the wrapper.
|
|
62
|
+
if (Array.isArray(obj[opts.payloadKey]))
|
|
63
|
+
return obj;
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
if (Array.isArray(obj[opts.payloadKey]))
|
|
67
|
+
return obj;
|
|
68
|
+
return undefined;
|
|
69
|
+
};
|
|
70
|
+
try {
|
|
71
|
+
const hit = asPayload(JSON.parse(stripped));
|
|
72
|
+
if (hit)
|
|
73
|
+
return hit;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
/* try a bracket slice below */
|
|
77
|
+
}
|
|
78
|
+
const objStart = stripped.indexOf("{");
|
|
79
|
+
const objEnd = stripped.lastIndexOf("}");
|
|
80
|
+
if (objStart >= 0 && objEnd > objStart) {
|
|
81
|
+
try {
|
|
82
|
+
const hit = asPayload(JSON.parse(stripped.slice(objStart, objEnd + 1)));
|
|
83
|
+
if (hit)
|
|
84
|
+
return hit;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
/* try array slice */
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const arrStart = stripped.indexOf("[");
|
|
91
|
+
const arrEnd = stripped.lastIndexOf("]");
|
|
92
|
+
if (arrStart >= 0 && arrEnd > arrStart) {
|
|
93
|
+
try {
|
|
94
|
+
return asPayload(JSON.parse(stripped.slice(arrStart, arrEnd + 1)));
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
/** One stderr line when a structured op got neither a tool call nor recoverable JSON. */
|
|
103
|
+
export function warnToolChoiceIgnored(op, reason) {
|
|
104
|
+
const detail = reason === "empty"
|
|
105
|
+
? "model returned no tool call and no content (provider may ignore forced tool_choice)"
|
|
106
|
+
: "model did not honor tool_choice and content is not parseable tool-call JSON";
|
|
107
|
+
console.error(`⚠ ${op}: ${detail} — this batch is empty`);
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=recover-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recover-tool.js","sourceRoot":"","sources":["../../../src/ai/llm/recover-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/ai/providers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,oEAAoE;IACpE,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,gCAAgC;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,oCAAoC;IACpC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,wEAAwE;IACxE,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/ai/providers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,oEAAoE;IACpE,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,gCAAgC;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,oCAAoC;IACpC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,wEAAwE;IACxE,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAKD,kCAAkC;AAClC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAOvD,CAAC;AAEF,eAAO,MAAM,QAAQ;uBACG,YAAY;;CAE1B,CAAC;AAEX,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,MAAM,GAAE,YAAiB,GAAG,cAAc,CAyCvE"}
|
package/dist/ai/providers.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
const OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1";
|
|
2
|
+
const ORCAROUTER_BASE_URL = "https://api.orcarouter.ai/v1";
|
|
2
3
|
/** Per-provider default model. */
|
|
3
4
|
export const DEFAULT_MODELS = {
|
|
4
5
|
openai: "openai/gpt-4o-mini",
|
|
5
6
|
anthropic: "claude-sonnet-5",
|
|
7
|
+
// Provider-prefixed so the LiteLLM proxy routes it; override with GRAFT_MODEL.
|
|
8
|
+
litellm: "openai/gpt-4o-mini",
|
|
9
|
+
// Provider-prefixed so the OrcaRouter gateway routes it; override with GRAFT_MODEL.
|
|
10
|
+
orcarouter: "openai/gpt-4o-mini",
|
|
6
11
|
};
|
|
7
12
|
export const DEFAULTS = {
|
|
8
13
|
provider: "openai",
|
|
@@ -14,14 +19,21 @@ export function resolveConfig(config = {}) {
|
|
|
14
19
|
const provider = config.provider ?? env.GRAFT_PROVIDER ?? DEFAULTS.provider;
|
|
15
20
|
const explicitKey = config.apiKey ?? env.GRAFT_API_KEY;
|
|
16
21
|
const legacyKey = env.OPENROUTER_API_KEY;
|
|
17
|
-
const apiKey = explicitKey ?? legacyKey;
|
|
22
|
+
const apiKey = explicitKey ?? legacyKey ?? env.ORCAROUTER_API_KEY;
|
|
18
23
|
const usedLegacyEnv = !explicitKey && !!legacyKey;
|
|
19
|
-
const model = config.model ??
|
|
20
|
-
|
|
24
|
+
const model = config.model ??
|
|
25
|
+
env.GRAFT_MODEL ??
|
|
26
|
+
env.GRAFT_OPENROUTER_MODEL ??
|
|
27
|
+
env.ORCAROUTER_MODEL ??
|
|
28
|
+
DEFAULT_MODELS[provider];
|
|
29
|
+
let baseUrl = config.baseUrl ?? env.GRAFT_BASE_URL ?? env.OPENROUTER_BASE_URL ?? env.ORCAROUTER_BASE_URL;
|
|
21
30
|
// Back-compat: an existing setup with only OPENROUTER_API_KEY keeps hitting
|
|
22
31
|
// OpenRouter without any config change.
|
|
23
32
|
if (!baseUrl && provider === "openai" && usedLegacyEnv)
|
|
24
33
|
baseUrl = OPENROUTER_BASE_URL;
|
|
34
|
+
// The orcarouter provider points at the gateway unless a base URL is given.
|
|
35
|
+
if (!baseUrl && provider === "orcarouter")
|
|
36
|
+
baseUrl = ORCAROUTER_BASE_URL;
|
|
25
37
|
const headers = provider === "openai" && baseUrl?.includes("openrouter.ai")
|
|
26
38
|
? { "X-Title": "graft" }
|
|
27
39
|
: undefined;
|
package/dist/ai/providers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/ai/providers.ts"],"names":[],"mappings":"AAwDA,MAAM,mBAAmB,GAAG,8BAA8B,CAAC;AAE3D,kCAAkC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAiC;IAC1D,MAAM,EAAE,oBAAoB;IAC5B,SAAS,EAAE,iBAAiB;
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/ai/providers.ts"],"names":[],"mappings":"AAwDA,MAAM,mBAAmB,GAAG,8BAA8B,CAAC;AAC3D,MAAM,mBAAmB,GAAG,8BAA8B,CAAC;AAE3D,kCAAkC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAiC;IAC1D,MAAM,EAAE,oBAAoB;IAC5B,SAAS,EAAE,iBAAiB;IAC5B,+EAA+E;IAC/E,OAAO,EAAE,oBAAoB;IAC7B,oFAAoF;IACpF,UAAU,EAAE,oBAAoB;CACjC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,QAAwB;IAClC,KAAK,EAAE,cAAc,CAAC,MAAM;CACpB,CAAC;AAEX,iEAAiE;AACjE,MAAM,UAAU,aAAa,CAAC,SAAuB,EAAE;IACrD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAK,GAAG,CAAC,cAA2C,IAAI,QAAQ,CAAC,QAAQ,CAAC;IAE1G,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,aAAa,CAAC;IACvD,MAAM,SAAS,GAAG,GAAG,CAAC,kBAAkB,CAAC;IACzC,MAAM,MAAM,GAAG,WAAW,IAAI,SAAS,IAAI,GAAG,CAAC,kBAAkB,CAAC;IAClE,MAAM,aAAa,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,SAAS,CAAC;IAElD,MAAM,KAAK,GACT,MAAM,CAAC,KAAK;QACZ,GAAG,CAAC,WAAW;QACf,GAAG,CAAC,sBAAsB;QAC1B,GAAG,CAAC,gBAAgB;QACpB,cAAc,CAAC,QAAQ,CAAC,CAAC;IAE3B,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,mBAAmB,IAAI,GAAG,CAAC,mBAAmB,CAAC;IACzG,4EAA4E;IAC5E,wCAAwC;IACxC,IAAI,CAAC,OAAO,IAAI,QAAQ,KAAK,QAAQ,IAAI,aAAa;QAAE,OAAO,GAAG,mBAAmB,CAAC;IACtF,4EAA4E;IAC5E,IAAI,CAAC,OAAO,IAAI,QAAQ,KAAK,YAAY;QAAE,OAAO,GAAG,mBAAmB,CAAC;IAEzE,MAAM,OAAO,GACX,QAAQ,KAAK,QAAQ,IAAI,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC;QACzD,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE;QACxB,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,SAAS;QAC9C,QAAQ;QACR,MAAM;QACN,KAAK;QACL,OAAO;QACP,OAAO;QACP,aAAa;QACb,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synthesize.d.ts","sourceRoot":"","sources":["../../src/ai/synthesize.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"synthesize.d.ts","sourceRoot":"","sources":["../../src/ai/synthesize.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,gFAAgF;AAChF,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,2EAA2E;AAC3E,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;CACxD;AA0FD,2EAA2E;AAC3E,qBAAa,eAAgB,YAAW,WAAW;IACrC,OAAO,CAAC,KAAK;gBAAL,KAAK,EAAE,SAAS;IAE9B,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;CAoB7D"}
|
package/dist/ai/synthesize.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { recoverToolArgsFromContent, warnToolChoiceIgnored } from "./llm/recover-tool.js";
|
|
1
2
|
const SYSTEM_PROMPT = `You build an ARCHITECTURE graph of a codebase from per-file summaries. The reader is an AI agent that will read this graph before working on the code, so it must describe the system at the level a senior engineer would explain it — not file by file.
|
|
2
3
|
|
|
3
4
|
Produce a CURATED set of nodes of mixed granularity:
|
|
@@ -107,11 +108,24 @@ export class ChatSynthesizer {
|
|
|
107
108
|
{ role: "user", content: userContent(files) },
|
|
108
109
|
],
|
|
109
110
|
});
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
return clean(nodesFromResponse(res)?.nodes);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Prefer a real tool call; if the gateway ignored `tool_choice` (#129), recover
|
|
116
|
+
* the same payload from `content`. Recovered args still go through {@link clean}.
|
|
117
|
+
*/
|
|
118
|
+
function nodesFromResponse(res) {
|
|
119
|
+
const call = res.toolCalls.find((c) => c.name === RECORD_TOOL) ?? res.toolCalls[0];
|
|
120
|
+
if (call?.args && typeof call.args === "object" && !Array.isArray(call.args)) {
|
|
121
|
+
return call.args;
|
|
115
122
|
}
|
|
123
|
+
const recovered = recoverToolArgsFromContent(res.text, {
|
|
124
|
+
toolNames: [RECORD_TOOL, "emit_json"],
|
|
125
|
+
payloadKey: "nodes",
|
|
126
|
+
});
|
|
127
|
+
if (!recovered)
|
|
128
|
+
warnToolChoiceIgnored("synthesize", res.text?.trim() ? "unparsed" : "empty");
|
|
129
|
+
return recovered;
|
|
116
130
|
}
|
|
117
131
|
//# sourceMappingURL=synthesize.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synthesize.js","sourceRoot":"","sources":["../../src/ai/synthesize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"synthesize.js","sourceRoot":"","sources":["../../src/ai/synthesize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface CheckoutRequest {
|
|
2
|
+
owner: string;
|
|
3
|
+
repo: string;
|
|
4
|
+
number: number;
|
|
5
|
+
baseRef: string;
|
|
6
|
+
token: string;
|
|
7
|
+
api?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface Checkout {
|
|
10
|
+
/** Working tree at the pull request's merge commit. */
|
|
11
|
+
dir: string;
|
|
12
|
+
/** What `blast --base` should diff against. */
|
|
13
|
+
base: string;
|
|
14
|
+
/** Removes the tree. Always call it — the token's clone is not something to
|
|
15
|
+
* leave in /tmp. */
|
|
16
|
+
cleanup: () => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Fetch the PR's merge ref and its base, shallow.
|
|
20
|
+
*
|
|
21
|
+
* `refs/pull/N/merge` is GitHub's own merge of the PR into its base — the same
|
|
22
|
+
* thing the checks see, and the right thing to review: it is what will land, not
|
|
23
|
+
* what the contributor's branch says in isolation.
|
|
24
|
+
*/
|
|
25
|
+
export declare function checkoutPullRequest(req: CheckoutRequest): Checkout;
|
|
26
|
+
/** Never let a token reach a log line, even inside git's own error text. */
|
|
27
|
+
export declare function redact(text: string, token: string): string;
|
|
28
|
+
//# sourceMappingURL=checkout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../../src/app/checkout.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb;wBACoB;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAkCD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,QAAQ,CAoClE;AAED,4EAA4E;AAC5E,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI1D"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Getting a pull request's code onto disk without running any of it.
|
|
3
|
+
*
|
|
4
|
+
* On a fork PR every byte here was written by a stranger, and this service holds
|
|
5
|
+
* an installation token for the base repository. So the rules are absolute:
|
|
6
|
+
*
|
|
7
|
+
* - **Nothing is executed.** No `npm install`, no build, no hooks. The graph is
|
|
8
|
+
* produced by tree-sitter reading source text, which runs none of it.
|
|
9
|
+
* - **Git is told not to run things either.** A repository can carry hooks, and
|
|
10
|
+
* `core.hooksPath` is a per-repo config a clone would otherwise honour; both
|
|
11
|
+
* are disabled explicitly rather than assumed absent.
|
|
12
|
+
* - **The token never lands in the repo.** It is passed per-invocation through
|
|
13
|
+
* an http header config, not baked into a remote URL that `git remote -v`,
|
|
14
|
+
* the reflog and any submodule would carry.
|
|
15
|
+
* - **Bounded.** A hostile or merely enormous repository must not hold a worker
|
|
16
|
+
* forever: every git call has a timeout, and the fetch is shallow.
|
|
17
|
+
*/
|
|
18
|
+
import { spawnSync } from "node:child_process";
|
|
19
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
20
|
+
import { tmpdir } from "node:os";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
/** Enough history for a merge base against the pull request's base branch. */
|
|
23
|
+
const FETCH_DEPTH = 50;
|
|
24
|
+
const GIT_TIMEOUT_MS = 120_000;
|
|
25
|
+
/** A git invocation with the dangerous parts of the environment removed. */
|
|
26
|
+
function git(dir, args, token) {
|
|
27
|
+
const auth = token
|
|
28
|
+
? [
|
|
29
|
+
"-c",
|
|
30
|
+
// Basic auth with the token as the password, per GitHub's own guidance for
|
|
31
|
+
// installation tokens. Passed as an argument to THIS call so it is never
|
|
32
|
+
// written into .git/config.
|
|
33
|
+
`http.extraheader=Authorization: Basic ${Buffer.from(`x-access-token:${token}`).toString("base64")}`,
|
|
34
|
+
]
|
|
35
|
+
: [];
|
|
36
|
+
const res = spawnSync("git", ["-c", "core.hooksPath=/dev/null", "-c", "protocol.version=2", ...auth, ...args], {
|
|
37
|
+
cwd: dir,
|
|
38
|
+
encoding: "utf8",
|
|
39
|
+
timeout: GIT_TIMEOUT_MS,
|
|
40
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
41
|
+
env: {
|
|
42
|
+
...process.env,
|
|
43
|
+
// No credential prompts, no system config, no repo-supplied helpers.
|
|
44
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
45
|
+
GIT_CONFIG_NOSYSTEM: "1",
|
|
46
|
+
GIT_ASKPASS: "",
|
|
47
|
+
HOME: dir,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
return { ok: res.status === 0, err: `${res.stderr ?? ""}${res.error ? ` ${res.error.message}` : ""}`.trim() };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Fetch the PR's merge ref and its base, shallow.
|
|
54
|
+
*
|
|
55
|
+
* `refs/pull/N/merge` is GitHub's own merge of the PR into its base — the same
|
|
56
|
+
* thing the checks see, and the right thing to review: it is what will land, not
|
|
57
|
+
* what the contributor's branch says in isolation.
|
|
58
|
+
*/
|
|
59
|
+
export function checkoutPullRequest(req) {
|
|
60
|
+
const host = (req.api ?? "https://github.com").replace(/\/$/, "");
|
|
61
|
+
const dir = mkdtempSync(join(tmpdir(), `graft-app-${req.owner}-${req.repo}-`));
|
|
62
|
+
const cleanup = () => rmSync(dir, { recursive: true, force: true });
|
|
63
|
+
const steps = [
|
|
64
|
+
["init", ["init", "--quiet", "-b", "__graft_base"]],
|
|
65
|
+
["remote", ["remote", "add", "origin", `${host}/${req.owner}/${req.repo}.git`]],
|
|
66
|
+
// Both refs in one fetch: the merge ref to review, the base to diff against.
|
|
67
|
+
[
|
|
68
|
+
"fetch",
|
|
69
|
+
[
|
|
70
|
+
"fetch",
|
|
71
|
+
"--quiet",
|
|
72
|
+
`--depth=${FETCH_DEPTH}`,
|
|
73
|
+
"--no-recurse-submodules",
|
|
74
|
+
"origin",
|
|
75
|
+
`+refs/pull/${req.number}/merge:refs/graft/merge`,
|
|
76
|
+
`+refs/heads/${req.baseRef}:refs/graft/base`,
|
|
77
|
+
],
|
|
78
|
+
],
|
|
79
|
+
["checkout", ["checkout", "--quiet", "--detach", "refs/graft/merge"]],
|
|
80
|
+
];
|
|
81
|
+
for (const [name, args] of steps) {
|
|
82
|
+
const { ok, err } = git(dir, args, name === "fetch" ? req.token : undefined);
|
|
83
|
+
if (!ok) {
|
|
84
|
+
cleanup();
|
|
85
|
+
// A merge ref is absent while GitHub is still computing mergeability, and
|
|
86
|
+
// present-but-stale right after a push — worth saying which step failed so
|
|
87
|
+
// that case is distinguishable from a permissions problem.
|
|
88
|
+
throw new Error(`checkout ${req.owner}/${req.repo}#${req.number} failed at ${name}: ${redact(err, req.token)}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { dir, base: "refs/graft/base", cleanup };
|
|
92
|
+
}
|
|
93
|
+
/** Never let a token reach a log line, even inside git's own error text. */
|
|
94
|
+
export function redact(text, token) {
|
|
95
|
+
if (!token)
|
|
96
|
+
return text;
|
|
97
|
+
const encoded = Buffer.from(`x-access-token:${token}`).toString("base64");
|
|
98
|
+
return text.split(token).join("[token]").split(encoded).join("[token]");
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=checkout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout.js","sourceRoot":"","sources":["../../src/app/checkout.ts"],"names":[],"mappings":"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"}
|