@jx-grxf/patchpilot 0.2.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/.env.example +13 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +71 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/agent.d.ts +21 -0
- package/dist/core/agent.js +346 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/codex.d.ts +22 -0
- package/dist/core/codex.js +242 -0
- package/dist/core/codex.js.map +1 -0
- package/dist/core/compute.d.ts +9 -0
- package/dist/core/compute.js +18 -0
- package/dist/core/compute.js.map +1 -0
- package/dist/core/doctor.d.ts +7 -0
- package/dist/core/doctor.js +226 -0
- package/dist/core/doctor.js.map +1 -0
- package/dist/core/env.d.ts +6 -0
- package/dist/core/env.js +103 -0
- package/dist/core/env.js.map +1 -0
- package/dist/core/gemini.d.ts +20 -0
- package/dist/core/gemini.js +177 -0
- package/dist/core/gemini.js.map +1 -0
- package/dist/core/json.d.ts +3 -0
- package/dist/core/json.js +95 -0
- package/dist/core/json.js.map +1 -0
- package/dist/core/modelClient.d.ts +8 -0
- package/dist/core/modelClient.js +42 -0
- package/dist/core/modelClient.js.map +1 -0
- package/dist/core/nvidia.d.ts +19 -0
- package/dist/core/nvidia.js +160 -0
- package/dist/core/nvidia.js.map +1 -0
- package/dist/core/ollama.d.ts +31 -0
- package/dist/core/ollama.js +176 -0
- package/dist/core/ollama.js.map +1 -0
- package/dist/core/openrouter.d.ts +27 -0
- package/dist/core/openrouter.js +168 -0
- package/dist/core/openrouter.js.map +1 -0
- package/dist/core/subagents.d.ts +14 -0
- package/dist/core/subagents.js +89 -0
- package/dist/core/subagents.js.map +1 -0
- package/dist/core/tokenAccounting.d.ts +6 -0
- package/dist/core/tokenAccounting.js +134 -0
- package/dist/core/tokenAccounting.js.map +1 -0
- package/dist/core/types.d.ts +90 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/workspace.d.ts +28 -0
- package/dist/core/workspace.js +616 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/tui/App.d.ts +6 -0
- package/dist/tui/App.js +1717 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/commands.d.ts +14 -0
- package/dist/tui/commands.js +210 -0
- package/dist/tui/commands.js.map +1 -0
- package/dist/tui/components/CommandSuggestions.d.ts +12 -0
- package/dist/tui/components/CommandSuggestions.js +12 -0
- package/dist/tui/components/CommandSuggestions.js.map +1 -0
- package/dist/tui/components/Composer.d.ts +13 -0
- package/dist/tui/components/Composer.js +29 -0
- package/dist/tui/components/Composer.js.map +1 -0
- package/dist/tui/components/Header.d.ts +25 -0
- package/dist/tui/components/Header.js +62 -0
- package/dist/tui/components/Header.js.map +1 -0
- package/dist/tui/components/OnboardingPanel.d.ts +38 -0
- package/dist/tui/components/OnboardingPanel.js +85 -0
- package/dist/tui/components/OnboardingPanel.js.map +1 -0
- package/dist/tui/components/Sidebar.d.ts +22 -0
- package/dist/tui/components/Sidebar.js +133 -0
- package/dist/tui/components/Sidebar.js.map +1 -0
- package/dist/tui/components/Transcript.d.ts +10 -0
- package/dist/tui/components/Transcript.js +111 -0
- package/dist/tui/components/Transcript.js.map +1 -0
- package/dist/tui/format.d.ts +29 -0
- package/dist/tui/format.js +202 -0
- package/dist/tui/format.js.map +1 -0
- package/dist/tui/hosts.d.ts +34 -0
- package/dist/tui/hosts.js +338 -0
- package/dist/tui/hosts.js.map +1 -0
- package/dist/tui/inputRouting.d.ts +8 -0
- package/dist/tui/inputRouting.js +94 -0
- package/dist/tui/inputRouting.js.map +1 -0
- package/dist/tui/platform.d.ts +2 -0
- package/dist/tui/platform.js +13 -0
- package/dist/tui/platform.js.map +1 -0
- package/dist/tui/systemStats.d.ts +25 -0
- package/dist/tui/systemStats.js +88 -0
- package/dist/tui/systemStats.js.map +1 -0
- package/dist/tui/types.d.ts +16 -0
- package/dist/tui/types.js +2 -0
- package/dist/tui/types.js.map +1 -0
- package/docs/showcase/patchpilot-showcase.svg +39 -0
- package/package.json +63 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const toolNameSchema = z.enum([
|
|
3
|
+
"list_files",
|
|
4
|
+
"read_file",
|
|
5
|
+
"search_text",
|
|
6
|
+
"inspect_document",
|
|
7
|
+
"write_file",
|
|
8
|
+
"run_shell"
|
|
9
|
+
]);
|
|
10
|
+
const toolCallSchema = z.object({
|
|
11
|
+
name: toolNameSchema,
|
|
12
|
+
arguments: z.record(z.string(), z.unknown()).default({})
|
|
13
|
+
});
|
|
14
|
+
const agentResponseSchema = z.discriminatedUnion("action", [
|
|
15
|
+
z.object({
|
|
16
|
+
action: z.literal("tools"),
|
|
17
|
+
message: z.string().default(""),
|
|
18
|
+
tool_calls: z.array(toolCallSchema).min(1)
|
|
19
|
+
}),
|
|
20
|
+
z.object({
|
|
21
|
+
action: z.literal("final"),
|
|
22
|
+
message: z.string()
|
|
23
|
+
})
|
|
24
|
+
]);
|
|
25
|
+
export function parseAgentResponse(rawContent) {
|
|
26
|
+
const parsed = normalizeModelJson(JSON.parse(extractJson(rawContent)));
|
|
27
|
+
return agentResponseSchema.parse(parsed);
|
|
28
|
+
}
|
|
29
|
+
export function formatParseError(error) {
|
|
30
|
+
if (error instanceof z.ZodError) {
|
|
31
|
+
const firstIssue = error.issues[0];
|
|
32
|
+
if (!firstIssue) {
|
|
33
|
+
return "response did not match the PatchPilot protocol.";
|
|
34
|
+
}
|
|
35
|
+
const location = firstIssue.path.length > 0 ? ` at ${firstIssue.path.join(".")}` : "";
|
|
36
|
+
return `${firstIssue.message}${location}`;
|
|
37
|
+
}
|
|
38
|
+
return error instanceof Error ? error.message : String(error);
|
|
39
|
+
}
|
|
40
|
+
function extractJson(rawContent) {
|
|
41
|
+
const trimmedContent = rawContent.trim();
|
|
42
|
+
if (trimmedContent.startsWith("{") && trimmedContent.endsWith("}")) {
|
|
43
|
+
return trimmedContent;
|
|
44
|
+
}
|
|
45
|
+
const fencedMatch = trimmedContent.match(/```(?:json)?\s*([\s\S]*?)\s*```/i);
|
|
46
|
+
if (fencedMatch?.[1]) {
|
|
47
|
+
return fencedMatch[1].trim();
|
|
48
|
+
}
|
|
49
|
+
const firstBrace = trimmedContent.indexOf("{");
|
|
50
|
+
const lastBrace = trimmedContent.lastIndexOf("}");
|
|
51
|
+
if (firstBrace >= 0 && lastBrace > firstBrace) {
|
|
52
|
+
return trimmedContent.slice(firstBrace, lastBrace + 1);
|
|
53
|
+
}
|
|
54
|
+
throw new Error("Model response did not contain a JSON object.");
|
|
55
|
+
}
|
|
56
|
+
function normalizeModelJson(parsed) {
|
|
57
|
+
if (Array.isArray(parsed)) {
|
|
58
|
+
if (parsed.length === 1) {
|
|
59
|
+
return normalizeModelJson(parsed[0]);
|
|
60
|
+
}
|
|
61
|
+
if (parsed.every(isToolCallLike)) {
|
|
62
|
+
return {
|
|
63
|
+
action: "tools",
|
|
64
|
+
message: "Requesting tools.",
|
|
65
|
+
tool_calls: parsed
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (isRecord(parsed)) {
|
|
70
|
+
if (!("action" in parsed) && "tool_calls" in parsed) {
|
|
71
|
+
return {
|
|
72
|
+
action: "tools",
|
|
73
|
+
message: readString(parsed.message, "Requesting tools."),
|
|
74
|
+
tool_calls: parsed.tool_calls
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (!("action" in parsed) && "message" in parsed) {
|
|
78
|
+
return {
|
|
79
|
+
action: "final",
|
|
80
|
+
message: readString(parsed.message, "")
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return parsed;
|
|
85
|
+
}
|
|
86
|
+
function isToolCallLike(value) {
|
|
87
|
+
return isRecord(value) && "name" in value && "arguments" in value;
|
|
88
|
+
}
|
|
89
|
+
function isRecord(value) {
|
|
90
|
+
return typeof value === "object" && value !== null;
|
|
91
|
+
}
|
|
92
|
+
function readString(value, fallback) {
|
|
93
|
+
return typeof value === "string" ? value : fallback;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/core/json.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ModelClient, ModelProvider } from "./types.js";
|
|
2
|
+
export declare function createModelClient(options: {
|
|
3
|
+
provider: ModelProvider;
|
|
4
|
+
ollamaUrl: string;
|
|
5
|
+
workspace?: string;
|
|
6
|
+
}): ModelClient;
|
|
7
|
+
export declare function readModelProvider(env?: NodeJS.ProcessEnv): ModelProvider;
|
|
8
|
+
export declare function normalizeModelProvider(value: string): ModelProvider;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CodexCliClient } from "./codex.js";
|
|
2
|
+
import { GeminiClient } from "./gemini.js";
|
|
3
|
+
import { NvidiaClient } from "./nvidia.js";
|
|
4
|
+
import { OllamaClient } from "./ollama.js";
|
|
5
|
+
import { OpenRouterClient } from "./openrouter.js";
|
|
6
|
+
export function createModelClient(options) {
|
|
7
|
+
if (options.provider === "gemini") {
|
|
8
|
+
return new GeminiClient();
|
|
9
|
+
}
|
|
10
|
+
if (options.provider === "codex") {
|
|
11
|
+
return new CodexCliClient({
|
|
12
|
+
workspace: options.workspace ?? process.cwd()
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
if (options.provider === "openrouter") {
|
|
16
|
+
return new OpenRouterClient();
|
|
17
|
+
}
|
|
18
|
+
if (options.provider === "nvidia") {
|
|
19
|
+
return new NvidiaClient();
|
|
20
|
+
}
|
|
21
|
+
return new OllamaClient(options.ollamaUrl);
|
|
22
|
+
}
|
|
23
|
+
export function readModelProvider(env = process.env) {
|
|
24
|
+
return normalizeModelProvider(env.PATCHPILOT_PROVIDER ?? env.PATCHPILOT_MODEL_PROVIDER ?? "ollama");
|
|
25
|
+
}
|
|
26
|
+
export function normalizeModelProvider(value) {
|
|
27
|
+
const normalizedValue = value.trim().toLowerCase();
|
|
28
|
+
if (normalizedValue === "gemini" || normalizedValue === "google") {
|
|
29
|
+
return "gemini";
|
|
30
|
+
}
|
|
31
|
+
if (normalizedValue === "codex" || normalizedValue === "openai" || normalizedValue === "openai-codex") {
|
|
32
|
+
return "codex";
|
|
33
|
+
}
|
|
34
|
+
if (normalizedValue === "openrouter" || normalizedValue === "open-router") {
|
|
35
|
+
return "openrouter";
|
|
36
|
+
}
|
|
37
|
+
if (normalizedValue === "nvidia" || normalizedValue === "nim") {
|
|
38
|
+
return "nvidia";
|
|
39
|
+
}
|
|
40
|
+
return "ollama";
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=modelClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modelClient.js","sourceRoot":"","sources":["../../src/core/modelClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,MAAM,UAAU,iBAAiB,CAAC,OAIjC;IACC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,IAAI,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,IAAI,cAAc,CAAC;YACxB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QACtC,OAAO,IAAI,gBAAgB,EAAE,CAAC;IAChC,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,IAAI,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACpE,OAAO,sBAAsB,CAAC,GAAG,CAAC,mBAAmB,IAAI,GAAG,CAAC,yBAAyB,IAAI,QAAQ,CAAC,CAAC;AACtG,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,IAAI,eAAe,KAAK,QAAQ,IAAI,eAAe,KAAK,QAAQ,EAAE,CAAC;QACjE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,eAAe,KAAK,OAAO,IAAI,eAAe,KAAK,QAAQ,IAAI,eAAe,KAAK,cAAc,EAAE,CAAC;QACtG,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,eAAe,KAAK,YAAY,IAAI,eAAe,KAAK,aAAa,EAAE,CAAC;QAC1E,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,eAAe,KAAK,QAAQ,IAAI,eAAe,KAAK,KAAK,EAAE,CAAC;QAC9D,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ModelChatOptions, ModelChatResult } from "./types.js";
|
|
2
|
+
export declare const defaultNvidiaModel = "meta/llama-3.1-70b-instruct";
|
|
3
|
+
export declare const defaultNvidiaBaseUrl = "https://integrate.api.nvidia.com/v1";
|
|
4
|
+
type NvidiaRuntimeOptions = {
|
|
5
|
+
maxTokens: number;
|
|
6
|
+
temperature: number;
|
|
7
|
+
};
|
|
8
|
+
export declare class NvidiaClient {
|
|
9
|
+
private readonly apiKey;
|
|
10
|
+
private readonly baseUrl;
|
|
11
|
+
private readonly runtimeOptions;
|
|
12
|
+
constructor(apiKey?: string, baseUrl?: string, runtimeOptions?: NvidiaRuntimeOptions);
|
|
13
|
+
chat(options: ModelChatOptions): Promise<ModelChatResult>;
|
|
14
|
+
listModels(): Promise<string[]>;
|
|
15
|
+
private fetchNvidia;
|
|
16
|
+
private assertConfigured;
|
|
17
|
+
}
|
|
18
|
+
export declare function readNvidiaApiKey(env?: NodeJS.ProcessEnv): string;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { attachTokenCost } from "./tokenAccounting.js";
|
|
2
|
+
export const defaultNvidiaModel = "meta/llama-3.1-70b-instruct";
|
|
3
|
+
export const defaultNvidiaBaseUrl = "https://integrate.api.nvidia.com/v1";
|
|
4
|
+
export class NvidiaClient {
|
|
5
|
+
apiKey;
|
|
6
|
+
baseUrl;
|
|
7
|
+
runtimeOptions;
|
|
8
|
+
constructor(apiKey = readNvidiaApiKey(), baseUrl = process.env.PATCHPILOT_NVIDIA_BASE_URL ?? defaultNvidiaBaseUrl, runtimeOptions = readNvidiaRuntimeOptions()) {
|
|
9
|
+
this.apiKey = apiKey;
|
|
10
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
11
|
+
this.runtimeOptions = runtimeOptions;
|
|
12
|
+
}
|
|
13
|
+
async chat(options) {
|
|
14
|
+
this.assertConfigured();
|
|
15
|
+
const startedAt = Date.now();
|
|
16
|
+
const response = await this.fetchNvidia("/chat/completions", {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: {
|
|
19
|
+
"Content-Type": "application/json",
|
|
20
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
21
|
+
},
|
|
22
|
+
body: JSON.stringify({
|
|
23
|
+
model: options.model,
|
|
24
|
+
messages: options.messages,
|
|
25
|
+
max_tokens: this.runtimeOptions.maxTokens,
|
|
26
|
+
temperature: this.runtimeOptions.temperature,
|
|
27
|
+
response_format: options.formatJson ? agentResponseFormat : undefined
|
|
28
|
+
}),
|
|
29
|
+
signal: options.signal
|
|
30
|
+
});
|
|
31
|
+
const durationMs = Date.now() - startedAt;
|
|
32
|
+
const payload = (await readJsonSafely(response));
|
|
33
|
+
if (!response.ok || payload.error) {
|
|
34
|
+
const reason = payload.error?.message ? ` ${payload.error.message}` : "";
|
|
35
|
+
throw new Error(`NVIDIA chat failed for model "${options.model}": HTTP ${response.status}.${reason}`);
|
|
36
|
+
}
|
|
37
|
+
const content = payload.choices?.[0]?.message?.content?.trim() ?? "";
|
|
38
|
+
if (!content) {
|
|
39
|
+
throw new Error("NVIDIA returned an empty response.");
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
content,
|
|
43
|
+
telemetry: toTelemetry(payload, durationMs, options.model)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async listModels() {
|
|
47
|
+
this.assertConfigured();
|
|
48
|
+
const response = await this.fetchNvidia("/models");
|
|
49
|
+
const payload = (await readJsonSafely(response));
|
|
50
|
+
if (!response.ok || payload.error) {
|
|
51
|
+
const reason = payload.error?.message ? ` ${payload.error.message}` : "";
|
|
52
|
+
throw new Error(`NVIDIA models failed with HTTP ${response.status}.${reason}`);
|
|
53
|
+
}
|
|
54
|
+
const models = payload.data?.map((model) => model.id?.trim()).filter((model) => Boolean(model)).sort() ?? [];
|
|
55
|
+
return models.length > 0 ? models : [defaultNvidiaModel];
|
|
56
|
+
}
|
|
57
|
+
async fetchNvidia(path, init) {
|
|
58
|
+
try {
|
|
59
|
+
return await fetch(`${this.baseUrl}${path}`, init);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
const suffix = error instanceof Error ? ` ${error.message}` : "";
|
|
63
|
+
throw new Error(`Cannot reach NVIDIA API at ${this.baseUrl}.${suffix}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
assertConfigured() {
|
|
67
|
+
if (!this.apiKey) {
|
|
68
|
+
throw new Error("NVIDIA API key missing. Set NVIDIA_API_KEY in PatchPilot config, .env, or your shell.");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const agentResponseFormat = {
|
|
73
|
+
type: "json_schema",
|
|
74
|
+
json_schema: {
|
|
75
|
+
name: "patchpilot_agent_response",
|
|
76
|
+
strict: true,
|
|
77
|
+
schema: {
|
|
78
|
+
anyOf: [
|
|
79
|
+
{
|
|
80
|
+
type: "object",
|
|
81
|
+
additionalProperties: false,
|
|
82
|
+
required: ["action", "message", "tool_calls"],
|
|
83
|
+
properties: {
|
|
84
|
+
action: { const: "tools" },
|
|
85
|
+
message: { type: "string" },
|
|
86
|
+
tool_calls: {
|
|
87
|
+
type: "array",
|
|
88
|
+
minItems: 1,
|
|
89
|
+
items: {
|
|
90
|
+
type: "object",
|
|
91
|
+
additionalProperties: false,
|
|
92
|
+
required: ["name", "arguments"],
|
|
93
|
+
properties: {
|
|
94
|
+
name: {
|
|
95
|
+
enum: ["list_files", "read_file", "search_text", "inspect_document", "write_file", "run_shell"]
|
|
96
|
+
},
|
|
97
|
+
arguments: {
|
|
98
|
+
type: "object",
|
|
99
|
+
additionalProperties: true
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
type: "object",
|
|
108
|
+
additionalProperties: false,
|
|
109
|
+
required: ["action", "message"],
|
|
110
|
+
properties: {
|
|
111
|
+
action: { const: "final" },
|
|
112
|
+
message: { type: "string" }
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
export function readNvidiaApiKey(env = process.env) {
|
|
120
|
+
return env.NVIDIA_API_KEY?.trim() || env.PATCHPILOT_NVIDIA_API_KEY?.trim() || "";
|
|
121
|
+
}
|
|
122
|
+
function readNvidiaRuntimeOptions(env = process.env) {
|
|
123
|
+
return {
|
|
124
|
+
maxTokens: readPositiveInteger(env.PATCHPILOT_NUM_PREDICT, 1024),
|
|
125
|
+
temperature: readTemperature(env.PATCHPILOT_TEMPERATURE, 0.1)
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function toTelemetry(payload, durationMs, model) {
|
|
129
|
+
const promptTokens = payload.usage?.prompt_tokens ?? 0;
|
|
130
|
+
const responseTokens = payload.usage?.completion_tokens ?? 0;
|
|
131
|
+
return attachTokenCost({
|
|
132
|
+
promptTokens,
|
|
133
|
+
cachedPromptTokens: 0,
|
|
134
|
+
cacheWriteTokens: 0,
|
|
135
|
+
responseTokens,
|
|
136
|
+
totalTokens: payload.usage?.total_tokens ?? promptTokens + responseTokens,
|
|
137
|
+
evalTokensPerSecond: responseTokens > 0 && durationMs > 0 ? responseTokens / (durationMs / 1000) : null,
|
|
138
|
+
promptDurationMs: 0,
|
|
139
|
+
responseDurationMs: durationMs,
|
|
140
|
+
totalDurationMs: durationMs,
|
|
141
|
+
tokenSource: "provider"
|
|
142
|
+
}, "nvidia", model);
|
|
143
|
+
}
|
|
144
|
+
async function readJsonSafely(response) {
|
|
145
|
+
try {
|
|
146
|
+
return await response.json();
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return {};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function readPositiveInteger(value, fallback) {
|
|
153
|
+
const parsedValue = Number.parseInt(value ?? "", 10);
|
|
154
|
+
return Number.isFinite(parsedValue) && parsedValue > 0 ? parsedValue : fallback;
|
|
155
|
+
}
|
|
156
|
+
function readTemperature(value, fallback) {
|
|
157
|
+
const parsedValue = Number.parseFloat(value ?? "");
|
|
158
|
+
return Number.isFinite(parsedValue) && parsedValue >= 0 ? parsedValue : fallback;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=nvidia.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nvidia.js","sourceRoot":"","sources":["../../src/core/nvidia.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ModelChatOptions, ModelChatResult } from "./types.js";
|
|
2
|
+
export declare const defaultOllamaModel = "qwen2.5-coder:7b";
|
|
3
|
+
export declare const defaultOllamaUrl = "http://127.0.0.1:11434";
|
|
4
|
+
export declare const defaultOllamaPort = 11434;
|
|
5
|
+
export type OllamaRunningModel = {
|
|
6
|
+
name: string;
|
|
7
|
+
sizeBytes: number | null;
|
|
8
|
+
sizeVramBytes: number | null;
|
|
9
|
+
expiresAt: string | null;
|
|
10
|
+
contextLength: number | null;
|
|
11
|
+
};
|
|
12
|
+
type OllamaRuntimeOptions = {
|
|
13
|
+
keepAlive: string;
|
|
14
|
+
numCtx: number;
|
|
15
|
+
numPredict: number;
|
|
16
|
+
temperature: number;
|
|
17
|
+
};
|
|
18
|
+
export declare class OllamaClient {
|
|
19
|
+
private readonly baseUrl;
|
|
20
|
+
private readonly runtimeOptions;
|
|
21
|
+
constructor(baseUrl?: string, runtimeOptions?: OllamaRuntimeOptions);
|
|
22
|
+
chat(options: ModelChatOptions): Promise<ModelChatResult>;
|
|
23
|
+
listModels(): Promise<string[]>;
|
|
24
|
+
listRunningModels(): Promise<OllamaRunningModel[]>;
|
|
25
|
+
unloadModel(model: string): Promise<void>;
|
|
26
|
+
private fetchOllama;
|
|
27
|
+
}
|
|
28
|
+
export declare function resolveOllamaBaseUrl(env?: NodeJS.ProcessEnv): string;
|
|
29
|
+
export declare function normalizeOllamaBaseUrl(value: string | undefined): string;
|
|
30
|
+
export declare function readOllamaRuntimeOptions(env?: NodeJS.ProcessEnv): OllamaRuntimeOptions;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { attachTokenCost } from "./tokenAccounting.js";
|
|
2
|
+
export const defaultOllamaModel = "qwen2.5-coder:7b";
|
|
3
|
+
export const defaultOllamaUrl = "http://127.0.0.1:11434";
|
|
4
|
+
export const defaultOllamaPort = 11434;
|
|
5
|
+
export class OllamaClient {
|
|
6
|
+
baseUrl;
|
|
7
|
+
runtimeOptions;
|
|
8
|
+
constructor(baseUrl = defaultOllamaUrl, runtimeOptions = readOllamaRuntimeOptions()) {
|
|
9
|
+
this.baseUrl = normalizeOllamaBaseUrl(baseUrl);
|
|
10
|
+
this.runtimeOptions = runtimeOptions;
|
|
11
|
+
}
|
|
12
|
+
async chat(options) {
|
|
13
|
+
const response = await this.fetchOllama("/api/chat", {
|
|
14
|
+
method: "POST",
|
|
15
|
+
headers: {
|
|
16
|
+
"Content-Type": "application/json"
|
|
17
|
+
},
|
|
18
|
+
body: JSON.stringify({
|
|
19
|
+
model: options.model,
|
|
20
|
+
messages: options.messages,
|
|
21
|
+
stream: false,
|
|
22
|
+
keep_alive: this.runtimeOptions.keepAlive,
|
|
23
|
+
options: {
|
|
24
|
+
num_ctx: this.runtimeOptions.numCtx,
|
|
25
|
+
num_predict: this.runtimeOptions.numPredict,
|
|
26
|
+
temperature: this.runtimeOptions.temperature
|
|
27
|
+
},
|
|
28
|
+
format: options.formatJson ? "json" : undefined
|
|
29
|
+
}),
|
|
30
|
+
signal: options.signal
|
|
31
|
+
});
|
|
32
|
+
const payload = (await readJsonSafely(response));
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
const reason = payload.error ? ` ${payload.error}` : "";
|
|
35
|
+
throw new Error(`Ollama chat failed for model "${options.model}" at ${this.baseUrl}: HTTP ${response.status}.${reason}`);
|
|
36
|
+
}
|
|
37
|
+
if (payload.error) {
|
|
38
|
+
throw new Error(payload.error);
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
content: payload.message?.content?.trim() ?? "",
|
|
42
|
+
telemetry: toTelemetry(payload, options.model)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async listModels() {
|
|
46
|
+
const response = await this.fetchOllama("/api/tags");
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
throw new Error(`Ollama tags failed with HTTP ${response.status}.`);
|
|
49
|
+
}
|
|
50
|
+
const payload = (await response.json());
|
|
51
|
+
return payload.models?.map((model) => model.name).sort() ?? [];
|
|
52
|
+
}
|
|
53
|
+
async listRunningModels() {
|
|
54
|
+
const response = await this.fetchOllama("/api/ps");
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
throw new Error(`Ollama ps failed with HTTP ${response.status}.`);
|
|
57
|
+
}
|
|
58
|
+
const payload = (await response.json());
|
|
59
|
+
return (payload.models
|
|
60
|
+
?.map((model) => {
|
|
61
|
+
const name = model.name?.trim() || model.model?.trim() || "";
|
|
62
|
+
return name
|
|
63
|
+
? {
|
|
64
|
+
name,
|
|
65
|
+
sizeBytes: readNullableFiniteNumber(model.size),
|
|
66
|
+
sizeVramBytes: readNullableFiniteNumber(model.size_vram),
|
|
67
|
+
expiresAt: typeof model.expires_at === "string" ? model.expires_at : null,
|
|
68
|
+
contextLength: readNullableFiniteNumber(model.context_length ?? model.details?.context_length)
|
|
69
|
+
}
|
|
70
|
+
: null;
|
|
71
|
+
})
|
|
72
|
+
.filter((model) => model !== null)
|
|
73
|
+
.sort((left, right) => left.name.localeCompare(right.name)) ?? []);
|
|
74
|
+
}
|
|
75
|
+
async unloadModel(model) {
|
|
76
|
+
const trimmedModel = model.trim();
|
|
77
|
+
if (!trimmedModel) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const response = await this.fetchOllama("/api/generate", {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: {
|
|
83
|
+
"Content-Type": "application/json"
|
|
84
|
+
},
|
|
85
|
+
body: JSON.stringify({
|
|
86
|
+
model: trimmedModel,
|
|
87
|
+
keep_alive: 0
|
|
88
|
+
})
|
|
89
|
+
});
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
throw new Error(`Ollama unload failed for model "${trimmedModel}" at ${this.baseUrl}: HTTP ${response.status}.`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async fetchOllama(path, init) {
|
|
95
|
+
try {
|
|
96
|
+
return await fetch(`${this.baseUrl}${path}`, init);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
throw new Error(formatOllamaConnectionError(this.baseUrl, error));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function readJsonSafely(response) {
|
|
104
|
+
try {
|
|
105
|
+
return await response.json();
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return {};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export function resolveOllamaBaseUrl(env = process.env) {
|
|
112
|
+
return normalizeOllamaBaseUrl(env.PATCHPILOT_OLLAMA_URL ?? env.OLLAMA_HOST ?? defaultOllamaUrl);
|
|
113
|
+
}
|
|
114
|
+
export function normalizeOllamaBaseUrl(value) {
|
|
115
|
+
const trimmedValue = value?.trim() ?? "";
|
|
116
|
+
const normalizedAlias = trimmedValue.toLowerCase();
|
|
117
|
+
if (!trimmedValue || normalizedAlias === "local" || normalizedAlias === "localhost") {
|
|
118
|
+
return defaultOllamaUrl;
|
|
119
|
+
}
|
|
120
|
+
const rawUrl = /^https?:\/\//i.test(trimmedValue) ? trimmedValue : `http://${trimmedValue}`;
|
|
121
|
+
const parsedUrl = new URL(rawUrl);
|
|
122
|
+
if (parsedUrl.hostname === "0.0.0.0" || parsedUrl.hostname === "[::]" || parsedUrl.hostname === "::") {
|
|
123
|
+
parsedUrl.hostname = "127.0.0.1";
|
|
124
|
+
}
|
|
125
|
+
if (!parsedUrl.port && parsedUrl.protocol === "http:") {
|
|
126
|
+
parsedUrl.port = String(defaultOllamaPort);
|
|
127
|
+
}
|
|
128
|
+
if (parsedUrl.pathname === "/api") {
|
|
129
|
+
parsedUrl.pathname = "";
|
|
130
|
+
}
|
|
131
|
+
return parsedUrl.toString().replace(/\/$/, "");
|
|
132
|
+
}
|
|
133
|
+
export function readOllamaRuntimeOptions(env = process.env) {
|
|
134
|
+
return {
|
|
135
|
+
keepAlive: env.PATCHPILOT_KEEP_ALIVE?.trim() || "15m",
|
|
136
|
+
numCtx: readPositiveInteger(env.PATCHPILOT_NUM_CTX, 8192),
|
|
137
|
+
numPredict: readPositiveInteger(env.PATCHPILOT_NUM_PREDICT, 1024),
|
|
138
|
+
temperature: readTemperature(env.PATCHPILOT_TEMPERATURE, 0.1)
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function readPositiveInteger(value, fallback) {
|
|
142
|
+
const parsedValue = Number.parseInt(value ?? "", 10);
|
|
143
|
+
return Number.isFinite(parsedValue) && parsedValue > 0 ? parsedValue : fallback;
|
|
144
|
+
}
|
|
145
|
+
function readTemperature(value, fallback) {
|
|
146
|
+
const parsedValue = Number.parseFloat(value ?? "");
|
|
147
|
+
return Number.isFinite(parsedValue) && parsedValue >= 0 ? parsedValue : fallback;
|
|
148
|
+
}
|
|
149
|
+
function readNullableFiniteNumber(value) {
|
|
150
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
151
|
+
}
|
|
152
|
+
function formatOllamaConnectionError(baseUrl, error) {
|
|
153
|
+
const suffix = error instanceof Error ? ` ${error.message}` : "";
|
|
154
|
+
return `Cannot reach Ollama at ${baseUrl}. Start Ollama, or run "ollama serve", then try /doctor.${suffix}`;
|
|
155
|
+
}
|
|
156
|
+
function toTelemetry(payload, model) {
|
|
157
|
+
const promptTokens = payload.prompt_eval_count ?? 0;
|
|
158
|
+
const responseTokens = payload.eval_count ?? 0;
|
|
159
|
+
const responseDurationMs = nanosToMillis(payload.eval_duration ?? 0);
|
|
160
|
+
return attachTokenCost({
|
|
161
|
+
promptTokens,
|
|
162
|
+
cachedPromptTokens: 0,
|
|
163
|
+
cacheWriteTokens: 0,
|
|
164
|
+
responseTokens,
|
|
165
|
+
totalTokens: promptTokens + responseTokens,
|
|
166
|
+
evalTokensPerSecond: responseTokens > 0 && responseDurationMs > 0 ? responseTokens / (responseDurationMs / 1000) : null,
|
|
167
|
+
promptDurationMs: nanosToMillis(payload.prompt_eval_duration ?? 0),
|
|
168
|
+
responseDurationMs,
|
|
169
|
+
totalDurationMs: nanosToMillis(payload.total_duration ?? 0),
|
|
170
|
+
tokenSource: "provider"
|
|
171
|
+
}, "ollama", model);
|
|
172
|
+
}
|
|
173
|
+
function nanosToMillis(value) {
|
|
174
|
+
return Math.round(value / 1_000_000);
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=ollama.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/core/ollama.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ModelChatOptions, ModelChatResult } from "./types.js";
|
|
2
|
+
export declare const defaultOpenRouterModel = "openrouter/auto";
|
|
3
|
+
export declare const defaultOpenRouterBaseUrl = "https://openrouter.ai/api/v1";
|
|
4
|
+
type OpenRouterRuntimeOptions = {
|
|
5
|
+
maxTokens: number;
|
|
6
|
+
temperature: number;
|
|
7
|
+
};
|
|
8
|
+
export type OpenRouterTokenRates = {
|
|
9
|
+
inputPerToken: number;
|
|
10
|
+
cachedInputPerToken: number;
|
|
11
|
+
cacheWritePerToken: number;
|
|
12
|
+
outputPerToken: number;
|
|
13
|
+
};
|
|
14
|
+
export declare class OpenRouterClient {
|
|
15
|
+
private readonly apiKey;
|
|
16
|
+
private readonly baseUrl;
|
|
17
|
+
private readonly runtimeOptions;
|
|
18
|
+
constructor(apiKey?: string, baseUrl?: string, runtimeOptions?: OpenRouterRuntimeOptions);
|
|
19
|
+
chat(options: ModelChatOptions): Promise<ModelChatResult>;
|
|
20
|
+
listModels(): Promise<string[]>;
|
|
21
|
+
private fetchOpenRouter;
|
|
22
|
+
private assertConfigured;
|
|
23
|
+
}
|
|
24
|
+
export declare function readOpenRouterApiKey(env?: NodeJS.ProcessEnv): string;
|
|
25
|
+
export declare function isOpenRouterFreeModel(model: string): boolean;
|
|
26
|
+
export declare function getOpenRouterModelRates(model: string): Promise<OpenRouterTokenRates | null>;
|
|
27
|
+
export {};
|