@agtlantis/core 0.5.0 → 0.5.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 (265) hide show
  1. package/dist/errors/index.d.ts +4 -0
  2. package/dist/errors/index.d.ts.map +1 -0
  3. package/dist/errors/index.js +3 -0
  4. package/dist/errors/index.js.map +1 -0
  5. package/dist/errors/types.d.ts +69 -0
  6. package/dist/errors/types.d.ts.map +1 -0
  7. package/dist/errors/types.js +119 -0
  8. package/dist/errors/types.js.map +1 -0
  9. package/dist/errors/utils.d.ts +17 -0
  10. package/dist/errors/utils.d.ts.map +1 -0
  11. package/dist/errors/utils.js +16 -0
  12. package/dist/errors/utils.js.map +1 -0
  13. package/dist/execution/constants.d.ts +7 -0
  14. package/dist/execution/constants.d.ts.map +1 -0
  15. package/dist/execution/constants.js +7 -0
  16. package/dist/execution/constants.js.map +1 -0
  17. package/dist/execution/index.d.ts +8 -0
  18. package/dist/execution/index.d.ts.map +1 -0
  19. package/dist/execution/index.js +7 -0
  20. package/dist/execution/index.js.map +1 -0
  21. package/dist/execution/mapping.d.ts +17 -0
  22. package/dist/execution/mapping.d.ts.map +1 -0
  23. package/dist/execution/mapping.js +197 -0
  24. package/dist/execution/mapping.js.map +1 -0
  25. package/dist/execution/shared.d.ts +86 -0
  26. package/dist/execution/shared.d.ts.map +1 -0
  27. package/dist/execution/shared.js +100 -0
  28. package/dist/execution/shared.js.map +1 -0
  29. package/dist/execution/simple-host.d.ts +56 -0
  30. package/dist/execution/simple-host.d.ts.map +1 -0
  31. package/dist/execution/simple-host.js +126 -0
  32. package/dist/execution/simple-host.js.map +1 -0
  33. package/dist/execution/streaming-host.d.ts +79 -0
  34. package/dist/execution/streaming-host.d.ts.map +1 -0
  35. package/dist/execution/streaming-host.js +276 -0
  36. package/dist/execution/streaming-host.js.map +1 -0
  37. package/dist/execution/testing/fixtures.d.ts +67 -0
  38. package/dist/execution/testing/fixtures.d.ts.map +1 -0
  39. package/dist/execution/testing/fixtures.js +145 -0
  40. package/dist/execution/testing/fixtures.js.map +1 -0
  41. package/dist/execution/testing/helpers.d.ts +218 -0
  42. package/dist/execution/testing/helpers.d.ts.map +1 -0
  43. package/dist/execution/testing/helpers.js +327 -0
  44. package/dist/execution/testing/helpers.js.map +1 -0
  45. package/dist/execution/testing/host-configs.d.ts +56 -0
  46. package/dist/execution/testing/host-configs.d.ts.map +1 -0
  47. package/dist/execution/testing/host-configs.js +154 -0
  48. package/dist/execution/testing/host-configs.js.map +1 -0
  49. package/dist/execution/testing/vitest-assertions.d.ts +102 -0
  50. package/dist/execution/testing/vitest-assertions.d.ts.map +1 -0
  51. package/dist/execution/testing/vitest-assertions.js +142 -0
  52. package/dist/execution/testing/vitest-assertions.js.map +1 -0
  53. package/dist/execution/types.d.ts +432 -0
  54. package/dist/execution/types.d.ts.map +1 -0
  55. package/dist/execution/types.js +2 -0
  56. package/dist/execution/types.js.map +1 -0
  57. package/dist/execution/utils.d.ts +68 -0
  58. package/dist/execution/utils.d.ts.map +1 -0
  59. package/dist/execution/utils.js +93 -0
  60. package/dist/execution/utils.js.map +1 -0
  61. package/dist/index.d.ts +10 -1506
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +9 -2979
  64. package/dist/index.js.map +1 -1
  65. package/dist/observability/index.d.ts +4 -0
  66. package/dist/observability/index.d.ts.map +1 -0
  67. package/dist/observability/index.js +2 -0
  68. package/dist/observability/index.js.map +1 -0
  69. package/dist/observability/logger.d.ts +161 -0
  70. package/dist/observability/logger.d.ts.map +1 -0
  71. package/dist/observability/logger.js +31 -0
  72. package/dist/observability/logger.js.map +1 -0
  73. package/dist/observability/types.d.ts +46 -0
  74. package/dist/observability/types.d.ts.map +1 -0
  75. package/dist/observability/types.js +2 -0
  76. package/dist/observability/types.js.map +1 -0
  77. package/dist/patterns/index.d.ts +2 -0
  78. package/dist/patterns/index.d.ts.map +1 -0
  79. package/dist/patterns/index.js +2 -0
  80. package/dist/patterns/index.js.map +1 -0
  81. package/dist/patterns/progressive/index.d.ts +2 -0
  82. package/dist/patterns/progressive/index.d.ts.map +1 -0
  83. package/dist/patterns/progressive/index.js +2 -0
  84. package/dist/patterns/progressive/index.js.map +1 -0
  85. package/dist/patterns/progressive/progressive-pattern.d.ts +174 -0
  86. package/dist/patterns/progressive/progressive-pattern.d.ts.map +1 -0
  87. package/dist/patterns/progressive/progressive-pattern.js +260 -0
  88. package/dist/patterns/progressive/progressive-pattern.js.map +1 -0
  89. package/dist/pricing/calculator.d.ts +71 -0
  90. package/dist/pricing/calculator.d.ts.map +1 -0
  91. package/dist/pricing/calculator.js +127 -0
  92. package/dist/pricing/calculator.js.map +1 -0
  93. package/dist/pricing/config.d.ts +61 -0
  94. package/dist/pricing/config.d.ts.map +1 -0
  95. package/dist/pricing/config.js +87 -0
  96. package/dist/pricing/config.js.map +1 -0
  97. package/dist/pricing/defaults.d.ts +29 -0
  98. package/dist/pricing/defaults.d.ts.map +1 -0
  99. package/dist/pricing/defaults.js +139 -0
  100. package/dist/pricing/defaults.js.map +1 -0
  101. package/dist/pricing/index.d.ts +40 -0
  102. package/dist/pricing/index.d.ts.map +1 -0
  103. package/dist/pricing/index.js +43 -0
  104. package/dist/pricing/index.js.map +1 -0
  105. package/dist/pricing/types.d.ts +96 -0
  106. package/dist/pricing/types.d.ts.map +1 -0
  107. package/dist/pricing/types.js +7 -0
  108. package/dist/pricing/types.js.map +1 -0
  109. package/dist/pricing/validator.d.ts +55 -0
  110. package/dist/pricing/validator.d.ts.map +1 -0
  111. package/dist/pricing/validator.js +84 -0
  112. package/dist/pricing/validator.js.map +1 -0
  113. package/dist/prompt/errors.d.ts +112 -0
  114. package/dist/prompt/errors.d.ts.map +1 -0
  115. package/dist/prompt/errors.js +175 -0
  116. package/dist/prompt/errors.js.map +1 -0
  117. package/dist/prompt/file-prompt-repository.d.ts +80 -0
  118. package/dist/prompt/file-prompt-repository.d.ts.map +1 -0
  119. package/dist/prompt/file-prompt-repository.js +287 -0
  120. package/dist/prompt/file-prompt-repository.js.map +1 -0
  121. package/dist/prompt/index.d.ts +34 -0
  122. package/dist/prompt/index.d.ts.map +1 -0
  123. package/dist/prompt/index.js +37 -0
  124. package/dist/prompt/index.js.map +1 -0
  125. package/dist/prompt/prompt-template.d.ts +64 -0
  126. package/dist/prompt/prompt-template.d.ts.map +1 -0
  127. package/dist/prompt/prompt-template.js +90 -0
  128. package/dist/prompt/prompt-template.js.map +1 -0
  129. package/dist/prompt/template.d.ts +23 -0
  130. package/dist/prompt/template.d.ts.map +1 -0
  131. package/dist/prompt/template.js +70 -0
  132. package/dist/prompt/template.js.map +1 -0
  133. package/dist/prompt/types.d.ts +148 -0
  134. package/dist/prompt/types.d.ts.map +1 -0
  135. package/dist/prompt/types.js +7 -0
  136. package/dist/prompt/types.js.map +1 -0
  137. package/dist/provider/base-provider.d.ts +41 -0
  138. package/dist/provider/base-provider.d.ts.map +1 -0
  139. package/dist/provider/base-provider.js +21 -0
  140. package/dist/provider/base-provider.js.map +1 -0
  141. package/dist/provider/file-cache.d.ts +14 -0
  142. package/dist/provider/file-cache.d.ts.map +1 -0
  143. package/dist/provider/file-cache.js +29 -0
  144. package/dist/provider/file-cache.js.map +1 -0
  145. package/dist/provider/file-source.d.ts +32 -0
  146. package/dist/provider/file-source.d.ts.map +1 -0
  147. package/dist/provider/file-source.js +180 -0
  148. package/dist/provider/file-source.js.map +1 -0
  149. package/dist/provider/google/factory.d.ts +107 -0
  150. package/dist/provider/google/factory.d.ts.map +1 -0
  151. package/dist/provider/google/factory.js +143 -0
  152. package/dist/provider/google/factory.js.map +1 -0
  153. package/dist/provider/google/file-manager.d.ts +14 -0
  154. package/dist/provider/google/file-manager.d.ts.map +1 -0
  155. package/dist/provider/google/file-manager.js +183 -0
  156. package/dist/provider/google/file-manager.js.map +1 -0
  157. package/dist/provider/google/index.d.ts +8 -0
  158. package/dist/provider/google/index.d.ts.map +1 -0
  159. package/dist/provider/google/index.js +10 -0
  160. package/dist/provider/google/index.js.map +1 -0
  161. package/dist/provider/hash.d.ts +3 -0
  162. package/dist/provider/hash.d.ts.map +1 -0
  163. package/dist/provider/hash.js +34 -0
  164. package/dist/provider/hash.js.map +1 -0
  165. package/dist/provider/index.d.ts +9 -0
  166. package/dist/provider/index.d.ts.map +1 -0
  167. package/dist/provider/index.js +11 -0
  168. package/dist/provider/index.js.map +1 -0
  169. package/dist/provider/noop-file-manager.d.ts +9 -0
  170. package/dist/provider/noop-file-manager.d.ts.map +1 -0
  171. package/dist/provider/noop-file-manager.js +28 -0
  172. package/dist/provider/noop-file-manager.js.map +1 -0
  173. package/dist/provider/openai/factory.d.ts +67 -0
  174. package/dist/provider/openai/factory.d.ts.map +1 -0
  175. package/dist/provider/openai/factory.js +95 -0
  176. package/dist/provider/openai/factory.js.map +1 -0
  177. package/dist/provider/openai/index.d.ts +7 -0
  178. package/dist/provider/openai/index.d.ts.map +1 -0
  179. package/dist/provider/openai/index.js +7 -0
  180. package/dist/provider/openai/index.js.map +1 -0
  181. package/dist/provider/types.d.ts +105 -0
  182. package/dist/provider/types.d.ts.map +1 -0
  183. package/dist/provider/types.js +19 -0
  184. package/dist/provider/types.js.map +1 -0
  185. package/dist/session/index.d.ts +7 -0
  186. package/dist/session/index.d.ts.map +1 -0
  187. package/dist/session/index.js +5 -0
  188. package/dist/session/index.js.map +1 -0
  189. package/dist/session/simple-session.d.ts +98 -0
  190. package/dist/session/simple-session.d.ts.map +1 -0
  191. package/dist/session/simple-session.js +299 -0
  192. package/dist/session/simple-session.js.map +1 -0
  193. package/dist/session/streaming-session.d.ts +90 -0
  194. package/dist/session/streaming-session.d.ts.map +1 -0
  195. package/dist/session/streaming-session.js +151 -0
  196. package/dist/session/streaming-session.js.map +1 -0
  197. package/dist/session/test-utils.d.ts +19 -0
  198. package/dist/session/test-utils.d.ts.map +1 -0
  199. package/dist/session/test-utils.js +65 -0
  200. package/dist/session/test-utils.js.map +1 -0
  201. package/dist/session/types.d.ts +219 -0
  202. package/dist/session/types.d.ts.map +1 -0
  203. package/dist/session/types.js +181 -0
  204. package/dist/session/types.js.map +1 -0
  205. package/dist/session/usage-extractors.d.ts +7 -0
  206. package/dist/session/usage-extractors.d.ts.map +1 -0
  207. package/dist/session/usage-extractors.js +71 -0
  208. package/dist/session/usage-extractors.js.map +1 -0
  209. package/dist/testing/fixtures.d.ts +34 -0
  210. package/dist/testing/fixtures.d.ts.map +1 -0
  211. package/dist/testing/fixtures.js +65 -0
  212. package/dist/testing/fixtures.js.map +1 -0
  213. package/dist/testing/helpers.d.ts +20 -0
  214. package/dist/testing/helpers.d.ts.map +1 -0
  215. package/dist/testing/helpers.js +32 -0
  216. package/dist/testing/helpers.js.map +1 -0
  217. package/dist/testing/index.d.ts +7 -519
  218. package/dist/testing/index.d.ts.map +1 -0
  219. package/dist/testing/index.js +21 -2123
  220. package/dist/testing/index.js.map +1 -1
  221. package/dist/testing/mock-provider.d.ts +79 -0
  222. package/dist/testing/mock-provider.d.ts.map +1 -0
  223. package/dist/testing/mock-provider.js +152 -0
  224. package/dist/testing/mock-provider.js.map +1 -0
  225. package/dist/testing/mock.d.ts +29 -0
  226. package/dist/testing/mock.d.ts.map +1 -0
  227. package/dist/testing/mock.js +154 -0
  228. package/dist/testing/mock.js.map +1 -0
  229. package/dist/testing/test-execution.d.ts +14 -0
  230. package/dist/testing/test-execution.d.ts.map +1 -0
  231. package/dist/testing/test-execution.js +108 -0
  232. package/dist/testing/test-execution.js.map +1 -0
  233. package/dist/utils/deep-merge.d.ts +6 -0
  234. package/dist/utils/deep-merge.d.ts.map +1 -0
  235. package/dist/utils/deep-merge.js +24 -0
  236. package/dist/utils/deep-merge.js.map +1 -0
  237. package/dist/validation/errors.d.ts +28 -0
  238. package/dist/validation/errors.d.ts.map +1 -0
  239. package/dist/validation/errors.js +39 -0
  240. package/dist/validation/errors.js.map +1 -0
  241. package/dist/validation/index.d.ts +5 -0
  242. package/dist/validation/index.d.ts.map +1 -0
  243. package/dist/validation/index.js +4 -0
  244. package/dist/validation/index.js.map +1 -0
  245. package/dist/validation/types.d.ts +49 -0
  246. package/dist/validation/types.d.ts.map +1 -0
  247. package/dist/validation/types.js +2 -0
  248. package/dist/validation/types.js.map +1 -0
  249. package/dist/validation/validation-history.d.ts +12 -0
  250. package/dist/validation/validation-history.d.ts.map +1 -0
  251. package/dist/validation/validation-history.js +29 -0
  252. package/dist/validation/validation-history.js.map +1 -0
  253. package/dist/validation/with-validation.d.ts +38 -0
  254. package/dist/validation/with-validation.d.ts.map +1 -0
  255. package/dist/validation/with-validation.js +58 -0
  256. package/dist/validation/with-validation.js.map +1 -0
  257. package/package.json +72 -76
  258. package/dist/base-provider-2TTw5HAa.d.cts +0 -1254
  259. package/dist/base-provider-2TTw5HAa.d.ts +0 -1254
  260. package/dist/index.cjs +0 -3085
  261. package/dist/index.cjs.map +0 -1
  262. package/dist/index.d.cts +0 -1506
  263. package/dist/testing/index.cjs +0 -2167
  264. package/dist/testing/index.cjs.map +0 -1
  265. package/dist/testing/index.d.cts +0 -520
@@ -1,2167 +0,0 @@
1
- 'use strict';
2
-
3
- var test = require('ai/test');
4
- var ai = require('ai');
5
-
6
- // src/session/usage-extractors.ts
7
- function mergeUsages(usages) {
8
- if (usages.length === 0) {
9
- return createZeroUsage();
10
- }
11
- let inputTokens = 0;
12
- let outputTokens = 0;
13
- let totalTokens = 0;
14
- let noCacheTokens = 0;
15
- let cacheReadTokens = 0;
16
- let cacheWriteTokens = 0;
17
- let textTokens = 0;
18
- let reasoningTokens = 0;
19
- for (const usage of usages) {
20
- inputTokens += usage.inputTokens ?? 0;
21
- outputTokens += usage.outputTokens ?? 0;
22
- totalTokens += usage.totalTokens ?? 0;
23
- noCacheTokens += usage.inputTokenDetails?.noCacheTokens ?? 0;
24
- cacheReadTokens += usage.inputTokenDetails?.cacheReadTokens ?? 0;
25
- cacheWriteTokens += usage.inputTokenDetails?.cacheWriteTokens ?? 0;
26
- textTokens += usage.outputTokenDetails?.textTokens ?? 0;
27
- reasoningTokens += usage.outputTokenDetails?.reasoningTokens ?? 0;
28
- }
29
- return {
30
- inputTokens,
31
- outputTokens,
32
- totalTokens,
33
- inputTokenDetails: {
34
- noCacheTokens,
35
- cacheReadTokens,
36
- cacheWriteTokens
37
- },
38
- outputTokenDetails: {
39
- textTokens,
40
- reasoningTokens
41
- }
42
- };
43
- }
44
- function createZeroUsage() {
45
- return {
46
- inputTokens: 0,
47
- outputTokens: 0,
48
- totalTokens: 0,
49
- inputTokenDetails: {
50
- noCacheTokens: 0,
51
- cacheReadTokens: 0,
52
- cacheWriteTokens: 0
53
- },
54
- outputTokenDetails: {
55
- textTokens: 0,
56
- reasoningTokens: 0
57
- }
58
- };
59
- }
60
-
61
- // src/session/types.ts
62
- var SessionSummary = class _SessionSummary {
63
- totalLLMUsage;
64
- llmCallCount;
65
- llmCalls;
66
- toolCalls;
67
- customRecords;
68
- llmCost;
69
- additionalCosts;
70
- metadata;
71
- /** Cost breakdown by model. Key format: `${provider}/${model}` */
72
- costByModel;
73
- startTime;
74
- constructor(data, startTime) {
75
- this.startTime = startTime;
76
- this.totalLLMUsage = data.totalLLMUsage;
77
- this.llmCallCount = data.llmCalls.length;
78
- this.llmCalls = Object.freeze([...data.llmCalls]);
79
- this.toolCalls = Object.freeze([...data.toolCalls]);
80
- this.customRecords = Object.freeze([...data.customRecords]);
81
- this.llmCost = data.llmCost;
82
- this.additionalCosts = Object.freeze([...data.additionalCosts]);
83
- this.metadata = Object.freeze({ ...data.metadata });
84
- this.costByModel = Object.freeze({ ...data.costByModel });
85
- }
86
- /**
87
- * Total duration from session start to now (computed dynamically).
88
- */
89
- get totalDuration() {
90
- return Date.now() - this.startTime;
91
- }
92
- /**
93
- * Creates an empty SessionSummary.
94
- */
95
- static empty(startTime) {
96
- return new _SessionSummary(
97
- {
98
- totalLLMUsage: createZeroUsage(),
99
- llmCalls: [],
100
- toolCalls: [],
101
- customRecords: [],
102
- llmCost: 0,
103
- additionalCosts: [],
104
- metadata: {},
105
- costByModel: {}
106
- },
107
- startTime
108
- );
109
- }
110
- /**
111
- * Creates a SessionSummary with custom data for testing purposes.
112
- * @internal For testing only - do not use in production code.
113
- */
114
- static forTest(data) {
115
- const startTime = data.startTime ?? Date.now() - 1e3;
116
- return new _SessionSummary(
117
- {
118
- totalLLMUsage: data.totalLLMUsage ?? createZeroUsage(),
119
- llmCalls: data.llmCalls ?? [],
120
- toolCalls: data.toolCalls ?? [],
121
- customRecords: data.customRecords ?? [],
122
- llmCost: data.llmCost ?? 0,
123
- additionalCosts: data.additionalCosts ?? [],
124
- metadata: data.metadata ?? {},
125
- costByModel: data.costByModel ?? {}
126
- },
127
- startTime
128
- );
129
- }
130
- /**
131
- * Total cost of all additional (non-LLM) operations.
132
- */
133
- get totalAdditionalCost() {
134
- return this.additionalCosts.reduce((sum, c) => sum + c.cost, 0);
135
- }
136
- /**
137
- * Total cost including LLM and additional costs.
138
- */
139
- get totalCost() {
140
- return this.llmCost + this.totalAdditionalCost;
141
- }
142
- /**
143
- * Returns a new SessionSummary with an LLM call added.
144
- */
145
- withLLMCall(call, newLlmCost, newCostByModel, newTotalUsage) {
146
- return new _SessionSummary(
147
- {
148
- totalLLMUsage: newTotalUsage,
149
- llmCalls: [...this.llmCalls, call],
150
- toolCalls: [...this.toolCalls],
151
- customRecords: [...this.customRecords],
152
- llmCost: newLlmCost,
153
- additionalCosts: [...this.additionalCosts],
154
- metadata: { ...this.metadata },
155
- costByModel: newCostByModel
156
- },
157
- this.startTime
158
- );
159
- }
160
- /**
161
- * Returns a new SessionSummary with an additional cost recorded.
162
- */
163
- withAdditionalCost(cost) {
164
- return new _SessionSummary(
165
- {
166
- totalLLMUsage: this.totalLLMUsage,
167
- llmCalls: [...this.llmCalls],
168
- toolCalls: [...this.toolCalls],
169
- customRecords: [...this.customRecords],
170
- llmCost: this.llmCost,
171
- additionalCosts: [...this.additionalCosts, cost],
172
- metadata: { ...this.metadata },
173
- costByModel: { ...this.costByModel }
174
- },
175
- this.startTime
176
- );
177
- }
178
- /**
179
- * Returns a new SessionSummary with metadata updated.
180
- */
181
- withMetadata(key, value) {
182
- return new _SessionSummary(
183
- {
184
- totalLLMUsage: this.totalLLMUsage,
185
- llmCalls: [...this.llmCalls],
186
- toolCalls: [...this.toolCalls],
187
- customRecords: [...this.customRecords],
188
- llmCost: this.llmCost,
189
- additionalCosts: [...this.additionalCosts],
190
- metadata: { ...this.metadata, [key]: value },
191
- costByModel: { ...this.costByModel }
192
- },
193
- this.startTime
194
- );
195
- }
196
- /**
197
- * Returns a new SessionSummary with a tool call added.
198
- */
199
- withToolCall(call) {
200
- return new _SessionSummary(
201
- {
202
- totalLLMUsage: this.totalLLMUsage,
203
- llmCalls: [...this.llmCalls],
204
- toolCalls: [...this.toolCalls, call],
205
- customRecords: [...this.customRecords],
206
- llmCost: this.llmCost,
207
- additionalCosts: [...this.additionalCosts],
208
- metadata: { ...this.metadata },
209
- costByModel: { ...this.costByModel }
210
- },
211
- this.startTime
212
- );
213
- }
214
- /**
215
- * Returns a new SessionSummary with a custom record added.
216
- */
217
- withCustomRecord(record) {
218
- return new _SessionSummary(
219
- {
220
- totalLLMUsage: this.totalLLMUsage,
221
- llmCalls: [...this.llmCalls],
222
- toolCalls: [...this.toolCalls],
223
- customRecords: [...this.customRecords, record],
224
- llmCost: this.llmCost,
225
- additionalCosts: [...this.additionalCosts],
226
- metadata: { ...this.metadata },
227
- costByModel: { ...this.costByModel }
228
- },
229
- this.startTime
230
- );
231
- }
232
- /**
233
- * Serializes to plain JSON object for database storage.
234
- */
235
- toJSON() {
236
- return {
237
- totalDuration: this.totalDuration,
238
- totalLLMUsage: this.totalLLMUsage,
239
- llmCallCount: this.llmCallCount,
240
- llmCalls: [...this.llmCalls],
241
- toolCalls: [...this.toolCalls],
242
- customRecords: [...this.customRecords],
243
- llmCost: this.llmCost,
244
- additionalCosts: [...this.additionalCosts],
245
- metadata: { ...this.metadata },
246
- costByModel: { ...this.costByModel },
247
- totalCost: this.totalCost,
248
- totalAdditionalCost: this.totalAdditionalCost
249
- };
250
- }
251
- };
252
-
253
- // src/testing/fixtures.ts
254
- var TEST_API_KEY = "test-api-key";
255
- function createMockUsage(overrides) {
256
- const inputTokens = overrides?.inputTokens ?? 10;
257
- const outputTokens = overrides?.outputTokens ?? 5;
258
- return {
259
- inputTokens,
260
- outputTokens,
261
- totalTokens: overrides?.totalTokens ?? inputTokens + outputTokens,
262
- inputTokenDetails: {
263
- cacheReadTokens: void 0,
264
- cacheWriteTokens: void 0,
265
- noCacheTokens: void 0,
266
- ...overrides?.inputTokenDetails
267
- },
268
- outputTokenDetails: {
269
- textTokens: void 0,
270
- reasoningTokens: void 0,
271
- ...overrides?.outputTokenDetails
272
- }
273
- };
274
- }
275
- function createTestEvent(type, overrides) {
276
- return {
277
- type,
278
- ...overrides
279
- };
280
- }
281
- function createDummyLLMCall() {
282
- return {
283
- startTime: Date.now() - 100,
284
- endTime: Date.now(),
285
- duration: 100,
286
- usage: createMockUsage(),
287
- type: "generateText",
288
- model: "test-model",
289
- provider: "openai"
290
- };
291
- }
292
- function createMockSessionSummary(overrides) {
293
- let startTime = overrides?.startTime;
294
- if (startTime === void 0 && overrides?.totalDuration !== void 0) {
295
- startTime = Date.now() - overrides.totalDuration;
296
- }
297
- const llmCost = overrides?.llmCost ?? overrides?.totalCost ?? 0;
298
- let llmCalls = overrides?.llmCalls;
299
- if (!llmCalls && overrides?.llmCallCount !== void 0) {
300
- llmCalls = Array.from({ length: overrides.llmCallCount }, () => createDummyLLMCall());
301
- }
302
- return SessionSummary.forTest({
303
- startTime,
304
- totalLLMUsage: overrides?.totalLLMUsage ?? createMockUsage(),
305
- llmCalls: llmCalls ?? [],
306
- toolCalls: overrides?.toolCalls ?? [],
307
- customRecords: overrides?.customRecords ?? [],
308
- llmCost,
309
- additionalCosts: overrides?.additionalCosts ?? [],
310
- metadata: overrides?.metadata ?? {},
311
- costByModel: overrides?.costByModel ?? {}
312
- });
313
- }
314
-
315
- // src/testing/helpers.ts
316
- async function collectEvents(execution) {
317
- const events = [];
318
- const iterable = "stream" in execution && typeof execution.stream === "function" ? execution.stream() : execution;
319
- for await (const event of iterable) {
320
- events.push(event);
321
- }
322
- return events;
323
- }
324
- async function consumeExecution(execution) {
325
- const iterable = "stream" in execution && typeof execution.stream === "function" ? execution.stream() : execution;
326
- for await (const _event of iterable) {
327
- }
328
- }
329
- function expectFileManagerInterface(obj) {
330
- const fm = obj;
331
- const requiredMethods = ["upload", "delete", "clear", "getUploadedFiles"];
332
- for (const method of requiredMethods) {
333
- if (typeof fm[method] !== "function") {
334
- throw new Error(
335
- `Expected FileManager.${method} to be a function, got ${typeof fm[method]}`
336
- );
337
- }
338
- }
339
- }
340
-
341
- // src/observability/logger.ts
342
- var noopLogger = {};
343
-
344
- // src/execution/constants.ts
345
- var ERRORS = {
346
- NO_RESULT: "No result available"};
347
-
348
- // src/execution/utils.ts
349
- function combineSignals(...signals) {
350
- const controller = new AbortController();
351
- for (const signal of signals) {
352
- if (signal.aborted) {
353
- controller.abort(signal.reason);
354
- return controller.signal;
355
- }
356
- signal.addEventListener("abort", () => controller.abort(signal.reason), {
357
- once: true
358
- });
359
- }
360
- return controller.signal;
361
- }
362
- var Deferred = class {
363
- promise;
364
- resolve;
365
- reject;
366
- constructor() {
367
- let res;
368
- let rej;
369
- this.promise = new Promise((resolve, reject) => {
370
- res = resolve;
371
- rej = reject;
372
- });
373
- this.resolve = res;
374
- this.reject = rej;
375
- }
376
- };
377
-
378
- // src/execution/shared.ts
379
- function isAbortError(error, signal) {
380
- if (error instanceof Error && error.name === "AbortError") {
381
- return true;
382
- }
383
- return signal.aborted;
384
- }
385
- function normalizeError(error) {
386
- return error instanceof Error ? error : new Error(String(error));
387
- }
388
- function createHookRunner(runHooks) {
389
- let ran = false;
390
- return {
391
- ensureRun: async () => {
392
- if (!ran) {
393
- ran = true;
394
- await runHooks();
395
- }
396
- },
397
- hasRun: () => ran
398
- };
399
- }
400
-
401
- // src/execution/streaming-host.ts
402
- var StreamingExecutionHost = class {
403
- constructor(createSession, generator, userSignal) {
404
- this.createSession = createSession;
405
- this.generator = generator;
406
- this.effectiveSignal = userSignal ? combineSignals(userSignal, this.abortController.signal) : this.abortController.signal;
407
- this.consumerPromise = this.startConsuming();
408
- }
409
- abortController = new AbortController();
410
- effectiveSignal;
411
- consumerPromise;
412
- eventBuffer = [];
413
- subscribers = /* @__PURE__ */ new Set();
414
- completed = false;
415
- cleaned = false;
416
- hookRunner = null;
417
- cancelRequested = false;
418
- extractedOutcome = null;
419
- extractedSummary = null;
420
- hasDataField(event) {
421
- return "data" in event && event.data !== void 0;
422
- }
423
- hasSummaryField(event) {
424
- return "summary" in event && event.summary !== void 0;
425
- }
426
- hasErrorField(event) {
427
- return "error" in event && event.error instanceof Error;
428
- }
429
- extractResultAndMetadata(event) {
430
- const isCompleteOrError = event.type === "complete" || event.type === "error";
431
- if (!isCompleteOrError) {
432
- return;
433
- }
434
- if (this.hasErrorField(event)) {
435
- this.extractedOutcome = { type: "error", error: event.error };
436
- } else if (this.hasDataField(event)) {
437
- this.extractedOutcome = { type: "result", value: event.data };
438
- }
439
- if (this.hasSummaryField(event)) {
440
- this.extractedSummary = event.summary;
441
- }
442
- }
443
- notifySubscribers(event) {
444
- this.subscribers.forEach((fn) => fn(event));
445
- }
446
- async startConsuming() {
447
- const session = this.createSession(this.effectiveSignal);
448
- this.hookRunner = createHookRunner(() => session.runOnDoneHooks());
449
- const gen = this.generator(session);
450
- try {
451
- let next = await gen.next();
452
- while (!next.done) {
453
- this.eventBuffer.push(next.value);
454
- this.notifySubscribers(next.value);
455
- const isTerminal = next.value.type === "complete" || next.value.type === "error";
456
- if (isTerminal) {
457
- this.extractResultAndMetadata(next.value);
458
- this.abortController.abort();
459
- break;
460
- }
461
- if (this.abortController.signal.aborted) {
462
- break;
463
- }
464
- next = await gen.next();
465
- }
466
- if (next.done && next.value !== void 0) {
467
- const finalEvent = await Promise.resolve(next.value);
468
- this.eventBuffer.push(finalEvent);
469
- this.notifySubscribers(finalEvent);
470
- this.extractResultAndMetadata(finalEvent);
471
- const isTerminal = finalEvent.type === "complete" || finalEvent.type === "error";
472
- if (isTerminal) {
473
- this.abortController.abort();
474
- }
475
- }
476
- return this.buildResult(session);
477
- } catch (error) {
478
- const errorObj = normalizeError(error);
479
- if (isAbortError(error, this.abortController.signal)) {
480
- return {
481
- success: false,
482
- aborted: true,
483
- error: errorObj,
484
- summary: await session.getSummary()
485
- };
486
- }
487
- const errorEvent = await session.fail(errorObj);
488
- this.eventBuffer.push(errorEvent);
489
- this.notifySubscribers(errorEvent);
490
- this.extractResultAndMetadata(errorEvent);
491
- this.abortController.abort();
492
- return this.buildResult(session);
493
- } finally {
494
- this.completed = true;
495
- await this.hookRunner?.ensureRun();
496
- await gen.return(void 0);
497
- }
498
- }
499
- async buildResult(session) {
500
- const summary = this.extractedSummary ?? await session.getSummary();
501
- if (this.extractedOutcome?.type === "error") {
502
- return {
503
- success: false,
504
- aborted: false,
505
- error: this.extractedOutcome.error,
506
- summary
507
- };
508
- }
509
- if (this.extractedOutcome?.type === "result") {
510
- return {
511
- success: true,
512
- result: this.extractedOutcome.value,
513
- summary
514
- };
515
- }
516
- return {
517
- success: false,
518
- aborted: true,
519
- error: new Error(ERRORS.NO_RESULT),
520
- summary
521
- };
522
- }
523
- /**
524
- * Get the event stream.
525
- * Returns buffered events first, then real-time events.
526
- * Can be called multiple times - replays buffer each time.
527
- */
528
- async *stream() {
529
- let index = 0;
530
- while (index < this.eventBuffer.length) {
531
- yield this.eventBuffer[index++];
532
- }
533
- if (this.completed) {
534
- return;
535
- }
536
- const queue = [];
537
- let pending = new Deferred();
538
- const subscriber = (event) => {
539
- queue.push(event);
540
- pending.resolve();
541
- };
542
- this.subscribers.add(subscriber);
543
- try {
544
- while (!this.completed || queue.length > 0) {
545
- if (queue.length > 0) {
546
- yield queue.shift();
547
- } else if (!this.completed) {
548
- await pending.promise;
549
- pending = new Deferred();
550
- }
551
- }
552
- } finally {
553
- this.subscribers.delete(subscriber);
554
- }
555
- }
556
- cancel() {
557
- this.cancelRequested = true;
558
- this.abortController.abort();
559
- }
560
- async cleanup() {
561
- if (this.cleaned) {
562
- return;
563
- }
564
- this.cleaned = true;
565
- if (!this.completed) {
566
- this.cancel();
567
- await this.consumerPromise.catch(() => {
568
- });
569
- }
570
- this.subscribers.clear();
571
- await this.hookRunner?.ensureRun();
572
- }
573
- async [Symbol.asyncDispose]() {
574
- await this.cleanup();
575
- }
576
- /**
577
- * Get the execution result with status, summary, and all events.
578
- * Never throws - returns a discriminated union with status.
579
- */
580
- async result() {
581
- const internal = await this.consumerPromise;
582
- const events = Object.freeze([...this.eventBuffer]);
583
- if (internal.success) {
584
- return {
585
- status: "succeeded",
586
- value: internal.result,
587
- summary: internal.summary,
588
- events
589
- };
590
- }
591
- if (this.cancelRequested || internal.aborted) {
592
- return {
593
- status: "canceled",
594
- summary: internal.summary,
595
- events
596
- };
597
- }
598
- return {
599
- status: "failed",
600
- error: internal.error,
601
- summary: internal.summary,
602
- events
603
- };
604
- }
605
- };
606
-
607
- // src/execution/simple-host.ts
608
- var SimpleExecutionHost = class {
609
- abortController = new AbortController();
610
- effectiveSignal;
611
- consumerPromise;
612
- cachedSession;
613
- startTime = Date.now();
614
- cancelRequested = false;
615
- constructor(createSession, fn, userSignal) {
616
- this.effectiveSignal = userSignal ? combineSignals(userSignal, this.abortController.signal) : this.abortController.signal;
617
- this.consumerPromise = this.execute(createSession, fn);
618
- }
619
- async execute(createSession, fn) {
620
- const session = createSession(this.effectiveSignal);
621
- this.cachedSession = session;
622
- const hookRunner = createHookRunner(() => session.runOnDoneHooks());
623
- session.notifyExecutionStart();
624
- try {
625
- const result = await fn(session);
626
- await session.notifyExecutionDone(result, this.startTime);
627
- return {
628
- success: true,
629
- result,
630
- summary: await session.getSummary()
631
- };
632
- } catch (error) {
633
- const errorObj = normalizeError(error);
634
- const isCancellation = isAbortError(error, this.abortController.signal);
635
- if (!isCancellation) {
636
- await session.notifyExecutionError(errorObj, this.startTime);
637
- }
638
- return {
639
- success: false,
640
- error: errorObj,
641
- aborted: isCancellation,
642
- summary: await session.getSummary()
643
- };
644
- } finally {
645
- await hookRunner.ensureRun();
646
- }
647
- }
648
- /**
649
- * Request cancellation of the execution.
650
- * Aborts the current LLM call if in progress.
651
- * No-op if execution already completed.
652
- */
653
- cancel() {
654
- this.cancelRequested = true;
655
- this.abortController.abort();
656
- }
657
- /**
658
- * Get the execution result with status and summary.
659
- * Never throws - returns a discriminated union with status.
660
- */
661
- async result() {
662
- const internal = await this.consumerPromise;
663
- if (internal.success) {
664
- return {
665
- status: "succeeded",
666
- value: internal.result,
667
- summary: internal.summary
668
- };
669
- }
670
- if (this.cancelRequested || internal.aborted) {
671
- return {
672
- status: "canceled",
673
- summary: internal.summary
674
- };
675
- }
676
- return {
677
- status: "failed",
678
- error: internal.error,
679
- summary: internal.summary
680
- };
681
- }
682
- /**
683
- * Cleanup resources.
684
- * For SimpleExecution, hooks are already run during execution,
685
- * so this is intentionally a no-op.
686
- */
687
- async cleanup() {
688
- }
689
- async [Symbol.asyncDispose]() {
690
- await this.cleanup();
691
- }
692
- };
693
-
694
- // src/provider/base-provider.ts
695
- var BaseProvider = class {
696
- streamingExecution(generator, options) {
697
- return new StreamingExecutionHost(
698
- (signal) => this.createStreamingSession(signal),
699
- generator,
700
- options?.signal
701
- );
702
- }
703
- /**
704
- * Execute a non-streaming function with cancellation support.
705
- * Returns immediately - execution starts in the background.
706
- */
707
- simpleExecution(fn, options) {
708
- return new SimpleExecutionHost(
709
- (signal) => this.createSimpleSession(signal),
710
- fn,
711
- options?.signal
712
- );
713
- }
714
- };
715
-
716
- // src/utils/deep-merge.ts
717
- function isPlainObject(value) {
718
- return typeof value === "object" && value !== null && !Array.isArray(value);
719
- }
720
- function deepMerge(...sources) {
721
- const result = {};
722
- for (const source of sources) {
723
- if (!source) continue;
724
- for (const key of Object.keys(source)) {
725
- const existing = result[key];
726
- const incoming = source[key];
727
- result[key] = isPlainObject(existing) && isPlainObject(incoming) ? deepMerge(existing, incoming) : incoming;
728
- }
729
- }
730
- return result;
731
- }
732
-
733
- // src/pricing/defaults.ts
734
- var OPENAI_PRICING = {
735
- "gpt-4o": { inputPricePerMillion: 2.5, outputPricePerMillion: 10 },
736
- "gpt-4o-mini": { inputPricePerMillion: 0.15, outputPricePerMillion: 0.6 },
737
- "gpt-4-turbo": { inputPricePerMillion: 10, outputPricePerMillion: 30 },
738
- "gpt-4-turbo-preview": {
739
- inputPricePerMillion: 10,
740
- outputPricePerMillion: 30
741
- },
742
- "gpt-4": { inputPricePerMillion: 30, outputPricePerMillion: 60 },
743
- "gpt-4-32k": { inputPricePerMillion: 60, outputPricePerMillion: 120 },
744
- "gpt-3.5-turbo": { inputPricePerMillion: 0.5, outputPricePerMillion: 1.5 },
745
- "gpt-3.5-turbo-16k": {
746
- inputPricePerMillion: 3,
747
- outputPricePerMillion: 4
748
- },
749
- "o1": { inputPricePerMillion: 15, outputPricePerMillion: 60 },
750
- "o1-mini": { inputPricePerMillion: 3, outputPricePerMillion: 12 },
751
- "o1-preview": { inputPricePerMillion: 15, outputPricePerMillion: 60 },
752
- "o3": { inputPricePerMillion: 20, outputPricePerMillion: 80 },
753
- "o3-mini": { inputPricePerMillion: 4, outputPricePerMillion: 16 }
754
- };
755
- var GOOGLE_PRICING = {
756
- "gemini-2.5-flash": {
757
- inputPricePerMillion: 0.15,
758
- outputPricePerMillion: 0.6,
759
- cachedInputPricePerMillion: 0.0375
760
- },
761
- "gemini-2.5-flash-lite": {
762
- inputPricePerMillion: 0.075,
763
- outputPricePerMillion: 0.3,
764
- cachedInputPricePerMillion: 0.01875
765
- },
766
- "gemini-2.5-pro": {
767
- inputPricePerMillion: 1.25,
768
- outputPricePerMillion: 10,
769
- cachedInputPricePerMillion: 0.3125
770
- },
771
- "gemini-2.0-flash": {
772
- inputPricePerMillion: 0.1,
773
- outputPricePerMillion: 0.4,
774
- cachedInputPricePerMillion: 0.025
775
- },
776
- "gemini-2.0-flash-lite": {
777
- inputPricePerMillion: 0.075,
778
- outputPricePerMillion: 0.3,
779
- cachedInputPricePerMillion: 0.01875
780
- },
781
- "gemini-1.5-pro": {
782
- inputPricePerMillion: 1.25,
783
- outputPricePerMillion: 5,
784
- cachedInputPricePerMillion: 0.3125
785
- },
786
- "gemini-1.5-flash": {
787
- inputPricePerMillion: 0.075,
788
- outputPricePerMillion: 0.3,
789
- cachedInputPricePerMillion: 0.01875
790
- },
791
- "gemini-1.5-flash-8b": {
792
- inputPricePerMillion: 0.0375,
793
- outputPricePerMillion: 0.15,
794
- cachedInputPricePerMillion: 0.01
795
- },
796
- "gemini-pro": { inputPricePerMillion: 0.5, outputPricePerMillion: 1.5 }
797
- };
798
- var ANTHROPIC_PRICING = {
799
- "claude-opus-4-5-20250514": {
800
- inputPricePerMillion: 15,
801
- outputPricePerMillion: 75,
802
- cachedInputPricePerMillion: 1.875
803
- },
804
- "claude-sonnet-4-20250514": {
805
- inputPricePerMillion: 3,
806
- outputPricePerMillion: 15,
807
- cachedInputPricePerMillion: 0.375
808
- },
809
- "claude-3-5-sonnet-20241022": {
810
- inputPricePerMillion: 3,
811
- outputPricePerMillion: 15,
812
- cachedInputPricePerMillion: 0.375
813
- },
814
- "claude-3-5-haiku-20241022": {
815
- inputPricePerMillion: 0.8,
816
- outputPricePerMillion: 4,
817
- cachedInputPricePerMillion: 0.1
818
- },
819
- "claude-3-opus-20240229": {
820
- inputPricePerMillion: 15,
821
- outputPricePerMillion: 75,
822
- cachedInputPricePerMillion: 1.875
823
- },
824
- "claude-3-sonnet-20240229": {
825
- inputPricePerMillion: 3,
826
- outputPricePerMillion: 15,
827
- cachedInputPricePerMillion: 0.375
828
- },
829
- "claude-3-haiku-20240307": {
830
- inputPricePerMillion: 0.25,
831
- outputPricePerMillion: 1.25,
832
- cachedInputPricePerMillion: 0.03
833
- }
834
- };
835
- var DEFAULT_PRICING_CONFIG = {
836
- providers: {
837
- openai: OPENAI_PRICING,
838
- google: GOOGLE_PRICING,
839
- anthropic: ANTHROPIC_PRICING
840
- },
841
- fallback: {
842
- inputPricePerMillion: 1,
843
- outputPricePerMillion: 5
844
- }
845
- };
846
- var DEFAULT_FALLBACK_PRICING = {
847
- inputPricePerMillion: 1,
848
- outputPricePerMillion: 5
849
- };
850
-
851
- // src/pricing/config.ts
852
- var globalConfig;
853
- function getPricingConfig() {
854
- return globalConfig;
855
- }
856
-
857
- // src/pricing/calculator.ts
858
- var TOKENS_PER_MILLION = 1e6;
859
- function getModelPricing(model, provider, providerPricing) {
860
- if (providerPricing?.[model]) {
861
- return providerPricing[model];
862
- }
863
- const globalConfig2 = getPricingConfig();
864
- const defaultProviderPricing = DEFAULT_PRICING_CONFIG.providers[provider];
865
- if (defaultProviderPricing?.[model]) {
866
- return defaultProviderPricing[model];
867
- }
868
- return globalConfig2?.fallback ?? DEFAULT_PRICING_CONFIG.fallback ?? DEFAULT_FALLBACK_PRICING;
869
- }
870
- function validateCostParams(params) {
871
- const { inputTokens, outputTokens, cachedInputTokens = 0 } = params;
872
- if (inputTokens < 0 || outputTokens < 0 || cachedInputTokens < 0) {
873
- throw new Error("Token counts must be non-negative");
874
- }
875
- if (cachedInputTokens > inputTokens) {
876
- throw new Error("cachedInputTokens cannot exceed inputTokens");
877
- }
878
- if (!Number.isFinite(inputTokens) || !Number.isFinite(outputTokens) || !Number.isFinite(cachedInputTokens)) {
879
- throw new Error("Token counts must be finite numbers");
880
- }
881
- }
882
- function calculateCost(params, providerPricing) {
883
- validateCostParams(params);
884
- const {
885
- inputTokens,
886
- outputTokens,
887
- cachedInputTokens = 0,
888
- model,
889
- provider
890
- } = params;
891
- const pricing = getModelPricing(model, provider, providerPricing);
892
- const nonCachedInputTokens = inputTokens - cachedInputTokens;
893
- const inputCost = nonCachedInputTokens / TOKENS_PER_MILLION * pricing.inputPricePerMillion;
894
- const outputCost = outputTokens / TOKENS_PER_MILLION * pricing.outputPricePerMillion;
895
- const cachedInputPricePerMillion = pricing.cachedInputPricePerMillion ?? pricing.inputPricePerMillion;
896
- const cachedInputCost = cachedInputTokens / TOKENS_PER_MILLION * cachedInputPricePerMillion;
897
- return {
898
- total: inputCost + outputCost + cachedInputCost,
899
- inputCost,
900
- outputCost,
901
- cachedInputCost
902
- };
903
- }
904
- function calculateCostFromUsage(usage, model, provider, providerPricing) {
905
- return calculateCost(
906
- {
907
- inputTokens: usage.inputTokens ?? 0,
908
- outputTokens: usage.outputTokens ?? 0,
909
- cachedInputTokens: usage.inputTokenDetails?.cacheReadTokens ?? 0,
910
- model,
911
- provider
912
- },
913
- providerPricing
914
- );
915
- }
916
- function calculateTotalCost(calls, providerPricing) {
917
- const costByModel = {};
918
- let totalCost = 0;
919
- for (const call of calls) {
920
- const cost = calculateCostFromUsage(
921
- call.usage,
922
- call.model,
923
- call.provider,
924
- providerPricing
925
- );
926
- totalCost += cost.total;
927
- const key = `${call.provider}/${call.model}`;
928
- costByModel[key] = (costByModel[key] ?? 0) + cost.total;
929
- }
930
- return { totalCost, costByModel };
931
- }
932
-
933
- // src/session/simple-session.ts
934
- var SimpleSession = class {
935
- defaultLanguageModel;
936
- modelFactory;
937
- providerType;
938
- providerPricing;
939
- defaultProviderOptions;
940
- defaultTools;
941
- defaultGenerationOptions;
942
- _fileManager;
943
- logger;
944
- sessionStartTime;
945
- signal;
946
- summary;
947
- pendingUsagePromises = [];
948
- onDoneFns = [];
949
- constructor(options) {
950
- this.defaultLanguageModel = options.defaultLanguageModel ?? null;
951
- this.modelFactory = options.modelFactory ?? null;
952
- this.providerType = options.providerType;
953
- this.providerPricing = options.providerPricing;
954
- this.defaultProviderOptions = options.defaultProviderOptions;
955
- this.defaultTools = options.defaultTools;
956
- this.defaultGenerationOptions = options.defaultGenerationOptions;
957
- this._fileManager = options.fileManager;
958
- this.logger = options.logger ?? noopLogger;
959
- this.sessionStartTime = options.startTime ?? Date.now();
960
- this.signal = options.signal;
961
- this.summary = SessionSummary.empty(this.sessionStartTime);
962
- }
963
- getModel(requestedModelId) {
964
- if (requestedModelId) {
965
- if (!this.modelFactory) {
966
- throw new Error(
967
- `Model '${requestedModelId}' requested but no modelFactory provided. Either use the default model or configure the provider with modelFactory.`
968
- );
969
- }
970
- return this.modelFactory(requestedModelId);
971
- }
972
- if (!this.defaultLanguageModel) {
973
- throw new Error(
974
- "No model specified and no default model set. Either specify a model in the call or configure the provider with withDefaultModel()."
975
- );
976
- }
977
- return this.defaultLanguageModel;
978
- }
979
- extractModelId(model) {
980
- const modelWithId = model;
981
- if (!modelWithId.modelId) {
982
- console.warn(
983
- '[SimpleSession] Model does not have modelId property, using "unknown". This may affect cost tracking accuracy.'
984
- );
985
- }
986
- return modelWithId.modelId ?? "unknown";
987
- }
988
- async generateText(params) {
989
- const callStartTime = Date.now();
990
- const { model: requestedModel, providerOptions, tools, ...restParams } = params;
991
- const languageModel = this.getModel(requestedModel);
992
- const modelId = this.extractModelId(languageModel);
993
- const mergedProviderOptions = this.defaultProviderOptions || providerOptions ? deepMerge(this.defaultProviderOptions ?? {}, providerOptions ?? {}) : void 0;
994
- const mergedTools = this.defaultTools || tools ? { ...this.defaultTools, ...tools } : void 0;
995
- this.logger.onLLMCallStart?.({
996
- type: "llm_call_start",
997
- callType: "generateText",
998
- modelId,
999
- timestamp: callStartTime,
1000
- request: { params: restParams }
1001
- });
1002
- try {
1003
- const result = await ai.generateText({
1004
- ...this.defaultGenerationOptions,
1005
- ...restParams,
1006
- tools: mergedTools,
1007
- providerOptions: mergedProviderOptions,
1008
- model: languageModel,
1009
- abortSignal: this.signal
1010
- });
1011
- const callEndTime = Date.now();
1012
- const call = {
1013
- startTime: callStartTime,
1014
- endTime: callEndTime,
1015
- duration: callEndTime - callStartTime,
1016
- usage: result.usage ?? createZeroUsage(),
1017
- type: "generateText",
1018
- model: modelId,
1019
- provider: this.providerType
1020
- };
1021
- this.updateSummaryWithLLMCall(call);
1022
- this.logger.onLLMCallEnd?.({
1023
- type: "llm_call_end",
1024
- callType: "generateText",
1025
- modelId,
1026
- timestamp: callEndTime,
1027
- response: {
1028
- duration: callEndTime - callStartTime,
1029
- usage: result.usage,
1030
- raw: result
1031
- }
1032
- });
1033
- return result;
1034
- } catch (error) {
1035
- const callEndTime = Date.now();
1036
- this.logger.onLLMCallEnd?.({
1037
- type: "llm_call_end",
1038
- callType: "generateText",
1039
- modelId,
1040
- timestamp: callEndTime,
1041
- response: {
1042
- duration: callEndTime - callStartTime,
1043
- raw: null,
1044
- error: error instanceof Error ? error : new Error(String(error))
1045
- }
1046
- });
1047
- throw error;
1048
- }
1049
- }
1050
- streamText(params) {
1051
- const callStartTime = Date.now();
1052
- const { model: requestedModel, providerOptions, tools, ...restParams } = params;
1053
- const languageModel = this.getModel(requestedModel);
1054
- const modelId = this.extractModelId(languageModel);
1055
- const mergedProviderOptions = this.defaultProviderOptions || providerOptions ? deepMerge(this.defaultProviderOptions ?? {}, providerOptions ?? {}) : void 0;
1056
- const mergedTools = this.defaultTools || tools ? { ...this.defaultTools, ...tools } : void 0;
1057
- this.logger.onLLMCallStart?.({
1058
- type: "llm_call_start",
1059
- callType: "streamText",
1060
- modelId,
1061
- timestamp: callStartTime,
1062
- request: { params: restParams }
1063
- });
1064
- const result = ai.streamText({
1065
- ...this.defaultGenerationOptions,
1066
- ...restParams,
1067
- tools: mergedTools,
1068
- providerOptions: mergedProviderOptions,
1069
- model: languageModel,
1070
- abortSignal: this.signal
1071
- });
1072
- const usagePromise = Promise.resolve(result.usage).then((usage) => {
1073
- const callEndTime = Date.now();
1074
- const call = {
1075
- startTime: callStartTime,
1076
- endTime: callEndTime,
1077
- duration: callEndTime - callStartTime,
1078
- usage: usage ?? createZeroUsage(),
1079
- type: "streamText",
1080
- model: modelId,
1081
- provider: this.providerType
1082
- };
1083
- this.updateSummaryWithLLMCall(call);
1084
- this.logger.onLLMCallEnd?.({
1085
- type: "llm_call_end",
1086
- callType: "streamText",
1087
- modelId,
1088
- timestamp: callEndTime,
1089
- response: {
1090
- duration: callEndTime - callStartTime,
1091
- usage,
1092
- raw: result
1093
- }
1094
- });
1095
- return usage;
1096
- });
1097
- this.pendingUsagePromises.push(usagePromise);
1098
- return result;
1099
- }
1100
- get fileManager() {
1101
- return this._fileManager;
1102
- }
1103
- record(data) {
1104
- this.summary = this.summary.withCustomRecord(data);
1105
- }
1106
- recordToolCall(toolCallSummary) {
1107
- this.summary = this.summary.withToolCall(toolCallSummary);
1108
- }
1109
- recordLLMCall(record) {
1110
- const call = {
1111
- ...record,
1112
- type: record.type ?? "manual"
1113
- };
1114
- this.updateSummaryWithLLMCall(call);
1115
- }
1116
- recordAdditionalCost(cost) {
1117
- this.summary = this.summary.withAdditionalCost({
1118
- ...cost,
1119
- timestamp: Date.now()
1120
- });
1121
- }
1122
- setMetadata(keyOrData, value) {
1123
- if (typeof keyOrData === "string") {
1124
- this.summary = this.summary.withMetadata(keyOrData, value);
1125
- } else {
1126
- for (const [k, v] of Object.entries(keyOrData)) {
1127
- this.summary = this.summary.withMetadata(k, v);
1128
- }
1129
- }
1130
- }
1131
- updateSummaryWithLLMCall(call) {
1132
- const newCalls = [...this.summary.llmCalls, call];
1133
- const { totalCost: llmCost, costByModel } = calculateTotalCost(
1134
- newCalls.map((c) => ({ usage: c.usage, model: c.model, provider: c.provider })),
1135
- this.providerPricing
1136
- );
1137
- const newTotalUsage = mergeUsages(newCalls.map((c) => c.usage));
1138
- this.summary = this.summary.withLLMCall(call, llmCost, costByModel, newTotalUsage);
1139
- }
1140
- onDone(fn) {
1141
- this.onDoneFns.push(fn);
1142
- }
1143
- async runOnDoneHooks() {
1144
- const reversedHooks = [...this.onDoneFns].reverse();
1145
- for (const fn of reversedHooks) {
1146
- try {
1147
- await fn();
1148
- } catch (error) {
1149
- console.error("[SimpleSession] onDone hook error:", error);
1150
- }
1151
- }
1152
- }
1153
- async getSummary() {
1154
- await Promise.all(this.pendingUsagePromises);
1155
- return this.summary;
1156
- }
1157
- /**
1158
- * Notifies Logger of execution start.
1159
- * @internal Called by SimpleExecutionHost - not intended for direct use.
1160
- */
1161
- notifyExecutionStart() {
1162
- this._logger.onExecutionStart?.({
1163
- type: "execution_start",
1164
- timestamp: Date.now()
1165
- });
1166
- }
1167
- /**
1168
- * Notifies Logger of execution completion with result data and summary.
1169
- * @param data - The execution result data
1170
- * @param startTime - Execution start timestamp for duration calculation
1171
- * @internal Called by SimpleExecutionHost - not intended for direct use.
1172
- */
1173
- async notifyExecutionDone(data, startTime) {
1174
- const summary = await this.getSummary();
1175
- this._logger.onExecutionDone?.({
1176
- type: "execution_done",
1177
- timestamp: Date.now(),
1178
- duration: Date.now() - startTime,
1179
- data,
1180
- summary
1181
- });
1182
- }
1183
- /**
1184
- * Notifies Logger of execution error with error details and summary (if available).
1185
- * Gracefully handles getSummary() failures - summary will be undefined if it fails.
1186
- * @param error - The error that occurred
1187
- * @param startTime - Execution start timestamp for duration calculation
1188
- * @internal Called by SimpleExecutionHost - not intended for direct use.
1189
- */
1190
- async notifyExecutionError(error, startTime) {
1191
- let summary;
1192
- try {
1193
- summary = await this.getSummary();
1194
- } catch {
1195
- }
1196
- this._logger.onExecutionError?.({
1197
- type: "execution_error",
1198
- timestamp: Date.now(),
1199
- duration: Date.now() - startTime,
1200
- error,
1201
- summary
1202
- });
1203
- }
1204
- get _logger() {
1205
- return this.logger;
1206
- }
1207
- get _startTime() {
1208
- return this.sessionStartTime;
1209
- }
1210
- get _modelId() {
1211
- if (!this.defaultLanguageModel) {
1212
- return "unknown";
1213
- }
1214
- return this.extractModelId(this.defaultLanguageModel);
1215
- }
1216
- };
1217
-
1218
- // src/session/streaming-session.ts
1219
- var StreamingSession = class extends SimpleSession {
1220
- lastEventTime;
1221
- _terminated = false;
1222
- constructor(options) {
1223
- super({
1224
- defaultLanguageModel: options.defaultLanguageModel,
1225
- modelFactory: options.modelFactory,
1226
- providerType: options.providerType,
1227
- providerPricing: options.providerPricing,
1228
- fileManager: options.fileManager,
1229
- logger: options.logger,
1230
- startTime: options.startTime,
1231
- signal: options.signal,
1232
- defaultProviderOptions: options.defaultProviderOptions,
1233
- defaultTools: options.defaultTools,
1234
- defaultGenerationOptions: options.defaultGenerationOptions
1235
- });
1236
- this.lastEventTime = this._startTime;
1237
- this._logger.onExecutionStart?.({
1238
- type: "execution_start",
1239
- timestamp: Date.now()
1240
- });
1241
- }
1242
- /**
1243
- * Emits a streaming event with automatically attached metrics.
1244
- *
1245
- * Reserved types ('complete', 'error') throw at runtime - use session.done()
1246
- * or session.fail() instead.
1247
- *
1248
- * @param event - The event to emit (metrics will be added automatically)
1249
- * @returns The complete event with metrics attached
1250
- * @throws Error when attempting to emit reserved types ('complete', 'error')
1251
- */
1252
- emit(event) {
1253
- if (this._terminated) {
1254
- throw new Error("Session already terminated. Cannot call emit() after a terminal operation.");
1255
- }
1256
- const eventType = event.type;
1257
- if (eventType === "complete" || eventType === "error") {
1258
- throw new Error(
1259
- `Cannot emit reserved type "${eventType}". Use session.done() for completion or session.fail() for errors.`
1260
- );
1261
- }
1262
- return this.emitInternal(event);
1263
- }
1264
- /**
1265
- * Internal emit method - bypasses reserved type check.
1266
- * Used by done() and fail() to emit terminal events.
1267
- */
1268
- emitInternal(event) {
1269
- const metrics = this.createMetrics();
1270
- const fullEvent = { ...event, metrics };
1271
- this._logger.onExecutionEmit?.({
1272
- type: "execution_emit",
1273
- event: fullEvent
1274
- });
1275
- return fullEvent;
1276
- }
1277
- /**
1278
- * Signals successful completion of the streaming execution.
1279
- * Emits a 'complete' event with the result data and session summary.
1280
- * Also triggers Logger.onExecutionDone for observability.
1281
- * @param data - The final result data
1282
- * @returns The complete event with data and summary
1283
- */
1284
- async done(data) {
1285
- if (this._terminated) {
1286
- throw new Error("Session already terminated. Cannot call done() after a terminal operation.");
1287
- }
1288
- this._terminated = true;
1289
- const summary = await this.getSummary();
1290
- this._logger.onExecutionDone?.({
1291
- type: "execution_done",
1292
- timestamp: Date.now(),
1293
- duration: summary.totalDuration,
1294
- data,
1295
- summary
1296
- });
1297
- return this.emitInternal({
1298
- type: "complete",
1299
- data,
1300
- summary
1301
- });
1302
- }
1303
- /**
1304
- * Signals that the streaming execution failed with an error.
1305
- * Emits an 'error' event and triggers Logger.onExecutionError for observability.
1306
- * Gracefully handles getSummary() failures - summary will be undefined if it fails.
1307
- * @param error - The error that caused the failure
1308
- * @param data - Optional partial result data (if any was produced before failure)
1309
- * @returns The error event
1310
- */
1311
- async fail(error, data) {
1312
- if (this._terminated) {
1313
- throw new Error("Session already terminated. Cannot call fail() after a terminal operation.");
1314
- }
1315
- this._terminated = true;
1316
- let summary;
1317
- try {
1318
- summary = await this.getSummary();
1319
- } catch {
1320
- }
1321
- this._logger.onExecutionError?.({
1322
- type: "execution_error",
1323
- timestamp: Date.now(),
1324
- duration: summary?.totalDuration ?? Date.now() - this._startTime,
1325
- error,
1326
- data,
1327
- summary
1328
- });
1329
- const errorEvent = {
1330
- type: "error",
1331
- error
1332
- };
1333
- if (summary) {
1334
- errorEvent.summary = summary;
1335
- }
1336
- if (data !== void 0) {
1337
- errorEvent.data = data;
1338
- }
1339
- return this.emitInternal(errorEvent);
1340
- }
1341
- createMetrics() {
1342
- const now = Date.now();
1343
- const metrics = {
1344
- timestamp: now,
1345
- elapsedMs: now - this._startTime,
1346
- deltaMs: now - this.lastEventTime
1347
- };
1348
- this.lastEventTime = now;
1349
- return metrics;
1350
- }
1351
- };
1352
-
1353
- // src/errors/utils.ts
1354
- function wrapAsError(error, ErrorClass, options) {
1355
- const cause = error instanceof Error ? error : new Error(String(error));
1356
- return new ErrorClass(cause.message, { ...options, cause });
1357
- }
1358
-
1359
- // src/errors/types.ts
1360
- var AgtlantisError = class extends Error {
1361
- code;
1362
- cause;
1363
- context;
1364
- constructor(message, options) {
1365
- super(message);
1366
- this.name = "AgtlantisError";
1367
- this.code = options.code;
1368
- this.cause = options.cause;
1369
- this.context = options.context;
1370
- const ErrorWithCapture = Error;
1371
- ErrorWithCapture.captureStackTrace?.(this, this.constructor);
1372
- }
1373
- get isRetryable() {
1374
- return false;
1375
- }
1376
- toJSON() {
1377
- return {
1378
- name: this.name,
1379
- message: this.message,
1380
- code: this.code,
1381
- isRetryable: this.isRetryable,
1382
- context: this.context,
1383
- cause: this.cause?.message,
1384
- stack: this.stack
1385
- };
1386
- }
1387
- };
1388
- var FileError = class _FileError extends AgtlantisError {
1389
- constructor(message, options = {}) {
1390
- super(message, {
1391
- code: options.code ?? "FILE_ERROR" /* FILE_ERROR */,
1392
- cause: options.cause,
1393
- context: options.context
1394
- });
1395
- this.name = "FileError";
1396
- }
1397
- static from(error, code = "FILE_ERROR" /* FILE_ERROR */, context) {
1398
- if (error instanceof _FileError) {
1399
- return error;
1400
- }
1401
- return wrapAsError(error, _FileError, { code, context });
1402
- }
1403
- };
1404
-
1405
- // src/provider/noop-file-manager.ts
1406
- var NoOpFileManager = class {
1407
- upload(_files) {
1408
- throw new FileError("File upload not supported by this provider", {
1409
- code: "UNSUPPORTED_TYPE" /* UNSUPPORTED_TYPE */,
1410
- context: {
1411
- provider: "noop",
1412
- suggestion: "Use a provider with file support (e.g., Google) or pass files inline"
1413
- }
1414
- });
1415
- }
1416
- delete(_fileId) {
1417
- throw new FileError("File delete not supported by this provider", {
1418
- code: "UNSUPPORTED_TYPE" /* UNSUPPORTED_TYPE */,
1419
- context: {
1420
- provider: "noop"
1421
- }
1422
- });
1423
- }
1424
- clear() {
1425
- return Promise.resolve();
1426
- }
1427
- getUploadedFiles() {
1428
- return [];
1429
- }
1430
- };
1431
-
1432
- // src/testing/mock-provider.ts
1433
- var MockProvider = class _MockProvider extends BaseProvider {
1434
- calls = [];
1435
- modelSource;
1436
- fileManagerInstance;
1437
- loggerInstance;
1438
- defaultModelId;
1439
- pricingConfig;
1440
- providerTypeId;
1441
- constructor(config) {
1442
- super();
1443
- if (!config.model && !config.modelFactory) {
1444
- throw new Error("MockProvider requires either model or modelFactory");
1445
- }
1446
- this.modelSource = config.modelFactory ?? config.model;
1447
- this.fileManagerInstance = config.fileManager ?? new NoOpFileManager();
1448
- this.loggerInstance = config.logger ?? noopLogger;
1449
- this.defaultModelId = null;
1450
- this.providerTypeId = config.providerType ?? "mock";
1451
- }
1452
- /**
1453
- * Creates instance for fluent API without calling constructor.
1454
- * Shares calls array between fluent instances for tracking.
1455
- */
1456
- static createWithConfig(modelSource, fileManager, logger, defaultModelId, pricingConfig, providerType, existingCalls) {
1457
- const provider = Object.create(_MockProvider.prototype);
1458
- Object.assign(provider, {
1459
- modelSource,
1460
- fileManagerInstance: fileManager,
1461
- loggerInstance: logger,
1462
- defaultModelId,
1463
- pricingConfig,
1464
- providerTypeId: providerType,
1465
- calls: existingCalls
1466
- });
1467
- return provider;
1468
- }
1469
- getCalls() {
1470
- return [...this.calls];
1471
- }
1472
- clearCalls() {
1473
- this.calls.length = 0;
1474
- }
1475
- withDefaultModel(modelId) {
1476
- return _MockProvider.createWithConfig(
1477
- this.modelSource,
1478
- this.fileManagerInstance,
1479
- this.loggerInstance,
1480
- modelId,
1481
- this.pricingConfig,
1482
- this.providerTypeId,
1483
- this.calls
1484
- );
1485
- }
1486
- withLogger(logger) {
1487
- return _MockProvider.createWithConfig(
1488
- this.modelSource,
1489
- this.fileManagerInstance,
1490
- logger,
1491
- this.defaultModelId,
1492
- this.pricingConfig,
1493
- this.providerTypeId,
1494
- this.calls
1495
- );
1496
- }
1497
- withPricing(pricing) {
1498
- return _MockProvider.createWithConfig(
1499
- this.modelSource,
1500
- this.fileManagerInstance,
1501
- this.loggerInstance,
1502
- this.defaultModelId,
1503
- pricing,
1504
- this.providerTypeId,
1505
- this.calls
1506
- );
1507
- }
1508
- /**
1509
- * Mock implementation - returns same provider since mocks don't use provider options.
1510
- */
1511
- withDefaultOptions(_options) {
1512
- return this;
1513
- }
1514
- /**
1515
- * Mock implementation - returns same provider since mocks don't use generation options.
1516
- */
1517
- withDefaultGenerationOptions(_options) {
1518
- return this;
1519
- }
1520
- createSimpleSession(signal) {
1521
- return new SimpleSession({ ...this.buildSessionConfig(), signal });
1522
- }
1523
- createStreamingSession(signal) {
1524
- return new StreamingSession({ ...this.buildSessionConfig(), signal });
1525
- }
1526
- buildSessionConfig() {
1527
- const effectiveModelId = this.defaultModelId ?? "default";
1528
- return {
1529
- defaultLanguageModel: this.createTrackingModel(effectiveModelId),
1530
- modelFactory: (modelId) => this.createTrackingModel(modelId),
1531
- providerType: this.providerTypeId,
1532
- providerPricing: this.pricingConfig,
1533
- fileManager: this.fileManagerInstance,
1534
- logger: this.loggerInstance
1535
- };
1536
- }
1537
- getBaseModel(modelId) {
1538
- if (typeof this.modelSource === "function") {
1539
- return this.modelSource(modelId);
1540
- }
1541
- return this.modelSource;
1542
- }
1543
- createTrackingModel(modelId) {
1544
- const baseModel = this.getBaseModel(modelId);
1545
- const calls = this.calls;
1546
- return {
1547
- ...baseModel,
1548
- specificationVersion: baseModel.specificationVersion,
1549
- provider: baseModel.provider,
1550
- modelId: baseModel.modelId,
1551
- supportedUrls: baseModel.supportedUrls,
1552
- doGenerate: async (params) => {
1553
- calls.push({
1554
- modelId,
1555
- type: "generate",
1556
- timestamp: Date.now(),
1557
- params
1558
- });
1559
- return baseModel.doGenerate(params);
1560
- },
1561
- doStream: async (params) => {
1562
- calls.push({
1563
- modelId,
1564
- type: "stream",
1565
- timestamp: Date.now(),
1566
- params
1567
- });
1568
- return baseModel.doStream(params);
1569
- }
1570
- };
1571
- }
1572
- };
1573
- function createMockProvider(configOrModel) {
1574
- if (typeof configOrModel === "function") {
1575
- return new MockProvider({ modelFactory: configOrModel });
1576
- }
1577
- if (configOrModel instanceof test.MockLanguageModelV3) {
1578
- return new MockProvider({ model: configOrModel });
1579
- }
1580
- return new MockProvider(configOrModel);
1581
- }
1582
-
1583
- // src/testing/mock.ts
1584
- var DEFAULT_USAGE = {
1585
- inputTokens: { total: 0, noCache: 0, cacheRead: void 0, cacheWrite: void 0 },
1586
- outputTokens: { total: 0, text: 0, reasoning: void 0 }
1587
- };
1588
- var DEFAULT_FINISH = {
1589
- unified: "stop",
1590
- raw: void 0
1591
- };
1592
- var mock = {
1593
- /**
1594
- * Creates a MockLanguageModelV3 that returns text content.
1595
- *
1596
- * @param text - The text to return from generateText
1597
- * @param options - Optional overrides for usage, finishReason, etc.
1598
- *
1599
- * @example
1600
- * const model = mock.text('Hello, world!');
1601
- *
1602
- * @example
1603
- * // With custom usage for cost calculation tests
1604
- * const model = mock.text('Hello', {
1605
- * usage: {
1606
- * inputTokens: { total: 100 },
1607
- * outputTokens: { total: 50 },
1608
- * },
1609
- * });
1610
- */
1611
- text(text, options) {
1612
- return new test.MockLanguageModelV3({
1613
- doGenerate: async () => ({
1614
- content: [{ type: "text", text }],
1615
- finishReason: options?.finishReason ?? DEFAULT_FINISH,
1616
- usage: options?.usage ?? DEFAULT_USAGE,
1617
- warnings: options?.warnings ?? [],
1618
- providerMetadata: options?.providerMetadata
1619
- })
1620
- });
1621
- },
1622
- /**
1623
- * Creates a MockLanguageModelV3 that returns JSON content.
1624
- *
1625
- * Automatically stringifies the data. Use with generateObject or
1626
- * generateText + Output.object.
1627
- *
1628
- * @param data - The object to return as JSON
1629
- * @param options - Optional overrides for usage, finishReason, etc.
1630
- *
1631
- * @example
1632
- * const model = mock.json({ name: 'Alice', age: 30 });
1633
- */
1634
- json(data, options) {
1635
- return mock.text(JSON.stringify(data), options);
1636
- },
1637
- /**
1638
- * Creates a MockLanguageModelV3 that streams text chunks.
1639
- *
1640
- * @param chunks - Array of text strings to stream
1641
- * @param options - Optional overrides for finishReason, usage, etc.
1642
- *
1643
- * @example
1644
- * const model = mock.stream(['Hello', ', ', 'world!']);
1645
- */
1646
- stream(chunks, options) {
1647
- return new test.MockLanguageModelV3({
1648
- doStream: async () => ({
1649
- stream: test.simulateReadableStream({
1650
- chunks: [
1651
- { type: "text-start", id: "text-1" },
1652
- ...chunks.map((chunk) => ({
1653
- type: "text-delta",
1654
- id: "text-1",
1655
- delta: chunk
1656
- })),
1657
- { type: "text-end", id: "text-1" },
1658
- {
1659
- type: "finish",
1660
- finishReason: options?.finishReason ?? DEFAULT_FINISH,
1661
- usage: options?.usage ?? DEFAULT_USAGE,
1662
- logprobs: void 0
1663
- }
1664
- ]
1665
- })
1666
- })
1667
- });
1668
- },
1669
- /**
1670
- * Creates a MockLanguageModelV3 that throws an error.
1671
- *
1672
- * @param error - The error to throw
1673
- *
1674
- * @example
1675
- * const model = mock.error(new Error('Rate limit exceeded'));
1676
- *
1677
- * await expect(generateText({ model, prompt: 'Hi' }))
1678
- * .rejects.toThrow('Rate limit exceeded');
1679
- */
1680
- error(error) {
1681
- return new test.MockLanguageModelV3({
1682
- doGenerate: async () => {
1683
- throw error;
1684
- },
1685
- doStream: async () => {
1686
- throw error;
1687
- }
1688
- });
1689
- },
1690
- /**
1691
- * Creates a MockProvider with call tracking.
1692
- *
1693
- * Supports three input styles:
1694
- * - Single model: `mock.provider(mock.text('Hello'))`
1695
- * - Model factory: `mock.provider((modelId) => mock.text(modelId))`
1696
- * - Full config: `mock.provider({ model, fileManager, logger })`
1697
- *
1698
- * @example
1699
- * ```typescript
1700
- * // Basic usage
1701
- * const provider = mock.provider(mock.text('Hello!'));
1702
- * const execution = provider.simpleExecution(async (session) => {
1703
- * const { text } = await session.generateText({ prompt: 'Say hi' });
1704
- * return text;
1705
- * });
1706
- * expect(await execution.toResult()).toBe('Hello!');
1707
- * expect(provider.getCalls()).toHaveLength(1);
1708
- *
1709
- * // With model factory for different responses per model
1710
- * const provider = mock.provider((modelId) => {
1711
- * if (modelId === 'gpt-4') return mock.text('GPT-4 response');
1712
- * return mock.text('Default response');
1713
- * });
1714
- * ```
1715
- */
1716
- provider(configOrModel) {
1717
- return createMockProvider(configOrModel);
1718
- }
1719
- };
1720
-
1721
- // src/execution/testing/helpers.ts
1722
- function createAbortScenario() {
1723
- const controller = new AbortController();
1724
- return {
1725
- controller,
1726
- signal: controller.signal,
1727
- abort: (reason) => controller.abort(reason),
1728
- isAborted: () => controller.signal.aborted
1729
- };
1730
- }
1731
- function createAlreadyAbortedSignal(reason = "Already aborted") {
1732
- const controller = new AbortController();
1733
- controller.abort(reason);
1734
- return controller.signal;
1735
- }
1736
- function createSimpleGenerator(result, events = []) {
1737
- return async function* (session) {
1738
- for (const event of events) {
1739
- yield session.emit(event);
1740
- }
1741
- return session.done(result);
1742
- };
1743
- }
1744
- function createErrorGenerator(error, eventsBeforeError = []) {
1745
- return async function* (session) {
1746
- for (const event of eventsBeforeError) {
1747
- yield session.emit(event);
1748
- }
1749
- throw error;
1750
- };
1751
- }
1752
- function createCancelableGenerator(abortScenario, onCancel, eventsBeforeWait = []) {
1753
- return async function* (session) {
1754
- for (const event of eventsBeforeWait) {
1755
- yield session.emit(event);
1756
- }
1757
- await new Promise((_, reject) => {
1758
- const signal = abortScenario.signal;
1759
- if (signal.aborted) {
1760
- onCancel?.();
1761
- reject(new DOMException("Aborted", "AbortError"));
1762
- return;
1763
- }
1764
- signal.addEventListener("abort", () => {
1765
- onCancel?.();
1766
- reject(new DOMException("Aborted", "AbortError"));
1767
- });
1768
- });
1769
- };
1770
- }
1771
- function createCancelableFunction(abortScenario, onCancel) {
1772
- return async () => {
1773
- await new Promise((_, reject) => {
1774
- const signal = abortScenario.signal;
1775
- if (signal.aborted) {
1776
- onCancel?.();
1777
- reject(new DOMException("Aborted", "AbortError"));
1778
- return;
1779
- }
1780
- signal.addEventListener("abort", () => {
1781
- onCancel?.();
1782
- reject(new DOMException("Aborted", "AbortError"));
1783
- });
1784
- });
1785
- return "should-not-reach";
1786
- };
1787
- }
1788
- function createDelayedGenerator(delayMs, result, abortScenario) {
1789
- return async function* (session) {
1790
- await new Promise((resolve, reject) => {
1791
- const timeoutId = setTimeout(resolve, delayMs);
1792
- if (abortScenario) {
1793
- abortScenario.signal.addEventListener("abort", () => {
1794
- clearTimeout(timeoutId);
1795
- reject(new DOMException("Aborted", "AbortError"));
1796
- });
1797
- }
1798
- });
1799
- return session.done(result);
1800
- };
1801
- }
1802
- function createSlowGenerator(events, delayBetweenEventsMs, abortScenario) {
1803
- return async function* (session) {
1804
- for (const event of events) {
1805
- if (abortScenario?.isAborted()) {
1806
- throw new DOMException("Aborted", "AbortError");
1807
- }
1808
- await new Promise((resolve, reject) => {
1809
- const timeoutId = setTimeout(resolve, delayBetweenEventsMs);
1810
- if (abortScenario) {
1811
- if (abortScenario.signal.aborted) {
1812
- clearTimeout(timeoutId);
1813
- reject(new DOMException("Aborted", "AbortError"));
1814
- return;
1815
- }
1816
- abortScenario.signal.addEventListener(
1817
- "abort",
1818
- () => {
1819
- clearTimeout(timeoutId);
1820
- reject(new DOMException("Aborted", "AbortError"));
1821
- },
1822
- { once: true }
1823
- );
1824
- }
1825
- });
1826
- yield session.emit(event);
1827
- }
1828
- return void 0;
1829
- };
1830
- }
1831
- async function collectStreamAsync(stream) {
1832
- const collected = [];
1833
- for await (const event of stream) {
1834
- collected.push(event);
1835
- }
1836
- return collected;
1837
- }
1838
- function createNeverEndingGenerator(eventsBeforeWait = [], abortScenario) {
1839
- return async function* (session) {
1840
- for (const event of eventsBeforeWait) {
1841
- yield session.emit(event);
1842
- }
1843
- await new Promise((_, reject) => {
1844
- if (abortScenario) {
1845
- if (abortScenario.signal.aborted) {
1846
- reject(new DOMException("Aborted", "AbortError"));
1847
- return;
1848
- }
1849
- abortScenario.signal.addEventListener(
1850
- "abort",
1851
- () => reject(new DOMException("Aborted", "AbortError")),
1852
- { once: true }
1853
- );
1854
- }
1855
- });
1856
- return void 0;
1857
- };
1858
- }
1859
- function createOrderTrackingLogger() {
1860
- const callOrder = [];
1861
- const logger = {
1862
- onLLMCallStart: () => {
1863
- },
1864
- onLLMCallEnd: () => {
1865
- },
1866
- onExecutionStart: () => {
1867
- callOrder.push("start");
1868
- },
1869
- onExecutionEmit: () => {
1870
- callOrder.push("emit");
1871
- },
1872
- onExecutionDone: () => {
1873
- callOrder.push("done");
1874
- },
1875
- onExecutionError: () => {
1876
- callOrder.push("error");
1877
- }
1878
- };
1879
- return {
1880
- logger,
1881
- getCallOrder: () => [...callOrder]
1882
- };
1883
- }
1884
-
1885
- // src/execution/testing/fixtures.ts
1886
- var TEST_PROVIDER_TYPE = "google";
1887
- var noop = () => {
1888
- };
1889
- var noopFactory = () => noop;
1890
- function createNoopWithReturn(value) {
1891
- return () => value;
1892
- }
1893
- function createNoopAsync(value) {
1894
- return () => Promise.resolve(value);
1895
- }
1896
- function createMockModel(options = {}) {
1897
- const { mockFn = noopFactory } = options;
1898
- return {
1899
- specificationVersion: "v1",
1900
- provider: "test-provider",
1901
- modelId: "test-model",
1902
- defaultObjectGenerationMode: "json",
1903
- doGenerate: mockFn(),
1904
- doStream: mockFn()
1905
- };
1906
- }
1907
- function createMockFileManager(options = {}) {
1908
- const { mockFn } = options;
1909
- if (mockFn) {
1910
- return {
1911
- upload: mockFn(),
1912
- delete: mockFn(),
1913
- clear: mockFn(),
1914
- getUploadedFiles: mockFn()
1915
- };
1916
- }
1917
- return {
1918
- upload: createNoopAsync([]),
1919
- delete: createNoopAsync(void 0),
1920
- clear: createNoopAsync(void 0),
1921
- getUploadedFiles: createNoopWithReturn([])
1922
- };
1923
- }
1924
- function createMockLogger(options = {}) {
1925
- const { mockFn = noopFactory } = options;
1926
- return {
1927
- onLLMCallStart: mockFn(),
1928
- onLLMCallEnd: mockFn(),
1929
- onExecutionStart: mockFn(),
1930
- onExecutionEmit: mockFn(),
1931
- onExecutionDone: mockFn(),
1932
- onExecutionError: mockFn()
1933
- };
1934
- }
1935
- function createMockUsage2(overrides = {}) {
1936
- return {
1937
- inputTokens: 100,
1938
- outputTokens: 50,
1939
- totalTokens: 150,
1940
- inputTokenDetails: {
1941
- noCacheTokens: 100,
1942
- cacheReadTokens: 0,
1943
- cacheWriteTokens: 0
1944
- },
1945
- outputTokenDetails: {
1946
- textTokens: 50,
1947
- reasoningTokens: 0
1948
- },
1949
- ...overrides
1950
- };
1951
- }
1952
- function createSimpleSessionFactory(options = {}) {
1953
- const { mockFn, logger } = options;
1954
- return (signal) => new SimpleSession({
1955
- defaultLanguageModel: createMockModel({ mockFn }),
1956
- providerType: TEST_PROVIDER_TYPE,
1957
- fileManager: createMockFileManager({ mockFn }),
1958
- signal,
1959
- logger
1960
- });
1961
- }
1962
- function createStreamingSessionFactory(options = {}) {
1963
- const { mockFn, logger } = options;
1964
- return () => new StreamingSession({
1965
- defaultLanguageModel: createMockModel({ mockFn }),
1966
- providerType: TEST_PROVIDER_TYPE,
1967
- fileManager: createMockFileManager({ mockFn }),
1968
- logger
1969
- });
1970
- }
1971
- function createStreamingSessionFactoryWithSignal(options = {}) {
1972
- const { mockFn, logger, onSignalCapture } = options;
1973
- return (signal) => {
1974
- onSignalCapture?.(signal);
1975
- return new StreamingSession({
1976
- defaultLanguageModel: createMockModel({ mockFn }),
1977
- providerType: TEST_PROVIDER_TYPE,
1978
- fileManager: createMockFileManager({ mockFn }),
1979
- signal,
1980
- logger
1981
- });
1982
- };
1983
- }
1984
- async function collectEvents2(stream) {
1985
- const events = [];
1986
- for await (const event of stream) {
1987
- events.push(event);
1988
- }
1989
- return events;
1990
- }
1991
- function createControllablePromise() {
1992
- let resolve;
1993
- let reject;
1994
- const promise = new Promise((res, rej) => {
1995
- resolve = res;
1996
- reject = rej;
1997
- });
1998
- return { promise, resolve, reject };
1999
- }
2000
-
2001
- // src/testing/test-execution.ts
2002
- function createTestMetrics() {
2003
- return { timestamp: Date.now(), elapsedMs: 0, deltaMs: 0 };
2004
- }
2005
- function createTestExecution(result, events = []) {
2006
- const summary = SessionSummary.forTest({});
2007
- const completionEvent = {
2008
- type: "complete",
2009
- data: result,
2010
- summary,
2011
- metrics: createTestMetrics()
2012
- };
2013
- const allEvents = [
2014
- ...events.map(
2015
- (e) => ({ ...e, metrics: createTestMetrics() })
2016
- ),
2017
- completionEvent
2018
- ];
2019
- return {
2020
- stream() {
2021
- return {
2022
- [Symbol.asyncIterator]() {
2023
- let index = 0;
2024
- return {
2025
- async next() {
2026
- if (index < allEvents.length) {
2027
- return { value: allEvents[index++], done: false };
2028
- }
2029
- return { value: void 0, done: true };
2030
- }
2031
- };
2032
- }
2033
- };
2034
- },
2035
- async result() {
2036
- return { status: "succeeded", value: result, events: allEvents, summary };
2037
- },
2038
- cancel() {
2039
- },
2040
- async cleanup() {
2041
- },
2042
- async [Symbol.asyncDispose]() {
2043
- }
2044
- };
2045
- }
2046
- function createTestErrorExecution(error, options = {}) {
2047
- const summary = SessionSummary.forTest({});
2048
- const errorEvent = {
2049
- type: "error",
2050
- error,
2051
- summary,
2052
- metrics: createTestMetrics()
2053
- };
2054
- if (options.data !== void 0) {
2055
- errorEvent.data = options.data;
2056
- }
2057
- const typedErrorEvent = errorEvent;
2058
- const allEvents = [
2059
- ...(options.events ?? []).map(
2060
- (e) => ({ ...e, metrics: createTestMetrics() })
2061
- ),
2062
- typedErrorEvent
2063
- ];
2064
- return {
2065
- stream() {
2066
- return {
2067
- [Symbol.asyncIterator]() {
2068
- let index = 0;
2069
- return {
2070
- async next() {
2071
- if (index < allEvents.length) {
2072
- return { value: allEvents[index++], done: false };
2073
- }
2074
- return { value: void 0, done: true };
2075
- }
2076
- };
2077
- }
2078
- };
2079
- },
2080
- async result() {
2081
- return { status: "failed", error, events: allEvents, summary };
2082
- },
2083
- cancel() {
2084
- },
2085
- async cleanup() {
2086
- },
2087
- async [Symbol.asyncDispose]() {
2088
- }
2089
- };
2090
- }
2091
- function createTestCanceledExecution(events = []) {
2092
- const summary = SessionSummary.forTest({});
2093
- const allEvents = events.map(
2094
- (e) => ({ ...e, metrics: createTestMetrics() })
2095
- );
2096
- return {
2097
- stream() {
2098
- return {
2099
- [Symbol.asyncIterator]() {
2100
- let index = 0;
2101
- return {
2102
- async next() {
2103
- if (index < allEvents.length) {
2104
- return { value: allEvents[index++], done: false };
2105
- }
2106
- return { value: void 0, done: true };
2107
- }
2108
- };
2109
- }
2110
- };
2111
- },
2112
- async result() {
2113
- return { status: "canceled", events: allEvents, summary };
2114
- },
2115
- cancel() {
2116
- },
2117
- async cleanup() {
2118
- },
2119
- async [Symbol.asyncDispose]() {
2120
- }
2121
- };
2122
- }
2123
-
2124
- Object.defineProperty(exports, "MockLanguageModelV3", {
2125
- enumerable: true,
2126
- get: function () { return test.MockLanguageModelV3; }
2127
- });
2128
- Object.defineProperty(exports, "simulateReadableStream", {
2129
- enumerable: true,
2130
- get: function () { return test.simulateReadableStream; }
2131
- });
2132
- exports.MockProvider = MockProvider;
2133
- exports.TEST_API_KEY = TEST_API_KEY;
2134
- exports.TEST_PROVIDER_TYPE = TEST_PROVIDER_TYPE;
2135
- exports.collectEvents = collectEvents;
2136
- exports.collectExecutionEvents = collectEvents2;
2137
- exports.collectStreamAsync = collectStreamAsync;
2138
- exports.consumeExecution = consumeExecution;
2139
- exports.createAbortScenario = createAbortScenario;
2140
- exports.createAlreadyAbortedSignal = createAlreadyAbortedSignal;
2141
- exports.createCancelableFunction = createCancelableFunction;
2142
- exports.createCancelableGenerator = createCancelableGenerator;
2143
- exports.createControllablePromise = createControllablePromise;
2144
- exports.createDelayedGenerator = createDelayedGenerator;
2145
- exports.createErrorGenerator = createErrorGenerator;
2146
- exports.createMockFileManager = createMockFileManager;
2147
- exports.createMockLanguageModelUsage = createMockUsage2;
2148
- exports.createMockLogger = createMockLogger;
2149
- exports.createMockModel = createMockModel;
2150
- exports.createMockProvider = createMockProvider;
2151
- exports.createMockSessionSummary = createMockSessionSummary;
2152
- exports.createMockUsage = createMockUsage;
2153
- exports.createNeverEndingGenerator = createNeverEndingGenerator;
2154
- exports.createOrderTrackingLogger = createOrderTrackingLogger;
2155
- exports.createSimpleGenerator = createSimpleGenerator;
2156
- exports.createSimpleSessionFactory = createSimpleSessionFactory;
2157
- exports.createSlowGenerator = createSlowGenerator;
2158
- exports.createStreamingSessionFactory = createStreamingSessionFactory;
2159
- exports.createStreamingSessionFactoryWithSignal = createStreamingSessionFactoryWithSignal;
2160
- exports.createTestCanceledExecution = createTestCanceledExecution;
2161
- exports.createTestErrorExecution = createTestErrorExecution;
2162
- exports.createTestEvent = createTestEvent;
2163
- exports.createTestExecution = createTestExecution;
2164
- exports.expectFileManagerInterface = expectFileManagerInterface;
2165
- exports.mock = mock;
2166
- //# sourceMappingURL=index.cjs.map
2167
- //# sourceMappingURL=index.cjs.map