@better-agent/core 0.1.0-beta.1

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 (179) hide show
  1. package/README.md +3 -0
  2. package/dist/agent/constants.mjs +6 -0
  3. package/dist/agent/constants.mjs.map +1 -0
  4. package/dist/agent/define-agent.d.mts +29 -0
  5. package/dist/agent/define-agent.d.mts.map +1 -0
  6. package/dist/agent/define-agent.mjs +27 -0
  7. package/dist/agent/define-agent.mjs.map +1 -0
  8. package/dist/agent/index.d.mts +2 -0
  9. package/dist/agent/types.d.mts +216 -0
  10. package/dist/agent/types.d.mts.map +1 -0
  11. package/dist/agent/validation.mjs +64 -0
  12. package/dist/agent/validation.mjs.map +1 -0
  13. package/dist/api.d.mts +8 -0
  14. package/dist/api.d.mts.map +1 -0
  15. package/dist/api.mjs +63 -0
  16. package/dist/api.mjs.map +1 -0
  17. package/dist/app/config.mjs +43 -0
  18. package/dist/app/config.mjs.map +1 -0
  19. package/dist/app/create-app.d.mts +36 -0
  20. package/dist/app/create-app.d.mts.map +1 -0
  21. package/dist/app/create-app.mjs +132 -0
  22. package/dist/app/create-app.mjs.map +1 -0
  23. package/dist/app/registry.mjs +43 -0
  24. package/dist/app/registry.mjs.map +1 -0
  25. package/dist/app/types.d.mts +142 -0
  26. package/dist/app/types.d.mts.map +1 -0
  27. package/dist/events/constants.d.mts +49 -0
  28. package/dist/events/constants.d.mts.map +1 -0
  29. package/dist/events/constants.mjs +46 -0
  30. package/dist/events/constants.mjs.map +1 -0
  31. package/dist/events/index.d.mts +4 -0
  32. package/dist/events/index.mjs +3 -0
  33. package/dist/events/types.d.mts +289 -0
  34. package/dist/events/types.d.mts.map +1 -0
  35. package/dist/index.d.mts +23 -0
  36. package/dist/index.mjs +14 -0
  37. package/dist/internal/id.mjs +21 -0
  38. package/dist/internal/id.mjs.map +1 -0
  39. package/dist/internal/types.d.mts +11 -0
  40. package/dist/internal/types.d.mts.map +1 -0
  41. package/dist/mcp/error/mcp-client-error.d.mts +36 -0
  42. package/dist/mcp/error/mcp-client-error.d.mts.map +1 -0
  43. package/dist/mcp/error/mcp-client-error.mjs +33 -0
  44. package/dist/mcp/error/mcp-client-error.mjs.map +1 -0
  45. package/dist/mcp/index.d.mts +8 -0
  46. package/dist/mcp/index.mjs +9 -0
  47. package/dist/mcp/tool/json-rpc-message.d.mts +50 -0
  48. package/dist/mcp/tool/json-rpc-message.d.mts.map +1 -0
  49. package/dist/mcp/tool/json-rpc-message.mjs +84 -0
  50. package/dist/mcp/tool/json-rpc-message.mjs.map +1 -0
  51. package/dist/mcp/tool/mcp-client.d.mts +71 -0
  52. package/dist/mcp/tool/mcp-client.d.mts.map +1 -0
  53. package/dist/mcp/tool/mcp-client.mjs +304 -0
  54. package/dist/mcp/tool/mcp-client.mjs.map +1 -0
  55. package/dist/mcp/tool/mcp-http-transport.d.mts +62 -0
  56. package/dist/mcp/tool/mcp-http-transport.d.mts.map +1 -0
  57. package/dist/mcp/tool/mcp-http-transport.mjs +307 -0
  58. package/dist/mcp/tool/mcp-http-transport.mjs.map +1 -0
  59. package/dist/mcp/tool/mcp-tools.d.mts +20 -0
  60. package/dist/mcp/tool/mcp-tools.d.mts.map +1 -0
  61. package/dist/mcp/tool/mcp-tools.mjs +73 -0
  62. package/dist/mcp/tool/mcp-tools.mjs.map +1 -0
  63. package/dist/mcp/tool/mcp-transport.d.mts +81 -0
  64. package/dist/mcp/tool/mcp-transport.d.mts.map +1 -0
  65. package/dist/mcp/tool/mcp-transport.mjs +11 -0
  66. package/dist/mcp/tool/mcp-transport.mjs.map +1 -0
  67. package/dist/mcp/tool/types.d.mts +230 -0
  68. package/dist/mcp/tool/types.d.mts.map +1 -0
  69. package/dist/mcp/tool/types.mjs +19 -0
  70. package/dist/mcp/tool/types.mjs.map +1 -0
  71. package/dist/persistence/index.d.mts +3 -0
  72. package/dist/persistence/index.mjs +3 -0
  73. package/dist/persistence/memory.d.mts +21 -0
  74. package/dist/persistence/memory.d.mts.map +1 -0
  75. package/dist/persistence/memory.mjs +107 -0
  76. package/dist/persistence/memory.mjs.map +1 -0
  77. package/dist/persistence/types.d.mts +124 -0
  78. package/dist/persistence/types.d.mts.map +1 -0
  79. package/dist/plugins/index.d.mts +2 -0
  80. package/dist/plugins/runtime.d.mts +17 -0
  81. package/dist/plugins/runtime.d.mts.map +1 -0
  82. package/dist/plugins/runtime.mjs +456 -0
  83. package/dist/plugins/runtime.mjs.map +1 -0
  84. package/dist/plugins/types.d.mts +344 -0
  85. package/dist/plugins/types.d.mts.map +1 -0
  86. package/dist/providers/index.d.mts +9 -0
  87. package/dist/providers/index.mjs +0 -0
  88. package/dist/providers/types/capabilities.d.mts +153 -0
  89. package/dist/providers/types/capabilities.d.mts.map +1 -0
  90. package/dist/providers/types/content.d.mts +125 -0
  91. package/dist/providers/types/content.d.mts.map +1 -0
  92. package/dist/providers/types/conversation.d.mts +32 -0
  93. package/dist/providers/types/conversation.d.mts.map +1 -0
  94. package/dist/providers/types/index.d.mts +8 -0
  95. package/dist/providers/types/input.d.mts +74 -0
  96. package/dist/providers/types/input.d.mts.map +1 -0
  97. package/dist/providers/types/model.d.mts +68 -0
  98. package/dist/providers/types/model.d.mts.map +1 -0
  99. package/dist/providers/types/output.d.mts +29 -0
  100. package/dist/providers/types/output.d.mts.map +1 -0
  101. package/dist/providers/types/response.d.mts +35 -0
  102. package/dist/providers/types/response.d.mts.map +1 -0
  103. package/dist/providers/types/tool-calls.d.mts +51 -0
  104. package/dist/providers/types/tool-calls.d.mts.map +1 -0
  105. package/dist/run/agent-loop.mjs +231 -0
  106. package/dist/run/agent-loop.mjs.map +1 -0
  107. package/dist/run/event-queue.mjs +67 -0
  108. package/dist/run/event-queue.mjs.map +1 -0
  109. package/dist/run/execute-tool-calls.mjs +550 -0
  110. package/dist/run/execute-tool-calls.mjs.map +1 -0
  111. package/dist/run/execution.mjs +93 -0
  112. package/dist/run/execution.mjs.map +1 -0
  113. package/dist/run/helpers.mjs +466 -0
  114. package/dist/run/helpers.mjs.map +1 -0
  115. package/dist/run/hooks.mjs +124 -0
  116. package/dist/run/hooks.mjs.map +1 -0
  117. package/dist/run/index.d.mts +4 -0
  118. package/dist/run/messages.d.mts +8 -0
  119. package/dist/run/messages.d.mts.map +1 -0
  120. package/dist/run/messages.mjs +83 -0
  121. package/dist/run/messages.mjs.map +1 -0
  122. package/dist/run/model-strategy.mjs +105 -0
  123. package/dist/run/model-strategy.mjs.map +1 -0
  124. package/dist/run/output-errors.d.mts +75 -0
  125. package/dist/run/output-errors.d.mts.map +1 -0
  126. package/dist/run/pending-tools.d.mts +1 -0
  127. package/dist/run/pending-tools.mjs +185 -0
  128. package/dist/run/pending-tools.mjs.map +1 -0
  129. package/dist/run/registry.mjs +22 -0
  130. package/dist/run/registry.mjs.map +1 -0
  131. package/dist/run/runtime.d.mts +19 -0
  132. package/dist/run/runtime.d.mts.map +1 -0
  133. package/dist/run/runtime.mjs +491 -0
  134. package/dist/run/runtime.mjs.map +1 -0
  135. package/dist/run/stop-conditions.mjs +41 -0
  136. package/dist/run/stop-conditions.mjs.map +1 -0
  137. package/dist/run/types.d.mts +348 -0
  138. package/dist/run/types.d.mts.map +1 -0
  139. package/dist/schema/index.d.mts +2 -0
  140. package/dist/schema/resolve-json-schema.d.mts +12 -0
  141. package/dist/schema/resolve-json-schema.d.mts.map +1 -0
  142. package/dist/schema/resolve-json-schema.mjs +167 -0
  143. package/dist/schema/resolve-json-schema.mjs.map +1 -0
  144. package/dist/schema/types.d.mts +27 -0
  145. package/dist/schema/types.d.mts.map +1 -0
  146. package/dist/server/create-server.d.mts +21 -0
  147. package/dist/server/create-server.d.mts.map +1 -0
  148. package/dist/server/create-server.mjs +107 -0
  149. package/dist/server/create-server.mjs.map +1 -0
  150. package/dist/server/http.mjs +182 -0
  151. package/dist/server/http.mjs.map +1 -0
  152. package/dist/server/index.d.mts +3 -0
  153. package/dist/server/index.mjs +3 -0
  154. package/dist/server/routes.mjs +399 -0
  155. package/dist/server/routes.mjs.map +1 -0
  156. package/dist/server/types.d.mts +31 -0
  157. package/dist/server/types.d.mts.map +1 -0
  158. package/dist/tools/constants.d.mts +12 -0
  159. package/dist/tools/constants.d.mts.map +1 -0
  160. package/dist/tools/constants.mjs +13 -0
  161. package/dist/tools/constants.mjs.map +1 -0
  162. package/dist/tools/define-tool.d.mts +25 -0
  163. package/dist/tools/define-tool.d.mts.map +1 -0
  164. package/dist/tools/define-tool.mjs +76 -0
  165. package/dist/tools/define-tool.mjs.map +1 -0
  166. package/dist/tools/index.d.mts +5 -0
  167. package/dist/tools/lazy-tools.d.mts +49 -0
  168. package/dist/tools/lazy-tools.d.mts.map +1 -0
  169. package/dist/tools/lazy-tools.mjs +87 -0
  170. package/dist/tools/lazy-tools.mjs.map +1 -0
  171. package/dist/tools/resolve-tools.d.mts +12 -0
  172. package/dist/tools/resolve-tools.d.mts.map +1 -0
  173. package/dist/tools/resolve-tools.mjs +86 -0
  174. package/dist/tools/resolve-tools.mjs.map +1 -0
  175. package/dist/tools/types.d.mts +318 -0
  176. package/dist/tools/types.d.mts.map +1 -0
  177. package/dist/tools/validation.mjs +23 -0
  178. package/dist/tools/validation.mjs.map +1 -0
  179. package/package.json +72 -0
@@ -0,0 +1,32 @@
1
+ import { Capabilities } from "./capabilities.mjs";
2
+ import { AudioContentBase, EmbeddingContentBase, FileContentBase, ImageContentBase, ReasoningContentBase, TextContentBase, TranscriptContentBase, VideoContentBase } from "./content.mjs";
3
+ import { GenerativeModelProviderToolResult, GenerativeModelToolCallRequest, GenerativeModelToolCallResult } from "./tool-calls.mjs";
4
+ import { GenerativeModelMessageRole } from "./input.mjs";
5
+
6
+ //#region src/providers/types/conversation.d.ts
7
+ /**
8
+ * Durable conversation message part.
9
+ *
10
+ * Unlike provider input/output parts, this is intentionally not capability-gated.
11
+ * It represents canonical stored state across turns.
12
+ */
13
+ type ConversationMessagePart = TextContentBase | ImageContentBase | FileContentBase | VideoContentBase | AudioContentBase | EmbeddingContentBase | TranscriptContentBase | ReasoningContentBase;
14
+ /**
15
+ * Durable conversation message content.
16
+ */
17
+ type ConversationMessageContent = string | ConversationMessagePart[];
18
+ /**
19
+ * Canonical stored message in a conversation timeline.
20
+ */
21
+ interface ConversationMessage {
22
+ type: "message";
23
+ role: GenerativeModelMessageRole<Capabilities>;
24
+ content: ConversationMessageContent;
25
+ }
26
+ /**
27
+ * Canonical durable conversation item.
28
+ */
29
+ type ConversationItem = ConversationMessage | GenerativeModelToolCallRequest | GenerativeModelToolCallResult | GenerativeModelProviderToolResult;
30
+ //#endregion
31
+ export { ConversationItem, ConversationMessage, ConversationMessageContent, ConversationMessagePart };
32
+ //# sourceMappingURL=conversation.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation.d.mts","names":[],"sources":["../../../src/providers/types/conversation.ts"],"mappings":";;;;;;;;AAwBA;;;;KAAY,uBAAA,GACN,eAAA,GACA,gBAAA,GACA,eAAA,GACA,gBAAA,GACA,gBAAA,GACA,oBAAA,GACA,qBAAA,GACA,oBAAA;;;;KAKM,0BAAA,YAAsC,uBAAA;;;;UAKjC,mBAAA;EACb,IAAA;EACA,IAAA,EAAM,0BAAA,CAA2B,YAAA;EACjC,OAAA,EAAS,0BAAA;AAAA;;;;KAMD,gBAAA,GACN,mBAAA,GACA,8BAAA,GACA,6BAAA,GACA,iCAAA"}
@@ -0,0 +1,8 @@
1
+ import { CapEnabled, Capabilities, IfCap, InferOutputSchema, InputEnabled, InputModalitySpec, InputShape, InstructionEnabled, ModalitiesField, ModalitiesParam, Modality, ModalityOptionsFor, OutputEnabled, OutputModalitySpec, OutputSchemaDefinition, OutputSchemaForCaps, OutputSchemaSource, ReplayMode, StructuredOutput } from "./capabilities.mjs";
2
+ import { AudioContentBase, EmbeddingContentBase, FileContentBase, GenerativeModelAudioSource, GenerativeModelFileSource, GenerativeModelImageSource, GenerativeModelVideoSource, ImageContentBase, ReasoningContentBase, TextContentBase, TranscriptContentBase, VideoContentBase } from "./content.mjs";
3
+ import { GenerativeModelProviderToolResult, GenerativeModelToolCallRequest, GenerativeModelToolCallResult, ToolChoice } from "./tool-calls.mjs";
4
+ import { ChatInputMessage, GenerativeModelCallOptions, GenerativeModelInput, GenerativeModelInputItem, GenerativeModelInputMessage, GenerativeModelInputMessageContent, GenerativeModelInputMessagePart, GenerativeModelMessageRole, ModelOptions, PromptInputMessage } from "./input.mjs";
5
+ import { ConversationItem, ConversationMessage, ConversationMessageContent, ConversationMessagePart } from "./conversation.mjs";
6
+ import { GenerativeModelOutputItem, GenerativeModelOutputMessage, GenerativeModelOutputMessageContent, GenerativeModelOutputMessagePart } from "./output.mjs";
7
+ import { GenerativeModelFinishReason, GenerativeModelResponse, GenerativeModelUsage } from "./response.mjs";
8
+ import { GenerativeModel, GenerativeModelGenerateResult, ModelDescriptor } from "./model.mjs";
@@ -0,0 +1,74 @@
1
+ import { StripIndex } from "../../internal/types.mjs";
2
+ import { Capabilities, IfCap, InputEnabled, ModalitiesField, ModalitiesParam, ModalityOptionsFor, StructuredOutput } from "./capabilities.mjs";
3
+ import { AudioContentBase, EmbeddingContentBase, FileContentBase, ImageContentBase, ReasoningContentBase, TextContentBase, TranscriptContentBase, VideoContentBase } from "./content.mjs";
4
+ import { AgentToolDefinition } from "../../tools/types.mjs";
5
+ import { GenerativeModelProviderToolResult, GenerativeModelToolCallResult, ToolChoice } from "./tool-calls.mjs";
6
+
7
+ //#region src/providers/types/input.d.ts
8
+ /**
9
+ * Message roles supported by a model.
10
+ */
11
+ type GenerativeModelMessageRole<TModelCaps extends Capabilities> = "system" | "user" | "assistant" | (TModelCaps["additionalSupportedRoles"] extends readonly (infer R)[] ? R : never) | (string & {});
12
+ /**
13
+ * One input message part.
14
+ */
15
+ type GenerativeModelInputMessagePart<TModelCaps extends Capabilities = Capabilities> = (InputEnabled<TModelCaps, "text"> extends true ? TextContentBase : never) | (InputEnabled<TModelCaps, "image"> extends true ? ImageContentBase : never) | (InputEnabled<TModelCaps, "file"> extends true ? FileContentBase : never) | (InputEnabled<TModelCaps, "video"> extends true ? VideoContentBase : never) | (InputEnabled<TModelCaps, "audio"> extends true ? AudioContentBase : never) | EmbeddingContentBase | TranscriptContentBase | ReasoningContentBase;
16
+ /**
17
+ * Input message content.
18
+ */
19
+ type GenerativeModelInputMessageContent<TModelCaps extends Capabilities = Capabilities> = (InputEnabled<TModelCaps, "text"> extends true ? string : never) | Array<GenerativeModelInputMessagePart<TModelCaps>>;
20
+ /**
21
+ * Prompt-style input message with no explicit role.
22
+ */
23
+ type PromptInputMessage<TModelCaps extends Capabilities> = {
24
+ type: "message";
25
+ content: GenerativeModelInputMessageContent<TModelCaps>;
26
+ role?: never;
27
+ };
28
+ /**
29
+ * Chat-style input message with an explicit role.
30
+ */
31
+ type ChatInputMessage<TModelCaps extends Capabilities> = {
32
+ type: "message";
33
+ role: GenerativeModelMessageRole<TModelCaps>;
34
+ content: GenerativeModelInputMessageContent<TModelCaps>;
35
+ };
36
+ /**
37
+ * Input message type selected by {@link Capabilities.inputShape | inputShape}.
38
+ */
39
+ type GenerativeModelInputMessage<TModelCaps extends Capabilities = Capabilities> = TModelCaps["inputShape"] extends "prompt" ? PromptInputMessage<TModelCaps> : ChatInputMessage<TModelCaps>;
40
+ /**
41
+ * Input item sent to a model.
42
+ */
43
+ type GenerativeModelInputItem<TModelCaps extends Capabilities = Capabilities> = GenerativeModelInputMessage<TModelCaps> | GenerativeModelToolCallResult | GenerativeModelProviderToolResult;
44
+ /**
45
+ * Complete input for a model call.
46
+ */
47
+ type GenerativeModelInput<TModelCaps extends Capabilities = Capabilities> = (InputEnabled<TModelCaps, "text"> extends true ? string : never) | Array<GenerativeModelInputItem<TModelCaps>>;
48
+ /**
49
+ * Provider options excluding reserved runtime fields.
50
+ *
51
+ * Strips keys that the framework manages internally (`tools`, `toolChoice`, `input`,
52
+ * `modalities`, `structured_output`) as well as fields that have framework-level
53
+ * equivalents (`instructions` → `agent.instruction`, `text` → use `textVerbosity`
54
+ * shorthand + `outputSchema`).
55
+ */
56
+ type ModelOptions<TOptions> = StripIndex<Omit<TOptions, "tools" | "toolChoice" | "input" | "modalities" | "structured_output" | "instructions" | "text">>;
57
+ /**
58
+ * Options for invoking a model call.
59
+ *
60
+ * @typeParam TModelCaps Capability flags for the model.
61
+ * @typeParam TOptions Provider-specific model options.
62
+ * @typeParam TModalities Selected output modalities, if any.
63
+ */
64
+ type GenerativeModelCallOptions<TModelCaps extends Capabilities = Capabilities, TOptions extends Record<string, unknown> = Record<string, unknown>, TModalities extends ModalitiesParam<TModelCaps> = undefined> = {
65
+ input: GenerativeModelInput<TModelCaps>;
66
+ } & ModalitiesField<TModalities> & IfCap<TModelCaps["tools"], {
67
+ tools?: readonly AgentToolDefinition[];
68
+ toolChoice?: ToolChoice;
69
+ }> & IfCap<TModelCaps["structured_output"], {
70
+ structured_output?: StructuredOutput;
71
+ }> & ModelOptions<TOptions> & ModalityOptionsFor<TModelCaps, TModalities>;
72
+ //#endregion
73
+ export { ChatInputMessage, GenerativeModelCallOptions, GenerativeModelInput, GenerativeModelInputItem, GenerativeModelInputMessage, GenerativeModelInputMessageContent, GenerativeModelInputMessagePart, GenerativeModelMessageRole, ModelOptions, PromptInputMessage };
74
+ //# sourceMappingURL=input.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.d.mts","names":[],"sources":["../../../src/providers/types/input.ts"],"mappings":";;;;;;;;;;KA8BY,0BAAA,oBAA8C,YAAA,uCAInD,UAAA,4DAAsE,CAAA;;;;KAMjE,+BAAA,oBAAmD,YAAA,GAAe,YAAA,KACvE,YAAA,CAAa,UAAA,yBAAmC,eAAA,aAChD,YAAA,CAAa,UAAA,0BAAoC,gBAAA,aACjD,YAAA,CAAa,UAAA,yBAAmC,eAAA,aAChD,YAAA,CAAa,UAAA,0BAAoC,gBAAA,aACjD,YAAA,CAAa,UAAA,0BAAoC,gBAAA,YAClD,oBAAA,GACA,qBAAA,GACA,oBAAA;;;;KAKM,kCAAA,oBAAsD,YAAA,GAAe,YAAA,KAC1E,YAAA,CAAa,UAAA,2CACd,KAAA,CAAM,+BAAA,CAAgC,UAAA;;;AAf5C;KAoBY,kBAAA,oBAAsC,YAAA;EAC9C,IAAA;EACA,OAAA,EAAS,kCAAA,CAAmC,UAAA;EAC5C,IAAA;AAAA;;;;KAMQ,gBAAA,oBAAoC,YAAA;EAC5C,IAAA;EACA,IAAA,EAAM,0BAAA,CAA2B,UAAA;EACjC,OAAA,EAAS,kCAAA,CAAmC,UAAA;AAAA;;;;KAMpC,2BAAA,oBAA+C,YAAA,GAAe,YAAA,IACtE,UAAA,kCACM,kBAAA,CAAmB,UAAA,IACnB,gBAAA,CAAiB,UAAA;;;;KAKf,wBAAA,oBAA4C,YAAA,GAAe,YAAA,IACjE,2BAAA,CAA4B,UAAA,IAC5B,6BAAA,GACA,iCAAA;;;;KAKM,oBAAA,oBAAwC,YAAA,GAAe,YAAA,KAC5D,YAAA,CAAa,UAAA,2CACd,KAAA,CAAM,wBAAA,CAAyB,UAAA;;;;;;;;;KAUzB,YAAA,aAAyB,UAAA,CACjC,IAAA,CACI,QAAA;;;;;;;;KAkBI,0BAAA,oBACW,YAAA,GAAe,YAAA,mBACjB,MAAA,oBAA0B,MAAA,uCACvB,eAAA,CAAgB,UAAA;EAEpC,KAAA,EAAO,oBAAA,CAAqB,UAAA;AAAA,IAC5B,eAAA,CAAgB,WAAA,IAChB,KAAA,CACI,UAAA;EAEI,KAAA,YAAiB,mBAAA;EACjB,UAAA,GAAa,UAAA;AAAA,KAGrB,KAAA,CACI,UAAA;EAEI,iBAAA,GAAoB,gBAAA;AAAA,KAG5B,YAAA,CAAa,QAAA,IACb,kBAAA,CAAmB,UAAA,EAAY,WAAA"}
@@ -0,0 +1,68 @@
1
+ import { Capabilities, ModalitiesParam } from "./capabilities.mjs";
2
+ import { GenerativeModelCallOptions } from "./input.mjs";
3
+ import { GenerativeModelResponse } from "./response.mjs";
4
+ import { RunContext } from "../../run/types.mjs";
5
+ import { Event } from "../../events/types.mjs";
6
+ import { BetterAgentError } from "@better-agent/shared/errors";
7
+ import { Result } from "@better-agent/shared/neverthrow";
8
+
9
+ //#region src/providers/types/model.d.ts
10
+ /**
11
+ * Model registry entry describing model options and capabilities.
12
+ */
13
+ type ModelDescriptor<TOptions extends Record<string, unknown> = Record<string, unknown>, TCaps extends Capabilities = Capabilities> = {
14
+ options: TOptions;
15
+ caps: TCaps;
16
+ };
17
+ /**
18
+ * Model definition used by the runtime.
19
+ *
20
+ * A model can implement non-streaming generation, streaming generation, or both.
21
+ */
22
+ type GenerativeModel<TOptions extends Record<string, unknown> = Record<string, unknown>, TProviderId extends string = string, TModelId extends string = string, TModelCaps extends Capabilities = Capabilities> = GenerativeModelBase<TProviderId, TModelId, TModelCaps> & (GenerativeModelWithGenerate<TModelCaps, TOptions> | GenerativeModelWithStream<TModelCaps, TOptions> | GenerativeModelWithGenerateAndStream<TModelCaps, TOptions>);
23
+ interface GenerativeModelBase<TProviderId extends string, TModelId extends string, TModelCaps extends Capabilities> {
24
+ /** Provider identifier for this model. */
25
+ readonly providerId: TProviderId;
26
+ /** Model identifier within the provider. */
27
+ readonly modelId: TModelId;
28
+ /** Runtime capability flags. */
29
+ readonly caps: TModelCaps;
30
+ }
31
+ /**
32
+ * Result returned by `doGenerate`.
33
+ */
34
+ interface GenerativeModelGenerateResult<TModelCaps extends Capabilities> {
35
+ response: GenerativeModelResponse<TModelCaps>;
36
+ events?: Event[];
37
+ }
38
+ interface GenerativeModelWithGenerate<TModelCaps extends Capabilities, TOptions extends Record<string, unknown>> {
39
+ /**
40
+ * Performs a non-streaming generation.
41
+ *
42
+ * @returns A {@link Result} containing the model response and optional emitted events.
43
+ */
44
+ doGenerate<const TModalities extends ModalitiesParam<TModelCaps> = undefined>(options: GenerativeModelCallOptions<TModelCaps, TOptions, TModalities>, ctx: RunContext): Promise<Result<GenerativeModelGenerateResult<TModelCaps>, BetterAgentError>>;
45
+ doGenerateStream?: undefined;
46
+ }
47
+ interface GenerativeModelWithStream<TModelCaps extends Capabilities, TOptions extends Record<string, unknown>> {
48
+ /**
49
+ * Performs a streaming generation.
50
+ *
51
+ * @returns A {@link Result} containing streamed events and a final response.
52
+ */
53
+ doGenerateStream<const TModalities extends ModalitiesParam<TModelCaps> = undefined>(options: GenerativeModelCallOptions<TModelCaps, TOptions, TModalities>, ctx: RunContext): Promise<Result<{
54
+ events: AsyncGenerator<Result<Event, BetterAgentError>>;
55
+ final: Promise<GenerativeModelResponse<TModelCaps>>;
56
+ }, BetterAgentError>>;
57
+ doGenerate?: undefined;
58
+ }
59
+ interface GenerativeModelWithGenerateAndStream<TModelCaps extends Capabilities, TOptions extends Record<string, unknown>> {
60
+ doGenerate<const TModalities extends ModalitiesParam<TModelCaps> = undefined>(options: GenerativeModelCallOptions<TModelCaps, TOptions, TModalities>, ctx: RunContext): Promise<Result<GenerativeModelGenerateResult<TModelCaps>, BetterAgentError>>;
61
+ doGenerateStream<const TModalities extends ModalitiesParam<TModelCaps> = undefined>(options: GenerativeModelCallOptions<TModelCaps, TOptions, TModalities>, ctx: RunContext): Promise<Result<{
62
+ events: AsyncGenerator<Result<Event, BetterAgentError>>;
63
+ final: Promise<GenerativeModelResponse<TModelCaps>>;
64
+ }, BetterAgentError>>;
65
+ }
66
+ //#endregion
67
+ export { GenerativeModel, GenerativeModelGenerateResult, ModelDescriptor };
68
+ //# sourceMappingURL=model.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.mts","names":[],"sources":["../../../src/providers/types/model.ts"],"mappings":";;;;;;;;;;;;KAWY,eAAA,kBACS,MAAA,oBAA0B,MAAA,iCAC7B,YAAA,GAAe,YAAA;EAE7B,OAAA,EAAS,QAAA;EACT,IAAA,EAAM,KAAA;AAAA;;;;;;KAQE,eAAA,kBACS,MAAA,oBAA0B,MAAA,6GAGxB,YAAA,GAAe,YAAA,IAClC,mBAAA,CAAoB,WAAA,EAAa,QAAA,EAAU,UAAA,KAErC,2BAAA,CAA4B,UAAA,EAAY,QAAA,IACxC,yBAAA,CAA0B,UAAA,EAAY,QAAA,IACtC,oCAAA,CAAqC,UAAA,EAAY,QAAA;AAAA,UAGjD,mBAAA,yEAGa,YAAA;EAvBR;EAAA,SA0BF,UAAA,EAAY,WAAA;EA9BJ;EAAA,SAgCR,OAAA,EAAS,QAAA;EA/BlB;EAAA,SAiCS,IAAA,EAAM,UAAA;AAAA;;;;UAMF,6BAAA,oBAAiD,YAAA;EAC9D,QAAA,EAAU,uBAAA,CAAwB,UAAA;EAClC,MAAA,GAAS,KAAA;AAAA;AAAA,UAGH,2BAAA,oBACa,YAAA,mBACF,MAAA;EAnCM;;;;;EA0CvB,UAAA,2BAAqC,eAAA,CAAgB,UAAA,eACjD,OAAA,EAAS,0BAAA,CAA2B,UAAA,EAAY,QAAA,EAAU,WAAA,GAC1D,GAAA,EAAK,UAAA,GACN,OAAA,CAAQ,MAAA,CAAO,6BAAA,CAA8B,UAAA,GAAa,gBAAA;EAC7D,gBAAA;AAAA;AAAA,UAGM,yBAAA,oBACa,YAAA,mBACF,MAAA;EA5CiB;;;;;EAmDlC,gBAAA,2BAA2C,eAAA,CAAgB,UAAA,eACvD,OAAA,EAAS,0BAAA,CAA2B,UAAA,EAAY,QAAA,EAAU,WAAA,GAC1D,GAAA,EAAK,UAAA,GACN,OAAA,CACC,MAAA;IAEQ,MAAA,EAAQ,cAAA,CAAe,MAAA,CAAO,KAAA,EAAO,gBAAA;IACrC,KAAA,EAAO,OAAA,CAAQ,uBAAA,CAAwB,UAAA;EAAA,GAE3C,gBAAA;EAGR,UAAA;AAAA;AAAA,UAGM,oCAAA,oBACa,YAAA,mBACF,MAAA;EAEjB,UAAA,2BAAqC,eAAA,CAAgB,UAAA,eACjD,OAAA,EAAS,0BAAA,CAA2B,UAAA,EAAY,QAAA,EAAU,WAAA,GAC1D,GAAA,EAAK,UAAA,GACN,OAAA,CAAQ,MAAA,CAAO,6BAAA,CAA8B,UAAA,GAAa,gBAAA;EAC7D,gBAAA,2BAA2C,eAAA,CAAgB,UAAA,eACvD,OAAA,EAAS,0BAAA,CAA2B,UAAA,EAAY,QAAA,EAAU,WAAA,GAC1D,GAAA,EAAK,UAAA,GACN,OAAA,CACC,MAAA;IAEQ,MAAA,EAAQ,cAAA,CAAe,MAAA,CAAO,KAAA,EAAO,gBAAA;IACrC,KAAA,EAAO,OAAA,CAAQ,uBAAA,CAAwB,UAAA;EAAA,GAE3C,gBAAA;AAAA"}
@@ -0,0 +1,29 @@
1
+ import { Capabilities, OutputEnabled } from "./capabilities.mjs";
2
+ import { AudioContentBase, EmbeddingContentBase, ImageContentBase, ReasoningContentBase, TextContentBase, TranscriptContentBase, VideoContentBase } from "./content.mjs";
3
+ import { GenerativeModelProviderToolResult, GenerativeModelToolCallRequest } from "./tool-calls.mjs";
4
+ import { GenerativeModelMessageRole } from "./input.mjs";
5
+
6
+ //#region src/providers/types/output.d.ts
7
+ /**
8
+ * One output message part.
9
+ */
10
+ type GenerativeModelOutputMessagePart<TModelCaps extends Capabilities = Capabilities> = (OutputEnabled<TModelCaps, "text"> extends true ? TextContentBase : never) | (OutputEnabled<TModelCaps, "image"> extends true ? ImageContentBase : never) | (OutputEnabled<TModelCaps, "video"> extends true ? VideoContentBase : never) | (OutputEnabled<TModelCaps, "audio"> extends true ? AudioContentBase : never) | (OutputEnabled<TModelCaps, "embedding"> extends true ? EmbeddingContentBase : never) | TranscriptContentBase | ReasoningContentBase;
11
+ /**
12
+ * Output message content.
13
+ */
14
+ type GenerativeModelOutputMessageContent<TModelCaps extends Capabilities = Capabilities> = (OutputEnabled<TModelCaps, "text"> extends true ? string : never) | Array<GenerativeModelOutputMessagePart<TModelCaps>>;
15
+ /**
16
+ * Output message emitted by the model.
17
+ */
18
+ type GenerativeModelOutputMessage<TModelCaps extends Capabilities = Capabilities> = {
19
+ type: "message";
20
+ role: GenerativeModelMessageRole<TModelCaps>;
21
+ content: GenerativeModelOutputMessageContent<TModelCaps>;
22
+ };
23
+ /**
24
+ * Output item returned by a model.
25
+ */
26
+ type GenerativeModelOutputItem<TModelCaps extends Capabilities = Capabilities> = GenerativeModelOutputMessage<TModelCaps> | GenerativeModelToolCallRequest | GenerativeModelProviderToolResult;
27
+ //#endregion
28
+ export { GenerativeModelOutputItem, GenerativeModelOutputMessage, GenerativeModelOutputMessageContent, GenerativeModelOutputMessagePart };
29
+ //# sourceMappingURL=output.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.mts","names":[],"sources":["../../../src/providers/types/output.ts"],"mappings":";;;;;;;;AAmBA;KAAY,gCAAA,oBAAoD,YAAA,GAAe,YAAA,KACxE,aAAA,CAAc,UAAA,yBAAmC,eAAA,aACjD,aAAA,CAAc,UAAA,0BAAoC,gBAAA,aAClD,aAAA,CAAc,UAAA,0BAAoC,gBAAA,aAClD,aAAA,CAAc,UAAA,0BAAoC,gBAAA,aAClD,aAAA,CAAc,UAAA,8BAAwC,oBAAA,YACvD,qBAAA,GACA,oBAAA;;;;KAKM,mCAAA,oBAAuD,YAAA,GAAe,YAAA,KAC3E,aAAA,CAAc,UAAA,2CACf,KAAA,CAAM,gCAAA,CAAiC,UAAA;;;;KAKjC,4BAAA,oBAAgD,YAAA,GAAe,YAAA;EACvE,IAAA;EACA,IAAA,EAAM,0BAAA,CAA2B,UAAA;EACjC,OAAA,EAAS,mCAAA,CAAoC,UAAA;AAAA;;;;KAMrC,yBAAA,oBAA6C,YAAA,GAAe,YAAA,IAClE,4BAAA,CAA6B,UAAA,IAC7B,8BAAA,GACA,iCAAA"}
@@ -0,0 +1,35 @@
1
+ import { Capabilities } from "./capabilities.mjs";
2
+ import { GenerativeModelOutputItem } from "./output.mjs";
3
+
4
+ //#region src/providers/types/response.d.ts
5
+ /**
6
+ * Token usage statistics for a model call.
7
+ */
8
+ interface GenerativeModelUsage {
9
+ inputTokens?: number;
10
+ outputTokens?: number;
11
+ totalTokens?: number;
12
+ reasoningTokens?: number;
13
+ cachedInputTokens?: number;
14
+ }
15
+ /**
16
+ * Finish reason reported by a model.
17
+ */
18
+ type GenerativeModelFinishReason = /** Model completed normally. */"stop" /** Model stopped because token/output limits were reached. */ | "length" /** Model output was blocked or truncated by safety/content filters. */ | "content-filter" /** Model stopped to request one or more tool calls. */ | "tool-calls" /** Generation was interrupted by an explicit abort action. */ | "abort" /** Any provider-specific reason that does not map to a normalized value. */ | "other";
19
+ /**
20
+ * Model response payload.
21
+ */
22
+ interface GenerativeModelResponse<TModelCaps extends Capabilities = Capabilities> {
23
+ output: Array<GenerativeModelOutputItem<TModelCaps>>;
24
+ finishReason: GenerativeModelFinishReason;
25
+ usage: GenerativeModelUsage;
26
+ request?: {
27
+ body: unknown;
28
+ };
29
+ response?: {
30
+ body: unknown;
31
+ };
32
+ }
33
+ //#endregion
34
+ export { GenerativeModelFinishReason, GenerativeModelResponse, GenerativeModelUsage };
35
+ //# sourceMappingURL=response.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.mts","names":[],"sources":["../../../src/providers/types/response.ts"],"mappings":";;;;;;AAMA;UAAiB,oBAAA;EACb,WAAA;EACA,YAAA;EACA,WAAA;EACA,eAAA;EACA,iBAAA;AAAA;;;;KAMQ,2BAAA,oHAiBZ;;;;UAAiB,uBAAA,oBAA2C,YAAA,GAAe,YAAA;EACvE,MAAA,EAAQ,KAAA,CAAM,yBAAA,CAA0B,UAAA;EACxC,YAAA,EAAc,2BAAA;EACd,KAAA,EAAO,oBAAA;EACP,OAAA;IACI,IAAA;EAAA;EAEJ,QAAA;IACI,IAAA;EAAA;AAAA"}
@@ -0,0 +1,51 @@
1
+ //#region src/providers/types/tool-calls.d.ts
2
+ /**
3
+ * Tool selection strategy for a model call.
4
+ */
5
+ type ToolChoice<TName extends string = string> = {
6
+ type: "auto";
7
+ } | {
8
+ type: "none";
9
+ } | {
10
+ type: "required";
11
+ } | {
12
+ type: "tool";
13
+ name: TName;
14
+ };
15
+ /**
16
+ * Tool call request emitted by a model.
17
+ */
18
+ interface GenerativeModelToolCallRequest {
19
+ type: "tool-call";
20
+ name: string;
21
+ arguments: string;
22
+ callId: string;
23
+ result?: never;
24
+ }
25
+ /**
26
+ * Tool call result returned to the model.
27
+ */
28
+ interface GenerativeModelToolCallResult {
29
+ type: "tool-call";
30
+ name: string;
31
+ callId: string;
32
+ result: unknown;
33
+ isError?: boolean;
34
+ arguments?: string;
35
+ }
36
+ /**
37
+ * Provider-originated tool result surfaced in model output.
38
+ *
39
+ * This is used for provider-native tool artifacts that appear in provider
40
+ * responses, but are not model-emitted tool-call requests.
41
+ */
42
+ interface GenerativeModelProviderToolResult {
43
+ type: "provider-tool-result";
44
+ name: string;
45
+ callId: string;
46
+ result: unknown;
47
+ isError?: boolean;
48
+ }
49
+ //#endregion
50
+ export { GenerativeModelProviderToolResult, GenerativeModelToolCallRequest, GenerativeModelToolCallResult, ToolChoice };
51
+ //# sourceMappingURL=tool-calls.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-calls.d.mts","names":[],"sources":["../../../src/providers/types/tool-calls.ts"],"mappings":";;AAGA;;KAAY,UAAA;EAEF,IAAA;AAAA;EAGA,IAAA;AAAA;EAGA,IAAA;AAAA;EAGA,IAAA;EACA,IAAA,EAAM,KAAA;AAAA;;AAMhB;;UAAiB,8BAAA;EACb,IAAA;EACA,IAAA;EACA,SAAA;EACA,MAAA;EACA,MAAA;AAAA;;;AAMJ;UAAiB,6BAAA;EACb,IAAA;EACA,IAAA;EACA,MAAA;EACA,MAAA;EACA,OAAA;EACA,SAAA;AAAA;;;;AASJ;;;UAAiB,iCAAA;EACb,IAAA;EACA,IAAA;EACA,MAAA;EACA,MAAA;EACA,OAAA;AAAA"}
@@ -0,0 +1,231 @@
1
+ import { resolveToolsForRun } from "../tools/resolve-tools.mjs";
2
+ import { Events } from "../events/constants.mjs";
3
+ import { executeToolCalls } from "./execute-tool-calls.mjs";
4
+ import { projectConversationItemsToInput } from "./messages.mjs";
5
+ import { prepareConversationReplayInput } from "./helpers.mjs";
6
+ import { applyAfterModelCall, applyBeforeModelCall, applyOnStep, applyOnStepFinish } from "./hooks.mjs";
7
+ import { evaluateStopConditions, extractToolCallRequests } from "./stop-conditions.mjs";
8
+ import { BetterAgentError } from "@better-agent/shared/errors";
9
+
10
+ //#region src/run/agent-loop.ts
11
+ const runAgentLoop = async (options, strategy) => {
12
+ const traceBase = strategy.mode === "stream" ? "core.run.runStreamLoop" : "core.run.runLoop";
13
+ const pluginToolsResult = options.pluginRuntime?.hasTools === true ? await options.pluginRuntime.resolveTools(options.context) : {
14
+ tools: [],
15
+ runCleanup: async () => {}
16
+ };
17
+ const { tools, runCleanup } = await resolveToolsForRun({
18
+ appTools: options.appTools,
19
+ agentTools: options.agent.tools,
20
+ context: options.context
21
+ });
22
+ const resolvedTools = [...tools, ...pluginToolsResult.tools];
23
+ if (strategy.mode === "run") {
24
+ const blockingTool = resolvedTools.find((tool) => tool.kind === "client" || tool.kind !== "hosted" && tool.approval !== void 0);
25
+ if (blockingTool) {
26
+ const reason = blockingTool.kind === "client" ? `client tool '${blockingTool.name}'` : `approval-gated tool '${blockingTool.name}'`;
27
+ throw BetterAgentError.fromCode("BAD_REQUEST", `Non-stream runs do not support interactive tools. Use stream() for ${reason}.`, {
28
+ context: {
29
+ agentName: options.agent.name,
30
+ toolName: blockingTool.name,
31
+ toolTarget: blockingTool.kind
32
+ },
33
+ trace: [{ at: `${traceBase}.validateNonInteractiveRun` }]
34
+ });
35
+ }
36
+ }
37
+ const state = {
38
+ runId: options.runId,
39
+ agentName: options.agent.name,
40
+ items: [...options.items],
41
+ replayStartIndex: options.replayStartIndex ?? 0,
42
+ steps: [],
43
+ stepIndex: 0,
44
+ maxSteps: options.maxSteps,
45
+ conversationId: options.conversationId,
46
+ context: options.context
47
+ };
48
+ const instructionField = "instruction" in options.agent ? options.agent.instruction : void 0;
49
+ const instructionResolver = instructionField;
50
+ const instruction = typeof instructionResolver === "function" ? instructionResolver(options.context) : instructionField ?? "";
51
+ const modelCaps = options.agent.model.caps;
52
+ const assertInstructionSupported = (currentInstruction, traceAt) => {
53
+ if (currentInstruction === void 0 || currentInstruction === "") return;
54
+ if (modelCaps.inputShape === "prompt" || modelCaps.supportsInstruction !== true) throw BetterAgentError.fromCode("VALIDATION_FAILED", `Agent '${options.agent.name}' model does not support instructions.`, {
55
+ context: {
56
+ agentName: options.agent.name,
57
+ modelId: options.agent.model.modelId,
58
+ inputShape: modelCaps.inputShape ?? "chat",
59
+ replayMode: modelCaps.replayMode ?? (modelCaps.inputShape === "prompt" ? "single_turn_persistent" : "multi_turn")
60
+ },
61
+ trace: [{ at: traceAt }]
62
+ });
63
+ };
64
+ assertInstructionSupported(instruction, `${traceBase}.validateInstruction`);
65
+ const stepErrorMessage = strategy.mode === "stream" ? "Run stream step failed" : "Run loop step failed";
66
+ try {
67
+ while (true) {
68
+ const previousStep = state.steps.at(-1);
69
+ const replayItems = state.items.slice(state.replayStartIndex);
70
+ const projectedMessages = state.conversationId !== void 0 && options.conversationReplayActive ? await prepareConversationReplayInput({
71
+ items: replayItems,
72
+ caps: modelCaps,
73
+ agentName: state.agentName,
74
+ conversationId: state.conversationId,
75
+ conversationReplay: options.conversationReplay
76
+ }) : projectConversationItemsToInput(replayItems, modelCaps);
77
+ const prepared = await applyOnStep({
78
+ runId: state.runId,
79
+ agentName: state.agentName,
80
+ stepIndex: state.stepIndex,
81
+ maxSteps: state.maxSteps,
82
+ messages: projectedMessages,
83
+ modelCaps,
84
+ conversationId: state.conversationId,
85
+ context: options.context,
86
+ previousStep,
87
+ onStep: options.agent.onStep,
88
+ pluginRuntime: options.pluginRuntime
89
+ });
90
+ await options.emit({
91
+ type: Events.STEP_START,
92
+ runId: state.runId,
93
+ agentName: state.agentName,
94
+ stepIndex: state.stepIndex,
95
+ maxSteps: state.maxSteps,
96
+ timestamp: Date.now(),
97
+ conversationId: state.conversationId
98
+ });
99
+ try {
100
+ const activeToolNames = prepared.activeTools;
101
+ const activeTools = activeToolNames === void 0 ? resolvedTools : resolvedTools.filter((tool) => activeToolNames.includes(tool.kind === "hosted" ? typeof tool.name === "string" && tool.name.length > 0 ? tool.name : tool.type : tool.name));
102
+ const effectiveInstruction = prepared.systemInstruction ?? instruction;
103
+ assertInstructionSupported(effectiveInstruction, `${traceBase}.prepareModelInput.validateInstruction`);
104
+ const modelInput = effectiveInstruction === void 0 || effectiveInstruction === "" ? [...prepared.messages] : [{
105
+ type: "message",
106
+ role: "system",
107
+ content: effectiveInstruction
108
+ }, ...prepared.messages];
109
+ const modelPrepared = await applyBeforeModelCall({
110
+ runId: state.runId,
111
+ agentName: state.agentName,
112
+ stepIndex: state.stepIndex,
113
+ modelCaps,
114
+ input: modelInput,
115
+ tools: activeTools,
116
+ conversationId: state.conversationId,
117
+ toolChoice: prepared.toolChoice ?? options.toolChoice,
118
+ pluginRuntime: options.pluginRuntime
119
+ });
120
+ const { response, assistantMessageId } = await strategy.call({
121
+ options,
122
+ modelInput: modelPrepared.input,
123
+ tools: modelPrepared.tools,
124
+ toolChoice: modelPrepared.toolChoice,
125
+ stepIndex: state.stepIndex,
126
+ runId: state.runId,
127
+ agentName: state.agentName,
128
+ conversationId: state.conversationId
129
+ });
130
+ await applyAfterModelCall({
131
+ runId: state.runId,
132
+ agentName: state.agentName,
133
+ stepIndex: state.stepIndex,
134
+ response,
135
+ conversationId: state.conversationId,
136
+ pluginRuntime: options.pluginRuntime
137
+ });
138
+ const toolCalls = extractToolCallRequests(response);
139
+ const toolBatch = toolCalls.length > 0 ? await executeToolCalls({
140
+ runId: state.runId,
141
+ agentName: state.agentName,
142
+ conversationId: state.conversationId,
143
+ parentMessageId: assistantMessageId,
144
+ toolCalls,
145
+ tools: modelPrepared.tools,
146
+ toolErrorMode: options.agent.toolErrorMode,
147
+ onToolError: options.agent.onToolError,
148
+ signal: options.signal,
149
+ emit: options.emit,
150
+ advanced: options.advanced,
151
+ pendingToolRuntime: options.pendingToolRuntime,
152
+ context: options.context,
153
+ pluginRuntime: options.pluginRuntime
154
+ }) : { results: [] };
155
+ state.items = [...state.items, ...response.output];
156
+ if (toolBatch.results.length > 0) state.items = [...state.items, ...toolBatch.results];
157
+ const stepResult = { response };
158
+ state.steps.push(stepResult);
159
+ const stopMessages = state.conversationId !== void 0 && options.conversationReplayActive ? await prepareConversationReplayInput({
160
+ items: state.items.slice(state.replayStartIndex),
161
+ caps: modelCaps,
162
+ agentName: state.agentName,
163
+ conversationId: state.conversationId,
164
+ conversationReplay: options.conversationReplay
165
+ }) : projectConversationItemsToInput(state.items.slice(state.replayStartIndex), modelCaps);
166
+ const stopDecision = evaluateStopConditions({
167
+ maxSteps: state.maxSteps,
168
+ stepIndex: state.stepIndex,
169
+ steps: state.steps,
170
+ messages: stopMessages,
171
+ lastStep: stepResult,
172
+ stopWhen: options.agent.stopWhen,
173
+ context: options.context
174
+ });
175
+ await options.emit({
176
+ type: Events.STEP_FINISH,
177
+ runId: state.runId,
178
+ agentName: state.agentName,
179
+ stepIndex: state.stepIndex,
180
+ maxSteps: state.maxSteps,
181
+ toolCallCount: toolCalls.length,
182
+ terminationReason: stopDecision.stop ? stopDecision.reason : void 0,
183
+ timestamp: Date.now(),
184
+ conversationId: state.conversationId
185
+ });
186
+ await applyOnStepFinish({
187
+ runId: state.runId,
188
+ agentName: state.agentName,
189
+ stepIndex: state.stepIndex,
190
+ maxSteps: state.maxSteps,
191
+ result: stepResult,
192
+ conversationId: state.conversationId,
193
+ context: options.context,
194
+ onStepFinish: options.agent.onStepFinish
195
+ });
196
+ if (stopDecision.stop) return {
197
+ response,
198
+ items: state.items
199
+ };
200
+ state.stepIndex += 1;
201
+ } catch (error) {
202
+ const wrapped = error instanceof BetterAgentError ? error.at({ at: traceBase }) : BetterAgentError.wrap({
203
+ err: error,
204
+ message: stepErrorMessage,
205
+ opts: {
206
+ code: "INTERNAL",
207
+ trace: [{ at: traceBase }]
208
+ }
209
+ });
210
+ await options.emit({
211
+ type: Events.STEP_ERROR,
212
+ runId: state.runId,
213
+ agentName: state.agentName,
214
+ stepIndex: state.stepIndex,
215
+ maxSteps: state.maxSteps,
216
+ error: wrapped,
217
+ timestamp: Date.now(),
218
+ conversationId: state.conversationId
219
+ });
220
+ throw wrapped;
221
+ }
222
+ }
223
+ } finally {
224
+ await runCleanup();
225
+ await pluginToolsResult.runCleanup();
226
+ }
227
+ };
228
+
229
+ //#endregion
230
+ export { runAgentLoop };
231
+ //# sourceMappingURL=agent-loop.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-loop.mjs","names":[],"sources":["../../src/run/agent-loop.ts"],"sourcesContent":["import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { Events } from \"../events\";\nimport type { GenerativeModelInputMessage, GenerativeModelInputMessageContent } from \"../providers\";\nimport type { ConversationItem } from \"../providers\";\nimport { resolveToolsForRun } from \"../tools\";\nimport { executeToolCalls } from \"./execute-tool-calls\";\nimport { prepareConversationReplayInput } from \"./helpers\";\nimport { applyAfterModelCall, applyBeforeModelCall, applyOnStep, applyOnStepFinish } from \"./hooks\";\nimport { projectConversationItemsToInput } from \"./messages\";\nimport {\n type LoopStopDecision,\n evaluateStopConditions,\n extractToolCallRequests,\n} from \"./stop-conditions\";\nimport type {\n LoopState,\n ModelCallStrategy,\n PreviousStepResult,\n RunResult,\n SharedRunLoopOptions,\n} from \"./types\";\n\nexport const runAgentLoop = async <TContext>(\n options: SharedRunLoopOptions<TContext>,\n strategy: ModelCallStrategy<TContext>,\n): Promise<RunResult & { items: ConversationItem[] }> => {\n const traceBase = strategy.mode === \"stream\" ? \"core.run.runStreamLoop\" : \"core.run.runLoop\";\n\n // Resolve plugin tools.\n const pluginToolsResult =\n options.pluginRuntime?.hasTools === true\n ? await options.pluginRuntime.resolveTools(options.context)\n : {\n tools: [],\n runCleanup: async () => {},\n };\n\n // Resolve agent tools.\n const { tools, runCleanup } = await resolveToolsForRun({\n appTools: options.appTools,\n agentTools: options.agent.tools,\n context: options.context,\n });\n\n const resolvedTools = [...tools, ...pluginToolsResult.tools];\n\n if (strategy.mode === \"run\") {\n const blockingTool = resolvedTools.find(\n (tool) =>\n tool.kind === \"client\" || (tool.kind !== \"hosted\" && tool.approval !== undefined),\n );\n\n if (blockingTool) {\n const reason =\n blockingTool.kind === \"client\"\n ? `client tool '${blockingTool.name}'`\n : `approval-gated tool '${blockingTool.name}'`;\n\n throw BetterAgentError.fromCode(\n \"BAD_REQUEST\",\n `Non-stream runs do not support interactive tools. Use stream() for ${reason}.`,\n {\n context: {\n agentName: options.agent.name,\n toolName: blockingTool.name,\n toolTarget: blockingTool.kind,\n },\n trace: [{ at: `${traceBase}.validateNonInteractiveRun` }],\n },\n );\n }\n }\n\n const state: LoopState<TContext> = {\n runId: options.runId,\n agentName: options.agent.name,\n items: [...options.items],\n replayStartIndex: options.replayStartIndex ?? 0,\n steps: [],\n stepIndex: 0,\n maxSteps: options.maxSteps,\n conversationId: options.conversationId,\n context: options.context,\n };\n\n const instructionField = \"instruction\" in options.agent ? options.agent.instruction : undefined;\n const instructionResolver = instructionField as ((context: TContext) => string) | undefined;\n const instruction =\n typeof instructionResolver === \"function\"\n ? instructionResolver(options.context as TContext)\n : (instructionField ?? \"\");\n\n const modelCaps = options.agent.model.caps;\n\n const assertInstructionSupported = (\n currentInstruction: GenerativeModelInputMessageContent<typeof modelCaps> | undefined,\n traceAt: string,\n ): void => {\n if (currentInstruction === undefined || currentInstruction === \"\") {\n return;\n }\n\n if (modelCaps.inputShape === \"prompt\" || modelCaps.supportsInstruction !== true) {\n throw BetterAgentError.fromCode(\n \"VALIDATION_FAILED\",\n `Agent '${options.agent.name}' model does not support instructions.`,\n {\n context: {\n agentName: options.agent.name,\n modelId: options.agent.model.modelId,\n inputShape: modelCaps.inputShape ?? \"chat\",\n replayMode:\n modelCaps.replayMode ??\n (modelCaps.inputShape === \"prompt\"\n ? \"single_turn_persistent\"\n : \"multi_turn\"),\n },\n trace: [{ at: traceAt }],\n },\n );\n }\n };\n\n assertInstructionSupported(instruction, `${traceBase}.validateInstruction`);\n\n const stepErrorMessage =\n strategy.mode === \"stream\" ? \"Run stream step failed\" : \"Run loop step failed\";\n\n try {\n while (true) {\n const previousStep = state.steps.at(-1);\n const replayItems = state.items.slice(state.replayStartIndex);\n const projectedMessages =\n state.conversationId !== undefined && options.conversationReplayActive\n ? await prepareConversationReplayInput({\n items: replayItems,\n caps: modelCaps,\n agentName: state.agentName,\n conversationId: state.conversationId,\n conversationReplay: options.conversationReplay,\n })\n : projectConversationItemsToInput(replayItems, modelCaps);\n const prepared = await applyOnStep({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n messages: projectedMessages,\n modelCaps,\n conversationId: state.conversationId,\n context: options.context,\n previousStep,\n onStep: options.agent.onStep,\n pluginRuntime: options.pluginRuntime,\n });\n\n await options.emit({\n type: Events.STEP_START,\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n timestamp: Date.now(),\n conversationId: state.conversationId,\n });\n\n try {\n const activeToolNames = prepared.activeTools;\n const activeTools =\n activeToolNames === undefined\n ? resolvedTools\n : resolvedTools.filter((tool) =>\n activeToolNames.includes(\n tool.kind === \"hosted\"\n ? typeof tool.name === \"string\" && tool.name.length > 0\n ? tool.name\n : tool.type\n : tool.name,\n ),\n );\n\n const effectiveInstruction = (prepared.systemInstruction ?? instruction) as\n | GenerativeModelInputMessageContent<typeof modelCaps>\n | undefined;\n assertInstructionSupported(\n effectiveInstruction,\n `${traceBase}.prepareModelInput.validateInstruction`,\n );\n const modelInput =\n effectiveInstruction === undefined || effectiveInstruction === \"\"\n ? [...prepared.messages]\n : [\n {\n type: \"message\",\n role: \"system\",\n content: effectiveInstruction,\n } as GenerativeModelInputMessage<typeof modelCaps>,\n ...prepared.messages,\n ];\n\n const modelPrepared = await applyBeforeModelCall({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n modelCaps,\n input: modelInput,\n tools: activeTools,\n conversationId: state.conversationId,\n toolChoice: prepared.toolChoice ?? options.toolChoice,\n pluginRuntime: options.pluginRuntime,\n });\n\n const { response, assistantMessageId } = await strategy.call({\n options,\n modelInput: modelPrepared.input,\n tools: modelPrepared.tools,\n toolChoice: modelPrepared.toolChoice,\n stepIndex: state.stepIndex,\n runId: state.runId,\n agentName: state.agentName,\n conversationId: state.conversationId,\n });\n\n await applyAfterModelCall({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n response,\n conversationId: state.conversationId,\n pluginRuntime: options.pluginRuntime,\n });\n\n const toolCalls = extractToolCallRequests(response);\n const toolBatch =\n toolCalls.length > 0\n ? await executeToolCalls({\n runId: state.runId,\n agentName: state.agentName,\n conversationId: state.conversationId,\n parentMessageId: assistantMessageId,\n toolCalls,\n tools: modelPrepared.tools,\n toolErrorMode: options.agent.toolErrorMode,\n onToolError: options.agent.onToolError,\n signal: options.signal,\n emit: options.emit,\n advanced: options.advanced,\n pendingToolRuntime: options.pendingToolRuntime,\n context: options.context,\n pluginRuntime: options.pluginRuntime,\n })\n : { results: [] };\n\n state.items = [...state.items, ...response.output];\n if (toolBatch.results.length > 0) {\n state.items = [...state.items, ...toolBatch.results];\n }\n\n const stepResult: PreviousStepResult = { response };\n state.steps.push(stepResult);\n\n const stopMessages =\n state.conversationId !== undefined && options.conversationReplayActive\n ? await prepareConversationReplayInput({\n items: state.items.slice(state.replayStartIndex),\n caps: modelCaps,\n agentName: state.agentName,\n conversationId: state.conversationId,\n conversationReplay: options.conversationReplay,\n })\n : projectConversationItemsToInput(\n state.items.slice(state.replayStartIndex),\n modelCaps,\n );\n\n const stopDecision: LoopStopDecision = evaluateStopConditions({\n maxSteps: state.maxSteps,\n stepIndex: state.stepIndex,\n steps: state.steps,\n messages: stopMessages,\n lastStep: stepResult,\n stopWhen: options.agent.stopWhen,\n context: options.context,\n });\n\n await options.emit({\n type: Events.STEP_FINISH,\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n toolCallCount: toolCalls.length,\n terminationReason: stopDecision.stop ? stopDecision.reason : undefined,\n timestamp: Date.now(),\n conversationId: state.conversationId,\n });\n\n await applyOnStepFinish({\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n result: stepResult,\n conversationId: state.conversationId,\n context: options.context,\n onStepFinish: options.agent.onStepFinish,\n });\n\n if (stopDecision.stop) {\n return {\n response,\n items: state.items,\n };\n }\n\n state.stepIndex += 1;\n } catch (error) {\n const wrapped =\n error instanceof BetterAgentError\n ? error.at({ at: traceBase })\n : BetterAgentError.wrap({\n err: error,\n message: stepErrorMessage,\n opts: {\n code: \"INTERNAL\",\n trace: [{ at: traceBase }],\n },\n });\n await options.emit({\n type: Events.STEP_ERROR,\n runId: state.runId,\n agentName: state.agentName,\n stepIndex: state.stepIndex,\n maxSteps: state.maxSteps,\n error: wrapped,\n timestamp: Date.now(),\n conversationId: state.conversationId,\n });\n throw wrapped;\n }\n }\n } finally {\n await runCleanup();\n await pluginToolsResult.runCleanup();\n }\n};\n"],"mappings":"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"}