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.
Files changed (43) hide show
  1. package/dist/bootstrap-DDFVEMYI.js +128 -0
  2. package/dist/{server-3FHI2SEB.js → chunk-2ERTYRHA.js} +26 -372
  3. package/dist/{chunk-5FNWBZ5K.js → chunk-33Z47EXI.js} +264 -274
  4. package/dist/{chunk-3S4GGLLR.js → chunk-35MX4ZUI.js} +23 -104
  5. package/dist/chunk-3UFPFWYP.js +12 -0
  6. package/dist/chunk-5SEMA47R.js +75 -0
  7. package/dist/{chunk-PHSAHTK4.js → chunk-6OOHHJ4N.js} +3 -108
  8. package/dist/{chunk-CGOXE4WP.js → chunk-7MWKT67G.js} +467 -914
  9. package/dist/chunk-AEHTQI3H.js +142 -0
  10. package/dist/{chunk-S6PHGKOC.js → chunk-AERHOXGC.js} +88 -322
  11. package/dist/chunk-ALKAAG4O.js +487 -0
  12. package/dist/{chunk-UP55PXFH.js → chunk-C4NKJT2Z.js} +8 -0
  13. package/dist/chunk-CUE4UZXR.js +129 -0
  14. package/dist/chunk-FUNF6H4W.js +251 -0
  15. package/dist/{chunk-7U7BOHCL.js → chunk-GHMXWAXI.js} +147 -63
  16. package/dist/{chunk-QBHRXLZS.js → chunk-H7MFXJZK.js} +2 -2
  17. package/dist/{chunk-QV2GLOTK.js → chunk-LC4TV3KL.js} +1 -1
  18. package/dist/{chunk-AYWEJCDB.js → chunk-LVTKJQ7O.js} +12 -10
  19. package/dist/{chunk-RCMD3U65.js → chunk-NQ6FZKCE.js} +13 -0
  20. package/dist/chunk-NVKBBTI6.js +128 -0
  21. package/dist/{setup-server-32XGDPE6.js → chunk-OIMAE24Q.js} +55 -216
  22. package/dist/{chunk-OJCLKU5Z.js → chunk-WFTC3JJW.js} +16 -0
  23. package/dist/chunk-WTDAICGT.js +175 -0
  24. package/dist/{chunk-KVXV7EF7.js → chunk-XDZDOKIF.js} +2 -2
  25. package/dist/cli/index.js +91 -27
  26. package/dist/{client-MPHPIZB6.js → client-5KD25NOP.js} +5 -4
  27. package/dist/{get-my-gifts-CC6HAVWB.js → get-my-gifts-Y7EN7RK4.js} +3 -3
  28. package/dist/index.js +19 -13
  29. package/dist/local-IHKJFQJS.js +9 -0
  30. package/dist/{memory-UBHM7ILG.js → memory-QMJRM3XJ.js} +9 -5
  31. package/dist/memory-hook-VUNWZ3NY.js +19 -0
  32. package/dist/{migrate-UBBEJ5BL.js → migrate-5VBAP52B.js} +5 -4
  33. package/dist/server-JF6FX772.js +813 -0
  34. package/dist/server-N4T7E25M.js +396 -0
  35. package/dist/setup-server-IX3BFPPH.js +217 -0
  36. package/dist/{store-M5IMUQCL.js → store-BY7S6IFN.js} +6 -5
  37. package/dist/{task-dependency-resolver-RR2O5S7B.js → task-dependency-resolver-L6UUMTHK.js} +2 -2
  38. package/dist/{task-executor-6W5HRX5C.js → task-executor-XBNJLUCS.js} +2 -2
  39. package/dist/{tool-adapter-IH5VGBOO.js → tool-adapter-IVX2XQJE.js} +1 -1
  40. package/dist/{tool-index-PMAOXWUA.js → tool-index-FTERJSZK.js} +4 -3
  41. package/dist/{transcript-NGDPSNIH.js → transcript-IM7G25OS.js} +2 -2
  42. package/package.json +4 -2
  43. package/dist/chunk-XBE4JB7C.js +0 -8
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-EYWNOHMJ.js";
4
4
  import {
5
5
  createLogger
6
- } from "./chunk-RCMD3U65.js";
6
+ } from "./chunk-NQ6FZKCE.js";
7
7
 
8
8
  // src/session/transcript.ts
9
9
  import {
@@ -1,18 +1,20 @@
1
1
  import {
2
2
  getClaudeCodeApiKey,
3
- getProviderMetadata,
4
3
  refreshClaudeCodeApiKey
5
- } from "./chunk-PHSAHTK4.js";
4
+ } from "./chunk-WTDAICGT.js";
6
5
  import {
7
- appendToTranscript,
8
- readTranscript
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-RCMD3U65.js";
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-IH5VGBOO.js");
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-IH5VGBOO.js");
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-IH5VGBOO.js");
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-OJCLKU5Z.js";
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-S6PHGKOC.js";
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-PHSAHTK4.js";
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-RCMD3U65.js";
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 = key.slice(0, 12) + "****" + key.slice(-4);
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
- SetupServer
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" },