talon-agent 4.3.2 → 4.4.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/package.json +1 -1
- package/src/app.ts +1 -1
- package/src/backend/claude-sdk/doctor.ts +1 -1
- package/src/backend/claude-sdk/state.ts +1 -1
- package/src/backend/codex/doctor.ts +1 -1
- package/src/backend/codex/init.ts +1 -1
- package/src/backend/codex/state.ts +1 -1
- package/src/backend/openai-agents/doctor.ts +1 -1
- package/src/backend/openai-agents/init.ts +1 -1
- package/src/backend/openai-agents/state.ts +1 -1
- package/src/backend/remote-server/factory.ts +1 -1
- package/src/backend/remote-server/mcp.ts +1 -1
- package/src/backend/remote-server/server-bindings.ts +1 -1
- package/src/backend/remote-server/state.ts +1 -1
- package/src/backend/shared/system-prompt.ts +1 -1
- package/src/bootstrap.ts +3 -3
- package/src/cli/chat.ts +1 -1
- package/src/cli/config.ts +2 -2
- package/src/cli/doctor.ts +1 -1
- package/src/cli/index.ts +8 -0
- package/src/cli/memory.ts +166 -0
- package/src/cli/setup.ts +1 -1
- package/src/core/agent-runtime/backend-registry.ts +2 -2
- package/src/core/agent-runtime/model-ref.ts +2 -2
- package/src/core/auth/expiry-monitor.ts +1 -1
- package/src/{util/config.ts → core/config/index.ts} +8 -8
- package/src/core/{doctor.ts → doctor/index.ts} +11 -11
- package/src/core/engine/backend-controller/legacy.ts +1 -1
- package/src/core/engine/backend-controller/pool.ts +1 -1
- package/src/core/engine/backend-controller/rebind.ts +1 -1
- package/src/core/engine/backend-controller/state.ts +1 -1
- package/src/core/engine/gateway-actions/plugins.ts +1 -1
- package/src/core/engine/model-audit.ts +1 -1
- package/src/core/{notify.ts → frontend-runtime/admin-notify.ts} +1 -1
- package/src/core/frontend-runtime/capabilities.ts +1 -1
- package/src/core/models/active-model.ts +1 -1
- package/src/core/plugin/builtins.ts +2 -2
- package/src/core/plugin/manage.ts +1 -1
- package/src/core/plugin/native-runtimes.ts +1 -1
- package/src/frontend/discord/admin.ts +1 -1
- package/src/frontend/discord/callbacks/components/index.ts +1 -1
- package/src/frontend/discord/callbacks/components/settings.ts +1 -1
- package/src/frontend/discord/callbacks/components/types.ts +1 -1
- package/src/frontend/discord/callbacks/modals.ts +1 -1
- package/src/frontend/discord/commands/admin.ts +2 -2
- package/src/frontend/discord/commands/definitions.ts +1 -1
- package/src/frontend/discord/commands/info.ts +1 -1
- package/src/frontend/discord/commands/router.ts +1 -1
- package/src/frontend/discord/commands/session.ts +1 -1
- package/src/frontend/discord/commands/settings.ts +1 -1
- package/src/frontend/discord/handlers/delivery.ts +1 -1
- package/src/frontend/discord/handlers/messages.ts +1 -1
- package/src/frontend/discord/handlers/queue.ts +1 -1
- package/src/frontend/discord/handlers/state.ts +1 -1
- package/src/frontend/discord/index.ts +1 -1
- package/src/frontend/discord/middleware.ts +1 -1
- package/src/frontend/discord/render.ts +1 -1
- package/src/frontend/discord/runtime.ts +1 -1
- package/src/frontend/native/extensions.ts +4 -1
- package/src/frontend/native/index.ts +1 -1
- package/src/frontend/native/runtime.ts +1 -1
- package/src/frontend/native/settings.ts +1 -1
- package/src/frontend/shared/model-commands.ts +1 -1
- package/src/frontend/shared/plan-usage-report.ts +1 -1
- package/src/frontend/shared/reasoning-levels.ts +1 -1
- package/src/frontend/shared/session-status.ts +1 -1
- package/src/frontend/teams/index.ts +1 -1
- package/src/frontend/teams/runtime.ts +1 -1
- package/src/frontend/telegram/actions/chat-info.ts +1 -1
- package/src/frontend/telegram/actions/coerce.ts +15 -0
- package/src/frontend/telegram/actions/index.ts +2 -2
- package/src/frontend/telegram/actions/media.ts +1 -1
- package/src/frontend/telegram/actions/messaging.ts +3 -4
- package/src/frontend/telegram/actions/moderation/chat.ts +63 -0
- package/src/frontend/telegram/actions/moderation/index.ts +74 -0
- package/src/frontend/telegram/actions/moderation/members.ts +77 -0
- package/src/frontend/telegram/actions/moderation/permissions.ts +69 -0
- package/src/frontend/telegram/actions/moderation/topics.ts +48 -0
- package/src/frontend/telegram/actions/moderation/types.ts +16 -0
- package/src/frontend/telegram/actions/rich-messages.ts +51 -0
- package/src/frontend/telegram/actions/{shared.ts → send.ts} +9 -59
- package/src/frontend/telegram/admin/background.ts +66 -0
- package/src/frontend/telegram/admin/chunked-reply.ts +20 -0
- package/src/frontend/telegram/admin/health.ts +81 -0
- package/src/frontend/telegram/admin/sessions.ts +105 -0
- package/src/frontend/telegram/admin.ts +57 -262
- package/src/frontend/telegram/callbacks/auth.ts +1 -1
- package/src/frontend/telegram/callbacks/effort.ts +1 -1
- package/src/frontend/telegram/callbacks/index.ts +3 -3
- package/src/frontend/telegram/callbacks/metrics.ts +1 -1
- package/src/frontend/telegram/callbacks/model/backend.ts +156 -0
- package/src/frontend/telegram/callbacks/model/control.ts +29 -0
- package/src/frontend/telegram/callbacks/model/nav.ts +54 -0
- package/src/frontend/telegram/callbacks/model/select.ts +100 -0
- package/src/frontend/telegram/callbacks/model/types.ts +39 -0
- package/src/frontend/telegram/callbacks/model/views.ts +116 -0
- package/src/frontend/telegram/callbacks/model.ts +61 -331
- package/src/frontend/telegram/callbacks/pulse.ts +1 -1
- package/src/frontend/telegram/callbacks/{shared.ts → query.ts} +3 -2
- package/src/frontend/telegram/callbacks/settings.ts +1 -1
- package/src/frontend/telegram/callbacks/whatsapp.ts +1 -1
- package/src/frontend/telegram/commands/admin.ts +108 -77
- package/src/frontend/telegram/commands/index.ts +1 -1
- package/src/frontend/telegram/commands/settings.ts +65 -43
- package/src/frontend/telegram/commands/state.ts +1 -1
- package/src/frontend/telegram/commands/whatsapp-pairing.ts +1 -1
- package/src/frontend/telegram/handlers/context.ts +1 -1
- package/src/frontend/telegram/handlers/delivery.ts +2 -2
- package/src/frontend/telegram/handlers/messages.ts +1 -1
- package/src/frontend/telegram/handlers/queue.ts +1 -1
- package/src/frontend/telegram/handlers/state.ts +1 -1
- package/src/frontend/telegram/helpers/diagnostics.ts +1 -1
- package/src/frontend/telegram/index.ts +1 -1
- package/src/frontend/telegram/middleware.ts +167 -202
- package/src/frontend/telegram/model-menu.ts +1 -1
- package/src/frontend/terminal/builtins/context.ts +184 -0
- package/src/frontend/terminal/builtins/help.ts +35 -0
- package/src/frontend/terminal/builtins/index.ts +23 -0
- package/src/frontend/terminal/builtins/model.ts +198 -0
- package/src/frontend/terminal/builtins/session.ts +101 -0
- package/src/frontend/terminal/builtins/status.ts +202 -0
- package/src/frontend/terminal/command-registry.ts +80 -0
- package/src/frontend/terminal/commands.ts +11 -674
- package/src/frontend/terminal/index.ts +1 -1
- package/src/frontend/terminal/input/history.ts +64 -0
- package/src/frontend/terminal/input/keys.ts +143 -0
- package/src/frontend/terminal/input/parts.ts +33 -0
- package/src/frontend/terminal/input/paste.ts +53 -0
- package/src/frontend/terminal/input/render.ts +42 -0
- package/src/frontend/terminal/input/state.ts +60 -0
- package/src/frontend/terminal/input.ts +27 -342
- package/src/frontend/whatsapp/connection.ts +1 -1
- package/src/frontend/whatsapp/index.ts +2 -2
- package/src/frontend/whatsapp/pairing-service.ts +1 -1
- package/src/frontend/whatsapp/runtime.ts +1 -1
- package/src/plugins/github/provision.ts +1 -1
- package/src/plugins/mempalace/provision.ts +1 -1
- package/src/plugins/playwright/provision.ts +1 -1
- package/src/storage/memory.ts +505 -0
- package/src/storage/repositories/memory-repo.ts +308 -0
- package/src/storage/sql/memory.sql +95 -0
- package/src/storage/sql/schema.sql +81 -0
- package/src/storage/sql/statements.generated.ts +146 -0
- package/src/frontend/telegram/actions/moderation.ts +0 -255
- /package/src/core/{doctor-types.ts → doctor/types.ts} +0 -0
- /package/src/core/{pairing-broker.ts → frontend-runtime/pairing-broker.ts} +0 -0
package/package.json
CHANGED
package/src/app.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* are loaded dynamically — only the selected platform's dependencies are required.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { getFrontends } from "./
|
|
9
|
+
import { getFrontends } from "./core/config/index.js";
|
|
10
10
|
import { startUploadCleanup, stopUploadCleanup } from "./util/workspace.js";
|
|
11
11
|
import { flushDatabase } from "./storage/db.js";
|
|
12
12
|
import { getActiveCount, stopAllTurns } from "./core/engine/dispatcher.js";
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import type {
|
|
8
8
|
DoctorCheck,
|
|
9
9
|
DoctorConfigSlice,
|
|
10
|
-
} from "../../core/doctor
|
|
10
|
+
} from "../../core/doctor/types.js";
|
|
11
11
|
import { getModels } from "../../core/models/catalog.js";
|
|
12
12
|
import { binaryOnPath } from "../../util/binary-on-path.js";
|
|
13
13
|
import { resolveModel } from "./model-provider.js";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* initialization functions + internal getters for sibling modules.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { TalonConfig } from "../../
|
|
8
|
+
import type { TalonConfig } from "../../core/config/index.js";
|
|
9
9
|
import { registerClaudeModels } from "./models/index.js";
|
|
10
10
|
|
|
11
11
|
// ── State ────────────────────────────────────────────────────────────────────
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { Codex } from "@openai/codex-sdk";
|
|
25
|
-
import type { TalonConfig } from "../../
|
|
25
|
+
import type { TalonConfig } from "../../core/config/index.js";
|
|
26
26
|
import type { FrontendName } from "../../core/agent-runtime/backend-registry.js";
|
|
27
27
|
import { log, logWarn } from "../../util/log.js";
|
|
28
28
|
import { nonTerminalFrontends } from "../shared/frontends.js";
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import type { Codex } from "@openai/codex-sdk";
|
|
13
13
|
import type { ReasoningEffortLevel } from "../../core/types.js";
|
|
14
|
-
import type { TalonConfig } from "../../
|
|
14
|
+
import type { TalonConfig } from "../../core/config/index.js";
|
|
15
15
|
import type { FrontendName } from "../../core/agent-runtime/backend-registry.js";
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
|
|
44
44
|
import OpenAI from "openai";
|
|
45
45
|
import { setDefaultOpenAIClient, setOpenAIAPI } from "@openai/agents";
|
|
46
|
-
import type { TalonConfig } from "../../
|
|
46
|
+
import type { TalonConfig } from "../../core/config/index.js";
|
|
47
47
|
import type { FrontendName } from "../../core/agent-runtime/backend-registry.js";
|
|
48
48
|
import { log, logWarn } from "../../util/log.js";
|
|
49
49
|
import { nonTerminalFrontends } from "../shared/frontends.js";
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* so the resolver, picker, and UIs can read it synchronously.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { TalonConfig } from "../../
|
|
11
|
+
import type { TalonConfig } from "../../core/config/index.js";
|
|
12
12
|
import type { FrontendName } from "../../core/agent-runtime/backend-registry.js";
|
|
13
13
|
import { TalonSession } from "./session.js";
|
|
14
14
|
import type { ReasoningEffortLevel } from "../../core/types.js";
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
type UsageTelemetry,
|
|
26
26
|
} from "../../core/agent-runtime/capabilities.js";
|
|
27
27
|
import type { OneShotAgentParams, OneShotUsage } from "../../core/types.js";
|
|
28
|
-
import type { TalonConfig } from "../../
|
|
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
31
|
import { handlerToEvents } from "../shared/handler-to-events.js";
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
import type { RemoteAgentClient } from "./client.js";
|
|
45
45
|
import type { RemoteServerState } from "./state.js";
|
|
46
46
|
import { errMsg } from "./state.js";
|
|
47
|
-
import type { TalonConfig } from "../../
|
|
47
|
+
import type { TalonConfig } from "../../core/config/index.js";
|
|
48
48
|
import type { FrontendName } from "../../core/agent-runtime/backend-registry.js";
|
|
49
49
|
import { ALL_TOOLS, nativeTools } from "../../core/tools/index.js";
|
|
50
50
|
import {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* `vi.mock("../backend/<name>/server.js")` all address.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
import type { TalonConfig } from "../../
|
|
23
|
+
import type { TalonConfig } from "../../core/config/index.js";
|
|
24
24
|
import type { FrontendName } from "../../core/agent-runtime/backend-registry.js";
|
|
25
25
|
import {
|
|
26
26
|
buildDeliveryContract,
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* fields) and avoids the "where does this method live" guessing game.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import type { TalonConfig } from "../../
|
|
18
|
+
import type { TalonConfig } from "../../core/config/index.js";
|
|
19
19
|
import type { FrontendName } from "../../core/agent-runtime/backend-registry.js";
|
|
20
20
|
import type { RemoteAgentClient } from "./client.js";
|
|
21
21
|
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
joinSystemPromptParts,
|
|
40
40
|
type SystemPromptParts,
|
|
41
41
|
type TalonConfig,
|
|
42
|
-
} from "../../
|
|
42
|
+
} from "../../core/config/index.js";
|
|
43
43
|
import { getPluginPromptAdditions } from "../../core/plugin/index.js";
|
|
44
44
|
import { onPromptInputsChanged } from "../../core/prompt/invalidation.js";
|
|
45
45
|
import { frontendForChatId, nonTerminalFrontends } from "./frontends.js";
|
package/src/bootstrap.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* differ (index.ts selects dynamically, cli.ts always uses terminal).
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { loadConfig, rebuildSystemPrompt } from "./
|
|
12
|
+
import { loadConfig, rebuildSystemPrompt } from "./core/config/index.js";
|
|
13
13
|
import { initWorkspace } from "./util/workspace.js";
|
|
14
14
|
import { loadSessions, resetSession } from "./storage/sessions.js";
|
|
15
15
|
import { loadChatSettings } from "./storage/chat-settings.js";
|
|
@@ -27,7 +27,7 @@ import { appendToJournal } from "./storage/journal.js";
|
|
|
27
27
|
import { initPulse, resetPulseTimer } from "./core/background/pulse.js";
|
|
28
28
|
import { initCron } from "./core/background/cron.js";
|
|
29
29
|
import { initPlanAlerts } from "./core/background/plan-alerts.js";
|
|
30
|
-
import { setAdminNotifier } from "./core/notify.js";
|
|
30
|
+
import { setAdminNotifier } from "./core/frontend-runtime/admin-notify.js";
|
|
31
31
|
import { startAuthExpiryMonitor } from "./core/auth/expiry-monitor.js";
|
|
32
32
|
import {
|
|
33
33
|
initTriggers,
|
|
@@ -38,7 +38,7 @@ import { initHeartbeat } from "./core/background/heartbeat/index.js";
|
|
|
38
38
|
import { log, logWarn, logDebug } from "./util/log.js";
|
|
39
39
|
import { bootPhase } from "./util/boot-timer.js";
|
|
40
40
|
import { mapConcurrent } from "./util/concurrency.js";
|
|
41
|
-
import type { TalonConfig } from "./
|
|
41
|
+
import type { TalonConfig } from "./core/config/index.js";
|
|
42
42
|
import { resolveFrontendIdAmong } from "./core/frontend-runtime/routing.js";
|
|
43
43
|
import type { Frontend } from "./core/frontend-runtime/index.js";
|
|
44
44
|
import type { ContextManager } from "./core/types.js";
|
package/src/cli/chat.ts
CHANGED
|
@@ -21,7 +21,7 @@ export async function startChat(): Promise<void> {
|
|
|
21
21
|
// spawning telegram-tools or teams-tools MCP servers and ensures the
|
|
22
22
|
// system prompt loads terminal.md instead of teams.md/telegram.md.
|
|
23
23
|
(config as Record<string, unknown>).frontend = "terminal";
|
|
24
|
-
const { rebuildSystemPrompt } = await import("../
|
|
24
|
+
const { rebuildSystemPrompt } = await import("../core/config/index.js");
|
|
25
25
|
const { getPluginPromptAdditions } = await import("../core/plugin/index.js");
|
|
26
26
|
rebuildSystemPrompt(config, getPluginPromptAdditions());
|
|
27
27
|
|
package/src/cli/config.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* CLI config model + load/save/format helpers, plus the banner.
|
|
3
3
|
*
|
|
4
4
|
* This is the on-disk `talon.json` shape as the CLI sees it; the runtime has
|
|
5
|
-
* its own richer config type in
|
|
5
|
+
* its own richer config type in core/config/index.ts.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import pc from "picocolors";
|
|
@@ -20,7 +20,7 @@ export function printBanner(): void {
|
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* The subset of ~/.talon/config.json the CLI reads or prompts for — a
|
|
23
|
-
* partial view, not the whole schema (that lives in
|
|
23
|
+
* partial view, not the whole schema (that lives in core/config/index.ts).
|
|
24
24
|
* Anything absent here is still present at runtime on a loaded config and
|
|
25
25
|
* MUST be carried through on save: `talon setup` used to rebuild the file
|
|
26
26
|
* from its own named fields alone and silently dropped every other key.
|
package/src/cli/doctor.ts
CHANGED
|
@@ -19,7 +19,7 @@ const DOCTOR_ICONS: Record<string, string> = {
|
|
|
19
19
|
export async function runDoctor(): Promise<void> {
|
|
20
20
|
printBanner();
|
|
21
21
|
console.log(` ${pc.bold("Environment check")}\n`);
|
|
22
|
-
const { collectDoctorReport } = await import("../core/doctor.js");
|
|
22
|
+
const { collectDoctorReport } = await import("../core/doctor/index.js");
|
|
23
23
|
// Doctor composes each backend's own checks off the registry, and the
|
|
24
24
|
// CLI runs standalone — nothing else has registered them yet.
|
|
25
25
|
const { loadBuiltinBackends } = await import("../backend/builtins.js");
|
package/src/cli/index.ts
CHANGED
|
@@ -34,6 +34,7 @@ import { showTasks, killTask } from "./tasks.js";
|
|
|
34
34
|
import { showEvents } from "./events.js";
|
|
35
35
|
import { runPluginCommand } from "./plugin.js";
|
|
36
36
|
import { runSkillCommand } from "./skill.js";
|
|
37
|
+
import { runMemoryCommand } from "./memory.js";
|
|
37
38
|
import { mainMenu } from "./menu.js";
|
|
38
39
|
|
|
39
40
|
export * from "./context.js";
|
|
@@ -56,6 +57,7 @@ const CLI_COMMANDS = [
|
|
|
56
57
|
"events",
|
|
57
58
|
"plugin",
|
|
58
59
|
"skill",
|
|
60
|
+
"memory",
|
|
59
61
|
];
|
|
60
62
|
|
|
61
63
|
/** Route a `talon <command>` invocation. Called by the entry point. */
|
|
@@ -121,6 +123,9 @@ export async function runCli(): Promise<void> {
|
|
|
121
123
|
case "skill":
|
|
122
124
|
await runSkillCommand(process.argv.slice(3));
|
|
123
125
|
break;
|
|
126
|
+
case "memory":
|
|
127
|
+
runMemoryCommand(process.argv.slice(3));
|
|
128
|
+
break;
|
|
124
129
|
case "--version":
|
|
125
130
|
case "-v": {
|
|
126
131
|
console.log(pkg.version);
|
|
@@ -151,6 +156,9 @@ export async function runCli(): Promise<void> {
|
|
|
151
156
|
console.log(
|
|
152
157
|
` ${pc.cyan("skill")} Manage skills (install/enable/disable)`,
|
|
153
158
|
);
|
|
159
|
+
console.log(
|
|
160
|
+
` ${pc.cyan("memory")} Read/edit the memory store (list/search/remember)`,
|
|
161
|
+
);
|
|
154
162
|
console.log(` ${pc.cyan("config")} View/edit configuration`);
|
|
155
163
|
console.log(` ${pc.cyan("logs")} Tail log file`);
|
|
156
164
|
console.log(` ${pc.cyan("doctor")} Validate environment`);
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `talon memory` — read and edit the typed memory store from a terminal.
|
|
3
|
+
*
|
|
4
|
+
* All lifecycle logic lives in storage/memory.ts; this module only parses
|
|
5
|
+
* argv and renders rows. One row per line, in the store's own
|
|
6
|
+
* `formatMemory` shape, so CLI output and the `/memory` surfaces read
|
|
7
|
+
* identically.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import pc from "picocolors";
|
|
11
|
+
import {
|
|
12
|
+
assertMemory,
|
|
13
|
+
dropMemory,
|
|
14
|
+
formatMemory,
|
|
15
|
+
getMemory,
|
|
16
|
+
isMemoryKind,
|
|
17
|
+
listMemories,
|
|
18
|
+
memoryHistory,
|
|
19
|
+
replaceStateKey,
|
|
20
|
+
searchMemories,
|
|
21
|
+
MEMORY_KINDS,
|
|
22
|
+
type MemoryKind,
|
|
23
|
+
type MemoryRow,
|
|
24
|
+
} from "../storage/memory.js";
|
|
25
|
+
|
|
26
|
+
const USAGE = [
|
|
27
|
+
` Usage: ${pc.cyan("talon memory <command>")}`,
|
|
28
|
+
"",
|
|
29
|
+
" Commands:",
|
|
30
|
+
` ${pc.cyan("list [kind]")} Show live memories, ranked`,
|
|
31
|
+
` ${pc.cyan("search <query>")} Full-text search`,
|
|
32
|
+
` ${pc.cyan("show <id>")} One row plus its history`,
|
|
33
|
+
` ${pc.cyan("remember <kind> <subject> <text>")} Record an operator claim`,
|
|
34
|
+
` ${pc.cyan("forget <id> [reason]")} Drop a row to the graveyard`,
|
|
35
|
+
` ${pc.cyan("state <key> <text>")} Replace the row for a state key`,
|
|
36
|
+
"",
|
|
37
|
+
` Kinds: ${MEMORY_KINDS.join(", ")}`,
|
|
38
|
+
"",
|
|
39
|
+
].join("\n");
|
|
40
|
+
|
|
41
|
+
function fail(message: string): void {
|
|
42
|
+
console.log(` ${pc.red("✖")} ${message}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function printRows(rows: readonly MemoryRow[], empty: string): void {
|
|
46
|
+
if (rows.length === 0) {
|
|
47
|
+
console.log(` ${pc.dim(empty)}\n`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
for (const row of rows) console.log(` ${formatMemory(row)}`);
|
|
51
|
+
console.log();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function parseKind(value: string | undefined): MemoryKind | undefined {
|
|
55
|
+
if (value === undefined) return undefined;
|
|
56
|
+
if (!isMemoryKind(value)) throw new Error(`Unknown kind "${value}"`);
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function cmdList(kindArg: string | undefined): void {
|
|
61
|
+
const kind = parseKind(kindArg);
|
|
62
|
+
const rows = listMemories(kind ? { kind } : {});
|
|
63
|
+
printRows(rows, kind ? `No ${kind} memories yet.` : "No memories yet.");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function cmdSearch(query: string): void {
|
|
67
|
+
printRows(searchMemories(query), `No memories matching "${query}".`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function cmdShow(idArg: string | undefined): void {
|
|
71
|
+
const id = Number(idArg);
|
|
72
|
+
if (!Number.isInteger(id)) {
|
|
73
|
+
fail("show needs a numeric memory id");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const row = getMemory(id);
|
|
77
|
+
if (!row) {
|
|
78
|
+
fail(`No memory with id ${id}`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
console.log(` ${formatMemory(row)}`);
|
|
82
|
+
console.log(
|
|
83
|
+
` ${pc.dim(`trust=${row.trust} confidence=${row.confidence} hits=${row.hitCount} salience=${row.salience}`)}`,
|
|
84
|
+
);
|
|
85
|
+
for (const entry of memoryHistory(id)) {
|
|
86
|
+
const when = new Date(entry.at).toISOString();
|
|
87
|
+
const why = entry.reason ? ` — ${entry.reason}` : "";
|
|
88
|
+
console.log(` ${pc.dim(when)} ${entry.op}${why}`);
|
|
89
|
+
}
|
|
90
|
+
console.log();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function cmdRemember(args: readonly string[]): void {
|
|
94
|
+
const [kindArg, subject, ...rest] = args;
|
|
95
|
+
const text = rest.join(" ");
|
|
96
|
+
if (!kindArg || !subject || !text) {
|
|
97
|
+
fail("remember needs <kind> <subject> <text...>");
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const kind = parseKind(kindArg);
|
|
101
|
+
const { id, similar } = assertMemory({
|
|
102
|
+
kind: kind!,
|
|
103
|
+
subject,
|
|
104
|
+
text,
|
|
105
|
+
trust: "operator",
|
|
106
|
+
});
|
|
107
|
+
console.log(` ${pc.green("●")} Remembered as #${id}`);
|
|
108
|
+
if (similar.length > 0) {
|
|
109
|
+
console.log(` ${pc.dim("Near-duplicates already stored:")}`);
|
|
110
|
+
for (const row of similar) console.log(` ${formatMemory(row)}`);
|
|
111
|
+
}
|
|
112
|
+
console.log();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function cmdForget(args: readonly string[]): void {
|
|
116
|
+
const id = Number(args[0]);
|
|
117
|
+
if (!Number.isInteger(id)) {
|
|
118
|
+
fail("forget needs a numeric memory id");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const reason = args.slice(1).join(" ");
|
|
122
|
+
dropMemory(id, reason || undefined);
|
|
123
|
+
console.log(` ${pc.green("●")} Dropped #${id} to the graveyard\n`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function cmdState(args: readonly string[]): void {
|
|
127
|
+
const [key, ...rest] = args;
|
|
128
|
+
const text = rest.join(" ");
|
|
129
|
+
if (!key || !text) {
|
|
130
|
+
fail("state needs <key> <text...>");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const id = replaceStateKey(key, text);
|
|
134
|
+
console.log(` ${pc.green("●")} ${key} is now #${id}\n`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Route a `talon memory <command>` invocation. */
|
|
138
|
+
export function runMemoryCommand(args: readonly string[]): void {
|
|
139
|
+
try {
|
|
140
|
+
switch (args[0]) {
|
|
141
|
+
case "list":
|
|
142
|
+
cmdList(args[1]);
|
|
143
|
+
break;
|
|
144
|
+
case "search":
|
|
145
|
+
if (!args[1]) fail("search needs a query");
|
|
146
|
+
else cmdSearch(args.slice(1).join(" "));
|
|
147
|
+
break;
|
|
148
|
+
case "show":
|
|
149
|
+
cmdShow(args[1]);
|
|
150
|
+
break;
|
|
151
|
+
case "remember":
|
|
152
|
+
cmdRemember(args.slice(1));
|
|
153
|
+
break;
|
|
154
|
+
case "forget":
|
|
155
|
+
cmdForget(args.slice(1));
|
|
156
|
+
break;
|
|
157
|
+
case "state":
|
|
158
|
+
cmdState(args.slice(1));
|
|
159
|
+
break;
|
|
160
|
+
default:
|
|
161
|
+
console.log(USAGE);
|
|
162
|
+
}
|
|
163
|
+
} catch (err) {
|
|
164
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
165
|
+
}
|
|
166
|
+
}
|
package/src/cli/setup.ts
CHANGED
|
@@ -650,7 +650,7 @@ export function buildSetupConfig(
|
|
|
650
650
|
: existing.discord,
|
|
651
651
|
// Never dropped. Deselecting WhatsApp shouldn't throw away its
|
|
652
652
|
// pairing setup, and dropping it while `frontend` still lists
|
|
653
|
-
// whatsapp produces a config
|
|
653
|
+
// whatsapp produces a config core/config/index.ts refuses to load at all
|
|
654
654
|
// ("WhatsApp frontend requires a whatsapp config block") — a daemon
|
|
655
655
|
// that won't start. The `??` keeps that impossible even if the
|
|
656
656
|
// branch that collects the answer is ever skipped.
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
32
|
import type { Backend } from "./capabilities.js";
|
|
33
|
-
import type { DoctorCheck, DoctorConfigSlice } from "../doctor
|
|
34
|
-
import type { TalonConfig } from "
|
|
33
|
+
import type { DoctorCheck, DoctorConfigSlice } from "../doctor/types.js";
|
|
34
|
+
import type { TalonConfig } from "../config/index.js";
|
|
35
35
|
|
|
36
36
|
// ── Types ───────────────────────────────────────────────────────────────────
|
|
37
37
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* logs, telemetry, tests) doesn't have to chase it down again.
|
|
14
14
|
*
|
|
15
15
|
* This module also pins the canonical `BackendId` union;
|
|
16
|
-
* `src/
|
|
16
|
+
* `src/core/config/index.ts` imports `BACKEND_IDS` directly for its zod
|
|
17
17
|
* enums. Adding a backend means updating THIS literal once; the
|
|
18
18
|
* config schema picks the change up automatically. Don't
|
|
19
19
|
* reintroduce a manually-mirrored zod tuple — it's a footgun.
|
|
@@ -24,7 +24,7 @@ import type { ReasoningEffortLevel } from "../types.js";
|
|
|
24
24
|
/**
|
|
25
25
|
* Canonical backend identifiers — single source of truth for the
|
|
26
26
|
* typed `BackendId` union AND the runtime zod enums in
|
|
27
|
-
* `src/
|
|
27
|
+
* `src/core/config/index.ts`. Update one place, everything stays in
|
|
28
28
|
* lockstep.
|
|
29
29
|
*/
|
|
30
30
|
export const BACKEND_IDS = [
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { existsSync, readFileSync, mkdirSync } from "node:fs";
|
|
2
2
|
import writeFileAtomic from "write-file-atomic";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
import { dirs, files as pathFiles } from "
|
|
5
|
-
import { hardenTalonPermissions } from "
|
|
6
|
-
import { setTimezone } from "
|
|
7
|
-
import { BACKEND_IDS } from "../
|
|
8
|
-
import { REASONING_LEVEL_ORDER } from "../
|
|
4
|
+
import { dirs, files as pathFiles } from "../../util/paths.js";
|
|
5
|
+
import { hardenTalonPermissions } from "../../util/harden.js";
|
|
6
|
+
import { setTimezone } from "../../util/time.js";
|
|
7
|
+
import { BACKEND_IDS } from "../agent-runtime/model-ref.js";
|
|
8
|
+
import { REASONING_LEVEL_ORDER } from "../models/reasoning-levels.js";
|
|
9
9
|
import {
|
|
10
10
|
assembleSystemPrompt,
|
|
11
11
|
joinSystemPromptParts,
|
|
12
12
|
type SystemPromptParts,
|
|
13
|
-
} from "../
|
|
13
|
+
} from "../prompt/assemble.js";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Backend-id literal source.
|
|
@@ -609,11 +609,11 @@ const configSchema = z.object({
|
|
|
609
609
|
|
|
610
610
|
// System-prompt assembly lives in core/prompt/ (section pipeline,
|
|
611
611
|
// templates, workspace listing). Re-exported here so existing
|
|
612
|
-
// consumers keep importing from
|
|
612
|
+
// consumers keep importing from core/config.
|
|
613
613
|
export {
|
|
614
614
|
joinSystemPromptParts,
|
|
615
615
|
type SystemPromptParts,
|
|
616
|
-
} from "../
|
|
616
|
+
} from "../prompt/assemble.js";
|
|
617
617
|
|
|
618
618
|
export type TalonConfig = z.infer<typeof configSchema> & {
|
|
619
619
|
systemPrompt: string;
|
|
@@ -13,22 +13,22 @@
|
|
|
13
13
|
|
|
14
14
|
import { existsSync } from "node:fs";
|
|
15
15
|
import { stat } from "node:fs/promises";
|
|
16
|
-
import { NATIVE_MODULES } from "
|
|
17
|
-
import { dirs } from "
|
|
18
|
-
import { getBackend, listBackends } from "
|
|
16
|
+
import { NATIVE_MODULES } from "../../native/registry.js";
|
|
17
|
+
import { dirs } from "../../util/paths.js";
|
|
18
|
+
import { getBackend, listBackends } from "../agent-runtime/backend-registry.js";
|
|
19
19
|
import type {
|
|
20
20
|
DoctorCheck,
|
|
21
21
|
DoctorConfigSlice,
|
|
22
22
|
DoctorReport,
|
|
23
23
|
NativeModuleCheck,
|
|
24
|
-
} from "./
|
|
24
|
+
} from "./types.js";
|
|
25
25
|
|
|
26
26
|
export type {
|
|
27
27
|
DoctorCheck,
|
|
28
28
|
DoctorConfigSlice,
|
|
29
29
|
DoctorReport,
|
|
30
30
|
NativeModuleCheck,
|
|
31
|
-
} from "./
|
|
31
|
+
} from "./types.js";
|
|
32
32
|
|
|
33
33
|
function errorNote(err: unknown): string {
|
|
34
34
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -180,7 +180,7 @@ async function checkPluginRuntimes(
|
|
|
180
180
|
config: DoctorConfigSlice | undefined,
|
|
181
181
|
): Promise<DoctorCheck[]> {
|
|
182
182
|
const checks: DoctorCheck[] = [];
|
|
183
|
-
const { NATIVE_RUNTIMES } = await import("
|
|
183
|
+
const { NATIVE_RUNTIMES } = await import("../plugin/native-runtimes.js");
|
|
184
184
|
for (const runtime of NATIVE_RUNTIMES) {
|
|
185
185
|
if (!runtime.enabled(config)) continue;
|
|
186
186
|
try {
|
|
@@ -322,7 +322,7 @@ export async function collectDoctorReport(opts: {
|
|
|
322
322
|
// on the in-process TS path. When present, report the live version.
|
|
323
323
|
{
|
|
324
324
|
const { wardenBinaryPath, wardenVersion } =
|
|
325
|
-
await import("
|
|
325
|
+
await import("../../native/warden.js");
|
|
326
326
|
const wardenBin = wardenBinaryPath();
|
|
327
327
|
if (wardenBin) {
|
|
328
328
|
const version = wardenVersion();
|
|
@@ -350,7 +350,7 @@ export async function collectDoctorReport(opts: {
|
|
|
350
350
|
// and on the event loop), so it's informational, not an issue. The
|
|
351
351
|
// addon was digest-verified at load time by nativeBlake3().
|
|
352
352
|
{
|
|
353
|
-
const { nativeBlake3 } = await import("
|
|
353
|
+
const { nativeBlake3 } = await import("../../native/blake3.js");
|
|
354
354
|
const addon = nativeBlake3();
|
|
355
355
|
checks.push(
|
|
356
356
|
addon
|
|
@@ -370,7 +370,7 @@ export async function collectDoctorReport(opts: {
|
|
|
370
370
|
// ~/.talon/ns is the symlink farm only (file mounts fine, no live
|
|
371
371
|
// proc//plugins views), so it's informational, not an issue.
|
|
372
372
|
{
|
|
373
|
-
const { nativeFuseFs } = await import("
|
|
373
|
+
const { nativeFuseFs } = await import("../../native/fusefs.js");
|
|
374
374
|
const addon = nativeFuseFs();
|
|
375
375
|
checks.push(
|
|
376
376
|
addon
|
|
@@ -392,7 +392,7 @@ export async function collectDoctorReport(opts: {
|
|
|
392
392
|
// stale or the package is incomplete — caught at check time, not
|
|
393
393
|
// mid-message when a backend assembles its system prompt.
|
|
394
394
|
{
|
|
395
|
-
const { loadSystemTemplate } = await import("
|
|
395
|
+
const { loadSystemTemplate } = await import("../prompt/index.js");
|
|
396
396
|
try {
|
|
397
397
|
const sample = loadSystemTemplate("workspace");
|
|
398
398
|
checks.push(
|
|
@@ -423,7 +423,7 @@ export async function collectDoctorReport(opts: {
|
|
|
423
423
|
// is which is the difference between "why didn't my prompt update?"
|
|
424
424
|
// and a one-line answer.
|
|
425
425
|
{
|
|
426
|
-
const { promptSeedReport } = await import("
|
|
426
|
+
const { promptSeedReport } = await import("../../util/workspace.js");
|
|
427
427
|
try {
|
|
428
428
|
const { tracking, edited } = promptSeedReport();
|
|
429
429
|
if (tracking.length + edited.length > 0) {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { Backend } from "../../agent-runtime/capabilities.js";
|
|
9
|
-
import type { TalonConfig } from "
|
|
9
|
+
import type { TalonConfig } from "../../config/index.js";
|
|
10
10
|
import { type BackendInitContext } from "../../agent-runtime/backend-registry.js";
|
|
11
11
|
import { log } from "../../../util/log.js";
|
|
12
12
|
import { roleHolder } from "./holders.js";
|
|
@@ -21,7 +21,7 @@ export async function performPluginReload(
|
|
|
21
21
|
): Promise<{ names: string[] }> {
|
|
22
22
|
const { reloadPlugins, getPluginPromptAdditions } =
|
|
23
23
|
await import("../../plugin/index.js");
|
|
24
|
-
const { rebuildSystemPrompt } = await import("
|
|
24
|
+
const { rebuildSystemPrompt } = await import("../../config/index.js");
|
|
25
25
|
const { notifyPromptInputsChanged } =
|
|
26
26
|
await import("../../prompt/invalidation.js");
|
|
27
27
|
|