@jsonstudio/rcc 0.90.429 → 0.90.701

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 (118) hide show
  1. package/dist/build-info.js +2 -2
  2. package/dist/cli/commands/heartbeat.js +138 -0
  3. package/dist/cli/commands/heartbeat.js.map +1 -1
  4. package/dist/cli/commands/launcher/types.d.ts +1 -0
  5. package/dist/cli/commands/launcher/utils.js +28 -2
  6. package/dist/cli/commands/launcher/utils.js.map +1 -1
  7. package/dist/cli/commands/launcher-kernel.js +61 -9
  8. package/dist/cli/commands/launcher-kernel.js.map +1 -1
  9. package/dist/cli.js +1 -0
  10. package/dist/cli.js.map +1 -1
  11. package/dist/config/system-prompts/codex-cli.txt +1 -1
  12. package/dist/config/user-data-paths.d.ts +1 -0
  13. package/dist/config/user-data-paths.js +29 -0
  14. package/dist/config/user-data-paths.js.map +1 -1
  15. package/dist/manager/modules/quota/antigravity-quota-persistence.js +18 -10
  16. package/dist/manager/modules/quota/antigravity-quota-persistence.js.map +1 -1
  17. package/dist/manager/quota/provider-quota-store.js +17 -9
  18. package/dist/manager/quota/provider-quota-store.js.map +1 -1
  19. package/dist/modules/llmswitch/bridge/index.d.ts +2 -2
  20. package/dist/modules/llmswitch/bridge/index.js +2 -2
  21. package/dist/modules/llmswitch/bridge/index.js.map +1 -1
  22. package/dist/modules/llmswitch/bridge/snapshot-recorder.d.ts +1 -0
  23. package/dist/modules/llmswitch/bridge/snapshot-recorder.js +223 -23
  24. package/dist/modules/llmswitch/bridge/snapshot-recorder.js.map +1 -1
  25. package/dist/modules/llmswitch/bridge/state-integrations.d.ts +18 -0
  26. package/dist/modules/llmswitch/bridge/state-integrations.js +34 -1
  27. package/dist/modules/llmswitch/bridge/state-integrations.js.map +1 -1
  28. package/dist/modules/llmswitch/bridge.d.ts +2 -2
  29. package/dist/modules/llmswitch/bridge.js +2 -2
  30. package/dist/modules/llmswitch/bridge.js.map +1 -1
  31. package/dist/providers/auth/apikey-auth.d.ts +1 -0
  32. package/dist/providers/auth/apikey-auth.js +7 -2
  33. package/dist/providers/auth/apikey-auth.js.map +1 -1
  34. package/dist/providers/core/runtime/provider-factory-helpers.js +25 -3
  35. package/dist/providers/core/runtime/provider-factory-helpers.js.map +1 -1
  36. package/dist/providers/core/runtime/transport/request-header-builder.d.ts +8 -0
  37. package/dist/providers/core/runtime/transport/request-header-builder.js +129 -9
  38. package/dist/providers/core/runtime/transport/request-header-builder.js.map +1 -1
  39. package/dist/providers/core/runtime/vercel-ai-sdk/openai-sdk-transport.d.ts +2 -1
  40. package/dist/providers/core/runtime/vercel-ai-sdk/openai-sdk-transport.js +28 -2
  41. package/dist/providers/core/runtime/vercel-ai-sdk/openai-sdk-transport.js.map +1 -1
  42. package/dist/providers/core/utils/snapshot-writer.js +10 -11
  43. package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
  44. package/dist/providers/mock/mock-provider-runtime.js +1 -1
  45. package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
  46. package/dist/server/handlers/handler-response-utils.js +134 -10
  47. package/dist/server/handlers/handler-response-utils.js.map +1 -1
  48. package/dist/server/handlers/handler-utils.js +2 -2
  49. package/dist/server/handlers/handler-utils.js.map +1 -1
  50. package/dist/server/handlers/types.d.ts +4 -0
  51. package/dist/server/runtime/http-server/clock-runtime-hooks.js +134 -35
  52. package/dist/server/runtime/http-server/clock-runtime-hooks.js.map +1 -1
  53. package/dist/server/runtime/http-server/executor/provider-response-converter.js +34 -8
  54. package/dist/server/runtime/http-server/executor/provider-response-converter.js.map +1 -1
  55. package/dist/server/runtime/http-server/executor/provider-runtime-resolver.js +11 -1
  56. package/dist/server/runtime/http-server/executor/provider-runtime-resolver.js.map +1 -1
  57. package/dist/server/runtime/http-server/executor-metadata.js +31 -1
  58. package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
  59. package/dist/server/runtime/http-server/executor-pipeline.js +24 -1
  60. package/dist/server/runtime/http-server/executor-pipeline.js.map +1 -1
  61. package/dist/server/runtime/http-server/executor-provider.js +1 -1
  62. package/dist/server/runtime/http-server/executor-provider.js.map +1 -1
  63. package/dist/server/runtime/http-server/heartbeat-runtime-hooks.js +128 -20
  64. package/dist/server/runtime/http-server/heartbeat-runtime-hooks.js.map +1 -1
  65. package/dist/server/runtime/http-server/http-server-legacy-pipeline.js +6 -2
  66. package/dist/server/runtime/http-server/http-server-legacy-pipeline.js.map +1 -1
  67. package/dist/server/runtime/http-server/http-server-lifecycle.js +16 -0
  68. package/dist/server/runtime/http-server/http-server-lifecycle.js.map +1 -1
  69. package/dist/server/runtime/http-server/http-server-runtime-providers.js +14 -0
  70. package/dist/server/runtime/http-server/http-server-runtime-providers.js.map +1 -1
  71. package/dist/server/runtime/http-server/http-server-session-daemon.js +14 -7
  72. package/dist/server/runtime/http-server/http-server-session-daemon.js.map +1 -1
  73. package/dist/server/runtime/http-server/index.js +18 -1
  74. package/dist/server/runtime/http-server/index.js.map +1 -1
  75. package/dist/server/runtime/http-server/request-executor.js +27 -1
  76. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  77. package/dist/server/runtime/http-server/session-client-registry.js +6 -1
  78. package/dist/server/runtime/http-server/session-client-registry.js.map +1 -1
  79. package/dist/server/runtime/http-server/session-client-routes.js +83 -5
  80. package/dist/server/runtime/http-server/session-client-routes.js.map +1 -1
  81. package/dist/server/runtime/http-server/session-execution-state.d.ts +47 -0
  82. package/dist/server/runtime/http-server/session-execution-state.js +328 -0
  83. package/dist/server/runtime/http-server/session-execution-state.js.map +1 -0
  84. package/dist/server/runtime/http-server/session-scope-resolution.d.ts +2 -0
  85. package/dist/server/runtime/http-server/session-scope-resolution.js +98 -4
  86. package/dist/server/runtime/http-server/session-scope-resolution.js.map +1 -1
  87. package/dist/server/runtime/http-server/session-storage-cleanup.d.ts +2 -0
  88. package/dist/server/runtime/http-server/session-storage-cleanup.js +74 -0
  89. package/dist/server/runtime/http-server/session-storage-cleanup.js.map +1 -1
  90. package/dist/server/runtime/http-server/tmux-injection-history.d.ts +12 -0
  91. package/dist/server/runtime/http-server/tmux-injection-history.js +94 -0
  92. package/dist/server/runtime/http-server/tmux-injection-history.js.map +1 -0
  93. package/dist/server/runtime/http-server/tmux-injection-runtime-config.d.ts +42 -0
  94. package/dist/server/runtime/http-server/tmux-injection-runtime-config.js +245 -0
  95. package/dist/server/runtime/http-server/tmux-injection-runtime-config.js.map +1 -0
  96. package/dist/server/runtime/http-server/tmux-session-probe.d.ts +1 -0
  97. package/dist/server/runtime/http-server/tmux-session-probe.js +89 -2
  98. package/dist/server/runtime/http-server/tmux-session-probe.js.map +1 -1
  99. package/dist/server/utils/request-id-manager.d.ts +8 -0
  100. package/dist/server/utils/request-id-manager.js +116 -27
  101. package/dist/server/utils/request-id-manager.js.map +1 -1
  102. package/dist/server/utils/request-log-color.d.ts +1 -0
  103. package/dist/server/utils/request-log-color.js +12 -1
  104. package/dist/server/utils/request-log-color.js.map +1 -1
  105. package/dist/server/utils/stage-logger.js +37 -3
  106. package/dist/server/utils/stage-logger.js.map +1 -1
  107. package/dist/utils/errorsamples.js +181 -1
  108. package/dist/utils/errorsamples.js.map +1 -1
  109. package/dist/utils/snapshot-writer.js +2 -6
  110. package/dist/utils/snapshot-writer.js.map +1 -1
  111. package/docs/ARCHITECTURE.md +8 -0
  112. package/docs/design/heartbeat-session-execution-state.md +227 -0
  113. package/docs/reports/apply-patch-errorsamples-classification.md +144 -0
  114. package/package.json +3 -2
  115. package/scripts/ci/repo-sanity.mjs +3 -1
  116. package/scripts/install-global.sh +17 -40
  117. package/scripts/install-release.sh +16 -0
  118. package/scripts/link-global-llms-local.mjs +108 -0
@@ -2,6 +2,16 @@ import fs from 'node:fs/promises';
2
2
  import os from 'node:os';
3
3
  import path from 'node:path';
4
4
  import { resolveRccPath } from '../config/user-data-paths.js';
5
+ const KB = 1024;
6
+ const MB = 1024 * KB;
7
+ const DEFAULT_MAX_SAMPLE_BYTES = 256 * KB;
8
+ const DEFAULT_MAX_FILES_PER_GROUP = 5000;
9
+ const DEFAULT_MAX_BYTES_PER_GROUP = 1024 * MB;
10
+ const DEFAULT_CLIENT_TOOL_MAX_SAMPLE_BYTES = 24 * KB;
11
+ const DEFAULT_CLIENT_TOOL_MAX_FILES = 120;
12
+ const DEFAULT_CLIENT_TOOL_MAX_BYTES = 12 * MB;
13
+ const DEFAULT_PRUNE_INTERVAL_MS = 2000;
14
+ const pruneState = new Map();
5
15
  function resolveErrorsamplesRoot() {
6
16
  const envOverride = process.env.ROUTECODEX_ERRORSAMPLES_DIR ||
7
17
  process.env.RCC_ERRORSAMPLES_DIR ||
@@ -18,12 +28,182 @@ function safeStamp() {
18
28
  const iso = new Date().toISOString();
19
29
  return iso.replace(/[-:]/g, '').replace('T', '-').replace('.', '-');
20
30
  }
31
+ function parseEnvPositiveInt(keys, fallback, min = 1) {
32
+ for (const key of keys) {
33
+ const raw = process.env[key];
34
+ if (raw == null || String(raw).trim() === '') {
35
+ continue;
36
+ }
37
+ const parsed = Number(raw);
38
+ if (!Number.isFinite(parsed)) {
39
+ continue;
40
+ }
41
+ const value = Math.floor(parsed);
42
+ if (value >= min) {
43
+ return value;
44
+ }
45
+ }
46
+ return fallback;
47
+ }
48
+ function resolveGroupBudget(group) {
49
+ const normalizedGroup = safeName(group || 'sample').toLowerCase();
50
+ const maxSampleBytes = parseEnvPositiveInt(['ROUTECODEX_ERRORSAMPLE_MAX_BYTES', 'RCC_ERRORSAMPLE_MAX_BYTES'], DEFAULT_MAX_SAMPLE_BYTES);
51
+ const defaultMaxFiles = parseEnvPositiveInt(['ROUTECODEX_ERRORSAMPLE_MAX_FILES_PER_GROUP', 'RCC_ERRORSAMPLE_MAX_FILES_PER_GROUP'], DEFAULT_MAX_FILES_PER_GROUP);
52
+ const defaultMaxBytes = parseEnvPositiveInt(['ROUTECODEX_ERRORSAMPLE_MAX_BYTES_PER_GROUP', 'RCC_ERRORSAMPLE_MAX_BYTES_PER_GROUP'], DEFAULT_MAX_BYTES_PER_GROUP);
53
+ const pruneIntervalMs = parseEnvPositiveInt(['ROUTECODEX_ERRORSAMPLE_PRUNE_INTERVAL_MS', 'RCC_ERRORSAMPLE_PRUNE_INTERVAL_MS'], DEFAULT_PRUNE_INTERVAL_MS, 0);
54
+ if (normalizedGroup === 'client-tool-error') {
55
+ return {
56
+ maxSampleBytes: parseEnvPositiveInt(['ROUTECODEX_ERRORSAMPLE_CLIENT_TOOL_MAX_SAMPLE_BYTES', 'RCC_ERRORSAMPLE_CLIENT_TOOL_MAX_SAMPLE_BYTES'], DEFAULT_CLIENT_TOOL_MAX_SAMPLE_BYTES),
57
+ maxFiles: parseEnvPositiveInt(['ROUTECODEX_ERRORSAMPLE_CLIENT_TOOL_MAX_FILES', 'RCC_ERRORSAMPLE_CLIENT_TOOL_MAX_FILES'], DEFAULT_CLIENT_TOOL_MAX_FILES),
58
+ maxBytes: parseEnvPositiveInt(['ROUTECODEX_ERRORSAMPLE_CLIENT_TOOL_MAX_BYTES', 'RCC_ERRORSAMPLE_CLIENT_TOOL_MAX_BYTES'], DEFAULT_CLIENT_TOOL_MAX_BYTES),
59
+ pruneIntervalMs
60
+ };
61
+ }
62
+ return {
63
+ maxSampleBytes,
64
+ maxFiles: defaultMaxFiles,
65
+ maxBytes: defaultMaxBytes,
66
+ pruneIntervalMs
67
+ };
68
+ }
69
+ function serializePayloadForWrite(payload, maxSampleBytes) {
70
+ const maxBytes = Math.max(1024, Math.floor(maxSampleBytes));
71
+ let pretty = '';
72
+ try {
73
+ pretty = JSON.stringify(payload, null, 2);
74
+ }
75
+ catch {
76
+ pretty = JSON.stringify({
77
+ truncated: true,
78
+ reason: 'payload_unserializable',
79
+ preview: String(payload)
80
+ }, null, 2);
81
+ }
82
+ if (Buffer.byteLength(pretty, 'utf8') <= maxBytes) {
83
+ return pretty;
84
+ }
85
+ let compact = '';
86
+ try {
87
+ compact = JSON.stringify(payload);
88
+ }
89
+ catch {
90
+ compact = '';
91
+ }
92
+ const originalBytes = Buffer.byteLength(compact || pretty, 'utf8');
93
+ let previewChars = Math.max(512, Math.floor(maxBytes * 0.6));
94
+ while (previewChars >= 256) {
95
+ const candidate = JSON.stringify({
96
+ truncated: true,
97
+ reason: 'payload_too_large',
98
+ maxBytes,
99
+ originalBytes,
100
+ preview: (compact || pretty).slice(0, previewChars)
101
+ }, null, 2);
102
+ if (Buffer.byteLength(candidate, 'utf8') <= maxBytes) {
103
+ return candidate;
104
+ }
105
+ previewChars = Math.floor(previewChars * 0.75);
106
+ }
107
+ return JSON.stringify({
108
+ truncated: true,
109
+ reason: 'payload_too_large',
110
+ maxBytes,
111
+ originalBytes
112
+ }, null, 2);
113
+ }
114
+ async function collectGroupFiles(dir) {
115
+ const entries = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
116
+ const files = [];
117
+ for (const entry of entries) {
118
+ if (!entry.isFile()) {
119
+ continue;
120
+ }
121
+ const full = path.join(dir, entry.name);
122
+ try {
123
+ const stat = await fs.stat(full);
124
+ files.push({ path: full, size: stat.size, mtimeMs: stat.mtimeMs || 0 });
125
+ }
126
+ catch {
127
+ // ignore race with concurrent deletion
128
+ }
129
+ }
130
+ files.sort((a, b) => a.mtimeMs - b.mtimeMs || a.path.localeCompare(b.path));
131
+ return files;
132
+ }
133
+ async function pruneGroupDirectoryNow(dir, budget) {
134
+ if (budget.maxFiles <= 0 || budget.maxBytes <= 0) {
135
+ return;
136
+ }
137
+ const files = await collectGroupFiles(dir);
138
+ if (files.length <= 0) {
139
+ return;
140
+ }
141
+ let totalBytes = files.reduce((sum, file) => sum + Math.max(0, file.size), 0);
142
+ let fileCount = files.length;
143
+ const toDelete = [];
144
+ for (const file of files) {
145
+ if (fileCount <= budget.maxFiles && totalBytes <= budget.maxBytes) {
146
+ break;
147
+ }
148
+ toDelete.push(file.path);
149
+ fileCount -= 1;
150
+ totalBytes -= Math.max(0, file.size);
151
+ }
152
+ if (toDelete.length <= 0) {
153
+ return;
154
+ }
155
+ await Promise.all(toDelete.map((filePath) => fs.rm(filePath, { force: true })));
156
+ }
157
+ async function maybePruneGroupDirectory(dir, budget, options) {
158
+ const force = options?.force === true;
159
+ const state = pruneState.get(dir) || { lastRunAt: 0, pending: null };
160
+ if (state.pending) {
161
+ await state.pending;
162
+ return;
163
+ }
164
+ const now = Date.now();
165
+ if (!force && budget.pruneIntervalMs > 0 && now - state.lastRunAt < budget.pruneIntervalMs) {
166
+ return;
167
+ }
168
+ const pending = (async () => {
169
+ await pruneGroupDirectoryNow(dir, budget);
170
+ state.lastRunAt = Date.now();
171
+ })().finally(() => {
172
+ const latest = pruneState.get(dir);
173
+ if (latest) {
174
+ latest.pending = null;
175
+ pruneState.set(dir, latest);
176
+ }
177
+ });
178
+ state.pending = pending;
179
+ pruneState.set(dir, state);
180
+ await pending;
181
+ }
182
+ function isEnospc(error) {
183
+ if (!error || typeof error !== 'object') {
184
+ return false;
185
+ }
186
+ const code = error.code;
187
+ return typeof code === 'string' && code.toUpperCase() === 'ENOSPC';
188
+ }
21
189
  export async function writeErrorsampleJson(options) {
22
190
  const root = resolveErrorsamplesRoot();
23
191
  const dir = path.join(root, safeName(options.group));
192
+ const budget = resolveGroupBudget(options.group);
24
193
  await fs.mkdir(dir, { recursive: true });
25
194
  const file = path.join(dir, `${safeName(options.kind)}-${safeStamp()}-${Math.random().toString(16).slice(2)}.json`);
26
- await fs.writeFile(file, JSON.stringify(options.payload, null, 2), 'utf8');
195
+ const serialized = serializePayloadForWrite(options.payload, budget.maxSampleBytes);
196
+ try {
197
+ await fs.writeFile(file, serialized, 'utf8');
198
+ }
199
+ catch (error) {
200
+ if (!isEnospc(error)) {
201
+ throw error;
202
+ }
203
+ await maybePruneGroupDirectory(dir, budget, { force: true });
204
+ await fs.writeFile(file, serialized, 'utf8');
205
+ }
206
+ await maybePruneGroupDirectory(dir, budget);
27
207
  return file;
28
208
  }
29
209
  //# sourceMappingURL=errorsamples.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errorsamples.js","sourceRoot":"","sources":["../../src/utils/errorsamples.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,SAAS,uBAAuB;IAC9B,MAAM,WAAW,GACf,OAAO,CAAC,GAAG,CAAC,2BAA2B;QACvC,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAChC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAC3C,IAAI,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,cAAc,CAAC,cAAc,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,MAAM,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAI1C;IACC,MAAM,IAAI,GAAG,uBAAuB,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACrD,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,GAAG,EACH,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CACvF,CAAC;IACF,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3E,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"errorsamples.js","sourceRoot":"","sources":["../../src/utils/errorsamples.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import fsp from 'fs/promises';
2
2
  import os from 'os';
3
3
  import path from 'path';
4
- import { resolveRccSnapshotsDir } from '../config/user-data-paths.js';
4
+ import { resolveRccSnapshotsDirFromEnv } from '../config/user-data-paths.js';
5
5
  import { runtimeFlags } from '../runtime/runtime-flags.js';
6
6
  let snapshotHookWriterPromise = null;
7
7
  function logServerSnapshotNonBlockingError(operation, error) {
@@ -22,11 +22,7 @@ export function isSnapshotsEnabled() {
22
22
  return runtimeFlags.snapshotsEnabled;
23
23
  }
24
24
  function resolveSnapshotRoot() {
25
- const override = String(process.env.ROUTECODEX_SNAPSHOT_DIR || process.env.RCC_SNAPSHOT_DIR || '').trim();
26
- if (override) {
27
- return path.isAbsolute(override) ? override : path.resolve(override);
28
- }
29
- return resolveRccSnapshotsDir();
25
+ return resolveRccSnapshotsDirFromEnv();
30
26
  }
31
27
  function mapEndpointToFolder(entryEndpoint) {
32
28
  const ep = String(entryEndpoint || '').trim().toLowerCase();
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot-writer.js","sourceRoot":"","sources":["../../src/utils/snapshot-writer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"snapshot-writer.js","sourceRoot":"","sources":["../../src/utils/snapshot-writer.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,13 @@ RouteCodex 是一个多 Provider OpenAI 代理服务器,支持动态路由、
17
17
 
18
18
  > **落地要求**:Host 不再解析旧的“合并配置”蓝图,也不在 Provider 层做“模型选择”;所有模型替换/目标决策由 Virtual Router 执行,Host 仅负责“把 HTTP/SSE 转交给 Hub Pipeline + 根据 runtimeKey 调用 Provider”,从而保证单一职责和无兜底策略。
19
19
 
20
+ ### Hub Pipeline / Virtual Router Rust 真源说明(当前状态)
21
+
22
+ - Hub Pipeline 与 Virtual Router 的核心运行时语义,当前以 Rust hotpath 为唯一真源:
23
+ - `sharedmodule/llmswitch-core/rust-core/crates/router-hotpath-napi/`
24
+ - TS 层职责为 thin-shell(桥接/编排/输入输出承接),不再承载第二套语义真源。
25
+ - 已废弃的 TS 旧实现统一归档到 `archive`/`*.legacy.ts`,避免在主路径被误改并引入双真源分叉。
26
+
20
27
  ## 系统架构
21
28
 
22
29
  ### 核心组件
@@ -177,6 +184,7 @@ RouteCodex 是一个多 Provider OpenAI 代理服务器,支持动态路由、
177
184
  RouteCodex 现在完全依赖 sharedmodule/llmswitch-core 的 Hub Pipeline,实现“HTTP ↔ 标准化请求 ↔ Virtual Router ↔ Provider”全链路处理:
178
185
 
179
186
  - **唯一入口**:服务器通过 `RouteCodexHttpServer` 调用 `sharedmodule/llmswitch-core/dist/conversion/hub/pipeline/hub-pipeline`,禁止旁路加载核心模块。
187
+ - **Rust 真源**:Hub Pipeline / Virtual Router 的 runtime semantics 由 `router-hotpath-napi` 提供,TS 仅保留桥接编排薄壳。
180
188
  - **配置来源**:`routecodex-config-loader` 读取用户配置后调用 `bootstrapVirtualRouterConfig`。该工具会校验 routing/providers、展开 `provider.keyAlias.model`、生成 `targetRuntime` 映射(endpoint、headers、auth、compat profile),Hub Pipeline 构造函数直接接受该结果。
181
189
  - **节点链路**:Hub Pipeline 在内部组成 `SSE Input → Input Node → Chat Process → Virtual Router → (Compatibility,可选) → Output/SSE`。Host 不关心节点细节,只需要把 HTTP 请求封装成标准化的 Hub 请求。
182
190
  - **工具治理**:唯一的工具治理点位于 `chat-process-node`。Compatibility 层已完全下沉到 llmswitch-core(`sharedmodule/llmswitch-core/src/conversion/compat`),仅做 Provider 特定的最小字段修剪。
@@ -0,0 +1,227 @@
1
+ # Heartbeat Session Execution State 设计
2
+
3
+ ## 目标
4
+
5
+ 为 heartbeat 注入建立一个 **tmux-scoped 执行状态真源**,在注入前判断目标 tmux 当前是否仍在执行任务;若仍在执行,则跳过本次 heartbeat,避免打扰。
6
+
7
+ 本设计重点解决两个问题:
8
+
9
+ 1. 不能再把 `client alive` 误判为 `session busy`。
10
+ 2. 不能只看 executor 生命周期;流式 SSE 仍在输出时,必须视为仍在执行。
11
+
12
+ ---
13
+
14
+ ## 已确认可用的现有信号
15
+
16
+ ### 1. tmux / session 绑定
17
+
18
+ 来源:
19
+
20
+ - `src/server/runtime/http-server/executor-metadata.ts`
21
+ - `src/server/runtime/http-server/session-scope-resolution.ts`
22
+
23
+ 当前可解析:
24
+
25
+ - `tmuxSessionId`
26
+ - `sessionId`
27
+ - `conversationId`
28
+ - `workdir`
29
+ - `clientType`
30
+
31
+ ### 2. request 开始/结束
32
+
33
+ 来源:
34
+
35
+ - `src/server/runtime/http-server/request-executor.ts`
36
+ - `src/server/runtime/http-server/request-activity-tracker.ts`
37
+
38
+ 可用作“请求已发出”的信号,但 **不能单独作为流式执行态真源**,因为 `onRequestEnd` 发生在 executor `finally`,早于 SSE 真正结束。
39
+
40
+ ### 3. SSE 生命周期与 finish_reason
41
+
42
+ 来源:
43
+
44
+ - `src/server/handlers/handler-response-utils.ts`
45
+ - `src/server/utils/finish-reason.ts`
46
+
47
+ 当前已经能识别:
48
+
49
+ - SSE stream start
50
+ - SSE end
51
+ - client close
52
+ - finish / terminal event
53
+ - `finish_reason`
54
+
55
+ 这些信号目前主要停留在响应层日志,没有形成 tmux-scoped 共享运行态。
56
+
57
+ ### 4. daemon alive / registry
58
+
59
+ 来源:
60
+
61
+ - `src/server/runtime/http-server/session-client-registry.ts`
62
+
63
+ 当前能说明:
64
+
65
+ - client daemon 是否仍在线
66
+ - 最近 heartbeat / inject 时间
67
+
68
+ 但这 **不能说明 pane 当前是否 busy**。
69
+
70
+ ---
71
+
72
+ ## 核心判断原则
73
+
74
+ ### A. 流式请求优先
75
+
76
+ 若目标 tmux 当前存在 **未关闭的 SSE**,则直接判定为 **正在执行**,heartbeat 必须跳过。
77
+
78
+ ### B. 非流式请求看最近 request/response 时间线
79
+
80
+ 若最近一条事件是 request,且还未观察到对应 response:
81
+
82
+ - 在 timeout 窗口内:视为仍在等待响应,应跳过 heartbeat
83
+ - 超过 timeout:视为大概率已超时/断连,不应无限跳过 heartbeat
84
+
85
+ ### C. 最近一条事件是 response 时,看 finish_reason
86
+
87
+ - `finish_reason=stop` 且之后没有新 request:视为空闲
88
+ - `finish_reason!=stop`:进入短暂 grace 窗口,避免刚结束 tool_calls / length 时立刻误判为空闲
89
+
90
+ ---
91
+
92
+ ## 建议新增的真源模块
93
+
94
+ 建议新增:
95
+
96
+ - `src/server/runtime/http-server/session-execution-state.ts`
97
+
98
+ 按 `tmuxSessionId` 维护最近执行态,至少记录:
99
+
100
+ - `state`
101
+ - `lastRequestId`
102
+ - `lastRequestAtMs`
103
+ - `lastRequestWasStream`
104
+ - `openSseCount`
105
+ - `lastSseOpenAtMs`
106
+ - `lastSseCloseAtMs`
107
+ - `lastResponseAtMs`
108
+ - `lastFinishReason`
109
+ - `lastTerminalAtMs`
110
+ - `lastClientCloseBeforeTerminal`
111
+
112
+ ---
113
+
114
+ ## 状态机
115
+
116
+ ### 状态
117
+
118
+ - `IDLE`
119
+ - `WAITING_RESPONSE`
120
+ - `STREAMING_OPEN`
121
+ - `POST_RESPONSE_GRACE`
122
+ - `STALED`
123
+ - `UNKNOWN`
124
+
125
+ ### 含义
126
+
127
+ #### `IDLE`
128
+
129
+ 当前可注入 heartbeat。
130
+
131
+ #### `WAITING_RESPONSE`
132
+
133
+ 已收到 request,但尚未观察到 response 完成;在 timeout 窗口内应跳过 heartbeat。
134
+
135
+ #### `STREAMING_OPEN`
136
+
137
+ 流式请求的 SSE 仍未关闭;这是“仍在执行”的最高优先级判定。
138
+
139
+ #### `POST_RESPONSE_GRACE`
140
+
141
+ 刚结束一个非 `stop` 的响应,例如 `tool_calls` / `length`,短时间内仍可能紧接下一轮请求。
142
+
143
+ #### `STALED`
144
+
145
+ 最近一条是 request,但超过 timeout 仍无 response,视为超时或断连,不应再无限跳过 heartbeat。
146
+
147
+ #### `UNKNOWN`
148
+
149
+ 当前没有足够的新执行态数据;只允许降级到 tmux pane heuristic,不允许把 daemon alive 直接当作 busy。
150
+
151
+ ---
152
+
153
+ ## 事件与转移
154
+
155
+ 建议统一记录这些事件:
156
+
157
+ - `REQUEST_STARTED`
158
+ - `SSE_OPENED`
159
+ - `SSE_CLOSED`
160
+ - `RESPONSE_COMPLETED`
161
+ - `RESPONSE_CLIENT_CLOSED`
162
+ - `RESPONSE_ERROR`
163
+ - `TIMEOUT_EXPIRED`
164
+
165
+ 主要转移:
166
+
167
+ - `IDLE -> WAITING_RESPONSE`:收到 request
168
+ - `WAITING_RESPONSE -> STREAMING_OPEN`:流式响应开始
169
+ - `WAITING_RESPONSE -> IDLE`:收到非流式终态且 `finish_reason=stop`
170
+ - `WAITING_RESPONSE -> POST_RESPONSE_GRACE`:收到非流式终态且 `finish_reason!=stop`
171
+ - `WAITING_RESPONSE -> STALED`:超时无响应
172
+ - `STREAMING_OPEN -> IDLE`:SSE 正常结束且 `finish_reason=stop`
173
+ - `STREAMING_OPEN -> POST_RESPONSE_GRACE`:SSE 正常结束且 `finish_reason!=stop`
174
+ - `STREAMING_OPEN -> STALED`:client close / 异常结束且没有正常终态
175
+ - `POST_RESPONSE_GRACE -> WAITING_RESPONSE`:grace 期间来了新 request
176
+ - `POST_RESPONSE_GRACE -> IDLE`:grace 到期且没有新 request
177
+ - `STALED -> WAITING_RESPONSE`:之后出现新的 request
178
+
179
+ ---
180
+
181
+ ## Heartbeat skip 决策顺序
182
+
183
+ 推荐优先级:
184
+
185
+ 1. **存在未关闭 SSE** → `skip`
186
+ 2. **最新是 request,且仍在 timeout 窗口内** → `skip`
187
+ 3. **最新是 response,`finish_reason=stop`,且之后无新 request** → `allow`
188
+ 4. **最新是 request,但已超时无响应** → `allow`
189
+ 5. **状态不足** → fallback 到 tmux pane heuristic
190
+
191
+ 明确禁止:
192
+
193
+ - 仅因为 `registry.hasAliveTmuxSession()` 为真,就直接判定 busy
194
+
195
+ ---
196
+
197
+ ## 与现有 heartbeat 的关系
198
+
199
+ 当前 heartbeat skip 逻辑里已有:
200
+
201
+ - tmux 存活检查
202
+ - request inflight 检查
203
+ - client daemon alive 检查
204
+ - tmux pane heuristic fallback
205
+
206
+ 新方案应调整为:
207
+
208
+ 1. execution-state tracker 为主真源
209
+ 2. tmux pane heuristic 仅作 fallback
210
+ 3. daemon alive 只表示“在线”,不表示“忙”
211
+
212
+ ---
213
+
214
+ ## 落地顺序建议
215
+
216
+ 1. 新增 `session-execution-state.ts`
217
+ 2. 在 request start 路径写入 `REQUEST_STARTED`
218
+ 3. 在 JSON response 完成路径写入 `RESPONSE_COMPLETED`
219
+ 4. 在 SSE 路径写入 `SSE_OPENED / SSE_CLOSED / RESPONSE_COMPLETED / RESPONSE_CLIENT_CLOSED`
220
+ 5. heartbeat 决策改为优先读取 execution-state tracker
221
+ 6. 在缺少状态时再回退到 tmux pane heuristic
222
+
223
+ ---
224
+
225
+ ## 备注
226
+
227
+ 该设计上线后,只能对 **上线后的新请求** 逐步建立准确执行态。对上线前已在跑的老 session,短期内仍需依赖 tmux pane heuristic 兜底。
@@ -0,0 +1,144 @@
1
+ # apply_patch 错误样本分类表(2026-03-18)
2
+
3
+ ## 范围
4
+
5
+ 本表基于两个样本集合:
6
+
7
+ 1. **近期主样本集**
8
+ - `~/.rcc/errorsamples/client-tool-error/chat_process.req.stage2.semantic_map.apply_patch-*.json`
9
+ - 按最近 **200** 条与最近 **500** 条做统计
10
+ 2. **历史回归样本集**
11
+ - `~/.rcc/errorsamples/apply-patch-regression/*.json`
12
+
13
+ ## 结论摘要
14
+
15
+ - 近期高频错误几乎全部是 `apply_patch_verification_failed`,而且高度集中在 **4 类**。
16
+ - 当前主因不是执行器随机失效,而是 **模型 patch 心智错误**:
17
+ 1. 把 GNU diff 头混进 `*** Begin Patch` 块;
18
+ 2. 把 merge/conflict 标记直接塞进 patch;
19
+ 3. 继续硬写 GNU 行号上下文(`@@ -51,7 +51,9 @@`);
20
+ 4. 少量真实的 `expected lines not found`。
21
+ - 历史回归样本还保留两类基础错误:
22
+ - `unsupported_patch_format`
23
+ - `empty_add_file_block`
24
+
25
+ ---
26
+
27
+ ## 近期样本统计
28
+
29
+ ### 最近 200 条 apply_patch 专属样本
30
+
31
+ 来源:
32
+
33
+ - `~/.rcc/errorsamples/client-tool-error/chat_process.req.stage2.semantic_map.apply_patch-*.json`
34
+
35
+ 统计结果:
36
+
37
+ | 分类 | 数量 |
38
+ |---|---:|
39
+ | conflict_markers_or_merge_chunks | 72 |
40
+ | gnu_line_number_context_not_found | 55 |
41
+ | mixed_gnu_diff_inside_begin_patch | 55 |
42
+ | expected_lines_not_found | 18 |
43
+
44
+ ### 最近 500 条 JSON 错误样本中的 apply_patch 相关分类
45
+
46
+ 来源:
47
+
48
+ - `~/.rcc/errorsamples/**/*.json`
49
+
50
+ 统计结果:
51
+
52
+ | 分类 | 数量 |
53
+ |---|---:|
54
+ | conflict_markers_or_merge_chunks | 75 |
55
+ | gnu_line_number_context_not_found | 57 |
56
+ | mixed_gnu_diff_inside_begin_patch | 49 |
57
+ | expected_lines_not_found | 19 |
58
+
59
+ 备注:
60
+
61
+ - 最近 500 条 JSON 样本里,**未看到**新的 `exec_command_nested_apply_patch_warning` 成为主流;说明这轮主要问题已从“工具选错”转向“patch 形状错误”。
62
+
63
+ ---
64
+
65
+ ## 历史回归样本统计
66
+
67
+ 来源:
68
+
69
+ - `~/.rcc/errorsamples/apply-patch-regression/*.json`
70
+
71
+ 统计结果:
72
+
73
+ | 分类 | 数量 |
74
+ |---|---:|
75
+ | unsupported_patch_format | 2 |
76
+ | empty_add_file_block | 1 |
77
+
78
+ ---
79
+
80
+ ## 分类表
81
+
82
+ | 分类 | 典型 matchedText / 症状 | 当前数量 | 更可能的根因 | 建议修复层 | 优先级 | 建议动作 |
83
+ |---|---|---:|---|---|---|---|
84
+ | `conflict_markers_or_merge_chunks` | `Expected update hunk to start with a @@ context marker, got: '======='` | 72 / 75 | 模型把 merge/conflict chunk 或非 patch 文本直接塞进 `Update File` | **prompt/guidance** + request-path guard | P0 | 强化“禁止 `=======/<<<<<<</>>>>>>>`”与“`Update File` 必须有 `@@` hunk”;必要时在 request-path 直接拦截冲突标记并回写 guard reason |
85
+ | `gnu_line_number_context_not_found` | `Failed to find context '-114,6 +114,7 @@'` | 55 / 57 | 模型误以为必须精确写 GNU 行号上下文;或基于旧内容生成 patch | **prompt/guidance** + post-failure retry policy | P0 | 明确“可以用 `@@` + 上下文,不必强写 GNU 行号”;失败后要求重读文件并缩小唯一上下文 |
86
+ | `mixed_gnu_diff_inside_begin_patch` | `invalid hunk at line 2, '--- a/src/server/index.ts' is not a valid hunk header` | 55 / 49 | 模型把 internal `*** Begin Patch` 与 GNU diff 头混用 | **prompt/guidance** + validator normalization(可选) | P0 | 明确“二选一,严禁混用”;可评估是否把 `*** Begin Patch` 包裹的 GNU diff 头再做一层自动剥离修复 |
87
+ | `expected_lines_not_found` | `Failed to find expected lines in ...` | 18 / 19 | 真正的上下文不匹配:文件已变化、上下文过大、不够唯一 | **runtime retry guidance** | P1 | 出错后强制重读最新文件,再用更小且唯一的上下文;必要时把单次 patch 拆小 |
88
+ | `unsupported_patch_format` | `Update File` 后直接跟 frontmatter / 正文,没有 hunk | 2(历史) | 模型不理解 internal grammar;把 `Update File` 当“全文替换” | **tool guidance** + validator reason hint | P1 | 强化最小合法模板,显式提示“没有 `@@` hunk 的 `Update File` 会被拒绝” |
89
+ | `empty_add_file_block` | `*** Add File: ...` 后没有任何 `+` 行 | 1(历史) | 模型误以为空文件 Add File 合法 | **tool guidance** + validator reason hint | P2 | 明确 Add File 必须至少包含一行 `+内容`;若真要空文件,应改为 shell `touch` 之类的受控策略或专门工具,而不是空 patch |
90
+ | `exec_command_nested_apply_patch_warning` | `Warning: apply_patch was requested via exec_command` | 非近期主流,历史存在 | 工具选错:模型把 `apply_patch` 当 shell 命令 | **rewrite/guard** | P2 | 维持现有 rewrite/guard;后续做样本分类时单独追踪是否再次升高 |
91
+
92
+ ---
93
+
94
+ ## 已完成的前置收敛
95
+
96
+ 本轮已先修正工具引导文案,避免继续制造同类错误:
97
+
98
+ - `src/config/system-prompts/codex-cli.txt`
99
+ - 去掉“apply_patch 不好用就换 Node/Python 脚本”的弱引导
100
+ - `sharedmodule/llmswitch-core/src/guidance/index.ts`
101
+ - 明确 **Begin Patch / GNU diff 二选一,禁止混用**
102
+ - 增加最小合法模板
103
+ - 禁止 conflict markers / 裸 frontmatter 作为 `Update File` body
104
+ - `sharedmodule/llmswitch-core/src/guidance/CCR_TOOL_GUIDE.md`
105
+ - 同步补齐以上规则
106
+ - `sharedmodule/llmswitch-core/src/conversion/hub/process/chat-process-clock-tool-schemas.ts`
107
+ - 工具描述补齐 FREEFORM 与“不混用”要求
108
+
109
+ ---
110
+
111
+ ## 建议修复顺序
112
+
113
+ ### 第一步:先修 prompt / guidance
114
+
115
+ 优先原因:
116
+
117
+ - 当前占比最高的三类错误都属于**模型生成 patch 形状错误**
118
+ - 不先收紧提示词,后面即使增强 validator,也只是在被动收垃圾输入
119
+
120
+ ### 第二步:补 request-path / validator 的 reason 编码与 guard
121
+
122
+ 优先看两点:
123
+
124
+ 1. 对 conflict markers 的 request-path 早拦截
125
+ 2. 对“mixed GNU diff inside Begin Patch”评估是否做自动修复,还是继续 fail-fast
126
+
127
+ ### 第三步:为 `expected_lines_not_found` 设计统一 retry 策略
128
+
129
+ 这是最像“正常 patch 失败”的一类,应通过:
130
+
131
+ - 重读文件
132
+ - 缩小上下文
133
+ - 拆小 patch
134
+
135
+ 来恢复,而不是继续堆更宽松的语法容错。
136
+
137
+ ---
138
+
139
+ ## 下一步实施建议
140
+
141
+ 1. 在 `apply_patch` 工具引导里增加**可复制模板**的实际注入验证
142
+ 2. 给 `tool-governor` / request-path 增加 **conflict-marker 明确分类 reason**
143
+ 3. 决定是否为“`*** Begin Patch` + GNU diff 头混用”加一层**自动正规化**
144
+ 4. 把本表对应到测试矩阵,新增每类错误至少 1 条回归用例