teleton 0.8.1 → 0.8.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/dist/bootstrap-DDFVEMYI.js +128 -0
- package/dist/{server-3FHI2SEB.js → chunk-2ERTYRHA.js} +26 -372
- package/dist/{chunk-5FNWBZ5K.js → chunk-33Z47EXI.js} +264 -274
- package/dist/{chunk-3S4GGLLR.js → chunk-35MX4ZUI.js} +23 -104
- package/dist/chunk-3UFPFWYP.js +12 -0
- package/dist/chunk-5SEMA47R.js +75 -0
- package/dist/{chunk-PHSAHTK4.js → chunk-6OOHHJ4N.js} +3 -108
- package/dist/{chunk-CGOXE4WP.js → chunk-7MWKT67G.js} +467 -914
- package/dist/chunk-AEHTQI3H.js +142 -0
- package/dist/{chunk-S6PHGKOC.js → chunk-AERHOXGC.js} +88 -322
- package/dist/chunk-ALKAAG4O.js +487 -0
- package/dist/{chunk-UP55PXFH.js → chunk-C4NKJT2Z.js} +8 -0
- package/dist/chunk-CUE4UZXR.js +129 -0
- package/dist/chunk-FUNF6H4W.js +251 -0
- package/dist/{chunk-7U7BOHCL.js → chunk-GHMXWAXI.js} +147 -63
- package/dist/{chunk-QBHRXLZS.js → chunk-H7MFXJZK.js} +2 -2
- package/dist/{chunk-QV2GLOTK.js → chunk-LC4TV3KL.js} +1 -1
- package/dist/{chunk-AYWEJCDB.js → chunk-LVTKJQ7O.js} +12 -10
- package/dist/{chunk-RCMD3U65.js → chunk-NQ6FZKCE.js} +13 -0
- package/dist/chunk-NVKBBTI6.js +128 -0
- package/dist/{setup-server-32XGDPE6.js → chunk-OIMAE24Q.js} +55 -216
- package/dist/{chunk-OJCLKU5Z.js → chunk-WFTC3JJW.js} +16 -0
- package/dist/chunk-WTDAICGT.js +175 -0
- package/dist/{chunk-KVXV7EF7.js → chunk-XDZDOKIF.js} +2 -2
- package/dist/cli/index.js +91 -27
- package/dist/{client-MPHPIZB6.js → client-5KD25NOP.js} +5 -4
- package/dist/{get-my-gifts-CC6HAVWB.js → get-my-gifts-Y7EN7RK4.js} +3 -3
- package/dist/index.js +19 -13
- package/dist/local-IHKJFQJS.js +9 -0
- package/dist/{memory-UBHM7ILG.js → memory-QMJRM3XJ.js} +9 -5
- package/dist/memory-hook-VUNWZ3NY.js +19 -0
- package/dist/{migrate-UBBEJ5BL.js → migrate-5VBAP52B.js} +5 -4
- package/dist/server-JF6FX772.js +813 -0
- package/dist/server-N4T7E25M.js +396 -0
- package/dist/setup-server-IX3BFPPH.js +217 -0
- package/dist/{store-M5IMUQCL.js → store-BY7S6IFN.js} +6 -5
- package/dist/{task-dependency-resolver-RR2O5S7B.js → task-dependency-resolver-L6UUMTHK.js} +2 -2
- package/dist/{task-executor-6W5HRX5C.js → task-executor-XBNJLUCS.js} +2 -2
- package/dist/{tool-adapter-IH5VGBOO.js → tool-adapter-IVX2XQJE.js} +1 -1
- package/dist/{tool-index-PMAOXWUA.js → tool-index-FTERJSZK.js} +4 -3
- package/dist/{transcript-NGDPSNIH.js → transcript-IM7G25OS.js} +2 -2
- package/package.json +4 -2
- package/dist/chunk-XBE4JB7C.js +0 -8
|
@@ -7,16 +7,16 @@ import {
|
|
|
7
7
|
EMBEDDING_CACHE_MAX_ENTRIES,
|
|
8
8
|
EMBEDDING_CACHE_TTL_DAYS,
|
|
9
9
|
VOYAGE_BATCH_SIZE
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-C4NKJT2Z.js";
|
|
11
11
|
import {
|
|
12
12
|
fetchWithTimeout
|
|
13
13
|
} from "./chunk-XQUHC3JZ.js";
|
|
14
14
|
import {
|
|
15
|
-
|
|
16
|
-
} from "./chunk-
|
|
15
|
+
LocalEmbeddingProvider
|
|
16
|
+
} from "./chunk-CUE4UZXR.js";
|
|
17
17
|
import {
|
|
18
18
|
createLogger
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-NQ6FZKCE.js";
|
|
20
20
|
|
|
21
21
|
// src/memory/embeddings/provider.ts
|
|
22
22
|
var NoopEmbeddingProvider = class {
|
|
@@ -52,7 +52,7 @@ var AnthropicEmbeddingProvider = class {
|
|
|
52
52
|
this.dimensions = dims[this.model] ?? 512;
|
|
53
53
|
}
|
|
54
54
|
async embedQuery(text) {
|
|
55
|
-
const result = await this.embed([text]);
|
|
55
|
+
const result = await this.embed([text], "query");
|
|
56
56
|
return result[0] ?? [];
|
|
57
57
|
}
|
|
58
58
|
async embedBatch(texts) {
|
|
@@ -66,7 +66,7 @@ var AnthropicEmbeddingProvider = class {
|
|
|
66
66
|
}
|
|
67
67
|
return results;
|
|
68
68
|
}
|
|
69
|
-
async embed(texts) {
|
|
69
|
+
async embed(texts, inputType = "document") {
|
|
70
70
|
const response = await fetchWithTimeout(`${this.baseUrl}/embeddings`, {
|
|
71
71
|
method: "POST",
|
|
72
72
|
headers: {
|
|
@@ -76,7 +76,7 @@ var AnthropicEmbeddingProvider = class {
|
|
|
76
76
|
body: JSON.stringify({
|
|
77
77
|
input: texts,
|
|
78
78
|
model: this.model,
|
|
79
|
-
input_type:
|
|
79
|
+
input_type: inputType
|
|
80
80
|
})
|
|
81
81
|
});
|
|
82
82
|
if (!response.ok) {
|
|
@@ -88,92 +88,6 @@ var AnthropicEmbeddingProvider = class {
|
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
// src/memory/embeddings/local.ts
|
|
92
|
-
import { pipeline, env } from "@huggingface/transformers";
|
|
93
|
-
import { join } from "path";
|
|
94
|
-
import { mkdirSync } from "fs";
|
|
95
|
-
var log = createLogger("Memory");
|
|
96
|
-
var modelCacheDir = join(TELETON_ROOT, "models");
|
|
97
|
-
try {
|
|
98
|
-
mkdirSync(modelCacheDir, { recursive: true });
|
|
99
|
-
} catch {
|
|
100
|
-
}
|
|
101
|
-
env.cacheDir = modelCacheDir;
|
|
102
|
-
var extractorPromise = null;
|
|
103
|
-
function getExtractor(model) {
|
|
104
|
-
if (!extractorPromise) {
|
|
105
|
-
log.info(`Loading local embedding model: ${model} (cache: ${modelCacheDir})`);
|
|
106
|
-
extractorPromise = pipeline("feature-extraction", model, {
|
|
107
|
-
dtype: "fp32",
|
|
108
|
-
// Explicit cache_dir to avoid any env race condition
|
|
109
|
-
cache_dir: modelCacheDir
|
|
110
|
-
}).then((ext) => {
|
|
111
|
-
log.info(`Local embedding model ready`);
|
|
112
|
-
return ext;
|
|
113
|
-
}).catch((err) => {
|
|
114
|
-
log.error(`Failed to load embedding model: ${err.message}`);
|
|
115
|
-
extractorPromise = null;
|
|
116
|
-
throw err;
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
return extractorPromise;
|
|
120
|
-
}
|
|
121
|
-
var LocalEmbeddingProvider = class {
|
|
122
|
-
id = "local";
|
|
123
|
-
model;
|
|
124
|
-
dimensions;
|
|
125
|
-
_disabled = false;
|
|
126
|
-
constructor(config) {
|
|
127
|
-
this.model = config.model || "Xenova/all-MiniLM-L6-v2";
|
|
128
|
-
this.dimensions = 384;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Pre-download and load the model at startup.
|
|
132
|
-
* If loading fails, retries once then marks provider as disabled (FTS5-only).
|
|
133
|
-
* Call this once during app init — avoids retry spam on every message.
|
|
134
|
-
* @returns true if model loaded successfully, false if fallback to noop
|
|
135
|
-
*/
|
|
136
|
-
async warmup() {
|
|
137
|
-
for (let attempt = 1; attempt <= 2; attempt++) {
|
|
138
|
-
try {
|
|
139
|
-
await getExtractor(this.model);
|
|
140
|
-
return true;
|
|
141
|
-
} catch {
|
|
142
|
-
if (attempt === 1) {
|
|
143
|
-
log.warn(`Embedding model load failed (attempt 1), retrying...`);
|
|
144
|
-
await new Promise((r) => setTimeout(r, 1e3));
|
|
145
|
-
} else {
|
|
146
|
-
log.warn(
|
|
147
|
-
`Local embedding model unavailable \u2014 falling back to FTS5-only search (no vector embeddings)`
|
|
148
|
-
);
|
|
149
|
-
this._disabled = true;
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
async embedQuery(text) {
|
|
157
|
-
if (this._disabled) return [];
|
|
158
|
-
const extractor = await getExtractor(this.model);
|
|
159
|
-
const output = await extractor(text, { pooling: "mean", normalize: true });
|
|
160
|
-
return Array.from(output.data);
|
|
161
|
-
}
|
|
162
|
-
async embedBatch(texts) {
|
|
163
|
-
if (this._disabled) return [];
|
|
164
|
-
if (texts.length === 0) return [];
|
|
165
|
-
const extractor = await getExtractor(this.model);
|
|
166
|
-
const output = await extractor(texts, { pooling: "mean", normalize: true });
|
|
167
|
-
const data = output.data;
|
|
168
|
-
const dims = this.dimensions;
|
|
169
|
-
const results = [];
|
|
170
|
-
for (let i = 0; i < texts.length; i++) {
|
|
171
|
-
results.push(Array.from(data.slice(i * dims, (i + 1) * dims)));
|
|
172
|
-
}
|
|
173
|
-
return results;
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
|
|
177
91
|
// src/memory/embeddings/utils.ts
|
|
178
92
|
import { createHash } from "crypto";
|
|
179
93
|
function hashText(text) {
|
|
@@ -202,6 +116,16 @@ var CachedEmbeddingProvider = class _CachedEmbeddingProvider {
|
|
|
202
116
|
this.id = inner.id;
|
|
203
117
|
this.model = inner.model;
|
|
204
118
|
this.dimensions = inner.dimensions;
|
|
119
|
+
this.stmtCacheGet = db.prepare(
|
|
120
|
+
`SELECT embedding FROM embedding_cache WHERE hash = ? AND model = ? AND provider = ?`
|
|
121
|
+
);
|
|
122
|
+
this.stmtCachePut = db.prepare(
|
|
123
|
+
`INSERT OR REPLACE INTO embedding_cache (hash, embedding, model, provider, dims, created_at, accessed_at)
|
|
124
|
+
VALUES (?, ?, ?, ?, ?, unixepoch(), unixepoch())`
|
|
125
|
+
);
|
|
126
|
+
this.stmtCacheTouch = db.prepare(
|
|
127
|
+
`UPDATE embedding_cache SET accessed_at = unixepoch() WHERE hash = ? AND model = ? AND provider = ?`
|
|
128
|
+
);
|
|
205
129
|
}
|
|
206
130
|
id;
|
|
207
131
|
model;
|
|
@@ -210,21 +134,17 @@ var CachedEmbeddingProvider = class _CachedEmbeddingProvider {
|
|
|
210
134
|
hits = 0;
|
|
211
135
|
misses = 0;
|
|
212
136
|
ops = 0;
|
|
137
|
+
stmtCacheGet;
|
|
138
|
+
stmtCachePut;
|
|
139
|
+
stmtCacheTouch;
|
|
213
140
|
cacheGet(hash) {
|
|
214
|
-
return this.
|
|
215
|
-
`SELECT embedding FROM embedding_cache WHERE hash = ? AND model = ? AND provider = ?`
|
|
216
|
-
).get(hash, this.model, this.id);
|
|
141
|
+
return this.stmtCacheGet.get(hash, this.model, this.id);
|
|
217
142
|
}
|
|
218
143
|
cachePut(hash, blob) {
|
|
219
|
-
this.
|
|
220
|
-
`INSERT OR REPLACE INTO embedding_cache (hash, embedding, model, provider, dims, created_at, accessed_at)
|
|
221
|
-
VALUES (?, ?, ?, ?, ?, unixepoch(), unixepoch())`
|
|
222
|
-
).run(hash, blob, this.model, this.id, this.dimensions);
|
|
144
|
+
this.stmtCachePut.run(hash, blob, this.model, this.id, this.dimensions);
|
|
223
145
|
}
|
|
224
146
|
cacheTouch(hash) {
|
|
225
|
-
this.
|
|
226
|
-
`UPDATE embedding_cache SET accessed_at = unixepoch() WHERE hash = ? AND model = ? AND provider = ?`
|
|
227
|
-
).run(hash, this.model, this.id);
|
|
147
|
+
this.stmtCacheTouch.run(hash, this.model, this.id);
|
|
228
148
|
}
|
|
229
149
|
async warmup() {
|
|
230
150
|
return this.inner.warmup?.() ?? true;
|
|
@@ -340,7 +260,6 @@ function createEmbeddingProvider(config) {
|
|
|
340
260
|
export {
|
|
341
261
|
NoopEmbeddingProvider,
|
|
342
262
|
AnthropicEmbeddingProvider,
|
|
343
|
-
LocalEmbeddingProvider,
|
|
344
263
|
hashText,
|
|
345
264
|
serializeEmbedding,
|
|
346
265
|
deserializeEmbedding,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// src/utils/errors.ts
|
|
2
|
+
function getErrorMessage(error) {
|
|
3
|
+
return error instanceof Error ? error.message : String(error);
|
|
4
|
+
}
|
|
5
|
+
function isHttpError(err) {
|
|
6
|
+
return typeof err === "object" && err !== null && ("status" in err || "response" in err);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
getErrorMessage,
|
|
11
|
+
isHttpError
|
|
12
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLogger
|
|
3
|
+
} from "./chunk-NQ6FZKCE.js";
|
|
4
|
+
|
|
5
|
+
// src/api/tls.ts
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
7
|
+
import { join } from "path";
|
|
8
|
+
import { createHash, X509Certificate } from "crypto";
|
|
9
|
+
import { generate } from "selfsigned";
|
|
10
|
+
var log = createLogger("TLS");
|
|
11
|
+
function computeFingerprint(certPem) {
|
|
12
|
+
const x509 = new X509Certificate(certPem);
|
|
13
|
+
const der = x509.raw;
|
|
14
|
+
return createHash("sha256").update(der).digest("hex");
|
|
15
|
+
}
|
|
16
|
+
function isCertValid(certPem) {
|
|
17
|
+
try {
|
|
18
|
+
const x509 = new X509Certificate(certPem);
|
|
19
|
+
const now = /* @__PURE__ */ new Date();
|
|
20
|
+
return now >= new Date(x509.validFrom) && now <= new Date(x509.validTo);
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async function ensureTlsCert(dataDir) {
|
|
26
|
+
const certPath = join(dataDir, "api-cert.pem");
|
|
27
|
+
const keyPath = join(dataDir, "api-key.pem");
|
|
28
|
+
if (existsSync(certPath) && existsSync(keyPath)) {
|
|
29
|
+
const cert = readFileSync(certPath, "utf-8");
|
|
30
|
+
const key = readFileSync(keyPath, "utf-8");
|
|
31
|
+
if (isCertValid(cert)) {
|
|
32
|
+
const fingerprint2 = computeFingerprint(cert);
|
|
33
|
+
log.info("Loaded existing TLS certificate");
|
|
34
|
+
return { cert, key, fingerprint: fingerprint2 };
|
|
35
|
+
}
|
|
36
|
+
log.warn("Existing TLS certificate is expired, regenerating");
|
|
37
|
+
}
|
|
38
|
+
log.info("Generating self-signed TLS certificate");
|
|
39
|
+
const notBeforeDate = /* @__PURE__ */ new Date();
|
|
40
|
+
const notAfterDate = /* @__PURE__ */ new Date();
|
|
41
|
+
notAfterDate.setFullYear(notAfterDate.getFullYear() + 2);
|
|
42
|
+
const pems = await generate([{ name: "commonName", value: "teleton-api" }], {
|
|
43
|
+
keySize: 2048,
|
|
44
|
+
algorithm: "sha256",
|
|
45
|
+
notBeforeDate,
|
|
46
|
+
notAfterDate,
|
|
47
|
+
extensions: [
|
|
48
|
+
{ name: "basicConstraints", cA: false, critical: true },
|
|
49
|
+
{
|
|
50
|
+
name: "keyUsage",
|
|
51
|
+
digitalSignature: true,
|
|
52
|
+
keyEncipherment: true,
|
|
53
|
+
critical: true
|
|
54
|
+
},
|
|
55
|
+
{ name: "extKeyUsage", serverAuth: true },
|
|
56
|
+
{
|
|
57
|
+
name: "subjectAltName",
|
|
58
|
+
altNames: [
|
|
59
|
+
{ type: 2, value: "localhost" },
|
|
60
|
+
{ type: 7, ip: "127.0.0.1" },
|
|
61
|
+
{ type: 7, ip: "::1" }
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
});
|
|
66
|
+
writeFileSync(certPath, pems.cert, { mode: 384 });
|
|
67
|
+
writeFileSync(keyPath, pems.private, { mode: 384 });
|
|
68
|
+
const fingerprint = computeFingerprint(pems.cert);
|
|
69
|
+
log.info(`TLS certificate generated (fingerprint: ${fingerprint.slice(0, 16)}...)`);
|
|
70
|
+
return { cert: pems.cert, key: pems.private, fingerprint };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export {
|
|
74
|
+
ensureTlsCert
|
|
75
|
+
};
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createLogger
|
|
3
|
-
} from "./chunk-RCMD3U65.js";
|
|
4
|
-
|
|
5
1
|
// src/config/providers.ts
|
|
6
2
|
var PROVIDER_REGISTRY = {
|
|
7
3
|
anthropic: {
|
|
@@ -30,12 +26,12 @@ var PROVIDER_REGISTRY = {
|
|
|
30
26
|
},
|
|
31
27
|
openai: {
|
|
32
28
|
id: "openai",
|
|
33
|
-
displayName: "OpenAI (GPT-
|
|
29
|
+
displayName: "OpenAI (GPT-5.4)",
|
|
34
30
|
envVar: "OPENAI_API_KEY",
|
|
35
31
|
keyPrefix: "sk-",
|
|
36
32
|
keyHint: "sk-proj-...",
|
|
37
33
|
consoleUrl: "https://platform.openai.com/api-keys",
|
|
38
|
-
defaultModel: "gpt-
|
|
34
|
+
defaultModel: "gpt-5.4",
|
|
39
35
|
utilityModel: "gpt-4o-mini",
|
|
40
36
|
toolLimit: 128,
|
|
41
37
|
piAiProvider: "openai"
|
|
@@ -206,109 +202,8 @@ function validateApiKeyFormat(provider, key) {
|
|
|
206
202
|
return void 0;
|
|
207
203
|
}
|
|
208
204
|
|
|
209
|
-
// src/providers/claude-code-credentials.ts
|
|
210
|
-
import { readFileSync, existsSync } from "fs";
|
|
211
|
-
import { execSync } from "child_process";
|
|
212
|
-
import { homedir } from "os";
|
|
213
|
-
import { join } from "path";
|
|
214
|
-
var log = createLogger("ClaudeCodeCreds");
|
|
215
|
-
var cachedToken = null;
|
|
216
|
-
var cachedExpiresAt = 0;
|
|
217
|
-
function getClaudeConfigDir() {
|
|
218
|
-
return process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
|
|
219
|
-
}
|
|
220
|
-
function getCredentialsFilePath() {
|
|
221
|
-
return join(getClaudeConfigDir(), ".credentials.json");
|
|
222
|
-
}
|
|
223
|
-
function readCredentialsFile() {
|
|
224
|
-
const filePath = getCredentialsFilePath();
|
|
225
|
-
if (!existsSync(filePath)) return null;
|
|
226
|
-
try {
|
|
227
|
-
const raw = readFileSync(filePath, "utf-8");
|
|
228
|
-
return JSON.parse(raw);
|
|
229
|
-
} catch (e) {
|
|
230
|
-
log.warn({ err: e, path: filePath }, "Failed to parse Claude Code credentials file");
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
function readKeychainCredentials() {
|
|
235
|
-
const serviceNames = ["Claude Code-credentials", "Claude Code"];
|
|
236
|
-
for (const service of serviceNames) {
|
|
237
|
-
try {
|
|
238
|
-
const raw = execSync(`security find-generic-password -s "${service}" -w`, {
|
|
239
|
-
encoding: "utf-8",
|
|
240
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
241
|
-
}).trim();
|
|
242
|
-
return JSON.parse(raw);
|
|
243
|
-
} catch {
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
return null;
|
|
247
|
-
}
|
|
248
|
-
function readCredentials() {
|
|
249
|
-
if (process.platform === "darwin") {
|
|
250
|
-
const keychainCreds = readKeychainCredentials();
|
|
251
|
-
if (keychainCreds) return keychainCreds;
|
|
252
|
-
log.debug("Keychain read failed, falling back to credentials file");
|
|
253
|
-
}
|
|
254
|
-
return readCredentialsFile();
|
|
255
|
-
}
|
|
256
|
-
function extractToken(creds) {
|
|
257
|
-
const oauth = creds.claudeAiOauth;
|
|
258
|
-
if (!oauth?.accessToken) {
|
|
259
|
-
log.warn("Claude Code credentials found but missing accessToken");
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
return {
|
|
263
|
-
token: oauth.accessToken,
|
|
264
|
-
expiresAt: oauth.expiresAt ?? 0
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
function getClaudeCodeApiKey(fallbackKey) {
|
|
268
|
-
if (cachedToken && Date.now() < cachedExpiresAt) {
|
|
269
|
-
return cachedToken;
|
|
270
|
-
}
|
|
271
|
-
const creds = readCredentials();
|
|
272
|
-
if (creds) {
|
|
273
|
-
const extracted = extractToken(creds);
|
|
274
|
-
if (extracted) {
|
|
275
|
-
cachedToken = extracted.token;
|
|
276
|
-
cachedExpiresAt = extracted.expiresAt;
|
|
277
|
-
log.debug("Claude Code credentials loaded successfully");
|
|
278
|
-
return cachedToken;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
if (fallbackKey && fallbackKey.length > 0) {
|
|
282
|
-
log.warn("Claude Code credentials not found, using fallback api_key from config");
|
|
283
|
-
return fallbackKey;
|
|
284
|
-
}
|
|
285
|
-
throw new Error("No Claude Code credentials found. Run 'claude login' or set api_key in config.");
|
|
286
|
-
}
|
|
287
|
-
function refreshClaudeCodeApiKey() {
|
|
288
|
-
cachedToken = null;
|
|
289
|
-
cachedExpiresAt = 0;
|
|
290
|
-
const creds = readCredentials();
|
|
291
|
-
if (creds) {
|
|
292
|
-
const extracted = extractToken(creds);
|
|
293
|
-
if (extracted) {
|
|
294
|
-
cachedToken = extracted.token;
|
|
295
|
-
cachedExpiresAt = extracted.expiresAt;
|
|
296
|
-
log.info("Claude Code credentials refreshed from disk");
|
|
297
|
-
return cachedToken;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
log.warn("Failed to refresh Claude Code credentials from disk");
|
|
301
|
-
return null;
|
|
302
|
-
}
|
|
303
|
-
function isClaudeCodeTokenValid() {
|
|
304
|
-
return cachedToken !== null && Date.now() < cachedExpiresAt;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
205
|
export {
|
|
308
206
|
getProviderMetadata,
|
|
309
207
|
getSupportedProviders,
|
|
310
|
-
validateApiKeyFormat
|
|
311
|
-
getClaudeCodeApiKey,
|
|
312
|
-
refreshClaudeCodeApiKey,
|
|
313
|
-
isClaudeCodeTokenValid
|
|
208
|
+
validateApiKeyFormat
|
|
314
209
|
};
|