@a1hvdy/cc-openclaw 0.30.0 → 0.32.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.
Files changed (207) hide show
  1. package/dist/src/channels/telegram-mirror/card-renderer.js +9 -5
  2. package/dist/src/channels/telegram-mirror/commands.js +0 -8
  3. package/dist/src/channels/telegram-mirror/status-line.js +32 -2
  4. package/dist/src/constants.js +16 -2
  5. package/dist/src/engines/persistent-session.js +11 -0
  6. package/dist/src/lib/config.js +40 -0
  7. package/dist/src/openai-compat/non-streaming-handler.js +2 -2
  8. package/dist/src/openai-compat/streaming-handler.js +121 -9
  9. package/package.json +3 -2
  10. package/dist/src/channels/adapter.d.ts +0 -103
  11. package/dist/src/channels/telegram-mirror/askuser.d.ts +0 -107
  12. package/dist/src/channels/telegram-mirror/burst-accumulator.d.ts +0 -96
  13. package/dist/src/channels/telegram-mirror/callback-mapping.d.ts +0 -61
  14. package/dist/src/channels/telegram-mirror/card-renderer.d.ts +0 -68
  15. package/dist/src/channels/telegram-mirror/card-state.d.ts +0 -83
  16. package/dist/src/channels/telegram-mirror/commands.d.ts +0 -183
  17. package/dist/src/channels/telegram-mirror/compose-buffer.d.ts +0 -71
  18. package/dist/src/channels/telegram-mirror/cost-views.d.ts +0 -58
  19. package/dist/src/channels/telegram-mirror/failure/callback-data-overflow.d.ts +0 -21
  20. package/dist/src/channels/telegram-mirror/failure/gateway-down.d.ts +0 -15
  21. package/dist/src/channels/telegram-mirror/failure/in-flight-conflict.d.ts +0 -15
  22. package/dist/src/channels/telegram-mirror/failure/index.d.ts +0 -23
  23. package/dist/src/channels/telegram-mirror/failure/model-5xx.d.ts +0 -16
  24. package/dist/src/channels/telegram-mirror/failure/network-blip.d.ts +0 -17
  25. package/dist/src/channels/telegram-mirror/failure/pool-exhausted-fallback.d.ts +0 -15
  26. package/dist/src/channels/telegram-mirror/failure/rate-limit.d.ts +0 -16
  27. package/dist/src/channels/telegram-mirror/failure/returning-after-24h.d.ts +0 -14
  28. package/dist/src/channels/telegram-mirror/failure/types.d.ts +0 -30
  29. package/dist/src/channels/telegram-mirror/inbound-handler.d.ts +0 -73
  30. package/dist/src/channels/telegram-mirror/index.d.ts +0 -32
  31. package/dist/src/channels/telegram-mirror/plan-attachment.d.ts +0 -120
  32. package/dist/src/channels/telegram-mirror/quota-reader.d.ts +0 -42
  33. package/dist/src/channels/telegram-mirror/sessions-keyboard.d.ts +0 -84
  34. package/dist/src/channels/telegram-mirror/soak-log.d.ts +0 -99
  35. package/dist/src/channels/telegram-mirror/state-machine.d.ts +0 -113
  36. package/dist/src/channels/telegram-mirror/status-line.d.ts +0 -51
  37. package/dist/src/channels/telegram-mirror/sync-commands.d.ts +0 -100
  38. package/dist/src/channels/telegram-mirror/threshold-watcher.d.ts +0 -54
  39. package/dist/src/channels/telegram-mirror/turn-bridge.d.ts +0 -125
  40. package/dist/src/cli/checks/bridge-wiring.d.ts +0 -14
  41. package/dist/src/cli/checks/config-schema.d.ts +0 -11
  42. package/dist/src/cli/checks/critical-openclaw-json-keys.d.ts +0 -21
  43. package/dist/src/cli/checks/install-path.d.ts +0 -11
  44. package/dist/src/cli/checks/patch-scaffold.d.ts +0 -17
  45. package/dist/src/cli/doctor.d.ts +0 -20
  46. package/dist/src/cli/index.d.ts +0 -8
  47. package/dist/src/cli/migrate.d.ts +0 -29
  48. package/dist/src/command-router/cc-handler.d.ts +0 -67
  49. package/dist/src/command-router/index.d.ts +0 -2
  50. package/dist/src/command-router/launch-policy.d.ts +0 -92
  51. package/dist/src/command-router/resume-policy.d.ts +0 -18
  52. package/dist/src/command-router/turn-formatter.d.ts +0 -19
  53. package/dist/src/config/loader.d.ts +0 -8
  54. package/dist/src/config/schema.d.ts +0 -192
  55. package/dist/src/constants.d.ts +0 -191
  56. package/dist/src/council/build-agent-prompt.d.ts +0 -11
  57. package/dist/src/council/cleanup-worktrees.d.ts +0 -10
  58. package/dist/src/council/consensus.d.ts +0 -20
  59. package/dist/src/council/council.d.ts +0 -67
  60. package/dist/src/council/index.d.ts +0 -2
  61. package/dist/src/council/system-prompt.d.ts +0 -16
  62. package/dist/src/council/write-worktree-claude-md.d.ts +0 -10
  63. package/dist/src/engines/base-oneshot-session.d.ts +0 -87
  64. package/dist/src/engines/heartbeat-guard.d.ts +0 -93
  65. package/dist/src/engines/index.d.ts +0 -8
  66. package/dist/src/engines/persistent-codex-session.d.ts +0 -16
  67. package/dist/src/engines/persistent-cursor-session.d.ts +0 -21
  68. package/dist/src/engines/persistent-custom-session.d.ts +0 -78
  69. package/dist/src/engines/persistent-gemini-session.d.ts +0 -21
  70. package/dist/src/engines/persistent-session.d.ts +0 -95
  71. package/dist/src/engines/resolve-bin.d.ts +0 -14
  72. package/dist/src/engines/subprocess-pool.d.ts +0 -78
  73. package/dist/src/health/handler.d.ts +0 -39
  74. package/dist/src/health/index.d.ts +0 -1
  75. package/dist/src/health/metrics.d.ts +0 -52
  76. package/dist/src/index.d.ts +0 -57
  77. package/dist/src/lib/auto-recovery.d.ts +0 -43
  78. package/dist/src/lib/cache-parity-decide.d.ts +0 -64
  79. package/dist/src/lib/cache-parity.d.ts +0 -38
  80. package/dist/src/lib/cc-cli-scan.d.ts +0 -52
  81. package/dist/src/lib/circuit-breaker.d.ts +0 -21
  82. package/dist/src/lib/config-service.d.ts +0 -106
  83. package/dist/src/lib/config.d.ts +0 -136
  84. package/dist/src/lib/cost-rollup.d.ts +0 -36
  85. package/dist/src/lib/debounce.d.ts +0 -12
  86. package/dist/src/lib/debug-tap.d.ts +0 -13
  87. package/dist/src/lib/domain-error.d.ts +0 -59
  88. package/dist/src/lib/drift-detector.d.ts +0 -46
  89. package/dist/src/lib/env-overrides.d.ts +0 -47
  90. package/dist/src/lib/error-formatter.d.ts +0 -91
  91. package/dist/src/lib/error-renderer.d.ts +0 -20
  92. package/dist/src/lib/heartbeat-config.d.ts +0 -34
  93. package/dist/src/lib/heartbeat-workaround.d.ts +0 -44
  94. package/dist/src/lib/html-render.d.ts +0 -50
  95. package/dist/src/lib/http-agent.d.ts +0 -47
  96. package/dist/src/lib/index.d.ts +0 -7
  97. package/dist/src/lib/index.js +0 -10
  98. package/dist/src/lib/json-array.d.ts +0 -10
  99. package/dist/src/lib/markdown-to-mdv2.d.ts +0 -53
  100. package/dist/src/lib/markdown-v2.d.ts +0 -27
  101. package/dist/src/lib/perf/async-compact.d.ts +0 -26
  102. package/dist/src/lib/perf/direct-sdk.d.ts +0 -26
  103. package/dist/src/lib/perf/haiku-route.d.ts +0 -19
  104. package/dist/src/lib/perf/predictive-continuation.d.ts +0 -18
  105. package/dist/src/lib/perf/read-batch.d.ts +0 -33
  106. package/dist/src/lib/perf/skill-list-collapse.d.ts +0 -22
  107. package/dist/src/lib/perf/speculative-bubble.d.ts +0 -27
  108. package/dist/src/lib/perf/typing-prefetch.d.ts +0 -25
  109. package/dist/src/lib/probes.d.ts +0 -50
  110. package/dist/src/lib/register-guard.d.ts +0 -56
  111. package/dist/src/lib/req-shape-log.d.ts +0 -31
  112. package/dist/src/lib/safe-upstream-probes.d.ts +0 -25
  113. package/dist/src/lib/session-registry.d.ts +0 -66
  114. package/dist/src/lib/spawn-async.d.ts +0 -18
  115. package/dist/src/lib/status-tee-reader.d.ts +0 -29
  116. package/dist/src/lib/sysprompt-strip.d.ts +0 -53
  117. package/dist/src/lib/telegram-bot-api.d.ts +0 -146
  118. package/dist/src/lib/telemetry.d.ts +0 -38
  119. package/dist/src/lib/test-mode.d.ts +0 -26
  120. package/dist/src/lib/trajectory.d.ts +0 -44
  121. package/dist/src/lib/vendor-paths.d.ts +0 -12
  122. package/dist/src/lifecycle/boot.d.ts +0 -48
  123. package/dist/src/lifecycle/patch-manifest.d.ts +0 -82
  124. package/dist/src/lifecycle/phase-import-upstream.d.ts +0 -12
  125. package/dist/src/lifecycle/phase-install-patches.d.ts +0 -12
  126. package/dist/src/lifecycle/phase-schedule-jobs.d.ts +0 -12
  127. package/dist/src/lifecycle/phase-start-server.d.ts +0 -11
  128. package/dist/src/lifecycle/phase-validate-config.d.ts +0 -9
  129. package/dist/src/lifecycle/phase-validate-upstream.d.ts +0 -11
  130. package/dist/src/lifecycle/phase-wire-handlers.d.ts +0 -12
  131. package/dist/src/lifecycle/safe-restart.d.ts +0 -99
  132. package/dist/src/logger.d.ts +0 -14
  133. package/dist/src/mcp/bridge.d.ts +0 -21
  134. package/dist/src/mcp/index.d.ts +0 -2
  135. package/dist/src/models.d.ts +0 -68
  136. package/dist/src/observability/event-bus.d.ts +0 -86
  137. package/dist/src/observability/get-event-bus.d.ts +0 -25
  138. package/dist/src/observability/observability-service.d.ts +0 -19
  139. package/dist/src/observability/perf-telemetry.d.ts +0 -65
  140. package/dist/src/observability/subscribers/metrics.d.ts +0 -11
  141. package/dist/src/observability/subscribers/session-capture.d.ts +0 -15
  142. package/dist/src/openai-compat/autonomy-rule.d.ts +0 -26
  143. package/dist/src/openai-compat/bridges/allowlist.d.ts +0 -19
  144. package/dist/src/openai-compat/bridges/factory.d.ts +0 -30
  145. package/dist/src/openai-compat/bridges/media-bridge.d.ts +0 -34
  146. package/dist/src/openai-compat/bridges/openclaw-api-shim.d.ts +0 -54
  147. package/dist/src/openai-compat/bridges/openclaw-native-tools.d.ts +0 -61
  148. package/dist/src/openai-compat/bridges/openclaw-tool-registry.d.ts +0 -26
  149. package/dist/src/openai-compat/bridges/tts-media-bridge.d.ts +0 -19
  150. package/dist/src/openai-compat/chat-cwd.d.ts +0 -22
  151. package/dist/src/openai-compat/cli-stream-parser.d.ts +0 -134
  152. package/dist/src/openai-compat/index.d.ts +0 -1
  153. package/dist/src/openai-compat/message-extractor.d.ts +0 -84
  154. package/dist/src/openai-compat/mode-flags.d.ts +0 -34
  155. package/dist/src/openai-compat/non-streaming-handler.d.ts +0 -29
  156. package/dist/src/openai-compat/openai-chunk-types.d.ts +0 -35
  157. package/dist/src/openai-compat/openai-compat.d.ts +0 -49
  158. package/dist/src/openai-compat/openai-types.d.ts +0 -71
  159. package/dist/src/openai-compat/parse-route-body.d.ts +0 -24
  160. package/dist/src/openai-compat/prompts.d.ts +0 -47
  161. package/dist/src/openai-compat/request-coalescer.d.ts +0 -77
  162. package/dist/src/openai-compat/response-formatter.d.ts +0 -33
  163. package/dist/src/openai-compat/session-key-resolver.d.ts +0 -41
  164. package/dist/src/openai-compat/skill-resolver.d.ts +0 -59
  165. package/dist/src/openai-compat/sse-translator.d.ts +0 -51
  166. package/dist/src/openai-compat/status-reporter.d.ts +0 -30
  167. package/dist/src/openai-compat/streaming-handler.d.ts +0 -52
  168. package/dist/src/openai-compat/tool-calls-parser.d.ts +0 -34
  169. package/dist/src/openai-compat/tool-results-serializer.d.ts +0 -60
  170. package/dist/src/openai-compat/tts-rule.d.ts +0 -20
  171. package/dist/src/openai-compat/voice-recovery.d.ts +0 -56
  172. package/dist/src/patches/cache-parity-registry.d.ts +0 -103
  173. package/dist/src/patches/claude-md-injection.d.ts +0 -10
  174. package/dist/src/patches/cwd-redirect.d.ts +0 -10
  175. package/dist/src/patches/embedded-server-route.d.ts +0 -23
  176. package/dist/src/patches/pricing-overrides.d.ts +0 -10
  177. package/dist/src/patches/resume-registry-restore.d.ts +0 -11
  178. package/dist/src/patches/session-pid-tracking.d.ts +0 -10
  179. package/dist/src/patches/sysprompt-strip.d.ts +0 -46
  180. package/dist/src/patches/tools-restoration.d.ts +0 -12
  181. package/dist/src/persistence/migration-v0.d.ts +0 -24
  182. package/dist/src/persistence/session-registry.d.ts +0 -58
  183. package/dist/src/proxy/anthropic-adapter.d.ts +0 -136
  184. package/dist/src/proxy/handler.d.ts +0 -39
  185. package/dist/src/proxy/index.d.ts +0 -4
  186. package/dist/src/proxy/schema-cleaner.d.ts +0 -11
  187. package/dist/src/proxy/thought-cache.d.ts +0 -19
  188. package/dist/src/session/embedded-server.d.ts +0 -25
  189. package/dist/src/session/inbox-manager.d.ts +0 -38
  190. package/dist/src/session/index.d.ts +0 -3
  191. package/dist/src/session/persisted-sessions.d.ts +0 -50
  192. package/dist/src/session/session-manager.d.ts +0 -247
  193. package/dist/src/session/watchdogs.d.ts +0 -92
  194. package/dist/src/session-bootstrap/boot-self-heal.d.ts +0 -32
  195. package/dist/src/session-bootstrap/cwd-patch.d.ts +0 -50
  196. package/dist/src/session-bootstrap/index.d.ts +0 -3
  197. package/dist/src/session-bootstrap/resume-registry.d.ts +0 -27
  198. package/dist/src/session-bootstrap/session-hygiene.d.ts +0 -23
  199. package/dist/src/session-bootstrap/sysprompt-strip.d.ts +0 -24
  200. package/dist/src/session-bootstrap/think-conflict-resolver.d.ts +0 -32
  201. package/dist/src/types/route.d.ts +0 -11
  202. package/dist/src/types/runtime-config.d.ts +0 -208
  203. package/dist/src/types/sse.d.ts +0 -29
  204. package/dist/src/types/tool-bridge.d.ts +0 -82
  205. package/dist/src/types/upstream.d.ts +0 -580
  206. package/dist/src/types.d.ts +0 -498
  207. package/dist/src/validation.d.ts +0 -31
@@ -1,67 +0,0 @@
1
- /**
2
- * Council — Multi-agent collaboration engine
3
- *
4
- * Ported from three-minds and adapted to use SessionManager + ISession
5
- * directly (no HTTP/SSE to external services).
6
- *
7
- * Key patterns:
8
- * - Git worktree isolation per agent
9
- * - Two-phase protocol: planning round → execution rounds
10
- * - Consensus voting: all agents vote YES to complete
11
- * - Parallel execution via Promise.allSettled
12
- * - Engine-agnostic: agents can use Claude, Codex, or any ISession engine
13
- */
14
- import { EventEmitter } from 'node:events';
15
- import { type CouncilConfig, type CouncilSession, type CouncilReviewResult, type CouncilAcceptResult, type CouncilRejectResult, type SessionConfig, type SessionInfo, type SendOptions, type SendResult } from '../types.js';
16
- import { type Logger } from '../logger.js';
17
- interface SessionManagerLike {
18
- startSession(config: Partial<SessionConfig> & {
19
- name?: string;
20
- }): Promise<SessionInfo>;
21
- sendMessage(name: string, message: string, options?: Partial<SendOptions>): Promise<SendResult>;
22
- stopSession(name: string): Promise<void>;
23
- }
24
- export declare class Council extends EventEmitter {
25
- private config;
26
- private manager;
27
- private agentTimeoutMs;
28
- private _aborted;
29
- private _activeSessions;
30
- private _session;
31
- private _pendingInjection;
32
- private logger;
33
- constructor(config: CouncilConfig, manager: SessionManagerLike, logger?: Logger);
34
- getSession(): CouncilSession | undefined;
35
- injectMessage(message: string): void;
36
- abort(): void;
37
- private emitEvent;
38
- private runSingleAgent;
39
- init(task: string): CouncilSession;
40
- run(task?: string): Promise<CouncilSession>;
41
- private generateSummary;
42
- private generateCompactContext;
43
- private saveTranscript;
44
- /**
45
- * Produce a structured review of the council's output.
46
- * Lists all changed files, branches, worktrees, plan.md status, and agent summaries.
47
- * Does NOT modify any state — purely informational.
48
- */
49
- review(): Promise<CouncilReviewResult>;
50
- /**
51
- * Internal cleanup helper — removes worktrees, branches, plan.md, and reviews/.
52
- * Each cleanup step is independently gated by the `options` flags.
53
- */
54
- private _cleanup;
55
- /**
56
- * Accept the council's work: clean up worktrees, branches, plan.md, and reviews/.
57
- * Should only be called after reviewing via `review()`.
58
- */
59
- accept(): Promise<CouncilAcceptResult>;
60
- /**
61
- * Reject the council's work: rewrite plan.md with feedback.
62
- * Does NOT delete any worktrees or branches — the council can retry.
63
- */
64
- reject(feedback: string): Promise<CouncilRejectResult>;
65
- }
66
- export declare function getDefaultCouncilConfig(projectDir: string): CouncilConfig;
67
- export {};
@@ -1,2 +0,0 @@
1
- export * from './council.js';
2
- export * from './consensus.js';
@@ -1,16 +0,0 @@
1
- /**
2
- * Council per-agent system prompt builder + config-path resolver.
3
- *
4
- * Extracted from `council.ts` 2026-05-13 as a pair (they're tightly coupled —
5
- * buildSystemPrompt always calls resolveConfigPath). Both are bounded I/O:
6
- * filesystem reads + string transformation, no module state.
7
- *
8
- * Note on path resolution: `import.meta.url` here points to
9
- * `src/council/system-prompt.ts` (same directory as `council.ts` was),
10
- * so the `../../configs` relative lookup resolves identically. Behavior
11
- * preservation verified.
12
- */
13
- import type { AgentPersona } from '../types.js';
14
- /** Resolve the path to configs/ relative to this module (works from both src/ and dist/) */
15
- export declare function resolveConfigPath(filename: string): string;
16
- export declare function buildSystemPrompt(agent: AgentPersona, allAgents: AgentPersona[], worktreePath: string): string;
@@ -1,10 +0,0 @@
1
- /**
2
- * Writes a per-agent `.claude/CLAUDE.md` into the worktree directory, scoping
3
- * the agent's identity, working branch, workspace boundary, and efficiency
4
- * rules for council collaboration.
5
- *
6
- * Extracted from `council.ts` 2026-05-13 as a bounded-I/O hot-path
7
- * decomposition. Deterministic for the same inputs; only writes one file
8
- * under the given `wtDir`.
9
- */
10
- export declare function writeWorktreeClaudeMd(wtDir: string, agentName: string, emoji: string, projectDir: string): void;
@@ -1,87 +0,0 @@
1
- /**
2
- * Base class for one-shot (process-per-send) session engines.
3
- *
4
- * Shared by Codex, Gemini, and Cursor — eliminates ~200 LOC of duplication
5
- * per engine. Subclasses only implement _run() (engine-specific CLI invocation)
6
- * and optionally override _cleanupProc() for extra cleanup (readline, streams).
7
- */
8
- import { ChildProcess } from 'node:child_process';
9
- import { EventEmitter } from 'node:events';
10
- import { type SessionConfig, type SessionStats, type EffortLevel, type ISession, type SessionSendOptions, type TurnResult, type CostBreakdown } from '../types.js';
11
- /**
12
- * Parameterizes engine-specific behavior without requiring method overrides.
13
- * Passed to the BaseOneShotSession constructor by each subclass.
14
- */
15
- export interface OneShotEngineConfig {
16
- /** Prefix for session ID generation, e.g. 'codex', 'gemini', 'cursor' */
17
- enginePrefix: string;
18
- /** Fallback model for pricing lookups when session has no explicit model */
19
- defaultModel: string;
20
- /** Model name shown in getCost() output; defaults to defaultModel if omitted */
21
- defaultModelDisplay?: string;
22
- /** Whether this engine tracks cached token pricing (Codex=false, Gemini/Cursor=true) */
23
- supportsCachedTokens: boolean;
24
- /** Human-readable engine name for compact() no-op message */
25
- engineDisplayName: string;
26
- }
27
- export declare abstract class BaseOneShotSession extends EventEmitter implements ISession {
28
- protected options: SessionConfig;
29
- protected engineBin: string;
30
- protected engineCfg: OneShotEngineConfig;
31
- private _isReady;
32
- private _isPaused;
33
- private _isBusy;
34
- protected currentProc: ChildProcess | null;
35
- private currentRequestId;
36
- private _startTime;
37
- private _history;
38
- sessionId?: string;
39
- protected _stats: {
40
- turns: number;
41
- toolCalls: number;
42
- toolErrors: number;
43
- tokensIn: number;
44
- tokensOut: number;
45
- cachedTokens: number;
46
- costUsd: number;
47
- lastActivity: string | null;
48
- };
49
- constructor(config: SessionConfig, bin: string, engineCfg: OneShotEngineConfig);
50
- get pid(): number | undefined;
51
- get isReady(): boolean;
52
- get isPaused(): boolean;
53
- get isBusy(): boolean;
54
- start(): Promise<this>;
55
- send(message: string | unknown[], options?: SessionSendOptions): Promise<TurnResult | {
56
- requestId: number;
57
- sent: boolean;
58
- }>;
59
- /** Engine-specific: spawn the CLI and return a TurnResult. */
60
- protected abstract _run(message: string, options: SessionSendOptions): Promise<TurnResult>;
61
- getStats(): SessionStats & {
62
- sessionId?: string;
63
- uptime: number;
64
- };
65
- getHistory(limit?: number): Array<{
66
- time: string;
67
- type: string;
68
- event: unknown;
69
- }>;
70
- compact(_summary?: string): Promise<TurnResult>;
71
- getEffort(): EffortLevel;
72
- setEffort(level: EffortLevel): void;
73
- getCost(): CostBreakdown;
74
- resolveModel(alias: string): string;
75
- pause(): void;
76
- resume(): void;
77
- stop(): void;
78
- /** Override in subclasses that need extra cleanup (readline, stream destroy). */
79
- protected _cleanupProc(): void;
80
- protected _getModelPricing(): import("../models.js").ModelPricing;
81
- protected _recordTurnComplete(): void;
82
- protected _addHistory(event: {
83
- text: string;
84
- code: number | null;
85
- }): void;
86
- protected _updateCost(): void;
87
- }
@@ -1,93 +0,0 @@
1
- /**
2
- * HeartbeatGuard — enforce `heartbeat.model` override at the engines layer.
3
- *
4
- * Context
5
- * -------
6
- * OpenClaw issues #9556, #13009, #14279 document a recurring bug: heartbeat-
7
- * triggered runs ignore the `heartbeat.model` field in the agent config and
8
- * fall through to the session's primary model (typically Opus), burning
9
- * expensive tokens on what should be a cheap Haiku ping.
10
- *
11
- * The existing `src/lib/heartbeat-workaround.ts` patches this at the SDK
12
- * request layer. This guard operates one level higher — at the engines /
13
- * agent-config layer — to:
14
- *
15
- * 1. Read `heartbeat.model` from the resolved agent config.
16
- * 2. If present, enforce it on any heartbeat invocation.
17
- * 3. If the upstream runtime ignores the override (bug still present),
18
- * REFUSE the heartbeat with a clear error that names the issue numbers.
19
- *
20
- * Usage
21
- * -----
22
- * ```ts
23
- * const guard = new HeartbeatGuard(agentConfig);
24
- * const result = guard.enforce(requestedModel);
25
- * if (!result.ok) throw result.error;
26
- * // use result.model for the heartbeat call
27
- * ```
28
- */
29
- export interface HeartbeatAgentConfig {
30
- /**
31
- * Optional heartbeat sub-config from the agent definition.
32
- * Mirrors the upstream OpenClaw `agents.list[x].heartbeat` shape.
33
- */
34
- heartbeat?: {
35
- /** The model that MUST be used for heartbeat turns. */
36
- model?: string;
37
- /** Whether heartbeats are enabled for this agent at all. */
38
- enabled?: boolean;
39
- };
40
- }
41
- export type GuardResult = {
42
- ok: true;
43
- model: string;
44
- } | {
45
- ok: false;
46
- error: HeartbeatGuardError;
47
- };
48
- export declare class HeartbeatGuardError extends Error {
49
- /** The model the upstream runtime attempted to use. */
50
- readonly requestedModel: string;
51
- /** The model the guard expected. */
52
- readonly expectedModel: string;
53
- /** Upstream issue numbers that describe why this guard exists. */
54
- readonly issueRefs: readonly ["#9556", "#13009", "#14279"];
55
- constructor(requestedModel: string, expectedModel: string);
56
- }
57
- export declare class HeartbeatGuard {
58
- private readonly config;
59
- constructor(agentConfig: HeartbeatAgentConfig);
60
- /**
61
- * Enforce the heartbeat model override.
62
- *
63
- * @param requestedModel - The model string the upstream runtime resolved for
64
- * this heartbeat invocation (i.e. whatever it actually passed to the SDK).
65
- *
66
- * @returns `{ ok: true, model }` — the model the caller MUST use.
67
- * `{ ok: false, error }` — the upstream ignored the override; refuse.
68
- *
69
- * When no `heartbeat.model` is configured this is a pass-through:
70
- * returns `{ ok: true, model: requestedModel }` unconditionally.
71
- */
72
- enforce(requestedModel: string): GuardResult;
73
- /**
74
- * Convenience: enforce and throw on refusal. Equivalent to:
75
- * const r = guard.enforce(model); if (!r.ok) throw r.error; return r.model;
76
- */
77
- enforceOrThrow(requestedModel: string): string;
78
- /**
79
- * Returns the configured heartbeat.model, or undefined if none is set.
80
- */
81
- get configuredModel(): string | undefined;
82
- /**
83
- * True if heartbeats are explicitly disabled in the agent config.
84
- */
85
- get heartbeatsDisabled(): boolean;
86
- }
87
- /**
88
- * Returns true when the guard should skip. Honours the legacy per-layer flag
89
- * (`OPENCLAW_HEARTBEAT_GUARD_DISABLE=1`) AND the unified bypass flag
90
- * (`CC_OPENCLAW_HEARTBEAT_BYPASS=1`) added in v0.21.0 E2. Prefer the unified
91
- * flag; the legacy one is kept for backward-compat.
92
- */
93
- export declare function isHeartbeatGuardDisabled(): boolean;
@@ -1,8 +0,0 @@
1
- export * from './base-oneshot-session.js';
2
- export * from './persistent-session.js';
3
- export * from './persistent-codex-session.js';
4
- export * from './persistent-cursor-session.js';
5
- export * from './persistent-custom-session.js';
6
- export * from './persistent-gemini-session.js';
7
- export * from './subprocess-pool.js';
8
- export * from './heartbeat-guard.js';
@@ -1,16 +0,0 @@
1
- /**
2
- * Persistent Codex Session — wraps OpenAI `codex` CLI
3
- *
4
- * Unlike Claude Code, Codex does not maintain a persistent subprocess with
5
- * streaming JSON I/O. Each send() spawns a new `codex` process in quiet +
6
- * full-auto mode. The "session" is persistent in the sense that:
7
- * - Working directory (cwd) carries accumulated code changes across sends
8
- * - Stats, history, and cost are tracked continuously
9
- * - The session has consistent lifecycle semantics (start/stop/pause/resume)
10
- */
11
- import type { SessionConfig, SessionSendOptions, TurnResult } from '../types.js';
12
- import { BaseOneShotSession } from './base-oneshot-session.js';
13
- export declare class PersistentCodexSession extends BaseOneShotSession {
14
- constructor(config: SessionConfig, codexBin?: string);
15
- protected _run(message: string, options: SessionSendOptions): Promise<TurnResult>;
16
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * Persistent Cursor Session — wraps `cursor-agent` CLI
3
- *
4
- * Like Codex/Gemini, each send() spawns a new `cursor-agent` process in
5
- * headless print mode. Cursor CLI supports `--output-format stream-json`
6
- * which provides NDJSON events similar to Gemini's stream protocol.
7
- *
8
- * The "session" is persistent in the same sense as Codex:
9
- * - Working directory carries accumulated code changes across sends
10
- * - Stats, history, and cost are tracked continuously
11
- * - Consistent lifecycle semantics (start/stop/pause/resume)
12
- */
13
- import type { SessionConfig, SessionSendOptions, TurnResult } from '../types.js';
14
- import { BaseOneShotSession } from './base-oneshot-session.js';
15
- export declare class PersistentCursorSession extends BaseOneShotSession {
16
- private _currentRl;
17
- constructor(config: SessionConfig, cursorBin?: string);
18
- protected _cleanupProc(): void;
19
- protected _run(message: string, options: SessionSendOptions): Promise<TurnResult>;
20
- private _handleStreamEvent;
21
- }
@@ -1,78 +0,0 @@
1
- /**
2
- * Persistent Custom Session — generic wrapper for any coding agent CLI
3
- *
4
- * Supports two operating modes based on CustomEngineConfig.persistent:
5
- *
6
- * persistent=true — long-running subprocess with stream-json I/O over
7
- * stdin/stdout (like Claude Code). Started once, messages
8
- * sent as JSON lines on stdin.
9
- *
10
- * persistent=false — one-shot per send (like Gemini/Codex). Each send()
11
- * spawns a new process with the message as a CLI argument.
12
- *
13
- * The config maps OpenClaw session concepts (permission modes, models, etc.)
14
- * to the target CLI's flags, so any coding agent with a CLI can be integrated
15
- * without writing engine-specific code.
16
- */
17
- import { EventEmitter } from 'node:events';
18
- import { type SessionConfig, type SessionStats, type EffortLevel, type ISession, type SessionSendOptions, type TurnResult, type CostBreakdown } from '../types.js';
19
- export declare class PersistentCustomSession extends EventEmitter implements ISession {
20
- private options;
21
- private engineConfig;
22
- private engineBin;
23
- private sanitize;
24
- private proc;
25
- private _rl;
26
- private _streamCallbacks;
27
- private _contextHighFired;
28
- private currentProc;
29
- private _currentRl;
30
- private _isReady;
31
- private _isPaused;
32
- private _isBusy;
33
- private currentRequestId;
34
- private _startTime;
35
- private _history;
36
- sessionId?: string;
37
- private _stats;
38
- constructor(config: SessionConfig);
39
- get pid(): number | undefined;
40
- get isReady(): boolean;
41
- get isPaused(): boolean;
42
- get isBusy(): boolean;
43
- start(): Promise<this>;
44
- private _startPersistent;
45
- private _startOneShot;
46
- send(message: string | unknown[], options?: SessionSendOptions): Promise<TurnResult | {
47
- requestId: number;
48
- sent: boolean;
49
- }>;
50
- private _sendPersistent;
51
- private _sendOneShot;
52
- private _runOneShot;
53
- private _handlePersistentEvent;
54
- private _handleOneShotEvent;
55
- private _waitForTurnComplete;
56
- getStats(): SessionStats & {
57
- sessionId?: string;
58
- uptime: number;
59
- };
60
- getHistory(limit?: number): Array<{
61
- time: string;
62
- type: string;
63
- event: unknown;
64
- }>;
65
- compact(summary?: string): Promise<TurnResult | {
66
- requestId: number;
67
- sent: boolean;
68
- }>;
69
- getEffort(): EffortLevel;
70
- setEffort(level: EffortLevel): void;
71
- getCost(): CostBreakdown;
72
- resolveModel(alias: string): string;
73
- pause(): void;
74
- resume(): void;
75
- stop(): void;
76
- private _appendPermissionArgs;
77
- private _updateCost;
78
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * Persistent Gemini Session — wraps Google `gemini` CLI
3
- *
4
- * Like Codex, each send() spawns a new `gemini` process. Unlike Codex,
5
- * Gemini CLI supports `--output-format stream-json` which provides real
6
- * token usage data and structured tool call events instead of raw text.
7
- *
8
- * The "session" is persistent in the same sense as Codex:
9
- * - Working directory carries accumulated code changes across sends
10
- * - Stats, history, and cost are tracked continuously
11
- * - Consistent lifecycle semantics (start/stop/pause/resume)
12
- */
13
- import type { SessionConfig, SessionSendOptions, TurnResult } from '../types.js';
14
- import { BaseOneShotSession } from './base-oneshot-session.js';
15
- export declare class PersistentGeminiSession extends BaseOneShotSession {
16
- private _currentRl;
17
- constructor(config: SessionConfig, geminiBin?: string);
18
- protected _cleanupProc(): void;
19
- protected _run(message: string, options: SessionSendOptions): Promise<TurnResult>;
20
- private _handleStreamEvent;
21
- }
@@ -1,95 +0,0 @@
1
- /**
2
- * Persistent Claude Code Session — wraps `claude` CLI via child_process.spawn
3
- *
4
- * Maintains a long-running Claude Code process with streaming JSON I/O.
5
- * Enables multi-turn agent loops, continuous conversation, and real-time streaming.
6
- */
7
- import { EventEmitter } from 'node:events';
8
- import { type SessionConfig, type SessionStats, type EffortLevel, type ISession, type SessionSendOptions, type TurnResult, type CostBreakdown } from '../types.js';
9
- export declare const THINKING_EVENT: "thinking";
10
- export interface ThinkingEventPayload {
11
- /** Partial or complete thinking/reasoning text from the upstream CLI. */
12
- text: string;
13
- /** ISO timestamp when the event was captured. */
14
- capturedAt: string;
15
- /** Source: 'thinking_delta' from stream_event, or 'assistant_block' from aggregate block. */
16
- source: 'thinking_delta' | 'assistant_block';
17
- }
18
- interface InternalStats {
19
- turns: number;
20
- toolCalls: number;
21
- toolErrors: number;
22
- tokensIn: number;
23
- tokensOut: number;
24
- cachedTokens: number;
25
- costUsd: number;
26
- startTime: string | null;
27
- lastActivity: string | null;
28
- /** v0.27.x — last PROGRESS event ts (excludes api_retry); watchdog keys off it. */
29
- lastProgressAt: string | null;
30
- /** v0.27.6 — count of tool calls currently in flight (dispatched onToolUse
31
- * without a matching onToolResult yet). The stalled-session watchdog treats
32
- * inFlightTools > 0 as "alive" so a long quiet Bash/build/test step is never
33
- * killed mid-run. Reset to 0 at turn boundaries (start / complete / close). */
34
- inFlightTools: number;
35
- history: Array<{
36
- time: string;
37
- type: string;
38
- event: unknown;
39
- }>;
40
- retries: number;
41
- lastRetryError?: string;
42
- lastTurnContextTokens: number;
43
- }
44
- export declare class PersistentClaudeSession extends EventEmitter implements ISession {
45
- private options;
46
- private claudeBin;
47
- private proc;
48
- private _rl;
49
- private _isReady;
50
- private _isPaused;
51
- private _isBusy;
52
- private currentRequestId;
53
- private _streamCallbacks;
54
- private _textStreamedThisTurn;
55
- private _contextHighFired;
56
- private _contextHighLastFiredAt;
57
- private _realModel;
58
- sessionId?: string;
59
- stats: InternalStats;
60
- constructor(config: SessionConfig, claudeBin?: string);
61
- get pid(): number | undefined;
62
- get isReady(): boolean;
63
- get isPaused(): boolean;
64
- get isBusy(): boolean;
65
- start(): Promise<this>;
66
- private _handleEvent;
67
- send(message: string | unknown[], options?: SessionSendOptions): Promise<TurnResult | {
68
- requestId: number;
69
- sent: boolean;
70
- }>;
71
- private _waitForTurnComplete;
72
- getStats(): SessionStats & {
73
- sessionId?: string;
74
- uptime: number;
75
- };
76
- getHistory(limit?: number): Array<{
77
- time: string;
78
- type: string;
79
- event: unknown;
80
- }>;
81
- compact(summary?: string): Promise<TurnResult | {
82
- requestId: number;
83
- sent: boolean;
84
- }>;
85
- getEffort(): EffortLevel;
86
- setEffort(level: EffortLevel): void;
87
- getCost(): CostBreakdown;
88
- resolveModel(alias: string): string;
89
- pause(): void;
90
- resume(): void;
91
- stop(): void;
92
- private _updateCost;
93
- private _fireHook;
94
- }
95
- export {};
@@ -1,14 +0,0 @@
1
- /**
2
- * Pure binary-path resolver for custom session engines.
3
- *
4
- * If `engineConfig.binEnv` names an env var that's set, returns its value.
5
- * Otherwise returns the configured `bin` fallback.
6
- *
7
- * Extracted from `persistent-custom-session.ts` 2026-05-13 as a pure-function
8
- * hot-path decomposition (no module state; reads only the named env var).
9
- */
10
- export interface ResolveBinConfig {
11
- bin: string;
12
- binEnv?: string;
13
- }
14
- export declare function resolveBin(engineConfig: ResolveBinConfig): string;
@@ -1,78 +0,0 @@
1
- /**
2
- * SubprocessPool — warm claude CLI subprocess pool for conversation-boundary recycle.
3
- *
4
- * DARK-FLAGGED: only consulted when OPENCLAW_SUBPROCESS_POOL=1.
5
- * When the flag is off, this module is a no-op and all behaviour is
6
- * byte-identical to the pre-v0.16 code path.
7
- *
8
- * Goal: cut Telegram cold-turn wall-clock toward direct CLI baseline
9
- * (currently ~3× direct CLI) by keeping a pool of warm `claude` CLI
10
- * subprocesses ready to accept the first message of a new conversation,
11
- * amortising the ~800-1200ms spawn + init cost.
12
- *
13
- * Pool policy:
14
- * - Maintains `minIdle` warm sessions (default 1).
15
- * - On conversation start: borrow the head idle session; the pool
16
- * immediately spawns a replacement to maintain the idle floor.
17
- * - On conversation boundary (session.stop() / recycle()): return the
18
- * session to the pool — the session's subprocess is killed, a fresh
19
- * one is spawned and warmed, then placed back into the idle queue.
20
- * - Hard cap: `maxSize` total (idle + borrowed) sessions (default 4).
21
- * - Idle sessions are reaped after `idleTtlMs` (default 5 min) to
22
- * avoid orphaning warm processes during quiet periods.
23
- */
24
- import { EventEmitter } from 'node:events';
25
- import { PersistentClaudeSession } from './persistent-session.js';
26
- import type { SessionConfig } from '../types.js';
27
- export interface SubprocessPoolOptions {
28
- /** Minimum idle (pre-warmed) sessions to keep ready. Default 1. */
29
- minIdle?: number;
30
- /** Hard cap on total sessions (idle + borrowed). Default 4. */
31
- maxSize?: number;
32
- /** Idle TTL before a warm session is reaped (ms). Default 300_000 (5 min). */
33
- idleTtlMs?: number;
34
- /** Base config applied to every pool-spawned session. */
35
- baseConfig: SessionConfig;
36
- /** Override the claude binary path (test injection). */
37
- claudeBin?: string;
38
- }
39
- /**
40
- * Returns true only when the pool feature flag is explicitly enabled.
41
- * Default off — behaviour is byte-identical to pre-v0.16 when off.
42
- */
43
- export declare function isSubprocessPoolEnabled(): boolean;
44
- export declare class SubprocessPool extends EventEmitter {
45
- private readonly opts;
46
- private idle;
47
- private borrowed;
48
- private reaperTimer;
49
- private _destroyed;
50
- constructor(options: SubprocessPoolOptions);
51
- /**
52
- * Start the pool: pre-warm `minIdle` sessions and schedule the idle reaper.
53
- */
54
- start(): Promise<void>;
55
- /**
56
- * Borrow a warm session for a new conversation.
57
- * Returns null if pool is disabled or at capacity and no idle sessions exist.
58
- * Callers MUST call recycle(session) when the conversation ends.
59
- */
60
- borrow(): Promise<PersistentClaudeSession | null>;
61
- /**
62
- * Recycle a borrowed session back into the pool.
63
- * The session's subprocess is terminated; a fresh warmed session replaces it.
64
- */
65
- recycle(session: PersistentClaudeSession): Promise<void>;
66
- /**
67
- * Destroy the pool: kill all idle sessions and stop the reaper.
68
- */
69
- destroy(): void;
70
- get stats(): {
71
- idle: number;
72
- borrowed: number;
73
- maxSize: number;
74
- };
75
- private _fillIdle;
76
- private _spawnWarm;
77
- private _reapStale;
78
- }
@@ -1,39 +0,0 @@
1
- /**
2
- * Health endpoint handler — GET /health → {status, version, sessions, uptime}.
3
- *
4
- * Architecturally a standalone module: exports getHealthInfo() (pure) and
5
- * healthRoute(req, res) (node:http handler). Wiring into the shared
6
- * embedded-server (:18796) is deferred — a follow-up edit to
7
- * src/session/embedded-server.ts will add `if (req.url === '/health') return healthRoute(req, res)`.
8
- *
9
- * Configurable port: CC_OPENCLAW_HEALTH_PORT (default 18796 — shares listener
10
- * with openai-compat by design).
11
- */
12
- import type { IncomingMessage, ServerResponse } from 'node:http';
13
- /** Default health port. Shares embedded-server :18796 by design. */
14
- export declare const DEFAULT_HEALTH_PORT = 18796;
15
- export declare function getHealthPort(): number;
16
- export interface HealthInfo {
17
- status: 'ok' | 'degraded' | 'starting';
18
- pluginId: string;
19
- version: string;
20
- sessions: {
21
- active: number;
22
- total: number;
23
- };
24
- uptime: {
25
- seconds: number;
26
- startedAt: string;
27
- };
28
- timestamp: string;
29
- }
30
- /** Called by plugin entry on register() to mark uptime baseline. */
31
- export declare function markStart(): void;
32
- /** Increment counters from session lifecycle hooks. */
33
- export declare function recordSessionStart(): void;
34
- export declare function recordSessionEnd(): void;
35
- /** Pure: compute current health info. */
36
- export declare function getHealthInfo(): HealthInfo;
37
- /** node:http compatible handler. */
38
- export declare function healthRoute(_req: IncomingMessage, res: ServerResponse): void;
39
- export declare function _resetForTests(): void;
@@ -1 +0,0 @@
1
- export { getHealthInfo, healthRoute, markStart, recordSessionStart, recordSessionEnd, getHealthPort, DEFAULT_HEALTH_PORT, _resetForTests, } from './handler.js';