@vtstech/pi-openrouter-sync 1.2.1 → 1.2.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.
Files changed (2) hide show
  1. package/openrouter-sync.js +107 -13
  2. package/package.json +10 -6
@@ -1,12 +1,106 @@
1
- // .build-npm/openrouter-sync/openrouter-sync.temp.ts
2
- import {
3
- MODELS_JSON_PATH as MODELS_FILE,
4
- readModelsJson,
5
- readModifyWriteModelsJson,
6
- BUILTIN_PROVIDERS,
7
- EXTENSION_VERSION
8
- } from "@vtstech/pi-shared/ollama";
9
- import { section, ok, warn } from "@vtstech/pi-shared/format";
1
+ // shared/ollama.ts
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
4
+ import os from "node:os";
5
+
6
+ // shared/debug.ts
7
+ var DEBUG_ENABLED = process?.env?.PI_EXTENSIONS_DEBUG === "1";
8
+ function debugLog(module, message, ...args) {
9
+ if (!DEBUG_ENABLED) return;
10
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
11
+ console.debug(`[pi-ext:${module}] ${timestamp} ${message}`, ...args);
12
+ }
13
+
14
+ // shared/ollama.ts
15
+ var EXTENSION_VERSION = "1.2.3";
16
+ var MODELS_JSON_PATH = path.join(os.homedir(), ".pi", "agent", "models.json");
17
+ var _modelsJsonCache = null;
18
+ var _ollamaBaseUrlCache = null;
19
+ var CACHE_TTL_MS = 2e3;
20
+ function readModelsJson() {
21
+ const now = Date.now();
22
+ if (_modelsJsonCache && now - _modelsJsonCache.ts < CACHE_TTL_MS) return _modelsJsonCache.data;
23
+ try {
24
+ if (fs.existsSync(MODELS_JSON_PATH)) {
25
+ const raw = fs.readFileSync(MODELS_JSON_PATH, "utf-8");
26
+ const data = JSON.parse(raw);
27
+ _modelsJsonCache = { data, ts: now };
28
+ return data;
29
+ }
30
+ } catch (err) {
31
+ debugLog("ollama", "failed to read/parse models.json", err);
32
+ }
33
+ const empty = { providers: {} };
34
+ _modelsJsonCache = { data: empty, ts: now };
35
+ return empty;
36
+ }
37
+ function writeModelsJson(data) {
38
+ const dir = path.dirname(MODELS_JSON_PATH);
39
+ if (!fs.existsSync(dir)) {
40
+ fs.mkdirSync(dir, { recursive: true });
41
+ }
42
+ const tmpPath = MODELS_JSON_PATH + ".tmp";
43
+ fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2) + "\n", "utf-8");
44
+ fs.renameSync(tmpPath, MODELS_JSON_PATH);
45
+ _modelsJsonCache = null;
46
+ _ollamaBaseUrlCache = null;
47
+ }
48
+ var _modelsJsonLock = null;
49
+ async function acquireModelsJsonLock() {
50
+ while (_modelsJsonLock) {
51
+ await _modelsJsonLock;
52
+ }
53
+ let releaseLock;
54
+ _modelsJsonLock = new Promise((resolve) => {
55
+ releaseLock = resolve;
56
+ });
57
+ return {
58
+ release: () => {
59
+ releaseLock();
60
+ _modelsJsonLock = null;
61
+ }
62
+ };
63
+ }
64
+ async function readModifyWriteModelsJson(modifier) {
65
+ const { release } = await acquireModelsJsonLock();
66
+ try {
67
+ const data = readModelsJson();
68
+ const modified = modifier(data);
69
+ if (modified === null) return false;
70
+ writeModelsJson(modified);
71
+ return true;
72
+ } finally {
73
+ release();
74
+ }
75
+ }
76
+ var BUILTIN_PROVIDERS = {
77
+ openrouter: { api: "openai-completions", baseUrl: "https://openrouter.ai/api/v1", envKey: "OPENROUTER_API_KEY" },
78
+ anthropic: { api: "anthropic-messages", baseUrl: "https://api.anthropic.com/v1", envKey: "ANTHROPIC_API_KEY" },
79
+ google: { api: "gemini", baseUrl: "https://generativelanguage.googleapis.com", envKey: "GOOGLE_API_KEY" },
80
+ openai: { api: "openai-completions", baseUrl: "https://api.openai.com/v1", envKey: "OPENAI_API_KEY" },
81
+ groq: { api: "openai-completions", baseUrl: "https://api.groq.com/v1", envKey: "GROQ_API_KEY" },
82
+ deepseek: { api: "openai-completions", baseUrl: "https://api.deepseek.com/v1", envKey: "DEEPSEEK_API_KEY" },
83
+ mistral: { api: "openai-completions", baseUrl: "https://api.mistral.ai/v1", envKey: "MISTRAL_API_KEY" },
84
+ xai: { api: "openai-completions", baseUrl: "https://api.x.ai/v1", envKey: "XAI_API_KEY" },
85
+ together: { api: "openai-completions", baseUrl: "https://api.together.xyz/v1", envKey: "TOGETHER_API_KEY" },
86
+ fireworks: { api: "openai-completions", baseUrl: "https://api.fireworks.ai/inference/v1", envKey: "FIREWORKS_API_KEY" },
87
+ cohere: { api: "cohere-chat", baseUrl: "https://api.cohere.com/v1", envKey: "COHERE_API_KEY" },
88
+ zai: { api: "openai-completions", baseUrl: "https://open.bigmodel.cn/api/paas/v4", envKey: "ZAI_API_KEY" }
89
+ };
90
+
91
+ // shared/format.ts
92
+ function section(title) {
93
+ return `
94
+ \u2500\u2500 ${title} ${"\u2500".repeat(Math.max(1, 60 - title.length - 4))}`;
95
+ }
96
+ function ok(msg) {
97
+ return ` \u2705 ${msg}`;
98
+ }
99
+ function warn(msg) {
100
+ return ` \u26A0\uFE0F ${msg}`;
101
+ }
102
+
103
+ // extensions/openrouter-sync.ts
10
104
  var BRANDING = [
11
105
  ` \u26A1 Pi OpenRouter Sync v${EXTENSION_VERSION}`,
12
106
  ` Written by VTSTech`,
@@ -66,7 +160,7 @@ async function performSync(modelIds) {
66
160
  });
67
161
  return result;
68
162
  }
69
- function openrouter_sync_temp_default(pi) {
163
+ function openrouter_sync_default(pi) {
70
164
  pi.registerCommand("openrouter-sync", {
71
165
  description: "Add OpenRouter model(s) to models.json. Use: /or-sync <url-or-id> [url-or-id ...]",
72
166
  async handler(args, ctx) {
@@ -94,7 +188,7 @@ function openrouter_sync_temp_default(pi) {
94
188
  for (const id of skipped) lines.push(warn(id));
95
189
  }
96
190
  lines.push("");
97
- lines.push(` Written to ${MODELS_FILE}`);
191
+ lines.push(` Written to ${MODELS_JSON_PATH}`);
98
192
  lines.push(` Run /reload to pick up changes`);
99
193
  lines.push(BRANDING);
100
194
  const report = lines.join("\n");
@@ -152,7 +246,7 @@ function openrouter_sync_temp_default(pi) {
152
246
  ...skipped.length > 0 ? ["\nSkipped (already present):"] : [],
153
247
  ...skipped.map((id) => ` = ${id}`),
154
248
  "",
155
- `Written to ${MODELS_FILE}. Run /reload to pick up changes.`,
249
+ `Written to ${MODELS_JSON_PATH}. Run /reload to pick up changes.`,
156
250
  "",
157
251
  "Current openrouter models:",
158
252
  modelList
@@ -171,5 +265,5 @@ function openrouter_sync_temp_default(pi) {
171
265
  });
172
266
  }
173
267
  export {
174
- openrouter_sync_temp_default as default
268
+ openrouter_sync_default as default
175
269
  };
package/package.json CHANGED
@@ -1,9 +1,14 @@
1
1
  {
2
2
  "name": "@vtstech/pi-openrouter-sync",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "OpenRouter model sync extension for Pi Coding Agent — add models from OpenRouter URLs or IDs",
5
5
  "main": "openrouter-sync.js",
6
- "keywords": ["pi-package", "pi", "pi-coding-agent", "pi-extensions"],
6
+ "keywords": [
7
+ "pi-package",
8
+ "pi",
9
+ "pi-coding-agent",
10
+ "pi-extensions"
11
+ ],
7
12
  "license": "MIT",
8
13
  "access": "public",
9
14
  "type": "module",
@@ -13,13 +18,12 @@
13
18
  "type": "git",
14
19
  "url": "https://github.com/VTSTech/pi-coding-agent"
15
20
  },
16
- "dependencies": {
17
- "@vtstech/pi-shared": "1.2.1"
18
- },
19
21
  "peerDependencies": {
20
22
  "@mariozechner/pi-coding-agent": ">=0.66"
21
23
  },
22
24
  "pi": {
23
- "extensions": ["./openrouter-sync.js"]
25
+ "extensions": [
26
+ "./openrouter-sync.js"
27
+ ]
24
28
  }
25
29
  }