@cjhyy/code-shell-core 0.5.0-rc.1 → 0.5.0-rc.2
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/dist/agent/agent-definition-registry.d.ts +18 -3
- package/dist/agent/agent-definition-registry.js +47 -18
- package/dist/agent/agent-definition.d.ts +17 -0
- package/dist/agent/agent-definition.js +22 -1
- package/dist/arena/arena.js +11 -12
- package/dist/arena/context/context-tools.js +2 -4
- package/dist/arena/context/within-root.d.ts +7 -0
- package/dist/arena/context/within-root.js +15 -0
- package/dist/arena/iterate/phases/argue.js +8 -2
- package/dist/arena/iterate/phases/revise.js +1 -1
- package/dist/arena/iterate/phases/tournament.js +3 -3
- package/dist/arena/phases/adjudication.js +1 -4
- package/dist/arena/phases/build-consensus.js +1 -4
- package/dist/arena/phases/cross-review.js +2 -8
- package/dist/arena/phases/debate-rounds.js +1 -4
- package/dist/arena/phases/participant-research.js +1 -4
- package/dist/arena/phases/planning-detail-expansion.js +8 -10
- package/dist/arena/planner.js +0 -1
- package/dist/arena/providers/docs.d.ts +1 -0
- package/dist/arena/providers/docs.js +5 -2
- package/dist/arena/providers/repo.d.ts +1 -0
- package/dist/arena/providers/repo.js +5 -2
- package/dist/arena/strategies/utils.js +36 -3
- package/dist/arena/transitions.d.ts +7 -2
- package/dist/arena/transitions.js +9 -4
- package/dist/arena/types.d.ts +8 -2
- package/dist/automation/cron-expr.d.ts +31 -0
- package/dist/automation/cron-expr.js +151 -0
- package/dist/automation/index.d.ts +41 -0
- package/dist/automation/index.js +39 -0
- package/dist/automation/runner.d.ts +67 -0
- package/dist/automation/runner.js +56 -0
- package/dist/automation/scheduler.d.ts +156 -0
- package/dist/automation/scheduler.js +546 -0
- package/dist/automation/store.d.ts +39 -0
- package/dist/automation/store.js +119 -0
- package/dist/automation/write-policy.d.ts +34 -0
- package/dist/automation/write-policy.js +113 -0
- package/dist/automation/write-run.d.ts +51 -0
- package/dist/automation/write-run.js +38 -0
- package/dist/capability-control/index.d.ts +5 -0
- package/dist/capability-control/index.js +3 -0
- package/dist/capability-control/overlay.d.ts +49 -0
- package/dist/capability-control/overlay.js +89 -0
- package/dist/capability-control/project.d.ts +65 -0
- package/dist/capability-control/project.js +147 -0
- package/dist/capability-control/service.d.ts +70 -0
- package/dist/capability-control/service.js +147 -0
- package/dist/capability-control/types.d.ts +62 -0
- package/dist/capability-control/types.js +17 -0
- package/dist/cli/agent-server-stdio.d.ts +12 -1
- package/dist/cli/agent-server-stdio.js +114 -19
- package/dist/cli/agent-server-tcp.d.ts +20 -0
- package/dist/cli/agent-server-tcp.js +120 -0
- package/dist/cli/graceful-shutdown.d.ts +27 -0
- package/dist/cli/graceful-shutdown.js +30 -0
- package/dist/context/compaction.js +23 -15
- package/dist/context/manager.d.ts +0 -20
- package/dist/context/manager.js +0 -37
- package/dist/cron/cron-runtime.d.ts +2 -0
- package/dist/cron/cron-runtime.js +2 -0
- package/dist/cron/cron-store.d.ts +2 -0
- package/dist/cron/cron-store.js +2 -0
- package/dist/cron/scheduler.d.ts +5 -32
- package/dist/cron/scheduler.js +5 -113
- package/dist/data/openrouter-sync.js +1 -1
- package/dist/engine/engine.d.ts +208 -14
- package/dist/engine/engine.js +754 -169
- package/dist/engine/goal.d.ts +42 -0
- package/dist/engine/goal.js +52 -0
- package/dist/engine/image-compression.d.ts +81 -0
- package/dist/engine/image-compression.js +186 -0
- package/dist/engine/image-policy.d.ts +152 -0
- package/dist/engine/image-policy.js +165 -0
- package/dist/engine/reactive-threshold.d.ts +13 -0
- package/dist/engine/reactive-threshold.js +17 -0
- package/dist/engine/runtime.js +7 -0
- package/dist/engine/session-title.d.ts +13 -0
- package/dist/engine/session-title.js +34 -0
- package/dist/engine/turn-loop.d.ts +29 -8
- package/dist/engine/turn-loop.js +498 -316
- package/dist/git/parse-log.d.ts +13 -0
- package/dist/git/parse-log.js +21 -0
- package/dist/git/utils.d.ts +8 -6
- package/dist/git/utils.js +57 -26
- package/dist/git/worktree.js +33 -18
- package/dist/hooks/events.d.ts +23 -1
- package/dist/hooks/goal-stop-hook.d.ts +30 -0
- package/dist/hooks/goal-stop-hook.js +102 -0
- package/dist/hooks/hook-output.d.ts +33 -0
- package/dist/hooks/hook-output.js +79 -0
- package/dist/hooks/registry.d.ts +7 -0
- package/dist/hooks/registry.js +38 -1
- package/dist/hooks/shell-runner.d.ts +2 -0
- package/dist/hooks/shell-runner.js +43 -2
- package/dist/index.d.ts +31 -6
- package/dist/index.js +30 -3
- package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
- package/dist/llm/capabilities/reasoning-control.js +38 -0
- package/dist/llm/capabilities/rules.js +33 -3
- package/dist/llm/capabilities/types.d.ts +22 -2
- package/dist/llm/clamp-max-tokens.d.ts +11 -0
- package/dist/llm/clamp-max-tokens.js +17 -0
- package/dist/llm/client-base.d.ts +41 -4
- package/dist/llm/client-base.js +67 -13
- package/dist/llm/client-factory.d.ts +3 -3
- package/dist/llm/client-factory.js +2 -2
- package/dist/llm/model-pool.d.ts +15 -11
- package/dist/llm/model-pool.js +23 -20
- package/dist/llm/provider-catalog.d.ts +2 -2
- package/dist/llm/providers/anthropic.d.ts +32 -2
- package/dist/llm/providers/anthropic.js +147 -8
- package/dist/llm/providers/openai.d.ts +11 -2
- package/dist/llm/providers/openai.js +253 -52
- package/dist/llm/reasoning-setting.d.ts +51 -0
- package/dist/llm/reasoning-setting.js +32 -0
- package/dist/llm/stop-reason.d.ts +13 -0
- package/dist/llm/stop-reason.js +21 -0
- package/dist/llm/strip-vision.d.ts +32 -0
- package/dist/llm/strip-vision.js +94 -0
- package/dist/llm/types.d.ts +5 -6
- package/dist/logging/logger.js +18 -4
- package/dist/logging/sanitize-messages.d.ts +10 -0
- package/dist/logging/sanitize-messages.js +90 -0
- package/dist/lsp/client.js +28 -8
- package/dist/lsp/manager.js +2 -1
- package/dist/lsp/root-path.d.ts +9 -0
- package/dist/lsp/root-path.js +12 -0
- package/dist/onboarding.js +18 -11
- package/dist/plugins/gitOps.d.ts +34 -0
- package/dist/plugins/gitOps.js +59 -3
- package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
- package/dist/plugins/installer/codex/convertAgents.js +55 -0
- package/dist/plugins/installer/codex/convertMcp.d.ts +8 -0
- package/dist/plugins/installer/codex/convertMcp.js +45 -0
- package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
- package/dist/plugins/installer/codex/convertSkills.js +33 -0
- package/dist/plugins/installer/detectFormat.d.ts +2 -0
- package/dist/plugins/installer/detectFormat.js +6 -0
- package/dist/plugins/installer/install.d.ts +7 -0
- package/dist/plugins/installer/install.js +99 -0
- package/dist/plugins/installer/installFromSource.d.ts +13 -0
- package/dist/plugins/installer/installFromSource.js +45 -0
- package/dist/plugins/installer/list.d.ts +9 -0
- package/dist/plugins/installer/list.js +30 -0
- package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
- package/dist/plugins/installer/loadPluginAgents.js +23 -0
- package/dist/plugins/installer/loadPluginMcp.d.ts +7 -0
- package/dist/plugins/installer/loadPluginMcp.js +74 -0
- package/dist/plugins/installer/parseSource.d.ts +20 -0
- package/dist/plugins/installer/parseSource.js +74 -0
- package/dist/plugins/installer/paths.d.ts +5 -0
- package/dist/plugins/installer/paths.js +25 -0
- package/dist/plugins/installer/types.d.ts +49 -0
- package/dist/plugins/installer/types.js +27 -0
- package/dist/plugins/installer/uninstall.d.ts +2 -0
- package/dist/plugins/installer/uninstall.js +14 -0
- package/dist/plugins/installer/update.d.ts +14 -0
- package/dist/plugins/installer/update.js +65 -0
- package/dist/plugins/loadPluginHooks.d.ts +8 -1
- package/dist/plugins/loadPluginHooks.js +11 -1
- package/dist/plugins/marketplaceManager.d.ts +8 -1
- package/dist/plugins/marketplaceManager.js +38 -4
- package/dist/plugins/pluginCommandHook.js +34 -0
- package/dist/plugins/pluginInstaller.d.ts +21 -0
- package/dist/plugins/pluginInstaller.js +128 -29
- package/dist/plugins/schemas.js +40 -6
- package/dist/plugins/types.d.ts +4 -0
- package/dist/preset/index.js +16 -0
- package/dist/prompt/composer.d.ts +4 -0
- package/dist/prompt/composer.js +28 -4
- package/dist/prompt/sections/orchestration.md +8 -0
- package/dist/protocol/chat-session-manager.d.ts +8 -1
- package/dist/protocol/chat-session-manager.js +10 -0
- package/dist/protocol/chat-session.d.ts +17 -0
- package/dist/protocol/chat-session.js +28 -0
- package/dist/protocol/redact.d.ts +50 -0
- package/dist/protocol/redact.js +71 -0
- package/dist/protocol/server.d.ts +41 -2
- package/dist/protocol/server.js +231 -33
- package/dist/protocol/tcp-transport.d.ts +45 -0
- package/dist/protocol/tcp-transport.js +74 -0
- package/dist/protocol/types.d.ts +23 -0
- package/dist/protocol/types.js +6 -0
- package/dist/remote/bridge.d.ts +11 -2
- package/dist/remote/bridge.js +61 -33
- package/dist/run/ArtifactTracker.js +5 -4
- package/dist/run/EngineRunner.d.ts +27 -1
- package/dist/run/EngineRunner.js +46 -8
- package/dist/run/FileRunStore.js +32 -8
- package/dist/run/RunLock.d.ts +28 -2
- package/dist/run/RunLock.js +49 -7
- package/dist/run/RunManager.js +51 -3
- package/dist/run/RunQueue.d.ts +1 -0
- package/dist/run/RunQueue.js +8 -2
- package/dist/run/factory.d.ts +7 -0
- package/dist/run/factory.js +1 -0
- package/dist/run/index.d.ts +2 -2
- package/dist/run/index.js +1 -1
- package/dist/run/redirect-target.d.ts +7 -0
- package/dist/run/redirect-target.js +13 -0
- package/dist/run/types.js +1 -1
- package/dist/services/browser-open.d.ts +13 -0
- package/dist/services/browser-open.js +16 -0
- package/dist/services/dream-consolidation.d.ts +57 -0
- package/dist/services/dream-consolidation.js +151 -0
- package/dist/services/memory-orchestrator.js +18 -0
- package/dist/services/notifier.d.ts +8 -0
- package/dist/services/notifier.js +39 -25
- package/dist/services/oauth.js +5 -7
- package/dist/services/session-memory-sort.d.ts +8 -0
- package/dist/services/session-memory-sort.js +9 -0
- package/dist/services/session-memory.js +8 -9
- package/dist/session/file-history.js +10 -3
- package/dist/session/session-manager.d.ts +23 -1
- package/dist/session/session-manager.js +73 -2
- package/dist/settings/disk-defaults.d.ts +35 -0
- package/dist/settings/disk-defaults.js +24 -0
- package/dist/settings/manager.d.ts +33 -0
- package/dist/settings/manager.js +94 -1
- package/dist/settings/personalization.d.ts +19 -0
- package/dist/settings/personalization.js +7 -0
- package/dist/settings/schema.d.ts +1142 -126
- package/dist/settings/schema.js +119 -10
- package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
- package/dist/tool-system/builtin/add-marketplace.js +76 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +11 -0
- package/dist/tool-system/builtin/agent-registry.js +8 -4
- package/dist/tool-system/builtin/agent.d.ts +29 -10
- package/dist/tool-system/builtin/agent.js +108 -52
- package/dist/tool-system/builtin/apply-patch/index.js +22 -3
- package/dist/tool-system/builtin/arena.js +6 -7
- package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
- package/dist/tool-system/builtin/complete-goal.js +45 -0
- package/dist/tool-system/builtin/cron.js +53 -9
- package/dist/tool-system/builtin/edit.d.ts +2 -1
- package/dist/tool-system/builtin/edit.js +6 -1
- package/dist/tool-system/builtin/generate-image.d.ts +25 -0
- package/dist/tool-system/builtin/generate-image.js +146 -0
- package/dist/tool-system/builtin/glob.js +7 -0
- package/dist/tool-system/builtin/grep.js +6 -0
- package/dist/tool-system/builtin/index.d.ts +18 -1
- package/dist/tool-system/builtin/index.js +62 -1
- package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
- package/dist/tool-system/builtin/notebook-edit.js +8 -1
- package/dist/tool-system/builtin/read.d.ts +2 -1
- package/dist/tool-system/builtin/read.js +9 -1
- package/dist/tool-system/builtin/sleep.js +9 -3
- package/dist/tool-system/builtin/task.js +4 -1
- package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
- package/dist/tool-system/builtin/update-automation-memory.js +60 -0
- package/dist/tool-system/builtin/view-image.d.ts +18 -0
- package/dist/tool-system/builtin/view-image.js +96 -0
- package/dist/tool-system/builtin/web-search.d.ts +4 -1
- package/dist/tool-system/builtin/web-search.js +36 -3
- package/dist/tool-system/builtin/write.d.ts +2 -1
- package/dist/tool-system/builtin/write.js +7 -1
- package/dist/tool-system/context.d.ts +12 -0
- package/dist/tool-system/executor.d.ts +0 -1
- package/dist/tool-system/executor.js +34 -40
- package/dist/tool-system/investigation-guard.d.ts +4 -1
- package/dist/tool-system/investigation-guard.js +19 -3
- package/dist/tool-system/mcp-manager.d.ts +36 -12
- package/dist/tool-system/mcp-manager.js +173 -10
- package/dist/tool-system/path-policy.d.ts +94 -0
- package/dist/tool-system/path-policy.js +279 -0
- package/dist/tool-system/permission.js +43 -50
- package/dist/tool-system/plan-mode-allowlist.d.ts +21 -0
- package/dist/tool-system/plan-mode-allowlist.js +43 -0
- package/dist/tool-system/registry.js +12 -1
- package/dist/tool-system/validation.d.ts +10 -0
- package/dist/tool-system/validation.js +16 -3
- package/dist/types.d.ts +90 -15
- package/dist/utils/format.js +4 -2
- package/dist/utils/lockfile.js +9 -2
- package/dist/utils/theme.d.ts +6 -0
- package/dist/utils/theme.js +4 -2
- package/package.json +2 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-server-tcp — headless server entry point over TCP (Phase 6).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors agent-server-stdio.ts (same EngineRuntime + ChatSessionManager +
|
|
5
|
+
* AgentServer bootstrap), but listens on a TCP socket instead of stdio and
|
|
6
|
+
* also starts the in-process automation scheduler so a deployed server runs
|
|
7
|
+
* scheduled jobs 7x24 with no Electron/GUI.
|
|
8
|
+
*
|
|
9
|
+
* The automation module is the SAME zero-env-dependency module the desktop
|
|
10
|
+
* loads (startAutomation) — this is the "thin server host" the plan's D2
|
|
11
|
+
* describes: one module, two hosts.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* AGENT_TCP_PORT=4321 node dist/cli/agent-server-tcp.js
|
|
15
|
+
*
|
|
16
|
+
* v1 SECURITY: binds 127.0.0.1 by default and has NO authentication. Do not
|
|
17
|
+
* expose to a public interface without adding auth (token/TLS). Use SSH
|
|
18
|
+
* tunneling for remote access in v1.
|
|
19
|
+
*/
|
|
20
|
+
import { Engine } from "../engine/engine.js";
|
|
21
|
+
import { EngineRuntime } from "../engine/runtime.js";
|
|
22
|
+
import { ChatSessionManager } from "../protocol/chat-session-manager.js";
|
|
23
|
+
import { AgentServer } from "../protocol/server.js";
|
|
24
|
+
import { listenTcp } from "../protocol/tcp-transport.js";
|
|
25
|
+
import { SettingsManager } from "../settings/manager.js";
|
|
26
|
+
import { personalizationFrom } from "../settings/personalization.js";
|
|
27
|
+
import { MCPManager } from "../tool-system/mcp-manager.js";
|
|
28
|
+
import { mergePluginMcpServers } from "../plugins/installer/loadPluginMcp.js";
|
|
29
|
+
import { CostTracker } from "../cost-tracker.js";
|
|
30
|
+
import { HeadlessApprovalBackend } from "../tool-system/permission.js";
|
|
31
|
+
import { createRunManager } from "../run/factory.js";
|
|
32
|
+
import { startAutomation } from "../automation/index.js";
|
|
33
|
+
import { CronStore, defaultCronStorePath } from "../automation/store.js";
|
|
34
|
+
const cwd = process.env.AGENT_CWD ?? process.cwd();
|
|
35
|
+
const port = Number(process.env.AGENT_TCP_PORT ?? "4321");
|
|
36
|
+
const host = process.env.AGENT_TCP_HOST ?? "127.0.0.1";
|
|
37
|
+
const settingsManager = new SettingsManager(cwd, "full");
|
|
38
|
+
const settings = settingsManager.get();
|
|
39
|
+
const llmConfig = {
|
|
40
|
+
provider: settings.model.provider,
|
|
41
|
+
model: settings.model.name,
|
|
42
|
+
apiKey: settings.model.apiKey ?? "",
|
|
43
|
+
baseUrl: settings.model.baseUrl,
|
|
44
|
+
maxTokens: settings.model.maxTokens,
|
|
45
|
+
};
|
|
46
|
+
// ── Shared runtime (same bootstrap as stdio) ─────────────────────
|
|
47
|
+
const seedEngine = new Engine({ llm: llmConfig, cwd, settingsScope: "full" });
|
|
48
|
+
const modelPool = seedEngine.getModelPool();
|
|
49
|
+
const toolRegistry = seedEngine.getToolRegistry();
|
|
50
|
+
const resolvedLlmConfig = seedEngine.getConfig().llm;
|
|
51
|
+
const resolvedClientDefaults = seedEngine.getConfig().clientDefaults;
|
|
52
|
+
const mcpPool = new MCPManager(toolRegistry);
|
|
53
|
+
const costTracker = new CostTracker();
|
|
54
|
+
const runtime = new EngineRuntime({
|
|
55
|
+
modelPool,
|
|
56
|
+
toolRegistry,
|
|
57
|
+
settings: settingsManager,
|
|
58
|
+
mcpPool,
|
|
59
|
+
costTracker,
|
|
60
|
+
});
|
|
61
|
+
const chatManager = new ChatSessionManager({
|
|
62
|
+
runtime,
|
|
63
|
+
engineFactory: (slice) => new Engine({
|
|
64
|
+
llm: runtime.modelPool.resolveLLMConfig() ?? resolvedLlmConfig,
|
|
65
|
+
clientDefaults: resolvedClientDefaults,
|
|
66
|
+
cwd,
|
|
67
|
+
runtime,
|
|
68
|
+
settingsScope: "full",
|
|
69
|
+
mcpServers: mergePluginMcpServers(settings.mcpServers ?? {}, settings.disabledPlugins ?? []),
|
|
70
|
+
permissionMode: slice.permissionMode,
|
|
71
|
+
preset: slice.preset,
|
|
72
|
+
customSystemPrompt: slice.customSystemPrompt,
|
|
73
|
+
appendSystemPrompt: slice.appendSystemPrompt,
|
|
74
|
+
// Personalization + instruction compat come from disk settings only
|
|
75
|
+
// (not per-request slice overrides) — same disk-only contract as the
|
|
76
|
+
// stdio host. Shared helper keeps the three fields wired identically.
|
|
77
|
+
...personalizationFrom(settings.agent),
|
|
78
|
+
maxTurns: slice.maxTurns,
|
|
79
|
+
maxContextTokens: slice.maxContextTokens,
|
|
80
|
+
...(slice.cwd ? { cwd: slice.cwd } : {}),
|
|
81
|
+
}),
|
|
82
|
+
maxSessions: 16,
|
|
83
|
+
idleTtlMs: 30 * 60 * 1000,
|
|
84
|
+
});
|
|
85
|
+
chatManager.startIdleSweeper();
|
|
86
|
+
// ── Automation (same module the desktop loads) ──────────────────
|
|
87
|
+
// Read-only by default until write tiers are configured per job. Runs land in
|
|
88
|
+
// the RunStore so history is queryable.
|
|
89
|
+
const automationRunManager = createRunManager({
|
|
90
|
+
llm: resolvedLlmConfig,
|
|
91
|
+
cwd,
|
|
92
|
+
permissionMode: "default",
|
|
93
|
+
approvalBackend: new HeadlessApprovalBackend("approve-read-only"),
|
|
94
|
+
});
|
|
95
|
+
const automation = startAutomation({
|
|
96
|
+
store: new CronStore(defaultCronStorePath()),
|
|
97
|
+
runManager: automationRunManager,
|
|
98
|
+
});
|
|
99
|
+
// ── Serve over TCP ──────────────────────────────────────────────
|
|
100
|
+
// One AgentServer per accepted connection, all sharing the same chatManager.
|
|
101
|
+
const servers = new Set();
|
|
102
|
+
listenTcp({ port, host }, (transport) => {
|
|
103
|
+
const server = new AgentServer({ chatManager, transport });
|
|
104
|
+
servers.add(server);
|
|
105
|
+
})
|
|
106
|
+
.then((listener) => {
|
|
107
|
+
process.stderr.write(`[code-shell] automation server listening on ${host}:${listener.port}\n`);
|
|
108
|
+
const shutdown = () => {
|
|
109
|
+
automation.stop();
|
|
110
|
+
for (const s of servers)
|
|
111
|
+
s.close();
|
|
112
|
+
void listener.close().then(() => process.exit(0));
|
|
113
|
+
};
|
|
114
|
+
process.on("SIGTERM", shutdown);
|
|
115
|
+
process.on("SIGINT", shutdown);
|
|
116
|
+
})
|
|
117
|
+
.catch((err) => {
|
|
118
|
+
process.stderr.write(`[code-shell] failed to start automation server: ${String(err)}\n`);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Minimal surface we need from a server to shut it down cleanly. */
|
|
2
|
+
interface Closable {
|
|
3
|
+
close(): void;
|
|
4
|
+
}
|
|
5
|
+
/** Minimal surface we need from `process` (injectable for tests). */
|
|
6
|
+
interface ProcLike {
|
|
7
|
+
on(event: string, listener: (...args: unknown[]) => void): unknown;
|
|
8
|
+
exit(code?: number): void;
|
|
9
|
+
}
|
|
10
|
+
export interface GracefulShutdownOptions {
|
|
11
|
+
/** Defaults to the real `process`. */
|
|
12
|
+
proc?: ProcLike;
|
|
13
|
+
/** Signals to handle. Defaults to SIGTERM, SIGINT, SIGHUP. */
|
|
14
|
+
signals?: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Register signal handlers that cleanly shut down a long-lived server before
|
|
18
|
+
* the process exits. Without this, SIGTERM/SIGINT (Ctrl+C)/SIGHUP terminate
|
|
19
|
+
* the process immediately, leaking the idle sweeper interval, open sessions,
|
|
20
|
+
* pending approvals, and child processes (MCP servers, tools).
|
|
21
|
+
*
|
|
22
|
+
* Idempotent: the first signal runs close() exactly once; later signals (or a
|
|
23
|
+
* second handler firing) are ignored. A throwing close() is swallowed so the
|
|
24
|
+
* process still exits.
|
|
25
|
+
*/
|
|
26
|
+
export declare function installGracefulShutdown(server: Closable, options?: GracefulShutdownOptions): void;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register signal handlers that cleanly shut down a long-lived server before
|
|
3
|
+
* the process exits. Without this, SIGTERM/SIGINT (Ctrl+C)/SIGHUP terminate
|
|
4
|
+
* the process immediately, leaking the idle sweeper interval, open sessions,
|
|
5
|
+
* pending approvals, and child processes (MCP servers, tools).
|
|
6
|
+
*
|
|
7
|
+
* Idempotent: the first signal runs close() exactly once; later signals (or a
|
|
8
|
+
* second handler firing) are ignored. A throwing close() is swallowed so the
|
|
9
|
+
* process still exits.
|
|
10
|
+
*/
|
|
11
|
+
export function installGracefulShutdown(server, options = {}) {
|
|
12
|
+
const proc = options.proc ?? globalThis.process;
|
|
13
|
+
const signals = options.signals ?? ["SIGTERM", "SIGINT", "SIGHUP"];
|
|
14
|
+
let shuttingDown = false;
|
|
15
|
+
const shutdown = () => {
|
|
16
|
+
if (shuttingDown)
|
|
17
|
+
return;
|
|
18
|
+
shuttingDown = true;
|
|
19
|
+
try {
|
|
20
|
+
server.close();
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Best-effort cleanup — never block exit on a close() failure.
|
|
24
|
+
}
|
|
25
|
+
proc.exit(0);
|
|
26
|
+
};
|
|
27
|
+
for (const sig of signals) {
|
|
28
|
+
proc.on(sig, shutdown);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -299,28 +299,36 @@ export function applyToolResultBudget(messages, maxTotalChars = 100_000) {
|
|
|
299
299
|
return msg;
|
|
300
300
|
// Sort by size descending — truncate largest first
|
|
301
301
|
resultBlocks.sort((a, b) => b.size - a.size);
|
|
302
|
+
// Build the exact replacement for a block, so the running budget uses the
|
|
303
|
+
// real post-truncation length (the old code assumed a flat ~200 chars,
|
|
304
|
+
// but the replacement is ~150 boilerplate + up to 500 preview ≈ 650+,
|
|
305
|
+
// which under-truncated and could even leave the message LARGER).
|
|
306
|
+
const truncate = (content) => {
|
|
307
|
+
const preview = content.slice(0, 500);
|
|
308
|
+
const sizeKb = (content.length / 1000).toFixed(0);
|
|
309
|
+
return (`Output too large (${sizeKb}KB) — truncated to fit the per-message budget. ` +
|
|
310
|
+
`Re-run the originating tool if you need the full output.\n\n` +
|
|
311
|
+
`Preview (first 500 chars):\n${preview}`);
|
|
312
|
+
};
|
|
302
313
|
let remaining = totalSize;
|
|
303
|
-
const
|
|
314
|
+
const replacements = new Map();
|
|
304
315
|
for (const rb of resultBlocks) {
|
|
305
316
|
if (remaining <= maxTotalChars)
|
|
306
317
|
break;
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
318
|
+
const original = msg.content[rb.index].content;
|
|
319
|
+
const replaced = truncate(original);
|
|
320
|
+
// Only truncate if it actually shrinks the block; otherwise skip it
|
|
321
|
+
// (truncating a barely-oversized block would grow the message).
|
|
322
|
+
if (replaced.length >= rb.size)
|
|
323
|
+
continue;
|
|
324
|
+
replacements.set(rb.index, replaced);
|
|
325
|
+
remaining -= rb.size - replaced.length;
|
|
310
326
|
}
|
|
311
|
-
if (
|
|
327
|
+
if (replacements.size === 0)
|
|
312
328
|
return msg;
|
|
313
329
|
const newContent = msg.content.map((block, i) => {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
const preview = typeof block.content === "string" ? block.content.slice(0, 500) : "";
|
|
317
|
-
const sizeKb = (block.content.length / 1000).toFixed(0);
|
|
318
|
-
return {
|
|
319
|
-
...block,
|
|
320
|
-
content: `Output too large (${sizeKb}KB) — truncated to fit the per-message budget. ` +
|
|
321
|
-
`Re-run the originating tool if you need the full output.\n\n` +
|
|
322
|
-
`Preview (first 500 chars):\n${preview}`,
|
|
323
|
-
};
|
|
330
|
+
const replaced = replacements.get(i);
|
|
331
|
+
return replaced === undefined ? block : { ...block, content: replaced };
|
|
324
332
|
});
|
|
325
333
|
return { ...msg, content: newContent };
|
|
326
334
|
});
|
|
@@ -39,7 +39,6 @@ export type OnCompactFn = (info: {
|
|
|
39
39
|
}) => void;
|
|
40
40
|
export declare class ContextManager {
|
|
41
41
|
private config;
|
|
42
|
-
private toolCallHashes;
|
|
43
42
|
private summarizeFn;
|
|
44
43
|
private consecutiveSummaryFailures;
|
|
45
44
|
private lastSummary;
|
|
@@ -123,23 +122,4 @@ export declare class ContextManager {
|
|
|
123
122
|
needsCompact: boolean;
|
|
124
123
|
needsEmergency: boolean;
|
|
125
124
|
};
|
|
126
|
-
/**
|
|
127
|
-
* Deduplicate tool calls by hashing arguments.
|
|
128
|
-
*/
|
|
129
|
-
deduplicateToolCalls(calls: Array<{
|
|
130
|
-
toolName: string;
|
|
131
|
-
args: Record<string, unknown>;
|
|
132
|
-
}>): {
|
|
133
|
-
toExecute: typeof calls;
|
|
134
|
-
cached: Array<{
|
|
135
|
-
toolName: string;
|
|
136
|
-
args: Record<string, unknown>;
|
|
137
|
-
result: string;
|
|
138
|
-
}>;
|
|
139
|
-
};
|
|
140
|
-
/**
|
|
141
|
-
* Record a tool call result for dedup tracking.
|
|
142
|
-
*/
|
|
143
|
-
recordToolResult(toolName: string, args: Record<string, unknown>, result: string): void;
|
|
144
|
-
private hashCall;
|
|
145
125
|
}
|
package/dist/context/manager.js
CHANGED
|
@@ -39,7 +39,6 @@ function defaultKeepRecent(maxTokens) {
|
|
|
39
39
|
}
|
|
40
40
|
export class ContextManager {
|
|
41
41
|
config;
|
|
42
|
-
toolCallHashes = new Map();
|
|
43
42
|
summarizeFn;
|
|
44
43
|
consecutiveSummaryFailures = 0;
|
|
45
44
|
lastSummary;
|
|
@@ -384,40 +383,4 @@ export class ContextManager {
|
|
|
384
383
|
needsEmergency: ratio >= this.config.summarizeAtRatio,
|
|
385
384
|
};
|
|
386
385
|
}
|
|
387
|
-
/**
|
|
388
|
-
* Deduplicate tool calls by hashing arguments.
|
|
389
|
-
*/
|
|
390
|
-
deduplicateToolCalls(calls) {
|
|
391
|
-
const toExecute = [];
|
|
392
|
-
const cached = [];
|
|
393
|
-
for (const call of calls) {
|
|
394
|
-
const hash = this.hashCall(call.toolName, call.args);
|
|
395
|
-
const existing = this.toolCallHashes.get(hash);
|
|
396
|
-
if (existing && existing.count >= 2) {
|
|
397
|
-
cached.push({ ...call, result: existing.lastResult });
|
|
398
|
-
existing.count++;
|
|
399
|
-
}
|
|
400
|
-
else {
|
|
401
|
-
toExecute.push(call);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
return { toExecute, cached };
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Record a tool call result for dedup tracking.
|
|
408
|
-
*/
|
|
409
|
-
recordToolResult(toolName, args, result) {
|
|
410
|
-
const hash = this.hashCall(toolName, args);
|
|
411
|
-
const existing = this.toolCallHashes.get(hash);
|
|
412
|
-
if (existing) {
|
|
413
|
-
existing.count++;
|
|
414
|
-
existing.lastResult = result;
|
|
415
|
-
}
|
|
416
|
-
else {
|
|
417
|
-
this.toolCallHashes.set(hash, { count: 1, lastResult: result });
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
hashCall(toolName, args) {
|
|
421
|
-
return `${toolName}:${JSON.stringify(args)}`;
|
|
422
|
-
}
|
|
423
386
|
}
|
package/dist/cron/scheduler.d.ts
CHANGED
|
@@ -1,34 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Back-compat shim. The cron scheduler moved to `automation/scheduler.ts`
|
|
3
|
+
* (see docs/automation-plan-2026-05-31.md). This re-export keeps existing
|
|
4
|
+
* `../cron/scheduler.js` importers working. New code should import from
|
|
5
|
+
* `../automation/scheduler.js`.
|
|
6
6
|
*/
|
|
7
|
-
export
|
|
8
|
-
id: string;
|
|
9
|
-
name: string;
|
|
10
|
-
schedule: string;
|
|
11
|
-
prompt: string;
|
|
12
|
-
enabled: boolean;
|
|
13
|
-
lastRun?: number;
|
|
14
|
-
nextRun?: number;
|
|
15
|
-
runCount: number;
|
|
16
|
-
createdAt: number;
|
|
17
|
-
}
|
|
18
|
-
declare class CronScheduler {
|
|
19
|
-
private jobs;
|
|
20
|
-
private timers;
|
|
21
|
-
private nextId;
|
|
22
|
-
private onExecute?;
|
|
23
|
-
setExecutor(fn: (job: CronJob) => Promise<void>): void;
|
|
24
|
-
create(name: string, schedule: string, prompt: string): CronJob;
|
|
25
|
-
delete(id: string): boolean;
|
|
26
|
-
list(): CronJob[];
|
|
27
|
-
get(id: string): CronJob | undefined;
|
|
28
|
-
pause(id: string): boolean;
|
|
29
|
-
resume(id: string): boolean;
|
|
30
|
-
stopAll(): void;
|
|
31
|
-
private startTimer;
|
|
32
|
-
}
|
|
33
|
-
export declare const cronScheduler: CronScheduler;
|
|
34
|
-
export {};
|
|
7
|
+
export * from "../automation/scheduler.js";
|
package/dist/cron/scheduler.js
CHANGED
|
@@ -1,115 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Back-compat shim. The cron scheduler moved to `automation/scheduler.ts`
|
|
3
|
+
* (see docs/automation-plan-2026-05-31.md). This re-export keeps existing
|
|
4
|
+
* `../cron/scheduler.js` importers working. New code should import from
|
|
5
|
+
* `../automation/scheduler.js`.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
jobs = new Map();
|
|
9
|
-
timers = new Map();
|
|
10
|
-
nextId = 1;
|
|
11
|
-
onExecute;
|
|
12
|
-
setExecutor(fn) {
|
|
13
|
-
this.onExecute = fn;
|
|
14
|
-
}
|
|
15
|
-
create(name, schedule, prompt) {
|
|
16
|
-
const id = String(this.nextId++);
|
|
17
|
-
const intervalMs = parseSchedule(schedule);
|
|
18
|
-
const job = {
|
|
19
|
-
id,
|
|
20
|
-
name,
|
|
21
|
-
schedule,
|
|
22
|
-
prompt,
|
|
23
|
-
enabled: true,
|
|
24
|
-
nextRun: Date.now() + intervalMs,
|
|
25
|
-
runCount: 0,
|
|
26
|
-
createdAt: Date.now(),
|
|
27
|
-
};
|
|
28
|
-
this.jobs.set(id, job);
|
|
29
|
-
this.startTimer(job, intervalMs);
|
|
30
|
-
return job;
|
|
31
|
-
}
|
|
32
|
-
delete(id) {
|
|
33
|
-
const timer = this.timers.get(id);
|
|
34
|
-
if (timer) {
|
|
35
|
-
clearInterval(timer);
|
|
36
|
-
this.timers.delete(id);
|
|
37
|
-
}
|
|
38
|
-
return this.jobs.delete(id);
|
|
39
|
-
}
|
|
40
|
-
list() {
|
|
41
|
-
return [...this.jobs.values()];
|
|
42
|
-
}
|
|
43
|
-
get(id) {
|
|
44
|
-
return this.jobs.get(id);
|
|
45
|
-
}
|
|
46
|
-
pause(id) {
|
|
47
|
-
const job = this.jobs.get(id);
|
|
48
|
-
if (!job)
|
|
49
|
-
return false;
|
|
50
|
-
job.enabled = false;
|
|
51
|
-
const timer = this.timers.get(id);
|
|
52
|
-
if (timer) {
|
|
53
|
-
clearInterval(timer);
|
|
54
|
-
this.timers.delete(id);
|
|
55
|
-
}
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
resume(id) {
|
|
59
|
-
const job = this.jobs.get(id);
|
|
60
|
-
if (!job)
|
|
61
|
-
return false;
|
|
62
|
-
job.enabled = true;
|
|
63
|
-
const intervalMs = parseSchedule(job.schedule);
|
|
64
|
-
this.startTimer(job, intervalMs);
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
stopAll() {
|
|
68
|
-
for (const timer of this.timers.values()) {
|
|
69
|
-
clearInterval(timer);
|
|
70
|
-
}
|
|
71
|
-
this.timers.clear();
|
|
72
|
-
}
|
|
73
|
-
startTimer(job, intervalMs) {
|
|
74
|
-
if (this.timers.has(job.id)) {
|
|
75
|
-
clearInterval(this.timers.get(job.id));
|
|
76
|
-
}
|
|
77
|
-
const timer = setInterval(async () => {
|
|
78
|
-
if (!job.enabled)
|
|
79
|
-
return;
|
|
80
|
-
job.lastRun = Date.now();
|
|
81
|
-
job.runCount++;
|
|
82
|
-
job.nextRun = Date.now() + intervalMs;
|
|
83
|
-
try {
|
|
84
|
-
await this.onExecute?.(job);
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
// Job execution failed — continue scheduling
|
|
88
|
-
}
|
|
89
|
-
}, intervalMs);
|
|
90
|
-
this.timers.set(job.id, timer);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Parse a schedule string into milliseconds.
|
|
95
|
-
* Supports: "30s", "5m", "1h", "1d", or raw milliseconds.
|
|
96
|
-
*/
|
|
97
|
-
function parseSchedule(schedule) {
|
|
98
|
-
const match = schedule.match(/^(\d+)(s|m|h|d)$/);
|
|
99
|
-
if (match) {
|
|
100
|
-
const value = parseInt(match[1], 10);
|
|
101
|
-
switch (match[2]) {
|
|
102
|
-
case "s": return value * 1000;
|
|
103
|
-
case "m": return value * 60 * 1000;
|
|
104
|
-
case "h": return value * 60 * 60 * 1000;
|
|
105
|
-
case "d": return value * 24 * 60 * 60 * 1000;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// Try raw number (milliseconds)
|
|
109
|
-
const ms = parseInt(schedule, 10);
|
|
110
|
-
if (!isNaN(ms) && ms > 0)
|
|
111
|
-
return ms;
|
|
112
|
-
// Default: 10 minutes
|
|
113
|
-
return 10 * 60 * 1000;
|
|
114
|
-
}
|
|
115
|
-
export const cronScheduler = new CronScheduler();
|
|
7
|
+
export * from "../automation/scheduler.js";
|
|
@@ -47,7 +47,7 @@ export async function syncOpenRouterCatalog(timeoutMs = 15_000) {
|
|
|
47
47
|
return { ok: true, count: models.length };
|
|
48
48
|
}
|
|
49
49
|
catch (err) {
|
|
50
|
-
return { ok: false, count: 0, error: err.message };
|
|
50
|
+
return { ok: false, count: 0, error: err instanceof Error ? err.message : String(err) };
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
export { getOpenRouterSnapshot };
|