@zhixuan92/multi-model-agent 5.0.1 → 5.0.3

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 (255) hide show
  1. package/README.md +8 -9
  2. package/dist/cli/index.d.ts +62 -0
  3. package/dist/cli/index.d.ts.map +1 -0
  4. package/dist/cli/index.js +345 -0
  5. package/dist/cli/index.js.map +1 -0
  6. package/dist/cli/info.d.ts +22 -0
  7. package/dist/cli/info.d.ts.map +1 -0
  8. package/dist/cli/info.js +100 -0
  9. package/dist/cli/info.js.map +1 -0
  10. package/dist/cli/logs.d.ts +15 -0
  11. package/dist/cli/logs.d.ts.map +1 -0
  12. package/dist/cli/logs.js +102 -0
  13. package/dist/cli/logs.js.map +1 -0
  14. package/dist/cli/print-token.d.ts +18 -0
  15. package/dist/cli/print-token.d.ts.map +1 -0
  16. package/dist/cli/print-token.js +60 -0
  17. package/dist/cli/print-token.js.map +1 -0
  18. package/dist/cli/serve.d.ts +28 -0
  19. package/dist/cli/serve.d.ts.map +1 -0
  20. package/dist/cli/serve.js +405 -0
  21. package/dist/cli/serve.js.map +1 -0
  22. package/dist/cli/status.d.ts +49 -0
  23. package/dist/cli/status.d.ts.map +1 -0
  24. package/dist/cli/status.js +155 -0
  25. package/dist/cli/status.js.map +1 -0
  26. package/dist/cli/sync-skills.d.ts +58 -0
  27. package/dist/cli/sync-skills.d.ts.map +1 -0
  28. package/dist/cli/sync-skills.js +266 -0
  29. package/dist/cli/sync-skills.js.map +1 -0
  30. package/dist/cli/telemetry.d.ts +10 -0
  31. package/dist/cli/telemetry.d.ts.map +1 -0
  32. package/dist/cli/telemetry.js +161 -0
  33. package/dist/cli/telemetry.js.map +1 -0
  34. package/dist/cli/toggle.d.ts +26 -0
  35. package/dist/cli/toggle.d.ts.map +1 -0
  36. package/dist/cli/toggle.js +185 -0
  37. package/dist/cli/toggle.js.map +1 -0
  38. package/dist/http/async-dispatch.d.ts +44 -0
  39. package/dist/http/async-dispatch.d.ts.map +1 -0
  40. package/dist/http/async-dispatch.js +175 -0
  41. package/dist/http/async-dispatch.js.map +1 -0
  42. package/dist/http/auth.d.ts +20 -0
  43. package/dist/http/auth.d.ts.map +1 -0
  44. package/dist/http/auth.js +56 -0
  45. package/dist/http/auth.js.map +1 -0
  46. package/dist/http/canonicalize-file-paths.d.ts +8 -0
  47. package/dist/http/canonicalize-file-paths.d.ts.map +1 -0
  48. package/dist/http/canonicalize-file-paths.js +43 -0
  49. package/dist/http/canonicalize-file-paths.js.map +1 -0
  50. package/dist/http/cwd-validator.d.ts +11 -0
  51. package/dist/http/cwd-validator.d.ts.map +1 -0
  52. package/dist/http/cwd-validator.js +130 -0
  53. package/dist/http/cwd-validator.js.map +1 -0
  54. package/dist/http/errors.d.ts +4 -0
  55. package/dist/http/errors.d.ts.map +1 -0
  56. package/dist/http/errors.js +9 -0
  57. package/dist/http/errors.js.map +1 -0
  58. package/dist/http/execution-context.d.ts +18 -0
  59. package/dist/http/execution-context.d.ts.map +1 -0
  60. package/dist/http/execution-context.js +61 -0
  61. package/dist/http/execution-context.js.map +1 -0
  62. package/dist/http/handler-deps.d.ts +19 -0
  63. package/dist/http/handler-deps.d.ts.map +1 -0
  64. package/dist/http/handler-deps.js +2 -0
  65. package/dist/http/handler-deps.js.map +1 -0
  66. package/dist/http/handlers/control/batch-slice.d.ts +4 -0
  67. package/dist/http/handlers/control/batch-slice.d.ts.map +1 -0
  68. package/dist/http/handlers/control/batch-slice.js +40 -0
  69. package/dist/http/handlers/control/batch-slice.js.map +1 -0
  70. package/dist/http/handlers/control/batch.d.ts +23 -0
  71. package/dist/http/handlers/control/batch.d.ts.map +1 -0
  72. package/dist/http/handlers/control/batch.js +332 -0
  73. package/dist/http/handlers/control/batch.js.map +1 -0
  74. package/dist/http/handlers/control/context-blocks.d.ts +22 -0
  75. package/dist/http/handlers/control/context-blocks.d.ts.map +1 -0
  76. package/dist/http/handlers/control/context-blocks.js +111 -0
  77. package/dist/http/handlers/control/context-blocks.js.map +1 -0
  78. package/dist/http/handlers/introspection/health.d.ts +20 -0
  79. package/dist/http/handlers/introspection/health.d.ts.map +1 -0
  80. package/dist/http/handlers/introspection/health.js +18 -0
  81. package/dist/http/handlers/introspection/health.js.map +1 -0
  82. package/dist/http/handlers/introspection/status.d.ts +26 -0
  83. package/dist/http/handlers/introspection/status.d.ts.map +1 -0
  84. package/dist/http/handlers/introspection/status.js +136 -0
  85. package/dist/http/handlers/introspection/status.js.map +1 -0
  86. package/dist/http/handlers/tools/audit.d.ts +4 -0
  87. package/dist/http/handlers/tools/audit.d.ts.map +1 -0
  88. package/dist/http/handlers/tools/audit.js +43 -0
  89. package/dist/http/handlers/tools/audit.js.map +1 -0
  90. package/dist/http/handlers/tools/debug.d.ts +4 -0
  91. package/dist/http/handlers/tools/debug.d.ts.map +1 -0
  92. package/dist/http/handlers/tools/debug.js +43 -0
  93. package/dist/http/handlers/tools/debug.js.map +1 -0
  94. package/dist/http/handlers/tools/delegate.d.ts +4 -0
  95. package/dist/http/handlers/tools/delegate.d.ts.map +1 -0
  96. package/dist/http/handlers/tools/delegate.js +43 -0
  97. package/dist/http/handlers/tools/delegate.js.map +1 -0
  98. package/dist/http/handlers/tools/execute-plan.d.ts +4 -0
  99. package/dist/http/handlers/tools/execute-plan.d.ts.map +1 -0
  100. package/dist/http/handlers/tools/execute-plan.js +45 -0
  101. package/dist/http/handlers/tools/execute-plan.js.map +1 -0
  102. package/dist/http/handlers/tools/investigate.d.ts +4 -0
  103. package/dist/http/handlers/tools/investigate.d.ts.map +1 -0
  104. package/dist/http/handlers/tools/investigate.js +64 -0
  105. package/dist/http/handlers/tools/investigate.js.map +1 -0
  106. package/dist/http/handlers/tools/journal-recall.d.ts +4 -0
  107. package/dist/http/handlers/tools/journal-recall.d.ts.map +1 -0
  108. package/dist/http/handlers/tools/journal-recall.js +40 -0
  109. package/dist/http/handlers/tools/journal-recall.js.map +1 -0
  110. package/dist/http/handlers/tools/journal-record.d.ts +8 -0
  111. package/dist/http/handlers/tools/journal-record.d.ts.map +1 -0
  112. package/dist/http/handlers/tools/journal-record.js +40 -0
  113. package/dist/http/handlers/tools/journal-record.js.map +1 -0
  114. package/dist/http/handlers/tools/research.d.ts +4 -0
  115. package/dist/http/handlers/tools/research.d.ts.map +1 -0
  116. package/dist/http/handlers/tools/research.js +64 -0
  117. package/dist/http/handlers/tools/research.js.map +1 -0
  118. package/dist/http/handlers/tools/retry.d.ts +4 -0
  119. package/dist/http/handlers/tools/retry.d.ts.map +1 -0
  120. package/dist/http/handlers/tools/retry.js +73 -0
  121. package/dist/http/handlers/tools/retry.js.map +1 -0
  122. package/dist/http/handlers/tools/review.d.ts +4 -0
  123. package/dist/http/handlers/tools/review.d.ts.map +1 -0
  124. package/dist/http/handlers/tools/review.js +43 -0
  125. package/dist/http/handlers/tools/review.js.map +1 -0
  126. package/dist/http/journal-lock.d.ts +4 -0
  127. package/dist/http/journal-lock.d.ts.map +1 -0
  128. package/dist/http/journal-lock.js +34 -0
  129. package/dist/http/journal-lock.js.map +1 -0
  130. package/dist/http/middleware/body-reader.d.ts +16 -0
  131. package/dist/http/middleware/body-reader.d.ts.map +1 -0
  132. package/dist/http/middleware/body-reader.js +44 -0
  133. package/dist/http/middleware/body-reader.js.map +1 -0
  134. package/dist/http/middleware/caller-identity.d.ts +16 -0
  135. package/dist/http/middleware/caller-identity.d.ts.map +1 -0
  136. package/dist/http/middleware/caller-identity.js +16 -0
  137. package/dist/http/middleware/caller-identity.js.map +1 -0
  138. package/dist/http/middleware/decompress.d.ts +14 -0
  139. package/dist/http/middleware/decompress.d.ts.map +1 -0
  140. package/dist/http/middleware/decompress.js +51 -0
  141. package/dist/http/middleware/decompress.js.map +1 -0
  142. package/dist/http/project-registry.d.ts +54 -0
  143. package/dist/http/project-registry.d.ts.map +1 -0
  144. package/dist/http/project-registry.js +130 -0
  145. package/dist/http/project-registry.js.map +1 -0
  146. package/dist/http/request-observability.d.ts +8 -0
  147. package/dist/http/request-observability.d.ts.map +1 -0
  148. package/dist/http/request-observability.js +20 -0
  149. package/dist/http/request-observability.js.map +1 -0
  150. package/dist/http/request-pipeline.d.ts +16 -0
  151. package/dist/http/request-pipeline.d.ts.map +1 -0
  152. package/dist/http/request-pipeline.js +144 -0
  153. package/dist/http/request-pipeline.js.map +1 -0
  154. package/dist/http/server.d.ts +17 -0
  155. package/dist/http/server.d.ts.map +1 -0
  156. package/dist/http/server.js +300 -0
  157. package/dist/http/server.js.map +1 -0
  158. package/dist/http/types.d.ts +20 -0
  159. package/dist/http/types.d.ts.map +1 -0
  160. package/dist/http/types.js +2 -0
  161. package/dist/http/types.js.map +1 -0
  162. package/dist/skill-install/disabled-state.d.ts +35 -0
  163. package/dist/skill-install/disabled-state.d.ts.map +1 -0
  164. package/dist/skill-install/disabled-state.js +96 -0
  165. package/dist/skill-install/disabled-state.js.map +1 -0
  166. package/dist/skill-install/discover.d.ts +29 -0
  167. package/dist/skill-install/discover.d.ts.map +1 -0
  168. package/dist/skill-install/discover.js +104 -0
  169. package/dist/skill-install/discover.js.map +1 -0
  170. package/dist/skill-install/include-utils.d.ts +27 -0
  171. package/dist/skill-install/include-utils.d.ts.map +1 -0
  172. package/dist/skill-install/include-utils.js +90 -0
  173. package/dist/skill-install/include-utils.js.map +1 -0
  174. package/dist/skill-install/manifest.d.ts +82 -0
  175. package/dist/skill-install/manifest.d.ts.map +1 -0
  176. package/dist/skill-install/manifest.js +215 -0
  177. package/dist/skill-install/manifest.js.map +1 -0
  178. package/dist/skill-install/skill-installer-common.d.ts +26 -0
  179. package/dist/skill-install/skill-installer-common.d.ts.map +1 -0
  180. package/dist/skill-install/skill-installer-common.js +139 -0
  181. package/dist/skill-install/skill-installer-common.js.map +1 -0
  182. package/dist/skill-install/skill-installers/claude-code.d.ts +43 -0
  183. package/dist/skill-install/skill-installers/claude-code.d.ts.map +1 -0
  184. package/dist/skill-install/skill-installers/claude-code.js +65 -0
  185. package/dist/skill-install/skill-installers/claude-code.js.map +1 -0
  186. package/dist/skill-install/skill-installers/codex-cli.d.ts +27 -0
  187. package/dist/skill-install/skill-installers/codex-cli.d.ts.map +1 -0
  188. package/dist/skill-install/skill-installers/codex-cli.js +84 -0
  189. package/dist/skill-install/skill-installers/codex-cli.js.map +1 -0
  190. package/dist/skill-install/skill-installers/cursor.d.ts +72 -0
  191. package/dist/skill-install/skill-installers/cursor.d.ts.map +1 -0
  192. package/dist/skill-install/skill-installers/cursor.js +81 -0
  193. package/dist/skill-install/skill-installers/cursor.js.map +1 -0
  194. package/dist/skill-install/skill-installers/gemini-cli.d.ts +50 -0
  195. package/dist/skill-install/skill-installers/gemini-cli.d.ts.map +1 -0
  196. package/dist/skill-install/skill-installers/gemini-cli.js +72 -0
  197. package/dist/skill-install/skill-installers/gemini-cli.js.map +1 -0
  198. package/dist/skill-install/skill-manifest-sync.d.ts +11 -0
  199. package/dist/skill-install/skill-manifest-sync.d.ts.map +1 -0
  200. package/dist/skill-install/skill-manifest-sync.js +65 -0
  201. package/dist/skill-install/skill-manifest-sync.js.map +1 -0
  202. package/dist/skills/_shared/auth.md +41 -0
  203. package/dist/skills/_shared/error-handling.md +31 -0
  204. package/dist/skills/_shared/polling.md +88 -0
  205. package/dist/skills/_shared/response-shape.md +55 -0
  206. package/dist/skills/_shared/review-policy.md +15 -0
  207. package/dist/skills/mma-audit/SKILL.md +270 -0
  208. package/dist/skills/mma-context-blocks/SKILL.md +148 -0
  209. package/dist/skills/mma-debug/SKILL.md +208 -0
  210. package/dist/skills/mma-delegate/SKILL.md +216 -0
  211. package/dist/skills/mma-execute-plan/SKILL.md +214 -0
  212. package/dist/skills/mma-explore/SKILL.md +190 -0
  213. package/dist/skills/mma-investigate/SKILL.md +258 -0
  214. package/dist/skills/mma-journal-recall/SKILL.md +242 -0
  215. package/dist/skills/mma-journal-record/SKILL.md +202 -0
  216. package/dist/skills/mma-research/SKILL.md +223 -0
  217. package/dist/skills/mma-retry/SKILL.md +221 -0
  218. package/dist/skills/mma-review/SKILL.md +209 -0
  219. package/dist/skills/multi-model-agent/SKILL.md +206 -0
  220. package/dist/telemetry/consent.d.ts +4 -0
  221. package/dist/telemetry/consent.d.ts.map +1 -0
  222. package/dist/telemetry/consent.js +40 -0
  223. package/dist/telemetry/consent.js.map +1 -0
  224. package/dist/telemetry/flusher.d.ts +19 -0
  225. package/dist/telemetry/flusher.d.ts.map +1 -0
  226. package/dist/telemetry/flusher.js +277 -0
  227. package/dist/telemetry/flusher.js.map +1 -0
  228. package/dist/telemetry/generation.d.ts +9 -0
  229. package/dist/telemetry/generation.d.ts.map +1 -0
  230. package/dist/telemetry/generation.js +33 -0
  231. package/dist/telemetry/generation.js.map +1 -0
  232. package/dist/telemetry/identity.d.ts +9 -0
  233. package/dist/telemetry/identity.d.ts.map +1 -0
  234. package/dist/telemetry/identity.js +35 -0
  235. package/dist/telemetry/identity.js.map +1 -0
  236. package/dist/telemetry/install-id.d.ts +13 -0
  237. package/dist/telemetry/install-id.d.ts.map +1 -0
  238. package/dist/telemetry/install-id.js +49 -0
  239. package/dist/telemetry/install-id.js.map +1 -0
  240. package/dist/telemetry/install-meta.d.ts +10 -0
  241. package/dist/telemetry/install-meta.d.ts.map +1 -0
  242. package/dist/telemetry/install-meta.js +15 -0
  243. package/dist/telemetry/install-meta.js.map +1 -0
  244. package/dist/telemetry/queue.d.ts +35 -0
  245. package/dist/telemetry/queue.d.ts.map +1 -0
  246. package/dist/telemetry/queue.js +287 -0
  247. package/dist/telemetry/queue.js.map +1 -0
  248. package/dist/telemetry/recorder.d.ts +39 -0
  249. package/dist/telemetry/recorder.d.ts.map +1 -0
  250. package/dist/telemetry/recorder.js +173 -0
  251. package/dist/telemetry/recorder.js.map +1 -0
  252. package/package.json +43 -24
  253. package/scripts/postinstall.js +36 -0
  254. package/bin/mmagent.mjs +0 -47
  255. package/postinstall.mjs +0 -8
@@ -0,0 +1,64 @@
1
+ import * as research from '@zhixuan92/multi-model-agent-core/tools/research/schema';
2
+ import { executeTask } from '@zhixuan92/multi-model-agent-core/lifecycle/task-executor';
3
+ import { toolConfig } from '@zhixuan92/multi-model-agent-core/tools/research/tool-config';
4
+ import { sendError, sendJson } from '../../errors.js';
5
+ import { asyncDispatch } from '../../async-dispatch.js';
6
+ import { emitRequestReceived } from '../../request-observability.js';
7
+ export function buildResearchHandler(deps) {
8
+ return async (_req, res, _params, ctx) => {
9
+ const parsed = research.inputSchema.safeParse(ctx.body);
10
+ if (!parsed.success) {
11
+ sendError(res, 400, 'invalid_request', 'Request body validation failed', {
12
+ fieldErrors: parsed.error.flatten(),
13
+ });
14
+ return;
15
+ }
16
+ const input = parsed.data;
17
+ const cwd = ctx.cwd;
18
+ const reserveResult = deps.projectRegistry.reserveProject(cwd);
19
+ if (!reserveResult.ok) {
20
+ sendError(res, 503, reserveResult.error, reserveResult.message);
21
+ return;
22
+ }
23
+ const pc = reserveResult.projectContext;
24
+ pc.lastActivityAt = Date.now();
25
+ deps.projectRegistry.cancelReservation(cwd);
26
+ const blockIds = input.contextBlockIds ?? [];
27
+ const resolvedContextBlocks = [];
28
+ const missingBlocks = [];
29
+ for (const id of blockIds) {
30
+ const content = pc.contextBlocks.get(id);
31
+ if (content === undefined) {
32
+ missingBlocks.push(id);
33
+ }
34
+ else {
35
+ resolvedContextBlocks.push({ id, content });
36
+ }
37
+ }
38
+ if (missingBlocks.length > 0) {
39
+ sendError(res, 400, 'context_block_not_found', 'one or more context block IDs do not exist', { missingBlocks });
40
+ return;
41
+ }
42
+ const researchCfg = deps.config.research;
43
+ const enrichedInput = {
44
+ ...input,
45
+ resolvedContextBlocks,
46
+ hasBrave: (researchCfg?.brave?.apiKeys?.length ?? 0) > 0,
47
+ };
48
+ const { batchId, statusUrl } = asyncDispatch({
49
+ tool: 'research',
50
+ projectCwd: cwd,
51
+ blockIds,
52
+ batchRegistry: deps.batchRegistry,
53
+ projectContext: pc,
54
+ deps,
55
+ caller: { client: ctx.callerClient, mainModel: ctx.mainModel },
56
+ executor: async (executionCtx) => {
57
+ return executeTask(toolConfig, executionCtx, enrichedInput);
58
+ },
59
+ });
60
+ await emitRequestReceived(deps, batchId, _req.url ?? '', input);
61
+ sendJson(res, 202, { batchId, statusUrl });
62
+ };
63
+ }
64
+ //# sourceMappingURL=research.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research.js","sourceRoot":"","sources":["../../../../src/http/handlers/tools/research.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { HandlerDeps } from '../../handler-deps.js';
2
+ import type { RawHandler } from '../../types.js';
3
+ export declare function buildRetryHandler(deps: HandlerDeps): RawHandler;
4
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../../src/http/handlers/tools/retry.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,CAqE/D"}
@@ -0,0 +1,73 @@
1
+ import * as retry from '@zhixuan92/multi-model-agent-core/tools/retry/schema';
2
+ import { executeTask } from '@zhixuan92/multi-model-agent-core/lifecycle/task-executor';
3
+ import { toolConfig } from '@zhixuan92/multi-model-agent-core/tools/retry/tool-config';
4
+ import { sendError, sendJson } from '../../errors.js';
5
+ import { asyncDispatch } from '../../async-dispatch.js';
6
+ export function buildRetryHandler(deps) {
7
+ return async (_req, res, _params, ctx) => {
8
+ const parsed = retry.inputSchema.safeParse(ctx.body);
9
+ if (!parsed.success) {
10
+ sendError(res, 400, 'invalid_request', 'Request body validation failed', {
11
+ fieldErrors: parsed.error.flatten(),
12
+ });
13
+ return;
14
+ }
15
+ const input = parsed.data;
16
+ const cwd = ctx.cwd;
17
+ const reserveResult = deps.projectRegistry.reserveProject(cwd);
18
+ if (!reserveResult.ok) {
19
+ sendError(res, 503, reserveResult.error, reserveResult.message);
20
+ return;
21
+ }
22
+ const pc = reserveResult.projectContext;
23
+ pc.lastActivityAt = Date.now();
24
+ deps.projectRegistry.cancelReservation(cwd);
25
+ const { batchId, statusUrl } = asyncDispatch({
26
+ tool: 'retry',
27
+ projectCwd: cwd,
28
+ blockIds: [],
29
+ batchRegistry: deps.batchRegistry,
30
+ projectContext: pc,
31
+ deps,
32
+ caller: { client: ctx.callerClient, mainModel: ctx.mainModel },
33
+ executor: async (executionCtx) => {
34
+ const callExecutor = async () => {
35
+ const batchCache = executionCtx.projectContext.batchCache;
36
+ const batch = batchCache.get(input.batchId);
37
+ if (!batch) {
38
+ throw new Error(`batch "${input.batchId}" is unknown or expired — re-dispatch with full task specs via delegate_tasks`);
39
+ }
40
+ batchCache.touch(input.batchId);
41
+ for (const i of input.taskIndices) {
42
+ if (i < 0 || i >= batch.tasks.length) {
43
+ throw new Error(`index ${i} is out of range for batch ${input.batchId} (size ${batch.tasks.length})`);
44
+ }
45
+ }
46
+ const subset = input.taskIndices.map((i) => batch.tasks[i]);
47
+ if (!executionCtx.batchId)
48
+ throw new Error('retry requires batchId');
49
+ const retryBatchId = batchCache.remember(executionCtx.batchId, subset);
50
+ try {
51
+ const result = await executeTask(toolConfig, executionCtx, input);
52
+ const results = Array.isArray(result.results) ? result.results : [];
53
+ try {
54
+ batchCache.complete(retryBatchId, results);
55
+ }
56
+ catch { /* already terminal */ }
57
+ return result;
58
+ }
59
+ catch (err) {
60
+ try {
61
+ batchCache.abort(retryBatchId);
62
+ }
63
+ catch { /* already terminal */ }
64
+ throw err;
65
+ }
66
+ };
67
+ return callExecutor();
68
+ },
69
+ });
70
+ sendJson(res, 202, { batchId, statusUrl });
71
+ };
72
+ }
73
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../../src/http/handlers/tools/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { HandlerDeps } from '../../handler-deps.js';
2
+ import type { RawHandler } from '../../types.js';
3
+ export declare function buildReviewHandler(deps: HandlerDeps): RawHandler;
4
+ //# sourceMappingURL=review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../../src/http/handlers/tools/review.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,CAwChE"}
@@ -0,0 +1,43 @@
1
+ import * as review from '@zhixuan92/multi-model-agent-core/tools/review/schema';
2
+ import { executeTask } from '@zhixuan92/multi-model-agent-core/lifecycle/task-executor';
3
+ import { toolConfig } from '@zhixuan92/multi-model-agent-core/tools/review/tool-config';
4
+ import { sendError, sendJson } from '../../errors.js';
5
+ import { asyncDispatch } from '../../async-dispatch.js';
6
+ import { emitRequestReceived } from '../../request-observability.js';
7
+ export function buildReviewHandler(deps) {
8
+ return async (_req, res, _params, ctx) => {
9
+ const parsed = review.inputSchema.safeParse(ctx.body);
10
+ if (!parsed.success) {
11
+ sendError(res, 400, 'invalid_request', 'Request body validation failed', {
12
+ fieldErrors: parsed.error.flatten(),
13
+ });
14
+ return;
15
+ }
16
+ const input = parsed.data;
17
+ const cwd = ctx.cwd;
18
+ const reserveResult = deps.projectRegistry.reserveProject(cwd);
19
+ if (!reserveResult.ok) {
20
+ sendError(res, 503, reserveResult.error, reserveResult.message);
21
+ return;
22
+ }
23
+ const pc = reserveResult.projectContext;
24
+ pc.lastActivityAt = Date.now();
25
+ deps.projectRegistry.cancelReservation(cwd);
26
+ const blockIds = input.contextBlockIds ?? [];
27
+ const { batchId, statusUrl } = asyncDispatch({
28
+ tool: 'review',
29
+ projectCwd: cwd,
30
+ blockIds,
31
+ batchRegistry: deps.batchRegistry,
32
+ projectContext: pc,
33
+ deps,
34
+ caller: { client: ctx.callerClient, mainModel: ctx.mainModel },
35
+ executor: async (executionCtx) => {
36
+ return executeTask(toolConfig, executionCtx, input);
37
+ },
38
+ });
39
+ await emitRequestReceived(deps, batchId, _req.url ?? '', input);
40
+ sendJson(res, 202, { batchId, statusUrl });
41
+ };
42
+ }
43
+ //# sourceMappingURL=review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../../../src/http/handlers/tools/review.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,MAAM,uDAAuD,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,2DAA2D,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,4DAA4D,CAAC;AACxF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,MAAM,UAAU,kBAAkB,CAAC,IAAiB;IAClD,OAAO,KAAK,EAAE,IAAqB,EAAE,GAAmB,EAAE,OAA+B,EAAE,GAAG,EAAE,EAAE;QAChG,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,iBAAiB,EAAE,gCAAgC,EAAE;gBACvE,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;aACpC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;QAC1B,MAAM,GAAG,GAAG,GAAG,CAAC,GAAI,CAAC;QAErB,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAC/D,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;YACtB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QACD,MAAM,EAAE,GAAG,aAAa,CAAC,cAAc,CAAC;QACxC,EAAE,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAAG,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC;QAC7C,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC;YAC3C,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,GAAG;YACf,QAAQ;YACR,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,cAAc,EAAE,EAAE;YAClB,IAAI;YACJ,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE;YAC9D,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE;gBAC/B,OAAO,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;YACtD,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;QAEhE,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7C,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function withProjectJournalLock<T>(cwd: string, fn: () => Promise<T>): Promise<T>;
2
+ /** Test-only: number of cwds with a live lock tail. */
3
+ export declare function __journalLockMapSize(): number;
4
+ //# sourceMappingURL=journal-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal-lock.d.ts","sourceRoot":"","sources":["../../src/http/journal-lock.ts"],"names":[],"mappings":"AAUA,wBAAsB,sBAAsB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoB7F;AAED,uDAAuD;AACvD,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Per-project (per-cwd) async mutex for journal writes. Chained-promise
3
+ * implementation: each caller awaits the previous caller's tail before running.
4
+ * Distinct cwds never block each other. The map entry is removed once the last
5
+ * queued caller for a cwd completes, so lock state grows only with active
6
+ * contention. On a contended acquire, one stderr breadcrumb is emitted; an
7
+ * uncontended acquire emits nothing.
8
+ */
9
+ const tails = new Map();
10
+ export async function withProjectJournalLock(cwd, fn) {
11
+ const prev = tails.get(cwd); // undefined => uncontended
12
+ let release;
13
+ const mine = new Promise((resolve) => { release = resolve; });
14
+ const tail = (prev ?? Promise.resolve()).then(() => mine);
15
+ tails.set(cwd, tail);
16
+ const start = Date.now();
17
+ if (prev) {
18
+ await prev; // queue behind the current holder
19
+ process.stderr.write(`[mmagent] event=journal_lock_wait cwd=${cwd} wait_ms=${Date.now() - start}\n`);
20
+ }
21
+ try {
22
+ return await fn();
23
+ }
24
+ finally {
25
+ release(); // let the next waiter proceed
26
+ if (tails.get(cwd) === tail)
27
+ tails.delete(cwd); // nobody queued behind us
28
+ }
29
+ }
30
+ /** Test-only: number of cwds with a live lock tail. */
31
+ export function __journalLockMapSize() {
32
+ return tails.size;
33
+ }
34
+ //# sourceMappingURL=journal-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal-lock.js","sourceRoot":"","sources":["../../src/http/journal-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAI,GAAW,EAAE,EAAoB;IAC/E,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAe,2BAA2B;IACtE,IAAI,OAAoB,CAAC;IACzB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC1D,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAErB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,IAAI,CAAC,CAA8B,kCAAkC;QAC3E,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yCAAyC,GAAG,YAAY,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAC/E,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,OAAO,EAAE,CAAC,CAA+B,8BAA8B;QACvE,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;YAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,0BAA0B;IAC5E,CAAC;AACH,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,oBAAoB;IAClC,OAAO,KAAK,CAAC,IAAI,CAAC;AACpB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { IncomingMessage } from 'node:http';
2
+ export type BodyReadResult = {
3
+ ok: true;
4
+ body: Buffer;
5
+ } | {
6
+ ok: false;
7
+ reason: 'too_large';
8
+ };
9
+ /**
10
+ * Reads the request body up to `maxBytes`.
11
+ * If the body exceeds `maxBytes`, drains remaining data and resolves with
12
+ * { ok: false, reason: 'too_large' } so the server can still send a 413 response
13
+ * before closing the connection.
14
+ */
15
+ export declare function readBody(req: IncomingMessage, maxBytes: number): Promise<BodyReadResult>;
16
+ //# sourceMappingURL=body-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body-reader.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/body-reader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AAEvC;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAuCxF"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Reads the request body up to `maxBytes`.
3
+ * If the body exceeds `maxBytes`, drains remaining data and resolves with
4
+ * { ok: false, reason: 'too_large' } so the server can still send a 413 response
5
+ * before closing the connection.
6
+ */
7
+ export function readBody(req, maxBytes) {
8
+ return new Promise((resolve) => {
9
+ const chunks = [];
10
+ let size = 0;
11
+ let settled = false;
12
+ let overflow = false;
13
+ function settle(result) {
14
+ if (settled)
15
+ return;
16
+ settled = true;
17
+ resolve(result);
18
+ }
19
+ req.on('data', (chunk) => {
20
+ if (overflow) {
21
+ // Drain remaining data silently after overflow is detected
22
+ return;
23
+ }
24
+ size += chunk.length;
25
+ if (size > maxBytes) {
26
+ overflow = true;
27
+ // Don't push this chunk; signal overflow and continue draining
28
+ settle({ ok: false, reason: 'too_large' });
29
+ return;
30
+ }
31
+ chunks.push(chunk);
32
+ });
33
+ req.on('end', () => {
34
+ if (!overflow) {
35
+ settle({ ok: true, body: Buffer.concat(chunks) });
36
+ }
37
+ // If overflow, already settled — no-op
38
+ });
39
+ req.on('error', () => {
40
+ settle({ ok: false, reason: 'too_large' });
41
+ });
42
+ });
43
+ }
44
+ //# sourceMappingURL=body-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body-reader.js","sourceRoot":"","sources":["../../../src/http/middleware/body-reader.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAoB,EAAE,QAAgB;IAC7D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,SAAS,MAAM,CAAC,MAAsB;YACpC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC;QAED,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,QAAQ,EAAE,CAAC;gBACb,2DAA2D;gBAC3D,OAAO;YACT,CAAC;YACD,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;YACrB,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC;gBACpB,QAAQ,GAAG,IAAI,CAAC;gBAChB,+DAA+D;gBAC/D,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;gBAC3C,OAAO;YACT,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACjB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACpD,CAAC;YACD,uCAAuC;QACzC,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACnB,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { IncomingMessage } from 'node:http';
2
+ export type CallerClient = 'claude-code' | 'cursor' | 'codex-cli' | 'gemini-cli' | 'other';
3
+ export interface CallerIdentity {
4
+ callerClient: CallerClient;
5
+ /** Calling agent's model id (e.g., claude-opus-4-7). Sourced from the
6
+ * required X-MMA-Main-Model header on tool routes. Used as `mainModel`
7
+ * in wire telemetry so cost-delta-vs-main and family attribution can
8
+ * be computed. null only when the caller didn't send the header; the
9
+ * request pipeline rejects with 400 main_model_required on tool routes
10
+ * before any handler sees a null. */
11
+ mainModel: string | null;
12
+ }
13
+ /** Default identity when no caller header is present. */
14
+ export declare const DEFAULT_IDENTITY: CallerIdentity;
15
+ export declare function resolveCallerIdentity(req: IncomingMessage): CallerIdentity;
16
+ //# sourceMappingURL=caller-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caller-identity.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/caller-identity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAIjD,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC;AAE3F,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B;;;;;0CAKsC;IACtC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,EAAE,cAG9B,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,cAAc,CAW1E"}
@@ -0,0 +1,16 @@
1
+ const CLIENT_ALLOWLIST = new Set(['claude-code', 'cursor', 'codex-cli', 'gemini-cli']);
2
+ /** Default identity when no caller header is present. */
3
+ export const DEFAULT_IDENTITY = {
4
+ callerClient: 'other',
5
+ mainModel: null,
6
+ };
7
+ export function resolveCallerIdentity(req) {
8
+ const rawClient = req.headers['x-mma-client']?.toLowerCase().trim();
9
+ const callerClient = (rawClient && CLIENT_ALLOWLIST.has(rawClient))
10
+ ? rawClient
11
+ : 'other';
12
+ const rawMainModel = req.headers['x-mma-main-model']?.trim();
13
+ const mainModel = rawMainModel && rawMainModel.length > 0 ? rawMainModel : null;
14
+ return { callerClient, mainModel };
15
+ }
16
+ //# sourceMappingURL=caller-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caller-identity.js","sourceRoot":"","sources":["../../../src/http/middleware/caller-identity.ts"],"names":[],"mappings":"AAEA,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;AAevF,yDAAyD;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAmB;IAC9C,YAAY,EAAE,OAAO;IACrB,SAAS,EAAE,IAAI;CAChB,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,GAAoB;IACxD,MAAM,SAAS,GAAI,GAAG,CAAC,OAAO,CAAC,cAAc,CAAwB,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAE5F,MAAM,YAAY,GAAG,CAAC,SAAS,IAAI,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACjE,CAAC,CAAE,SAA0B;QAC7B,CAAC,CAAC,OAAO,CAAC;IAEZ,MAAM,YAAY,GAAI,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAwB,EAAE,IAAI,EAAE,CAAC;IACrF,MAAM,SAAS,GAAG,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;IAEhF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface DecompressOpts {
2
+ maxDecompressedBytes: number;
3
+ }
4
+ export type DecompressResult = {
5
+ ok: true;
6
+ body: Buffer;
7
+ } | {
8
+ ok: false;
9
+ reason: 'too_large' | 'unsupported_encoding' | 'decompress_error';
10
+ statusCode: number;
11
+ message: string;
12
+ };
13
+ export declare function decompressBody(rawBody: Buffer, contentEncoding: string | undefined, opts: DecompressOpts): Promise<DecompressResult>;
14
+ //# sourceMappingURL=decompress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decompress.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/decompress.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,sBAAsB,GAAG,kBAAkB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1H,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,gBAAgB,CAAC,CAiC3B"}
@@ -0,0 +1,51 @@
1
+ import { createGunzip } from 'node:zlib';
2
+ export function decompressBody(rawBody, contentEncoding, opts) {
3
+ const enc = (contentEncoding ?? '').toLowerCase().trim();
4
+ if (enc === '' || enc === 'identity') {
5
+ if (rawBody.byteLength > opts.maxDecompressedBytes) {
6
+ return Promise.resolve({
7
+ ok: false,
8
+ reason: 'too_large',
9
+ statusCode: 413,
10
+ message: `Request body exceeds the ${opts.maxDecompressedBytes}-byte limit`,
11
+ });
12
+ }
13
+ return Promise.resolve({ ok: true, body: rawBody });
14
+ }
15
+ if (enc === 'gzip') {
16
+ return streamGunzip(rawBody, opts.maxDecompressedBytes).then((data) => ({ ok: true, body: data }), (e) => {
17
+ if (e.statusCode === 413) {
18
+ return { ok: false, reason: 'too_large', statusCode: 413, message: 'Decompressed body exceeds size cap' };
19
+ }
20
+ return { ok: false, reason: 'decompress_error', statusCode: 400, message: `gzip decompression failed: ${e.message}` };
21
+ });
22
+ }
23
+ return Promise.resolve({
24
+ ok: false,
25
+ reason: 'unsupported_encoding',
26
+ statusCode: 415,
27
+ message: `Unsupported content-encoding: ${enc}`,
28
+ });
29
+ }
30
+ function streamGunzip(buf, capBytes) {
31
+ return new Promise((resolve, reject) => {
32
+ const gz = createGunzip();
33
+ const chunks = [];
34
+ let total = 0;
35
+ gz.on('data', (chunk) => {
36
+ total += chunk.length;
37
+ if (total > capBytes) {
38
+ gz.destroy();
39
+ const err = new Error('decompressed body exceeds cap');
40
+ err.statusCode = 413;
41
+ reject(err);
42
+ return;
43
+ }
44
+ chunks.push(chunk);
45
+ });
46
+ gz.on('end', () => resolve(Buffer.concat(chunks)));
47
+ gz.on('error', (e) => reject(e));
48
+ gz.end(buf);
49
+ });
50
+ }
51
+ //# sourceMappingURL=decompress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decompress.js","sourceRoot":"","sources":["../../../src/http/middleware/decompress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAUzC,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,eAAmC,EACnC,IAAoB;IAEpB,MAAM,GAAG,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAEzD,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;QACrC,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACnD,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,WAAW;gBACnB,UAAU,EAAE,GAAG;gBACf,OAAO,EAAE,4BAA4B,IAAI,CAAC,oBAAoB,aAAa;aAC5E,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACnB,OAAO,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAC1D,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EACpC,CAAC,CAAkC,EAAE,EAAE;YACrC,IAAI,CAAC,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBACzB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,oCAAoC,EAAE,CAAC;YAC5G,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,8BAA8B,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QACxH,CAAC,CACF,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,sBAAsB;QAC9B,UAAU,EAAE,GAAG;QACf,OAAO,EAAE,iCAAiC,GAAG,EAAE;KAChD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,GAAW,EAAE,QAAgB;IACjD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC9B,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;YACtB,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;gBACrB,EAAE,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,GAAG,GAAoC,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBACxF,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;gBACrB,MAAM,CAAC,GAAG,CAAC,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACnD,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { type ProjectContext, BatchRegistry } from '@zhixuan92/multi-model-agent-core';
2
+ export type ReserveError = 'project_cap' | 'invalid_cwd' | 'missing_cwd' | 'cwd_not_dir' | 'forbidden_cwd';
3
+ export type ReserveResult = {
4
+ ok: true;
5
+ projectContext: ProjectContext;
6
+ created: boolean;
7
+ } | {
8
+ ok: false;
9
+ error: ReserveError;
10
+ message: string;
11
+ };
12
+ export interface ProjectRegistryOptions {
13
+ cap: number;
14
+ idleEvictionMs: number;
15
+ evictionIntervalMs: number;
16
+ onProjectCreated?: (cwd: string) => void;
17
+ onProjectEvicted?: (cwd: string, idleMs: number) => void;
18
+ }
19
+ export declare class ProjectRegistry {
20
+ private readonly map;
21
+ private readonly cap;
22
+ private readonly idleEvictionMs;
23
+ private readonly evictionIntervalMs;
24
+ private evictionTimer;
25
+ private readonly onProjectCreated?;
26
+ private readonly onProjectEvicted?;
27
+ constructor(options: ProjectRegistryOptions);
28
+ startEvictionTimer(): void;
29
+ stopEvictionTimer(): void;
30
+ /** Synchronous lookup-or-create with cap enforcement. Increments pendingReservations on success. */
31
+ reserveProject(cwd: string): ReserveResult;
32
+ /**
33
+ * Called from onsessioninitialized. Decrements pendingReservations and registers the session.
34
+ * `canonicalCwd` MUST be the `.cwd` value returned from a prior `reserveProject` call.
35
+ */
36
+ attachSession(canonicalCwd: string, sessionId: string): void;
37
+ /** Detach a session. `canonicalCwd` must match `projectContext.cwd`. No-op if unknown. */
38
+ detachSession(canonicalCwd: string, sessionId: string): void;
39
+ /** Called if attachSession never fires. `canonicalCwd` must match `projectContext.cwd`. */
40
+ cancelReservation(canonicalCwd: string): void;
41
+ /** Look up a project by its canonical cwd. */
42
+ get(canonicalCwd: string): ProjectContext | undefined;
43
+ get size(): number;
44
+ entries(): IterableIterator<[string, ProjectContext]>;
45
+ /**
46
+ * Returns true if the project context is idle and eligible for eviction.
47
+ * Gates on: no active HTTP requests, no active batches in the registry,
48
+ * no active sessions, no pending reservations, and idle for at least idleTimeoutMs.
49
+ */
50
+ isIdleFor(pc: ProjectContext, now: number, idleTimeoutMs: number, batchRegistry: BatchRegistry): boolean;
51
+ evictIdle(batchRegistry?: BatchRegistry): void;
52
+ clear(): void;
53
+ }
54
+ //# sourceMappingURL=project-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-registry.d.ts","sourceRoot":"","sources":["../../src/http/project-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,cAAc,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAG7G,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,aAAa,GAAG,aAAa,GAAG,aAAa,GAAG,eAAe,CAAC;AAE3G,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqC;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAwB;IAC1D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAwC;gBAE9D,OAAO,EAAE,sBAAsB;IAQ3C,kBAAkB,IAAI,IAAI;IAM1B,iBAAiB,IAAI,IAAI;IAKzB,oGAAoG;IACpG,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa;IAoB1C;;;OAGG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAQ5D,0FAA0F;IAC1F,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAO5D,2FAA2F;IAC3F,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAO7C,8CAA8C;IAC9C,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIrD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEA,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAItD;;;;OAIG;IACH,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,GAAG,OAAO;IAUxG,SAAS,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI;IAuB9C,KAAK,IAAI,IAAI;CAOd"}