teleton 0.5.1 → 0.5.2

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.
@@ -49,7 +49,7 @@ import {
49
49
  openModuleDb,
50
50
  setTonapiKey,
51
51
  tonapiFetch
52
- } from "./chunk-BYTHCDZA.js";
52
+ } from "./chunk-WUTMT6DW.js";
53
53
  import {
54
54
  GRAMJS_RETRY_DELAY_MS,
55
55
  RETRY_BLOCKCHAIN_BASE_DELAY_MS,
@@ -195,6 +195,10 @@ var WebUIConfigSchema = z.object({
195
195
  cors_origins: z.array(z.string()).default(["http://localhost:5173", "http://localhost:7777"]).describe("Allowed CORS origins for development"),
196
196
  log_requests: z.boolean().default(false).describe("Log all HTTP requests")
197
197
  }).default({});
198
+ var EmbeddingConfigSchema = z.object({
199
+ provider: z.enum(["local", "anthropic", "none"]).default("local").describe("Embedding provider: local (ONNX), anthropic (API), or none (FTS5-only)"),
200
+ model: z.string().optional().describe("Model override (default: Xenova/all-MiniLM-L6-v2 for local)")
201
+ }).default({});
198
202
  var DevConfigSchema = z.object({
199
203
  hot_reload: z.boolean().default(false).describe("Enable plugin hot-reload (watches ~/.teleton/plugins/ for changes)")
200
204
  }).default({});
@@ -203,6 +207,7 @@ var ConfigSchema = z.object({
203
207
  agent: AgentConfigSchema,
204
208
  telegram: TelegramConfigSchema,
205
209
  storage: StorageConfigSchema.default({}),
210
+ embedding: EmbeddingConfigSchema,
206
211
  deals: DealsConfigSchema,
207
212
  webui: WebUIConfigSchema,
208
213
  dev: DevConfigSchema,
@@ -21353,6 +21358,8 @@ function registerAllTools(registry) {
21353
21358
  import { readdirSync as readdirSync5, existsSync as existsSync16, statSync as statSync2 } from "fs";
21354
21359
  import { join as join14 } from "path";
21355
21360
  import { pathToFileURL } from "url";
21361
+ import { execFile } from "child_process";
21362
+ import { promisify } from "util";
21356
21363
 
21357
21364
  // src/agent/tools/plugin-validator.ts
21358
21365
  import { z as z2 } from "zod";
@@ -23063,6 +23070,7 @@ function semverSatisfies(current, range) {
23063
23070
  }
23064
23071
 
23065
23072
  // src/agent/tools/plugin-loader.ts
23073
+ var execFileAsync = promisify(execFile);
23066
23074
  var PLUGIN_DATA_DIR = join14(TELETON_ROOT, "plugins", "data");
23067
23075
  function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps) {
23068
23076
  let manifest = null;
@@ -23248,6 +23256,33 @@ function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps) {
23248
23256
  };
23249
23257
  return module;
23250
23258
  }
23259
+ async function ensurePluginDeps(pluginDir, pluginEntry) {
23260
+ const pkgJson = join14(pluginDir, "package.json");
23261
+ const lockfile = join14(pluginDir, "package-lock.json");
23262
+ const nodeModules = join14(pluginDir, "node_modules");
23263
+ if (!existsSync16(pkgJson)) return;
23264
+ if (!existsSync16(lockfile)) {
23265
+ console.warn(
23266
+ `\u26A0\uFE0F [${pluginEntry}] package.json without package-lock.json \u2014 skipping (lockfile required)`
23267
+ );
23268
+ return;
23269
+ }
23270
+ if (existsSync16(nodeModules)) {
23271
+ const marker = join14(nodeModules, ".package-lock.json");
23272
+ if (existsSync16(marker) && statSync2(marker).mtimeMs >= statSync2(lockfile).mtimeMs) return;
23273
+ }
23274
+ console.log(`\u{1F4E6} [${pluginEntry}] Installing dependencies...`);
23275
+ try {
23276
+ await execFileAsync("npm", ["ci", "--ignore-scripts", "--no-audit", "--no-fund"], {
23277
+ cwd: pluginDir,
23278
+ timeout: 6e4,
23279
+ env: { ...process.env, NODE_ENV: "production" }
23280
+ });
23281
+ console.log(`\u{1F4E6} [${pluginEntry}] Dependencies installed`);
23282
+ } catch (err) {
23283
+ console.error(`\u274C [${pluginEntry}] Failed to install deps: ${String(err).slice(0, 300)}`);
23284
+ }
23285
+ }
23251
23286
  async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps) {
23252
23287
  const pluginsDir = WORKSPACE_PATHS.PLUGINS_DIR;
23253
23288
  if (!existsSync16(pluginsDir)) {
@@ -23278,6 +23313,9 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps) {
23278
23313
  pluginPaths.push({ entry, path: modulePath });
23279
23314
  }
23280
23315
  }
23316
+ await Promise.allSettled(
23317
+ pluginPaths.filter(({ path }) => path.endsWith("index.js")).map(({ entry }) => ensurePluginDeps(join14(pluginsDir, entry), entry))
23318
+ );
23281
23319
  const loadResults = await Promise.allSettled(
23282
23320
  pluginPaths.map(async ({ entry, path }) => {
23283
23321
  const moduleUrl = pathToFileURL(path).href;
@@ -23442,7 +23480,8 @@ var PluginWatcher = class {
23442
23480
  "**/.git/**",
23443
23481
  "**/*.map",
23444
23482
  "**/*.d.ts",
23445
- "**/*.md"
23483
+ "**/*.md",
23484
+ "**/package-lock.json"
23446
23485
  ],
23447
23486
  depth: 1,
23448
23487
  followSymlinks: false,
@@ -23466,11 +23505,11 @@ var PluginWatcher = class {
23466
23505
  */
23467
23506
  resolvePluginName(filePath) {
23468
23507
  const fileName = basename2(filePath);
23469
- if (!fileName.endsWith(".js")) return null;
23508
+ if (!fileName.endsWith(".js") && fileName !== "package.json") return null;
23470
23509
  const rel = relative(this.pluginsDir, filePath);
23471
23510
  const segments = rel.split(sep);
23472
23511
  if (segments.some((s) => s === ".." || s === ".")) return null;
23473
- if (segments.length === 2 && segments[1] === "index.js") {
23512
+ if (segments.length === 2 && (segments[1] === "index.js" || segments[1] === "package.json")) {
23474
23513
  return segments[0];
23475
23514
  }
23476
23515
  if (segments.length === 1 && fileName.endsWith(".js")) {
@@ -23542,6 +23581,10 @@ var PluginWatcher = class {
23542
23581
  if (!modulePath) {
23543
23582
  throw new Error(`Plugin file not found for "${pluginName}"`);
23544
23583
  }
23584
+ if (basename2(modulePath) === "index.js") {
23585
+ const pluginDir = resolve(this.pluginsDir, pluginName);
23586
+ await ensurePluginDeps(pluginDir, pluginName);
23587
+ }
23545
23588
  const moduleUrl = pathToFileURL2(modulePath).href + `?t=${Date.now()}`;
23546
23589
  const freshMod = await import(moduleUrl);
23547
23590
  if (!freshMod.tools || typeof freshMod.tools !== "function" && !Array.isArray(freshMod.tools)) {
@@ -23638,15 +23681,17 @@ var TeletonApp = class {
23638
23681
  autoReconnect: true,
23639
23682
  floodSleepThreshold: TELEGRAM_FLOOD_SLEEP_THRESHOLD
23640
23683
  });
23684
+ const embeddingProvider = this.config.embedding.provider;
23641
23685
  this.memory = initializeMemory({
23642
23686
  database: {
23643
23687
  path: join15(TELETON_ROOT, "memory.db"),
23644
- enableVectorSearch: true,
23688
+ enableVectorSearch: embeddingProvider !== "none",
23645
23689
  vectorDimensions: 384
23646
23690
  },
23647
23691
  embeddings: {
23648
- provider: "local",
23649
- model: ""
23692
+ provider: embeddingProvider,
23693
+ model: this.config.embedding.model,
23694
+ apiKey: embeddingProvider === "anthropic" ? this.config.agent.api_key : void 0
23650
23695
  },
23651
23696
  workspaceDir: join15(TELETON_ROOT)
23652
23697
  });
@@ -23727,10 +23772,13 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
23727
23772
  `\u26A0\uFE0F Tool count (${this.toolCount}) exceeds ${providerMeta.displayName} limit (${providerMeta.toolLimit})`
23728
23773
  );
23729
23774
  }
23730
- const { migrateSessionsToDb } = await import("./migrate-PMB2JVXH.js");
23775
+ const { migrateSessionsToDb } = await import("./migrate-UEQCDWL2.js");
23731
23776
  migrateSessionsToDb();
23732
23777
  const { cleanupOldTranscripts } = await import("./transcript-7V4UNID4.js");
23733
23778
  cleanupOldTranscripts(30);
23779
+ if (this.memory.embedder.warmup) {
23780
+ await this.memory.embedder.warmup();
23781
+ }
23734
23782
  const indexResult = await this.memory.knowledge.indexAll();
23735
23783
  const db2 = getDatabase();
23736
23784
  const ftsResult = db2.rebuildFtsIndexes();
@@ -23922,7 +23970,7 @@ Task: "${taskDescription}"`;
23922
23970
  const { getTaskStore } = await import("./tasks-QSCWSMPS.js");
23923
23971
  const { executeScheduledTask } = await import("./task-executor-N7XNVK5N.js");
23924
23972
  const { TaskDependencyResolver } = await import("./task-dependency-resolver-TRPILAHM.js");
23925
- const { getDatabase: getDatabase2 } = await import("./memory-657W5AS6.js");
23973
+ const { getDatabase: getDatabase2 } = await import("./memory-Y5J7CXAR.js");
23926
23974
  const db2 = getDatabase2().getDb();
23927
23975
  const taskStore = getTaskStore(db2);
23928
23976
  const match = message.text.match(/^\[TASK:([^\]]+)\]/);
@@ -874,11 +874,13 @@ var AnthropicEmbeddingProvider = class {
874
874
  };
875
875
 
876
876
  // src/memory/embeddings/local.ts
877
- import { pipeline } from "@huggingface/transformers";
877
+ import { pipeline, env } from "@huggingface/transformers";
878
+ import { join as join2 } from "path";
879
+ env.cacheDir = join2(TELETON_ROOT, "models");
878
880
  var extractorPromise = null;
879
881
  function getExtractor(model) {
880
882
  if (!extractorPromise) {
881
- console.log(`\u{1F4E6} Loading local embedding model: ${model} \u2026`);
883
+ console.log(`\u{1F4E6} Loading local embedding model: ${model} (cache: ${env.cacheDir})`);
882
884
  extractorPromise = pipeline("feature-extraction", model, {
883
885
  dtype: "fp32"
884
886
  }).then((ext) => {
@@ -896,16 +898,37 @@ var LocalEmbeddingProvider = class {
896
898
  id = "local";
897
899
  model;
898
900
  dimensions;
901
+ _disabled = false;
899
902
  constructor(config) {
900
903
  this.model = config.model || "Xenova/all-MiniLM-L6-v2";
901
904
  this.dimensions = 384;
902
905
  }
906
+ /**
907
+ * Pre-download and load the model at startup.
908
+ * If loading fails, marks this provider as disabled (returns empty embeddings).
909
+ * Call this once during app init — avoids retry spam on every message.
910
+ * @returns true if model loaded successfully, false if fallback to noop
911
+ */
912
+ async warmup() {
913
+ try {
914
+ await getExtractor(this.model);
915
+ return true;
916
+ } catch (err) {
917
+ console.warn(
918
+ `\u26A0\uFE0F Local embedding model unavailable \u2014 falling back to FTS5-only search (no vector embeddings)`
919
+ );
920
+ this._disabled = true;
921
+ return false;
922
+ }
923
+ }
903
924
  async embedQuery(text) {
925
+ if (this._disabled) return [];
904
926
  const extractor = await getExtractor(this.model);
905
927
  const output = await extractor(text, { pooling: "mean", normalize: true });
906
928
  return Array.from(output.data);
907
929
  }
908
930
  async embedBatch(texts) {
931
+ if (this._disabled) return [];
909
932
  if (texts.length === 0) return [];
910
933
  const extractor = await getExtractor(this.model);
911
934
  const output = await extractor(texts, { pooling: "mean", normalize: true });
@@ -950,6 +973,9 @@ var CachedEmbeddingProvider = class {
950
973
  `UPDATE embedding_cache SET accessed_at = unixepoch() WHERE hash = ? AND model = ? AND provider = ?`
951
974
  ).run(hash, this.model, this.id);
952
975
  }
976
+ async warmup() {
977
+ return this.inner.warmup?.() ?? true;
978
+ }
953
979
  async embedQuery(text) {
954
980
  const hash = hashText(text);
955
981
  const row = this.cacheGet(hash);
@@ -1075,7 +1101,7 @@ function deserializeEmbedding(data) {
1075
1101
 
1076
1102
  // src/memory/agent/knowledge.ts
1077
1103
  import { readFileSync, existsSync as existsSync3, readdirSync, statSync } from "fs";
1078
- import { join as join2 } from "path";
1104
+ import { join as join3 } from "path";
1079
1105
  var KnowledgeIndexer = class {
1080
1106
  constructor(db, workspaceDir, embedder, vectorEnabled) {
1081
1107
  this.db = db;
@@ -1146,15 +1172,15 @@ var KnowledgeIndexer = class {
1146
1172
  }
1147
1173
  listMemoryFiles() {
1148
1174
  const files = [];
1149
- const memoryMd = join2(this.workspaceDir, "MEMORY.md");
1175
+ const memoryMd = join3(this.workspaceDir, "MEMORY.md");
1150
1176
  if (existsSync3(memoryMd)) {
1151
1177
  files.push(memoryMd);
1152
1178
  }
1153
- const memoryDir = join2(this.workspaceDir, "memory");
1179
+ const memoryDir = join3(this.workspaceDir, "memory");
1154
1180
  if (existsSync3(memoryDir)) {
1155
1181
  const entries = readdirSync(memoryDir);
1156
1182
  for (const entry of entries) {
1157
- const absPath = join2(memoryDir, entry);
1183
+ const absPath = join3(memoryDir, entry);
1158
1184
  if (statSync(absPath).isFile() && entry.endsWith(".md")) {
1159
1185
  files.push(absPath);
1160
1186
  }
package/dist/cli/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  saveWallet,
16
16
  validateApiKeyFormat,
17
17
  walletExists
18
- } from "../chunk-RRB6BWU7.js";
18
+ } from "../chunk-WOXBZOQX.js";
19
19
  import "../chunk-WL2Q3VRD.js";
20
20
  import "../chunk-EHEV7FJ7.js";
21
21
  import "../chunk-U7FQYCBQ.js";
@@ -23,7 +23,7 @@ import "../chunk-5WWR4CU3.js";
23
23
  import "../chunk-YBA6IBGT.js";
24
24
  import {
25
25
  fetchWithTimeout
26
- } from "../chunk-BYTHCDZA.js";
26
+ } from "../chunk-WUTMT6DW.js";
27
27
  import "../chunk-4DU3C27M.js";
28
28
  import {
29
29
  TELEGRAM_MAX_MESSAGE_LENGTH
@@ -579,6 +579,7 @@ Get it at: ${providerMeta.consoleUrl}`,
579
579
  memory_file: `${workspace.root}/memory.json`,
580
580
  history_limit: 100
581
581
  },
582
+ embedding: { provider: "local" },
582
583
  deals: DealsConfigSchema.parse({
583
584
  enabled: dealsEnabled,
584
585
  buy_max_floor_percent: buyMaxFloorPercent,
@@ -760,6 +761,7 @@ async function runNonInteractiveOnboarding(options, prompter) {
760
761
  memory_file: `${workspace.root}/memory.json`,
761
762
  history_limit: 100
762
763
  },
764
+ embedding: { provider: "local" },
763
765
  deals: DealsConfigSchema.parse({}),
764
766
  webui: {
765
767
  enabled: false,
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  TeletonApp,
3
3
  main
4
- } from "./chunk-RRB6BWU7.js";
4
+ } from "./chunk-WOXBZOQX.js";
5
5
  import "./chunk-WL2Q3VRD.js";
6
6
  import "./chunk-EHEV7FJ7.js";
7
7
  import "./chunk-U7FQYCBQ.js";
8
8
  import "./chunk-5WWR4CU3.js";
9
9
  import "./chunk-YBA6IBGT.js";
10
- import "./chunk-BYTHCDZA.js";
10
+ import "./chunk-WUTMT6DW.js";
11
11
  import "./chunk-4DU3C27M.js";
12
12
  import "./chunk-O4R7V5Y2.js";
13
13
  import "./chunk-EYWNOHMJ.js";
@@ -24,7 +24,7 @@ import {
24
24
  runMigrations,
25
25
  serializeEmbedding,
26
26
  setSchemaVersion
27
- } from "./chunk-BYTHCDZA.js";
27
+ } from "./chunk-WUTMT6DW.js";
28
28
  import "./chunk-4DU3C27M.js";
29
29
  import "./chunk-O4R7V5Y2.js";
30
30
  import "./chunk-EYWNOHMJ.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDatabase
3
- } from "./chunk-BYTHCDZA.js";
3
+ } from "./chunk-WUTMT6DW.js";
4
4
  import "./chunk-4DU3C27M.js";
5
5
  import "./chunk-O4R7V5Y2.js";
6
6
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teleton",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "workspaces": [
5
5
  "packages/*"
6
6
  ],
@@ -61,13 +61,11 @@
61
61
  "dependencies": {
62
62
  "@clack/prompts": "^0.7.0",
63
63
  "@dedust/sdk": "^0.8.7",
64
- "@evaafi/sdk": "^0.9.5",
65
64
  "@hono/node-server": "^1.19.9",
66
65
  "@huggingface/transformers": "^3.8.1",
67
66
  "@mariozechner/pi-ai": "^0.50.9",
68
67
  "@orbs-network/ton-access": "^2.3.3",
69
68
  "@sinclair/typebox": "^0.34.48",
70
- "@storm-trade/sdk": "^1.0.0-rc.4",
71
69
  "@ton/core": "^0.63.0",
72
70
  "@ton/crypto": "^3.3.0",
73
71
  "@ton/ton": "^16.1.0",