cmdr-agent 1.0.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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +238 -0
  3. package/dist/bin/cmdr.d.ts +9 -0
  4. package/dist/bin/cmdr.d.ts.map +1 -0
  5. package/dist/bin/cmdr.js +49 -0
  6. package/dist/bin/cmdr.js.map +1 -0
  7. package/dist/src/cli/args.d.ts +19 -0
  8. package/dist/src/cli/args.d.ts.map +1 -0
  9. package/dist/src/cli/args.js +89 -0
  10. package/dist/src/cli/args.js.map +1 -0
  11. package/dist/src/cli/commands.d.ts +12 -0
  12. package/dist/src/cli/commands.d.ts.map +1 -0
  13. package/dist/src/cli/commands.js +400 -0
  14. package/dist/src/cli/commands.js.map +1 -0
  15. package/dist/src/cli/renderer.d.ts +8 -0
  16. package/dist/src/cli/renderer.d.ts.map +1 -0
  17. package/dist/src/cli/renderer.js +47 -0
  18. package/dist/src/cli/renderer.js.map +1 -0
  19. package/dist/src/cli/repl.d.ts +18 -0
  20. package/dist/src/cli/repl.d.ts.map +1 -0
  21. package/dist/src/cli/repl.js +751 -0
  22. package/dist/src/cli/repl.js.map +1 -0
  23. package/dist/src/cli/spinner.d.ts +16 -0
  24. package/dist/src/cli/spinner.d.ts.map +1 -0
  25. package/dist/src/cli/spinner.js +233 -0
  26. package/dist/src/cli/spinner.js.map +1 -0
  27. package/dist/src/cli/theme.d.ts +95 -0
  28. package/dist/src/cli/theme.d.ts.map +1 -0
  29. package/dist/src/cli/theme.js +178 -0
  30. package/dist/src/cli/theme.js.map +1 -0
  31. package/dist/src/communication/message-bus.d.ts +35 -0
  32. package/dist/src/communication/message-bus.d.ts.map +1 -0
  33. package/dist/src/communication/message-bus.js +60 -0
  34. package/dist/src/communication/message-bus.js.map +1 -0
  35. package/dist/src/communication/shared-memory.d.ts +19 -0
  36. package/dist/src/communication/shared-memory.d.ts.map +1 -0
  37. package/dist/src/communication/shared-memory.js +37 -0
  38. package/dist/src/communication/shared-memory.js.map +1 -0
  39. package/dist/src/communication/task-queue.d.ts +50 -0
  40. package/dist/src/communication/task-queue.d.ts.map +1 -0
  41. package/dist/src/communication/task-queue.js +158 -0
  42. package/dist/src/communication/task-queue.js.map +1 -0
  43. package/dist/src/config/config-loader.d.ts +23 -0
  44. package/dist/src/config/config-loader.d.ts.map +1 -0
  45. package/dist/src/config/config-loader.js +91 -0
  46. package/dist/src/config/config-loader.js.map +1 -0
  47. package/dist/src/config/defaults.d.ts +6 -0
  48. package/dist/src/config/defaults.d.ts.map +1 -0
  49. package/dist/src/config/defaults.js +21 -0
  50. package/dist/src/config/defaults.js.map +1 -0
  51. package/dist/src/config/schema.d.ts +135 -0
  52. package/dist/src/config/schema.d.ts.map +1 -0
  53. package/dist/src/config/schema.js +35 -0
  54. package/dist/src/config/schema.js.map +1 -0
  55. package/dist/src/config/telemetry.d.ts +41 -0
  56. package/dist/src/config/telemetry.d.ts.map +1 -0
  57. package/dist/src/config/telemetry.js +57 -0
  58. package/dist/src/config/telemetry.js.map +1 -0
  59. package/dist/src/core/agent-pool.d.ts +40 -0
  60. package/dist/src/core/agent-pool.d.ts.map +1 -0
  61. package/dist/src/core/agent-pool.js +66 -0
  62. package/dist/src/core/agent-pool.js.map +1 -0
  63. package/dist/src/core/agent-runner.d.ts +51 -0
  64. package/dist/src/core/agent-runner.d.ts.map +1 -0
  65. package/dist/src/core/agent-runner.js +251 -0
  66. package/dist/src/core/agent-runner.js.map +1 -0
  67. package/dist/src/core/agent.d.ts +34 -0
  68. package/dist/src/core/agent.d.ts.map +1 -0
  69. package/dist/src/core/agent.js +143 -0
  70. package/dist/src/core/agent.js.map +1 -0
  71. package/dist/src/core/intent.d.ts +33 -0
  72. package/dist/src/core/intent.d.ts.map +1 -0
  73. package/dist/src/core/intent.js +91 -0
  74. package/dist/src/core/intent.js.map +1 -0
  75. package/dist/src/core/orchestrator.d.ts +43 -0
  76. package/dist/src/core/orchestrator.d.ts.map +1 -0
  77. package/dist/src/core/orchestrator.js +115 -0
  78. package/dist/src/core/orchestrator.js.map +1 -0
  79. package/dist/src/core/permissions.d.ts +36 -0
  80. package/dist/src/core/permissions.d.ts.map +1 -0
  81. package/dist/src/core/permissions.js +129 -0
  82. package/dist/src/core/permissions.js.map +1 -0
  83. package/dist/src/core/presets.d.ts +12 -0
  84. package/dist/src/core/presets.d.ts.map +1 -0
  85. package/dist/src/core/presets.js +148 -0
  86. package/dist/src/core/presets.js.map +1 -0
  87. package/dist/src/core/team.d.ts +44 -0
  88. package/dist/src/core/team.d.ts.map +1 -0
  89. package/dist/src/core/team.js +156 -0
  90. package/dist/src/core/team.js.map +1 -0
  91. package/dist/src/core/types.d.ts +257 -0
  92. package/dist/src/core/types.d.ts.map +1 -0
  93. package/dist/src/core/types.js +7 -0
  94. package/dist/src/core/types.js.map +1 -0
  95. package/dist/src/index.d.ts +44 -0
  96. package/dist/src/index.d.ts.map +1 -0
  97. package/dist/src/index.js +45 -0
  98. package/dist/src/index.js.map +1 -0
  99. package/dist/src/llm/adapter.d.ts +5 -0
  100. package/dist/src/llm/adapter.d.ts.map +1 -0
  101. package/dist/src/llm/adapter.js +5 -0
  102. package/dist/src/llm/adapter.js.map +1 -0
  103. package/dist/src/llm/model-registry.d.ts +14 -0
  104. package/dist/src/llm/model-registry.d.ts.map +1 -0
  105. package/dist/src/llm/model-registry.js +30 -0
  106. package/dist/src/llm/model-registry.js.map +1 -0
  107. package/dist/src/llm/ollama.d.ts +26 -0
  108. package/dist/src/llm/ollama.d.ts.map +1 -0
  109. package/dist/src/llm/ollama.js +375 -0
  110. package/dist/src/llm/ollama.js.map +1 -0
  111. package/dist/src/llm/token-counter.d.ts +11 -0
  112. package/dist/src/llm/token-counter.d.ts.map +1 -0
  113. package/dist/src/llm/token-counter.js +35 -0
  114. package/dist/src/llm/token-counter.js.map +1 -0
  115. package/dist/src/plugins/mcp-client.d.ts +38 -0
  116. package/dist/src/plugins/mcp-client.d.ts.map +1 -0
  117. package/dist/src/plugins/mcp-client.js +113 -0
  118. package/dist/src/plugins/mcp-client.js.map +1 -0
  119. package/dist/src/plugins/plugin-manager.d.ts +37 -0
  120. package/dist/src/plugins/plugin-manager.d.ts.map +1 -0
  121. package/dist/src/plugins/plugin-manager.js +146 -0
  122. package/dist/src/plugins/plugin-manager.js.map +1 -0
  123. package/dist/src/scheduling/semaphore.d.ts +20 -0
  124. package/dist/src/scheduling/semaphore.d.ts.map +1 -0
  125. package/dist/src/scheduling/semaphore.js +52 -0
  126. package/dist/src/scheduling/semaphore.js.map +1 -0
  127. package/dist/src/scheduling/strategies.d.ts +39 -0
  128. package/dist/src/scheduling/strategies.d.ts.map +1 -0
  129. package/dist/src/scheduling/strategies.js +88 -0
  130. package/dist/src/scheduling/strategies.js.map +1 -0
  131. package/dist/src/session/compaction.d.ts +32 -0
  132. package/dist/src/session/compaction.d.ts.map +1 -0
  133. package/dist/src/session/compaction.js +172 -0
  134. package/dist/src/session/compaction.js.map +1 -0
  135. package/dist/src/session/cost-tracker.d.ts +41 -0
  136. package/dist/src/session/cost-tracker.d.ts.map +1 -0
  137. package/dist/src/session/cost-tracker.js +76 -0
  138. package/dist/src/session/cost-tracker.js.map +1 -0
  139. package/dist/src/session/project-context.d.ts +6 -0
  140. package/dist/src/session/project-context.d.ts.map +1 -0
  141. package/dist/src/session/project-context.js +147 -0
  142. package/dist/src/session/project-context.js.map +1 -0
  143. package/dist/src/session/prompt-builder.d.ts +11 -0
  144. package/dist/src/session/prompt-builder.d.ts.map +1 -0
  145. package/dist/src/session/prompt-builder.js +30 -0
  146. package/dist/src/session/prompt-builder.js.map +1 -0
  147. package/dist/src/session/session-manager.d.ts +32 -0
  148. package/dist/src/session/session-manager.d.ts.map +1 -0
  149. package/dist/src/session/session-manager.js +84 -0
  150. package/dist/src/session/session-manager.js.map +1 -0
  151. package/dist/src/session/session-persistence.d.ts +44 -0
  152. package/dist/src/session/session-persistence.d.ts.map +1 -0
  153. package/dist/src/session/session-persistence.js +150 -0
  154. package/dist/src/session/session-persistence.js.map +1 -0
  155. package/dist/src/session/undo-manager.d.ts +35 -0
  156. package/dist/src/session/undo-manager.d.ts.map +1 -0
  157. package/dist/src/session/undo-manager.js +79 -0
  158. package/dist/src/session/undo-manager.js.map +1 -0
  159. package/dist/src/tools/built-in/ask-user.d.ts +7 -0
  160. package/dist/src/tools/built-in/ask-user.d.ts.map +1 -0
  161. package/dist/src/tools/built-in/ask-user.js +28 -0
  162. package/dist/src/tools/built-in/ask-user.js.map +1 -0
  163. package/dist/src/tools/built-in/bash.d.ts +9 -0
  164. package/dist/src/tools/built-in/bash.d.ts.map +1 -0
  165. package/dist/src/tools/built-in/bash.js +67 -0
  166. package/dist/src/tools/built-in/bash.js.map +1 -0
  167. package/dist/src/tools/built-in/file-edit.d.ts +9 -0
  168. package/dist/src/tools/built-in/file-edit.d.ts.map +1 -0
  169. package/dist/src/tools/built-in/file-edit.js +39 -0
  170. package/dist/src/tools/built-in/file-edit.js.map +1 -0
  171. package/dist/src/tools/built-in/file-read.d.ts +9 -0
  172. package/dist/src/tools/built-in/file-read.d.ts.map +1 -0
  173. package/dist/src/tools/built-in/file-read.js +41 -0
  174. package/dist/src/tools/built-in/file-read.js.map +1 -0
  175. package/dist/src/tools/built-in/file-write.d.ts +8 -0
  176. package/dist/src/tools/built-in/file-write.d.ts.map +1 -0
  177. package/dist/src/tools/built-in/file-write.js +29 -0
  178. package/dist/src/tools/built-in/file-write.js.map +1 -0
  179. package/dist/src/tools/built-in/git-commit.d.ts +12 -0
  180. package/dist/src/tools/built-in/git-commit.d.ts.map +1 -0
  181. package/dist/src/tools/built-in/git-commit.js +96 -0
  182. package/dist/src/tools/built-in/git-commit.js.map +1 -0
  183. package/dist/src/tools/built-in/git-diff.d.ts +8 -0
  184. package/dist/src/tools/built-in/git-diff.d.ts.map +1 -0
  185. package/dist/src/tools/built-in/git-diff.js +43 -0
  186. package/dist/src/tools/built-in/git-diff.js.map +1 -0
  187. package/dist/src/tools/built-in/git-log.d.ts +8 -0
  188. package/dist/src/tools/built-in/git-log.d.ts.map +1 -0
  189. package/dist/src/tools/built-in/git-log.js +39 -0
  190. package/dist/src/tools/built-in/git-log.js.map +1 -0
  191. package/dist/src/tools/built-in/glob.d.ts +8 -0
  192. package/dist/src/tools/built-in/glob.d.ts.map +1 -0
  193. package/dist/src/tools/built-in/glob.js +60 -0
  194. package/dist/src/tools/built-in/glob.js.map +1 -0
  195. package/dist/src/tools/built-in/grep.d.ts +9 -0
  196. package/dist/src/tools/built-in/grep.d.ts.map +1 -0
  197. package/dist/src/tools/built-in/grep.js +115 -0
  198. package/dist/src/tools/built-in/grep.js.map +1 -0
  199. package/dist/src/tools/built-in/index.d.ts +21 -0
  200. package/dist/src/tools/built-in/index.d.ts.map +1 -0
  201. package/dist/src/tools/built-in/index.js +30 -0
  202. package/dist/src/tools/built-in/index.js.map +1 -0
  203. package/dist/src/tools/built-in/think.d.ts +7 -0
  204. package/dist/src/tools/built-in/think.d.ts.map +1 -0
  205. package/dist/src/tools/built-in/think.js +18 -0
  206. package/dist/src/tools/built-in/think.js.map +1 -0
  207. package/dist/src/tools/built-in/web-fetch.d.ts +11 -0
  208. package/dist/src/tools/built-in/web-fetch.d.ts.map +1 -0
  209. package/dist/src/tools/built-in/web-fetch.js +70 -0
  210. package/dist/src/tools/built-in/web-fetch.js.map +1 -0
  211. package/dist/src/tools/executor.d.ts +25 -0
  212. package/dist/src/tools/executor.d.ts.map +1 -0
  213. package/dist/src/tools/executor.js +61 -0
  214. package/dist/src/tools/executor.js.map +1 -0
  215. package/dist/src/tools/registry.d.ts +25 -0
  216. package/dist/src/tools/registry.d.ts.map +1 -0
  217. package/dist/src/tools/registry.js +135 -0
  218. package/dist/src/tools/registry.js.map +1 -0
  219. package/package.json +63 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * PluginManager — loads, registers, and manages plugin lifecycle.
3
+ *
4
+ * Plugins can provide hooks, tools, and slash commands.
5
+ */
6
+ import type { CmdrPlugin, LLMChatOptions, LLMResponse, ToolResult, SessionState, SlashCommand } from '../core/types.js';
7
+ import type { ToolRegistry } from '../tools/registry.js';
8
+ export declare class PluginManager {
9
+ private plugins;
10
+ /** Load a plugin from a module path or package name. */
11
+ load(source: string): Promise<void>;
12
+ /** Register a plugin instance directly (for programmatic use). */
13
+ register(plugin: CmdrPlugin): void;
14
+ /** Unregister a plugin by name. */
15
+ unregister(name: string): boolean;
16
+ /** Get all loaded plugins. */
17
+ list(): CmdrPlugin[];
18
+ /** Register all plugin tools into a ToolRegistry. */
19
+ registerTools(registry: ToolRegistry): void;
20
+ /** Get all slash commands from plugins. */
21
+ getCommands(): SlashCommand[];
22
+ /** Run beforePrompt hooks. Plugins can modify the chat options. */
23
+ runBeforePrompt(options: LLMChatOptions): Promise<LLMChatOptions>;
24
+ /** Run afterResponse hooks. Plugins can modify the response. */
25
+ runAfterResponse(response: LLMResponse): Promise<LLMResponse>;
26
+ /** Run beforeToolExec hooks. Plugins can modify tool input. */
27
+ runBeforeToolExec(tool: string, input: unknown): Promise<unknown>;
28
+ /** Run afterToolExec hooks. Plugins can modify tool results. */
29
+ runAfterToolExec(tool: string, result: ToolResult): Promise<ToolResult>;
30
+ /** Run onError hooks. */
31
+ runOnError(error: Error): Promise<void>;
32
+ /** Run onSessionStart hooks. */
33
+ runOnSessionStart(session: SessionState): Promise<void>;
34
+ /** Run onSessionEnd hooks. */
35
+ runOnSessionEnd(session: SessionState): Promise<void>;
36
+ }
37
+ //# sourceMappingURL=plugin-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-manager.d.ts","sourceRoot":"","sources":["../../../src/plugins/plugin-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,UAAU,EAAE,cAAc,EAAE,WAAW,EACvC,UAAU,EAAE,YAAY,EAAkB,YAAY,EACvD,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAExD,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAmB;IAElC,wDAAwD;IAClD,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBzC,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAOlC,mCAAmC;IACnC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAOjC,8BAA8B;IAC9B,IAAI,IAAI,UAAU,EAAE;IAIpB,qDAAqD;IACrD,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAU3C,2CAA2C;IAC3C,WAAW,IAAI,YAAY,EAAE;IAY7B,mEAAmE;IAC7D,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAUvE,gEAAgE;IAC1D,gBAAgB,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAUnE,+DAA+D;IACzD,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAUvE,gEAAgE;IAC1D,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAU7E,yBAAyB;IACnB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7C,gCAAgC;IAC1B,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7D,8BAA8B;IACxB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAW5D"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * PluginManager — loads, registers, and manages plugin lifecycle.
3
+ *
4
+ * Plugins can provide hooks, tools, and slash commands.
5
+ */
6
+ export class PluginManager {
7
+ plugins = [];
8
+ /** Load a plugin from a module path or package name. */
9
+ async load(source) {
10
+ try {
11
+ const mod = await import(source);
12
+ const plugin = mod.default ?? mod;
13
+ if (!plugin.name) {
14
+ throw new Error(`Plugin from "${source}" has no name`);
15
+ }
16
+ if (this.plugins.some(p => p.name === plugin.name)) {
17
+ throw new Error(`Plugin "${plugin.name}" is already loaded`);
18
+ }
19
+ this.plugins.push(plugin);
20
+ }
21
+ catch (err) {
22
+ const msg = err instanceof Error ? err.message : String(err);
23
+ throw new Error(`Failed to load plugin "${source}": ${msg}`);
24
+ }
25
+ }
26
+ /** Register a plugin instance directly (for programmatic use). */
27
+ register(plugin) {
28
+ if (this.plugins.some(p => p.name === plugin.name)) {
29
+ throw new Error(`Plugin "${plugin.name}" is already registered`);
30
+ }
31
+ this.plugins.push(plugin);
32
+ }
33
+ /** Unregister a plugin by name. */
34
+ unregister(name) {
35
+ const idx = this.plugins.findIndex(p => p.name === name);
36
+ if (idx === -1)
37
+ return false;
38
+ this.plugins.splice(idx, 1);
39
+ return true;
40
+ }
41
+ /** Get all loaded plugins. */
42
+ list() {
43
+ return [...this.plugins];
44
+ }
45
+ /** Register all plugin tools into a ToolRegistry. */
46
+ registerTools(registry) {
47
+ for (const plugin of this.plugins) {
48
+ if (plugin.tools) {
49
+ for (const tool of plugin.tools) {
50
+ registry.register(tool);
51
+ }
52
+ }
53
+ }
54
+ }
55
+ /** Get all slash commands from plugins. */
56
+ getCommands() {
57
+ const cmds = [];
58
+ for (const plugin of this.plugins) {
59
+ if (plugin.commands) {
60
+ cmds.push(...plugin.commands);
61
+ }
62
+ }
63
+ return cmds;
64
+ }
65
+ // ─── Hook pipeline ────────────────────────────────────────
66
+ /** Run beforePrompt hooks. Plugins can modify the chat options. */
67
+ async runBeforePrompt(options) {
68
+ let result = options;
69
+ for (const plugin of this.plugins) {
70
+ if (plugin.hooks?.beforePrompt) {
71
+ result = await plugin.hooks.beforePrompt(result);
72
+ }
73
+ }
74
+ return result;
75
+ }
76
+ /** Run afterResponse hooks. Plugins can modify the response. */
77
+ async runAfterResponse(response) {
78
+ let result = response;
79
+ for (const plugin of this.plugins) {
80
+ if (plugin.hooks?.afterResponse) {
81
+ result = await plugin.hooks.afterResponse(result);
82
+ }
83
+ }
84
+ return result;
85
+ }
86
+ /** Run beforeToolExec hooks. Plugins can modify tool input. */
87
+ async runBeforeToolExec(tool, input) {
88
+ let result = input;
89
+ for (const plugin of this.plugins) {
90
+ if (plugin.hooks?.beforeToolExec) {
91
+ result = await plugin.hooks.beforeToolExec(tool, result);
92
+ }
93
+ }
94
+ return result;
95
+ }
96
+ /** Run afterToolExec hooks. Plugins can modify tool results. */
97
+ async runAfterToolExec(tool, result) {
98
+ let modified = result;
99
+ for (const plugin of this.plugins) {
100
+ if (plugin.hooks?.afterToolExec) {
101
+ modified = await plugin.hooks.afterToolExec(tool, modified);
102
+ }
103
+ }
104
+ return modified;
105
+ }
106
+ /** Run onError hooks. */
107
+ async runOnError(error) {
108
+ for (const plugin of this.plugins) {
109
+ if (plugin.hooks?.onError) {
110
+ try {
111
+ await plugin.hooks.onError(error);
112
+ }
113
+ catch {
114
+ // Don't let plugin errors cascade
115
+ }
116
+ }
117
+ }
118
+ }
119
+ /** Run onSessionStart hooks. */
120
+ async runOnSessionStart(session) {
121
+ for (const plugin of this.plugins) {
122
+ if (plugin.hooks?.onSessionStart) {
123
+ try {
124
+ await plugin.hooks.onSessionStart(session);
125
+ }
126
+ catch {
127
+ // best effort
128
+ }
129
+ }
130
+ }
131
+ }
132
+ /** Run onSessionEnd hooks. */
133
+ async runOnSessionEnd(session) {
134
+ for (const plugin of this.plugins) {
135
+ if (plugin.hooks?.onSessionEnd) {
136
+ try {
137
+ await plugin.hooks.onSessionEnd(session);
138
+ }
139
+ catch {
140
+ // best effort
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ //# sourceMappingURL=plugin-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-manager.js","sourceRoot":"","sources":["../../../src/plugins/plugin-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Semaphore — concurrency limiter for parallel agent/task execution.
3
+ */
4
+ export declare class Semaphore {
5
+ private readonly max;
6
+ private current;
7
+ private queue;
8
+ constructor(max: number);
9
+ /** Acquire a slot. Resolves when a slot is available. */
10
+ acquire(): Promise<void>;
11
+ /** Release a slot. Wakes the next waiter if any. */
12
+ release(): void;
13
+ /** Run a function while holding a semaphore slot. */
14
+ run<T>(fn: () => Promise<T>): Promise<T>;
15
+ /** Current number of active slots. */
16
+ get active(): number;
17
+ /** Number of waiters in queue. */
18
+ get waiting(): number;
19
+ }
20
+ //# sourceMappingURL=semaphore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semaphore.d.ts","sourceRoot":"","sources":["../../../src/scheduling/semaphore.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,SAAS;IAIR,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHhC,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,KAAK,CAAwB;gBAER,GAAG,EAAE,MAAM;IAIxC,yDAAyD;IACzD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAUxB,oDAAoD;IACpD,OAAO,IAAI,IAAI;IASf,qDAAqD;IAC/C,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAS9C,sCAAsC;IACtC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,kCAAkC;IAClC,IAAI,OAAO,IAAI,MAAM,CAEpB;CACF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Semaphore — concurrency limiter for parallel agent/task execution.
3
+ */
4
+ export class Semaphore {
5
+ max;
6
+ current = 0;
7
+ queue = [];
8
+ constructor(max) {
9
+ this.max = max;
10
+ if (max < 1)
11
+ throw new Error('Semaphore max must be >= 1');
12
+ }
13
+ /** Acquire a slot. Resolves when a slot is available. */
14
+ acquire() {
15
+ if (this.current < this.max) {
16
+ this.current++;
17
+ return Promise.resolve();
18
+ }
19
+ return new Promise(resolve => {
20
+ this.queue.push(resolve);
21
+ });
22
+ }
23
+ /** Release a slot. Wakes the next waiter if any. */
24
+ release() {
25
+ if (this.queue.length > 0) {
26
+ const next = this.queue.shift();
27
+ next();
28
+ }
29
+ else {
30
+ this.current = Math.max(0, this.current - 1);
31
+ }
32
+ }
33
+ /** Run a function while holding a semaphore slot. */
34
+ async run(fn) {
35
+ await this.acquire();
36
+ try {
37
+ return await fn();
38
+ }
39
+ finally {
40
+ this.release();
41
+ }
42
+ }
43
+ /** Current number of active slots. */
44
+ get active() {
45
+ return this.current;
46
+ }
47
+ /** Number of waiters in queue. */
48
+ get waiting() {
49
+ return this.queue.length;
50
+ }
51
+ }
52
+ //# sourceMappingURL=semaphore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semaphore.js","sourceRoot":"","sources":["../../../src/scheduling/semaphore.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,OAAO,SAAS;IAIS;IAHrB,OAAO,GAAG,CAAC,CAAA;IACX,KAAK,GAAsB,EAAE,CAAA;IAErC,YAA6B,GAAW;QAAX,QAAG,GAAH,GAAG,CAAQ;QACtC,IAAI,GAAG,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;IAC5D,CAAC;IAED,yDAAyD;IACzD,OAAO;QACL,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,EAAE,CAAA;YACd,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;QAC1B,CAAC;QACD,OAAO,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;YACjC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC1B,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,oDAAoD;IACpD,OAAO;QACL,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAA;YAChC,IAAI,EAAE,CAAA;QACR,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,KAAK,CAAC,GAAG,CAAI,EAAoB;QAC/B,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;QACpB,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAA;QACnB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,EAAE,CAAA;QAChB,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,kCAAkC;IAClC,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAA;IAC1B,CAAC;CACF"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Scheduling strategies for multi-agent task assignment.
3
+ *
4
+ * Each strategy takes a list of available agents and a task,
5
+ * and returns the name of the best agent to handle it.
6
+ */
7
+ import type { AgentConfig, Task } from '../core/types.js';
8
+ export type SchedulingStrategy = 'round-robin' | 'least-busy' | 'capability-match' | 'dependency-first';
9
+ export interface AgentLoad {
10
+ readonly name: string;
11
+ readonly activeTasks: number;
12
+ readonly completedTasks: number;
13
+ }
14
+ /**
15
+ * Round-robin: Cycle through agents in order.
16
+ */
17
+ export declare function roundRobin(agents: readonly AgentConfig[], _task: Task, counter: number): string;
18
+ /**
19
+ * Least-busy: Pick the agent with the fewest active tasks.
20
+ */
21
+ export declare function leastBusy(agents: readonly AgentConfig[], _task: Task, loads: readonly AgentLoad[]): string;
22
+ /**
23
+ * Capability-match: Pick the agent whose tool set best matches the task.
24
+ * Scores agents by how many task-relevant keywords match their tools + system prompt.
25
+ */
26
+ export declare function capabilityMatch(agents: readonly AgentConfig[], task: Task): string;
27
+ /**
28
+ * Dependency-first: Assign tasks whose dependencies are most satisfied first,
29
+ * then use capability-match for the actual agent selection.
30
+ */
31
+ export declare function dependencyFirst(agents: readonly AgentConfig[], task: Task): string;
32
+ /**
33
+ * Select agent using the specified strategy.
34
+ */
35
+ export declare function selectAgent(strategy: SchedulingStrategy, agents: readonly AgentConfig[], task: Task, state: {
36
+ counter: number;
37
+ loads: AgentLoad[];
38
+ }): string;
39
+ //# sourceMappingURL=strategies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategies.d.ts","sourceRoot":"","sources":["../../../src/scheduling/strategies.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAEzD,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,YAAY,GAAG,kBAAkB,GAAG,kBAAkB,CAAA;AAEvG,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,KAAK,EAAE,IAAI,EACX,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,SAAS,SAAS,EAAE,GAC1B,MAAM,CAcR;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,IAAI,EAAE,IAAI,GACT,MAAM,CA8BR;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,IAAI,EAAE,IAAI,GACT,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,GAC7C,MAAM,CAWR"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Scheduling strategies for multi-agent task assignment.
3
+ *
4
+ * Each strategy takes a list of available agents and a task,
5
+ * and returns the name of the best agent to handle it.
6
+ */
7
+ /**
8
+ * Round-robin: Cycle through agents in order.
9
+ */
10
+ export function roundRobin(agents, _task, counter) {
11
+ return agents[counter % agents.length].name;
12
+ }
13
+ /**
14
+ * Least-busy: Pick the agent with the fewest active tasks.
15
+ */
16
+ export function leastBusy(agents, _task, loads) {
17
+ const loadMap = new Map(loads.map(l => [l.name, l.activeTasks]));
18
+ let best = agents[0].name;
19
+ let bestLoad = Infinity;
20
+ for (const agent of agents) {
21
+ const load = loadMap.get(agent.name) ?? 0;
22
+ if (load < bestLoad) {
23
+ bestLoad = load;
24
+ best = agent.name;
25
+ }
26
+ }
27
+ return best;
28
+ }
29
+ /**
30
+ * Capability-match: Pick the agent whose tool set best matches the task.
31
+ * Scores agents by how many task-relevant keywords match their tools + system prompt.
32
+ */
33
+ export function capabilityMatch(agents, task) {
34
+ const taskText = `${task.title} ${task.description}`.toLowerCase();
35
+ let bestAgent = agents[0].name;
36
+ let bestScore = -1;
37
+ for (const agent of agents) {
38
+ let score = 0;
39
+ const agentProfile = `${agent.name} ${agent.systemPrompt ?? ''} ${(agent.tools ?? []).join(' ')}`.toLowerCase();
40
+ // Score based on keyword overlap
41
+ const taskWords = new Set(taskText.split(/\s+/).filter(w => w.length > 3));
42
+ for (const word of taskWords) {
43
+ if (agentProfile.includes(word))
44
+ score++;
45
+ }
46
+ // Bonus if agent has tools that seem relevant
47
+ if (taskText.includes('test') && agentProfile.includes('bash'))
48
+ score += 2;
49
+ if (taskText.includes('review') && agentProfile.includes('review'))
50
+ score += 3;
51
+ if (taskText.includes('write') && agentProfile.includes('file_write'))
52
+ score += 2;
53
+ if (taskText.includes('fix') && agentProfile.includes('file_edit'))
54
+ score += 2;
55
+ if (taskText.includes('search') && agentProfile.includes('grep'))
56
+ score += 2;
57
+ if (score > bestScore) {
58
+ bestScore = score;
59
+ bestAgent = agent.name;
60
+ }
61
+ }
62
+ return bestAgent;
63
+ }
64
+ /**
65
+ * Dependency-first: Assign tasks whose dependencies are most satisfied first,
66
+ * then use capability-match for the actual agent selection.
67
+ */
68
+ export function dependencyFirst(agents, task) {
69
+ // Delegate to capability-match for agent selection.
70
+ // The ordering is handled by the TaskQueue's topological sort.
71
+ return capabilityMatch(agents, task);
72
+ }
73
+ /**
74
+ * Select agent using the specified strategy.
75
+ */
76
+ export function selectAgent(strategy, agents, task, state) {
77
+ switch (strategy) {
78
+ case 'round-robin':
79
+ return roundRobin(agents, task, state.counter);
80
+ case 'least-busy':
81
+ return leastBusy(agents, task, state.loads);
82
+ case 'capability-match':
83
+ return capabilityMatch(agents, task);
84
+ case 'dependency-first':
85
+ return dependencyFirst(agents, task);
86
+ }
87
+ }
88
+ //# sourceMappingURL=strategies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategies.js","sourceRoot":"","sources":["../../../src/scheduling/strategies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Compaction — intelligent conversation history compaction.
3
+ *
4
+ * Multi-stage strategy:
5
+ * 1. Truncate old tool results (no LLM call needed)
6
+ * 2. Summarize old conversation via LLM
7
+ * 3. Hard truncation as emergency fallback
8
+ */
9
+ import type { LLMMessage, LLMAdapter } from '../core/types.js';
10
+ export interface CompactionConfig {
11
+ /** Model's context window size in tokens */
12
+ maxContextTokens: number;
13
+ /** Trigger compaction at this fraction of max (default: 0.75) */
14
+ compactionThreshold: number;
15
+ /** Always keep last N user+assistant pairs intact (default: 4) */
16
+ preserveRecentTurns: number;
17
+ /** Max tokens for the summary message (default: 500) */
18
+ summaryMaxTokens: number;
19
+ }
20
+ export declare const DEFAULT_COMPACTION_CONFIG: CompactionConfig;
21
+ /**
22
+ * Check whether compaction should be triggered.
23
+ */
24
+ export declare function shouldCompact(messages: LLMMessage[], tokenCount: number, config: CompactionConfig): boolean;
25
+ /**
26
+ * Full compaction pipeline: truncate tool results → LLM summary → hard truncation.
27
+ */
28
+ export declare function compactHistory(messages: LLMMessage[], config: CompactionConfig, adapter: LLMAdapter, model: string): Promise<{
29
+ messages: LLMMessage[];
30
+ tokensSaved: number;
31
+ }>;
32
+ //# sourceMappingURL=compaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/session/compaction.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAA4B,MAAM,kBAAkB,CAAA;AAGxF,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,gBAAgB,EAAE,MAAM,CAAA;IACxB,iEAAiE;IACjE,mBAAmB,EAAE,MAAM,CAAA;IAC3B,kEAAkE;IAClE,mBAAmB,EAAE,MAAM,CAAA;IAC3B,wDAAwD;IACxD,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,eAAO,MAAM,yBAAyB,EAAE,gBAKvC,CAAA;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,UAAU,EAAE,EACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAET;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,UAAU,EAAE,EACtB,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CA4D1D"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Compaction — intelligent conversation history compaction.
3
+ *
4
+ * Multi-stage strategy:
5
+ * 1. Truncate old tool results (no LLM call needed)
6
+ * 2. Summarize old conversation via LLM
7
+ * 3. Hard truncation as emergency fallback
8
+ */
9
+ import { countMessageTokens } from '../llm/token-counter.js';
10
+ export const DEFAULT_COMPACTION_CONFIG = {
11
+ maxContextTokens: 32768,
12
+ compactionThreshold: 0.75,
13
+ preserveRecentTurns: 4,
14
+ summaryMaxTokens: 500,
15
+ };
16
+ /**
17
+ * Check whether compaction should be triggered.
18
+ */
19
+ export function shouldCompact(messages, tokenCount, config) {
20
+ return tokenCount > config.maxContextTokens * config.compactionThreshold;
21
+ }
22
+ /**
23
+ * Full compaction pipeline: truncate tool results → LLM summary → hard truncation.
24
+ */
25
+ export async function compactHistory(messages, config, adapter, model) {
26
+ const originalTokens = countMessageTokens(messages);
27
+ // Determine the split point: keep the last `preserveRecentTurns * 2` messages
28
+ const keepCount = config.preserveRecentTurns * 2;
29
+ if (messages.length <= keepCount) {
30
+ return { messages, tokensSaved: 0 };
31
+ }
32
+ const oldMessages = messages.slice(0, messages.length - keepCount);
33
+ const recentMessages = messages.slice(messages.length - keepCount);
34
+ // ─── Stage 1: Truncate old tool results ───
35
+ const truncatedOld = truncateToolResults(oldMessages);
36
+ let result = [...truncatedOld, ...recentMessages];
37
+ let currentTokens = countMessageTokens(result);
38
+ if (currentTokens <= config.maxContextTokens * config.compactionThreshold) {
39
+ return { messages: result, tokensSaved: originalTokens - currentTokens };
40
+ }
41
+ // ─── Stage 2: LLM-powered summary of old messages ───
42
+ try {
43
+ const summaryMessage = await summarizeMessages(truncatedOld, adapter, model, config.summaryMaxTokens);
44
+ result = [summaryMessage, ...recentMessages];
45
+ currentTokens = countMessageTokens(result);
46
+ if (currentTokens <= config.maxContextTokens * config.compactionThreshold) {
47
+ return { messages: result, tokensSaved: originalTokens - currentTokens };
48
+ }
49
+ }
50
+ catch {
51
+ // LLM summary failed — fall through to hard truncation
52
+ // Use a simple text-based summary instead
53
+ const fallbackSummary = buildFallbackSummary(truncatedOld);
54
+ result = [fallbackSummary, ...recentMessages];
55
+ currentTokens = countMessageTokens(result);
56
+ }
57
+ // ─── Stage 3: Hard truncation ───
58
+ // Drop oldest messages (after summary) one at a time until under threshold
59
+ while (result.length > 2 && currentTokens > config.maxContextTokens * config.compactionThreshold) {
60
+ // Never drop the first message (summary) or the recent messages
61
+ if (result.length <= keepCount + 1) {
62
+ // Truncate the summary itself if needed
63
+ const summaryBlock = result[0];
64
+ if (summaryBlock.role === 'user' && summaryBlock.content[0]?.type === 'text') {
65
+ const text = summaryBlock.content[0].text;
66
+ const halfLen = Math.floor(text.length / 2);
67
+ result[0] = {
68
+ role: 'user',
69
+ content: [{ type: 'text', text: text.slice(0, halfLen) + '\n... (truncated)' }],
70
+ };
71
+ }
72
+ break;
73
+ }
74
+ result.splice(1, 1); // Remove second message (first after summary)
75
+ currentTokens = countMessageTokens(result);
76
+ }
77
+ return { messages: result, tokensSaved: originalTokens - currentTokens };
78
+ }
79
+ /**
80
+ * Stage 1: Truncate tool result contents in old messages.
81
+ */
82
+ function truncateToolResults(messages) {
83
+ return messages.map(msg => {
84
+ const newContent = msg.content.map(block => {
85
+ if (block.type === 'tool_result') {
86
+ const content = block.content;
87
+ if (content.length > 500) {
88
+ return {
89
+ ...block,
90
+ content: content.slice(0, 200) + `\n... (truncated, was ${content.length} chars)`,
91
+ };
92
+ }
93
+ }
94
+ return block;
95
+ });
96
+ return { ...msg, content: newContent };
97
+ });
98
+ }
99
+ /**
100
+ * Stage 2: Use the LLM to create a concise summary of old messages.
101
+ */
102
+ async function summarizeMessages(messages, adapter, model, maxTokens) {
103
+ // Build a text representation of the conversation to summarize
104
+ const conversationText = messages.map(msg => {
105
+ const textParts = msg.content
106
+ .filter(b => b.type === 'text')
107
+ .map(b => b.text)
108
+ .join('');
109
+ const toolParts = msg.content
110
+ .filter(b => b.type === 'tool_use')
111
+ .map(b => `[tool: ${b.name}]`)
112
+ .join(', ');
113
+ const prefix = msg.role === 'user' ? 'User' : 'Assistant';
114
+ let line = `${prefix}: ${textParts.slice(0, 300)}`;
115
+ if (toolParts)
116
+ line += ` ${toolParts}`;
117
+ return line;
118
+ }).join('\n');
119
+ const summaryPrompt = [
120
+ {
121
+ role: 'user',
122
+ content: [{
123
+ type: 'text',
124
+ text: `Summarize the following conversation between a user and a coding assistant.\nFocus on: what files were read/modified, what tasks were completed, what decisions were made, and what the current state of work is.\nBe concise. Output only the summary, no preamble.\n\n${conversationText}`,
125
+ }],
126
+ },
127
+ ];
128
+ const response = await adapter.chat(summaryPrompt, {
129
+ model,
130
+ maxTokens,
131
+ temperature: 0.3,
132
+ });
133
+ const summaryText = response.content
134
+ .filter(b => b.type === 'text')
135
+ .map(b => b.text)
136
+ .join('');
137
+ return {
138
+ role: 'user',
139
+ content: [{
140
+ type: 'text',
141
+ text: `[Previous conversation summary]\n${summaryText}\n[End of summary — recent conversation follows]`,
142
+ }],
143
+ };
144
+ }
145
+ /**
146
+ * Fallback summary when LLM call fails — simple text extraction.
147
+ */
148
+ function buildFallbackSummary(messages) {
149
+ const parts = ['[Previous conversation summary]'];
150
+ for (const msg of messages) {
151
+ const text = msg.content
152
+ .filter(b => b.type === 'text')
153
+ .map(b => b.text)
154
+ .join('')
155
+ .slice(0, 200);
156
+ if (text) {
157
+ parts.push(`${msg.role}: ${text}${text.length >= 200 ? '...' : ''}`);
158
+ }
159
+ const tools = msg.content
160
+ .filter(b => b.type === 'tool_use')
161
+ .map(b => b.name);
162
+ if (tools.length > 0) {
163
+ parts.push(` [tools: ${tools.join(', ')}]`);
164
+ }
165
+ }
166
+ parts.push('[End of summary — recent conversation follows]');
167
+ return {
168
+ role: 'user',
169
+ content: [{ type: 'text', text: parts.join('\n') }],
170
+ };
171
+ }
172
+ //# sourceMappingURL=compaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../../src/session/compaction.ts"],"names":[],"mappings":"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"}