talon-agent 1.12.0 → 1.34.0
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/README.md +111 -52
- package/package.json +39 -12
- package/prompts/README.md +112 -0
- package/prompts/base.md +12 -12
- package/prompts/discord.md +10 -47
- package/prompts/heartbeat.md +23 -8
- package/prompts/identity.md +12 -22
- package/prompts/native.md +23 -0
- package/prompts/system/contract-text-or-tools.md +8 -0
- package/prompts/system/contract-text-preferred.md +5 -0
- package/prompts/system/contract-tool-only.md +10 -0
- package/prompts/system/cron.md +3 -0
- package/prompts/system/daily-memory.md +3 -0
- package/prompts/system/goals.md +7 -0
- package/prompts/system/heartbeat-agent.md +44 -0
- package/prompts/system/persistent-memory.md +8 -0
- package/prompts/system/skills.md +9 -0
- package/prompts/system/triggers.md +5 -0
- package/prompts/system/workspace.md +9 -0
- package/prompts/teams.md +4 -14
- package/prompts/telegram.md +17 -89
- package/src/app.ts +278 -0
- package/src/backend/claude-sdk/constants.ts +22 -10
- package/src/backend/claude-sdk/factory.ts +79 -22
- package/src/backend/claude-sdk/handler.ts +431 -160
- package/src/backend/claude-sdk/index.ts +6 -2
- package/src/backend/claude-sdk/mcp-ready.ts +54 -0
- package/src/backend/claude-sdk/model-drift.ts +65 -0
- package/src/backend/claude-sdk/model-provider.ts +12 -6
- package/src/backend/claude-sdk/models/convert.ts +169 -0
- package/src/backend/claude-sdk/models/discovery.ts +203 -0
- package/src/backend/claude-sdk/models/index.ts +18 -0
- package/src/backend/claude-sdk/models/parsing.ts +264 -0
- package/src/backend/claude-sdk/models/static.ts +45 -0
- package/src/backend/claude-sdk/one-shot.ts +19 -13
- package/src/backend/claude-sdk/options.ts +228 -104
- package/src/backend/claude-sdk/state.ts +1 -1
- package/src/backend/claude-sdk/stream.ts +153 -45
- package/src/backend/claude-sdk/warm.ts +12 -5
- package/src/backend/codex/auth.ts +216 -40
- package/src/backend/codex/constants.ts +63 -22
- package/src/backend/codex/discovery.ts +427 -0
- package/src/backend/codex/factory.ts +63 -33
- package/src/backend/codex/handler/events.ts +239 -0
- package/src/backend/codex/handler/index.ts +15 -0
- package/src/backend/codex/handler/message.ts +669 -0
- package/src/backend/codex/handler/state.ts +14 -0
- package/src/backend/codex/handler/usage.ts +68 -0
- package/src/backend/codex/index.ts +2 -2
- package/src/backend/codex/init.ts +92 -11
- package/src/backend/codex/mcp-config.ts +89 -62
- package/src/backend/codex/models.ts +305 -54
- package/src/backend/codex/oauth-incompat.ts +302 -0
- package/src/backend/codex/one-shot.ts +91 -8
- package/src/backend/codex/state.ts +54 -3
- package/src/backend/codex/token-usage.ts +434 -0
- package/src/backend/kilo/factory.ts +60 -35
- package/src/backend/kilo/handler/index.ts +13 -0
- package/src/backend/kilo/handler/message.ts +317 -0
- package/src/backend/kilo/handler/state.ts +14 -0
- package/src/backend/kilo/handler/turn.ts +321 -0
- package/src/backend/kilo/index.ts +5 -5
- package/src/backend/kilo/model-provider.ts +26 -168
- package/src/backend/kilo/models/index.ts +52 -0
- package/src/backend/kilo/one-shot.ts +20 -142
- package/src/backend/kilo/server.ts +14 -21
- package/src/backend/openai-agents/builtins.ts +215 -114
- package/src/backend/openai-agents/constants.ts +41 -15
- package/src/backend/openai-agents/discovery.ts +332 -0
- package/src/backend/openai-agents/factory.ts +66 -28
- package/src/backend/openai-agents/handler/events.ts +170 -0
- package/src/backend/openai-agents/handler/index.ts +13 -0
- package/src/backend/openai-agents/handler/message.ts +527 -0
- package/src/backend/openai-agents/handler/state.ts +13 -0
- package/src/backend/openai-agents/index.ts +22 -4
- package/src/backend/openai-agents/init.ts +51 -88
- package/src/backend/openai-agents/mcp-pool.ts +252 -0
- package/src/backend/openai-agents/models.ts +118 -11
- package/src/backend/openai-agents/session.ts +277 -0
- package/src/backend/openai-agents/state.ts +82 -11
- package/src/backend/opencode/factory.ts +54 -25
- package/src/backend/opencode/handler/index.ts +13 -0
- package/src/backend/opencode/handler/message.ts +325 -0
- package/src/backend/opencode/handler/state.ts +14 -0
- package/src/backend/opencode/handler/turn.ts +304 -0
- package/src/backend/opencode/index.ts +2 -2
- package/src/backend/opencode/model-provider.ts +26 -168
- package/src/backend/opencode/models/index.ts +51 -0
- package/src/backend/opencode/one-shot.ts +20 -137
- package/src/backend/opencode/server.ts +12 -11
- package/src/backend/remote-server/client.ts +13 -6
- package/src/backend/remote-server/events.ts +59 -9
- package/src/backend/remote-server/lifecycle.ts +3 -1
- package/src/backend/remote-server/mcp.ts +52 -19
- package/src/backend/remote-server/model-catalog/catalog.ts +270 -0
- package/src/backend/remote-server/model-catalog/index.ts +100 -0
- package/src/backend/remote-server/model-catalog/presentation.ts +298 -0
- package/src/backend/remote-server/model-catalog/provider.ts +193 -0
- package/src/backend/remote-server/model-catalog/resolve.ts +225 -0
- package/src/backend/remote-server/model-catalog/types.ts +136 -0
- package/src/backend/remote-server/one-shot.ts +225 -0
- package/src/backend/remote-server/session-helpers.ts +3 -4
- package/src/backend/remote-server/state.ts +1 -1
- package/src/backend/shared/delivery-contract.ts +161 -0
- package/src/backend/shared/delivery.ts +49 -0
- package/src/backend/shared/flow-violation.ts +38 -7
- package/src/backend/shared/frontends.ts +66 -0
- package/src/backend/shared/handle-retry.ts +244 -0
- package/src/backend/shared/handler-to-events.ts +186 -0
- package/src/backend/shared/handler-types.ts +57 -0
- package/src/backend/shared/index.ts +51 -5
- package/src/backend/shared/metrics.ts +199 -0
- package/src/backend/shared/model-retry.ts +1 -1
- package/src/backend/shared/prompt-format.ts +69 -0
- package/src/backend/shared/session-name.ts +1 -1
- package/src/backend/shared/stream-state.ts +36 -2
- package/src/backend/shared/system-prompt.ts +200 -23
- package/src/bootstrap.ts +338 -38
- package/src/cli/chat.ts +49 -0
- package/src/cli/config-view.ts +100 -0
- package/src/cli/config.ts +105 -0
- package/src/cli/context.ts +23 -0
- package/src/cli/daemon.ts +95 -0
- package/src/cli/doctor.ts +53 -0
- package/src/cli/index.ts +139 -0
- package/src/cli/logs.ts +60 -0
- package/src/cli/menu.ts +104 -0
- package/src/cli/setup.ts +455 -0
- package/src/cli/status.ts +75 -0
- package/src/cli.ts +20 -1211
- package/src/core/agent-runtime/README.md +173 -0
- package/src/{backend/registry.ts → core/agent-runtime/backend-registry.ts} +15 -6
- package/src/core/agent-runtime/capabilities.ts +330 -0
- package/src/core/agent-runtime/contract-tests.ts +378 -0
- package/src/core/agent-runtime/events.ts +291 -0
- package/src/core/agent-runtime/index.ts +62 -0
- package/src/core/agent-runtime/model-ref.ts +130 -0
- package/src/core/background/cron.ts +469 -0
- package/src/core/{dream.ts → background/dream.ts} +118 -53
- package/src/core/background/heartbeat/agent.ts +333 -0
- package/src/core/background/heartbeat/index.ts +25 -0
- package/src/core/background/heartbeat/scheduler.ts +211 -0
- package/src/core/background/heartbeat/state.ts +153 -0
- package/src/core/background/index.ts +21 -0
- package/src/core/background/isolated-agent.ts +115 -0
- package/src/core/background/job-health.ts +140 -0
- package/src/core/background/job-oneshot.ts +165 -0
- package/src/core/background/job-prompt.ts +54 -0
- package/src/core/{pulse.ts → background/pulse.ts} +6 -5
- package/src/core/background/triggers/command.ts +60 -0
- package/src/core/background/triggers/exit.ts +202 -0
- package/src/core/background/triggers/index.ts +38 -0
- package/src/core/background/triggers/output.ts +142 -0
- package/src/core/background/triggers/resume.ts +127 -0
- package/src/core/background/triggers/spawn.ts +282 -0
- package/src/core/background/triggers/state.ts +52 -0
- package/src/core/constants.ts +57 -28
- package/src/core/daemon/control.ts +229 -0
- package/src/core/daemon/discovery.ts +169 -0
- package/src/core/daemon/pidfile.ts +98 -0
- package/src/core/doctor.ts +459 -0
- package/src/core/engine/backend-controller/holders.ts +17 -0
- package/src/core/engine/backend-controller/index.ts +71 -0
- package/src/core/engine/backend-controller/legacy.ts +111 -0
- package/src/core/engine/backend-controller/pool.ts +296 -0
- package/src/core/engine/backend-controller/rebind.ts +205 -0
- package/src/core/engine/backend-controller/state.ts +150 -0
- package/src/core/engine/backend-controller/types.ts +51 -0
- package/src/core/engine/dispatcher.ts +68 -0
- package/src/core/engine/gateway-actions/cron.ts +518 -0
- package/src/core/engine/gateway-actions/fetch-url.ts +120 -0
- package/src/core/engine/gateway-actions/goals.ts +178 -0
- package/src/core/engine/gateway-actions/history.ts +53 -0
- package/src/core/engine/gateway-actions/index.ts +60 -0
- package/src/core/engine/gateway-actions/models.ts +120 -0
- package/src/core/engine/gateway-actions/plugins.ts +83 -0
- package/src/core/engine/gateway-actions/scripts.ts +127 -0
- package/src/core/engine/gateway-actions/shared.ts +66 -0
- package/src/core/engine/gateway-actions/skills.ts +120 -0
- package/src/core/engine/gateway-actions/triggers.ts +237 -0
- package/src/core/engine/gateway-actions/types.ts +18 -0
- package/src/core/{gateway.ts → engine/gateway.ts} +223 -60
- package/src/core/engine/index.ts +20 -0
- package/src/core/engine/model-audit.ts +121 -0
- package/src/core/errors.ts +68 -6
- package/src/core/mcp-hub/children.ts +254 -0
- package/src/core/mcp-hub/index.ts +335 -0
- package/src/core/mcp-hub/proxy-server.ts +45 -0
- package/src/core/mcp-hub/talon-server.ts +71 -0
- package/src/core/memory/retrieval.ts +90 -0
- package/src/core/models/active-model.ts +441 -0
- package/src/core/{models.ts → models/catalog.ts} +6 -0
- package/src/core/models/index.ts +17 -0
- package/src/core/models/reasoning-levels.ts +57 -0
- package/src/core/plugin/actions.ts +32 -0
- package/src/core/plugin/builtins.ts +162 -0
- package/src/core/plugin/index.ts +37 -0
- package/src/core/plugin/loader.ts +289 -0
- package/src/core/plugin/mcp.ts +86 -0
- package/src/core/plugin/registry.ts +124 -0
- package/src/core/plugin/types.ts +126 -0
- package/src/core/prompt/assemble.ts +273 -0
- package/src/core/prompt/disk-prompts.ts +41 -0
- package/src/core/prompt/embed.ts +107 -0
- package/src/core/prompt/embedded-prompts.ts +85 -0
- package/src/core/prompt/index.ts +30 -0
- package/src/core/prompt/templates.ts +124 -0
- package/src/core/prompt/workspace-listing.ts +91 -0
- package/src/core/scripting/lua-runner.ts +210 -0
- package/src/core/scripts/runner.ts +125 -0
- package/src/core/soul/README.md +110 -0
- package/src/core/soul/RESEARCH.md +98 -0
- package/src/core/soul/associative.ts +98 -0
- package/src/core/soul/centrality.ts +98 -0
- package/src/core/soul/cluster.ts +83 -0
- package/src/core/soul/compiler.ts +207 -0
- package/src/core/soul/consolidate.ts +179 -0
- package/src/core/soul/critic.ts +159 -0
- package/src/core/soul/dag.ts +265 -0
- package/src/core/soul/delta.ts +123 -0
- package/src/core/soul/drift.ts +99 -0
- package/src/core/soul/embedder.ts +129 -0
- package/src/core/soul/emergent-critic.ts +96 -0
- package/src/core/soul/forgetting.ts +131 -0
- package/src/core/soul/governance.ts +93 -0
- package/src/core/soul/hash.ts +97 -0
- package/src/core/soul/hdc.ts +154 -0
- package/src/core/soul/index.ts +140 -0
- package/src/core/soul/kernel.ts +540 -0
- package/src/core/soul/lattice.ts +103 -0
- package/src/core/soul/lens.ts +110 -0
- package/src/core/soul/projector.ts +240 -0
- package/src/core/soul/reflect.ts +170 -0
- package/src/core/soul/reflex.ts +164 -0
- package/src/core/soul/retrieve.ts +146 -0
- package/src/core/soul/salience.ts +142 -0
- package/src/core/soul/service.ts +204 -0
- package/src/core/soul/settings.ts +47 -0
- package/src/core/soul/signals.ts +117 -0
- package/src/core/soul/talon-embedder.ts +80 -0
- package/src/core/soul/taps.ts +199 -0
- package/src/core/soul/types.ts +298 -0
- package/src/core/soul/valence.ts +83 -0
- package/src/core/tools/goals.ts +117 -0
- package/src/core/tools/index.ts +10 -0
- package/src/core/tools/mcp-env.ts +94 -0
- package/src/core/tools/mcp-server.ts +27 -4
- package/src/core/tools/messaging.ts +122 -29
- package/src/core/tools/models.ts +39 -0
- package/src/core/tools/scheduling.ts +133 -14
- package/src/core/tools/schemas.ts +16 -4
- package/src/core/tools/scripts.ts +78 -0
- package/src/core/tools/skills.ts +90 -0
- package/src/core/tools/stickers.ts +1 -1
- package/src/core/tools/triggers.ts +19 -3
- package/src/core/tools/types.ts +6 -6
- package/src/core/types.ts +62 -112
- package/src/core/update/self-update.ts +269 -0
- package/src/core/weaver/index.ts +10 -0
- package/src/core/weaver/loom.ts +125 -0
- package/src/core/weaver/thread-session.ts +51 -0
- package/src/core/weaver/thread.ts +196 -0
- package/src/core/weaver/weaver.ts +357 -0
- package/src/frontend/discord/actions/chat-info.ts +268 -0
- package/src/frontend/discord/actions/index.ts +77 -0
- package/src/frontend/discord/actions/media.ts +190 -0
- package/src/frontend/discord/actions/messaging.ts +277 -0
- package/src/frontend/discord/actions/shared.ts +100 -0
- package/src/frontend/discord/actions/types.ts +33 -0
- package/src/frontend/discord/admin.ts +13 -23
- package/src/frontend/discord/callbacks/autocomplete.ts +55 -0
- package/src/frontend/discord/{callbacks.ts → callbacks/components.ts} +150 -190
- package/src/frontend/discord/callbacks/index.ts +14 -0
- package/src/frontend/discord/callbacks/modals.ts +76 -0
- package/src/frontend/discord/callbacks/shared.ts +22 -0
- package/src/frontend/discord/commands/admin.ts +88 -0
- package/src/frontend/discord/commands/definitions.ts +200 -0
- package/src/frontend/discord/commands/index.ts +19 -0
- package/src/frontend/discord/commands/info.ts +106 -0
- package/src/frontend/discord/commands/router.ts +149 -0
- package/src/frontend/discord/commands/session.ts +89 -0
- package/src/frontend/discord/commands/settings.ts +405 -0
- package/src/frontend/discord/commands/shared.ts +50 -0
- package/src/frontend/discord/formatting.ts +8 -34
- package/src/frontend/discord/handlers/access.ts +248 -0
- package/src/frontend/discord/handlers/context.ts +161 -0
- package/src/frontend/discord/handlers/delivery.ts +94 -0
- package/src/frontend/discord/handlers/index.ts +34 -0
- package/src/frontend/discord/handlers/messages.ts +120 -0
- package/src/frontend/discord/handlers/queue.ts +135 -0
- package/src/frontend/discord/handlers/registry.ts +29 -0
- package/src/frontend/discord/handlers/state.ts +94 -0
- package/src/frontend/discord/helpers.ts +46 -57
- package/src/frontend/discord/index.ts +10 -7
- package/src/frontend/discord/middleware.ts +2 -2
- package/src/frontend/native/actions.ts +133 -0
- package/src/frontend/native/chats.ts +146 -0
- package/src/frontend/native/discovery.ts +50 -0
- package/src/frontend/native/index.ts +1227 -0
- package/src/frontend/native/logs.ts +95 -0
- package/src/frontend/native/protocol.ts +253 -0
- package/src/frontend/native/server.ts +612 -0
- package/src/frontend/native/settings.ts +205 -0
- package/src/frontend/native/turn-meta.ts +43 -0
- package/src/frontend/shared/format.ts +51 -0
- package/src/frontend/shared/reasoning-levels.ts +46 -0
- package/src/frontend/shared/session-status.ts +189 -0
- package/src/frontend/shared/status-context.ts +125 -0
- package/src/frontend/teams/actions.ts +7 -5
- package/src/frontend/teams/formatting.ts +7 -18
- package/src/frontend/teams/graph.ts +2 -1
- package/src/frontend/teams/index.ts +76 -54
- package/src/frontend/telegram/actions/chat-info.ts +323 -0
- package/src/frontend/telegram/actions/index.ts +68 -0
- package/src/frontend/telegram/actions/media.ts +224 -0
- package/src/frontend/telegram/actions/messaging.ts +295 -0
- package/src/frontend/telegram/actions/shared.ts +58 -0
- package/src/frontend/telegram/actions/types.ts +31 -0
- package/src/frontend/telegram/admin.ts +12 -22
- package/src/frontend/telegram/callbacks/effort.ts +68 -0
- package/src/frontend/telegram/callbacks/index.ts +68 -0
- package/src/frontend/telegram/callbacks/model.ts +311 -0
- package/src/frontend/telegram/callbacks/pulse.ts +50 -0
- package/src/frontend/telegram/callbacks/settings.ts +177 -0
- package/src/frontend/telegram/callbacks/shared.ts +71 -0
- package/src/frontend/telegram/commands/admin.ts +226 -0
- package/src/frontend/telegram/commands/definitions.ts +60 -0
- package/src/frontend/telegram/commands/index.ts +39 -0
- package/src/frontend/telegram/commands/info.ts +125 -0
- package/src/frontend/telegram/commands/session.ts +77 -0
- package/src/frontend/telegram/commands/settings.ts +345 -0
- package/src/frontend/telegram/commands/state.ts +34 -0
- package/src/frontend/telegram/formatting.ts +14 -25
- package/src/frontend/telegram/handlers/access.ts +287 -0
- package/src/frontend/telegram/handlers/context.ts +210 -0
- package/src/frontend/telegram/handlers/delivery.ts +236 -0
- package/src/frontend/telegram/handlers/index.ts +39 -0
- package/src/frontend/telegram/handlers/messages.ts +477 -0
- package/src/frontend/telegram/handlers/queue.ts +241 -0
- package/src/frontend/telegram/handlers/state.ts +75 -0
- package/src/frontend/telegram/helpers/diagnostics.ts +188 -0
- package/src/frontend/telegram/helpers/format.ts +41 -0
- package/src/frontend/telegram/helpers/index.ts +13 -0
- package/src/frontend/telegram/{helpers.ts → helpers/menu.ts} +209 -210
- package/src/frontend/telegram/index.ts +24 -27
- package/src/frontend/telegram/middleware.ts +16 -3
- package/src/frontend/telegram/model-callbacks.ts +14 -0
- package/src/frontend/telegram/model-menu.ts +317 -0
- package/src/frontend/telegram/sticker-library.ts +178 -0
- package/src/frontend/telegram/userbot.ts +2 -44
- package/src/frontend/terminal/commands.ts +47 -41
- package/src/frontend/terminal/index.ts +46 -31
- package/src/frontend/terminal/input.ts +5 -0
- package/src/frontend/terminal/renderer.ts +4 -2
- package/src/index.ts +13 -171
- package/src/login.ts +3 -2
- package/src/native/blake3-wasm-bytes.ts +7 -0
- package/src/native/blake3.ts +234 -0
- package/src/native/htmlents-wasm-bytes.ts +7 -0
- package/src/native/htmlents.ts +56 -0
- package/src/native/prelude.d.mts +168 -0
- package/src/native/prelude.mjs +1561 -0
- package/src/native/registry.ts +142 -0
- package/src/native/runtime.ts +164 -0
- package/src/native/scheduler-core/gleam.d.mts +2 -0
- package/src/native/scheduler-core/gleam.mjs +1 -0
- package/src/native/scheduler-core/scheduler_core.d.mts +76 -0
- package/src/native/scheduler-core/scheduler_core.mjs +252 -0
- package/src/native/scheduler-core.ts +124 -0
- package/src/native/sqlguard-wasm-bytes.ts +7 -0
- package/src/native/sqlguard.ts +107 -0
- package/src/native/strsim-wasm-bytes.ts +7 -0
- package/src/native/strsim.ts +98 -0
- package/src/native/textops-wasm-bytes.ts +7 -0
- package/src/native/textops.ts +83 -0
- package/src/native/warden.ts +287 -0
- package/src/plugins/github/index.ts +1 -1
- package/src/plugins/mempalace/index.ts +1 -1
- package/src/plugins/playwright/index.ts +1 -1
- package/src/storage/chat-settings.ts +335 -85
- package/src/storage/cron-store.ts +266 -109
- package/src/storage/daily-log.ts +15 -3
- package/src/storage/db.ts +206 -0
- package/src/storage/goal-store.ts +186 -0
- package/src/storage/history.ts +137 -188
- package/src/storage/kv.ts +52 -0
- package/src/storage/legacy-import.ts +47 -0
- package/src/storage/media-index.ts +118 -61
- package/src/storage/repositories/chat-settings-repo.ts +60 -0
- package/src/storage/repositories/cron-repo.ts +128 -0
- package/src/storage/repositories/goals-repo.ts +122 -0
- package/src/storage/repositories/history-repo.ts +207 -0
- package/src/storage/repositories/kv-repo.ts +25 -0
- package/src/storage/repositories/media-index-repo.ts +147 -0
- package/src/storage/repositories/scripts-repo.ts +81 -0
- package/src/storage/repositories/sessions-repo.ts +129 -0
- package/src/storage/repositories/triggers-repo.ts +158 -0
- package/src/storage/repositories/turn-meta-repo.ts +32 -0
- package/src/storage/scheduled-store.ts +84 -0
- package/src/storage/script-store.ts +198 -0
- package/src/storage/sessions.ts +227 -102
- package/src/storage/skill-store.ts +325 -0
- package/src/storage/sql/README.md +18 -0
- package/src/storage/sql/chat-settings.sql +11 -0
- package/src/storage/sql/cron.sql +40 -0
- package/src/storage/sql/db.sql +11 -0
- package/src/storage/sql/embed.ts +118 -0
- package/src/storage/sql/goals.sql +41 -0
- package/src/storage/sql/history.sql +83 -0
- package/src/storage/sql/kv.sql +11 -0
- package/src/storage/sql/media-index.sql +45 -0
- package/src/storage/sql/schema.sql +233 -0
- package/src/storage/sql/scripts.sql +28 -0
- package/src/storage/sql/sessions.sql +22 -0
- package/src/storage/sql/statements.generated.ts +500 -0
- package/src/storage/sql/triggers.sql +69 -0
- package/src/storage/sql/turn-meta.sql +24 -0
- package/src/storage/sticker-store.ts +141 -0
- package/src/storage/trigger-store.ts +104 -126
- package/src/storage/turn-meta.ts +118 -0
- package/src/util/chat-id.ts +30 -0
- package/src/util/config.ts +313 -195
- package/src/util/fs-path.ts +32 -0
- package/src/util/log.ts +53 -31
- package/src/util/mcp-launcher.ts +351 -33
- package/src/util/paths.ts +45 -17
- package/src/util/tail-file.ts +24 -0
- package/src/util/workspace.ts +161 -10
- package/tsconfig.json +1 -0
- package/src/backend/claude-sdk/models.ts +0 -501
- package/src/backend/codex/handler.ts +0 -595
- package/src/backend/kilo/handler.ts +0 -707
- package/src/backend/kilo/models.ts +0 -762
- package/src/backend/openai-agents/handler.ts +0 -539
- package/src/backend/openai-agents/mcp.ts +0 -139
- package/src/backend/opencode/handler.ts +0 -663
- package/src/backend/opencode/models.ts +0 -741
- package/src/core/cron.ts +0 -184
- package/src/core/dispatcher.ts +0 -144
- package/src/core/gateway-actions.ts +0 -603
- package/src/core/heartbeat.ts +0 -575
- package/src/core/plugin.ts +0 -776
- package/src/core/triggers.ts +0 -640
- package/src/frontend/discord/actions.ts +0 -729
- package/src/frontend/discord/commands.ts +0 -1036
- package/src/frontend/discord/handlers.ts +0 -798
- package/src/frontend/telegram/actions.ts +0 -731
- package/src/frontend/telegram/callbacks.ts +0 -419
- package/src/frontend/telegram/commands.ts +0 -642
- package/src/frontend/telegram/handlers.ts +0 -1352
- package/src/util/mcp-launcher.mjs +0 -140
|
@@ -7,11 +7,28 @@
|
|
|
7
7
|
|
|
8
8
|
import pc from "picocolors";
|
|
9
9
|
import type { TalonConfig } from "../../util/config.js";
|
|
10
|
-
import type {
|
|
10
|
+
import type { Backend } from "../../core/agent-runtime/capabilities.js";
|
|
11
11
|
import type { Renderer } from "./renderer.js";
|
|
12
12
|
import { formatTimeAgo } from "./renderer.js";
|
|
13
13
|
import { isTerminalChatId } from "../../util/chat-id.js";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
resolveModel as coreResolveModel,
|
|
16
|
+
getModels,
|
|
17
|
+
} from "../../core/models/catalog.js";
|
|
18
|
+
import { buildCacheDisplay } from "../shared/status-context.js";
|
|
19
|
+
import {
|
|
20
|
+
getChatSettings,
|
|
21
|
+
setChatModel,
|
|
22
|
+
setChatEffort,
|
|
23
|
+
resolveModelName,
|
|
24
|
+
} from "../../storage/chat-settings.js";
|
|
25
|
+
import {
|
|
26
|
+
getAllSessions,
|
|
27
|
+
getSession,
|
|
28
|
+
getSessionInfo,
|
|
29
|
+
setSessionName,
|
|
30
|
+
} from "../../storage/sessions.js";
|
|
31
|
+
import { getLoadedPlugins } from "../../core/plugin/index.js";
|
|
15
32
|
|
|
16
33
|
// ── Types ────────────────────────────────────────────────────────────────────
|
|
17
34
|
|
|
@@ -26,7 +43,7 @@ export type CommandContext = {
|
|
|
26
43
|
/** Close the terminal (for /quit). */
|
|
27
44
|
close: () => void;
|
|
28
45
|
/** AI backend (available after bootstrap). */
|
|
29
|
-
backend?:
|
|
46
|
+
backend?: Backend | null;
|
|
30
47
|
};
|
|
31
48
|
|
|
32
49
|
export type CommandHandler = (
|
|
@@ -96,8 +113,6 @@ export function registerBuiltinCommands(): void {
|
|
|
96
113
|
argHint: "[name]",
|
|
97
114
|
description: "Switch model",
|
|
98
115
|
async handler(args, ctx) {
|
|
99
|
-
const { getChatSettings, setChatModel, resolveModelName } =
|
|
100
|
-
await import("../../storage/chat-settings.js");
|
|
101
116
|
const currentModel =
|
|
102
117
|
getChatSettings(ctx.chatId()).model ?? ctx.config.model;
|
|
103
118
|
const be = ctx.backend;
|
|
@@ -106,7 +121,7 @@ export function registerBuiltinCommands(): void {
|
|
|
106
121
|
const lowerArgs = trimmedArgs.toLowerCase();
|
|
107
122
|
|
|
108
123
|
if (!trimmedArgs) {
|
|
109
|
-
const modelInfo = await be?.
|
|
124
|
+
const modelInfo = await be?.models?.getRawModelInfo?.(currentModel);
|
|
110
125
|
const displayName = modelInfo?.displayName ?? currentModel;
|
|
111
126
|
const details = modelInfo
|
|
112
127
|
? [
|
|
@@ -125,8 +140,8 @@ export function registerBuiltinCommands(): void {
|
|
|
125
140
|
` Context window: ${modelInfo.contextWindow.toLocaleString()}`,
|
|
126
141
|
);
|
|
127
142
|
}
|
|
128
|
-
if (be?.getProviders) {
|
|
129
|
-
const providers = await be.getProviders();
|
|
143
|
+
if (be?.models?.getProviders) {
|
|
144
|
+
const providers = await be.models?.getProviders();
|
|
130
145
|
const connected = providers.filter((p) => p.connected);
|
|
131
146
|
if (connected.length > 0) {
|
|
132
147
|
ctx.renderer.writeln(
|
|
@@ -149,9 +164,9 @@ export function registerBuiltinCommands(): void {
|
|
|
149
164
|
}
|
|
150
165
|
|
|
151
166
|
if (lowerArgs === "free" || lowerArgs === "list" || lowerArgs === "all") {
|
|
152
|
-
if (be?.listModels) {
|
|
167
|
+
if (be?.models?.listModels) {
|
|
153
168
|
const filter = lowerArgs === "free" ? "free" : "all";
|
|
154
|
-
const { models, total } = await be.listModels(filter);
|
|
169
|
+
const { models, total } = await be.models.listModels(filter);
|
|
155
170
|
const list = models.slice(0, 20);
|
|
156
171
|
ctx.renderer.writeSystem(
|
|
157
172
|
`${filter === "free" ? "Free" : "Available"} models (${total})`,
|
|
@@ -165,7 +180,6 @@ export function registerBuiltinCommands(): void {
|
|
|
165
180
|
ctx.renderer.writeln(` …and ${total - list.length} more`);
|
|
166
181
|
}
|
|
167
182
|
} else {
|
|
168
|
-
const { getModels } = await import("../../core/models.js");
|
|
169
183
|
const names = getModels()
|
|
170
184
|
.map((m) => m.aliases[0] ?? m.id)
|
|
171
185
|
.join(", ");
|
|
@@ -176,8 +190,8 @@ export function registerBuiltinCommands(): void {
|
|
|
176
190
|
}
|
|
177
191
|
|
|
178
192
|
if (lowerArgs === "providers") {
|
|
179
|
-
if (be?.getProviders) {
|
|
180
|
-
const providers = await be.getProviders();
|
|
193
|
+
if (be?.models?.getProviders) {
|
|
194
|
+
const providers = await be.models?.getProviders();
|
|
181
195
|
ctx.renderer.writeSystem(`Providers (${providers.length})`);
|
|
182
196
|
for (const p of providers.slice(0, 20)) {
|
|
183
197
|
ctx.renderer.writeln(
|
|
@@ -192,11 +206,11 @@ export function registerBuiltinCommands(): void {
|
|
|
192
206
|
}
|
|
193
207
|
|
|
194
208
|
// Resolve model query via backend
|
|
195
|
-
if (be?.
|
|
196
|
-
const resolution = await be.
|
|
209
|
+
if (be?.models?.resolveModelInfo) {
|
|
210
|
+
const resolution = await be.models?.resolveModelInfo(trimmedArgs);
|
|
197
211
|
if (resolution.kind === "missing") {
|
|
198
212
|
const msg =
|
|
199
|
-
be.formatModelError?.(trimmedArgs, resolution) ??
|
|
213
|
+
be.models?.formatModelError?.(trimmedArgs, resolution) ??
|
|
200
214
|
`No model matched "${trimmedArgs}".`;
|
|
201
215
|
ctx.renderer.writeError(msg);
|
|
202
216
|
ctx.reprompt();
|
|
@@ -237,8 +251,6 @@ export function registerBuiltinCommands(): void {
|
|
|
237
251
|
argHint: "[lvl]",
|
|
238
252
|
description: "Thinking effort (off/low/medium/high/max)",
|
|
239
253
|
async handler(args, ctx) {
|
|
240
|
-
const { getChatSettings, setChatEffort } =
|
|
241
|
-
await import("../../storage/chat-settings.js");
|
|
242
254
|
if (!args) {
|
|
243
255
|
ctx.renderer.writeSystem(
|
|
244
256
|
`Effort: ${getChatSettings(ctx.chatId()).effort ?? "adaptive"}`,
|
|
@@ -260,10 +272,6 @@ export function registerBuiltinCommands(): void {
|
|
|
260
272
|
name: "status",
|
|
261
273
|
description: "Session stats",
|
|
262
274
|
async handler(_args, ctx) {
|
|
263
|
-
const { getSessionInfo } = await import("../../storage/sessions.js");
|
|
264
|
-
const { getChatSettings } =
|
|
265
|
-
await import("../../storage/chat-settings.js");
|
|
266
|
-
const { getLoadedPlugins } = await import("../../core/plugin.js");
|
|
267
275
|
const info = getSessionInfo(ctx.chatId());
|
|
268
276
|
const u = info.usage;
|
|
269
277
|
const be = ctx.backend;
|
|
@@ -279,9 +287,9 @@ export function registerBuiltinCommands(): void {
|
|
|
279
287
|
const nameStr = info.sessionName ? `"${info.sessionName}" · ` : "";
|
|
280
288
|
|
|
281
289
|
// Enrich from backend when available
|
|
282
|
-
if (be?.getSessionSnapshot && info.sessionId) {
|
|
283
|
-
const snap = await be
|
|
284
|
-
|
|
290
|
+
if (be?.usage?.getSessionSnapshot && info.sessionId) {
|
|
291
|
+
const snap = await be.usage
|
|
292
|
+
?.getSessionSnapshot(info.sessionId)
|
|
285
293
|
.catch(() => undefined);
|
|
286
294
|
if (snap) {
|
|
287
295
|
displayInputTokens = snap.inputTokens ?? displayInputTokens;
|
|
@@ -291,28 +299,29 @@ export function registerBuiltinCommands(): void {
|
|
|
291
299
|
}
|
|
292
300
|
}
|
|
293
301
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
302
|
+
const cache = buildCacheDisplay({
|
|
303
|
+
cacheMetrics: be?.cacheMetrics,
|
|
304
|
+
inputTokens: displayInputTokens,
|
|
305
|
+
cacheRead: displayCacheRead,
|
|
306
|
+
cacheWrite: displayCacheWrite,
|
|
307
|
+
});
|
|
308
|
+
if (be?.models?.getRawModelInfo) {
|
|
309
|
+
const modelInfo = await be.models
|
|
310
|
+
?.getRawModelInfo(activeModel)
|
|
297
311
|
.catch(() => undefined);
|
|
298
|
-
const label = be.
|
|
312
|
+
const label = be.label ?? "Backend";
|
|
299
313
|
if (modelInfo) {
|
|
300
314
|
backendModelLine = ` ${pc.bold(label)} ${modelInfo.displayName} · ${modelInfo.providerName}${modelInfo.free ? " · free" : ""}`;
|
|
301
315
|
if (modelInfo.contextWindow) {
|
|
302
|
-
backendContextLine =
|
|
316
|
+
backendContextLine = cache
|
|
317
|
+
? ` ${pc.dim(`context window ${modelInfo.contextWindow.toLocaleString()} · cache ${cache.read.toLocaleString()} / ${cache.write.toLocaleString()}`)}`
|
|
318
|
+
: ` ${pc.dim(`context window ${modelInfo.contextWindow.toLocaleString()}`)}`;
|
|
303
319
|
}
|
|
304
320
|
}
|
|
305
321
|
}
|
|
306
322
|
|
|
307
|
-
const cacheHit =
|
|
308
|
-
displayInputTokens + displayCacheRead > 0
|
|
309
|
-
? Math.round(
|
|
310
|
-
(displayCacheRead / (displayInputTokens + displayCacheRead)) *
|
|
311
|
-
100,
|
|
312
|
-
)
|
|
313
|
-
: 0;
|
|
314
323
|
ctx.renderer.writeln(
|
|
315
|
-
` ${pc.bold("Session")} ${nameStr}turns ${info.turns} · ${
|
|
324
|
+
` ${pc.bold("Session")} ${nameStr}turns ${info.turns}${cache ? ` · ${cache.hitPct}% cache` : ""}`,
|
|
316
325
|
);
|
|
317
326
|
ctx.renderer.writeln(
|
|
318
327
|
` ${pc.dim(`in ${displayInputTokens.toLocaleString()} · out ${displayOutputTokens.toLocaleString()} tokens`)}`,
|
|
@@ -360,7 +369,6 @@ export function registerBuiltinCommands(): void {
|
|
|
360
369
|
name: "resume",
|
|
361
370
|
description: "List & resume a past session",
|
|
362
371
|
async handler(_args, ctx) {
|
|
363
|
-
const { getAllSessions } = await import("../../storage/sessions.js");
|
|
364
372
|
const sessions = getAllSessions()
|
|
365
373
|
.filter(
|
|
366
374
|
(s) =>
|
|
@@ -420,8 +428,6 @@ export function registerBuiltinCommands(): void {
|
|
|
420
428
|
argHint: "[name]",
|
|
421
429
|
description: "Name the current session",
|
|
422
430
|
async handler(args, ctx) {
|
|
423
|
-
const { getSession, setSessionName } =
|
|
424
|
-
await import("../../storage/sessions.js");
|
|
425
431
|
// Ensure session exists in store (auto-creates if needed)
|
|
426
432
|
getSession(ctx.chatId());
|
|
427
433
|
if (!args) {
|
|
@@ -11,13 +11,14 @@
|
|
|
11
11
|
import pc from "picocolors";
|
|
12
12
|
import type { TalonConfig } from "../../util/config.js";
|
|
13
13
|
import type { ContextManager, ActionResult } from "../../core/types.js";
|
|
14
|
-
import type { Gateway } from "../../core/gateway.js";
|
|
14
|
+
import type { Gateway } from "../../core/engine/gateway.js";
|
|
15
15
|
import { log } from "../../util/log.js";
|
|
16
16
|
import {
|
|
17
17
|
deriveNumericChatId,
|
|
18
18
|
generateTerminalChatId,
|
|
19
19
|
} from "../../util/chat-id.js";
|
|
20
|
-
import { resolveModel } from "../../core/models.js";
|
|
20
|
+
import { resolveModel } from "../../core/models/catalog.js";
|
|
21
|
+
import { toolInputToRecord } from "../../core/agent-runtime/events.js";
|
|
21
22
|
import { createRenderer } from "./renderer.js";
|
|
22
23
|
import { createInput } from "./input.js";
|
|
23
24
|
import {
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
clearCommands,
|
|
27
28
|
type CommandContext,
|
|
28
29
|
} from "./commands.js";
|
|
30
|
+
import { buildCacheDisplay } from "../shared/status-context.js";
|
|
29
31
|
|
|
30
32
|
// ── State ────────────────────────────────────────────────────────────────────
|
|
31
33
|
|
|
@@ -118,7 +120,8 @@ export function createTerminalFrontend(
|
|
|
118
120
|
let toolCallCount = 0;
|
|
119
121
|
|
|
120
122
|
const context: ContextManager = {
|
|
121
|
-
acquire: () =>
|
|
123
|
+
acquire: () =>
|
|
124
|
+
gateway.setContext(terminalNumericId, terminalChatId, "terminal"),
|
|
122
125
|
release: () => gateway.clearContext(terminalNumericId),
|
|
123
126
|
getMessageCount: (chatId: number) => gateway.getMessageCount(chatId),
|
|
124
127
|
};
|
|
@@ -138,7 +141,10 @@ export function createTerminalFrontend(
|
|
|
138
141
|
getBridgePort: () => gateway.getPort(),
|
|
139
142
|
|
|
140
143
|
async init() {
|
|
141
|
-
gateway.
|
|
144
|
+
gateway.registerFrontendHandler(
|
|
145
|
+
"terminal",
|
|
146
|
+
createActionHandler(gateway, renderer),
|
|
147
|
+
);
|
|
142
148
|
const port = await gateway.start(19877);
|
|
143
149
|
log("bot", `Terminal gateway on port ${port}`);
|
|
144
150
|
},
|
|
@@ -155,7 +161,7 @@ export function createTerminalFrontend(
|
|
|
155
161
|
);
|
|
156
162
|
renderer.writeln(` ${pc.dim("─".repeat(renderer.cols - 2))}`);
|
|
157
163
|
|
|
158
|
-
const { execute } = await import("../../core/dispatcher.js");
|
|
164
|
+
const { execute } = await import("../../core/engine/dispatcher.js");
|
|
159
165
|
const { getSessionInfo } = await import("../../storage/sessions.js");
|
|
160
166
|
const input = createInput(` ${pc.green("❯")} `);
|
|
161
167
|
|
|
@@ -216,26 +222,36 @@ export function createTerminalFrontend(
|
|
|
216
222
|
senderName: "User",
|
|
217
223
|
isGroup: false,
|
|
218
224
|
source: "message",
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
onEvent: async (event) => {
|
|
226
|
+
switch (event.type) {
|
|
227
|
+
case "text_delta":
|
|
228
|
+
if (currentPhase !== "text") {
|
|
229
|
+
currentPhase = "text";
|
|
230
|
+
renderer.updateSpinnerLabel("responding");
|
|
231
|
+
}
|
|
232
|
+
break;
|
|
233
|
+
case "reasoning":
|
|
234
|
+
if (currentPhase !== "thinking") {
|
|
235
|
+
currentPhase = "thinking";
|
|
236
|
+
renderer.updateSpinnerLabel("thinking");
|
|
237
|
+
}
|
|
238
|
+
break;
|
|
239
|
+
case "tool_call":
|
|
240
|
+
renderer.stopSpinner();
|
|
241
|
+
currentPhase = "tool";
|
|
242
|
+
toolCallCount++;
|
|
243
|
+
renderer.renderToolCall(
|
|
244
|
+
event.name,
|
|
245
|
+
toolInputToRecord(event.name, event.input),
|
|
246
|
+
);
|
|
247
|
+
renderer.startSpinner("running tools");
|
|
248
|
+
break;
|
|
249
|
+
case "assistant_message":
|
|
250
|
+
renderer.stopSpinner();
|
|
251
|
+
renderer.renderAssistantMessage(event.text);
|
|
252
|
+
break;
|
|
226
253
|
}
|
|
227
254
|
},
|
|
228
|
-
onToolUse: (toolName, toolInput) => {
|
|
229
|
-
renderer.stopSpinner();
|
|
230
|
-
currentPhase = "tool";
|
|
231
|
-
toolCallCount++;
|
|
232
|
-
renderer.renderToolCall(toolName, toolInput);
|
|
233
|
-
renderer.startSpinner("running tools");
|
|
234
|
-
},
|
|
235
|
-
onTextBlock: async (blockText) => {
|
|
236
|
-
renderer.stopSpinner();
|
|
237
|
-
renderer.renderAssistantMessage(blockText);
|
|
238
|
-
},
|
|
239
255
|
});
|
|
240
256
|
|
|
241
257
|
renderer.stopSpinner();
|
|
@@ -247,20 +263,19 @@ export function createTerminalFrontend(
|
|
|
247
263
|
|
|
248
264
|
const info = getSessionInfo(terminalChatId);
|
|
249
265
|
const u = info.usage;
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
: 0;
|
|
266
|
+
const cache = buildCacheDisplay({
|
|
267
|
+
cacheMetrics: gateway.backend?.cacheMetrics,
|
|
268
|
+
inputTokens: u.totalInputTokens,
|
|
269
|
+
cacheRead: u.totalCacheRead,
|
|
270
|
+
cacheWrite: u.totalCacheWrite,
|
|
271
|
+
});
|
|
257
272
|
renderer.renderStatusLine(result.durationMs, toolCallCount, {
|
|
258
273
|
model: modelDisplay,
|
|
259
274
|
sessionName: info.sessionName,
|
|
260
275
|
turns: info.turns,
|
|
261
276
|
inputTokens: u.totalInputTokens,
|
|
262
277
|
outputTokens: u.totalOutputTokens,
|
|
263
|
-
cacheHitPct:
|
|
278
|
+
cacheHitPct: cache?.hitPct,
|
|
264
279
|
costUsd: u.estimatedCostUsd,
|
|
265
280
|
});
|
|
266
281
|
reprompt(); // readline back on, show prompt
|
|
@@ -289,6 +289,11 @@ export function createInput(promptStr: string): InputHandler {
|
|
|
289
289
|
paused = false;
|
|
290
290
|
},
|
|
291
291
|
close() {
|
|
292
|
+
if (pendingResolve) {
|
|
293
|
+
const resolve = pendingResolve;
|
|
294
|
+
pendingResolve = null;
|
|
295
|
+
resolve("");
|
|
296
|
+
}
|
|
292
297
|
process.stdout.write("\x1b[?2004l");
|
|
293
298
|
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
294
299
|
process.stdin.pause();
|
|
@@ -16,7 +16,7 @@ export type StatusBarInfo = {
|
|
|
16
16
|
turns: number;
|
|
17
17
|
inputTokens: number;
|
|
18
18
|
outputTokens: number;
|
|
19
|
-
cacheHitPct
|
|
19
|
+
cacheHitPct?: number;
|
|
20
20
|
costUsd: number;
|
|
21
21
|
};
|
|
22
22
|
|
|
@@ -189,8 +189,10 @@ export function createRenderer(cols?: number, displayName = "Talon"): Renderer {
|
|
|
189
189
|
p.push(
|
|
190
190
|
`${info.turns} turn${info.turns !== 1 ? "s" : ""}`,
|
|
191
191
|
`${fmtTok(info.inputTokens + info.outputTokens)} tok`,
|
|
192
|
-
`${info.cacheHitPct}% cache`,
|
|
193
192
|
);
|
|
193
|
+
if (typeof info.cacheHitPct === "number") {
|
|
194
|
+
p.push(`${info.cacheHitPct}% cache`);
|
|
195
|
+
}
|
|
194
196
|
if (tools > 0) p.push(`${tools} tool${tools > 1 ? "s" : ""}`);
|
|
195
197
|
writeln();
|
|
196
198
|
writeln(` ${pc.dim(p.join(" · "))}`);
|
package/src/index.ts
CHANGED
|
@@ -1,178 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Talon
|
|
3
|
-
* Composition root: loads config, creates frontend + backend, wires dispatcher.
|
|
2
|
+
* Talon entry shim.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Dispatches the hidden `_mcp-launch` (MCP supervisor) and `_lua-run`
|
|
5
|
+
* (WASM Lua trigger runner) subcommands BEFORE the app graph loads —
|
|
6
|
+
* both are Talon re-invoking itself (see util/mcp-launcher.ts). The
|
|
7
|
+
* dynamic import keeps these helper processes light: they evaluate this
|
|
8
|
+
* shim and their own module, never the backends/frontends/plugins.
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { flushSessions } from "./storage/sessions.js";
|
|
12
|
-
import { flushChatSettings } from "./storage/chat-settings.js";
|
|
13
|
-
import { flushCronJobs } from "./storage/cron-store.js";
|
|
14
|
-
import { flushTriggers } from "./storage/trigger-store.js";
|
|
15
|
-
import { flushHistory } from "./storage/history.js";
|
|
16
|
-
import { flushMediaIndex } from "./storage/media-index.js";
|
|
17
|
-
import { getActiveCount } from "./core/dispatcher.js";
|
|
18
|
-
import { startPulseTimer, stopPulseTimer } from "./core/pulse.js";
|
|
19
|
-
import {
|
|
20
|
-
startHeartbeatTimer,
|
|
21
|
-
stopHeartbeatTimer,
|
|
22
|
-
awaitCurrentRun as awaitHeartbeat,
|
|
23
|
-
} from "./core/heartbeat.js";
|
|
24
|
-
import { startCronTimer, stopCronTimer } from "./core/cron.js";
|
|
25
|
-
import { shutdownTriggers } from "./core/triggers.js";
|
|
26
|
-
import { startWatchdog, stopWatchdog } from "./util/watchdog.js";
|
|
27
|
-
import { log, logError, logWarn } from "./util/log.js";
|
|
28
|
-
import { bootstrap, initBackendAndDispatcher } from "./bootstrap.js";
|
|
29
|
-
import { Gateway } from "./core/gateway.js";
|
|
30
|
-
import type { Frontend } from "./bootstrap.js";
|
|
11
|
+
import { MCP_LAUNCH_SUBCOMMAND, runSupervisor } from "./util/mcp-launcher.js";
|
|
12
|
+
import { LUA_RUN_SUBCOMMAND, runLuaMain } from "./core/scripting/lua-runner.js";
|
|
31
13
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const { config } = await bootstrap();
|
|
38
|
-
|
|
39
|
-
// Write PID file for daemon management
|
|
40
|
-
try {
|
|
41
|
-
writeFileSync(pathFiles.pid, String(process.pid));
|
|
42
|
-
} catch {
|
|
43
|
-
/* ok */
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// ── Create gateway + frontend ─────────────────────────────────────────────────
|
|
47
|
-
|
|
48
|
-
const gateway = new Gateway();
|
|
49
|
-
|
|
50
|
-
const selectedFrontend = getFrontends(config)[0]; // use first configured frontend
|
|
51
|
-
let frontend: Frontend;
|
|
52
|
-
|
|
53
|
-
if (selectedFrontend === "terminal") {
|
|
54
|
-
const { createTerminalFrontend } =
|
|
55
|
-
await import("./frontend/terminal/index.js");
|
|
56
|
-
frontend = createTerminalFrontend(config, gateway);
|
|
57
|
-
log("bot", "Frontend: Terminal");
|
|
58
|
-
} else if (selectedFrontend === "teams") {
|
|
59
|
-
const { createTeamsFrontend } = await import("./frontend/teams/index.js");
|
|
60
|
-
frontend = createTeamsFrontend(config, gateway);
|
|
61
|
-
log("bot", "Frontend: Teams");
|
|
62
|
-
} else if (selectedFrontend === "discord") {
|
|
63
|
-
const { createDiscordFrontend } = await import("./frontend/discord/index.js");
|
|
64
|
-
frontend = createDiscordFrontend(config, gateway);
|
|
65
|
-
log("bot", "Frontend: Discord");
|
|
14
|
+
if (process.argv[2] === MCP_LAUNCH_SUBCOMMAND) {
|
|
15
|
+
await runSupervisor(process.argv.slice(3));
|
|
16
|
+
} else if (process.argv[2] === LUA_RUN_SUBCOMMAND) {
|
|
17
|
+
await runLuaMain(process.argv.slice(3));
|
|
66
18
|
} else {
|
|
67
|
-
|
|
68
|
-
await import("./frontend/telegram/index.js");
|
|
69
|
-
frontend = createTelegramFrontend(config, gateway);
|
|
70
|
-
log("bot", "Frontend: Telegram");
|
|
19
|
+
await import("./app.js");
|
|
71
20
|
}
|
|
72
|
-
|
|
73
|
-
// ── Create backend + wire dispatcher ─────────────────────────────────────────
|
|
74
|
-
|
|
75
|
-
const { backend } = await initBackendAndDispatcher(config, frontend);
|
|
76
|
-
gateway.backend = backend;
|
|
77
|
-
|
|
78
|
-
// ── Graceful shutdown ────────────────────────────────────────────────────────
|
|
79
|
-
|
|
80
|
-
let shuttingDown = false;
|
|
81
|
-
|
|
82
|
-
const SHUTDOWN_TIMEOUT_MS = 15_000;
|
|
83
|
-
|
|
84
|
-
async function gracefulShutdown(signal: string): Promise<void> {
|
|
85
|
-
if (shuttingDown) return;
|
|
86
|
-
shuttingDown = true;
|
|
87
|
-
log("shutdown", `${signal} received, shutting down gracefully...`);
|
|
88
|
-
|
|
89
|
-
const forceTimer = setTimeout(() => {
|
|
90
|
-
logError("shutdown", "Timeout exceeded, forcing exit");
|
|
91
|
-
process.exit(1);
|
|
92
|
-
}, SHUTDOWN_TIMEOUT_MS);
|
|
93
|
-
forceTimer.unref();
|
|
94
|
-
|
|
95
|
-
const pending = getActiveCount();
|
|
96
|
-
if (pending > 0) {
|
|
97
|
-
log("shutdown", `Waiting for ${pending} in-flight queries to drain...`);
|
|
98
|
-
await new Promise((r) => setTimeout(r, 5000));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
await frontend.stop();
|
|
102
|
-
if (config.backend === "opencode") {
|
|
103
|
-
const { stopOpenCodeServer } = await import("./backend/opencode/index.js");
|
|
104
|
-
stopOpenCodeServer();
|
|
105
|
-
}
|
|
106
|
-
// Destroy plugins (cleanup resources)
|
|
107
|
-
if (config.plugins.length > 0) {
|
|
108
|
-
const { destroyPlugins } = await import("./core/plugin.js");
|
|
109
|
-
await destroyPlugins();
|
|
110
|
-
}
|
|
111
|
-
stopPulseTimer();
|
|
112
|
-
stopHeartbeatTimer();
|
|
113
|
-
await awaitHeartbeat();
|
|
114
|
-
stopCronTimer();
|
|
115
|
-
await shutdownTriggers();
|
|
116
|
-
stopWatchdog();
|
|
117
|
-
stopUploadCleanup();
|
|
118
|
-
flushSessions();
|
|
119
|
-
flushChatSettings();
|
|
120
|
-
flushCronJobs();
|
|
121
|
-
flushTriggers();
|
|
122
|
-
flushHistory();
|
|
123
|
-
flushMediaIndex();
|
|
124
|
-
try {
|
|
125
|
-
unlinkSync(pathFiles.pid);
|
|
126
|
-
} catch {
|
|
127
|
-
/* ok */
|
|
128
|
-
}
|
|
129
|
-
log("shutdown", "State saved");
|
|
130
|
-
process.exit(0);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
|
|
134
|
-
process.on("SIGINT", () => gracefulShutdown("SIGINT"));
|
|
135
|
-
|
|
136
|
-
process.on("uncaughtException", (err) => {
|
|
137
|
-
// EPIPE errors from network sockets (e.g. Telegram MTProto) are transient —
|
|
138
|
-
// gramjs will reconnect; crashing the process here is wrong.
|
|
139
|
-
if ((err as NodeJS.ErrnoException).code === "EPIPE") {
|
|
140
|
-
logWarn("bot", `Suppressed transient EPIPE error: ${err.message}`);
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
logError("bot", "Uncaught exception", err);
|
|
144
|
-
flushSessions();
|
|
145
|
-
flushChatSettings();
|
|
146
|
-
flushCronJobs();
|
|
147
|
-
flushTriggers();
|
|
148
|
-
flushHistory();
|
|
149
|
-
flushMediaIndex();
|
|
150
|
-
process.exit(1);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
process.on("unhandledRejection", (reason) => {
|
|
154
|
-
logWarn(
|
|
155
|
-
"bot",
|
|
156
|
-
`Unhandled rejection: ${reason instanceof Error ? reason.message : reason}`,
|
|
157
|
-
);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// ── Start ────────────────────────────────────────────────────────────────────
|
|
161
|
-
|
|
162
|
-
async function main(): Promise<void> {
|
|
163
|
-
await frontend.init();
|
|
164
|
-
log("bot", "Starting Talon...");
|
|
165
|
-
|
|
166
|
-
if (config.pulse) startPulseTimer(config.pulseIntervalMs);
|
|
167
|
-
if (config.heartbeat) startHeartbeatTimer(config.heartbeatIntervalMinutes);
|
|
168
|
-
startCronTimer();
|
|
169
|
-
startWatchdog(config.workspace);
|
|
170
|
-
startUploadCleanup(config.workspace);
|
|
171
|
-
|
|
172
|
-
await frontend.start();
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
main().catch((err) => {
|
|
176
|
-
logError("bot", "Fatal startup error", err);
|
|
177
|
-
process.exit(1);
|
|
178
|
-
});
|
package/src/login.ts
CHANGED
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
|
|
11
11
|
import { TelegramClient } from "telegram";
|
|
12
12
|
import { StringSession } from "telegram/sessions/index.js";
|
|
13
|
-
import { existsSync, readFileSync,
|
|
13
|
+
import { existsSync, readFileSync, mkdirSync } from "node:fs";
|
|
14
14
|
import { resolve, dirname } from "node:path";
|
|
15
15
|
import { createInterface } from "node:readline";
|
|
16
|
+
import writeFileAtomic from "write-file-atomic";
|
|
16
17
|
import { files } from "./util/paths.js";
|
|
17
18
|
|
|
18
19
|
// Load .env
|
|
@@ -76,7 +77,7 @@ async function main() {
|
|
|
76
77
|
const newSession = client.session.save() as unknown as string;
|
|
77
78
|
const dir = dirname(SESSION_FILE);
|
|
78
79
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
79
|
-
|
|
80
|
+
writeFileAtomic.sync(SESSION_FILE, newSession);
|
|
80
81
|
console.log(`Session saved to ${SESSION_FILE}`);
|
|
81
82
|
|
|
82
83
|
await client.disconnect();
|