teleton 0.7.3 → 0.7.4

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.
@@ -0,0 +1,158 @@
1
+ // src/config/model-catalog.ts
2
+ var MODEL_OPTIONS = {
3
+ anthropic: [
4
+ {
5
+ value: "claude-opus-4-6",
6
+ name: "Claude Opus 4.6",
7
+ description: "Most capable, 1M ctx, $5/M"
8
+ },
9
+ {
10
+ value: "claude-opus-4-5-20251101",
11
+ name: "Claude Opus 4.5",
12
+ description: "Previous gen, 200K ctx, $5/M"
13
+ },
14
+ {
15
+ value: "claude-sonnet-4-6",
16
+ name: "Claude Sonnet 4.6",
17
+ description: "Balanced, 200K ctx, $3/M"
18
+ },
19
+ {
20
+ value: "claude-haiku-4-5-20251001",
21
+ name: "Claude Haiku 4.5",
22
+ description: "Fast & cheap, $1/M"
23
+ }
24
+ ],
25
+ openai: [
26
+ { value: "gpt-5", name: "GPT-5", description: "Most capable, 400K ctx, $1.25/M" },
27
+ { value: "gpt-5-pro", name: "GPT-5 Pro", description: "Extended thinking, 400K ctx" },
28
+ { value: "gpt-5-mini", name: "GPT-5 Mini", description: "Fast & cheap, 400K ctx" },
29
+ { value: "gpt-5.1", name: "GPT-5.1", description: "Latest gen, 400K ctx" },
30
+ { value: "gpt-4o", name: "GPT-4o", description: "Balanced, 128K ctx, $2.50/M" },
31
+ { value: "gpt-4.1", name: "GPT-4.1", description: "1M ctx, $2/M" },
32
+ { value: "gpt-4.1-mini", name: "GPT-4.1 Mini", description: "1M ctx, cheap, $0.40/M" },
33
+ { value: "o4-mini", name: "o4 Mini", description: "Reasoning, fast, 200K ctx" },
34
+ { value: "o3", name: "o3", description: "Reasoning, 200K ctx, $2/M" },
35
+ { value: "codex-mini-latest", name: "Codex Mini", description: "Coding specialist" }
36
+ ],
37
+ google: [
38
+ { value: "gemini-3-pro-preview", name: "Gemini 3 Pro", description: "Preview, most capable" },
39
+ { value: "gemini-3-flash-preview", name: "Gemini 3 Flash", description: "Preview, fast" },
40
+ { value: "gemini-2.5-pro", name: "Gemini 2.5 Pro", description: "Stable, 1M ctx, $1.25/M" },
41
+ { value: "gemini-2.5-flash", name: "Gemini 2.5 Flash", description: "Fast, 1M ctx, $0.30/M" },
42
+ {
43
+ value: "gemini-2.5-flash-lite",
44
+ name: "Gemini 2.5 Flash Lite",
45
+ description: "Ultra cheap, 1M ctx"
46
+ },
47
+ { value: "gemini-2.0-flash", name: "Gemini 2.0 Flash", description: "Cheap, 1M ctx, $0.10/M" }
48
+ ],
49
+ xai: [
50
+ { value: "grok-4-1-fast", name: "Grok 4.1 Fast", description: "Latest, vision, 2M ctx" },
51
+ { value: "grok-4-fast", name: "Grok 4 Fast", description: "Vision, 2M ctx, $0.20/M" },
52
+ { value: "grok-4", name: "Grok 4", description: "Reasoning, 256K ctx, $3/M" },
53
+ { value: "grok-code-fast-1", name: "Grok Code", description: "Coding specialist, fast" },
54
+ { value: "grok-3", name: "Grok 3", description: "Stable, 131K ctx, $3/M" }
55
+ ],
56
+ groq: [
57
+ {
58
+ value: "meta-llama/llama-4-maverick-17b-128e-instruct",
59
+ name: "Llama 4 Maverick",
60
+ description: "Vision, 131K ctx, $0.20/M"
61
+ },
62
+ { value: "qwen/qwen3-32b", name: "Qwen3 32B", description: "Reasoning, 131K ctx, $0.29/M" },
63
+ {
64
+ value: "deepseek-r1-distill-llama-70b",
65
+ name: "DeepSeek R1 70B",
66
+ description: "Reasoning, 131K ctx, $0.75/M"
67
+ },
68
+ {
69
+ value: "llama-3.3-70b-versatile",
70
+ name: "Llama 3.3 70B",
71
+ description: "General purpose, 131K ctx, $0.59/M"
72
+ }
73
+ ],
74
+ openrouter: [
75
+ { value: "anthropic/claude-opus-4.5", name: "Claude Opus 4.5", description: "200K ctx, $5/M" },
76
+ {
77
+ value: "anthropic/claude-sonnet-4-6",
78
+ name: "Claude Sonnet 4.6",
79
+ description: "200K ctx, $3/M"
80
+ },
81
+ { value: "openai/gpt-5", name: "GPT-5", description: "400K ctx, $1.25/M" },
82
+ { value: "google/gemini-2.5-flash", name: "Gemini 2.5 Flash", description: "1M ctx, $0.30/M" },
83
+ {
84
+ value: "deepseek/deepseek-r1",
85
+ name: "DeepSeek R1",
86
+ description: "Reasoning, 64K ctx, $0.70/M"
87
+ },
88
+ {
89
+ value: "deepseek/deepseek-r1-0528",
90
+ name: "DeepSeek R1 0528",
91
+ description: "Reasoning improved, 64K ctx"
92
+ },
93
+ {
94
+ value: "deepseek/deepseek-v3.2",
95
+ name: "DeepSeek V3.2",
96
+ description: "Latest, general, 64K ctx"
97
+ },
98
+ { value: "deepseek/deepseek-v3.1", name: "DeepSeek V3.1", description: "General, 64K ctx" },
99
+ {
100
+ value: "deepseek/deepseek-v3-0324",
101
+ name: "DeepSeek V3",
102
+ description: "General, 64K ctx, $0.30/M"
103
+ },
104
+ { value: "qwen/qwen3-coder", name: "Qwen3 Coder", description: "Coding specialist" },
105
+ { value: "qwen/qwen3-max", name: "Qwen3 Max", description: "Most capable Qwen" },
106
+ { value: "qwen/qwen3-235b-a22b", name: "Qwen3 235B", description: "235B params, MoE" },
107
+ {
108
+ value: "nvidia/nemotron-nano-9b-v2",
109
+ name: "Nemotron Nano 9B",
110
+ description: "Small & fast, Nvidia"
111
+ },
112
+ {
113
+ value: "perplexity/sonar-pro",
114
+ name: "Perplexity Sonar Pro",
115
+ description: "Web search integrated"
116
+ },
117
+ { value: "minimax/minimax-m2.5", name: "MiniMax M2.5", description: "Latest MiniMax" },
118
+ { value: "x-ai/grok-4", name: "Grok 4", description: "256K ctx, $3/M" }
119
+ ],
120
+ moonshot: [
121
+ { value: "kimi-k2.5", name: "Kimi K2.5", description: "Free, 256K ctx, multimodal" },
122
+ {
123
+ value: "kimi-k2-thinking",
124
+ name: "Kimi K2 Thinking",
125
+ description: "Free, 256K ctx, reasoning"
126
+ }
127
+ ],
128
+ mistral: [
129
+ {
130
+ value: "devstral-small-2507",
131
+ name: "Devstral Small",
132
+ description: "Coding, 128K ctx, $0.10/M"
133
+ },
134
+ {
135
+ value: "devstral-medium-latest",
136
+ name: "Devstral Medium",
137
+ description: "Coding, 262K ctx, $0.40/M"
138
+ },
139
+ {
140
+ value: "mistral-large-latest",
141
+ name: "Mistral Large",
142
+ description: "General, 128K ctx, $2/M"
143
+ },
144
+ {
145
+ value: "magistral-small",
146
+ name: "Magistral Small",
147
+ description: "Reasoning, 128K ctx, $0.50/M"
148
+ }
149
+ ]
150
+ };
151
+ function getModelsForProvider(provider) {
152
+ const key = provider === "claude-code" ? "anthropic" : provider;
153
+ return MODEL_OPTIONS[key] || [];
154
+ }
155
+
156
+ export {
157
+ getModelsForProvider
158
+ };
@@ -6,7 +6,7 @@ import {
6
6
  createEmbeddingProvider,
7
7
  hashText,
8
8
  serializeEmbedding
9
- } from "./chunk-FNV5FF35.js";
9
+ } from "./chunk-EK7M5K26.js";
10
10
  import {
11
11
  HYBRID_SEARCH_MIN_SCORE,
12
12
  KNOWLEDGE_CHUNK_SIZE,
@@ -7,7 +7,7 @@ import {
7
7
  getWalletBalance,
8
8
  invalidateTonClientCache,
9
9
  loadWallet
10
- } from "./chunk-DAMCNMYL.js";
10
+ } from "./chunk-BGC2IUM5.js";
11
11
  import {
12
12
  require_BigInteger
13
13
  } from "./chunk-TSKJCWQQ.js";
@@ -97,7 +97,6 @@ Run 'teleton setup' to create one.`);
97
97
  }
98
98
  config.telegram.session_path = expandPath(config.telegram.session_path);
99
99
  config.storage.sessions_file = expandPath(config.storage.sessions_file);
100
- config.storage.pairing_file = expandPath(config.storage.pairing_file);
101
100
  config.storage.memory_file = expandPath(config.storage.memory_file);
102
101
  if (process.env.TELETON_API_KEY) {
103
102
  config.agent.api_key = process.env.TELETON_API_KEY;
@@ -3022,11 +3021,22 @@ function numberInRange(min, max) {
3022
3021
  function enumValidator(options) {
3023
3022
  return (v) => options.includes(v) ? void 0 : `Must be one of: ${options.join(", ")}`;
3024
3023
  }
3024
+ function positiveInteger(v) {
3025
+ const n = Number(v);
3026
+ if (!Number.isInteger(n) || n <= 0) return "Must be a positive integer";
3027
+ return void 0;
3028
+ }
3029
+ function validateUrl(v) {
3030
+ if (v === "") return void 0;
3031
+ if (v.startsWith("http://") || v.startsWith("https://")) return void 0;
3032
+ return "Must be empty or start with http:// or https://";
3033
+ }
3025
3034
  var CONFIGURABLE_KEYS = {
3026
3035
  // ─── API Keys ──────────────────────────────────────────────────────
3027
3036
  "agent.api_key": {
3028
3037
  type: "string",
3029
3038
  category: "API Keys",
3039
+ label: "LLM API Key",
3030
3040
  description: "LLM provider API key",
3031
3041
  sensitive: true,
3032
3042
  validate: (v) => v.length >= 10 ? void 0 : "Must be at least 10 characters",
@@ -3036,6 +3046,7 @@ var CONFIGURABLE_KEYS = {
3036
3046
  tavily_api_key: {
3037
3047
  type: "string",
3038
3048
  category: "API Keys",
3049
+ label: "Tavily API Key",
3039
3050
  description: "Tavily API key for web search",
3040
3051
  sensitive: true,
3041
3052
  validate: (v) => v.startsWith("tvly-") ? void 0 : "Must start with 'tvly-'",
@@ -3045,6 +3056,7 @@ var CONFIGURABLE_KEYS = {
3045
3056
  tonapi_key: {
3046
3057
  type: "string",
3047
3058
  category: "API Keys",
3059
+ label: "TonAPI Key",
3048
3060
  description: "TonAPI key for higher rate limits",
3049
3061
  sensitive: true,
3050
3062
  validate: (v) => v.length >= 10 ? void 0 : "Must be at least 10 characters",
@@ -3054,6 +3066,7 @@ var CONFIGURABLE_KEYS = {
3054
3066
  "telegram.bot_token": {
3055
3067
  type: "string",
3056
3068
  category: "API Keys",
3069
+ label: "Bot Token",
3057
3070
  description: "Bot token from @BotFather",
3058
3071
  sensitive: true,
3059
3072
  validate: (v) => v.includes(":") ? void 0 : "Must contain ':' (e.g., 123456:ABC...)",
@@ -3064,6 +3077,7 @@ var CONFIGURABLE_KEYS = {
3064
3077
  "agent.provider": {
3065
3078
  type: "enum",
3066
3079
  category: "Agent",
3080
+ label: "Provider",
3067
3081
  description: "LLM provider",
3068
3082
  sensitive: false,
3069
3083
  options: [
@@ -3098,6 +3112,7 @@ var CONFIGURABLE_KEYS = {
3098
3112
  "agent.model": {
3099
3113
  type: "string",
3100
3114
  category: "Agent",
3115
+ label: "Model",
3101
3116
  description: "Main LLM model ID",
3102
3117
  sensitive: false,
3103
3118
  validate: nonEmpty,
@@ -3107,6 +3122,7 @@ var CONFIGURABLE_KEYS = {
3107
3122
  "agent.utility_model": {
3108
3123
  type: "string",
3109
3124
  category: "Agent",
3125
+ label: "Utility Model",
3110
3126
  description: "Cheap model for summarization (auto-detected if empty)",
3111
3127
  sensitive: false,
3112
3128
  validate: noValidation,
@@ -3116,6 +3132,7 @@ var CONFIGURABLE_KEYS = {
3116
3132
  "agent.temperature": {
3117
3133
  type: "number",
3118
3134
  category: "Agent",
3135
+ label: "Temperature",
3119
3136
  description: "Response creativity (0.0 = deterministic, 2.0 = max)",
3120
3137
  sensitive: false,
3121
3138
  validate: numberInRange(0, 2),
@@ -3125,6 +3142,7 @@ var CONFIGURABLE_KEYS = {
3125
3142
  "agent.max_tokens": {
3126
3143
  type: "number",
3127
3144
  category: "Agent",
3145
+ label: "Max Tokens",
3128
3146
  description: "Maximum response length in tokens",
3129
3147
  sensitive: false,
3130
3148
  validate: numberInRange(256, 128e3),
@@ -3134,16 +3152,38 @@ var CONFIGURABLE_KEYS = {
3134
3152
  "agent.max_agentic_iterations": {
3135
3153
  type: "number",
3136
3154
  category: "Agent",
3155
+ label: "Max Iterations",
3137
3156
  description: "Max tool-call loop iterations per message",
3138
3157
  sensitive: false,
3139
3158
  validate: numberInRange(1, 20),
3140
3159
  mask: identity,
3141
3160
  parse: (v) => Number(v)
3142
3161
  },
3162
+ "agent.base_url": {
3163
+ type: "string",
3164
+ category: "Agent",
3165
+ label: "API Base URL",
3166
+ description: "Base URL for local LLM server (requires restart)",
3167
+ sensitive: false,
3168
+ validate: validateUrl,
3169
+ mask: identity,
3170
+ parse: identity
3171
+ },
3172
+ "cocoon.port": {
3173
+ type: "number",
3174
+ category: "Agent",
3175
+ label: "Cocoon Port",
3176
+ description: "Cocoon proxy port (requires restart)",
3177
+ sensitive: false,
3178
+ validate: numberInRange(1, 65535),
3179
+ mask: identity,
3180
+ parse: (v) => Number(v)
3181
+ },
3143
3182
  // ─── Session ───────────────────────────────────────────────────
3144
3183
  "agent.session_reset_policy.daily_reset_enabled": {
3145
3184
  type: "boolean",
3146
3185
  category: "Session",
3186
+ label: "Daily Reset",
3147
3187
  description: "Enable daily session reset at specified hour",
3148
3188
  sensitive: false,
3149
3189
  validate: enumValidator(["true", "false"]),
@@ -3153,6 +3193,7 @@ var CONFIGURABLE_KEYS = {
3153
3193
  "agent.session_reset_policy.daily_reset_hour": {
3154
3194
  type: "number",
3155
3195
  category: "Session",
3196
+ label: "Reset Hour",
3156
3197
  description: "Hour (0-23 UTC) for daily session reset",
3157
3198
  sensitive: false,
3158
3199
  validate: numberInRange(0, 23),
@@ -3162,6 +3203,7 @@ var CONFIGURABLE_KEYS = {
3162
3203
  "agent.session_reset_policy.idle_expiry_enabled": {
3163
3204
  type: "boolean",
3164
3205
  category: "Session",
3206
+ label: "Idle Expiry",
3165
3207
  description: "Enable automatic session expiry after idle period",
3166
3208
  sensitive: false,
3167
3209
  validate: enumValidator(["true", "false"]),
@@ -3171,6 +3213,7 @@ var CONFIGURABLE_KEYS = {
3171
3213
  "agent.session_reset_policy.idle_expiry_minutes": {
3172
3214
  type: "number",
3173
3215
  category: "Session",
3216
+ label: "Idle Minutes",
3174
3217
  description: "Idle minutes before session expires (minimum 1)",
3175
3218
  sensitive: false,
3176
3219
  validate: numberInRange(1, Number.MAX_SAFE_INTEGER),
@@ -3181,6 +3224,7 @@ var CONFIGURABLE_KEYS = {
3181
3224
  "telegram.bot_username": {
3182
3225
  type: "string",
3183
3226
  category: "Telegram",
3227
+ label: "Bot Username",
3184
3228
  description: "Bot username without @",
3185
3229
  sensitive: false,
3186
3230
  validate: (v) => v.length >= 3 ? void 0 : "Must be at least 3 characters",
@@ -3190,19 +3234,23 @@ var CONFIGURABLE_KEYS = {
3190
3234
  "telegram.dm_policy": {
3191
3235
  type: "enum",
3192
3236
  category: "Telegram",
3193
- description: "DM access policy",
3237
+ label: "DM Policy",
3238
+ description: "Who can message the bot in private",
3194
3239
  sensitive: false,
3195
- options: ["pairing", "allowlist", "open", "disabled"],
3196
- validate: enumValidator(["pairing", "allowlist", "open", "disabled"]),
3240
+ options: ["open", "allowlist", "disabled"],
3241
+ optionLabels: { open: "Open", allowlist: "Allow Users", disabled: "Admin Only" },
3242
+ validate: enumValidator(["allowlist", "open", "disabled"]),
3197
3243
  mask: identity,
3198
3244
  parse: identity
3199
3245
  },
3200
3246
  "telegram.group_policy": {
3201
3247
  type: "enum",
3202
3248
  category: "Telegram",
3203
- description: "Group access policy",
3249
+ label: "Group Policy",
3250
+ description: "Which groups the bot can respond in",
3204
3251
  sensitive: false,
3205
3252
  options: ["open", "allowlist", "disabled"],
3253
+ optionLabels: { open: "Open", allowlist: "Allow Groups", disabled: "Disabled" },
3206
3254
  validate: enumValidator(["open", "allowlist", "disabled"]),
3207
3255
  mask: identity,
3208
3256
  parse: identity
@@ -3210,6 +3258,7 @@ var CONFIGURABLE_KEYS = {
3210
3258
  "telegram.require_mention": {
3211
3259
  type: "boolean",
3212
3260
  category: "Telegram",
3261
+ label: "Require Mention",
3213
3262
  description: "Require @mention in groups to respond",
3214
3263
  sensitive: false,
3215
3264
  validate: enumValidator(["true", "false"]),
@@ -3219,6 +3268,7 @@ var CONFIGURABLE_KEYS = {
3219
3268
  "telegram.owner_name": {
3220
3269
  type: "string",
3221
3270
  category: "Telegram",
3271
+ label: "Owner Name",
3222
3272
  description: "Owner's first name (used in system prompt)",
3223
3273
  sensitive: false,
3224
3274
  validate: noValidation,
@@ -3228,6 +3278,7 @@ var CONFIGURABLE_KEYS = {
3228
3278
  "telegram.owner_username": {
3229
3279
  type: "string",
3230
3280
  category: "Telegram",
3281
+ label: "Owner Username",
3231
3282
  description: "Owner's Telegram username (without @)",
3232
3283
  sensitive: false,
3233
3284
  validate: noValidation,
@@ -3237,6 +3288,7 @@ var CONFIGURABLE_KEYS = {
3237
3288
  "telegram.debounce_ms": {
3238
3289
  type: "number",
3239
3290
  category: "Telegram",
3291
+ label: "Debounce (ms)",
3240
3292
  description: "Group message debounce delay in ms (0 = disabled)",
3241
3293
  sensitive: false,
3242
3294
  validate: numberInRange(0, 1e4),
@@ -3246,6 +3298,7 @@ var CONFIGURABLE_KEYS = {
3246
3298
  "telegram.agent_channel": {
3247
3299
  type: "string",
3248
3300
  category: "Telegram",
3301
+ label: "Agent Channel",
3249
3302
  description: "Channel username for auto-publishing",
3250
3303
  sensitive: false,
3251
3304
  validate: noValidation,
@@ -3255,16 +3308,91 @@ var CONFIGURABLE_KEYS = {
3255
3308
  "telegram.typing_simulation": {
3256
3309
  type: "boolean",
3257
3310
  category: "Telegram",
3311
+ label: "Typing Simulation",
3258
3312
  description: "Simulate typing indicator before sending replies",
3259
3313
  sensitive: false,
3260
3314
  validate: enumValidator(["true", "false"]),
3261
3315
  mask: identity,
3262
3316
  parse: (v) => v === "true"
3263
3317
  },
3318
+ "telegram.owner_id": {
3319
+ type: "number",
3320
+ category: "Telegram",
3321
+ label: "Admin ID",
3322
+ description: "Primary admin Telegram user ID (auto-added to Admin IDs)",
3323
+ sensitive: false,
3324
+ validate: positiveInteger,
3325
+ mask: identity,
3326
+ parse: (v) => Number(v)
3327
+ },
3328
+ "telegram.max_message_length": {
3329
+ type: "number",
3330
+ category: "Telegram",
3331
+ label: "Max Message Length",
3332
+ description: "Maximum message length in characters",
3333
+ sensitive: false,
3334
+ validate: numberInRange(1, 32768),
3335
+ mask: identity,
3336
+ parse: (v) => Number(v)
3337
+ },
3338
+ "telegram.rate_limit_messages_per_second": {
3339
+ type: "number",
3340
+ category: "Telegram",
3341
+ label: "Rate Limit \u2014 Messages/sec",
3342
+ description: "Rate limit: messages per second (requires restart)",
3343
+ sensitive: false,
3344
+ validate: numberInRange(0.1, 10),
3345
+ mask: identity,
3346
+ parse: (v) => Number(v)
3347
+ },
3348
+ "telegram.rate_limit_groups_per_minute": {
3349
+ type: "number",
3350
+ category: "Telegram",
3351
+ label: "Rate Limit \u2014 Groups/min",
3352
+ description: "Rate limit: groups per minute (requires restart)",
3353
+ sensitive: false,
3354
+ validate: numberInRange(1, 60),
3355
+ mask: identity,
3356
+ parse: (v) => Number(v)
3357
+ },
3358
+ "telegram.admin_ids": {
3359
+ type: "array",
3360
+ itemType: "number",
3361
+ category: "Telegram",
3362
+ label: "Admin IDs",
3363
+ description: "Admin user IDs with elevated access",
3364
+ sensitive: false,
3365
+ validate: positiveInteger,
3366
+ mask: identity,
3367
+ parse: (v) => Number(v)
3368
+ },
3369
+ "telegram.allow_from": {
3370
+ type: "array",
3371
+ itemType: "number",
3372
+ category: "Telegram",
3373
+ label: "Allowed Users",
3374
+ description: "User IDs allowed for DM access",
3375
+ sensitive: false,
3376
+ validate: positiveInteger,
3377
+ mask: identity,
3378
+ parse: (v) => Number(v)
3379
+ },
3380
+ "telegram.group_allow_from": {
3381
+ type: "array",
3382
+ itemType: "number",
3383
+ category: "Telegram",
3384
+ label: "Allowed Groups",
3385
+ description: "Group IDs allowed for group access",
3386
+ sensitive: false,
3387
+ validate: positiveInteger,
3388
+ mask: identity,
3389
+ parse: (v) => Number(v)
3390
+ },
3264
3391
  // ─── Embedding ─────────────────────────────────────────────────────
3265
3392
  "embedding.provider": {
3266
3393
  type: "enum",
3267
3394
  category: "Embedding",
3395
+ label: "Embedding Provider",
3268
3396
  description: "Embedding provider for RAG",
3269
3397
  sensitive: false,
3270
3398
  options: ["local", "anthropic", "none"],
@@ -3272,10 +3400,21 @@ var CONFIGURABLE_KEYS = {
3272
3400
  mask: identity,
3273
3401
  parse: identity
3274
3402
  },
3403
+ "embedding.model": {
3404
+ type: "string",
3405
+ category: "Embedding",
3406
+ label: "Embedding Model",
3407
+ description: "Embedding model ID (requires restart)",
3408
+ sensitive: false,
3409
+ validate: noValidation,
3410
+ mask: identity,
3411
+ parse: identity
3412
+ },
3275
3413
  // ─── WebUI ─────────────────────────────────────────────────────────
3276
3414
  "webui.port": {
3277
3415
  type: "number",
3278
3416
  category: "WebUI",
3417
+ label: "WebUI Port",
3279
3418
  description: "HTTP server port (requires restart)",
3280
3419
  sensitive: false,
3281
3420
  validate: numberInRange(1024, 65535),
@@ -3285,6 +3424,7 @@ var CONFIGURABLE_KEYS = {
3285
3424
  "webui.log_requests": {
3286
3425
  type: "boolean",
3287
3426
  category: "WebUI",
3427
+ label: "Log HTTP Requests",
3288
3428
  description: "Log all HTTP requests to console",
3289
3429
  sensitive: false,
3290
3430
  validate: enumValidator(["true", "false"]),
@@ -3295,16 +3435,48 @@ var CONFIGURABLE_KEYS = {
3295
3435
  "deals.enabled": {
3296
3436
  type: "boolean",
3297
3437
  category: "Deals",
3438
+ label: "Deals Enabled",
3298
3439
  description: "Enable the deals/escrow module",
3299
3440
  sensitive: false,
3300
3441
  validate: enumValidator(["true", "false"]),
3301
3442
  mask: identity,
3302
3443
  parse: (v) => v === "true"
3303
3444
  },
3445
+ "deals.expiry_seconds": {
3446
+ type: "number",
3447
+ category: "Deals",
3448
+ label: "Deal Expiry",
3449
+ description: "Deal expiry timeout in seconds",
3450
+ sensitive: false,
3451
+ validate: numberInRange(10, 3600),
3452
+ mask: identity,
3453
+ parse: (v) => Number(v)
3454
+ },
3455
+ "deals.buy_max_floor_percent": {
3456
+ type: "number",
3457
+ category: "Deals",
3458
+ label: "Buy Max Floor %",
3459
+ description: "Maximum floor % for buy deals",
3460
+ sensitive: false,
3461
+ validate: numberInRange(1, 100),
3462
+ mask: identity,
3463
+ parse: (v) => Number(v)
3464
+ },
3465
+ "deals.sell_min_floor_percent": {
3466
+ type: "number",
3467
+ category: "Deals",
3468
+ label: "Sell Min Floor %",
3469
+ description: "Minimum floor % for sell deals",
3470
+ sensitive: false,
3471
+ validate: numberInRange(100, 500),
3472
+ mask: identity,
3473
+ parse: (v) => Number(v)
3474
+ },
3304
3475
  // ─── Developer ─────────────────────────────────────────────────────
3305
3476
  "dev.hot_reload": {
3306
3477
  type: "boolean",
3307
3478
  category: "Developer",
3479
+ label: "Hot Reload",
3308
3480
  description: "Watch ~/.teleton/plugins/ for live changes",
3309
3481
  sensitive: false,
3310
3482
  validate: enumValidator(["true", "false"]),