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
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getClaudeCodeApiKey,
|
|
3
|
-
getProviderMetadata,
|
|
4
3
|
refreshClaudeCodeApiKey
|
|
5
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WTDAICGT.js";
|
|
6
5
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from "./chunk-QV2GLOTK.js";
|
|
6
|
+
getProviderMetadata
|
|
7
|
+
} from "./chunk-6OOHHJ4N.js";
|
|
10
8
|
import {
|
|
11
9
|
fetchWithTimeout
|
|
12
10
|
} from "./chunk-XQUHC3JZ.js";
|
|
11
|
+
import {
|
|
12
|
+
appendToTranscript,
|
|
13
|
+
readTranscript
|
|
14
|
+
} from "./chunk-LC4TV3KL.js";
|
|
13
15
|
import {
|
|
14
16
|
createLogger
|
|
15
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-NQ6FZKCE.js";
|
|
16
18
|
|
|
17
19
|
// src/agent/client.ts
|
|
18
20
|
import {
|
|
@@ -262,7 +264,7 @@ async function chatWithContext(config, options) {
|
|
|
262
264
|
systemPrompt = "/no_think\n" + systemPrompt;
|
|
263
265
|
if (tools && tools.length > 0) {
|
|
264
266
|
cocoonAllowedTools = new Set(tools.map((t) => t.name));
|
|
265
|
-
const { injectToolsIntoSystemPrompt } = await import("./tool-adapter-
|
|
267
|
+
const { injectToolsIntoSystemPrompt } = await import("./tool-adapter-IVX2XQJE.js");
|
|
266
268
|
systemPrompt = injectToolsIntoSystemPrompt(systemPrompt, tools);
|
|
267
269
|
tools = void 0;
|
|
268
270
|
}
|
|
@@ -281,13 +283,13 @@ async function chatWithContext(config, options) {
|
|
|
281
283
|
cacheRetention: "long"
|
|
282
284
|
};
|
|
283
285
|
if (isCocoon) {
|
|
284
|
-
const { stripCocoonPayload } = await import("./tool-adapter-
|
|
286
|
+
const { stripCocoonPayload } = await import("./tool-adapter-IVX2XQJE.js");
|
|
285
287
|
completeOptions.onPayload = stripCocoonPayload;
|
|
286
288
|
}
|
|
287
289
|
let response = await complete(model, context, completeOptions);
|
|
288
290
|
if (provider === "claude-code" && response.stopReason === "error" && response.errorMessage && (response.errorMessage.includes("401") || response.errorMessage.toLowerCase().includes("unauthorized"))) {
|
|
289
291
|
log.warn("Claude Code token rejected (401), refreshing credentials and retrying...");
|
|
290
|
-
const refreshedKey = refreshClaudeCodeApiKey();
|
|
292
|
+
const refreshedKey = await refreshClaudeCodeApiKey();
|
|
291
293
|
if (refreshedKey) {
|
|
292
294
|
completeOptions.apiKey = refreshedKey;
|
|
293
295
|
response = await complete(model, context, completeOptions);
|
|
@@ -296,7 +298,7 @@ async function chatWithContext(config, options) {
|
|
|
296
298
|
if (isCocoon) {
|
|
297
299
|
const textBlock = response.content.find((b) => b.type === "text");
|
|
298
300
|
if (textBlock?.type === "text" && textBlock.text.includes("<tool_call>")) {
|
|
299
|
-
const { parseToolCallsFromText, extractPlainText } = await import("./tool-adapter-
|
|
301
|
+
const { parseToolCallsFromText, extractPlainText } = await import("./tool-adapter-IVX2XQJE.js");
|
|
300
302
|
const syntheticCalls = parseToolCallsFromText(textBlock.text, cocoonAllowedTools);
|
|
301
303
|
if (syntheticCalls.length > 0) {
|
|
302
304
|
const plainText = extractPlainText(textBlock.text);
|
|
@@ -88,12 +88,20 @@ var rootLogger = pino(
|
|
|
88
88
|
paths: [
|
|
89
89
|
"apiKey",
|
|
90
90
|
"api_key",
|
|
91
|
+
"api_hash",
|
|
92
|
+
"accessToken",
|
|
93
|
+
"access_token",
|
|
94
|
+
"refresh_token",
|
|
91
95
|
"password",
|
|
92
96
|
"secret",
|
|
93
97
|
"token",
|
|
94
98
|
"mnemonic",
|
|
95
99
|
"*.apiKey",
|
|
96
100
|
"*.api_key",
|
|
101
|
+
"*.api_hash",
|
|
102
|
+
"*.accessToken",
|
|
103
|
+
"*.access_token",
|
|
104
|
+
"*.refresh_token",
|
|
97
105
|
"*.password",
|
|
98
106
|
"*.secret",
|
|
99
107
|
"*.token",
|
|
@@ -120,6 +128,11 @@ function setLogLevel(level) {
|
|
|
120
128
|
const streams = multiStream.streams;
|
|
121
129
|
if (Array.isArray(streams) && streams[0]) {
|
|
122
130
|
streams[0].level = pino.levels.values[level] ?? 30;
|
|
131
|
+
} else {
|
|
132
|
+
process.stderr.write(
|
|
133
|
+
`[Logger] setLogLevel: pino multistream internal API changed, stdout level not updated
|
|
134
|
+
`
|
|
135
|
+
);
|
|
123
136
|
}
|
|
124
137
|
_verbose = level === "debug" || level === "trace";
|
|
125
138
|
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLogger
|
|
3
|
+
} from "./chunk-NQ6FZKCE.js";
|
|
4
|
+
|
|
5
|
+
// src/agent/lifecycle.ts
|
|
6
|
+
import { EventEmitter } from "events";
|
|
7
|
+
var log = createLogger("Lifecycle");
|
|
8
|
+
var AgentLifecycle = class extends EventEmitter {
|
|
9
|
+
state = "stopped";
|
|
10
|
+
error;
|
|
11
|
+
startPromise = null;
|
|
12
|
+
stopPromise = null;
|
|
13
|
+
runningSince = null;
|
|
14
|
+
registeredStartFn = null;
|
|
15
|
+
registeredStopFn = null;
|
|
16
|
+
getState() {
|
|
17
|
+
return this.state;
|
|
18
|
+
}
|
|
19
|
+
getError() {
|
|
20
|
+
return this.error;
|
|
21
|
+
}
|
|
22
|
+
getUptime() {
|
|
23
|
+
if (this.state !== "running" || this.runningSince === null) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return Math.floor((Date.now() - this.runningSince) / 1e3);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Register the start/stop callbacks so start()/stop() can be called without args.
|
|
30
|
+
*/
|
|
31
|
+
registerCallbacks(startFn, stopFn) {
|
|
32
|
+
this.registeredStartFn = startFn;
|
|
33
|
+
this.registeredStopFn = stopFn;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Start the agent. Uses the provided callback or falls back to registered one.
|
|
37
|
+
* - No-op if already running
|
|
38
|
+
* - Returns existing promise if already starting
|
|
39
|
+
* - Throws if currently stopping
|
|
40
|
+
*/
|
|
41
|
+
async start(startFn) {
|
|
42
|
+
const fn = startFn ?? this.registeredStartFn;
|
|
43
|
+
if (!fn) {
|
|
44
|
+
throw new Error("No start function provided or registered");
|
|
45
|
+
}
|
|
46
|
+
if (this.state === "running") {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (this.state === "starting") {
|
|
50
|
+
return this.startPromise ?? Promise.resolve();
|
|
51
|
+
}
|
|
52
|
+
if (this.state === "stopping") {
|
|
53
|
+
throw new Error("Cannot start while agent is stopping");
|
|
54
|
+
}
|
|
55
|
+
this.transition("starting");
|
|
56
|
+
this.startPromise = (async () => {
|
|
57
|
+
try {
|
|
58
|
+
await fn();
|
|
59
|
+
this.error = void 0;
|
|
60
|
+
this.runningSince = Date.now();
|
|
61
|
+
this.transition("running");
|
|
62
|
+
} catch (err) {
|
|
63
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
64
|
+
this.error = message;
|
|
65
|
+
this.runningSince = null;
|
|
66
|
+
this.transition("stopped", message);
|
|
67
|
+
throw err;
|
|
68
|
+
} finally {
|
|
69
|
+
this.startPromise = null;
|
|
70
|
+
}
|
|
71
|
+
})();
|
|
72
|
+
return this.startPromise;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Stop the agent. Uses the provided callback or falls back to registered one.
|
|
76
|
+
* - No-op if already stopped
|
|
77
|
+
* - Returns existing promise if already stopping
|
|
78
|
+
* - If starting, waits for start to complete then stops
|
|
79
|
+
*/
|
|
80
|
+
async stop(stopFn) {
|
|
81
|
+
const fn = stopFn ?? this.registeredStopFn;
|
|
82
|
+
if (!fn) {
|
|
83
|
+
throw new Error("No stop function provided or registered");
|
|
84
|
+
}
|
|
85
|
+
if (this.state === "stopped") {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (this.state === "stopping") {
|
|
89
|
+
return this.stopPromise ?? Promise.resolve();
|
|
90
|
+
}
|
|
91
|
+
if (this.state === "starting" && this.startPromise) {
|
|
92
|
+
try {
|
|
93
|
+
await this.startPromise;
|
|
94
|
+
} catch {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
this.transition("stopping");
|
|
99
|
+
this.stopPromise = (async () => {
|
|
100
|
+
try {
|
|
101
|
+
await fn();
|
|
102
|
+
} catch (err) {
|
|
103
|
+
log.error({ err }, "Error during agent stop");
|
|
104
|
+
} finally {
|
|
105
|
+
this.runningSince = null;
|
|
106
|
+
this.transition("stopped");
|
|
107
|
+
this.stopPromise = null;
|
|
108
|
+
}
|
|
109
|
+
})();
|
|
110
|
+
return this.stopPromise;
|
|
111
|
+
}
|
|
112
|
+
transition(newState, error) {
|
|
113
|
+
this.state = newState;
|
|
114
|
+
const event = {
|
|
115
|
+
state: newState,
|
|
116
|
+
timestamp: Date.now()
|
|
117
|
+
};
|
|
118
|
+
if (error !== void 0) {
|
|
119
|
+
event.error = error;
|
|
120
|
+
}
|
|
121
|
+
log.info(`Agent state: ${newState}${error ? ` (${error})` : ""}`);
|
|
122
|
+
this.emit("stateChange", event);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export {
|
|
127
|
+
AgentLifecycle
|
|
128
|
+
};
|
|
@@ -1,54 +1,44 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getModelsForProvider
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WFTC3JJW.js";
|
|
4
4
|
import {
|
|
5
|
-
ConfigSchema,
|
|
6
|
-
DealsConfigSchema,
|
|
7
|
-
ensureWorkspace,
|
|
8
5
|
generateWallet,
|
|
9
6
|
getWalletAddress,
|
|
10
7
|
importWallet,
|
|
11
|
-
isNewWorkspace,
|
|
12
8
|
saveWallet,
|
|
13
9
|
walletExists
|
|
14
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-FUNF6H4W.js";
|
|
11
|
+
import {
|
|
12
|
+
ConfigSchema,
|
|
13
|
+
DealsConfigSchema,
|
|
14
|
+
ensureWorkspace,
|
|
15
|
+
isNewWorkspace
|
|
16
|
+
} from "./chunk-AERHOXGC.js";
|
|
17
|
+
import {
|
|
18
|
+
TELEGRAM_MAX_MESSAGE_LENGTH
|
|
19
|
+
} from "./chunk-C4NKJT2Z.js";
|
|
15
20
|
import {
|
|
16
21
|
getClaudeCodeApiKey,
|
|
22
|
+
isClaudeCodeTokenValid
|
|
23
|
+
} from "./chunk-WTDAICGT.js";
|
|
24
|
+
import {
|
|
17
25
|
getProviderMetadata,
|
|
18
26
|
getSupportedProviders,
|
|
19
|
-
isClaudeCodeTokenValid,
|
|
20
27
|
validateApiKeyFormat
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import "./chunk-VFA7QMCZ.js";
|
|
23
|
-
import {
|
|
24
|
-
TELEGRAM_MAX_MESSAGE_LENGTH
|
|
25
|
-
} from "./chunk-UP55PXFH.js";
|
|
28
|
+
} from "./chunk-6OOHHJ4N.js";
|
|
26
29
|
import {
|
|
27
30
|
fetchWithTimeout
|
|
28
31
|
} from "./chunk-XQUHC3JZ.js";
|
|
29
|
-
import "./chunk-R4YSJ4EY.js";
|
|
30
32
|
import {
|
|
31
33
|
TELETON_ROOT
|
|
32
34
|
} from "./chunk-EYWNOHMJ.js";
|
|
33
35
|
import {
|
|
34
36
|
createLogger
|
|
35
|
-
} from "./chunk-
|
|
36
|
-
import "./chunk-3RG5ZIWI.js";
|
|
37
|
-
|
|
38
|
-
// src/webui/setup-server.ts
|
|
39
|
-
import { Hono as Hono2 } from "hono";
|
|
40
|
-
import { serve } from "@hono/node-server";
|
|
41
|
-
import { cors } from "hono/cors";
|
|
42
|
-
import { bodyLimit } from "hono/body-limit";
|
|
43
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
44
|
-
import { join as join3, dirname as dirname2, resolve, relative } from "path";
|
|
45
|
-
import { fileURLToPath } from "url";
|
|
46
|
-
import { exec } from "child_process";
|
|
47
|
-
import { platform } from "os";
|
|
37
|
+
} from "./chunk-NQ6FZKCE.js";
|
|
48
38
|
|
|
49
39
|
// src/webui/routes/setup.ts
|
|
50
40
|
import { Hono } from "hono";
|
|
51
|
-
import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
41
|
+
import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2, statSync } from "fs";
|
|
52
42
|
import { join as join2 } from "path";
|
|
53
43
|
import YAML from "yaml";
|
|
54
44
|
|
|
@@ -400,7 +390,7 @@ function maskKey(key) {
|
|
|
400
390
|
if (key.length <= 10) return "***";
|
|
401
391
|
return key.slice(0, 6) + "..." + key.slice(-4);
|
|
402
392
|
}
|
|
403
|
-
function createSetupRoutes() {
|
|
393
|
+
function createSetupRoutes(options) {
|
|
404
394
|
const app = new Hono();
|
|
405
395
|
const authManager = new TelegramAuthManager();
|
|
406
396
|
app.get("/status", async (c) => {
|
|
@@ -467,7 +457,7 @@ function createSetupRoutes() {
|
|
|
467
457
|
app.get("/detect-claude-code-key", (c) => {
|
|
468
458
|
try {
|
|
469
459
|
const key = getClaudeCodeApiKey();
|
|
470
|
-
const masked =
|
|
460
|
+
const masked = maskKey(key);
|
|
471
461
|
return c.json({
|
|
472
462
|
success: true,
|
|
473
463
|
data: {
|
|
@@ -758,6 +748,33 @@ function createSetupRoutes() {
|
|
|
758
748
|
);
|
|
759
749
|
}
|
|
760
750
|
});
|
|
751
|
+
app.post("/embeddings/warmup", async (c) => {
|
|
752
|
+
try {
|
|
753
|
+
const { LocalEmbeddingProvider } = await import("./local-IHKJFQJS.js");
|
|
754
|
+
const provider = new LocalEmbeddingProvider({});
|
|
755
|
+
const success = await provider.warmup();
|
|
756
|
+
return c.json({
|
|
757
|
+
success,
|
|
758
|
+
model: provider.model,
|
|
759
|
+
dimensions: provider.dimensions
|
|
760
|
+
});
|
|
761
|
+
} catch (error) {
|
|
762
|
+
return c.json(
|
|
763
|
+
{ success: false, error: error instanceof Error ? error.message : String(error) },
|
|
764
|
+
500
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
});
|
|
768
|
+
app.get("/embeddings/status", (c) => {
|
|
769
|
+
const model = "Xenova/all-MiniLM-L6-v2";
|
|
770
|
+
const modelPath = join2(TELETON_ROOT, "models", model, "onnx", "model.onnx");
|
|
771
|
+
try {
|
|
772
|
+
const stats = statSync(modelPath);
|
|
773
|
+
return c.json({ cached: true, model, modelPath, sizeBytes: stats.size });
|
|
774
|
+
} catch {
|
|
775
|
+
return c.json({ cached: false, model, modelPath });
|
|
776
|
+
}
|
|
777
|
+
});
|
|
761
778
|
app.post("/config/save", async (c) => {
|
|
762
779
|
try {
|
|
763
780
|
const input = await c.req.json();
|
|
@@ -854,7 +871,14 @@ function createSetupRoutes() {
|
|
|
854
871
|
...input.cocoon ? { cocoon: input.cocoon } : {},
|
|
855
872
|
...input.tonapi_key ? { tonapi_key: input.tonapi_key } : {},
|
|
856
873
|
...input.toncenter_api_key ? { toncenter_api_key: input.toncenter_api_key } : {},
|
|
857
|
-
...input.tavily_api_key ? { tavily_api_key: input.tavily_api_key } : {}
|
|
874
|
+
...input.tavily_api_key ? { tavily_api_key: input.tavily_api_key } : {},
|
|
875
|
+
// Persist Management API key hash so it survives reboots
|
|
876
|
+
api: {
|
|
877
|
+
enabled: true,
|
|
878
|
+
port: 7778,
|
|
879
|
+
host: "0.0.0.0",
|
|
880
|
+
...options?.keyHash ? { key_hash: options.keyHash } : {}
|
|
881
|
+
}
|
|
858
882
|
};
|
|
859
883
|
ConfigSchema.parse(config);
|
|
860
884
|
const configPath = workspace.configPath;
|
|
@@ -871,191 +895,6 @@ function createSetupRoutes() {
|
|
|
871
895
|
return app;
|
|
872
896
|
}
|
|
873
897
|
|
|
874
|
-
// src/webui/setup-server.ts
|
|
875
|
-
import { randomBytes as randomBytes2 } from "crypto";
|
|
876
|
-
import { readFileSync as readYaml, writeFileSync as writeFileSync3 } from "fs";
|
|
877
|
-
import YAML2 from "yaml";
|
|
878
|
-
var log3 = createLogger("Setup");
|
|
879
|
-
function findWebDist() {
|
|
880
|
-
const candidates = [resolve("dist/web"), resolve("web")];
|
|
881
|
-
const __dirname = dirname2(fileURLToPath(import.meta.url));
|
|
882
|
-
candidates.push(resolve(__dirname, "web"), resolve(__dirname, "../dist/web"));
|
|
883
|
-
for (const candidate of candidates) {
|
|
884
|
-
if (existsSync3(join3(candidate, "index.html"))) {
|
|
885
|
-
return candidate;
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
return null;
|
|
889
|
-
}
|
|
890
|
-
function autoOpenBrowser(url) {
|
|
891
|
-
const os = platform();
|
|
892
|
-
let cmd;
|
|
893
|
-
if (os === "darwin") {
|
|
894
|
-
cmd = `open "${url}"`;
|
|
895
|
-
} else if (os === "win32") {
|
|
896
|
-
cmd = `start "${url}"`;
|
|
897
|
-
} else {
|
|
898
|
-
cmd = `xdg-open "${url}"`;
|
|
899
|
-
}
|
|
900
|
-
exec(cmd, (err) => {
|
|
901
|
-
if (err) {
|
|
902
|
-
log3.info(`Open this URL in your browser: ${url}`);
|
|
903
|
-
}
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
|
-
var SetupServer = class {
|
|
907
|
-
constructor(port = 7777) {
|
|
908
|
-
this.port = port;
|
|
909
|
-
this.app = new Hono2();
|
|
910
|
-
this.launchPromise = new Promise((resolve2) => {
|
|
911
|
-
this.launchResolve = resolve2;
|
|
912
|
-
});
|
|
913
|
-
this.setupMiddleware();
|
|
914
|
-
this.setupRoutes();
|
|
915
|
-
this.setupStaticServing();
|
|
916
|
-
}
|
|
917
|
-
app;
|
|
918
|
-
server = null;
|
|
919
|
-
launchResolve = null;
|
|
920
|
-
launchPromise;
|
|
921
|
-
/** Returns a promise that resolves with the auth token when the user clicks "Start Agent" */
|
|
922
|
-
waitForLaunch() {
|
|
923
|
-
return this.launchPromise;
|
|
924
|
-
}
|
|
925
|
-
setupMiddleware() {
|
|
926
|
-
this.app.use(
|
|
927
|
-
"*",
|
|
928
|
-
cors({
|
|
929
|
-
origin: [
|
|
930
|
-
"http://localhost:5173",
|
|
931
|
-
`http://localhost:${this.port}`,
|
|
932
|
-
"http://127.0.0.1:5173",
|
|
933
|
-
`http://127.0.0.1:${this.port}`
|
|
934
|
-
],
|
|
935
|
-
credentials: true,
|
|
936
|
-
allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
|
|
937
|
-
allowHeaders: ["Content-Type"],
|
|
938
|
-
maxAge: 3600
|
|
939
|
-
})
|
|
940
|
-
);
|
|
941
|
-
this.app.use(
|
|
942
|
-
"*",
|
|
943
|
-
bodyLimit({
|
|
944
|
-
maxSize: 2 * 1024 * 1024,
|
|
945
|
-
onError: (c) => c.json({ success: false, error: "Request body too large (max 2MB)" }, 413)
|
|
946
|
-
})
|
|
947
|
-
);
|
|
948
|
-
this.app.use("*", async (c, next) => {
|
|
949
|
-
await next();
|
|
950
|
-
c.res.headers.set("X-Content-Type-Options", "nosniff");
|
|
951
|
-
c.res.headers.set("X-Frame-Options", "DENY");
|
|
952
|
-
c.res.headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
953
|
-
});
|
|
954
|
-
}
|
|
955
|
-
setupRoutes() {
|
|
956
|
-
this.app.get("/health", (c) => c.json({ status: "ok" }));
|
|
957
|
-
this.app.route("/api/setup", createSetupRoutes());
|
|
958
|
-
this.app.get(
|
|
959
|
-
"/auth/check",
|
|
960
|
-
(c) => c.json({ success: true, data: { authenticated: false, setup: true } })
|
|
961
|
-
);
|
|
962
|
-
this.app.post("/api/setup/launch", async (c) => {
|
|
963
|
-
try {
|
|
964
|
-
const token = randomBytes2(32).toString("hex");
|
|
965
|
-
const configPath = join3(TELETON_ROOT, "config.yaml");
|
|
966
|
-
const raw = readYaml(configPath, "utf-8");
|
|
967
|
-
const config = YAML2.parse(raw);
|
|
968
|
-
config.webui = { ...config.webui || {}, enabled: true, auth_token: token };
|
|
969
|
-
writeFileSync3(configPath, YAML2.stringify(config), { encoding: "utf-8", mode: 384 });
|
|
970
|
-
log3.info("Launch requested \u2014 auth token generated");
|
|
971
|
-
const resolve2 = this.launchResolve;
|
|
972
|
-
this.launchResolve = null;
|
|
973
|
-
if (resolve2) {
|
|
974
|
-
setTimeout(() => resolve2(token), 500);
|
|
975
|
-
}
|
|
976
|
-
return c.json({ success: true, data: { token } });
|
|
977
|
-
} catch (err) {
|
|
978
|
-
return c.json(
|
|
979
|
-
{ success: false, error: err instanceof Error ? err.message : String(err) },
|
|
980
|
-
500
|
|
981
|
-
);
|
|
982
|
-
}
|
|
983
|
-
});
|
|
984
|
-
this.app.onError((err, c) => {
|
|
985
|
-
log3.error({ err }, "Setup server error");
|
|
986
|
-
return c.json({ success: false, error: err.message || "Internal server error" }, 500);
|
|
987
|
-
});
|
|
988
|
-
}
|
|
989
|
-
setupStaticServing() {
|
|
990
|
-
const webDist = findWebDist();
|
|
991
|
-
if (!webDist) return;
|
|
992
|
-
const indexHtml = readFileSync2(join3(webDist, "index.html"), "utf-8");
|
|
993
|
-
const mimeTypes = {
|
|
994
|
-
js: "application/javascript",
|
|
995
|
-
css: "text/css",
|
|
996
|
-
svg: "image/svg+xml",
|
|
997
|
-
png: "image/png",
|
|
998
|
-
jpg: "image/jpeg",
|
|
999
|
-
jpeg: "image/jpeg",
|
|
1000
|
-
ico: "image/x-icon",
|
|
1001
|
-
json: "application/json",
|
|
1002
|
-
woff2: "font/woff2",
|
|
1003
|
-
woff: "font/woff"
|
|
1004
|
-
};
|
|
1005
|
-
this.app.get("*", (c) => {
|
|
1006
|
-
const filePath = resolve(join3(webDist, c.req.path));
|
|
1007
|
-
const rel = relative(webDist, filePath);
|
|
1008
|
-
if (rel.startsWith("..") || resolve(filePath) !== filePath) {
|
|
1009
|
-
return c.html(indexHtml);
|
|
1010
|
-
}
|
|
1011
|
-
try {
|
|
1012
|
-
const content = readFileSync2(filePath);
|
|
1013
|
-
const ext = filePath.split(".").pop() || "";
|
|
1014
|
-
if (mimeTypes[ext]) {
|
|
1015
|
-
const immutable = c.req.path.startsWith("/assets/");
|
|
1016
|
-
return c.body(content, 200, {
|
|
1017
|
-
"Content-Type": mimeTypes[ext],
|
|
1018
|
-
"Cache-Control": immutable ? "public, max-age=31536000, immutable" : "public, max-age=3600"
|
|
1019
|
-
});
|
|
1020
|
-
}
|
|
1021
|
-
} catch {
|
|
1022
|
-
}
|
|
1023
|
-
return c.html(indexHtml);
|
|
1024
|
-
});
|
|
1025
|
-
}
|
|
1026
|
-
async start() {
|
|
1027
|
-
return new Promise((resolve2, reject) => {
|
|
1028
|
-
try {
|
|
1029
|
-
this.server = serve(
|
|
1030
|
-
{
|
|
1031
|
-
fetch: this.app.fetch,
|
|
1032
|
-
hostname: "127.0.0.1",
|
|
1033
|
-
port: this.port
|
|
1034
|
-
},
|
|
1035
|
-
() => {
|
|
1036
|
-
const url = `http://localhost:${this.port}/setup`;
|
|
1037
|
-
log3.info(`Setup wizard: ${url}`);
|
|
1038
|
-
autoOpenBrowser(url);
|
|
1039
|
-
resolve2();
|
|
1040
|
-
}
|
|
1041
|
-
);
|
|
1042
|
-
} catch (error) {
|
|
1043
|
-
reject(error);
|
|
1044
|
-
}
|
|
1045
|
-
});
|
|
1046
|
-
}
|
|
1047
|
-
async stop() {
|
|
1048
|
-
if (this.server) {
|
|
1049
|
-
return new Promise((resolve2) => {
|
|
1050
|
-
this.server.closeAllConnections();
|
|
1051
|
-
this.server?.close(() => {
|
|
1052
|
-
log3.info("Setup server stopped");
|
|
1053
|
-
resolve2();
|
|
1054
|
-
});
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
};
|
|
1059
898
|
export {
|
|
1060
|
-
|
|
899
|
+
createSetupRoutes
|
|
1061
900
|
};
|
|
@@ -26,6 +26,16 @@ var MODEL_OPTIONS = {
|
|
|
26
26
|
{ value: "gpt-5", name: "GPT-5", description: "Most capable, 400K ctx, $1.25/M" },
|
|
27
27
|
{ value: "gpt-5-pro", name: "GPT-5 Pro", description: "Extended thinking, 400K ctx" },
|
|
28
28
|
{ value: "gpt-5-mini", name: "GPT-5 Mini", description: "Fast & cheap, 400K ctx" },
|
|
29
|
+
{
|
|
30
|
+
value: "gpt-5.4",
|
|
31
|
+
name: "GPT-5.4",
|
|
32
|
+
description: "Latest frontier, reasoning, openai-responses API"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
value: "gpt-5.4-pro",
|
|
36
|
+
name: "GPT-5.4 Pro",
|
|
37
|
+
description: "Extended thinking, openai-responses API"
|
|
38
|
+
},
|
|
29
39
|
{ value: "gpt-5.1", name: "GPT-5.1", description: "Latest gen, 400K ctx" },
|
|
30
40
|
{ value: "gpt-4o", name: "GPT-4o", description: "Balanced, 128K ctx, $2.50/M" },
|
|
31
41
|
{ value: "gpt-4.1", name: "GPT-4.1", description: "1M ctx, $2/M" },
|
|
@@ -35,6 +45,12 @@ var MODEL_OPTIONS = {
|
|
|
35
45
|
{ value: "codex-mini-latest", name: "Codex Mini", description: "Coding specialist" }
|
|
36
46
|
],
|
|
37
47
|
google: [
|
|
48
|
+
{ value: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro", description: "Preview, latest gen" },
|
|
49
|
+
{
|
|
50
|
+
value: "gemini-3.1-flash-lite-preview",
|
|
51
|
+
name: "Gemini 3.1 Flash Lite",
|
|
52
|
+
description: "Preview, fast & cheap"
|
|
53
|
+
},
|
|
38
54
|
{ value: "gemini-3-pro-preview", name: "Gemini 3 Pro", description: "Preview, most capable" },
|
|
39
55
|
{ value: "gemini-3-flash-preview", name: "Gemini 3 Flash", description: "Preview, fast" },
|
|
40
56
|
{ value: "gemini-2.5-pro", name: "Gemini 2.5 Pro", description: "Stable, 1M ctx, $1.25/M" },
|