talon-agent 4.6.1 → 5.0.1
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 +3 -3
- package/package.json +2 -1
- package/prompts/README.md +2 -2
- package/prompts/system/memory-recall.md +16 -0
- package/src/app.ts +22 -7
- package/src/backend/claude-sdk/factory.ts +21 -41
- package/src/backend/claude-sdk/handler.ts +28 -7
- package/src/backend/claude-sdk/host/in-process.ts +147 -0
- package/src/backend/claude-sdk/one-shot.ts +1 -1
- package/src/backend/claude-sdk/options.ts +7 -6
- package/src/backend/claude-sdk/stream.ts +30 -3
- package/src/backend/claude-sdk/warm.ts +1 -1
- package/src/backend/codex/constants.ts +1 -1
- package/src/backend/codex/factory.ts +2 -2
- package/src/backend/codex/handler/events.ts +1 -1
- package/src/backend/codex/handler/message.ts +26 -12
- package/src/backend/codex/handler/rollout-accounting.ts +1 -1
- package/src/backend/codex/init.ts +1 -1
- package/src/backend/codex/mcp-config.ts +2 -2
- package/src/backend/codex/one-shot.ts +1 -1
- package/src/backend/kilo/handler/message.ts +4 -1
- package/src/backend/openai-agents/constants.ts +1 -1
- package/src/backend/openai-agents/factory.ts +2 -2
- package/src/backend/openai-agents/handler/events.ts +1 -1
- package/src/backend/openai-agents/handler/message.ts +8 -4
- package/src/backend/openai-agents/init.ts +1 -1
- package/src/backend/openai-agents/mcp-pool.ts +2 -2
- package/src/backend/opencode/handler/message.ts +4 -1
- package/src/backend/remote-server/chat-turn.ts +31 -23
- package/src/backend/remote-server/events.ts +3 -3
- package/src/backend/remote-server/factory.ts +6 -3
- package/src/backend/remote-server/index.ts +1 -1
- package/src/backend/remote-server/mcp.ts +1 -1
- package/src/backend/remote-server/one-shot.ts +1 -1
- package/src/backend/remote-server/server-bindings.ts +1 -1
- package/src/backend/remote-server/turn.ts +1 -1
- package/src/backend/runtime/cache/cache-metrics.ts +126 -0
- package/src/backend/{shared → runtime/cache}/cache-telemetry.ts +22 -2
- package/src/backend/{shared → runtime}/index.ts +34 -25
- package/src/backend/{shared → runtime/prompt}/delivery-contract.ts +1 -1
- package/src/backend/{shared → runtime/prompt}/prompt-format.ts +46 -2
- package/src/backend/{shared → runtime/prompt}/system-prompt.ts +4 -4
- package/src/backend/{shared → runtime/turn}/delivered-text.ts +1 -1
- package/src/backend/{shared → runtime/turn}/delivery.ts +3 -3
- package/src/backend/{shared → runtime/turn}/handle-retry.ts +5 -5
- package/src/backend/{shared → runtime/turn}/handler-to-events.ts +24 -10
- package/src/backend/{shared → runtime/turn}/handler-types.ts +7 -1
- package/src/backend/{shared → runtime/turn}/model-retry.ts +2 -2
- package/src/backend/{shared → runtime/turn}/result-events.ts +2 -2
- package/src/backend/{shared → runtime/turn}/stream-state.ts +2 -2
- package/src/backend/{shared → runtime/turn}/turn-interrupt.ts +2 -2
- package/src/backend/{shared → runtime/turn}/turn-phases.ts +6 -6
- package/src/bootstrap.ts +6 -21
- package/src/cli.ts +6 -3
- package/src/core/agent-runtime/README.md +15 -0
- package/src/core/agent-runtime/agent-host.ts +387 -0
- package/src/core/agent-runtime/capabilities.ts +11 -0
- package/src/core/agent-runtime/contract-tests.ts +92 -1
- package/src/core/agent-runtime/events.ts +1 -1
- package/src/core/background/{isolated-agent.ts → cron/isolated-agent.ts} +3 -3
- package/src/core/background/{job-health.ts → cron/job-health.ts} +1 -1
- package/src/core/background/{job-oneshot.ts → cron/job-oneshot.ts} +5 -5
- package/src/core/background/{job-prompt.ts → cron/job-prompt.ts} +1 -1
- package/src/core/background/{cron.ts → cron/scheduler.ts} +6 -6
- package/src/core/background/{cron-spec.ts → cron/spec.ts} +1 -1
- package/src/core/background/{dream.ts → dream/index.ts} +10 -15
- package/src/core/background/{plan-alerts.ts → pulse/plan-alerts.ts} +3 -3
- package/src/core/background/{pulse.ts → pulse/pulse.ts} +8 -5
- package/src/core/background/triggers/command.ts +2 -2
- package/src/{util → core/config}/harden.ts +1 -1
- package/src/core/config/index.ts +16 -12
- package/src/{util → core/daemon}/boot-timer.ts +15 -1
- package/src/core/daemon/pidfile.ts +1 -1
- package/src/core/daemon/resource-sampler.ts +121 -0
- package/src/{util → core/daemon}/respawn.ts +1 -1
- package/src/core/doctor/index.ts +1 -1
- package/src/core/engine/dispatcher.ts +16 -0
- package/src/core/engine/gateway-actions/cron.ts +2 -2
- package/src/core/engine/gateway-actions/fetch-url.ts +1 -1
- package/src/core/engine/gateway-actions/index.ts +4 -1
- package/src/core/engine/gateway-actions/memory.ts +335 -0
- package/src/core/engine/gateway-actions/native/exec-background.ts +129 -0
- package/src/core/engine/gateway-actions/native/exec-remote.ts +85 -0
- package/src/core/engine/gateway-actions/native/exec.ts +182 -0
- package/src/core/engine/gateway-actions/native/index.ts +46 -0
- package/src/core/engine/gateway-actions/native/params.ts +46 -0
- package/src/core/engine/gateway-actions/native/read.ts +182 -0
- package/src/core/engine/gateway-actions/native/results.ts +34 -0
- package/src/core/engine/gateway-actions/native/search.ts +212 -0
- package/src/core/engine/gateway-actions/native/shell.ts +39 -0
- package/src/core/engine/gateway-actions/native/teleport.ts +55 -0
- package/src/core/engine/gateway-actions/native/write.ts +170 -0
- package/src/core/engine/gateway.ts +0 -6
- package/src/core/frontend-runtime/builtins.ts +2 -2
- package/src/{util → core/frontend-runtime}/chat-id.ts +30 -0
- package/src/core/mcp-hub/index.ts +1 -1
- package/src/core/mcp-hub/talon-server.ts +1 -1
- package/src/core/memory/import.ts +3 -2
- package/src/core/memory/taps.ts +199 -0
- package/src/core/memory/turn-retrieval.ts +222 -0
- package/src/core/plugin/mcp.ts +1 -1
- package/src/core/prompt/assemble.ts +2 -12
- package/src/core/prompt/index.ts +2 -2
- package/src/core/prompt/invalidation.ts +1 -1
- package/src/core/{scripting/lua-runner.ts → scripts/lua.ts} +1 -1
- package/src/core/tasks/index.ts +1 -1
- package/src/core/tools/{chat.ts → chat/chat.ts} +1 -1
- package/src/core/tools/{cross-send.ts → chat/cross-send.ts} +1 -1
- package/src/core/tools/{history.ts → chat/history.ts} +2 -2
- package/src/core/tools/{media.ts → chat/media.ts} +1 -1
- package/src/core/tools/{members.ts → chat/members.ts} +2 -2
- package/src/core/tools/{messaging.ts → chat/messaging.ts} +2 -2
- package/src/core/tools/{moderation.ts → chat/moderation.ts} +2 -2
- package/src/core/tools/{stickers.ts → chat/stickers.ts} +2 -2
- package/src/core/tools/{whatsapp.ts → chat/whatsapp.ts} +1 -1
- package/src/core/tools/content/memory.ts +128 -0
- package/src/core/tools/{web.ts → content/web.ts} +1 -1
- package/src/core/tools/index.ts +21 -19
- package/src/core/tools/{admin.ts → ops/admin.ts} +1 -1
- package/src/core/tools/{bridge.ts → ops/bridge.ts} +2 -2
- package/src/core/tools/{goals.ts → ops/goals.ts} +2 -2
- package/src/core/tools/{mesh.ts → ops/mesh.ts} +1 -1
- package/src/core/tools/{models.ts → ops/models.ts} +1 -1
- package/src/core/tools/{native.ts → ops/native.ts} +1 -1
- package/src/core/tools/{scheduling.ts → ops/scheduling.ts} +1 -1
- package/src/core/tools/{scripts.ts → ops/scripts.ts} +1 -1
- package/src/core/tools/{skills.ts → ops/skills.ts} +1 -1
- package/src/core/tools/{triggers.ts → ops/triggers.ts} +1 -1
- package/src/core/tools/types.ts +1 -0
- package/src/{util → core/vfs}/workspace.ts +2 -2
- package/src/core/weaver/turn-cpu.ts +32 -0
- package/src/core/weaver/weaver.ts +36 -0
- package/src/frontend/discord/admin.ts +1 -1
- package/src/frontend/discord/callbacks/components/backend-select.ts +1 -1
- package/src/frontend/discord/callbacks/components/effort.ts +1 -1
- package/src/frontend/discord/callbacks/components/index.ts +1 -1
- package/src/frontend/discord/callbacks/components/pulse.ts +1 -1
- package/src/frontend/discord/callbacks/components/settings.ts +2 -2
- package/src/frontend/discord/callbacks/modals.ts +4 -1
- package/src/frontend/discord/commands/admin.ts +2 -36
- package/src/frontend/discord/commands/definitions.ts +0 -11
- package/src/frontend/discord/commands/info.ts +1 -1
- package/src/frontend/discord/commands/interaction.ts +1 -1
- package/src/frontend/discord/commands/router.ts +0 -3
- package/src/frontend/discord/commands/session.ts +8 -2
- package/src/frontend/discord/commands/settings.ts +2 -2
- package/src/frontend/discord/handlers/messages.ts +1 -1
- package/src/frontend/discord/handlers/state.ts +1 -1
- package/src/frontend/discord/middleware.ts +2 -26
- package/src/frontend/discord/ready.ts +1 -1
- package/src/frontend/discord/render.ts +41 -259
- package/src/frontend/discord/runtime.ts +1 -2
- package/src/frontend/native/{auth.ts → bridge/auth.ts} +2 -2
- package/src/frontend/native/{discovery.ts → bridge/discovery.ts} +3 -3
- package/src/frontend/native/{routes → bridge/routes}/chats.ts +1 -1
- package/src/frontend/native/{routes → bridge/routes}/daemon.ts +1 -1
- package/src/frontend/native/{routes → bridge/routes}/host.ts +6 -3
- package/src/frontend/native/{routes → bridge/routes}/pre-auth.ts +1 -1
- package/src/frontend/native/{server.ts → bridge/server.ts} +3 -3
- package/src/frontend/native/{tls.ts → bridge/tls.ts} +2 -2
- package/src/frontend/native/{chat-lifecycle.ts → chats/chat-lifecycle.ts} +3 -3
- package/src/frontend/native/{chat-wire.ts → chats/chat-wire.ts} +4 -4
- package/src/frontend/native/{chats.ts → chats/chats.ts} +4 -4
- package/src/frontend/native/{empty-chat-sweep.ts → chats/empty-chat-sweep.ts} +4 -4
- package/src/frontend/native/{history.ts → chats/history.ts} +7 -7
- package/src/frontend/native/{reset.ts → chats/reset.ts} +7 -7
- package/src/frontend/native/index.ts +13 -10
- package/src/frontend/native/{media.ts → media/media.ts} +3 -3
- package/src/frontend/native/runtime.ts +1 -1
- package/src/frontend/native/{control.ts → surface/control.ts} +4 -4
- package/src/frontend/native/{extensions.ts → surface/extensions.ts} +12 -9
- package/src/frontend/native/{handlers.ts → surface/handlers.ts} +19 -14
- package/src/frontend/native/{logs.ts → surface/logs.ts} +2 -2
- package/src/frontend/native/{memory.ts → surface/memory.ts} +2 -2
- package/src/frontend/native/{models.ts → surface/models.ts} +17 -10
- package/src/frontend/native/{settings.ts → surface/settings.ts} +9 -9
- package/src/frontend/native/{status.ts → surface/status.ts} +3 -3
- package/src/frontend/native/{actions.ts → turn/actions.ts} +7 -4
- package/src/frontend/native/{context.ts → turn/context.ts} +8 -8
- package/src/frontend/native/{emit.ts → turn/emit.ts} +7 -7
- package/src/frontend/native/{queue.ts → turn/queue.ts} +3 -3
- package/src/frontend/native/{turn-meta.ts → turn/turn-meta.ts} +2 -2
- package/src/frontend/native/{turn.ts → turn/turn.ts} +9 -9
- package/src/frontend/{shared → presentation}/format.ts +4 -3
- package/src/frontend/{shared → presentation}/model-commands.ts +1 -1
- package/src/frontend/{shared → presentation}/reasoning-levels.ts +12 -0
- package/src/frontend/presentation/reports.ts +493 -0
- package/src/frontend/{shared → presentation}/session-status.ts +36 -9
- package/src/frontend/{shared → presentation}/status-context.ts +101 -2
- package/src/frontend/teams/commands.ts +2 -2
- package/src/frontend/teams/turn.ts +1 -1
- package/src/frontend/telegram/admin/background.ts +1 -1
- package/src/frontend/telegram/admin/health.ts +1 -1
- package/src/frontend/telegram/admin/sessions.ts +1 -1
- package/src/frontend/telegram/callbacks/effort.ts +2 -2
- package/src/frontend/telegram/callbacks/metrics.ts +1 -1
- package/src/frontend/telegram/callbacks/model/backend.ts +1 -1
- package/src/frontend/telegram/callbacks/model/views.ts +1 -1
- package/src/frontend/telegram/callbacks/pulse.ts +1 -1
- package/src/frontend/telegram/callbacks/query.ts +1 -1
- package/src/frontend/telegram/callbacks/settings.ts +3 -3
- package/src/frontend/telegram/commands/admin.ts +6 -41
- package/src/frontend/telegram/commands/index.ts +1 -1
- package/src/frontend/telegram/commands/info.ts +2 -2
- package/src/frontend/telegram/commands/session.ts +9 -3
- package/src/frontend/telegram/commands/settings.ts +5 -3
- package/src/frontend/telegram/handlers/messages.ts +0 -10
- package/src/frontend/telegram/handlers/state.ts +1 -1
- package/src/frontend/telegram/index.ts +1 -5
- package/src/frontend/telegram/middleware.ts +1 -15
- package/src/frontend/telegram/model-menu.ts +1 -1
- package/src/frontend/telegram/render/html.ts +30 -0
- package/src/frontend/telegram/{helpers → render}/menu.ts +46 -19
- package/src/frontend/telegram/render/reports.ts +182 -0
- package/src/frontend/terminal/builtins/context.ts +2 -2
- package/src/frontend/terminal/builtins/session.ts +1 -1
- package/src/frontend/terminal/builtins/status.ts +2 -2
- package/src/frontend/terminal/index.ts +2 -2
- package/src/frontend/terminal/renderer.ts +1 -1
- package/src/frontend/whatsapp/access.ts +2 -2
- package/src/frontend/whatsapp/actions/history.ts +2 -2
- package/src/frontend/whatsapp/actions/messaging.ts +2 -2
- package/src/frontend/whatsapp/actions/moderation.ts +1 -1
- package/src/frontend/whatsapp/actions/send.ts +1 -1
- package/src/frontend/whatsapp/commands.ts +12 -6
- package/src/frontend/whatsapp/{connection.ts → connection/connection.ts} +5 -5
- package/src/frontend/whatsapp/{pairing-service.ts → connection/pairing-service.ts} +3 -3
- package/src/frontend/whatsapp/{wa-logger.ts → connection/wa-logger.ts} +2 -2
- package/src/frontend/whatsapp/index.ts +4 -4
- package/src/frontend/whatsapp/{inbound.ts → messages/inbound.ts} +15 -15
- package/src/frontend/whatsapp/{media-store.ts → messages/media-store.ts} +4 -4
- package/src/frontend/whatsapp/{message-store.ts → messages/message-store.ts} +1 -1
- package/src/frontend/whatsapp/{turn-recovery.ts → messages/turn-recovery.ts} +4 -4
- package/src/frontend/whatsapp/registry.ts +2 -2
- package/src/frontend/whatsapp/runtime.ts +1 -1
- package/src/index.ts +6 -3
- package/src/storage/db.ts +6 -1
- package/src/storage/memory.ts +59 -8
- package/src/storage/metrics.ts +38 -0
- package/src/storage/repositories/sessions-repo.ts +6 -0
- package/src/storage/session-record.ts +13 -2
- package/src/storage/sessions.ts +12 -0
- package/src/storage/sql/db.sql +5 -0
- package/src/storage/sql/schema.sql +4 -0
- package/src/storage/sql/sessions.sql +3 -3
- package/src/storage/sql/statements.generated.ts +10 -3
- package/src/storage/sql/turn-meta.sql +1 -1
- package/src/util/log.ts +1 -1
- package/src/util/paths.ts +0 -2
- package/src/util/runtime.ts +1 -1
- package/src/core/engine/gateway-actions/native.ts +0 -1035
- package/src/core/soul/README.md +0 -110
- package/src/core/soul/RESEARCH.md +0 -98
- package/src/core/soul/associative.ts +0 -98
- package/src/core/soul/centrality.ts +0 -98
- package/src/core/soul/cluster.ts +0 -83
- package/src/core/soul/compiler.ts +0 -207
- package/src/core/soul/consolidate.ts +0 -179
- package/src/core/soul/critic.ts +0 -162
- package/src/core/soul/dag.ts +0 -265
- package/src/core/soul/delta.ts +0 -123
- package/src/core/soul/drift.ts +0 -99
- package/src/core/soul/embedder.ts +0 -129
- package/src/core/soul/emergent-critic.ts +0 -96
- package/src/core/soul/forgetting.ts +0 -131
- package/src/core/soul/governance.ts +0 -93
- package/src/core/soul/hash.ts +0 -97
- package/src/core/soul/hdc.ts +0 -154
- package/src/core/soul/kernel.ts +0 -540
- package/src/core/soul/lattice.ts +0 -103
- package/src/core/soul/lens.ts +0 -110
- package/src/core/soul/projector.ts +0 -240
- package/src/core/soul/reflect.ts +0 -170
- package/src/core/soul/reflex.ts +0 -164
- package/src/core/soul/retrieve.ts +0 -146
- package/src/core/soul/salience.ts +0 -146
- package/src/core/soul/service.ts +0 -204
- package/src/core/soul/settings.ts +0 -47
- package/src/core/soul/signals.ts +0 -117
- package/src/core/soul/talon-embedder.ts +0 -80
- package/src/core/soul/taps.ts +0 -199
- package/src/core/soul/types.ts +0 -298
- package/src/core/soul/valence.ts +0 -83
- package/src/frontend/telegram/helpers/diagnostics.ts +0 -428
- package/src/frontend/telegram/helpers/format.ts +0 -42
- package/src/frontend/telegram/helpers/index.ts +0 -13
- package/src/util/cleanup-registry.ts +0 -36
- /package/src/backend/{shared → runtime}/frontends.ts +0 -0
- /package/src/backend/{shared → runtime}/metrics.ts +0 -0
- /package/src/backend/{shared → runtime}/sleep.ts +0 -0
- /package/src/backend/{shared → runtime/turn}/flow-violation.ts +0 -0
- /package/src/backend/{shared → runtime}/usage.ts +0 -0
- /package/src/{util/mcp-launcher.ts → core/mcp-hub/launcher.ts} +0 -0
- /package/src/{util → core/tools/content}/web-content.ts +0 -0
- /package/src/core/tools/{mcp-env.ts → ops/mcp-env.ts} +0 -0
- /package/src/{util → core/weaver}/session-name.ts +0 -0
- /package/src/frontend/native/{routes → bridge/routes}/index.ts +0 -0
- /package/src/frontend/native/{routes → bridge/routes}/memory.ts +0 -0
- /package/src/frontend/native/{routes → bridge/routes}/mesh.ts +0 -0
- /package/src/frontend/native/{routes → bridge/routes}/models.ts +0 -0
- /package/src/frontend/native/{routes → bridge/routes}/params.ts +0 -0
- /package/src/frontend/native/{routes → bridge/routes}/table.ts +0 -0
- /package/src/frontend/native/{tool-result.ts → turn/tool-result.ts} +0 -0
- /package/src/frontend/{shared → presentation}/access.ts +0 -0
- /package/src/frontend/{shared → presentation}/plan-usage-report.ts +0 -0
- /package/src/frontend/whatsapp/{auth-state.ts → connection/auth-state.ts} +0 -0
- /package/src/frontend/whatsapp/{identity.ts → connection/identity.ts} +0 -0
- /package/src/frontend/whatsapp/{pairing-lock.ts → connection/pairing-lock.ts} +0 -0
- /package/src/frontend/whatsapp/{pairing.ts → connection/pairing.ts} +0 -0
- /package/src/frontend/whatsapp/{pins.ts → messages/pins.ts} +0 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message taps — the memory store's mechanical input stream.
|
|
3
|
+
*
|
|
4
|
+
* This is the one part of the soul kernel that was worth keeping
|
|
5
|
+
* (docs/memory-persona-plan.md §2): a pair of high-precision regex sets
|
|
6
|
+
* that recognise, without a model call, the two message shapes that carry
|
|
7
|
+
* durable intent — a *directive* ("from now on, …") and a *correction*
|
|
8
|
+
* ("no, that's wrong"). The kernel that consumed them is gone; the rows
|
|
9
|
+
* now land in the typed memory store, where the core view and the
|
|
10
|
+
* retriever already know how to read them.
|
|
11
|
+
*
|
|
12
|
+
* Three rules govern what gets written, and none of them live in the
|
|
13
|
+
* store:
|
|
14
|
+
*
|
|
15
|
+
* - **Trust comes from the chat.** A DM (or a local terminal/native
|
|
16
|
+
* session) is the operator typing, so the row is `operator` trust —
|
|
17
|
+
* stronger than `remember`'s `agent`, because a tap records what a
|
|
18
|
+
* human literally wrote rather than what the model concluded. A
|
|
19
|
+
* group — or a chat-id grammar that cannot tell, which fails closed —
|
|
20
|
+
* is `group_chat`, and a **directive is not recorded there at all**:
|
|
21
|
+
* durable standing intent only comes from a direct conversation with
|
|
22
|
+
* the operator. Same rule as the `remember` action.
|
|
23
|
+
* - **A repeated phrase is not a second memory.** The FTS near-dupe
|
|
24
|
+
* probe runs before every write, so saying "always use ripgrep" twice
|
|
25
|
+
* leaves one row, not two.
|
|
26
|
+
* - **It fails closed and it is never on the prompt-cache path.** Any
|
|
27
|
+
* store error is one warning and nothing else; the turn proceeds. This
|
|
28
|
+
* module must not import `core/prompt/invalidation.js` — a tap that
|
|
29
|
+
* invalidated every live session's prompt snapshot would turn a
|
|
30
|
+
* ~50-token claim into a 60–90 k cache write (plan §3.6).
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import {
|
|
34
|
+
assertMemory,
|
|
35
|
+
findSimilarMemories,
|
|
36
|
+
type MemoryKind,
|
|
37
|
+
type MemorySource,
|
|
38
|
+
type MemoryTrust,
|
|
39
|
+
} from "../../storage/memory.js";
|
|
40
|
+
import { chatScope } from "../frontend-runtime/chat-id.js";
|
|
41
|
+
import { log, logWarn } from "../../util/log.js";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* High-precision cues that a message is a *correction* of Talon's behavior. Kept
|
|
45
|
+
* tight on purpose: a false positive stores a claim about how to behave, so we
|
|
46
|
+
* would rather miss a soft correction than mislabel ordinary chat.
|
|
47
|
+
*/
|
|
48
|
+
const CORRECTION_PATTERNS: readonly RegExp[] = [
|
|
49
|
+
/^\s*(no|nope|nah)\b[\s,.!:-]/i,
|
|
50
|
+
/\bthat'?s (wrong|incorrect|not (right|correct)|false)\b/i,
|
|
51
|
+
/\b(you'?re|you are) wrong\b/i,
|
|
52
|
+
/\bnot what i (asked|meant|wanted|said)\b/i,
|
|
53
|
+
/\bnever (do|say) that( again)?\b/i,
|
|
54
|
+
/\b(stop|quit) (doing|saying) that\b/i,
|
|
55
|
+
/\bwrong[\s,.!]/i,
|
|
56
|
+
/\byou (messed|screwed|fucked) (that|this|it)? ?up\b/i,
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* High-precision cues that a message is a *directive* about how to be — a
|
|
61
|
+
* standing instruction rather than a one-off request. These are stored verbatim
|
|
62
|
+
* as evidence, so again we favor precision over recall.
|
|
63
|
+
*/
|
|
64
|
+
const DIRECTIVE_PATTERNS: readonly RegExp[] = [
|
|
65
|
+
/\bfrom now on\b/i,
|
|
66
|
+
/\bgoing forward\b/i,
|
|
67
|
+
/\bin (the )?future\b/i,
|
|
68
|
+
/\byou should (always|never)\b/i,
|
|
69
|
+
/\b(always|never) (do|say|reply|respond|answer|use|be|call|check)\b/i,
|
|
70
|
+
/\bi (want|need|'?d like) you to\b/i,
|
|
71
|
+
/\bmake sure (you|to|that)\b/i,
|
|
72
|
+
/\bremember to\b/i,
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
export type MessageClass = "directive" | "correction" | null;
|
|
76
|
+
|
|
77
|
+
/** `source.actor` on every row this path writes — the ownership marker. */
|
|
78
|
+
const TAP_ACTOR = "tap";
|
|
79
|
+
|
|
80
|
+
/** The subject a tapped directive is filed under: standing operator intent. */
|
|
81
|
+
const DIRECTIVE_SUBJECT = "operator";
|
|
82
|
+
|
|
83
|
+
/** The subject a tapped correction is filed under. */
|
|
84
|
+
const CORRECTION_SUBJECT = "correction";
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Classify a single inbound message. Returns "correction" or "directive" when a
|
|
88
|
+
* cue matches, else null. Corrections are checked first because a correction is
|
|
89
|
+
* the more specific (and more consequential) signal. Very long messages are
|
|
90
|
+
* skipped — standing instructions and corrections are terse.
|
|
91
|
+
*/
|
|
92
|
+
export function classifyMessage(text: string): MessageClass {
|
|
93
|
+
const t = text.trim();
|
|
94
|
+
if (t.length === 0 || t.length > 500) return null;
|
|
95
|
+
if (CORRECTION_PATTERNS.some((re) => re.test(t))) return "correction";
|
|
96
|
+
if (DIRECTIVE_PATTERNS.some((re) => re.test(t))) return "directive";
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The trust tier for something the human typed in this chat. A DM is the
|
|
102
|
+
* operator speaking for themselves; anything multi-party — or a grammar that
|
|
103
|
+
* cannot tell, which fails closed — is `group_chat`.
|
|
104
|
+
*/
|
|
105
|
+
function trustForChat(chatKey: string): MemoryTrust {
|
|
106
|
+
return chatScope(chatKey) === "dm" ? "operator" : "group_chat";
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* How much of two claims' wording must coincide before the tap calls the
|
|
111
|
+
* second one a restatement of the first. Jaccard over the word sets, so
|
|
112
|
+
* word order and punctuation don't matter.
|
|
113
|
+
*
|
|
114
|
+
* A threshold is needed because the tap files every directive under the
|
|
115
|
+
* *same* subject, and the store's FTS probe ORs a claim's terms: "from now
|
|
116
|
+
* on, always use ripgrep" and "from now on, never use emoji" both match it
|
|
117
|
+
* on `from`/`now`/`use`. Without this, the first directive Talon ever heard
|
|
118
|
+
* would swallow every later one. Set high on purpose — the case this
|
|
119
|
+
* exists for is the same sentence typed twice.
|
|
120
|
+
*/
|
|
121
|
+
const DUPLICATE_OVERLAP = 0.8;
|
|
122
|
+
|
|
123
|
+
/** The word set of a claim, lowercased, punctuation dropped. */
|
|
124
|
+
function wordSet(text: string): Set<string> {
|
|
125
|
+
return new Set(
|
|
126
|
+
text
|
|
127
|
+
.toLowerCase()
|
|
128
|
+
.split(/[^\p{L}\p{N}]+/u)
|
|
129
|
+
.filter(Boolean),
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Jaccard similarity of two claims' word sets, 0..1. */
|
|
134
|
+
function overlap(a: Set<string>, b: Set<string>): number {
|
|
135
|
+
if (a.size === 0 || b.size === 0) return 0;
|
|
136
|
+
let shared = 0;
|
|
137
|
+
for (const w of a) if (b.has(w)) shared += 1;
|
|
138
|
+
return shared / (a.size + b.size - shared);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Write one tapped claim, unless the store already holds a restatement of it
|
|
143
|
+
* under the same kind and subject. Returns true when a row was inserted.
|
|
144
|
+
*
|
|
145
|
+
* The store's FTS probe is the cheap prefilter — live rows only, right kind
|
|
146
|
+
* and subject, best textual match first — and `DUPLICATE_OVERLAP` is the
|
|
147
|
+
* decision.
|
|
148
|
+
*/
|
|
149
|
+
function storeClaim(
|
|
150
|
+
kind: MemoryKind,
|
|
151
|
+
subject: string,
|
|
152
|
+
text: string,
|
|
153
|
+
trust: MemoryTrust,
|
|
154
|
+
source: MemorySource,
|
|
155
|
+
speaker: string,
|
|
156
|
+
): boolean {
|
|
157
|
+
const words = wordSet(text);
|
|
158
|
+
const restated = findSimilarMemories(kind, subject, text).some(
|
|
159
|
+
(row) => overlap(words, wordSet(row.text)) >= DUPLICATE_OVERLAP,
|
|
160
|
+
);
|
|
161
|
+
if (restated) return false;
|
|
162
|
+
const { id } = assertMemory({ kind, subject, text, trust, source });
|
|
163
|
+
log("memory", `tap: [${kind}] ${subject} from ${speaker} #${id}`);
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Feed one inbound message to the memory store if it reads as a directive or a
|
|
169
|
+
* correction. Returns the class recognised, whether or not a row was written —
|
|
170
|
+
* a group-chat directive is classified and deliberately dropped.
|
|
171
|
+
*
|
|
172
|
+
* Never throws: the tap runs beside a turn, not inside it, so a store failure
|
|
173
|
+
* costs one warning and nothing else.
|
|
174
|
+
*/
|
|
175
|
+
export function recordMessageSignal(opts: {
|
|
176
|
+
readonly text: string;
|
|
177
|
+
readonly chatKey: string;
|
|
178
|
+
readonly actor?: string;
|
|
179
|
+
}): MessageClass {
|
|
180
|
+
const cls = classifyMessage(opts.text);
|
|
181
|
+
if (cls === null) return null;
|
|
182
|
+
const text = opts.text.trim();
|
|
183
|
+
const trust = trustForChat(opts.chatKey);
|
|
184
|
+
const source: MemorySource = { chat: opts.chatKey, actor: TAP_ACTOR };
|
|
185
|
+
const speaker = opts.actor ?? "user";
|
|
186
|
+
try {
|
|
187
|
+
if (cls === "directive") {
|
|
188
|
+
// A standing instruction only counts when the operator gave it
|
|
189
|
+
// directly — anyone in a group could otherwise plant one.
|
|
190
|
+
if (trust !== "operator") return cls;
|
|
191
|
+
storeClaim("directive", DIRECTIVE_SUBJECT, text, trust, source, speaker);
|
|
192
|
+
} else {
|
|
193
|
+
storeClaim("episode", CORRECTION_SUBJECT, text, trust, source, speaker);
|
|
194
|
+
}
|
|
195
|
+
} catch (err) {
|
|
196
|
+
logWarn("memory", `tap failed to record ${cls}: ${String(err)}`);
|
|
197
|
+
}
|
|
198
|
+
return cls;
|
|
199
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **Turn retrieval** — the per-turn tier of docs/memory-persona-plan.md
|
|
3
|
+
* §3.4, behind `TALON_MEMORY_STORE`.
|
|
4
|
+
*
|
|
5
|
+
* Retrieval has two tiers and the boundary between them is a
|
|
6
|
+
* prompt-cache invariant (plan §3.6):
|
|
7
|
+
*
|
|
8
|
+
* - **Core view** (`core-view.ts`) — computed once per session build,
|
|
9
|
+
* lives in `staticText`, frozen for the session.
|
|
10
|
+
* - **Turn retrieval** (this module) — keyed to the *incoming
|
|
11
|
+
* message*, resolved once per turn by the Weaver and injected into
|
|
12
|
+
* the **user turn** by `formatUserPrompt`. It never enters
|
|
13
|
+
* `prepareSystemPrompt()` and nothing here may ever call
|
|
14
|
+
* `notifyPromptInputsChanged()` — a per-turn invalidation would
|
|
15
|
+
* force a full-prompt cache write on every live session, every
|
|
16
|
+
* turn, which is the single most expensive mistake in the plan.
|
|
17
|
+
*
|
|
18
|
+
* This is the seam #639 deleted, rebuilt without the divergence that
|
|
19
|
+
* justified deleting it. The old `retrievedMemory` field was read by
|
|
20
|
+
* two backends out of six and silently dropped by the rest; now there
|
|
21
|
+
* is exactly ONE consumer — `backend/runtime/prompt/prompt-format.ts` — that
|
|
22
|
+
* every backend already calls, so a backend cannot forget to inject it
|
|
23
|
+
* without also losing its time tag and `msg_id` framing.
|
|
24
|
+
*
|
|
25
|
+
* **Trust policy (plan §5, #373).** Only `operator` and `agent` rows
|
|
26
|
+
* are ever auto-injected. `user_claim` and `group_chat` rows are
|
|
27
|
+
* reachable only through the explicit `recall` tool: an auto-injected
|
|
28
|
+
* low-trust row is a permanent prompt injection that anyone in a group
|
|
29
|
+
* chat can plant. `reflection` rows are excluded too — the diary is the
|
|
30
|
+
* persona layer and is structurally never a fact source (plan §3.5).
|
|
31
|
+
*
|
|
32
|
+
* **Fail closed.** A broken store must never block chat delivery: any
|
|
33
|
+
* error logs once per process and the turn runs with no injected
|
|
34
|
+
* memory, exactly as if the flag were off.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import {
|
|
38
|
+
formatMemory,
|
|
39
|
+
searchMemories,
|
|
40
|
+
touchMemory,
|
|
41
|
+
type MemoryRow,
|
|
42
|
+
type MemoryTrust,
|
|
43
|
+
} from "../../storage/memory.js";
|
|
44
|
+
import { logDebug, logWarn } from "../../util/log.js";
|
|
45
|
+
import { memoryStoreEnabled } from "./flag.js";
|
|
46
|
+
|
|
47
|
+
// ── Tunables ────────────────────────────────────────────────────────────────
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Hard cap on the injected block, header excluded. Whole rows only —
|
|
51
|
+
* a truncated memory is a misquoted memory, and a half-line is worse
|
|
52
|
+
* than a missing one. Paid on *every* turn (unlike the core view,
|
|
53
|
+
* which is paid once per session and then cached), so it stays small.
|
|
54
|
+
*/
|
|
55
|
+
export const TURN_MEMORY_MAX_CHARS = 3_000;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Candidates pulled from FTS before re-ranking. The trust filter runs
|
|
59
|
+
* *after* this cut, so a query whose twenty best matches are all
|
|
60
|
+
* low-trust injects nothing — which is the conservative direction: an
|
|
61
|
+
* untrusted row must never be promoted into the prompt just because
|
|
62
|
+
* nothing trusted matched.
|
|
63
|
+
*/
|
|
64
|
+
const CANDIDATE_LIMIT = 20;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Trust tiers eligible for automatic injection (plan §5). Everything
|
|
68
|
+
* else stays pull-only, through the explicit `recall` tool.
|
|
69
|
+
*/
|
|
70
|
+
const AUTO_INJECT_TRUST: ReadonlySet<MemoryTrust> = new Set([
|
|
71
|
+
"operator",
|
|
72
|
+
"agent",
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
/** `hitCount` at which the affinity term saturates. */
|
|
76
|
+
const HIT_SATURATION = 20;
|
|
77
|
+
|
|
78
|
+
/** Age at which the recency term reaches zero. */
|
|
79
|
+
const RECENCY_HORIZON_MS = 30 * 24 * 60 * 60 * 1000;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Re-ranking weights. bm25 order (as the store returned it) is the
|
|
83
|
+
* strongest signal — it is the only one that knows what was *asked* —
|
|
84
|
+
* and the three store-side signals refine it rather than overturn it:
|
|
85
|
+
* salience is the curator's judgement, `hitCount` is the feedback loop
|
|
86
|
+
* this module itself feeds, and recency breaks ties towards the live
|
|
87
|
+
* world. They sum to 1 so a score reads as a 0..1 fraction.
|
|
88
|
+
*/
|
|
89
|
+
const W_RELEVANCE = 0.4;
|
|
90
|
+
const W_SALIENCE = 0.3;
|
|
91
|
+
const W_AFFINITY = 0.2;
|
|
92
|
+
const W_RECENCY = 0.1;
|
|
93
|
+
|
|
94
|
+
// ── Types ───────────────────────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
/** What one turn's retrieval produced. `undefined` means "inject nothing". */
|
|
97
|
+
export type TurnMemory = {
|
|
98
|
+
/** The rendered block, one row per line. Never truncated mid-row. */
|
|
99
|
+
text: string;
|
|
100
|
+
/** How many rows it carries. */
|
|
101
|
+
rows: number;
|
|
102
|
+
/** `text.length` — the per-turn cost, recorded as `turn.memory_chars`. */
|
|
103
|
+
chars: number;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/** One turn's retrieval context: the raw inbound message and its chat. */
|
|
107
|
+
export type TurnRetrievalInput = {
|
|
108
|
+
chatId: string;
|
|
109
|
+
/** The user's text, as the Weaver received it (no prompt framing yet). */
|
|
110
|
+
text: string;
|
|
111
|
+
isGroup: boolean;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// ── Ranking ─────────────────────────────────────────────────────────────────
|
|
115
|
+
|
|
116
|
+
/** Eligible for auto-injection: trusted tier, and not the diary. */
|
|
117
|
+
function injectable(row: MemoryRow): boolean {
|
|
118
|
+
return AUTO_INJECT_TRUST.has(row.trust) && row.kind !== "reflection";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Blend the store's bm25 order with the row's own standing. `index` is
|
|
123
|
+
* the row's position in the bm25 result, best first.
|
|
124
|
+
*/
|
|
125
|
+
function score(row: MemoryRow, index: number, total: number, now: number) {
|
|
126
|
+
const relevance = total > 1 ? 1 - index / (total - 1) : 1;
|
|
127
|
+
const affinity = Math.min(
|
|
128
|
+
1,
|
|
129
|
+
Math.log1p(row.hitCount) / Math.log1p(HIT_SATURATION),
|
|
130
|
+
);
|
|
131
|
+
const age = Math.max(0, now - row.lastSeenAt);
|
|
132
|
+
const recency = Math.max(0, 1 - age / RECENCY_HORIZON_MS);
|
|
133
|
+
return (
|
|
134
|
+
W_RELEVANCE * relevance +
|
|
135
|
+
W_SALIENCE * row.salience +
|
|
136
|
+
W_AFFINITY * affinity +
|
|
137
|
+
W_RECENCY * recency
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Trust-filtered candidates, best first. */
|
|
142
|
+
function rank(hits: MemoryRow[], now: number): MemoryRow[] {
|
|
143
|
+
const scored = hits
|
|
144
|
+
.map((row, index) => ({ row, index }))
|
|
145
|
+
.filter(({ row }) => injectable(row))
|
|
146
|
+
.map(({ row, index }) => ({
|
|
147
|
+
row,
|
|
148
|
+
score: score(row, index, hits.length, now),
|
|
149
|
+
}));
|
|
150
|
+
scored.sort((a, b) => b.score - a.score || a.row.id - b.row.id);
|
|
151
|
+
return scored.map((s) => s.row);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Fill the budget with whole rows, in rank order. */
|
|
155
|
+
function fill(rows: MemoryRow[]): { lines: string[]; taken: MemoryRow[] } {
|
|
156
|
+
const lines: string[] = [];
|
|
157
|
+
const taken: MemoryRow[] = [];
|
|
158
|
+
let used = 0;
|
|
159
|
+
for (const row of rows) {
|
|
160
|
+
const line = formatMemory(row);
|
|
161
|
+
// +1 for the newline that joins this line to the previous one.
|
|
162
|
+
const cost = line.length + (lines.length > 0 ? 1 : 0);
|
|
163
|
+
if (used + cost > TURN_MEMORY_MAX_CHARS) break;
|
|
164
|
+
lines.push(line);
|
|
165
|
+
taken.push(row);
|
|
166
|
+
used += cost;
|
|
167
|
+
}
|
|
168
|
+
return { lines, taken };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ── Entry point ─────────────────────────────────────────────────────────────
|
|
172
|
+
|
|
173
|
+
/** One warning per process — a broken store must not spam every turn. */
|
|
174
|
+
let warned = false;
|
|
175
|
+
|
|
176
|
+
function failClosed(err: unknown): undefined {
|
|
177
|
+
if (!warned) {
|
|
178
|
+
warned = true;
|
|
179
|
+
logWarn(
|
|
180
|
+
"dispatcher",
|
|
181
|
+
"memory turn retrieval failed (turns run without it): " +
|
|
182
|
+
(err instanceof Error ? err.message : String(err)),
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Retrieve the memory block for one chat turn, or `undefined` when
|
|
190
|
+
* there is nothing to inject (flag off, no match, or any failure).
|
|
191
|
+
*
|
|
192
|
+
* Injected rows are `touch`ed — that is the ranking feedback loop:
|
|
193
|
+
* a row that keeps getting recalled climbs, one that never matches
|
|
194
|
+
* stays where it is.
|
|
195
|
+
*/
|
|
196
|
+
export function retrieveForTurn(
|
|
197
|
+
input: TurnRetrievalInput,
|
|
198
|
+
): TurnMemory | undefined {
|
|
199
|
+
if (!memoryStoreEnabled()) return undefined;
|
|
200
|
+
try {
|
|
201
|
+
// `match: "any"` — the query is a sentence the user wrote as a
|
|
202
|
+
// message, not as a search; AND-ing its every word would match
|
|
203
|
+
// nothing. bm25 over the OR-ed terms does the ranking.
|
|
204
|
+
const hits = searchMemories(input.text, {
|
|
205
|
+
limit: CANDIDATE_LIMIT,
|
|
206
|
+
match: "any",
|
|
207
|
+
});
|
|
208
|
+
if (hits.length === 0) return undefined;
|
|
209
|
+
const { lines, taken } = fill(rank(hits, Date.now()));
|
|
210
|
+
if (taken.length === 0) return undefined;
|
|
211
|
+
for (const row of taken) touchMemory(row.id);
|
|
212
|
+
const text = lines.join("\n");
|
|
213
|
+
logDebug(
|
|
214
|
+
"dispatcher",
|
|
215
|
+
`memory turn retrieval chat=${input.chatId}${input.isGroup ? " (group)" : ""}: ` +
|
|
216
|
+
`${taken.length}/${hits.length} row(s), ${text.length} chars`,
|
|
217
|
+
);
|
|
218
|
+
return { text, rows: taken.length, chars: text.length };
|
|
219
|
+
} catch (err) {
|
|
220
|
+
return failClosed(err);
|
|
221
|
+
}
|
|
222
|
+
}
|
package/src/core/plugin/mcp.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { resolve } from "node:path";
|
|
8
8
|
import { logWarn } from "../../util/log.js";
|
|
9
|
-
import { wrapMcpServer } from "
|
|
9
|
+
import { wrapMcpServer } from "../mcp-hub/launcher.js";
|
|
10
10
|
import { isBunRuntime } from "../../util/runtime.js";
|
|
11
11
|
import { registry, reloadState } from "./registry.js";
|
|
12
12
|
import type { McpServerConfig } from "./types.js";
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* 6. Plugin additions plugin.systemPrompt() contributions
|
|
31
31
|
* (7. Delivery contract — appended by the backend as its suffix,
|
|
32
32
|
* AFTER plugins, so it is the last thing the model reads.
|
|
33
|
-
* See backend/
|
|
33
|
+
* See backend/runtime/prompt/delivery-contract.ts.)
|
|
34
34
|
*
|
|
35
35
|
* DYNAMIC
|
|
36
36
|
* 1. Daily-memory pointer prompts/system/daily-memory.md
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
* ## Deliberate omissions
|
|
53
53
|
*
|
|
54
54
|
* No "Current Date & Time" section: every user message already
|
|
55
|
-
* carries a `[YYYY-MM-DD HH:MM:SS]` tag (see
|
|
55
|
+
* carries a `[YYYY-MM-DD HH:MM:SS]` tag (see backend/runtime/prompt/prompt-format),
|
|
56
56
|
* the daily-memory pointer names today's file, and the `check_time`
|
|
57
57
|
* tool covers timezone queries. A minute-precision timestamp here was
|
|
58
58
|
* the single biggest cache-buster — it guaranteed every rebuild
|
|
@@ -72,7 +72,6 @@ import { renderStickerLibraryPrompt } from "../../storage/stickers.js";
|
|
|
72
72
|
import { recordHistogram } from "../../storage/metrics.js";
|
|
73
73
|
import { renderCoreView } from "../memory/core-view.js";
|
|
74
74
|
import { memoryStoreEnabled } from "../memory/flag.js";
|
|
75
|
-
import { getSoul } from "../soul/service.js";
|
|
76
75
|
|
|
77
76
|
// ── Types ───────────────────────────────────────────────────────────────────
|
|
78
77
|
|
|
@@ -213,15 +212,6 @@ export function assembleSystemPrompt(
|
|
|
213
212
|
loaded.push("identity");
|
|
214
213
|
}
|
|
215
214
|
|
|
216
|
-
// 1.5. Soul — the compiled identity surface, when the soul is enabled.
|
|
217
|
-
// Off by default (TALON_SOUL_ENABLED); inert deployments add nothing.
|
|
218
|
-
// Selection-based and verbatim, so it never injects invented self-text.
|
|
219
|
-
const soulSection = getSoul().renderPromptSection();
|
|
220
|
-
if (soulSection) {
|
|
221
|
-
staticParts.push(soulSection);
|
|
222
|
-
loaded.push("soul");
|
|
223
|
-
}
|
|
224
|
-
|
|
225
215
|
// 2. Core behaviour — custom.md replaces base.md wholesale when present.
|
|
226
216
|
const custom = readOptionalFile(resolve(promptDir, "custom.md"));
|
|
227
217
|
const basePrompt = readOptionalFile(resolve(promptDir, "base.md"));
|
package/src/core/prompt/index.ts
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* - `workspace-listing` — lazy workspace tree for the dynamic tail
|
|
9
9
|
*
|
|
10
10
|
* The per-session freezing/caching of assembled prompts lives in
|
|
11
|
-
* `backend/
|
|
11
|
+
* `backend/runtime/prompt/system-prompt.ts` (it is a backend concern); the
|
|
12
12
|
* delivery-contract suffix builders live in
|
|
13
|
-
* `backend/
|
|
13
|
+
* `backend/runtime/prompt/delivery-contract.ts`.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
export { loadSystemTemplate } from "./templates.js";
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* skill toggle).
|
|
5
5
|
*
|
|
6
6
|
* Whoever caches assembled prompts registers a hook here (today: the
|
|
7
|
-
* per-session snapshot store in backend/
|
|
7
|
+
* per-session snapshot store in backend/runtime/prompt/system-prompt.ts, at its
|
|
8
8
|
* module load). Core and frontends call `notifyPromptInputsChanged()`
|
|
9
9
|
* and never import the cache — the dependency points backend → core,
|
|
10
10
|
* as the layer rule requires.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* (kill/respawn, SIGTERM grace, log streaming, TALON_FIRE line scanning)
|
|
8
8
|
* is built around child processes. Lua therefore runs as `talon _lua-run
|
|
9
9
|
* <script>` — the same self-reinvocation shape MCP supervision uses
|
|
10
|
-
* (
|
|
10
|
+
* (core/mcp-hub/launcher.ts) — so it works identically for tsx source runs,
|
|
11
11
|
* npm installs, and bun-compiled binaries with no source tree on disk.
|
|
12
12
|
*
|
|
13
13
|
* Sandbox (verified empirically, not aspirational):
|
package/src/core/tasks/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Task table — public surface.
|
|
3
3
|
*
|
|
4
4
|
* See table.ts for the registry and types.ts for the vocabulary. Wiring
|
|
5
|
-
* points: weaver (turns), heartbeat/agent, dream, background/job-oneshot
|
|
5
|
+
* points: weaver (turns), heartbeat/agent, dream, background/cron/job-oneshot
|
|
6
6
|
* (isolated cron/trigger jobs); read surfaces: gateway `GET /tasks` +
|
|
7
7
|
* `POST /tasks/kill`, CLI `talon ps` / `talon kill`.
|
|
8
8
|
*/
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
import type { ToolDefinition } from "
|
|
7
|
-
import { snowflakeOrIdSchema } from "
|
|
6
|
+
import type { ToolDefinition } from "../types.js";
|
|
7
|
+
import { snowflakeOrIdSchema } from "../schemas.js";
|
|
8
8
|
|
|
9
9
|
export const historyTools: ToolDefinition[] = [
|
|
10
10
|
{
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
import type { ToolDefinition } from "
|
|
7
|
-
import { snowflakeOrIdSchema } from "
|
|
6
|
+
import type { ToolDefinition } from "../types.js";
|
|
7
|
+
import { snowflakeOrIdSchema } from "../schemas.js";
|
|
8
8
|
|
|
9
9
|
export const memberTools: ToolDefinition[] = [
|
|
10
10
|
{
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import type { ToolDefinition } from "
|
|
8
|
-
import { chatIdSchema, idSchema, snowflakeOrIdSchema } from "
|
|
7
|
+
import type { ToolDefinition } from "../types.js";
|
|
8
|
+
import { chatIdSchema, idSchema, snowflakeOrIdSchema } from "../schemas.js";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Throw a typed Error when a bridge response reports failure
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { z } from "zod";
|
|
8
|
-
import type { ToolDefinition } from "
|
|
9
|
-
import { chatIdSchema, snowflakeOrIdSchema } from "
|
|
8
|
+
import type { ToolDefinition } from "../types.js";
|
|
9
|
+
import { chatIdSchema, snowflakeOrIdSchema } from "../schemas.js";
|
|
10
10
|
|
|
11
11
|
export const moderationTools: ToolDefinition[] = [
|
|
12
12
|
{
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
import type { ToolDefinition } from "
|
|
7
|
-
import { idSchema } from "
|
|
6
|
+
import type { ToolDefinition } from "../types.js";
|
|
7
|
+
import { idSchema } from "../schemas.js";
|
|
8
8
|
|
|
9
9
|
export const stickerTools: ToolDefinition[] = [
|
|
10
10
|
{
|