@comma-agents/core 2.0.0-rc.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 (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -0
  3. package/dist/abortable/abortable.d.ts +5 -0
  4. package/dist/abortable/abortable.types.d.ts +10 -0
  5. package/dist/abortable/index.d.ts +2 -0
  6. package/dist/agents/agent/agent.constants.d.ts +5 -0
  7. package/dist/agents/agent/agent.d.ts +24 -0
  8. package/dist/agents/agent/agent.types.d.ts +408 -0
  9. package/dist/agents/agent/agent.utils.d.ts +107 -0
  10. package/dist/agents/built-in/user/user-agent.d.ts +32 -0
  11. package/dist/agents/built-in/user/user-agent.types.d.ts +53 -0
  12. package/dist/agents/built-in/user/user-agent.utils.d.ts +2 -0
  13. package/dist/agents/hook-into-agent/hook-into-agent.d.ts +29 -0
  14. package/dist/agents/hooks/hooks.types.d.ts +64 -0
  15. package/dist/agents/hooks/hooks.utils.d.ts +9 -0
  16. package/dist/agents/hooks/index.d.ts +2 -0
  17. package/dist/agents/loader/index.d.ts +4 -0
  18. package/dist/agents/loader/loader.d.ts +49 -0
  19. package/dist/agents/loader/loader.schema.d.ts +270 -0
  20. package/dist/agents/loader/loader.types.d.ts +15 -0
  21. package/dist/conversation-context/conversation-context.d.ts +78 -0
  22. package/dist/conversation-context/conversation-context.types.d.ts +111 -0
  23. package/dist/conversation-context/conversation-context.utils.d.ts +6 -0
  24. package/dist/conversation-context/index.d.ts +3 -0
  25. package/dist/conversation-context/retention/compaction/compaction.constants.d.ts +3 -0
  26. package/dist/conversation-context/retention/compaction/compaction.d.ts +21 -0
  27. package/dist/conversation-context/retention/compaction/compaction.types.d.ts +26 -0
  28. package/dist/conversation-context/retention/compaction/index.d.ts +2 -0
  29. package/dist/conversation-context/retention/index.d.ts +4 -0
  30. package/dist/conversation-context/retention/retention.d.ts +9 -0
  31. package/dist/conversation-context/retention/retention.types.d.ts +90 -0
  32. package/dist/conversation-context/retention/retention.utils.d.ts +3 -0
  33. package/dist/conversation-context/retention/rolling-window/index.d.ts +2 -0
  34. package/dist/conversation-context/retention/rolling-window/rolling-window.d.ts +13 -0
  35. package/dist/conversation-context/retention/rolling-window/rolling-window.types.d.ts +5 -0
  36. package/dist/credentials/backends/json-file.d.ts +21 -0
  37. package/dist/credentials/credentials.constants.d.ts +9 -0
  38. package/dist/credentials/credentials.d.ts +18 -0
  39. package/dist/credentials/credentials.schema.d.ts +102 -0
  40. package/dist/credentials/credentials.types.d.ts +118 -0
  41. package/dist/credentials/credentials.utils.d.ts +30 -0
  42. package/dist/credentials/index.d.ts +6 -0
  43. package/dist/defaults/defaults.d.ts +108 -0
  44. package/dist/defaults/defaults.types.d.ts +51 -0
  45. package/dist/defaults/index.d.ts +2 -0
  46. package/dist/errors/index.d.ts +70 -0
  47. package/dist/flows/built-in/broadcast/broadcast-flow.constants.d.ts +2 -0
  48. package/dist/flows/built-in/broadcast/broadcast-flow.d.ts +30 -0
  49. package/dist/flows/built-in/cycle/cycle-flow.d.ts +53 -0
  50. package/dist/flows/built-in/sequential/sequential-flow.d.ts +25 -0
  51. package/dist/flows/flow/flow.d.ts +79 -0
  52. package/dist/flows/flow/flow.types.d.ts +179 -0
  53. package/dist/flows/flow/flow.utils.d.ts +18 -0
  54. package/dist/flows/hook-into-flow/hook-into-flow.d.ts +30 -0
  55. package/dist/flows/index.d.ts +6 -0
  56. package/dist/flows/loader/index.d.ts +4 -0
  57. package/dist/flows/loader/loader.d.ts +55 -0
  58. package/dist/flows/loader/loader.schema.d.ts +195 -0
  59. package/dist/flows/loader/loader.types.d.ts +27 -0
  60. package/dist/guard/guard.d.ts +17 -0
  61. package/dist/guard/guard.types.d.ts +112 -0
  62. package/dist/guard/index.d.ts +3 -0
  63. package/dist/guard/policies.d.ts +28 -0
  64. package/dist/hooks/built-in/token-tracking/index.d.ts +2 -0
  65. package/dist/hooks/built-in/token-tracking/token-tracking.constants.d.ts +14 -0
  66. package/dist/hooks/built-in/token-tracking/token-tracking.d.ts +87 -0
  67. package/dist/hooks/built-in/token-tracking/token-tracking.types.d.ts +136 -0
  68. package/dist/hooks/hooks.d.ts +10 -0
  69. package/dist/hooks/hooks.types.d.ts +11 -0
  70. package/dist/hooks/index.d.ts +2 -0
  71. package/dist/index.d.ts +50 -0
  72. package/dist/index.js +8961 -0
  73. package/dist/language/index.d.ts +1 -0
  74. package/dist/language/language.types.d.ts +60 -0
  75. package/dist/model/index.d.ts +5 -0
  76. package/dist/model/model.d.ts +63 -0
  77. package/dist/model/model.types.d.ts +85 -0
  78. package/dist/model/model.utils.d.ts +151 -0
  79. package/dist/model/providers/catalog/catalog.d.ts +57 -0
  80. package/dist/model/providers/catalog/catalog.types.d.ts +50 -0
  81. package/dist/model/providers/catalog/catalog.utils.d.ts +15 -0
  82. package/dist/model/providers/catalog/index.d.ts +3 -0
  83. package/dist/model/providers/index.d.ts +7 -0
  84. package/dist/model/providers/listers/copilot.d.ts +10 -0
  85. package/dist/model/providers/listers/index.d.ts +2 -0
  86. package/dist/model/providers/listers/ollama.d.ts +9 -0
  87. package/dist/model/providers/providers.d.ts +69 -0
  88. package/dist/model/providers/providers.types.d.ts +157 -0
  89. package/dist/model/providers/providers.utils.d.ts +16 -0
  90. package/dist/prompts/index.d.ts +4 -0
  91. package/dist/prompts/message-builder.d.ts +89 -0
  92. package/dist/prompts/prompts.types.d.ts +86 -0
  93. package/dist/prompts/template/prompt-template.d.ts +22 -0
  94. package/dist/sandbox/in-sandbox.d.ts +31 -0
  95. package/dist/sandbox/index.d.ts +4 -0
  96. package/dist/sandbox/sandbox.constants.d.ts +31 -0
  97. package/dist/sandbox/sandbox.d.ts +11 -0
  98. package/dist/sandbox/sandbox.types.d.ts +105 -0
  99. package/dist/skills/index.d.ts +4 -0
  100. package/dist/skills/skills.constants.d.ts +10 -0
  101. package/dist/skills/skills.loader.d.ts +46 -0
  102. package/dist/skills/skills.registry.d.ts +18 -0
  103. package/dist/skills/skills.types.d.ts +66 -0
  104. package/dist/skills/skills.utils.d.ts +37 -0
  105. package/dist/strategy/discover/discover.d.ts +16 -0
  106. package/dist/strategy/discover/discover.types.d.ts +70 -0
  107. package/dist/strategy/discover/discover.utils.d.ts +95 -0
  108. package/dist/strategy/discover/index.d.ts +3 -0
  109. package/dist/strategy/exporter/exporter.d.ts +27 -0
  110. package/dist/strategy/exporter/exporter.types.d.ts +6 -0
  111. package/dist/strategy/index.d.ts +10 -0
  112. package/dist/strategy/loader/loader.d.ts +39 -0
  113. package/dist/strategy/loader/loader.types.d.ts +106 -0
  114. package/dist/strategy/loader/loader.utils.d.ts +20 -0
  115. package/dist/strategy/loader/project-loader.d.ts +9 -0
  116. package/dist/strategy/schema.d.ts +1032 -0
  117. package/dist/timeline/index.d.ts +4 -0
  118. package/dist/timeline/projections/conversation-context.d.ts +19 -0
  119. package/dist/timeline/projections/file-state.d.ts +8 -0
  120. package/dist/timeline/projections/index.d.ts +3 -0
  121. package/dist/timeline/timeline.d.ts +11 -0
  122. package/dist/timeline/timeline.types.d.ts +97 -0
  123. package/dist/tools/build-tool-system-prompt.d.ts +41 -0
  124. package/dist/tools/built-in/ask-question/ask-question.d.ts +21 -0
  125. package/dist/tools/built-in/ask-question/index.d.ts +2 -0
  126. package/dist/tools/built-in/create-file/create-file.d.ts +18 -0
  127. package/dist/tools/built-in/create-file/create-file.types.d.ts +11 -0
  128. package/dist/tools/built-in/create-file/index.d.ts +2 -0
  129. package/dist/tools/built-in/delete-file/delete-file.constants.d.ts +14 -0
  130. package/dist/tools/built-in/delete-file/delete-file.d.ts +5 -0
  131. package/dist/tools/built-in/delete-file/delete-file.types.d.ts +26 -0
  132. package/dist/tools/built-in/delete-file/index.d.ts +2 -0
  133. package/dist/tools/built-in/describe-tool.d.ts +61 -0
  134. package/dist/tools/built-in/edit-file/edit-file.d.ts +46 -0
  135. package/dist/tools/built-in/edit-file/edit-file.replacers.d.ts +81 -0
  136. package/dist/tools/built-in/edit-file/edit-file.types.d.ts +59 -0
  137. package/dist/tools/built-in/edit-file/edit-file.utils.d.ts +70 -0
  138. package/dist/tools/built-in/edit-file/index.d.ts +2 -0
  139. package/dist/tools/built-in/glob/glob.constants.d.ts +3 -0
  140. package/dist/tools/built-in/glob/glob.d.ts +25 -0
  141. package/dist/tools/built-in/glob/glob.types.d.ts +31 -0
  142. package/dist/tools/built-in/glob/glob.utils.d.ts +4 -0
  143. package/dist/tools/built-in/glob/index.d.ts +2 -0
  144. package/dist/tools/built-in/launch-strategy/index.d.ts +2 -0
  145. package/dist/tools/built-in/launch-strategy/launch-strategy.d.ts +26 -0
  146. package/dist/tools/built-in/launch-strategy/launch-strategy.types.d.ts +14 -0
  147. package/dist/tools/built-in/list-directory/index.d.ts +2 -0
  148. package/dist/tools/built-in/list-directory/list-directory.constants.d.ts +3 -0
  149. package/dist/tools/built-in/list-directory/list-directory.d.ts +20 -0
  150. package/dist/tools/built-in/list-directory/list-directory.types.d.ts +41 -0
  151. package/dist/tools/built-in/list-directory/list-directory.utils.d.ts +4 -0
  152. package/dist/tools/built-in/list-skills/index.d.ts +2 -0
  153. package/dist/tools/built-in/list-skills/list-skills.d.ts +5 -0
  154. package/dist/tools/built-in/list-skills/list-skills.types.d.ts +10 -0
  155. package/dist/tools/built-in/list-strategy/index.d.ts +2 -0
  156. package/dist/tools/built-in/list-strategy/list-strategy.d.ts +14 -0
  157. package/dist/tools/built-in/list-strategy/list-strategy.types.d.ts +33 -0
  158. package/dist/tools/built-in/load-skill/index.d.ts +2 -0
  159. package/dist/tools/built-in/load-skill/load-skill.d.ts +24 -0
  160. package/dist/tools/built-in/load-skill/load-skill.types.d.ts +15 -0
  161. package/dist/tools/built-in/lsp-request/index.d.ts +2 -0
  162. package/dist/tools/built-in/lsp-request/lsp-request.d.ts +4 -0
  163. package/dist/tools/built-in/lsp-request/lsp-request.schema.d.ts +23 -0
  164. package/dist/tools/built-in/lsp-request/lsp-request.types.d.ts +4 -0
  165. package/dist/tools/built-in/move-file/index.d.ts +2 -0
  166. package/dist/tools/built-in/move-file/move-file.d.ts +21 -0
  167. package/dist/tools/built-in/move-file/move-file.types.d.ts +12 -0
  168. package/dist/tools/built-in/read-file/index.d.ts +2 -0
  169. package/dist/tools/built-in/read-file/read-file.constants.d.ts +1 -0
  170. package/dist/tools/built-in/read-file/read-file.d.ts +32 -0
  171. package/dist/tools/built-in/read-file/read-file.types.d.ts +34 -0
  172. package/dist/tools/built-in/read-file/read-file.utils.d.ts +14 -0
  173. package/dist/tools/built-in/restore-file/index.d.ts +2 -0
  174. package/dist/tools/built-in/restore-file/restore-file.d.ts +16 -0
  175. package/dist/tools/built-in/restore-file/restore-file.types.d.ts +11 -0
  176. package/dist/tools/built-in/run-command/index.d.ts +2 -0
  177. package/dist/tools/built-in/run-command/run-command.constants.d.ts +23 -0
  178. package/dist/tools/built-in/run-command/run-command.d.ts +21 -0
  179. package/dist/tools/built-in/run-command/run-command.types.d.ts +81 -0
  180. package/dist/tools/built-in/run-command/run-command.utils.d.ts +37 -0
  181. package/dist/tools/built-in/search-files/index.d.ts +2 -0
  182. package/dist/tools/built-in/search-files/search-files.constants.d.ts +5 -0
  183. package/dist/tools/built-in/search-files/search-files.d.ts +30 -0
  184. package/dist/tools/built-in/search-files/search-files.types.d.ts +19 -0
  185. package/dist/tools/built-in/search-files/search-files.utils.d.ts +11 -0
  186. package/dist/tools/built-in/todo/todo.d.ts +62 -0
  187. package/dist/tools/built-in/todo/todo.types.d.ts +7 -0
  188. package/dist/tools/built-in/webfetch/webfetch.constants.d.ts +3 -0
  189. package/dist/tools/built-in/webfetch/webfetch.d.ts +33 -0
  190. package/dist/tools/built-in/webfetch/webfetch.types.d.ts +8 -0
  191. package/dist/tools/built-in/webfetch/webfetch.utils.d.ts +19 -0
  192. package/dist/tools/built-in/write-file/index.d.ts +2 -0
  193. package/dist/tools/built-in/write-file/write-file.d.ts +18 -0
  194. package/dist/tools/built-in/write-file/write-file.types.d.ts +11 -0
  195. package/dist/tools/define/define-tool.d.ts +15 -0
  196. package/dist/tools/io/atomic-write.d.ts +37 -0
  197. package/dist/tools/io/audit-sink.d.ts +29 -0
  198. package/dist/tools/io/audit.types.d.ts +115 -0
  199. package/dist/tools/io/audit.utils.d.ts +48 -0
  200. package/dist/tools/io/binary.d.ts +16 -0
  201. package/dist/tools/io/bom.d.ts +15 -0
  202. package/dist/tools/io/diff.d.ts +27 -0
  203. package/dist/tools/io/hash.d.ts +25 -0
  204. package/dist/tools/io/index.d.ts +19 -0
  205. package/dist/tools/io/newline.d.ts +34 -0
  206. package/dist/tools/io/sandbox-error.d.ts +13 -0
  207. package/dist/tools/io/session-file-state.d.ts +68 -0
  208. package/dist/tools/io/stale-file.d.ts +9 -0
  209. package/dist/tools/io/trash.d.ts +57 -0
  210. package/dist/tools/launch-strategy.types.d.ts +38 -0
  211. package/dist/tools/result/index.d.ts +1 -0
  212. package/dist/tools/result/result.d.ts +47 -0
  213. package/dist/tools/tool.constants.d.ts +7 -0
  214. package/dist/tools/tool.registry.d.ts +54 -0
  215. package/dist/tools/tool.types.d.ts +191 -0
  216. package/package.json +48 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CloAI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # @comma-agents/core
2
+
3
+ Agent orchestration APIs for CommaAgents.
4
+
5
+ ```bash
6
+ bun add @comma-agents/core@next
7
+ ```
8
+
9
+ ```ts
10
+ import { createAgent } from "@comma-agents/core";
11
+
12
+ const agent = createAgent({
13
+ name: "assistant",
14
+ model: "openai/gpt-4o",
15
+ });
16
+ ```
17
+
18
+ Requires Bun 1.3 or newer.
@@ -0,0 +1,5 @@
1
+ import type { AbortableAsyncGenerator, AbortablePromise } from "./abortable.types";
2
+ /** Create a cancellable promise backed by an `AbortController`. */
3
+ export declare function createAbortablePromise<ResultType>(executor: (signal: AbortSignal) => Promise<ResultType>): AbortablePromise<ResultType>;
4
+ /** Create a cancellable async generator backed by an `AbortController`. */
5
+ export declare function createAbortableGenerator<YieldType>(generatorFactory: (signal: AbortSignal) => AsyncGenerator<YieldType, void, undefined>): AbortableAsyncGenerator<YieldType>;
@@ -0,0 +1,10 @@
1
+ /** A promise that can be cancelled by calling `.abort()`. */
2
+ export interface AbortablePromise<ResultType> extends Promise<ResultType> {
3
+ /** Cancel the in-flight operation. */
4
+ abort(): void;
5
+ }
6
+ /** An async generator that can be cancelled by calling `.abort()`. */
7
+ export interface AbortableAsyncGenerator<YieldType> extends AsyncGenerator<YieldType, void, undefined> {
8
+ /** Cancel the in-flight stream. */
9
+ abort(): void;
10
+ }
@@ -0,0 +1,2 @@
1
+ export { createAbortableGenerator, createAbortablePromise, } from "./abortable";
2
+ export type { AbortableAsyncGenerator, AbortablePromise, } from "./abortable.types";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Default maximum number of LLM round-trips (steps) per call.
3
+ * Each tool-call + response counts as one step.
4
+ */
5
+ export declare const DEFAULT_MAX_STEPS = 100;
@@ -0,0 +1,24 @@
1
+ import type { Agent, AgentConfig } from "./agent.types";
2
+ /**
3
+ * Create an LLM-backed agent using closure-based state management.
4
+ *
5
+ * Returns an `Agent` with all optional LLM fields populated (stream,
6
+ * getConversationContext, config).
7
+ *
8
+ * State (conversation history, first-call flag) is captured in closure.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { createAgent } from "@comma-agents/core";
13
+ *
14
+ * const agent = createAgent({
15
+ * name: "writer",
16
+ * model: "openai/gpt-4o",
17
+ * systemPrompt: "You are a helpful code writer.",
18
+ * });
19
+ *
20
+ * const result = await agent.call("Write a hello world in TypeScript");
21
+ * console.log(result.text);
22
+ * ```
23
+ */
24
+ export declare function createAgent(config: AgentConfig): Agent;
@@ -0,0 +1,408 @@
1
+ import type { AbortableAsyncGenerator, AbortablePromise } from "../../abortable";
2
+ import type { tool as aiTool, CallSettings, FlexibleSchema, LanguageModel, ModelMessage, StepResult, stepCountIs, streamText, ToolChoice } from "ai";
3
+ import type { ContextUsage, ConversationContext, ConversationContextOptions, ConversationRetentionEvent, ResponseMessage } from "../../conversation-context";
4
+ import type { LanguageService } from "../../language";
5
+ import type { PromptTemplate, TemplateVariables } from "../../prompts";
6
+ import type { Sandbox } from "../../sandbox/sandbox.types";
7
+ import type { SkillRegistry } from "../../skills/skills.types";
8
+ import type { LaunchStrategyHandle } from "../../tools/launch-strategy.types";
9
+ import type { InputCollector } from "../built-in/user/user-agent.types";
10
+ /**
11
+ * Model-level generation parameters forwarded to `streamText`.
12
+ *
13
+ * Derived from the AI SDK's `CallSettings` to stay in sync with
14
+ * upstream changes. Provider-specific features (extended thinking,
15
+ * reasoning effort) should use {@link AgentConfig.providerOptions} instead.
16
+ *
17
+ * Excludes runtime-only fields (`abortSignal`, `timeout`, `headers`,
18
+ * `stopSequences`) that are managed by the agent lifecycle, not user config.
19
+ */
20
+ export type ModelOptions = Pick<CallSettings, "temperature" | "topP" | "topK" | "maxOutputTokens" | "maxRetries" | "frequencyPenalty" | "presencePenalty" | "seed">;
21
+ /** Schema used to constrain and validate an agent's structured output. */
22
+ export type AgentOutputSchema = FlexibleSchema<unknown>;
23
+ /** Configuration for creating an LLM-backed agent via `createAgent()`. */
24
+ export interface AgentConfig {
25
+ /** Unique name for this agent. */
26
+ readonly name: string;
27
+ /**
28
+ * Model identifier in "providerID/modelID" format (e.g., `"openai/gpt-4o"`).
29
+ * Resolved internally by `createAgent()` via the model registry and provider system.
30
+ * Optional if a custom `execute` override is provided.
31
+ */
32
+ readonly model?: string;
33
+ /**
34
+ * System prompt sent to the model at the start of every call.
35
+ * Accepts a static string or a `PromptTemplate` for dynamic interpolation.
36
+ * When a `PromptTemplate` is provided, its baked-in variables are used.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * // Static string
41
+ * const agent = createAgent({
42
+ * name: "writer",
43
+ * model: "openai/gpt-4o",
44
+ * systemPrompt: "You are a helpful code writer.",
45
+ * });
46
+ *
47
+ * // Dynamic template
48
+ * import { createPromptTemplate } from "@comma-agents/core";
49
+ *
50
+ * const agent = createAgent({
51
+ * name: "reviewer",
52
+ * model: "openai/gpt-4o",
53
+ * systemPrompt: createPromptTemplate({
54
+ * template: "You are {{ role }}, reviewing {{ language }} code.",
55
+ * variables: { role: "a senior engineer", language: "TypeScript" },
56
+ * }),
57
+ * });
58
+ * ```
59
+ */
60
+ readonly systemPrompt?: string | PromptTemplate;
61
+ /**
62
+ * Tool names the agent can invoke during a call.
63
+ * Resolved internally by `createAgent()` via the tool registry.
64
+ */
65
+ readonly tools?: readonly string[];
66
+ /**
67
+ * Sandbox governing file-system access for all tools invoked by this agent.
68
+ * When omitted, a permissive sandbox (no restrictions, cwd = process.cwd())
69
+ * is used so that existing strategies remain unaffected.
70
+ */
71
+ readonly sandbox?: Sandbox;
72
+ /**
73
+ * Skill registry exposed to the `load_skill` tool when included in `tools`.
74
+ * When omitted, `load_skill` returns `skill_unavailable` for every call.
75
+ * Typically populated by the strategy loader from
76
+ * `<configRoot>/comma-agents/skills/` plus `./.comma/skills/`.
77
+ */
78
+ readonly skillRegistry?: SkillRegistry;
79
+ /**
80
+ * Per-invocation run identifier propagated to {@link ToolContext.runId}.
81
+ *
82
+ * Distinct from {@link AgentConfig.sessionId} — `runId` identifies one
83
+ * strategy invocation (top-level run *or* one `launch_strategy`
84
+ * sub-invocation), while `sessionId` identifies a broader user/daemon
85
+ * session that may span many runs. The two are deliberately separate:
86
+ * audit logs are session-scoped, but per-run isolation (notably the
87
+ * `todo_*` tools' shared run-level silo, which must not leak into
88
+ * recursive `launch_strategy` calls) keys on `runId`.
89
+ *
90
+ * The strategy loader sets this from {@link LoadStrategyOptions.runId};
91
+ * the daemon executor passes the top-level run id at the entry point
92
+ * and a fresh derived id for each sub-launch so recursive strategy
93
+ * invocations get isolated state.
94
+ *
95
+ * When omitted, runId-aware tools fall back to `agentName`-only keying
96
+ * (their original behaviour) — safe for tests and embedded callers
97
+ * that don't care about cross-launch isolation.
98
+ */
99
+ readonly runId?: string;
100
+ /**
101
+ * Input collector threaded into the {@link ToolContext} of every tool
102
+ * call. Used by tools (e.g., `launch_strategy`) that need to forward
103
+ * the parent strategy's input bridge into a spawned sub-strategy.
104
+ */
105
+ readonly inputCollector?: InputCollector;
106
+ /**
107
+ * Optional handle for spawning sub-strategies, threaded into every
108
+ * tool's {@link ToolContext}. Supplied by the strategy loader (which
109
+ * receives it via {@link LoadStrategyOptions}).
110
+ */
111
+ readonly launchStrategy?: LaunchStrategyHandle;
112
+ /**
113
+ * Runtime language service exposed to language-aware tools.
114
+ * Usually supplied by the daemon for a workspace.
115
+ */
116
+ readonly languageService?: LanguageService;
117
+ /**
118
+ * Per-call provider options forwarded to the model provider. Used to enable
119
+ * provider-specific behaviour such as reasoning / extended thinking.
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * createAgent({
124
+ * name: "planner",
125
+ * model: "anthropic/claude-sonnet-4-5",
126
+ * providerOptions: {
127
+ * anthropic: { thinking: { type: "enabled", budgetTokens: 8000 } },
128
+ * },
129
+ * });
130
+ * ```
131
+ */
132
+ readonly providerOptions?: Record<string, Record<string, unknown>>;
133
+ /**
134
+ * Model-level generation parameters forwarded to `streamText`.
135
+ *
136
+ * Provider-agnostic options like `temperature`, `maxOutputTokens`, `topP`, and
137
+ * `seed`. Provider-specific features should use `providerOptions` instead.
138
+ *
139
+ * @example
140
+ * ```ts
141
+ * createAgent({
142
+ * name: "creative-writer",
143
+ * model: "openai/gpt-4o",
144
+ * modelOptions: { temperature: 0.9, maxOutputTokens: 4096 },
145
+ * });
146
+ * ```
147
+ */
148
+ readonly modelOptions?: ModelOptions;
149
+ /**
150
+ * Schema for structured agent output.
151
+ *
152
+ * Forwarded to `streamText` as `output: Output.object({ schema })`.
153
+ * Programmatic callers may pass a Zod schema or another AI SDK
154
+ * `FlexibleSchema`. YAML/JSON agent and strategy definitions accept a JSON
155
+ * Schema object.
156
+ */
157
+ readonly outputSchema?: AgentOutputSchema;
158
+ /**
159
+ * Maximum number of LLM round-trips (steps) per call.
160
+ * Each tool-call + response counts as one step.
161
+ * @default 10
162
+ */
163
+ readonly maxSteps?: number;
164
+ /**
165
+ * Custom execute override — replaces the LLM call with arbitrary logic.
166
+ *
167
+ * When set, `model` is not required. Return a plain `string` (a synthetic
168
+ * result with an `{ role: "assistant" }` message will be created
169
+ * automatically) or a full `AgentCallResult` for complete control.
170
+ *
171
+ * @example
172
+ * ```ts
173
+ * const echo = createAgent({
174
+ * name: "echo",
175
+ * execute: async (message) => `Echo: ${message}`,
176
+ * });
177
+ * ```
178
+ */
179
+ readonly execute?: (message: string) => Promise<string | AgentCallResult>;
180
+ /**
181
+ * Conversation context retention and compaction options. Transformations are
182
+ * non-destructive: superseded records are kept for export but excluded from
183
+ * the LLM-visible projection.
184
+ *
185
+ * YAML/JSON definitions can use serializable `rollingWindow` and
186
+ * `compaction` values. Programmatic callers may also pass `transformRecords`
187
+ * for custom behavior.
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * createAgent({
192
+ * name: "writer",
193
+ * model: "anthropic/claude-opus-4-8",
194
+ * context: { rollingWindow: 40, compaction: { keepRecent: 8 } },
195
+ * });
196
+ * ```
197
+ */
198
+ readonly context?: ConversationContextOptions;
199
+ }
200
+ /**
201
+ * The unified agent contract. Every agent — LLM-backed, human-in-the-loop,
202
+ * flow, or custom — implements this interface.
203
+ *
204
+ * **Required fields** (`name`, `call`, `reset`) are the polymorphic minimum
205
+ * that flows and orchestration depend on.
206
+ *
207
+ * **Optional fields** (`stream`, `getConversationContext`, `config`) are
208
+ * provided by LLM-backed agents created via `createAgent()`. Consumer code
209
+ * that needs LLM-specific features can check for their existence or work
210
+ * with a known `createAgent()` result.
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * // Flows accept any Agent — only name, call, reset are required
215
+ * const flow = createSequentialFlow({
216
+ * name: "pipeline",
217
+ * agents: [llmAgent, userAgent, customAgent],
218
+ * });
219
+ *
220
+ * // LLM-specific features are optional
221
+ * const agent = createAgent({ name: "writer", model: "openai/gpt-4o" });
222
+ * const context = agent.getConversationContext(); // always present on createAgent results
223
+ * const messages = context.messages(); // flat ModelMessage[]
224
+ * const records = context.records(); // structured records
225
+ * for await (const event of agent.stream("Hi")) { ... }
226
+ * ```
227
+ */
228
+ export interface Agent {
229
+ /** Unique name for this agent. */
230
+ readonly name: string;
231
+ /** The agent's configuration. */
232
+ readonly config?: AgentConfig;
233
+ /**
234
+ * Call the agent with a message.
235
+ * Runs the full hook lifecycle around the core action.
236
+ * Returns an AbortablePromise — call `.abort()` to cancel the in-flight operation.
237
+ */
238
+ call(message: string): AbortablePromise<AgentCallResult>;
239
+ /**
240
+ * Stream a call, yielding events as they arrive.
241
+ * Returns an AbortableAsyncGenerator — call `.abort()` to cancel the stream.
242
+ */
243
+ stream?(message: string): AbortableAsyncGenerator<AgentStreamEvent>;
244
+ /**
245
+ * The agent's internal conversation context.
246
+ * Provides canonical conversation records, message projection, and import/export helpers.
247
+ */
248
+ getConversationContext?(): ConversationContext;
249
+ /** Reset internal state (history, first-call flag, etc.). */
250
+ reset(): void;
251
+ /**
252
+ * Update variables used by this agent's prompt template.
253
+ *
254
+ * When the agent was configured with a `PromptTemplate` (via
255
+ * `systemPrompt`), calling this merges new variables into the template's
256
+ * defaults — matching keys are overwritten, the rest are kept.
257
+ * If the agent uses a static string prompt, this is a no-op.
258
+ *
259
+ * @example
260
+ * ```ts
261
+ * const agent = createAgent({
262
+ * name: "reviewer",
263
+ * model: "openai/gpt-4o",
264
+ * systemPrompt: createPromptTemplate({
265
+ * template: "You are {{ role }}, reviewing {{ language }} code.",
266
+ * variables: { role: "a reviewer" },
267
+ * }),
268
+ * });
269
+ *
270
+ * agent.updatePromptVariables({ language: "TypeScript" });
271
+ * // Next call renders: "You are a reviewer, reviewing TypeScript code."
272
+ * ```
273
+ */
274
+ updatePromptVariables?(variables: TemplateVariables): void;
275
+ /**
276
+ * Append a hook callback to this agent's lifecycle.
277
+ * Used internally by `hookIntoAgent` — not part of the public API.
278
+ * @internal
279
+ */
280
+ appendHook?(hookName: string, callback: unknown): void;
281
+ }
282
+ /**
283
+ * Result from any agent call.
284
+ *
285
+ * Contains the response text, token usage, finish reason, and the full
286
+ * response message chain and step details. Non-LLM agents (mocks, flows,
287
+ * custom execute overrides) provide empty arrays for `responseMessages`
288
+ * and `steps`.
289
+ *
290
+ * @example
291
+ * ```ts
292
+ * const result = await agent.call("Hello");
293
+ * console.log(result.text); // final text
294
+ * console.log(result.responseMessages); // full message chain
295
+ * console.log(result.steps); // tool calls, reasoning, etc.
296
+ * ```
297
+ */
298
+ export interface AgentCallResult {
299
+ /** The final text response from the agent. */
300
+ readonly text: string;
301
+ /** Total token usage across all steps. Zero for non-LLM agents. */
302
+ readonly usage: {
303
+ readonly promptTokens: number;
304
+ readonly completionTokens: number;
305
+ };
306
+ /** Final model-step context usage. */
307
+ readonly contextUsage?: ContextUsage;
308
+ /** Why the agent stopped (e.g., "stop", "tool-calls", "length"). */
309
+ readonly finishReason: string;
310
+ /**
311
+ * The full assistant + tool message chain, preserving tool calls,
312
+ * tool results, reasoning, and multi-modal content.
313
+ * Empty array for non-LLM agents.
314
+ */
315
+ readonly responseMessages: readonly ResponseMessage[];
316
+ /** All steps taken during this call (LLM calls + tool executions). Empty array for non-LLM agents. */
317
+ readonly steps: ReadonlyArray<StepResult<any>>;
318
+ }
319
+ /**
320
+ * Event emitted during a streaming agent call.
321
+ *
322
+ * Reasoning ("thinking") events come in three parts mirroring the AI SDK
323
+ * v6 stream: `thinking-start` opens a reasoning block, zero or more
324
+ * `thinking` deltas append text to it, and `thinking-end` closes it. The
325
+ * `id` is supplied by the model and lets multiple interleaved reasoning
326
+ * blocks within a single step be reassembled correctly downstream.
327
+ */
328
+ /**
329
+ * Lifecycle status of a tool invocation. `running` is implicit (no
330
+ * `tool-result` has been emitted yet for the matching `toolCallId`);
331
+ * `completed` and `error` arrive on the `tool-result` event.
332
+ */
333
+ export type ToolCallStatus = "completed" | "error";
334
+ export type AgentStreamEvent = {
335
+ readonly type: "retention";
336
+ readonly event: ConversationRetentionEvent;
337
+ } | {
338
+ readonly type: "text";
339
+ readonly text: string;
340
+ } | {
341
+ readonly type: "tool-call";
342
+ /**
343
+ * Correlation id assigned by the model. Pairs this call with its eventual
344
+ * `tool-result` event so consumers can render a single row per call
345
+ * even when calls run concurrently or interleave with text/thinking.
346
+ */
347
+ readonly toolCallId: string;
348
+ readonly toolName: string;
349
+ readonly args: string;
350
+ } | {
351
+ readonly type: "tool-result";
352
+ /** Correlates with the `tool-call` event that started this invocation. */
353
+ readonly toolCallId: string;
354
+ readonly toolName: string;
355
+ /**
356
+ * Raw tool output. For `status: "error"` results this is an empty
357
+ * string by default — the human-readable failure message lives on
358
+ * `error`.
359
+ */
360
+ readonly output: string;
361
+ /** Outcome of the tool invocation. */
362
+ readonly status: ToolCallStatus;
363
+ /** Failure message when `status === "error"`. */
364
+ readonly error?: string;
365
+ } | {
366
+ readonly type: "thinking-start";
367
+ readonly id: string;
368
+ } | {
369
+ readonly type: "thinking";
370
+ readonly id: string;
371
+ readonly text: string;
372
+ } | {
373
+ readonly type: "thinking-end";
374
+ readonly id: string;
375
+ } | {
376
+ readonly type: "step-start";
377
+ } | {
378
+ readonly type: "done";
379
+ readonly result: AgentCallResult;
380
+ };
381
+ /** Common options passed to generateText / streamText. */
382
+ export interface CallOptions {
383
+ readonly model: LanguageModel;
384
+ readonly system?: string | ModelMessage | ModelMessage[];
385
+ readonly messages: ModelMessage[];
386
+ readonly tools?: Record<string, ReturnType<typeof aiTool<any, any>>> | undefined;
387
+ readonly toolChoice?: ToolChoice<Record<string, unknown>> | undefined;
388
+ readonly abortSignal?: AbortSignal | undefined;
389
+ readonly timeout?: number | undefined;
390
+ readonly stopWhen?: ReturnType<typeof stepCountIs>;
391
+ /**
392
+ * Per-call provider options forwarded verbatim to `streamText`.
393
+ */
394
+ readonly providerOptions?: unknown;
395
+ /** Structured output specification forwarded to `streamText`. */
396
+ readonly output?: Parameters<typeof streamText>[0]["output"];
397
+ /**
398
+ * Model-level generation parameters forwarded to `streamText`.
399
+ */
400
+ readonly modelOptions?: ModelOptions;
401
+ }
402
+ /** Prepared model-call options plus retention events emitted before the call. */
403
+ export interface BuildCallOptionsResult {
404
+ /** AI SDK call options passed to `streamText`. */
405
+ readonly callOptions: CallOptions;
406
+ /** Retention events emitted while preparing conversation context. */
407
+ readonly retentionEvents: readonly ConversationRetentionEvent[];
408
+ }
@@ -0,0 +1,107 @@
1
+ import { tool as aiTool } from "ai";
2
+ import type { ConversationContext, ResponseMessage, SummarizeRecords } from "../../conversation-context";
3
+ import type { SideEffectHook, TransformHook } from "../../hooks/hooks.types";
4
+ import type { LanguageService } from "../../language";
5
+ import type { Sandbox } from "../../sandbox/sandbox.types";
6
+ import type { SkillRegistry } from "../../skills/skills.types";
7
+ import type { AuditSink } from "../../tools/io/audit.types";
8
+ import type { LaunchStrategyHandle } from "../../tools/launch-strategy.types";
9
+ import type { ToolContext, ToolDefinition } from "../../tools/tool.types";
10
+ import type { InputCollector } from "../built-in/user/user-agent.types";
11
+ import type { ToolHooks } from "../hooks";
12
+ import type { AgentCallResult, AgentConfig, AgentStreamEvent, BuildCallOptionsResult } from "./agent.types";
13
+ export type AgentHookStore = {
14
+ alterFirstCallMessage: Array<TransformHook<string>> | undefined;
15
+ beforeFirstCall: Array<SideEffectHook<string>> | undefined;
16
+ afterFirstCallResult: Array<SideEffectHook<AgentCallResult>> | undefined;
17
+ alterFirstResponse: Array<TransformHook<string>> | undefined;
18
+ alterCallMessage: Array<TransformHook<string>> | undefined;
19
+ beforeCall: Array<SideEffectHook<string>> | undefined;
20
+ alterResponse: Array<TransformHook<string>> | undefined;
21
+ afterCallResult: Array<SideEffectHook<AgentCallResult>> | undefined;
22
+ onStreamEvent: Array<SideEffectHook<AgentStreamEvent>> | undefined;
23
+ beforeToolCall: Array<SideEffectHook<{
24
+ readonly name: string;
25
+ readonly args: string;
26
+ readonly toolContext: ToolContext;
27
+ }>> | undefined;
28
+ afterToolCall: Array<SideEffectHook<{
29
+ readonly name: string;
30
+ readonly args: string;
31
+ readonly result: string;
32
+ readonly toolContext: ToolContext;
33
+ }>> | undefined;
34
+ };
35
+ /** Build a ToolHooks view from the mutable store for passing to buildCallOptions. */
36
+ export declare function getToolHooks(hooks: AgentHookStore): ToolHooks;
37
+ /**
38
+ * Run the pre-call hook lifecycle and return the altered message.
39
+ */
40
+ export declare function runPreCallHooks(hooks: AgentHookStore, message: string, isFirst: boolean): Promise<string>;
41
+ /**
42
+ * Run the post-call hook lifecycle and return the result with altered text.
43
+ */
44
+ export declare function runPostCallHooks(hooks: AgentHookStore, result: AgentCallResult, isFirst: boolean): Promise<AgentCallResult>;
45
+ /**
46
+ * Converts a ToolDef map into the AI SDK's tool format.
47
+ * Wraps each tool's execute with ToolHooks and a centralized
48
+ * SandboxViolationError → ToolError catch.
49
+ *
50
+ * Each tool gets its own per-tool Guard from `sandbox.guardFor(toolName)`.
51
+ * Tools call `ctx.guard.authorize()` for path resolution, jail enforcement,
52
+ * and policy evaluation.
53
+ *
54
+ * @param toolDefinitions - The tool definitions to wrap.
55
+ * @param agentName - Surfaced on `ToolContext.agentName` and audit entries.
56
+ * @param toolHooks - Optional side-effect hooks invoked around each call.
57
+ * @param sandbox - Guard registry; falls back to a permissive sandbox.
58
+ * @param sessionId - Propagated to `ToolContext.sessionId`. Identifies a
59
+ * broader user/daemon session; used by audit log / trash metadata.
60
+ * @param auditSink - Explicit audit sink. When omitted but `sessionId` is set,
61
+ * a `createFileAuditSink(sandbox.cwd)` is constructed automatically.
62
+ * @param skillRegistry - Propagated to `ToolContext.skillRegistry`.
63
+ * @param inputCollector - Propagated to `ToolContext.inputCollector`.
64
+ * @param launchStrategy - Propagated to `ToolContext.launchStrategy`.
65
+ * @param languageService - Propagated to `ToolContext.languageService`.
66
+ * @param runId - Propagated to `ToolContext.runId`. Identifies a single
67
+ * strategy invocation (top-level run *or* one `launch_strategy`
68
+ * sub-load). Tools that need per-launch isolation (notably `todo_*`)
69
+ * silo on this. Kept distinct from `sessionId`.
70
+ */
71
+ export declare function buildAgentToolSet(toolDefinitions: Readonly<Record<string, ToolDefinition>> | undefined, agentName: string, toolHooks?: ToolHooks, sandbox?: Sandbox, sessionId?: string, auditSink?: AuditSink, skillRegistry?: SkillRegistry, inputCollector?: InputCollector, launchStrategy?: LaunchStrategyHandle, languageService?: LanguageService, runId?: string): Record<string, ReturnType<typeof aiTool<any, any>>> | undefined;
72
+ /**
73
+ * Build the full AI SDK call options from agent config + current message.
74
+ * Resolves the model string to a LanguageModel, tool names to tool definitions,
75
+ * then builds messages and system prompt into a single options object.
76
+ *
77
+ * @param config - The agent configuration.
78
+ * @param message - The current user message.
79
+ * @param context - The conversation context.
80
+ * @param toolHooks - Tool hooks from the agent's mutable closure store.
81
+ * Dynamically appended hooks (via `hookIntoAgent`) take effect here.
82
+ * @param abortSignal - Optional AbortSignal for cancellation.
83
+ *
84
+ * @throws {Error} if config.model is not set.
85
+ * @throws {ModelResolutionError} if the model string cannot be resolved.
86
+ */
87
+ export declare function buildCallOptions(config: AgentConfig, message: string, context: ConversationContext, toolHooks?: ToolHooks, abortSignal?: AbortSignal): Promise<BuildCallOptionsResult>;
88
+ /**
89
+ * Build the default summarizer used by context compaction. Resolves the model
90
+ * lazily so unused summarizers cost nothing.
91
+ *
92
+ * @param model - Model identifier in "providerID/modelID" format.
93
+ */
94
+ export declare function createModelSummarizer(model: string): SummarizeRecords;
95
+ /**
96
+ * Maps an AI SDK stream part to an AgentStreamEvent.
97
+ * Returns undefined for parts we don't surface (e.g., finish, error).
98
+ */
99
+ export declare function mapStreamPart(streamPart: any): AgentStreamEvent | undefined;
100
+ /**
101
+ * Build an AgentCallResult from consumed stream results.
102
+ * Used by the shared `runStream` generator inside createAgent.
103
+ */
104
+ export declare function buildStreamCallResult(text: string, responseMessages: readonly ResponseMessage[], steps: ReadonlyArray<any>, totalUsage: {
105
+ readonly inputTokens: number | undefined;
106
+ readonly outputTokens: number | undefined;
107
+ }, finishReason: string | null | undefined): AgentCallResult;
@@ -0,0 +1,32 @@
1
+ import type { Agent } from "../../agent/agent.types";
2
+ import type { UserAgentConfig } from "./user-agent.types";
3
+ export type { InputCollector, InputRequest, UserAgentConfig, } from "./user-agent.types";
4
+ /**
5
+ * Create a human-in-the-loop agent.
6
+ *
7
+ * Returns an Agent that collects input from the user (or returns a preset
8
+ * message) instead of calling an LLM. Supports the full hook lifecycle
9
+ * by delegating to `createAgent` with a custom `execute` override.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { createUserAgent } from "@comma-agents/core";
14
+ *
15
+ * // Interactive — prompts user for input
16
+ * const interactive = createUserAgent({
17
+ * name: "user",
18
+ * requireInput: true,
19
+ * });
20
+ *
21
+ * // Preset — always returns the same message
22
+ * const preset = createUserAgent({
23
+ * name: "user",
24
+ * requireInput: false,
25
+ * presetMessage: "Please review the code above.",
26
+ * });
27
+ *
28
+ * // Both satisfy the Agent interface — usable in any flow
29
+ * const result = await interactive.call("");
30
+ * ```
31
+ */
32
+ export declare function createUserAgent(config: UserAgentConfig): Agent;