@gtc6244/immediacy-daemon 0.1.1 → 0.1.3
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 +58 -25
- package/dist/src/agent/agent.d.ts +19 -6
- package/dist/src/agent/agent.js +3 -1
- package/dist/src/agent/agent.js.map +1 -1
- package/dist/src/agent/anthropic-probe.d.ts +24 -0
- package/dist/src/agent/anthropic-probe.js +81 -0
- package/dist/src/agent/anthropic-probe.js.map +1 -0
- package/dist/src/agent/claude.d.ts +4 -2
- package/dist/src/agent/claude.js +32 -4
- package/dist/src/agent/claude.js.map +1 -1
- package/dist/src/agent/codex.d.ts +1 -1
- package/dist/src/agent/codex.js +26 -3
- package/dist/src/agent/codex.js.map +1 -1
- package/dist/src/agent/images.d.ts +21 -0
- package/dist/src/agent/images.js +54 -0
- package/dist/src/agent/images.js.map +1 -0
- package/dist/src/agent/mock.d.ts +1 -1
- package/dist/src/agent/mock.js +28 -3
- package/dist/src/agent/mock.js.map +1 -1
- package/dist/src/agent/ollama-probe.d.ts +28 -0
- package/dist/src/agent/ollama-probe.js +76 -0
- package/dist/src/agent/ollama-probe.js.map +1 -0
- package/dist/src/agent/ollama.d.ts +42 -0
- package/dist/src/agent/ollama.js +64 -0
- package/dist/src/agent/ollama.js.map +1 -0
- package/dist/src/agent/openai-probe.d.ts +18 -0
- package/dist/src/agent/openai-probe.js +83 -0
- package/dist/src/agent/openai-probe.js.map +1 -0
- package/dist/src/agent/openrouter-probe.d.ts +21 -0
- package/dist/src/agent/openrouter-probe.js +77 -0
- package/dist/src/agent/openrouter-probe.js.map +1 -0
- package/dist/src/cli/paths.d.ts +2 -0
- package/dist/src/cli/paths.js +14 -7
- package/dist/src/cli/paths.js.map +1 -1
- package/dist/src/cli.js +40 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/crypto.js +7 -2
- package/dist/src/crypto.js.map +1 -1
- package/dist/src/hub.d.ts +7 -0
- package/dist/src/hub.js +14 -0
- package/dist/src/hub.js.map +1 -1
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.js +35 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/jobs/scheduler.d.ts +1 -0
- package/dist/src/jobs/scheduler.js +1 -0
- package/dist/src/jobs/scheduler.js.map +1 -1
- package/dist/src/media-watch.d.ts +29 -0
- package/dist/src/media-watch.js +108 -0
- package/dist/src/media-watch.js.map +1 -0
- package/dist/src/media.d.ts +54 -0
- package/dist/src/media.js +156 -0
- package/dist/src/media.js.map +1 -0
- package/dist/src/model-efforts.d.ts +49 -0
- package/dist/src/model-efforts.js +107 -0
- package/dist/src/model-efforts.js.map +1 -0
- package/dist/src/models.d.ts +50 -17
- package/dist/src/models.js +119 -21
- package/dist/src/models.js.map +1 -1
- package/dist/src/projects.d.ts +7 -0
- package/dist/src/projects.js +14 -0
- package/dist/src/projects.js.map +1 -1
- package/dist/src/protocol.d.ts +163 -9
- package/dist/src/protocol.js +1 -1
- package/dist/src/server.js +141 -5
- package/dist/src/server.js.map +1 -1
- package/dist/src/types.d.ts +9 -0
- package/dist/src/updater.d.ts +78 -0
- package/dist/src/updater.js +240 -0
- package/dist/src/updater.js.map +1 -0
- package/dist/src/workspace.d.ts +25 -0
- package/dist/src/workspace.js +159 -6
- package/dist/src/workspace.js.map +1 -1
- package/package.json +4 -2
- package/dist/src/migrate-state-dir.d.ts +0 -1
- package/dist/src/migrate-state-dir.js +0 -47
- package/dist/src/migrate-state-dir.js.map +0 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend-neutral image extraction.
|
|
3
|
+
*
|
|
4
|
+
* Screenshots (and any other agent-produced images) arrive as Anthropic-style
|
|
5
|
+
* `image` content blocks — either directly in an assistant/user message's
|
|
6
|
+
* `content[]`, or nested inside a `tool_result` block's own `content[]` (the
|
|
7
|
+
* common case: a screenshot tool returns an image as its result). This helper
|
|
8
|
+
* walks either shape and pulls out every base64 image, so any agent backend can
|
|
9
|
+
* translate its own output into the shared `{ kind: "image" }` AgentEvent
|
|
10
|
+
* without duplicating the traversal.
|
|
11
|
+
*
|
|
12
|
+
* It intentionally knows nothing about any specific SDK — it operates on plain
|
|
13
|
+
* `unknown` and defends against every field being missing/mistyped.
|
|
14
|
+
*/
|
|
15
|
+
/** Pull every base64 image block out of a message/tool-result content value. */
|
|
16
|
+
export function extractImages(content) {
|
|
17
|
+
const out = [];
|
|
18
|
+
collect(content, out);
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
function collect(node, out) {
|
|
22
|
+
if (Array.isArray(node)) {
|
|
23
|
+
for (const child of node)
|
|
24
|
+
collect(child, out);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!node || typeof node !== "object")
|
|
28
|
+
return;
|
|
29
|
+
const block = node;
|
|
30
|
+
if (block.type === "image") {
|
|
31
|
+
const img = readImageSource(block.source);
|
|
32
|
+
if (img)
|
|
33
|
+
out.push(img);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// A tool_result carries its own content[] — recurse so a screenshot returned
|
|
37
|
+
// as a tool result is found. Also handles any other nested content shape.
|
|
38
|
+
if (block.content !== undefined)
|
|
39
|
+
collect(block.content, out);
|
|
40
|
+
}
|
|
41
|
+
/** Read a `{ type:"base64", media_type, data }` image source, if well-formed. */
|
|
42
|
+
function readImageSource(source) {
|
|
43
|
+
if (!source || typeof source !== "object")
|
|
44
|
+
return null;
|
|
45
|
+
const s = source;
|
|
46
|
+
if (s.type !== "base64")
|
|
47
|
+
return null; // URL sources aren't bytes we can store
|
|
48
|
+
const mediaType = typeof s.media_type === "string" ? s.media_type : "";
|
|
49
|
+
const data = typeof s.data === "string" ? s.data : "";
|
|
50
|
+
if (!mediaType.startsWith("image/") || data.length === 0)
|
|
51
|
+
return null;
|
|
52
|
+
return { mediaType, data };
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=images.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.js","sourceRoot":"","sources":["../../../src/agent/images.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,MAAM,GAAG,GAAqB,EAAE,CAAC;IACjC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACtB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,IAAa,EAAE,GAAqB;IACnD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,IAAI;YAAE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO;IAC9C,MAAM,KAAK,GAAG,IAA8D,CAAC;IAE7E,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,GAAG;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO;IACT,CAAC;IACD,6EAA6E;IAC7E,0EAA0E;IAC1E,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC/D,CAAC;AAED,iFAAiF;AACjF,SAAS,eAAe,CAAC,MAAe;IACtC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvD,MAAM,CAAC,GAAG,MAAiE,CAAC;IAC5E,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,CAAC,wCAAwC;IAC9E,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC"}
|
package/dist/src/agent/mock.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export declare class MockAgent extends BaseAgent {
|
|
|
21
21
|
private turn;
|
|
22
22
|
constructor(ctx: AgentContext);
|
|
23
23
|
prompt(text: string, attachments?: AgentAttachment[]): void;
|
|
24
|
-
respondPermission(requestId: string, decision: PermissionResponse):
|
|
24
|
+
respondPermission(requestId: string, decision: PermissionResponse): boolean;
|
|
25
25
|
/** See ClaudeAgent.releaseCoveredPending — same retroactive-release sweep. */
|
|
26
26
|
private releaseCoveredPending;
|
|
27
27
|
stop(): Promise<void>;
|
package/dist/src/agent/mock.js
CHANGED
|
@@ -46,14 +46,14 @@ export class MockAgent extends BaseAgent {
|
|
|
46
46
|
.catch(() => { });
|
|
47
47
|
}
|
|
48
48
|
this.pendingCalls.delete(requestId);
|
|
49
|
-
this.gate.resolve(requestId, "allow");
|
|
49
|
+
const accepted = this.gate.resolve(requestId, "allow");
|
|
50
50
|
// Mirror ClaudeAgent: a new rule retroactively releases matching pending
|
|
51
51
|
// calls (see claude.ts releaseCoveredPending).
|
|
52
52
|
this.releaseCoveredPending();
|
|
53
|
-
return;
|
|
53
|
+
return accepted;
|
|
54
54
|
}
|
|
55
55
|
this.pendingCalls.delete(requestId);
|
|
56
|
-
this.gate.resolve(requestId, decision);
|
|
56
|
+
return this.gate.resolve(requestId, decision);
|
|
57
57
|
}
|
|
58
58
|
/** See ClaudeAgent.releaseCoveredPending — same retroactive-release sweep. */
|
|
59
59
|
releaseCoveredPending() {
|
|
@@ -89,6 +89,27 @@ export class MockAgent extends BaseAgent {
|
|
|
89
89
|
this.emitEvent({ kind: "status", status: "error" });
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
|
+
// QA hook: "/shot" exercises both image-capture paths without a model —
|
|
93
|
+
// (1) a tool-result image event, and (2) a real PNG written into the
|
|
94
|
+
// worktree for the file-on-disk detector to surface (`source: "file"`).
|
|
95
|
+
if (promptText.trim().startsWith("/shot")) {
|
|
96
|
+
this.emitEvent({ kind: "status", status: "running" });
|
|
97
|
+
await delay(150);
|
|
98
|
+
this.emitEvent({ kind: "assistant", text: "Here's a screenshot." });
|
|
99
|
+
this.emitEvent({
|
|
100
|
+
kind: "image",
|
|
101
|
+
mediaType: "image/png",
|
|
102
|
+
data: TINY_PNG_B64,
|
|
103
|
+
source: "tool",
|
|
104
|
+
});
|
|
105
|
+
// Distinct bytes from the tool image so both surface (the store dedupes by
|
|
106
|
+
// content hash) — exercises the file-on-disk detector (`source: "file"`).
|
|
107
|
+
const shotPath = join(this.ctx.worktreePath, `shot-${this.turn}.png`);
|
|
108
|
+
await writeFile(shotPath, Buffer.from(DIFF_PNG_B64, "base64"));
|
|
109
|
+
this.emitEvent({ kind: "done", summary: "screenshot", usage: MOCK_USAGE });
|
|
110
|
+
this.emitEvent({ kind: "status", status: "done" });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
92
113
|
const fileName = `mock-${this.turn}.txt`;
|
|
93
114
|
const filePath = join(this.ctx.worktreePath, fileName);
|
|
94
115
|
const contents = `Created by MockAgent for prompt:\n${promptText}\n`;
|
|
@@ -152,4 +173,8 @@ const MOCK_USAGE = {
|
|
|
152
173
|
function delay(ms) {
|
|
153
174
|
return new Promise((r) => setTimeout(r, ms));
|
|
154
175
|
}
|
|
176
|
+
/** A minimal valid 1×1 PNG, base64 (no data: prefix) — the /shot tool image. */
|
|
177
|
+
const TINY_PNG_B64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+M8AAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
|
|
178
|
+
/** A second, distinct 1×1 PNG — the /shot on-disk file (different content hash). */
|
|
179
|
+
const DIFF_PNG_B64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
|
|
155
180
|
//# sourceMappingURL=mock.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock.js","sourceRoot":"","sources":["../../../src/agent/mock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAqD,MAAM,YAAY,CAAC;AAC1F,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,OAAO,SAAU,SAAQ,SAAS;IAOlB;IANZ,IAAI,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;IAC3C,2EAA2E;IACnE,YAAY,GAAG,IAAI,GAAG,EAA4D,CAAC;IACnF,SAAS,GAAG,UAAU,EAAE,CAAC;IACzB,IAAI,GAAG,CAAC,CAAC;IAEjB,YAAoB,GAAiB;QACnC,KAAK,EAAE,CAAC;QADU,QAAG,GAAH,GAAG,CAAc;QAEnC,qEAAqE;QACrE,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,WAA+B;QAClD,yEAAyE;QACzE,iEAAiE;QACjE,MAAM,IAAI,GACR,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;YACnC,CAAC,CAAC,GAAG,IAAI,KAAK,WAAW,CAAC,MAAM,mBAAmB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAC/F,CAAC,CAAC,IAAI,CAAC;QACX,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,iBAAiB,CAAC,SAAiB,EAAE,QAA4B;QAC/D,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC9C,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;gBAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,SAAS;qBACpB,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC;qBACjF,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACrB,CAAC;YACD,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"mock.js","sourceRoot":"","sources":["../../../src/agent/mock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama discovery — probe a local Ollama instance for the models it actually
|
|
3
|
+
* serves, so the picker offers what's installed instead of a guessed list.
|
|
4
|
+
*
|
|
5
|
+
* Ollama's native REST API exposes `GET /api/tags`: the locally-pulled models.
|
|
6
|
+
* A connection error (refused / timeout) means Ollama isn't running — we treat
|
|
7
|
+
* that as "no Ollama models" rather than an error, so a machine without Ollama
|
|
8
|
+
* simply shows none.
|
|
9
|
+
*
|
|
10
|
+
* The result is cached with a short TTL: the daemon probes once at startup and
|
|
11
|
+
* re-probes lazily when a client asks for `models.list`, so a freshly
|
|
12
|
+
* `ollama pull`ed model appears without a daemon restart — and without hammering
|
|
13
|
+
* the endpoint on every request.
|
|
14
|
+
*/
|
|
15
|
+
import type { ModelInfo } from "../protocol.js";
|
|
16
|
+
/**
|
|
17
|
+
* Ollama host root. Both the native `/api/tags` used here and the
|
|
18
|
+
* Anthropic-compatible endpoint the SDK targets (see OllamaAgent) hang off it,
|
|
19
|
+
* so this is the single source of truth for where Ollama lives.
|
|
20
|
+
*/
|
|
21
|
+
export declare const OLLAMA_BASE_URL: string;
|
|
22
|
+
/** Last known Ollama models (may be up to CACHE_TTL_MS stale). */
|
|
23
|
+
export declare function ollamaModels(): ModelInfo[];
|
|
24
|
+
/**
|
|
25
|
+
* Refresh the Ollama model cache, honoring the TTL unless `force`. Returns the
|
|
26
|
+
* (possibly empty) list. Never throws — an unreachable Ollama yields `[]`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function refreshOllamaModels(force?: boolean): Promise<ModelInfo[]>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama discovery — probe a local Ollama instance for the models it actually
|
|
3
|
+
* serves, so the picker offers what's installed instead of a guessed list.
|
|
4
|
+
*
|
|
5
|
+
* Ollama's native REST API exposes `GET /api/tags`: the locally-pulled models.
|
|
6
|
+
* A connection error (refused / timeout) means Ollama isn't running — we treat
|
|
7
|
+
* that as "no Ollama models" rather than an error, so a machine without Ollama
|
|
8
|
+
* simply shows none.
|
|
9
|
+
*
|
|
10
|
+
* The result is cached with a short TTL: the daemon probes once at startup and
|
|
11
|
+
* re-probes lazily when a client asks for `models.list`, so a freshly
|
|
12
|
+
* `ollama pull`ed model appears without a daemon restart — and without hammering
|
|
13
|
+
* the endpoint on every request.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Ollama host root. Both the native `/api/tags` used here and the
|
|
17
|
+
* Anthropic-compatible endpoint the SDK targets (see OllamaAgent) hang off it,
|
|
18
|
+
* so this is the single source of truth for where Ollama lives.
|
|
19
|
+
*/
|
|
20
|
+
export const OLLAMA_BASE_URL = process.env.OLLAMA_BASE_URL ?? "http://localhost:11434";
|
|
21
|
+
/** Optional bearer for a protected/remote Ollama; a local instance ignores it. */
|
|
22
|
+
const OLLAMA_API_KEY = process.env.OLLAMA_API_KEY?.trim();
|
|
23
|
+
/** Cap the probe so a hung endpoint can't stall startup or a models.list reply. */
|
|
24
|
+
const PROBE_TIMEOUT_MS = 1500;
|
|
25
|
+
/** Serve the cached list for this long before re-probing on the next request. */
|
|
26
|
+
const CACHE_TTL_MS = 15_000;
|
|
27
|
+
let cache = [];
|
|
28
|
+
let lastProbeMs = 0;
|
|
29
|
+
/** Last known Ollama models (may be up to CACHE_TTL_MS stale). */
|
|
30
|
+
export function ollamaModels() {
|
|
31
|
+
return cache;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Refresh the Ollama model cache, honoring the TTL unless `force`. Returns the
|
|
35
|
+
* (possibly empty) list. Never throws — an unreachable Ollama yields `[]`.
|
|
36
|
+
*/
|
|
37
|
+
export async function refreshOllamaModels(force = false) {
|
|
38
|
+
const now = Date.now();
|
|
39
|
+
if (!force && now - lastProbeMs < CACHE_TTL_MS)
|
|
40
|
+
return cache;
|
|
41
|
+
lastProbeMs = now;
|
|
42
|
+
cache = await probeOllama();
|
|
43
|
+
return cache;
|
|
44
|
+
}
|
|
45
|
+
/** GET `{base}/api/tags` → ModelInfo[]; `[]` on any failure (incl. Ollama absent). */
|
|
46
|
+
async function probeOllama() {
|
|
47
|
+
try {
|
|
48
|
+
const res = await fetch(`${OLLAMA_BASE_URL}/api/tags`, {
|
|
49
|
+
signal: AbortSignal.timeout(PROBE_TIMEOUT_MS),
|
|
50
|
+
headers: OLLAMA_API_KEY ? { Authorization: `Bearer ${OLLAMA_API_KEY}` } : {},
|
|
51
|
+
});
|
|
52
|
+
if (!res.ok)
|
|
53
|
+
return [];
|
|
54
|
+
const body = (await res.json());
|
|
55
|
+
const seen = new Set();
|
|
56
|
+
const models = [];
|
|
57
|
+
for (const t of body.models ?? []) {
|
|
58
|
+
const id = (t.name ?? t.model ?? "").trim();
|
|
59
|
+
if (!id || seen.has(id))
|
|
60
|
+
continue;
|
|
61
|
+
seen.add(id);
|
|
62
|
+
models.push({ id, label: labelFor(id), provider: "ollama" });
|
|
63
|
+
}
|
|
64
|
+
return models;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Connection refused, DNS failure, timeout, or malformed JSON → treat as
|
|
68
|
+
// "Ollama not available", which is the common (no-Ollama) case.
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** `"qwen3-coder:latest"` → `"qwen3-coder"`; other tags are kept verbatim. */
|
|
73
|
+
function labelFor(tag) {
|
|
74
|
+
return tag.endsWith(":latest") ? tag.slice(0, -":latest".length) : tag;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=ollama-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-probe.js","sourceRoot":"","sources":["../../../src/agent/ollama-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAC1B,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB,CAAC;AAE1D,kFAAkF;AAClF,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;AAE1D,mFAAmF;AACnF,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,iFAAiF;AACjF,MAAM,YAAY,GAAG,MAAM,CAAC;AAW5B,IAAI,KAAK,GAAgB,EAAE,CAAC;AAC5B,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB,kEAAkE;AAClE,MAAM,UAAU,YAAY;IAC1B,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAK,GAAG,KAAK;IACrD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG,WAAW,GAAG,YAAY;QAAE,OAAO,KAAK,CAAC;IAC7D,WAAW,GAAG,GAAG,CAAC;IAClB,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,sFAAsF;AACtF,KAAK,UAAU,WAAW;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,eAAe,WAAW,EAAE;YACrD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC;YAC7C,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE;SAC7E,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAuB,CAAC;QACtD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YAClC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,SAAS;YAClC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;QACzE,gEAAgE;QAChE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,SAAS,QAAQ,CAAC,GAAW;IAC3B,OAAO,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OllamaAgent — a locally-hosted Ollama model driven through the Claude Agent
|
|
3
|
+
* SDK.
|
|
4
|
+
*
|
|
5
|
+
* Ollama runs models on the user's own machine (or a self-hosted box) and can
|
|
6
|
+
* expose an Anthropic-compatible Messages endpoint, so — exactly like
|
|
7
|
+
* OpenRouterAgent — we reuse the SDK that already powers ClaudeAgent and just
|
|
8
|
+
* retarget it. Every guarantee ClaudeAgent gives (worktree-scoped auto-approve,
|
|
9
|
+
* phone permission gate on escape, streaming, session resume, no
|
|
10
|
+
* `bypassPermissions`) holds identically; the only difference is that inference
|
|
11
|
+
* runs locally instead of against a hosted API — no tokens are billed and the
|
|
12
|
+
* code never leaves the machine.
|
|
13
|
+
*
|
|
14
|
+
* We subclass ClaudeAgent and hand it SDK `env` overrides instead of touching
|
|
15
|
+
* `process.env`, so a native-Claude workspace and an Ollama workspace can be
|
|
16
|
+
* live at the same time without stepping on each other's config.
|
|
17
|
+
*
|
|
18
|
+
* Config (nothing sensitive in source):
|
|
19
|
+
* OLLAMA_BASE_URL default http://localhost:11434 — the Ollama host's
|
|
20
|
+
* Anthropic-compatible endpoint. Override for a remote box or
|
|
21
|
+
* a proxy that fronts Ollama with an Anthropic skin.
|
|
22
|
+
* OLLAMA_API_KEY optional — only needed for a remote/protected Ollama behind
|
|
23
|
+
* an auth proxy. Local Ollama is keyless, so this defaults to
|
|
24
|
+
* a placeholder token (the SDK requires a non-empty one).
|
|
25
|
+
*
|
|
26
|
+
* The model id (`ctx.model`) is an Ollama model tag (e.g. `qwen3-coder`,
|
|
27
|
+
* `llama3.3`; see models.ts). It flows to the SDK's `model` option via
|
|
28
|
+
* ClaudeAgent, and we pin every Claude Code "model class" to that same tag so a
|
|
29
|
+
* stray built-in default (e.g. a background haiku call) can't be sent to Ollama,
|
|
30
|
+
* which would only recognize its own locally-pulled tags.
|
|
31
|
+
*/
|
|
32
|
+
import { ClaudeAgent } from "./claude.js";
|
|
33
|
+
import type { AgentContext } from "./agent.js";
|
|
34
|
+
export declare class OllamaAgent extends ClaudeAgent {
|
|
35
|
+
/**
|
|
36
|
+
* @param apiKey Optional token for a protected/remote Ollama. Local Ollama is
|
|
37
|
+
* keyless, so when unset we fall back to OLLAMA_API_KEY, then a placeholder
|
|
38
|
+
* ("ollama") — the SDK rejects an empty auth token even when the endpoint
|
|
39
|
+
* ignores it.
|
|
40
|
+
*/
|
|
41
|
+
constructor(ctx: AgentContext, apiKey?: string);
|
|
42
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OllamaAgent — a locally-hosted Ollama model driven through the Claude Agent
|
|
3
|
+
* SDK.
|
|
4
|
+
*
|
|
5
|
+
* Ollama runs models on the user's own machine (or a self-hosted box) and can
|
|
6
|
+
* expose an Anthropic-compatible Messages endpoint, so — exactly like
|
|
7
|
+
* OpenRouterAgent — we reuse the SDK that already powers ClaudeAgent and just
|
|
8
|
+
* retarget it. Every guarantee ClaudeAgent gives (worktree-scoped auto-approve,
|
|
9
|
+
* phone permission gate on escape, streaming, session resume, no
|
|
10
|
+
* `bypassPermissions`) holds identically; the only difference is that inference
|
|
11
|
+
* runs locally instead of against a hosted API — no tokens are billed and the
|
|
12
|
+
* code never leaves the machine.
|
|
13
|
+
*
|
|
14
|
+
* We subclass ClaudeAgent and hand it SDK `env` overrides instead of touching
|
|
15
|
+
* `process.env`, so a native-Claude workspace and an Ollama workspace can be
|
|
16
|
+
* live at the same time without stepping on each other's config.
|
|
17
|
+
*
|
|
18
|
+
* Config (nothing sensitive in source):
|
|
19
|
+
* OLLAMA_BASE_URL default http://localhost:11434 — the Ollama host's
|
|
20
|
+
* Anthropic-compatible endpoint. Override for a remote box or
|
|
21
|
+
* a proxy that fronts Ollama with an Anthropic skin.
|
|
22
|
+
* OLLAMA_API_KEY optional — only needed for a remote/protected Ollama behind
|
|
23
|
+
* an auth proxy. Local Ollama is keyless, so this defaults to
|
|
24
|
+
* a placeholder token (the SDK requires a non-empty one).
|
|
25
|
+
*
|
|
26
|
+
* The model id (`ctx.model`) is an Ollama model tag (e.g. `qwen3-coder`,
|
|
27
|
+
* `llama3.3`; see models.ts). It flows to the SDK's `model` option via
|
|
28
|
+
* ClaudeAgent, and we pin every Claude Code "model class" to that same tag so a
|
|
29
|
+
* stray built-in default (e.g. a background haiku call) can't be sent to Ollama,
|
|
30
|
+
* which would only recognize its own locally-pulled tags.
|
|
31
|
+
*/
|
|
32
|
+
import { ClaudeAgent } from "./claude.js";
|
|
33
|
+
import { OLLAMA_BASE_URL } from "./ollama-probe.js";
|
|
34
|
+
export class OllamaAgent extends ClaudeAgent {
|
|
35
|
+
/**
|
|
36
|
+
* @param apiKey Optional token for a protected/remote Ollama. Local Ollama is
|
|
37
|
+
* keyless, so when unset we fall back to OLLAMA_API_KEY, then a placeholder
|
|
38
|
+
* ("ollama") — the SDK rejects an empty auth token even when the endpoint
|
|
39
|
+
* ignores it.
|
|
40
|
+
*/
|
|
41
|
+
constructor(ctx, apiKey) {
|
|
42
|
+
// Ollama authenticates (when it does at all) via ANTHROPIC_AUTH_TOKEN (a
|
|
43
|
+
// bearer token); ANTHROPIC_API_KEY must be blank so the SDK doesn't prefer a
|
|
44
|
+
// stored Anthropic key and bypass the local endpoint.
|
|
45
|
+
const key = apiKey ?? process.env.OLLAMA_API_KEY ?? "ollama";
|
|
46
|
+
const tag = ctx.model;
|
|
47
|
+
super(ctx, {
|
|
48
|
+
ANTHROPIC_BASE_URL: OLLAMA_BASE_URL,
|
|
49
|
+
ANTHROPIC_AUTH_TOKEN: key,
|
|
50
|
+
ANTHROPIC_API_KEY: "",
|
|
51
|
+
// Route every model class to the selected tag; leaving these unset lets
|
|
52
|
+
// the CLI fall back to Anthropic default ids Ollama can't serve.
|
|
53
|
+
...(tag
|
|
54
|
+
? {
|
|
55
|
+
ANTHROPIC_MODEL: tag,
|
|
56
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: tag,
|
|
57
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: tag,
|
|
58
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: tag,
|
|
59
|
+
}
|
|
60
|
+
: {}),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=ollama.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../src/agent/ollama.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,OAAO,WAAY,SAAQ,WAAW;IAC1C;;;;;OAKG;IACH,YAAY,GAAiB,EAAE,MAAe;QAC5C,yEAAyE;QACzE,6EAA6E;QAC7E,sDAAsD;QACtD,MAAM,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,QAAQ,CAAC;QAC7D,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC;QACtB,KAAK,CAAC,GAAG,EAAE;YACT,kBAAkB,EAAE,eAAe;YACnC,oBAAoB,EAAE,GAAG;YACzB,iBAAiB,EAAE,EAAE;YACrB,wEAAwE;YACxE,iEAAiE;YACjE,GAAG,CAAC,GAAG;gBACL,CAAC,CAAC;oBACE,eAAe,EAAE,GAAG;oBACpB,4BAA4B,EAAE,GAAG;oBACjC,8BAA8B,EAAE,GAAG;oBACnC,6BAA6B,EAAE,GAAG;iBACnC;gBACH,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI model discovery — enumerate the models the account can use from the
|
|
3
|
+
* live Models API (`GET /v1/models`), scoped to the last 12 months, for the
|
|
4
|
+
* Codex backend.
|
|
5
|
+
*
|
|
6
|
+
* The list endpoint returns `{ id, created }` (a Unix timestamp) per model; we
|
|
7
|
+
* keep only chat/reasoning models `created` within the trailing year and attach
|
|
8
|
+
* the reasoning-effort levels each family supports (see effortsForCodex).
|
|
9
|
+
*
|
|
10
|
+
* Requires an OpenAI API key — a ChatGPT-login Codex can't enumerate models. No
|
|
11
|
+
* key → `[]`, and models.ts falls back to the curated static catalog (which
|
|
12
|
+
* still includes the keyless "codex (account default)" sentinel). Never throws.
|
|
13
|
+
*/
|
|
14
|
+
import type { ModelInfo } from "../protocol.js";
|
|
15
|
+
/** Last known OpenAI models (may be up to CACHE_TTL_MS stale). */
|
|
16
|
+
export declare function openaiModels(): ModelInfo[];
|
|
17
|
+
/** Refresh the OpenAI catalog, honoring the TTL unless `force`. Never throws. */
|
|
18
|
+
export declare function refreshOpenAIModels(apiKey?: string, force?: boolean): Promise<ModelInfo[]>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI model discovery — enumerate the models the account can use from the
|
|
3
|
+
* live Models API (`GET /v1/models`), scoped to the last 12 months, for the
|
|
4
|
+
* Codex backend.
|
|
5
|
+
*
|
|
6
|
+
* The list endpoint returns `{ id, created }` (a Unix timestamp) per model; we
|
|
7
|
+
* keep only chat/reasoning models `created` within the trailing year and attach
|
|
8
|
+
* the reasoning-effort levels each family supports (see effortsForCodex).
|
|
9
|
+
*
|
|
10
|
+
* Requires an OpenAI API key — a ChatGPT-login Codex can't enumerate models. No
|
|
11
|
+
* key → `[]`, and models.ts falls back to the curated static catalog (which
|
|
12
|
+
* still includes the keyless "codex (account default)" sentinel). Never throws.
|
|
13
|
+
*/
|
|
14
|
+
import { effortsForCodex, DEFAULT_CODEX_EFFORT } from "../model-efforts.js";
|
|
15
|
+
const OPENAI_BASE_URL = process.env.OPENAI_BASE_URL ?? "https://api.openai.com";
|
|
16
|
+
const PROBE_TIMEOUT_MS = 4000;
|
|
17
|
+
const CACHE_TTL_MS = 60_000;
|
|
18
|
+
const YEAR_MS = 365 * 24 * 60 * 60 * 1000;
|
|
19
|
+
/**
|
|
20
|
+
* Only surface models that back the Codex CLI — chat/reasoning families. The
|
|
21
|
+
* raw list also carries embeddings, audio, image, and moderation models that
|
|
22
|
+
* would just clutter the picker.
|
|
23
|
+
*/
|
|
24
|
+
function isCodexModel(id) {
|
|
25
|
+
return /^(gpt-5|gpt-4\.|o[0-9]|codex)/i.test(id) && !/audio|realtime|image|tts|transcribe|embedding/i.test(id);
|
|
26
|
+
}
|
|
27
|
+
let cache = [];
|
|
28
|
+
let lastProbeMs = 0;
|
|
29
|
+
/** Last known OpenAI models (may be up to CACHE_TTL_MS stale). */
|
|
30
|
+
export function openaiModels() {
|
|
31
|
+
return cache;
|
|
32
|
+
}
|
|
33
|
+
/** Refresh the OpenAI catalog, honoring the TTL unless `force`. Never throws. */
|
|
34
|
+
export async function refreshOpenAIModels(apiKey, force = false) {
|
|
35
|
+
if (!apiKey) {
|
|
36
|
+
cache = [];
|
|
37
|
+
return cache;
|
|
38
|
+
}
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
if (!force && now - lastProbeMs < CACHE_TTL_MS)
|
|
41
|
+
return cache;
|
|
42
|
+
lastProbeMs = now;
|
|
43
|
+
cache = await probe(apiKey);
|
|
44
|
+
return cache;
|
|
45
|
+
}
|
|
46
|
+
async function probe(apiKey) {
|
|
47
|
+
try {
|
|
48
|
+
const res = await fetch(`${OPENAI_BASE_URL}/v1/models`, {
|
|
49
|
+
signal: AbortSignal.timeout(PROBE_TIMEOUT_MS),
|
|
50
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
51
|
+
});
|
|
52
|
+
if (!res.ok)
|
|
53
|
+
return [];
|
|
54
|
+
const body = (await res.json());
|
|
55
|
+
const cutoff = Date.now() - YEAR_MS;
|
|
56
|
+
const models = [];
|
|
57
|
+
for (const m of body.data ?? []) {
|
|
58
|
+
const id = (m.id ?? "").trim();
|
|
59
|
+
if (!id || !isCodexModel(id))
|
|
60
|
+
continue;
|
|
61
|
+
// `created` is a Unix timestamp in seconds; keep only the last 12 months.
|
|
62
|
+
if (typeof m.created === "number" && m.created * 1000 < cutoff)
|
|
63
|
+
continue;
|
|
64
|
+
const efforts = effortsForCodex(id);
|
|
65
|
+
models.push({
|
|
66
|
+
id,
|
|
67
|
+
label: id,
|
|
68
|
+
provider: "codex",
|
|
69
|
+
...(typeof m.created === "number"
|
|
70
|
+
? { released: new Date(m.created * 1000).toISOString() }
|
|
71
|
+
: {}),
|
|
72
|
+
...(efforts
|
|
73
|
+
? { efforts, defaultEffort: DEFAULT_CODEX_EFFORT(efforts) }
|
|
74
|
+
: {}),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return models;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=openai-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-probe.js","sourceRoot":"","sources":["../../../src/agent/openai-probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter model discovery — enumerate routable models from the live catalog
|
|
3
|
+
* (`GET /api/v1/models`), scoped to the last 12 months.
|
|
4
|
+
*
|
|
5
|
+
* The endpoint is keyless for listing and returns `{ id, name, created,
|
|
6
|
+
* supported_parameters }` per model; we keep models `created` within the
|
|
7
|
+
* trailing year (newest first) and attach reasoning-effort levels to any model
|
|
8
|
+
* whose `supported_parameters` advertises `reasoning` (see effortsForOpenRouter).
|
|
9
|
+
*
|
|
10
|
+
* Never throws: an unreachable endpoint yields `[]`, and models.ts falls back to
|
|
11
|
+
* its curated OpenRouter starter set.
|
|
12
|
+
*/
|
|
13
|
+
import type { ModelInfo } from "../protocol.js";
|
|
14
|
+
/** Last known OpenRouter models (may be up to CACHE_TTL_MS stale). */
|
|
15
|
+
export declare function openrouterModels(): ModelInfo[];
|
|
16
|
+
/**
|
|
17
|
+
* Refresh the OpenRouter catalog, honoring the TTL unless `force`. Listing is
|
|
18
|
+
* keyless; `apiKey` is forwarded when present (some deployments gate it). Never
|
|
19
|
+
* throws.
|
|
20
|
+
*/
|
|
21
|
+
export declare function refreshOpenRouterModels(apiKey?: string, force?: boolean): Promise<ModelInfo[]>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter model discovery — enumerate routable models from the live catalog
|
|
3
|
+
* (`GET /api/v1/models`), scoped to the last 12 months.
|
|
4
|
+
*
|
|
5
|
+
* The endpoint is keyless for listing and returns `{ id, name, created,
|
|
6
|
+
* supported_parameters }` per model; we keep models `created` within the
|
|
7
|
+
* trailing year (newest first) and attach reasoning-effort levels to any model
|
|
8
|
+
* whose `supported_parameters` advertises `reasoning` (see effortsForOpenRouter).
|
|
9
|
+
*
|
|
10
|
+
* Never throws: an unreachable endpoint yields `[]`, and models.ts falls back to
|
|
11
|
+
* its curated OpenRouter starter set.
|
|
12
|
+
*/
|
|
13
|
+
import { effortsForOpenRouter, DEFAULT_OPENROUTER_EFFORT } from "../model-efforts.js";
|
|
14
|
+
const OPENROUTER_BASE_URL = process.env.OPENROUTER_BASE_URL ?? "https://openrouter.ai/api";
|
|
15
|
+
const PROBE_TIMEOUT_MS = 5000;
|
|
16
|
+
const CACHE_TTL_MS = 60_000;
|
|
17
|
+
const YEAR_MS = 365 * 24 * 60 * 60 * 1000;
|
|
18
|
+
let cache = [];
|
|
19
|
+
let lastProbeMs = 0;
|
|
20
|
+
/** Last known OpenRouter models (may be up to CACHE_TTL_MS stale). */
|
|
21
|
+
export function openrouterModels() {
|
|
22
|
+
return cache;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Refresh the OpenRouter catalog, honoring the TTL unless `force`. Listing is
|
|
26
|
+
* keyless; `apiKey` is forwarded when present (some deployments gate it). Never
|
|
27
|
+
* throws.
|
|
28
|
+
*/
|
|
29
|
+
export async function refreshOpenRouterModels(apiKey, force = false) {
|
|
30
|
+
const now = Date.now();
|
|
31
|
+
if (!force && now - lastProbeMs < CACHE_TTL_MS)
|
|
32
|
+
return cache;
|
|
33
|
+
lastProbeMs = now;
|
|
34
|
+
cache = await probe(apiKey);
|
|
35
|
+
return cache;
|
|
36
|
+
}
|
|
37
|
+
async function probe(apiKey) {
|
|
38
|
+
try {
|
|
39
|
+
const res = await fetch(`${OPENROUTER_BASE_URL}/v1/models`, {
|
|
40
|
+
signal: AbortSignal.timeout(PROBE_TIMEOUT_MS),
|
|
41
|
+
headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : {},
|
|
42
|
+
});
|
|
43
|
+
if (!res.ok)
|
|
44
|
+
return [];
|
|
45
|
+
const body = (await res.json());
|
|
46
|
+
const cutoff = Date.now() - YEAR_MS;
|
|
47
|
+
const rows = (body.data ?? [])
|
|
48
|
+
// `created` is a Unix timestamp in seconds; keep only the last 12 months.
|
|
49
|
+
.filter((m) => typeof m.created !== "number" || m.created * 1000 >= cutoff)
|
|
50
|
+
.sort((a, b) => (b.created ?? 0) - (a.created ?? 0));
|
|
51
|
+
const models = [];
|
|
52
|
+
const seen = new Set();
|
|
53
|
+
for (const m of rows) {
|
|
54
|
+
const id = (m.id ?? "").trim();
|
|
55
|
+
if (!id || seen.has(id))
|
|
56
|
+
continue;
|
|
57
|
+
seen.add(id);
|
|
58
|
+
const efforts = effortsForOpenRouter(m.supported_parameters);
|
|
59
|
+
models.push({
|
|
60
|
+
id,
|
|
61
|
+
label: (m.name ?? id).trim() || id,
|
|
62
|
+
provider: "openrouter",
|
|
63
|
+
...(typeof m.created === "number"
|
|
64
|
+
? { released: new Date(m.created * 1000).toISOString() }
|
|
65
|
+
: {}),
|
|
66
|
+
...(efforts
|
|
67
|
+
? { efforts, defaultEffort: DEFAULT_OPENROUTER_EFFORT(efforts) }
|
|
68
|
+
: {}),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return models;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=openrouter-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter-probe.js","sourceRoot":"","sources":["../../../src/agent/openrouter-probe.ts"],"names":[],"mappings":"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"}
|
package/dist/src/cli/paths.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export declare function logPaths(): {
|
|
|
23
23
|
};
|
|
24
24
|
/** Read the published version out of package.json (two dirs up from dist/src). */
|
|
25
25
|
export declare function packageVersion(): string;
|
|
26
|
+
/** Read the published npm name out of package.json (for self-update installs). */
|
|
27
|
+
export declare function packageName(): string;
|
|
26
28
|
/** Runtime config baked into a service unit's environment. */
|
|
27
29
|
export interface ServiceEnv {
|
|
28
30
|
port: number;
|
package/dist/src/cli/paths.js
CHANGED
|
@@ -42,19 +42,26 @@ export function logPaths() {
|
|
|
42
42
|
err: join(STATE_DIR, "daemon.err.log"),
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
-
/**
|
|
46
|
-
|
|
45
|
+
/** Parsed name + version out of this package's package.json. */
|
|
46
|
+
function readPackageJson() {
|
|
47
|
+
// This module compiles to dist/src/cli/paths.js — three levels below the
|
|
48
|
+
// package root where package.json lives (cli/ → src/ → dist/ → root).
|
|
47
49
|
try {
|
|
48
|
-
// This module compiles to dist/src/cli/paths.js — three levels below the
|
|
49
|
-
// package root where package.json lives (cli/ → src/ → dist/ → root).
|
|
50
50
|
const pkgUrl = new URL("../../../package.json", import.meta.url);
|
|
51
|
-
|
|
52
|
-
return pkg.version ?? "0.0.0";
|
|
51
|
+
return JSON.parse(readFileSync(pkgUrl, "utf8"));
|
|
53
52
|
}
|
|
54
53
|
catch {
|
|
55
|
-
return
|
|
54
|
+
return {};
|
|
56
55
|
}
|
|
57
56
|
}
|
|
57
|
+
/** Read the published version out of package.json (two dirs up from dist/src). */
|
|
58
|
+
export function packageVersion() {
|
|
59
|
+
return readPackageJson().version ?? "0.0.0";
|
|
60
|
+
}
|
|
61
|
+
/** Read the published npm name out of package.json (for self-update installs). */
|
|
62
|
+
export function packageName() {
|
|
63
|
+
return readPackageJson().name ?? "@gtc6244/immediacy-daemon";
|
|
64
|
+
}
|
|
58
65
|
export const DEFAULT_ENV = {
|
|
59
66
|
port: 8787,
|
|
60
67
|
host: "127.0.0.1",
|