talon-agent 4.6.0 → 5.0.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 +3 -3
- package/package.json +3 -2
- package/prompts/README.md +2 -2
- package/prompts/system/memory-recall.md +16 -0
- package/src/app.ts +19 -4
- package/src/backend/claude-sdk/handler.ts +28 -7
- 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 +1 -1
- 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 +1 -1
- package/src/backend/opencode/handler/message.ts +4 -1
- package/src/backend/remote-server/chat-turn.ts +31 -24
- 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 +32 -23
- 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 +2 -2
- 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 +4 -19
- package/src/cli.ts +1 -1
- 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 +1 -1
- package/src/core/config/index.ts +15 -11
- package/src/core/daemon/resource-sampler.ts +121 -0
- package/src/core/engine/dispatcher.ts +16 -0
- package/src/core/engine/gateway-actions/cron.ts +2 -2
- package/src/core/engine/gateway-actions/index.ts +3 -0
- package/src/core/engine/gateway-actions/memory.ts +335 -0
- package/src/core/engine/gateway.ts +0 -6
- 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/prompt/assemble.ts +2 -12
- package/src/core/prompt/index.ts +2 -2
- package/src/core/prompt/invalidation.ts +1 -1
- package/src/core/tasks/index.ts +1 -1
- package/src/core/tools/index.ts +2 -0
- package/src/core/tools/memory.ts +128 -0
- package/src/core/tools/types.ts +1 -0
- 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/pulse.ts +1 -1
- package/src/frontend/discord/callbacks/components/settings.ts +1 -1
- package/src/frontend/discord/callbacks/modals.ts +4 -1
- package/src/frontend/discord/commands/admin.ts +1 -35
- package/src/frontend/discord/commands/definitions.ts +0 -11
- package/src/frontend/discord/commands/router.ts +0 -3
- package/src/frontend/discord/commands/session.ts +6 -0
- package/src/frontend/discord/commands/settings.ts +1 -1
- package/src/frontend/discord/middleware.ts +1 -25
- 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/model-commands.ts +1 -1
- package/src/frontend/shared/session-status.ts +35 -8
- package/src/frontend/shared/status-context.ts +101 -2
- package/src/frontend/telegram/admin/background.ts +1 -1
- package/src/frontend/telegram/callbacks/model/backend.ts +1 -1
- package/src/frontend/telegram/callbacks/pulse.ts +1 -1
- package/src/frontend/telegram/callbacks/settings.ts +1 -1
- package/src/frontend/telegram/commands/admin.ts +2 -37
- package/src/frontend/telegram/commands/index.ts +1 -1
- package/src/frontend/telegram/commands/session.ts +6 -0
- package/src/frontend/telegram/commands/settings.ts +1 -1
- package/src/frontend/telegram/handlers/messages.ts +0 -10
- package/src/frontend/telegram/index.ts +1 -5
- package/src/frontend/telegram/middleware.ts +1 -15
- 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 +8 -2
- 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 +1 -1
- package/src/frontend/whatsapp/runtime.ts +1 -1
- package/src/index.ts +1 -1
- 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/goals-repo.ts +2 -1
- 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/boot-timer.ts +15 -1
- package/src/util/chat-id.ts +30 -0
- package/src/util/concurrency.ts +1 -1
- package/src/util/log.ts +1 -1
- package/src/util/paths.ts +0 -2
- 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/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/core/{scripting/lua-runner.ts → scripts/lua.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/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
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Resolves the active model against the server's catalog, makes sure the
|
|
6
6
|
* server, session, and this chat's MCP servers exist, builds the prompt
|
|
7
7
|
* pair, drives the turn (`./turn.ts`), then runs the shared post-turn
|
|
8
|
-
* phases (`backend/
|
|
8
|
+
* phases (`backend/runtime/turn/turn-phases.ts`) with the one family-specific
|
|
9
9
|
* step in between: the usage fallback from the session summary.
|
|
10
10
|
*
|
|
11
11
|
* Kilo and OpenCode ran byte-for-byte copies of this (modulo the backend
|
|
@@ -18,8 +18,14 @@ import { getSession, incrementTurns } from "../../storage/sessions.js";
|
|
|
18
18
|
import { getChatSettings } from "../../storage/chat-settings.js";
|
|
19
19
|
import { log, logError } from "../../util/log.js";
|
|
20
20
|
import { traceMessage } from "../../util/trace.js";
|
|
21
|
-
import type {
|
|
22
|
-
|
|
21
|
+
import type {
|
|
22
|
+
QueryParams,
|
|
23
|
+
QueryResult,
|
|
24
|
+
} from "../runtime/turn/handler-types.js";
|
|
25
|
+
import {
|
|
26
|
+
frontendsForChat,
|
|
27
|
+
nonTerminalFrontends,
|
|
28
|
+
} from "../runtime/frontends.js";
|
|
23
29
|
import {
|
|
24
30
|
createStreamState,
|
|
25
31
|
recordTokens,
|
|
@@ -33,8 +39,7 @@ import {
|
|
|
33
39
|
accountFailedTurn,
|
|
34
40
|
nameSessionFromFirstMessage,
|
|
35
41
|
finishCallbackTurn,
|
|
36
|
-
|
|
37
|
-
} from "../shared/index.js";
|
|
42
|
+
} from "../runtime/index.js";
|
|
38
43
|
import type { RemoteAgentClient } from "./client.js";
|
|
39
44
|
import type { RemoteServerBindings } from "./server-bindings.js";
|
|
40
45
|
import { getTurnSummary, type RemoteSessionClient } from "./session-helpers.js";
|
|
@@ -69,16 +74,7 @@ export async function runRemoteChatTurn<TClient extends RemoteAgentClient>(
|
|
|
69
74
|
const config = bindings.getConfig();
|
|
70
75
|
if (!config) throw new Error(`${label} agent not initialized`);
|
|
71
76
|
|
|
72
|
-
const {
|
|
73
|
-
chatId,
|
|
74
|
-
text,
|
|
75
|
-
senderName,
|
|
76
|
-
senderHandle,
|
|
77
|
-
isGroup,
|
|
78
|
-
messageId,
|
|
79
|
-
onTextBlock,
|
|
80
|
-
onToolUse,
|
|
81
|
-
} = params;
|
|
77
|
+
const { chatId, text, senderName, onTextBlock, onToolUse } = params;
|
|
82
78
|
const t0 = Date.now();
|
|
83
79
|
const session = getSession(chatId);
|
|
84
80
|
const previousTurns = session.turns;
|
|
@@ -109,14 +105,8 @@ export async function runRemoteChatTurn<TClient extends RemoteAgentClient>(
|
|
|
109
105
|
pluginMcpServerNames,
|
|
110
106
|
);
|
|
111
107
|
|
|
112
|
-
// Build the prompt (time tag + sender + msg_id
|
|
113
|
-
const prompt =
|
|
114
|
-
text,
|
|
115
|
-
senderName: senderName ?? "user",
|
|
116
|
-
senderHandle,
|
|
117
|
-
isGroup,
|
|
118
|
-
messageId,
|
|
119
|
-
});
|
|
108
|
+
// Build the prompt (time tag + sender + msg_id + recalled memory).
|
|
109
|
+
const prompt = buildTurnPrompt(params);
|
|
120
110
|
|
|
121
111
|
// Per-session frozen prompt + this backend's delivery suffix.
|
|
122
112
|
const { text: systemPrompt } = prepareSystemPrompt({
|
|
@@ -131,7 +121,7 @@ export async function runRemoteChatTurn<TClient extends RemoteAgentClient>(
|
|
|
131
121
|
});
|
|
132
122
|
|
|
133
123
|
log("agent", `[${chatId}] <- (${text.length} chars)`);
|
|
134
|
-
traceMessage(chatId, "in", text, { senderName, isGroup });
|
|
124
|
+
traceMessage(chatId, "in", text, { senderName, isGroup: params.isGroup });
|
|
135
125
|
|
|
136
126
|
// Bind the stream state to the chat so token mutators mirror counts
|
|
137
127
|
// into the live-turn overlay — /status updates while the turn runs.
|
|
@@ -269,6 +259,23 @@ export async function runRemoteChatTurn<TClient extends RemoteAgentClient>(
|
|
|
269
259
|
* session summaries can race on cancellation, so a failure leaves the
|
|
270
260
|
* counts at zero.
|
|
271
261
|
*/
|
|
262
|
+
/**
|
|
263
|
+
* The turn's user prompt: the shared framing every backend emits, plus
|
|
264
|
+
* whatever this turn's memory retrieval produced. `formatUserPrompt` is
|
|
265
|
+
* the one place `retrievedMemory` is rendered — see
|
|
266
|
+
* `backend/runtime/prompt/prompt-format.ts`.
|
|
267
|
+
*/
|
|
268
|
+
function buildTurnPrompt(params: QueryParams): string {
|
|
269
|
+
return formatUserPrompt({
|
|
270
|
+
text: params.text,
|
|
271
|
+
senderName: params.senderName ?? "user",
|
|
272
|
+
senderHandle: params.senderHandle,
|
|
273
|
+
isGroup: params.isGroup,
|
|
274
|
+
messageId: params.messageId,
|
|
275
|
+
retrievedMemory: params.retrievedMemory,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
272
279
|
async function fillUsageFromSummary(
|
|
273
280
|
oc: RemoteSessionClient,
|
|
274
281
|
sessionId: string,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
recordToolUse,
|
|
34
34
|
recordToolCall,
|
|
35
35
|
type StreamState,
|
|
36
|
-
} from "../
|
|
36
|
+
} from "../runtime/index.js";
|
|
37
37
|
import {
|
|
38
38
|
extractAssistantUsage,
|
|
39
39
|
type RemoteAssistantInfo,
|
|
@@ -68,7 +68,7 @@ export interface EventProcessingContext {
|
|
|
68
68
|
chatId: string;
|
|
69
69
|
/** Session id we're scoped to — events for other sessions are dropped. */
|
|
70
70
|
sessionId: string;
|
|
71
|
-
/** Stream state accumulator (
|
|
71
|
+
/** Stream state accumulator (runtime/turn/). */
|
|
72
72
|
state: StreamState;
|
|
73
73
|
/** Tool-call ids we've already fired callbacks for. */
|
|
74
74
|
seenToolCallIds: Set<string>;
|
|
@@ -164,7 +164,7 @@ export async function processStreamEvent(
|
|
|
164
164
|
* lands so token/context stats are live mid-turn instead of appearing
|
|
165
165
|
* only at the post-loop accounting. `recordTokens` also mirrors the
|
|
166
166
|
* counts into the chat's live-turn overlay when the state is bound to a
|
|
167
|
-
* chat (see `
|
|
167
|
+
* chat (see `runtime/turn/stream-state.ts: pushLiveUsage`).
|
|
168
168
|
*
|
|
169
169
|
* Values are the message's totals (not deltas), matching what the
|
|
170
170
|
* post-loop `extractAssistantUsage(lastAssistant.info)` reads — so the
|
|
@@ -28,9 +28,12 @@ import type { OneShotAgentParams, OneShotUsage } from "../../core/types.js";
|
|
|
28
28
|
import type { TalonConfig } from "../../core/config/index.js";
|
|
29
29
|
import { binaryOnPath } from "../../util/binary-on-path.js";
|
|
30
30
|
import { log } from "../../util/log.js";
|
|
31
|
-
import { handlerToEvents } from "../
|
|
32
|
-
import type {
|
|
33
|
-
|
|
31
|
+
import { handlerToEvents } from "../runtime/turn/handler-to-events.js";
|
|
32
|
+
import type {
|
|
33
|
+
QueryParams,
|
|
34
|
+
QueryResult,
|
|
35
|
+
} from "../runtime/turn/handler-types.js";
|
|
36
|
+
import { interruptChatTurn } from "../runtime/turn/turn-interrupt.js";
|
|
34
37
|
import type { RemoteModelProvider } from "./model-catalog/provider.js";
|
|
35
38
|
import type { RemoteSessionSnapshot } from "./session-helpers.js";
|
|
36
39
|
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* What's NOT here (intentionally):
|
|
29
29
|
*
|
|
30
30
|
* - Tool definitions, frontend prompt format — those are backend-
|
|
31
|
-
* agnostic and live in `core/` and `backend/
|
|
31
|
+
* agnostic and live in `core/` and `backend/runtime/`.
|
|
32
32
|
*
|
|
33
33
|
* This barrel exposes the helper layer for tests and the conformance
|
|
34
34
|
* suite; the bindings modules import from the concrete files directly.
|
|
@@ -50,7 +50,7 @@ import { ALL_TOOLS, nativeTools } from "../../core/tools/index.js";
|
|
|
50
50
|
import {
|
|
51
51
|
frontendForChatId,
|
|
52
52
|
nonTerminalFrontends,
|
|
53
|
-
} from "../
|
|
53
|
+
} from "../runtime/frontends.js";
|
|
54
54
|
|
|
55
55
|
// ── Constants ───────────────────────────────────────────────────────────────
|
|
56
56
|
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
type RemoteSessionClient,
|
|
42
42
|
type RemoteAssistantInfo,
|
|
43
43
|
} from "./session-helpers.js";
|
|
44
|
-
import { appendBackendSuffix, sleep } from "../
|
|
44
|
+
import { appendBackendSuffix, sleep } from "../runtime/index.js";
|
|
45
45
|
import { buildPermissionRuleset } from "./sessions.js";
|
|
46
46
|
|
|
47
47
|
// ── Client surface ──────────────────────────────────────────────────────────
|
|
@@ -25,7 +25,7 @@ import type { FrontendName } from "../../core/agent-runtime/backend-registry.js"
|
|
|
25
25
|
import {
|
|
26
26
|
buildDeliveryContract,
|
|
27
27
|
type DeliveryMode,
|
|
28
|
-
} from "../
|
|
28
|
+
} from "../runtime/prompt/delivery-contract.js";
|
|
29
29
|
import type { RemoteAgentClient } from "./client.js";
|
|
30
30
|
import { createRemoteServerState, errMsg } from "./state.js";
|
|
31
31
|
import { ensureRemoteServer, stopRemoteServer } from "./lifecycle.js";
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { logWarn } from "../../util/log.js";
|
|
16
|
-
import { createStreamState, recordTokens, sleep } from "../
|
|
16
|
+
import { createStreamState, recordTokens, sleep } from "../runtime/index.js";
|
|
17
17
|
import { processStreamEvent, finalizePartsIntoState } from "./events.js";
|
|
18
18
|
import { findLastAssistantMessage } from "./messages.js";
|
|
19
19
|
import {
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt-cache rollups — the per-turn verdict, the tool fingerprint and the
|
|
3
|
+
* SDK's compaction boundaries, folded into counters an operator can read.
|
|
4
|
+
*
|
|
5
|
+
* `cache-telemetry.ts` next door decides WHAT a turn did (verdict,
|
|
6
|
+
* fingerprint, lookback risk) and is pure apart from its own per-chat maps.
|
|
7
|
+
* This module is the side-effecting half: it writes to the metrics store and
|
|
8
|
+
* logs, so the telemetry stays testable without a store.
|
|
9
|
+
*
|
|
10
|
+
* Why these numbers exist (docs/cache-economics.md, PR A): every decision in
|
|
11
|
+
* PR B ("one prefix per frontend") and PR C ("compact when the cache has gone
|
|
12
|
+
* cold") needs a before/after figure, and nothing here changes a prompt byte
|
|
13
|
+
* or a turn's behaviour — measurement only.
|
|
14
|
+
*
|
|
15
|
+
* - `cache.first_request.{hit,miss,none}` — did the previous turn's prefix
|
|
16
|
+
* survive? The turn's first request is the only one that can say, and it
|
|
17
|
+
* is the number that tracks cost.
|
|
18
|
+
* - `cache.first_request.{read,write}_tokens` — how big the prefix is, so a
|
|
19
|
+
* miss can be priced.
|
|
20
|
+
* - `cache.session_start.{hit,miss,none}` — the same verdict restricted to a
|
|
21
|
+
* chat's FIRST turn. A hit there means another chat had already warmed an
|
|
22
|
+
* identical prefix: the cross-chat sharing signal PR B is aiming at.
|
|
23
|
+
* - `cache.tool_fingerprint.changed` — tools render before the system
|
|
24
|
+
* prompt, so a change invalidates everything after it.
|
|
25
|
+
* - `session.compacted.{manual,auto}` + `session.compact.{pre,post}_tokens`
|
|
26
|
+
* — how often the SDK compacts and how much it reclaims, the baseline
|
|
27
|
+
* PR C's idle-compaction policy is measured against.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import { log } from "../../../util/log.js";
|
|
31
|
+
import {
|
|
32
|
+
incrementCounter,
|
|
33
|
+
noteCacheVerdict,
|
|
34
|
+
recordHistogram,
|
|
35
|
+
} from "../../../storage/metrics.js";
|
|
36
|
+
import {
|
|
37
|
+
crossTurnVerdict,
|
|
38
|
+
fingerprintHash,
|
|
39
|
+
hasToolFingerprint,
|
|
40
|
+
noteToolFingerprint,
|
|
41
|
+
type CrossTurnVerdict,
|
|
42
|
+
type TurnCacheStats,
|
|
43
|
+
} from "./cache-telemetry.js";
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Roll one finished turn's cache behaviour up into the metrics store and
|
|
47
|
+
* remember the verdict for `/status`.
|
|
48
|
+
*
|
|
49
|
+
* `turnsIncludingThis` is the chat's turn count with this turn already
|
|
50
|
+
* counted, so 1 means the turn was the session's first — the only turn whose
|
|
51
|
+
* verdict says anything about cross-chat prefix sharing.
|
|
52
|
+
*/
|
|
53
|
+
export function rollUpTurnCache(
|
|
54
|
+
chatId: string,
|
|
55
|
+
stats: TurnCacheStats,
|
|
56
|
+
turnsIncludingThis: number,
|
|
57
|
+
): CrossTurnVerdict {
|
|
58
|
+
const verdict = crossTurnVerdict(stats);
|
|
59
|
+
incrementCounter(`cache.first_request.${verdict}`);
|
|
60
|
+
// Recorded on every turn, zeros included: the average is then "tokens per
|
|
61
|
+
// turn", which is what a miss costs, rather than an average over the
|
|
62
|
+
// turns that happened to be interesting.
|
|
63
|
+
recordHistogram("cache.first_request.read_tokens", stats.firstRead);
|
|
64
|
+
recordHistogram("cache.first_request.write_tokens", stats.firstWrite);
|
|
65
|
+
if (turnsIncludingThis <= 1) {
|
|
66
|
+
incrementCounter(`cache.session_start.${verdict}`);
|
|
67
|
+
}
|
|
68
|
+
noteCacheVerdict(chatId, verdict);
|
|
69
|
+
return verdict;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Record a chat's tool set: one info line the first time a chat is seen (so
|
|
74
|
+
* two chats on the same frontend can be compared by eye — identical hash +
|
|
75
|
+
* identical static prompt ⇒ shared cache), and a counter whenever it changes
|
|
76
|
+
* mid-process. `noteToolFingerprint` still owns the warning it already logs
|
|
77
|
+
* for a mid-session change.
|
|
78
|
+
*/
|
|
79
|
+
export function reportToolFingerprint(
|
|
80
|
+
chatId: string,
|
|
81
|
+
fingerprint: readonly string[],
|
|
82
|
+
): void {
|
|
83
|
+
const seen = hasToolFingerprint(chatId);
|
|
84
|
+
const changed = noteToolFingerprint(chatId, fingerprint);
|
|
85
|
+
if (!seen) {
|
|
86
|
+
log(
|
|
87
|
+
"agent",
|
|
88
|
+
`[${chatId}] tool fingerprint ${fingerprintHash(fingerprint)} ` +
|
|
89
|
+
`(${fingerprint.length} tools)`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
if (changed) incrementCounter("cache.tool_fingerprint.changed");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** The SDK's compaction metadata, narrowed to the fields that are measured. */
|
|
96
|
+
export type CompactBoundary = {
|
|
97
|
+
trigger: "manual" | "auto";
|
|
98
|
+
pre_tokens: number;
|
|
99
|
+
post_tokens?: number;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Record a compaction boundary the SDK reported mid-stream. Purely
|
|
104
|
+
* observational — the turn carries on exactly as it did before, this just
|
|
105
|
+
* stops the event being dropped on the floor.
|
|
106
|
+
*/
|
|
107
|
+
export function recordCompactBoundary(
|
|
108
|
+
chatId: string,
|
|
109
|
+
meta: CompactBoundary,
|
|
110
|
+
): void {
|
|
111
|
+
const trigger = meta.trigger === "manual" ? "manual" : "auto";
|
|
112
|
+
incrementCounter(`session.compacted.${trigger}`);
|
|
113
|
+
const pre = Number.isFinite(meta.pre_tokens) ? meta.pre_tokens : 0;
|
|
114
|
+
const post =
|
|
115
|
+
typeof meta.post_tokens === "number" && Number.isFinite(meta.post_tokens)
|
|
116
|
+
? meta.post_tokens
|
|
117
|
+
: undefined;
|
|
118
|
+
recordHistogram("session.compact.pre_tokens", pre);
|
|
119
|
+
if (post !== undefined) recordHistogram("session.compact.post_tokens", post);
|
|
120
|
+
log(
|
|
121
|
+
"agent",
|
|
122
|
+
`[${chatId}] context compacted (${trigger}): ${pre} tokens` +
|
|
123
|
+
(post !== undefined ? ` -> ${post}` : "") +
|
|
124
|
+
` — the prefix after the boundary is new, so the next turn re-writes it`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
@@ -36,7 +36,9 @@
|
|
|
36
36
|
* did.
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
-
import {
|
|
39
|
+
import { createHash } from "node:crypto";
|
|
40
|
+
|
|
41
|
+
import { logWarn } from "../../../util/log.js";
|
|
40
42
|
|
|
41
43
|
// ── Per-turn cache stats ────────────────────────────────────────────────────
|
|
42
44
|
|
|
@@ -244,7 +246,7 @@ export function cacheMinimumTokens(model: string): number | undefined {
|
|
|
244
246
|
return best?.min;
|
|
245
247
|
}
|
|
246
248
|
|
|
247
|
-
/** Cheap tokenizer-free estimate (~4 chars/token),
|
|
249
|
+
/** Cheap tokenizer-free estimate (~4 chars/token), the house heuristic. */
|
|
248
250
|
function estimateTokens(text: string): number {
|
|
249
251
|
return Math.ceil(text.length / 4);
|
|
250
252
|
}
|
|
@@ -307,6 +309,24 @@ export function toolFingerprint(
|
|
|
307
309
|
].sort();
|
|
308
310
|
}
|
|
309
311
|
|
|
312
|
+
/**
|
|
313
|
+
* Short, stable digest of a tool set — the thing to compare between two
|
|
314
|
+
* chats. Two chats whose fingerprints (and static prompt) match render a
|
|
315
|
+
* byte-identical prefix and therefore share the cache; two that don't,
|
|
316
|
+
* can't, however similar they look (docs/cache-economics.md, PR B).
|
|
317
|
+
*/
|
|
318
|
+
export function fingerprintHash(fingerprint: readonly string[]): string {
|
|
319
|
+
return createHash("sha256")
|
|
320
|
+
.update(fingerprint.join("\n"))
|
|
321
|
+
.digest("hex")
|
|
322
|
+
.slice(0, 12);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** True once a fingerprint has been recorded for this chat in this process. */
|
|
326
|
+
export function hasToolFingerprint(chatId: string): boolean {
|
|
327
|
+
return lastToolSets.has(chatId);
|
|
328
|
+
}
|
|
329
|
+
|
|
310
330
|
/**
|
|
311
331
|
* Record this turn's tool set for a chat and warn when it differs from the
|
|
312
332
|
* previous turn's. Returns true when a change was detected.
|
|
@@ -1,30 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Backend runtime library — barrel re-export.
|
|
3
3
|
*
|
|
4
4
|
* Helpers used by every concrete backend (`claude-sdk`, `codex`,
|
|
5
5
|
* `kilo`, `opencode`, `openai-agents`) to keep behaviour aligned and
|
|
6
|
-
* avoid copy-paste drift.
|
|
6
|
+
* avoid copy-paste drift. The modules sit in three groups — `turn/`
|
|
7
|
+
* (what a turn does once the SDK loop is running), `prompt/` (the text
|
|
8
|
+
* handed to the model) and `cache/` (prompt-cache telemetry) — with the
|
|
9
|
+
* cross-cutting vocabulary (`usage`, `metrics`, `frontends`, `sleep`)
|
|
10
|
+
* at the root beside this barrel.
|
|
7
11
|
*
|
|
8
12
|
* What's here:
|
|
9
|
-
* - `delivered-text` — scratchpad/dedup primitives.
|
|
10
|
-
* - `delivery-contract` — per-backend response-flow contract
|
|
13
|
+
* - `turn/delivered-text` — scratchpad/dedup primitives.
|
|
14
|
+
* - `prompt/delivery-contract` — per-backend response-flow contract
|
|
11
15
|
* (rendered from prompts/system templates), frontend-aware
|
|
12
16
|
* flow-violation reminder, first-turn nudge.
|
|
13
|
-
* - `flow-violation` — flow-violation detection + reminder text.
|
|
17
|
+
* - `turn/flow-violation` — flow-violation detection + reminder text.
|
|
14
18
|
* - `metrics` — the shared metric vocabulary (tool calls, per-turn
|
|
15
19
|
* rollups, flow violations) with backend dimensions.
|
|
16
|
-
* - `prompt-format` — user-prompt formatter
|
|
20
|
+
* - `prompt/prompt-format` — user-prompt formatter
|
|
21
|
+
* ([time] [Name] [msg_id:N]).
|
|
17
22
|
* - `frontends` — config `frontend` → messaging-frontend list.
|
|
18
23
|
* - `extractSessionName` — re-exported from `util/session-name` so the
|
|
19
24
|
* backends keep one import site; the helper itself is frontend-neutral.
|
|
20
25
|
* - `usage` — cache-hit % + log summarisers.
|
|
21
|
-
* - `system-prompt` — per-session prompt snapshots + backend
|
|
22
|
-
* (assembly itself lives in `core/prompt/`).
|
|
23
|
-
* - `model-retry` — session-expiry / context-overflow / fallback
|
|
24
|
-
*
|
|
25
|
-
* - `turn-
|
|
26
|
+
* - `prompt/system-prompt` — per-session prompt snapshots + backend
|
|
27
|
+
* suffix (assembly itself lives in `core/prompt/`).
|
|
28
|
+
* - `turn/model-retry` — session-expiry / context-overflow / fallback
|
|
29
|
+
* decisions.
|
|
30
|
+
* - `turn/stream-state` — backend-agnostic accumulator for stream loops.
|
|
31
|
+
* - `turn/turn-interrupt` — user-driven mid-turn interrupt registry (the
|
|
26
32
|
* shared `ChatBackend.interruptChatTurn` for callback backends).
|
|
27
|
-
* - `turn-phases` — the post-stream phases (accounting, session name,
|
|
33
|
+
* - `turn/turn-phases` — the post-stream phases (accounting, session name,
|
|
28
34
|
* trailing-prose contract, result tail) every handler runs.
|
|
29
35
|
*
|
|
30
36
|
* What's NOT here (intentionally):
|
|
@@ -34,17 +40,17 @@
|
|
|
34
40
|
* (the spawn/env contract they share is `core/tools/mcp-env.ts`).
|
|
35
41
|
*/
|
|
36
42
|
|
|
37
|
-
export { captureDeliveredText } from "./delivered-text.js";
|
|
43
|
+
export { captureDeliveredText } from "./turn/delivered-text.js";
|
|
38
44
|
|
|
39
|
-
export { registerTurnInterrupt } from "./turn-interrupt.js";
|
|
45
|
+
export { registerTurnInterrupt } from "./turn/turn-interrupt.js";
|
|
40
46
|
|
|
41
|
-
export { formatUserPrompt } from "./prompt-format.js";
|
|
47
|
+
export { formatUserPrompt } from "./prompt/prompt-format.js";
|
|
42
48
|
|
|
43
49
|
export {
|
|
44
50
|
buildDeliveryContract,
|
|
45
51
|
buildFlowViolationReminder,
|
|
46
52
|
buildFirstTurnReminder,
|
|
47
|
-
} from "./delivery-contract.js";
|
|
53
|
+
} from "./prompt/delivery-contract.js";
|
|
48
54
|
|
|
49
55
|
export { summarizeUsage } from "./usage.js";
|
|
50
56
|
|
|
@@ -57,9 +63,12 @@ export {
|
|
|
57
63
|
priorLookbackOverflow,
|
|
58
64
|
noteLookbackRisk,
|
|
59
65
|
CACHE_LOOKBACK_BLOCKS,
|
|
60
|
-
} from "./cache-telemetry.js";
|
|
66
|
+
} from "./cache/cache-telemetry.js";
|
|
61
67
|
|
|
62
|
-
export {
|
|
68
|
+
export {
|
|
69
|
+
prepareSystemPrompt,
|
|
70
|
+
appendBackendSuffix,
|
|
71
|
+
} from "./prompt/system-prompt.js";
|
|
63
72
|
|
|
64
73
|
export {
|
|
65
74
|
createStreamState,
|
|
@@ -71,19 +80,19 @@ export {
|
|
|
71
80
|
pushLiveUsage,
|
|
72
81
|
finalizeResponseText,
|
|
73
82
|
type StreamState,
|
|
74
|
-
} from "./stream-state.js";
|
|
83
|
+
} from "./turn/stream-state.js";
|
|
75
84
|
|
|
76
85
|
export {
|
|
77
86
|
routeDelivery,
|
|
78
87
|
buildDeliveryFailureReminder,
|
|
79
88
|
TextBlockDeliveryError,
|
|
80
|
-
} from "./delivery.js";
|
|
89
|
+
} from "./turn/delivery.js";
|
|
81
90
|
|
|
82
91
|
export { sleep } from "./sleep.js";
|
|
83
92
|
|
|
84
93
|
export { recordToolCall } from "./metrics.js";
|
|
85
94
|
|
|
86
|
-
export { applyRetryDecision } from "./handle-retry.js";
|
|
95
|
+
export { applyRetryDecision } from "./turn/handle-retry.js";
|
|
87
96
|
|
|
88
97
|
export {
|
|
89
98
|
accountTurn,
|
|
@@ -92,6 +101,6 @@ export {
|
|
|
92
101
|
enforceTrailingProse,
|
|
93
102
|
finishCallbackTurn,
|
|
94
103
|
turnUsageSnapshot,
|
|
95
|
-
} from "./turn-phases.js";
|
|
104
|
+
} from "./turn/turn-phases.js";
|
|
96
105
|
|
|
97
|
-
export { buildResultEvents } from "./result-events.js";
|
|
106
|
+
export { buildResultEvents } from "./turn/result-events.js";
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* logic-adjacent strings, like log messages.
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
|
-
import { loadSystemTemplate } from "
|
|
37
|
+
import { loadSystemTemplate } from "../../../core/prompt/templates.js";
|
|
38
38
|
|
|
39
39
|
// ── Types ───────────────────────────────────────────────────────────────────
|
|
40
40
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* DM (no msg_id): "[2026-05-15 11:01:23] actual text"
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import { formatFullDatetime } from "
|
|
18
|
+
import { formatFullDatetime } from "../../../util/time.js";
|
|
19
19
|
|
|
20
20
|
// ── Public API ──────────────────────────────────────────────────────────────
|
|
21
21
|
|
|
@@ -38,8 +38,33 @@ export type PromptFormatInputs = {
|
|
|
38
38
|
messageId?: number | string;
|
|
39
39
|
/** When true, omit the leading `[YYYY-MM-DD HH:MM:SS]` tag. */
|
|
40
40
|
omitTimeTag?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Memory retrieved for THIS turn (`core/memory/turn-retrieval.ts`),
|
|
43
|
+
* already ranked, trust-filtered and budgeted. Appended after the
|
|
44
|
+
* message text under a verify-first header.
|
|
45
|
+
*
|
|
46
|
+
* This is the **only** place retrieved memory enters a prompt, and
|
|
47
|
+
* every backend reaches it through this one helper — which is what
|
|
48
|
+
* keeps #639's divergence (two backends reading the field, four
|
|
49
|
+
* silently dropping it) from coming back. It belongs to the user
|
|
50
|
+
* turn: it must never reach `prepareSystemPrompt()`, a prompt
|
|
51
|
+
* addition, or a backend `system` field, or it would break the
|
|
52
|
+
* per-session frozen prompt (plan §3.6).
|
|
53
|
+
*
|
|
54
|
+
* Absent or blank → the returned prompt is BYTE-IDENTICAL to what
|
|
55
|
+
* this helper produced before the field existed.
|
|
56
|
+
*/
|
|
57
|
+
retrievedMemory?: string;
|
|
41
58
|
};
|
|
42
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Header on the injected block. "Verify before relying on it" is
|
|
62
|
+
* deliberate: retrieval is a bm25 guess, not a fact, and the model
|
|
63
|
+
* should treat a recalled line as a lead rather than as truth.
|
|
64
|
+
*/
|
|
65
|
+
export const RECALLED_MEMORY_HEADER =
|
|
66
|
+
"[Recalled from memory — verify before relying on it]";
|
|
67
|
+
|
|
43
68
|
/**
|
|
44
69
|
* Format a user prompt for the AI backend.
|
|
45
70
|
*
|
|
@@ -49,6 +74,13 @@ export type PromptFormatInputs = {
|
|
|
49
74
|
* is on the other end.
|
|
50
75
|
*/
|
|
51
76
|
export function formatUserPrompt(inputs: PromptFormatInputs): string {
|
|
77
|
+
return withRecalledMemory(formatMessageLine(inputs), inputs.retrievedMemory);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ── Helpers ─────────────────────────────────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
/** The message line itself — time tag, sender label, `msg_id`, text. */
|
|
83
|
+
function formatMessageLine(inputs: PromptFormatInputs): string {
|
|
52
84
|
const timeTag = inputs.omitTimeTag ? "" : `[${formatFullDatetime()}]`;
|
|
53
85
|
const msgIdHint =
|
|
54
86
|
inputs.messageId !== undefined ? ` [msg_id:${inputs.messageId}]` : "";
|
|
@@ -68,7 +100,19 @@ export function formatUserPrompt(inputs: PromptFormatInputs): string {
|
|
|
68
100
|
return joinNonEmpty(timeTag, inputs.text);
|
|
69
101
|
}
|
|
70
102
|
|
|
71
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Append the retrieved-memory block AFTER the message, never before:
|
|
105
|
+
* the user's own words stay the first thing the model reads, and the
|
|
106
|
+
* recalled lines read as an annotation on them.
|
|
107
|
+
*/
|
|
108
|
+
function withRecalledMemory(
|
|
109
|
+
prompt: string,
|
|
110
|
+
memory: string | undefined,
|
|
111
|
+
): string {
|
|
112
|
+
const block = memory?.trim();
|
|
113
|
+
if (!block) return prompt;
|
|
114
|
+
return `${prompt}\n\n${RECALLED_MEMORY_HEADER}\n${block}`;
|
|
115
|
+
}
|
|
72
116
|
|
|
73
117
|
function joinNonEmpty(...parts: string[]): string {
|
|
74
118
|
return parts
|
|
@@ -39,10 +39,10 @@ import {
|
|
|
39
39
|
joinSystemPromptParts,
|
|
40
40
|
type SystemPromptParts,
|
|
41
41
|
type TalonConfig,
|
|
42
|
-
} from "
|
|
43
|
-
import { getPluginPromptAdditions } from "
|
|
44
|
-
import { onPromptInputsChanged } from "
|
|
45
|
-
import { frontendForChatId, nonTerminalFrontends } from "
|
|
42
|
+
} from "../../../core/config/index.js";
|
|
43
|
+
import { getPluginPromptAdditions } from "../../../core/plugin/index.js";
|
|
44
|
+
import { onPromptInputsChanged } from "../../../core/prompt/invalidation.js";
|
|
45
|
+
import { frontendForChatId, nonTerminalFrontends } from "../frontends.js";
|
|
46
46
|
|
|
47
47
|
// ── Types ───────────────────────────────────────────────────────────────────
|
|
48
48
|
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* whether to surface a flow violation.
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
import { stripMcpPrefix } from "
|
|
28
|
+
import { stripMcpPrefix } from "../../../core/tools/index.js";
|
|
29
29
|
|
|
30
30
|
// ── Constants ───────────────────────────────────────────────────────────────
|
|
31
31
|
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
|
|
36
36
|
import type { StreamState } from "./stream-state.js";
|
|
37
37
|
import { undeliveredResponseText } from "./stream-state.js";
|
|
38
|
-
import { logWarn } from "
|
|
39
|
-
import { incrementCounter } from "
|
|
38
|
+
import { logWarn } from "../../../util/log.js";
|
|
39
|
+
import { incrementCounter } from "../../../storage/metrics.js";
|
|
40
40
|
|
|
41
41
|
/** Route the delivery decision selected. */
|
|
42
42
|
export type DeliveryRoute =
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import type { QueryParams, QueryResult } from "./handler-types.js";
|
|
26
|
-
import { classify, type TalonError } from "
|
|
27
|
-
import { logWarn } from "
|
|
28
|
-
import { incrementCounter } from "
|
|
29
|
-
import { resetSession } from "
|
|
26
|
+
import { classify, type TalonError } from "../../../core/errors.js";
|
|
27
|
+
import { logWarn } from "../../../util/log.js";
|
|
28
|
+
import { incrementCounter } from "../../../storage/metrics.js";
|
|
29
|
+
import { resetSession } from "../../../storage/sessions.js";
|
|
30
30
|
import { classifyRetry } from "./model-retry.js";
|
|
31
|
-
import type { AgentEvent } from "
|
|
31
|
+
import type { AgentEvent } from "../../../core/agent-runtime/events.js";
|
|
32
32
|
|
|
33
33
|
/** Inputs for `applyRetryDecision`. */
|
|
34
34
|
export interface ApplyRetryDecisionInputs {
|