@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
package/dist/index.cjs DELETED
@@ -1,3085 +0,0 @@
1
- 'use strict';
2
-
3
- var ai = require('ai');
4
- var zod = require('zod');
5
- var Handlebars = require('handlebars');
6
- var fs = require('fs/promises');
7
- var path3 = require('path');
8
- var yaml = require('yaml');
9
- var crypto = require('crypto');
10
- var google = require('@ai-sdk/google');
11
- var genai = require('@google/genai');
12
- var openai = require('@ai-sdk/openai');
13
-
14
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
-
16
- function _interopNamespace(e) {
17
- if (e && e.__esModule) return e;
18
- var n = Object.create(null);
19
- if (e) {
20
- Object.keys(e).forEach(function (k) {
21
- if (k !== 'default') {
22
- var d = Object.getOwnPropertyDescriptor(e, k);
23
- Object.defineProperty(n, k, d.get ? d : {
24
- enumerable: true,
25
- get: function () { return e[k]; }
26
- });
27
- }
28
- });
29
- }
30
- n.default = e;
31
- return Object.freeze(n);
32
- }
33
-
34
- var Handlebars__default = /*#__PURE__*/_interopDefault(Handlebars);
35
- var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
36
- var path3__namespace = /*#__PURE__*/_interopNamespace(path3);
37
- var yaml__namespace = /*#__PURE__*/_interopNamespace(yaml);
38
-
39
- // src/errors/utils.ts
40
- function wrapAsError(error, ErrorClass, options) {
41
- const cause = error instanceof Error ? error : new Error(String(error));
42
- return new ErrorClass(cause.message, { ...options, cause });
43
- }
44
-
45
- // src/errors/types.ts
46
- var ExecutionErrorCode = /* @__PURE__ */ ((ExecutionErrorCode2) => {
47
- ExecutionErrorCode2["EXECUTION_ERROR"] = "EXECUTION_ERROR";
48
- ExecutionErrorCode2["STREAM_ERROR"] = "STREAM_ERROR";
49
- ExecutionErrorCode2["RESULT_EXTRACTION_ERROR"] = "RESULT_EXTRACTION_ERROR";
50
- ExecutionErrorCode2["CANCELLED"] = "CANCELLED";
51
- ExecutionErrorCode2["VALIDATION_ERROR"] = "VALIDATION_ERROR";
52
- return ExecutionErrorCode2;
53
- })(ExecutionErrorCode || {});
54
- var ConfigurationErrorCode = /* @__PURE__ */ ((ConfigurationErrorCode2) => {
55
- ConfigurationErrorCode2["CONFIG_ERROR"] = "CONFIG_ERROR";
56
- ConfigurationErrorCode2["MISSING_API_KEY"] = "MISSING_API_KEY";
57
- ConfigurationErrorCode2["INVALID_CONFIG"] = "INVALID_CONFIG";
58
- ConfigurationErrorCode2["MISSING_REQUIRED"] = "MISSING_REQUIRED";
59
- return ConfigurationErrorCode2;
60
- })(ConfigurationErrorCode || {});
61
- var FileErrorCode = /* @__PURE__ */ ((FileErrorCode2) => {
62
- FileErrorCode2["FILE_ERROR"] = "FILE_ERROR";
63
- FileErrorCode2["UPLOAD_ERROR"] = "UPLOAD_ERROR";
64
- FileErrorCode2["DELETE_ERROR"] = "DELETE_ERROR";
65
- FileErrorCode2["NOT_FOUND"] = "NOT_FOUND";
66
- FileErrorCode2["TOO_LARGE"] = "TOO_LARGE";
67
- FileErrorCode2["UNSUPPORTED_TYPE"] = "UNSUPPORTED_TYPE";
68
- return FileErrorCode2;
69
- })(FileErrorCode || {});
70
- var AgtlantisError = class extends Error {
71
- code;
72
- cause;
73
- context;
74
- constructor(message, options) {
75
- super(message);
76
- this.name = "AgtlantisError";
77
- this.code = options.code;
78
- this.cause = options.cause;
79
- this.context = options.context;
80
- const ErrorWithCapture = Error;
81
- ErrorWithCapture.captureStackTrace?.(this, this.constructor);
82
- }
83
- get isRetryable() {
84
- return false;
85
- }
86
- toJSON() {
87
- return {
88
- name: this.name,
89
- message: this.message,
90
- code: this.code,
91
- isRetryable: this.isRetryable,
92
- context: this.context,
93
- cause: this.cause?.message,
94
- stack: this.stack
95
- };
96
- }
97
- };
98
- var ExecutionError = class _ExecutionError extends AgtlantisError {
99
- constructor(message, options = {}) {
100
- super(message, {
101
- code: options.code ?? "EXECUTION_ERROR" /* EXECUTION_ERROR */,
102
- cause: options.cause,
103
- context: options.context
104
- });
105
- this.name = "ExecutionError";
106
- }
107
- static from(error, code = "EXECUTION_ERROR" /* EXECUTION_ERROR */, context) {
108
- if (error instanceof _ExecutionError) {
109
- return error;
110
- }
111
- return wrapAsError(error, _ExecutionError, { code, context });
112
- }
113
- };
114
- var ConfigurationError = class _ConfigurationError extends AgtlantisError {
115
- constructor(message, options = {}) {
116
- super(message, {
117
- code: options.code ?? "CONFIG_ERROR" /* CONFIG_ERROR */,
118
- cause: options.cause,
119
- context: options.context
120
- });
121
- this.name = "ConfigurationError";
122
- }
123
- static from(error, code = "CONFIG_ERROR" /* CONFIG_ERROR */, context) {
124
- if (error instanceof _ConfigurationError) {
125
- return error;
126
- }
127
- return wrapAsError(error, _ConfigurationError, { code, context });
128
- }
129
- };
130
- var FileError = class _FileError extends AgtlantisError {
131
- constructor(message, options = {}) {
132
- super(message, {
133
- code: options.code ?? "FILE_ERROR" /* FILE_ERROR */,
134
- cause: options.cause,
135
- context: options.context
136
- });
137
- this.name = "FileError";
138
- }
139
- static from(error, code = "FILE_ERROR" /* FILE_ERROR */, context) {
140
- if (error instanceof _FileError) {
141
- return error;
142
- }
143
- return wrapAsError(error, _FileError, { code, context });
144
- }
145
- };
146
-
147
- // src/execution/constants.ts
148
- var ERRORS = {
149
- ALREADY_CONSUMED: "Execution already consumed",
150
- METADATA_NOT_AVAILABLE: "Metadata not available yet. Consume the execution first.",
151
- NO_RESULT: "No result available",
152
- UNKNOWN_ERROR: "Execution failed with unknown error"
153
- };
154
-
155
- // src/execution/utils.ts
156
- function getDuration(startTime) {
157
- return Date.now() - startTime;
158
- }
159
- function combineSignals(...signals) {
160
- const controller = new AbortController();
161
- for (const signal of signals) {
162
- if (signal.aborted) {
163
- controller.abort(signal.reason);
164
- return controller.signal;
165
- }
166
- signal.addEventListener("abort", () => controller.abort(signal.reason), {
167
- once: true
168
- });
169
- }
170
- return controller.signal;
171
- }
172
- var Deferred = class {
173
- promise;
174
- resolve;
175
- reject;
176
- constructor() {
177
- let res;
178
- let rej;
179
- this.promise = new Promise((resolve2, reject) => {
180
- res = resolve2;
181
- rej = reject;
182
- });
183
- this.resolve = res;
184
- this.reject = rej;
185
- }
186
- };
187
-
188
- // src/execution/shared.ts
189
- function isAbortError(error, signal) {
190
- if (error instanceof Error && error.name === "AbortError") {
191
- return true;
192
- }
193
- return signal.aborted;
194
- }
195
- function normalizeError(error) {
196
- return error instanceof Error ? error : new Error(String(error));
197
- }
198
- function determineResultStatus(cancelRequested, aborted, hasError) {
199
- if (cancelRequested || aborted) {
200
- return "canceled";
201
- }
202
- if (hasError) {
203
- return "failed";
204
- }
205
- return "succeeded";
206
- }
207
- function createHookRunner(runHooks) {
208
- let ran = false;
209
- return {
210
- ensureRun: async () => {
211
- if (!ran) {
212
- ran = true;
213
- await runHooks();
214
- }
215
- },
216
- hasRun: () => ran
217
- };
218
- }
219
-
220
- // src/execution/streaming-host.ts
221
- var StreamingExecutionHost = class {
222
- constructor(createSession, generator, userSignal) {
223
- this.createSession = createSession;
224
- this.generator = generator;
225
- this.effectiveSignal = userSignal ? combineSignals(userSignal, this.abortController.signal) : this.abortController.signal;
226
- this.consumerPromise = this.startConsuming();
227
- }
228
- abortController = new AbortController();
229
- effectiveSignal;
230
- consumerPromise;
231
- eventBuffer = [];
232
- subscribers = /* @__PURE__ */ new Set();
233
- completed = false;
234
- cleaned = false;
235
- hookRunner = null;
236
- cancelRequested = false;
237
- extractedOutcome = null;
238
- extractedSummary = null;
239
- hasDataField(event) {
240
- return "data" in event && event.data !== void 0;
241
- }
242
- hasSummaryField(event) {
243
- return "summary" in event && event.summary !== void 0;
244
- }
245
- hasErrorField(event) {
246
- return "error" in event && event.error instanceof Error;
247
- }
248
- extractResultAndMetadata(event) {
249
- const isCompleteOrError = event.type === "complete" || event.type === "error";
250
- if (!isCompleteOrError) {
251
- return;
252
- }
253
- if (this.hasErrorField(event)) {
254
- this.extractedOutcome = { type: "error", error: event.error };
255
- } else if (this.hasDataField(event)) {
256
- this.extractedOutcome = { type: "result", value: event.data };
257
- }
258
- if (this.hasSummaryField(event)) {
259
- this.extractedSummary = event.summary;
260
- }
261
- }
262
- notifySubscribers(event) {
263
- this.subscribers.forEach((fn) => fn(event));
264
- }
265
- async startConsuming() {
266
- const session = this.createSession(this.effectiveSignal);
267
- this.hookRunner = createHookRunner(() => session.runOnDoneHooks());
268
- const gen = this.generator(session);
269
- try {
270
- let next = await gen.next();
271
- while (!next.done) {
272
- this.eventBuffer.push(next.value);
273
- this.notifySubscribers(next.value);
274
- const isTerminal = next.value.type === "complete" || next.value.type === "error";
275
- if (isTerminal) {
276
- this.extractResultAndMetadata(next.value);
277
- this.abortController.abort();
278
- break;
279
- }
280
- if (this.abortController.signal.aborted) {
281
- break;
282
- }
283
- next = await gen.next();
284
- }
285
- if (next.done && next.value !== void 0) {
286
- const finalEvent = await Promise.resolve(next.value);
287
- this.eventBuffer.push(finalEvent);
288
- this.notifySubscribers(finalEvent);
289
- this.extractResultAndMetadata(finalEvent);
290
- const isTerminal = finalEvent.type === "complete" || finalEvent.type === "error";
291
- if (isTerminal) {
292
- this.abortController.abort();
293
- }
294
- }
295
- return this.buildResult(session);
296
- } catch (error) {
297
- const errorObj = normalizeError(error);
298
- if (isAbortError(error, this.abortController.signal)) {
299
- return {
300
- success: false,
301
- aborted: true,
302
- error: errorObj,
303
- summary: await session.getSummary()
304
- };
305
- }
306
- const errorEvent = await session.fail(errorObj);
307
- this.eventBuffer.push(errorEvent);
308
- this.notifySubscribers(errorEvent);
309
- this.extractResultAndMetadata(errorEvent);
310
- this.abortController.abort();
311
- return this.buildResult(session);
312
- } finally {
313
- this.completed = true;
314
- await this.hookRunner?.ensureRun();
315
- await gen.return(void 0);
316
- }
317
- }
318
- async buildResult(session) {
319
- const summary = this.extractedSummary ?? await session.getSummary();
320
- if (this.extractedOutcome?.type === "error") {
321
- return {
322
- success: false,
323
- aborted: false,
324
- error: this.extractedOutcome.error,
325
- summary
326
- };
327
- }
328
- if (this.extractedOutcome?.type === "result") {
329
- return {
330
- success: true,
331
- result: this.extractedOutcome.value,
332
- summary
333
- };
334
- }
335
- return {
336
- success: false,
337
- aborted: true,
338
- error: new Error(ERRORS.NO_RESULT),
339
- summary
340
- };
341
- }
342
- /**
343
- * Get the event stream.
344
- * Returns buffered events first, then real-time events.
345
- * Can be called multiple times - replays buffer each time.
346
- */
347
- async *stream() {
348
- let index = 0;
349
- while (index < this.eventBuffer.length) {
350
- yield this.eventBuffer[index++];
351
- }
352
- if (this.completed) {
353
- return;
354
- }
355
- const queue = [];
356
- let pending = new Deferred();
357
- const subscriber = (event) => {
358
- queue.push(event);
359
- pending.resolve();
360
- };
361
- this.subscribers.add(subscriber);
362
- try {
363
- while (!this.completed || queue.length > 0) {
364
- if (queue.length > 0) {
365
- yield queue.shift();
366
- } else if (!this.completed) {
367
- await pending.promise;
368
- pending = new Deferred();
369
- }
370
- }
371
- } finally {
372
- this.subscribers.delete(subscriber);
373
- }
374
- }
375
- cancel() {
376
- this.cancelRequested = true;
377
- this.abortController.abort();
378
- }
379
- async cleanup() {
380
- if (this.cleaned) {
381
- return;
382
- }
383
- this.cleaned = true;
384
- if (!this.completed) {
385
- this.cancel();
386
- await this.consumerPromise.catch(() => {
387
- });
388
- }
389
- this.subscribers.clear();
390
- await this.hookRunner?.ensureRun();
391
- }
392
- async [Symbol.asyncDispose]() {
393
- await this.cleanup();
394
- }
395
- /**
396
- * Get the execution result with status, summary, and all events.
397
- * Never throws - returns a discriminated union with status.
398
- */
399
- async result() {
400
- const internal = await this.consumerPromise;
401
- const events = Object.freeze([...this.eventBuffer]);
402
- if (internal.success) {
403
- return {
404
- status: "succeeded",
405
- value: internal.result,
406
- summary: internal.summary,
407
- events
408
- };
409
- }
410
- if (this.cancelRequested || internal.aborted) {
411
- return {
412
- status: "canceled",
413
- summary: internal.summary,
414
- events
415
- };
416
- }
417
- return {
418
- status: "failed",
419
- error: internal.error,
420
- summary: internal.summary,
421
- events
422
- };
423
- }
424
- };
425
-
426
- // src/execution/simple-host.ts
427
- var SimpleExecutionHost = class {
428
- abortController = new AbortController();
429
- effectiveSignal;
430
- consumerPromise;
431
- cachedSession;
432
- startTime = Date.now();
433
- cancelRequested = false;
434
- constructor(createSession, fn, userSignal) {
435
- this.effectiveSignal = userSignal ? combineSignals(userSignal, this.abortController.signal) : this.abortController.signal;
436
- this.consumerPromise = this.execute(createSession, fn);
437
- }
438
- async execute(createSession, fn) {
439
- const session = createSession(this.effectiveSignal);
440
- this.cachedSession = session;
441
- const hookRunner = createHookRunner(() => session.runOnDoneHooks());
442
- session.notifyExecutionStart();
443
- try {
444
- const result = await fn(session);
445
- await session.notifyExecutionDone(result, this.startTime);
446
- return {
447
- success: true,
448
- result,
449
- summary: await session.getSummary()
450
- };
451
- } catch (error) {
452
- const errorObj = normalizeError(error);
453
- const isCancellation = isAbortError(error, this.abortController.signal);
454
- if (!isCancellation) {
455
- await session.notifyExecutionError(errorObj, this.startTime);
456
- }
457
- return {
458
- success: false,
459
- error: errorObj,
460
- aborted: isCancellation,
461
- summary: await session.getSummary()
462
- };
463
- } finally {
464
- await hookRunner.ensureRun();
465
- }
466
- }
467
- /**
468
- * Request cancellation of the execution.
469
- * Aborts the current LLM call if in progress.
470
- * No-op if execution already completed.
471
- */
472
- cancel() {
473
- this.cancelRequested = true;
474
- this.abortController.abort();
475
- }
476
- /**
477
- * Get the execution result with status and summary.
478
- * Never throws - returns a discriminated union with status.
479
- */
480
- async result() {
481
- const internal = await this.consumerPromise;
482
- if (internal.success) {
483
- return {
484
- status: "succeeded",
485
- value: internal.result,
486
- summary: internal.summary
487
- };
488
- }
489
- if (this.cancelRequested || internal.aborted) {
490
- return {
491
- status: "canceled",
492
- summary: internal.summary
493
- };
494
- }
495
- return {
496
- status: "failed",
497
- error: internal.error,
498
- summary: internal.summary
499
- };
500
- }
501
- /**
502
- * Cleanup resources.
503
- * For SimpleExecution, hooks are already run during execution,
504
- * so this is intentionally a no-op.
505
- */
506
- async cleanup() {
507
- }
508
- async [Symbol.asyncDispose]() {
509
- await this.cleanup();
510
- }
511
- };
512
-
513
- // src/execution/mapping.ts
514
- function mapExecution(execution, fn) {
515
- if ("stream" in execution) {
516
- return mapStreamingExecution(execution, fn);
517
- }
518
- return mapSimpleExecution(execution, fn);
519
- }
520
- function mapExecutionResult(execution, fn) {
521
- if ("stream" in execution) {
522
- return mapStreamingExecutionResult(execution, fn);
523
- }
524
- return mapSimpleExecution(execution, fn);
525
- }
526
- function mapStreamingExecution(execution, fn) {
527
- return {
528
- stream() {
529
- const original = execution.stream();
530
- return {
531
- [Symbol.asyncIterator]() {
532
- const iter = original[Symbol.asyncIterator]();
533
- return {
534
- async next() {
535
- const { value, done } = await iter.next();
536
- if (done) return { value: void 0, done: true };
537
- const event = value;
538
- if (event.type === "error") {
539
- return { value: event, done: false };
540
- }
541
- const { metrics, ...pureEvent } = event;
542
- try {
543
- const mapped = await fn(pureEvent);
544
- return {
545
- value: { ...mapped, metrics },
546
- done: false
547
- };
548
- } catch (err) {
549
- const errorEvent = {
550
- type: "error",
551
- error: normalizeError(err),
552
- metrics
553
- };
554
- return { value: errorEvent, done: false };
555
- }
556
- }
557
- };
558
- }
559
- };
560
- },
561
- async result() {
562
- const original = await execution.result();
563
- if (original.status !== "succeeded") {
564
- return original;
565
- }
566
- try {
567
- const mappedEvents = [];
568
- for (const event of original.events) {
569
- if (event.type === "error") {
570
- mappedEvents.push(event);
571
- continue;
572
- }
573
- const { metrics, ...pureEvent } = event;
574
- const mapped = await fn(pureEvent);
575
- mappedEvents.push({ ...mapped, metrics });
576
- }
577
- const completionEvent = mappedEvents.find((e) => e.type === "complete");
578
- return {
579
- status: "succeeded",
580
- value: completionEvent.data,
581
- events: mappedEvents,
582
- summary: original.summary
583
- };
584
- } catch (err) {
585
- return {
586
- status: "failed",
587
- error: normalizeError(err),
588
- events: original.events,
589
- summary: original.summary
590
- };
591
- }
592
- },
593
- cancel: () => execution.cancel(),
594
- cleanup: () => execution.cleanup(),
595
- [Symbol.asyncDispose]: () => execution[Symbol.asyncDispose]()
596
- };
597
- }
598
- function mapStreamingExecutionResult(execution, fn) {
599
- return {
600
- stream() {
601
- const original = execution.stream();
602
- return {
603
- [Symbol.asyncIterator]() {
604
- const iter = original[Symbol.asyncIterator]();
605
- return {
606
- async next() {
607
- const { value, done } = await iter.next();
608
- if (done) return { value: void 0, done: true };
609
- const event = value;
610
- if (event.type === "complete") {
611
- const { metrics, ...rest } = event;
612
- try {
613
- const mapped = await fn(rest.data);
614
- return {
615
- value: { type: "complete", data: mapped, summary: rest.summary, metrics },
616
- done: false
617
- };
618
- } catch (err) {
619
- const errorEvent = {
620
- type: "error",
621
- error: normalizeError(err),
622
- metrics
623
- };
624
- return { value: errorEvent, done: false };
625
- }
626
- }
627
- return { value: event, done: false };
628
- }
629
- };
630
- }
631
- };
632
- },
633
- async result() {
634
- const original = await execution.result();
635
- if (original.status !== "succeeded") {
636
- return original;
637
- }
638
- try {
639
- const mapped = await fn(original.value);
640
- const mappedEvents = original.events.map((event) => {
641
- if (event.type === "complete") {
642
- return { ...event, data: mapped };
643
- }
644
- return event;
645
- });
646
- return {
647
- status: "succeeded",
648
- value: mapped,
649
- events: mappedEvents,
650
- summary: original.summary
651
- };
652
- } catch (err) {
653
- return {
654
- status: "failed",
655
- error: normalizeError(err),
656
- events: original.events,
657
- summary: original.summary
658
- };
659
- }
660
- },
661
- cancel: () => execution.cancel(),
662
- cleanup: () => execution.cleanup(),
663
- [Symbol.asyncDispose]: () => execution[Symbol.asyncDispose]()
664
- };
665
- }
666
- function mapSimpleExecution(execution, fn) {
667
- return {
668
- async result() {
669
- const original = await execution.result();
670
- if (original.status !== "succeeded") {
671
- return original;
672
- }
673
- try {
674
- const mapped = await fn(original.value);
675
- return {
676
- status: "succeeded",
677
- value: mapped,
678
- summary: original.summary
679
- };
680
- } catch (err) {
681
- return {
682
- status: "failed",
683
- error: normalizeError(err),
684
- summary: original.summary
685
- };
686
- }
687
- },
688
- cancel: () => execution.cancel(),
689
- cleanup: () => execution.cleanup(),
690
- [Symbol.asyncDispose]: () => execution[Symbol.asyncDispose]()
691
- };
692
- }
693
-
694
- // src/observability/logger.ts
695
- var noopLogger = {};
696
- function createLogger(handlers) {
697
- return handlers;
698
- }
699
- var TOOL_DESCRIPTIONS = {
700
- reportProgress: "[OPTIONAL] Report progress during task execution. Use this to show intermediate work. You may call this multiple times, then you MUST call tools::submitResult.",
701
- submitResult: "[REQUIRED] Submit the final result. You MUST call this exactly once to complete the task. Without this call, the task FAILS."
702
- };
703
- var TOOL_CALLING_PROTOCOL = `## CRITICAL INSTRUCTION - READ CAREFULLY
704
-
705
- You have 2 tools available:
706
- 1. reportProgress - [OPTIONAL] Show intermediate work (multiple times)
707
- 2. submitResult - [REQUIRED] Submit your final answer
708
-
709
- \u26A0\uFE0F IMPORTANT RULES:
710
- - You may call reportProgress 0-3 times to show progress
711
- - You MUST call submitResult exactly once to complete the task
712
- - After calling reportProgress, you MUST call submitResult in your NEXT response
713
- - If you call reportProgress more than 3 times without submitResult, the task FAILS
714
- - The task is NOT complete until submitResult is called
715
-
716
- CORRECT SEQUENCE:
717
- 1. [Optional] reportProgress
718
- 2. [Required] submitResult (exactly once)
719
-
720
- \u274C WRONG: reportProgress \u2192 reportProgress \u2192 reportProgress \u2192 reportProgress (no submitResult = FAIL)
721
- \u2705 CORRECT: reportProgress \u2192 submitResult (SUCCESS)`;
722
- function defineProgressivePattern(config) {
723
- return new ProgressivePattern(config.progressSchema, config.resultSchema);
724
- }
725
- var ProgressivePattern = class {
726
- constructor(progressSchema, resultSchema) {
727
- this.progressSchema = progressSchema;
728
- this.resultSchema = resultSchema;
729
- }
730
- lastParseError = null;
731
- /**
732
- * Runs the pattern within an existing session. Use this for composing
733
- * multiple patterns or when you need fine-grained control over the session.
734
- *
735
- * @param session - The streaming session to run within
736
- * @param options - Stream options including:
737
- * - `stopWhen` - Additional stop conditions (combined with default `hasToolCall('submitResult')`)
738
- * - `protocol` - Custom protocol instructions (replaces default `TOOL_CALLING_PROTOCOL`)
739
- * - All other `streamText` options except `tools`, `toolChoice`, `stopWhen`
740
- *
741
- * @example Basic usage
742
- * ```typescript
743
- * provider.streamingExecution(async function*(session) {
744
- * yield* pattern.runInSession(session, {
745
- * system: 'You are an analyzer.',
746
- * messages: [{ role: 'user', content: 'Analyze...' }],
747
- * });
748
- * });
749
- * ```
750
- *
751
- * @example With custom stopWhen
752
- * ```typescript
753
- * yield* pattern.runInSession(session, {
754
- * prompt: 'Analyze...',
755
- * stopWhen: stepCountIs(5), // Combined: submitResult OR 5 steps
756
- * });
757
- * ```
758
- */
759
- async *runInSession(session, options) {
760
- const {
761
- tools: userTools,
762
- system,
763
- stopWhen: userStopWhen,
764
- protocol,
765
- ...restOptions
766
- } = options;
767
- const internalTools = this.createTools();
768
- const allTools = { ...userTools, ...internalTools };
769
- const systemString = typeof system === "string" ? system : void 0;
770
- const fullSystem = this.renderSystemPrompt(systemString, protocol);
771
- const defaultStopCondition = ai.hasToolCall("submitResult");
772
- const stopConditions = this.combineStopConditions(defaultStopCondition, userStopWhen);
773
- const stream = session.streamText({
774
- ...restOptions,
775
- system: fullSystem,
776
- tools: allTools,
777
- toolChoice: "required",
778
- stopWhen: stopConditions
779
- });
780
- let result = null;
781
- for await (const part of stream.fullStream) {
782
- if (part.type === "tool-call") {
783
- if (part.toolName === "reportProgress") {
784
- const input = "input" in part ? part.input : void 0;
785
- const progressData = this.parseProgressInput(input);
786
- if (progressData !== null) {
787
- yield session.emit({
788
- type: "progress",
789
- data: progressData
790
- });
791
- }
792
- } else if (part.toolName === "submitResult") {
793
- const input = "input" in part ? part.input : void 0;
794
- result = this.parseResultInput(input);
795
- }
796
- }
797
- }
798
- if (result === null) {
799
- const baseMsg = "ProgressivePattern: No result received.";
800
- const detail = this.lastParseError ? ` Last parse error: ${this.lastParseError.message}` : " The LLM did not call submitResult tool.";
801
- throw new Error(baseMsg + detail);
802
- }
803
- const completeEvent = await session.done(result);
804
- yield completeEvent;
805
- return completeEvent;
806
- }
807
- /**
808
- * Standalone execution that creates a new session internally.
809
- * Use this for simple, single-pattern executions.
810
- *
811
- * @param provider - The AI provider to use
812
- * @param options - Stream options including:
813
- * - `stopWhen` - Additional stop conditions (combined with default `hasToolCall('submitResult')`)
814
- * - `protocol` - Custom protocol instructions (replaces default `TOOL_CALLING_PROTOCOL`)
815
- *
816
- * @example Basic usage
817
- * ```typescript
818
- * for await (const event of pattern.run(provider, {
819
- * system: 'You are an analyzer.',
820
- * prompt: 'Analyze this document...',
821
- * })) {
822
- * if (event.type === 'progress') {
823
- * console.log('Progress:', event.data);
824
- * } else if (event.type === 'complete') {
825
- * console.log('Result:', event.data);
826
- * }
827
- * }
828
- * ```
829
- *
830
- * @example With step limit
831
- * ```typescript
832
- * import { stepCountIs } from 'ai';
833
- *
834
- * for await (const event of pattern.run(provider, {
835
- * prompt: 'Analyze...',
836
- * stopWhen: stepCountIs(10),
837
- * })) { ... }
838
- * ```
839
- */
840
- run(provider, options) {
841
- const self = this;
842
- const execution = provider.streamingExecution(async function* (session) {
843
- return yield* self.runInSession(session, options);
844
- });
845
- return execution.stream();
846
- }
847
- createTools() {
848
- return {
849
- reportProgress: ai.tool({
850
- description: TOOL_DESCRIPTIONS.reportProgress,
851
- inputSchema: zod.z.object({
852
- data: this.progressSchema
853
- }),
854
- execute: async () => ({
855
- status: "progress_recorded",
856
- instruction: "After all progress reports, you MUST call tools::submitResult to complete the task."
857
- })
858
- }),
859
- submitResult: ai.tool({
860
- description: TOOL_DESCRIPTIONS.submitResult,
861
- inputSchema: zod.z.object({
862
- data: this.resultSchema
863
- }),
864
- execute: async () => ({
865
- status: "result_submitted",
866
- message: "Task completed successfully."
867
- })
868
- })
869
- };
870
- }
871
- parseJsonWrapper(input, schema) {
872
- try {
873
- if (!input || typeof input !== "object") return null;
874
- const wrapper = input;
875
- if (wrapper.data === void 0) return null;
876
- const parsed = typeof wrapper.data === "string" ? JSON.parse(wrapper.data) : wrapper.data;
877
- return schema.parse(parsed);
878
- } catch (error) {
879
- this.lastParseError = error instanceof Error ? error : new Error(String(error));
880
- return null;
881
- }
882
- }
883
- parseProgressInput(input) {
884
- return this.parseJsonWrapper(input, this.progressSchema);
885
- }
886
- parseResultInput(input) {
887
- return this.parseJsonWrapper(input, this.resultSchema);
888
- }
889
- combineStopConditions(defaultCondition, userConditions) {
890
- if (!userConditions) {
891
- return [defaultCondition];
892
- }
893
- const userArray = Array.isArray(userConditions) ? userConditions : [userConditions];
894
- return [defaultCondition, ...userArray];
895
- }
896
- renderSystemPrompt(userSystem, protocol) {
897
- const protocolText = protocol ?? TOOL_CALLING_PROTOCOL;
898
- return userSystem ? `${userSystem}
899
-
900
- ${protocolText}` : protocolText;
901
- }
902
- };
903
-
904
- // src/pricing/validator.ts
905
- function validatePriceValue(value, fieldName, context) {
906
- if (!Number.isFinite(value)) {
907
- throw new Error(`${context}: ${fieldName} must be a finite number`);
908
- }
909
- if (value < 0) {
910
- throw new Error(`${context}: ${fieldName} cannot be negative`);
911
- }
912
- }
913
- function validateModelPricing(pricing, context) {
914
- validatePriceValue(
915
- pricing.inputPricePerMillion,
916
- "inputPricePerMillion",
917
- context
918
- );
919
- validatePriceValue(
920
- pricing.outputPricePerMillion,
921
- "outputPricePerMillion",
922
- context
923
- );
924
- if (pricing.cachedInputPricePerMillion !== void 0) {
925
- validatePriceValue(
926
- pricing.cachedInputPricePerMillion,
927
- "cachedInputPricePerMillion",
928
- context
929
- );
930
- }
931
- }
932
- function validateProviderPricing(pricing, providerContext) {
933
- for (const [model, modelPricing] of Object.entries(pricing)) {
934
- const context = providerContext ? `${providerContext}/${model}` : model;
935
- validateModelPricing(modelPricing, context);
936
- }
937
- }
938
- function validatePricingConfig(config) {
939
- if (config.providers) {
940
- for (const [providerKey, pricing] of Object.entries(config.providers)) {
941
- if (pricing) {
942
- validateProviderPricing(pricing, providerKey);
943
- }
944
- }
945
- }
946
- if (config.fallback) {
947
- validateModelPricing(config.fallback, "fallback");
948
- }
949
- }
950
-
951
- // src/pricing/defaults.ts
952
- var OPENAI_PRICING = {
953
- "gpt-4o": { inputPricePerMillion: 2.5, outputPricePerMillion: 10 },
954
- "gpt-4o-mini": { inputPricePerMillion: 0.15, outputPricePerMillion: 0.6 },
955
- "gpt-4-turbo": { inputPricePerMillion: 10, outputPricePerMillion: 30 },
956
- "gpt-4-turbo-preview": {
957
- inputPricePerMillion: 10,
958
- outputPricePerMillion: 30
959
- },
960
- "gpt-4": { inputPricePerMillion: 30, outputPricePerMillion: 60 },
961
- "gpt-4-32k": { inputPricePerMillion: 60, outputPricePerMillion: 120 },
962
- "gpt-3.5-turbo": { inputPricePerMillion: 0.5, outputPricePerMillion: 1.5 },
963
- "gpt-3.5-turbo-16k": {
964
- inputPricePerMillion: 3,
965
- outputPricePerMillion: 4
966
- },
967
- "o1": { inputPricePerMillion: 15, outputPricePerMillion: 60 },
968
- "o1-mini": { inputPricePerMillion: 3, outputPricePerMillion: 12 },
969
- "o1-preview": { inputPricePerMillion: 15, outputPricePerMillion: 60 },
970
- "o3": { inputPricePerMillion: 20, outputPricePerMillion: 80 },
971
- "o3-mini": { inputPricePerMillion: 4, outputPricePerMillion: 16 }
972
- };
973
- var GOOGLE_PRICING = {
974
- "gemini-2.5-flash": {
975
- inputPricePerMillion: 0.15,
976
- outputPricePerMillion: 0.6,
977
- cachedInputPricePerMillion: 0.0375
978
- },
979
- "gemini-2.5-flash-lite": {
980
- inputPricePerMillion: 0.075,
981
- outputPricePerMillion: 0.3,
982
- cachedInputPricePerMillion: 0.01875
983
- },
984
- "gemini-2.5-pro": {
985
- inputPricePerMillion: 1.25,
986
- outputPricePerMillion: 10,
987
- cachedInputPricePerMillion: 0.3125
988
- },
989
- "gemini-2.0-flash": {
990
- inputPricePerMillion: 0.1,
991
- outputPricePerMillion: 0.4,
992
- cachedInputPricePerMillion: 0.025
993
- },
994
- "gemini-2.0-flash-lite": {
995
- inputPricePerMillion: 0.075,
996
- outputPricePerMillion: 0.3,
997
- cachedInputPricePerMillion: 0.01875
998
- },
999
- "gemini-1.5-pro": {
1000
- inputPricePerMillion: 1.25,
1001
- outputPricePerMillion: 5,
1002
- cachedInputPricePerMillion: 0.3125
1003
- },
1004
- "gemini-1.5-flash": {
1005
- inputPricePerMillion: 0.075,
1006
- outputPricePerMillion: 0.3,
1007
- cachedInputPricePerMillion: 0.01875
1008
- },
1009
- "gemini-1.5-flash-8b": {
1010
- inputPricePerMillion: 0.0375,
1011
- outputPricePerMillion: 0.15,
1012
- cachedInputPricePerMillion: 0.01
1013
- },
1014
- "gemini-pro": { inputPricePerMillion: 0.5, outputPricePerMillion: 1.5 }
1015
- };
1016
- var ANTHROPIC_PRICING = {
1017
- "claude-opus-4-5-20250514": {
1018
- inputPricePerMillion: 15,
1019
- outputPricePerMillion: 75,
1020
- cachedInputPricePerMillion: 1.875
1021
- },
1022
- "claude-sonnet-4-20250514": {
1023
- inputPricePerMillion: 3,
1024
- outputPricePerMillion: 15,
1025
- cachedInputPricePerMillion: 0.375
1026
- },
1027
- "claude-3-5-sonnet-20241022": {
1028
- inputPricePerMillion: 3,
1029
- outputPricePerMillion: 15,
1030
- cachedInputPricePerMillion: 0.375
1031
- },
1032
- "claude-3-5-haiku-20241022": {
1033
- inputPricePerMillion: 0.8,
1034
- outputPricePerMillion: 4,
1035
- cachedInputPricePerMillion: 0.1
1036
- },
1037
- "claude-3-opus-20240229": {
1038
- inputPricePerMillion: 15,
1039
- outputPricePerMillion: 75,
1040
- cachedInputPricePerMillion: 1.875
1041
- },
1042
- "claude-3-sonnet-20240229": {
1043
- inputPricePerMillion: 3,
1044
- outputPricePerMillion: 15,
1045
- cachedInputPricePerMillion: 0.375
1046
- },
1047
- "claude-3-haiku-20240307": {
1048
- inputPricePerMillion: 0.25,
1049
- outputPricePerMillion: 1.25,
1050
- cachedInputPricePerMillion: 0.03
1051
- }
1052
- };
1053
- var DEFAULT_PRICING_CONFIG = {
1054
- providers: {
1055
- openai: OPENAI_PRICING,
1056
- google: GOOGLE_PRICING,
1057
- anthropic: ANTHROPIC_PRICING
1058
- },
1059
- fallback: {
1060
- inputPricePerMillion: 1,
1061
- outputPricePerMillion: 5
1062
- }
1063
- };
1064
- var DEFAULT_FALLBACK_PRICING = {
1065
- inputPricePerMillion: 1,
1066
- outputPricePerMillion: 5
1067
- };
1068
-
1069
- // src/pricing/config.ts
1070
- var globalConfig;
1071
- function configurePricing(config) {
1072
- if (config) {
1073
- validatePricingConfig(config);
1074
- }
1075
- globalConfig = config;
1076
- }
1077
- function getPricingConfig() {
1078
- return globalConfig;
1079
- }
1080
- function resetPricingConfig() {
1081
- globalConfig = void 0;
1082
- }
1083
- function getEffectivePricing(model, provider) {
1084
- if (globalConfig?.providers?.[provider]?.[model]) {
1085
- return {
1086
- pricing: globalConfig.providers[provider][model],
1087
- source: "global"
1088
- };
1089
- }
1090
- const defaultPricing = DEFAULT_PRICING_CONFIG.providers[provider];
1091
- if (defaultPricing?.[model]) {
1092
- return {
1093
- pricing: defaultPricing[model],
1094
- source: "default"
1095
- };
1096
- }
1097
- return {
1098
- pricing: globalConfig?.fallback ?? DEFAULT_PRICING_CONFIG.fallback ?? DEFAULT_FALLBACK_PRICING,
1099
- source: "fallback"
1100
- };
1101
- }
1102
-
1103
- // src/pricing/calculator.ts
1104
- var TOKENS_PER_MILLION = 1e6;
1105
- function getModelPricing(model, provider, providerPricing) {
1106
- if (providerPricing?.[model]) {
1107
- return providerPricing[model];
1108
- }
1109
- const globalConfig2 = getPricingConfig();
1110
- if (globalConfig2?.providers?.[provider]?.[model]) {
1111
- return globalConfig2.providers[provider][model];
1112
- }
1113
- const defaultProviderPricing = DEFAULT_PRICING_CONFIG.providers[provider];
1114
- if (defaultProviderPricing?.[model]) {
1115
- return defaultProviderPricing[model];
1116
- }
1117
- return globalConfig2?.fallback ?? DEFAULT_PRICING_CONFIG.fallback ?? DEFAULT_FALLBACK_PRICING;
1118
- }
1119
- function validateCostParams(params) {
1120
- const { inputTokens, outputTokens, cachedInputTokens = 0 } = params;
1121
- if (inputTokens < 0 || outputTokens < 0 || cachedInputTokens < 0) {
1122
- throw new Error("Token counts must be non-negative");
1123
- }
1124
- if (cachedInputTokens > inputTokens) {
1125
- throw new Error("cachedInputTokens cannot exceed inputTokens");
1126
- }
1127
- if (!Number.isFinite(inputTokens) || !Number.isFinite(outputTokens) || !Number.isFinite(cachedInputTokens)) {
1128
- throw new Error("Token counts must be finite numbers");
1129
- }
1130
- }
1131
- function calculateCost(params, providerPricing) {
1132
- validateCostParams(params);
1133
- const {
1134
- inputTokens,
1135
- outputTokens,
1136
- cachedInputTokens = 0,
1137
- model,
1138
- provider
1139
- } = params;
1140
- const pricing = getModelPricing(model, provider, providerPricing);
1141
- const nonCachedInputTokens = inputTokens - cachedInputTokens;
1142
- const inputCost = nonCachedInputTokens / TOKENS_PER_MILLION * pricing.inputPricePerMillion;
1143
- const outputCost = outputTokens / TOKENS_PER_MILLION * pricing.outputPricePerMillion;
1144
- const cachedInputPricePerMillion = pricing.cachedInputPricePerMillion ?? pricing.inputPricePerMillion;
1145
- const cachedInputCost = cachedInputTokens / TOKENS_PER_MILLION * cachedInputPricePerMillion;
1146
- return {
1147
- total: inputCost + outputCost + cachedInputCost,
1148
- inputCost,
1149
- outputCost,
1150
- cachedInputCost
1151
- };
1152
- }
1153
- function calculateCostFromUsage(usage, model, provider, providerPricing) {
1154
- return calculateCost(
1155
- {
1156
- inputTokens: usage.inputTokens ?? 0,
1157
- outputTokens: usage.outputTokens ?? 0,
1158
- cachedInputTokens: usage.inputTokenDetails?.cacheReadTokens ?? 0,
1159
- model,
1160
- provider
1161
- },
1162
- providerPricing
1163
- );
1164
- }
1165
- function calculateTotalCost(calls, providerPricing) {
1166
- const costByModel = {};
1167
- let totalCost = 0;
1168
- for (const call of calls) {
1169
- const cost = calculateCostFromUsage(
1170
- call.usage,
1171
- call.model,
1172
- call.provider,
1173
- providerPricing
1174
- );
1175
- totalCost += cost.total;
1176
- const key = `${call.provider}/${call.model}`;
1177
- costByModel[key] = (costByModel[key] ?? 0) + cost.total;
1178
- }
1179
- return { totalCost, costByModel };
1180
- }
1181
-
1182
- // src/prompt/errors.ts
1183
- var PromptErrorCode = /* @__PURE__ */ ((PromptErrorCode2) => {
1184
- PromptErrorCode2["PROMPT_ERROR"] = "PROMPT_ERROR";
1185
- PromptErrorCode2["NOT_FOUND"] = "PROMPT_NOT_FOUND";
1186
- PromptErrorCode2["INVALID_FORMAT"] = "PROMPT_INVALID_FORMAT";
1187
- PromptErrorCode2["TEMPLATE_ERROR"] = "PROMPT_TEMPLATE_ERROR";
1188
- PromptErrorCode2["IO_ERROR"] = "PROMPT_IO_ERROR";
1189
- return PromptErrorCode2;
1190
- })(PromptErrorCode || {});
1191
- var PromptError = class _PromptError extends AgtlantisError {
1192
- constructor(message, options = {}) {
1193
- super(message, {
1194
- code: options.code ?? "PROMPT_ERROR" /* PROMPT_ERROR */,
1195
- cause: options.cause,
1196
- context: options.context
1197
- });
1198
- this.name = "PromptError";
1199
- }
1200
- /**
1201
- * Creates a PromptError from an unknown error.
1202
- */
1203
- static from(error, code = "PROMPT_ERROR" /* PROMPT_ERROR */, context) {
1204
- if (error instanceof _PromptError) {
1205
- return error;
1206
- }
1207
- const cause = error instanceof Error ? error : new Error(String(error));
1208
- return new _PromptError(cause.message, { code, cause, context });
1209
- }
1210
- };
1211
- var PromptNotFoundError = class extends PromptError {
1212
- promptId;
1213
- version;
1214
- constructor(promptId, version, options = {}) {
1215
- const message = version ? `Prompt '${promptId}' version '${version}' not found` : `Prompt '${promptId}' not found`;
1216
- super(message, {
1217
- code: "PROMPT_NOT_FOUND" /* NOT_FOUND */,
1218
- cause: options.cause,
1219
- context: { promptId, version, ...options.context }
1220
- });
1221
- this.name = "PromptNotFoundError";
1222
- this.promptId = promptId;
1223
- this.version = version;
1224
- }
1225
- };
1226
- var PromptInvalidFormatError = class extends PromptError {
1227
- promptId;
1228
- details;
1229
- constructor(promptId, details, options = {}) {
1230
- super(`Invalid format for prompt '${promptId}': ${details}`, {
1231
- code: "PROMPT_INVALID_FORMAT" /* INVALID_FORMAT */,
1232
- cause: options.cause,
1233
- context: { promptId, details, ...options.context }
1234
- });
1235
- this.name = "PromptInvalidFormatError";
1236
- this.promptId = promptId;
1237
- this.details = details;
1238
- }
1239
- };
1240
- var PromptTemplateError = class extends PromptError {
1241
- promptId;
1242
- details;
1243
- constructor(promptId, details, options = {}) {
1244
- super(`Template compilation failed for prompt '${promptId}': ${details}`, {
1245
- code: "PROMPT_TEMPLATE_ERROR" /* TEMPLATE_ERROR */,
1246
- cause: options.cause,
1247
- context: { promptId, details, ...options.context }
1248
- });
1249
- this.name = "PromptTemplateError";
1250
- this.promptId = promptId;
1251
- this.details = details;
1252
- }
1253
- };
1254
- var PromptIOError = class extends PromptError {
1255
- operation;
1256
- path;
1257
- constructor(operation, path5, options = {}) {
1258
- const opText = operation === "list" ? "list prompts in" : `${operation} prompt file`;
1259
- super(`Failed to ${opText}: ${path5}`, {
1260
- code: "PROMPT_IO_ERROR" /* IO_ERROR */,
1261
- cause: options.cause,
1262
- context: { operation, path: path5, ...options.context }
1263
- });
1264
- this.name = "PromptIOError";
1265
- this.operation = operation;
1266
- this.path = path5;
1267
- }
1268
- };
1269
-
1270
- // src/prompt/template.ts
1271
- var handlebars = Handlebars__default.default.create();
1272
- handlebars.registerHelper("add", (a, b) => {
1273
- const numA = Number(a);
1274
- const numB = Number(b);
1275
- if (Number.isNaN(numA) || Number.isNaN(numB)) {
1276
- return NaN;
1277
- }
1278
- return numA + numB;
1279
- });
1280
- function wrapTemplateError(promptId, error) {
1281
- const message = error instanceof Error ? error.message : String(error);
1282
- const cause = error instanceof Error ? error : void 0;
1283
- return new PromptTemplateError(promptId, message, { cause });
1284
- }
1285
- function compileTemplate(template, promptId) {
1286
- try {
1287
- const compiled = handlebars.compile(template, {
1288
- strict: true,
1289
- noEscape: true
1290
- });
1291
- return (input) => {
1292
- try {
1293
- return compiled(input);
1294
- } catch (error) {
1295
- throw wrapTemplateError(promptId, error);
1296
- }
1297
- };
1298
- } catch (error) {
1299
- throw wrapTemplateError(promptId, error);
1300
- }
1301
- }
1302
-
1303
- // src/prompt/prompt-template.ts
1304
- var PromptTemplate = class _PromptTemplate {
1305
- constructor(id, version, system, userTemplate) {
1306
- this.id = id;
1307
- this.version = version;
1308
- this.system = system;
1309
- this.userTemplate = userTemplate;
1310
- }
1311
- /**
1312
- * Creates a PromptTemplate instance from raw data.
1313
- *
1314
- * @param data - Raw prompt template data
1315
- * @returns PromptTemplate instance
1316
- */
1317
- static from(data) {
1318
- return new _PromptTemplate(data.id, data.version, data.system, data.userTemplate);
1319
- }
1320
- /**
1321
- * Compiles templates and returns a PromptRenderer.
1322
- *
1323
- * @typeParam TSystemInput - Type of input for system prompt template
1324
- * @typeParam TUserInput - Type of input for user prompt template (defaults to TSystemInput)
1325
- * @returns Compiled prompt renderer with renderSystemPrompt and renderUserPrompt functions
1326
- * @throws {PromptTemplateError} If template compilation fails
1327
- *
1328
- * @example
1329
- * ```typescript
1330
- * // Different input types for system and user prompts
1331
- * const renderer = template.compile<SessionCtx, TurnCtx>();
1332
- *
1333
- * // Same input type for both
1334
- * const simpleRenderer = template.compile<CommonCtx>();
1335
- * ```
1336
- */
1337
- compile() {
1338
- return {
1339
- id: this.id,
1340
- version: this.version,
1341
- renderSystemPrompt: compileTemplate(this.system, this.id),
1342
- renderUserPrompt: compileTemplate(this.userTemplate, this.id)
1343
- };
1344
- }
1345
- /**
1346
- * Returns raw data representation.
1347
- * Useful for serialization or passing to repository.write().
1348
- */
1349
- toData() {
1350
- return {
1351
- id: this.id,
1352
- version: this.version,
1353
- system: this.system,
1354
- userTemplate: this.userTemplate
1355
- };
1356
- }
1357
- };
1358
- function toErrorCause(error) {
1359
- return error instanceof Error ? error : void 0;
1360
- }
1361
- function toErrorMessage(error) {
1362
- return error instanceof Error ? error.message : String(error);
1363
- }
1364
- var defaultFileSystem = {
1365
- readFile: (filePath) => fs__namespace.readFile(filePath, "utf-8"),
1366
- writeFile: (filePath, content) => fs__namespace.writeFile(filePath, content, "utf-8"),
1367
- readdir: (dirPath) => fs__namespace.readdir(dirPath)
1368
- };
1369
- function parseVersion(version) {
1370
- const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
1371
- if (!match) return null;
1372
- return [parseInt(match[1], 10), parseInt(match[2], 10), parseInt(match[3], 10)];
1373
- }
1374
- function compareVersions(a, b) {
1375
- const parsedA = parseVersion(a);
1376
- const parsedB = parseVersion(b);
1377
- if (!parsedA && !parsedB) return 0;
1378
- if (!parsedA) return 1;
1379
- if (!parsedB) return -1;
1380
- for (let i = 0; i < 3; i++) {
1381
- if (parsedA[i] !== parsedB[i]) {
1382
- return parsedA[i] - parsedB[i];
1383
- }
1384
- }
1385
- return 0;
1386
- }
1387
- var FILE_EXTENSION = ".yaml";
1388
- function getFileName(id, version) {
1389
- return `${id}-${version}${FILE_EXTENSION}`;
1390
- }
1391
- function parseFileName(fileName) {
1392
- if (!fileName.endsWith(FILE_EXTENSION)) return null;
1393
- const baseName = fileName.slice(0, -FILE_EXTENSION.length);
1394
- const lastDash = baseName.lastIndexOf("-");
1395
- if (lastDash === -1) return null;
1396
- const id = baseName.slice(0, lastDash);
1397
- const version = baseName.slice(lastDash + 1);
1398
- if (!id || !parseVersion(version)) return null;
1399
- return { id, version };
1400
- }
1401
- function parsePromptYaml(content, promptId) {
1402
- let parsed;
1403
- try {
1404
- parsed = yaml__namespace.parse(content);
1405
- } catch (error) {
1406
- throw new PromptInvalidFormatError(promptId, `Invalid YAML: ${toErrorMessage(error)}`, {
1407
- cause: toErrorCause(error)
1408
- });
1409
- }
1410
- if (!parsed || typeof parsed !== "object") {
1411
- throw new PromptInvalidFormatError(promptId, "Expected YAML object");
1412
- }
1413
- const obj = parsed;
1414
- const requiredFields = ["id", "version", "system", "userTemplate"];
1415
- for (const field of requiredFields) {
1416
- if (typeof obj[field] !== "string") {
1417
- throw new PromptInvalidFormatError(
1418
- promptId,
1419
- `Missing or invalid required field: ${field} (expected string)`
1420
- );
1421
- }
1422
- }
1423
- return {
1424
- id: obj.id,
1425
- version: obj.version,
1426
- system: obj.system,
1427
- userTemplate: obj.userTemplate
1428
- };
1429
- }
1430
- function serializePromptYaml(content) {
1431
- return yaml__namespace.stringify(content);
1432
- }
1433
- var FilePromptRepository = class {
1434
- directory;
1435
- fileSystem;
1436
- cacheEnabled;
1437
- contentCache = /* @__PURE__ */ new Map();
1438
- constructor(options) {
1439
- this.directory = options.directory;
1440
- this.fileSystem = options.fs ?? defaultFileSystem;
1441
- this.cacheEnabled = options.cache ?? true;
1442
- }
1443
- /**
1444
- * Generates file name from prompt id and version.
1445
- * Override this along with `parseFileName` to change file naming convention.
1446
- */
1447
- getFileName(id, version) {
1448
- return getFileName(id, version);
1449
- }
1450
- /**
1451
- * Parses file name into id and version.
1452
- * Override this along with `getFileName` to change file naming convention.
1453
- */
1454
- parseFileName(fileName) {
1455
- return parseFileName(fileName);
1456
- }
1457
- /**
1458
- * Parses raw file content into PromptTemplateData.
1459
- * Override this to support different file formats (e.g., JSON, TOML).
1460
- */
1461
- parseContent(content, promptId) {
1462
- return parsePromptYaml(content, promptId);
1463
- }
1464
- /**
1465
- * Serializes PromptTemplateData to file content string.
1466
- * Override this to support different file formats (e.g., JSON, TOML).
1467
- */
1468
- serializeContent(content) {
1469
- return serializePromptYaml(content);
1470
- }
1471
- getCacheKey(id, version) {
1472
- return `${id}:${version}`;
1473
- }
1474
- async read(id, version) {
1475
- if (version) {
1476
- const cacheKey = this.getCacheKey(id, version);
1477
- if (this.cacheEnabled) {
1478
- const cached = this.contentCache.get(cacheKey);
1479
- if (cached) {
1480
- return cached;
1481
- }
1482
- }
1483
- const fileName = this.getFileName(id, version);
1484
- const filePath = path3__namespace.join(this.directory, fileName);
1485
- let content;
1486
- try {
1487
- content = await this.fileSystem.readFile(filePath);
1488
- } catch (error) {
1489
- if (error instanceof Error && "code" in error && error.code === "ENOENT") {
1490
- throw new PromptNotFoundError(id, version);
1491
- }
1492
- throw new PromptIOError("read", filePath, { cause: toErrorCause(error) });
1493
- }
1494
- const promptTemplate = this.parseContent(content, id);
1495
- if (promptTemplate.id !== id || promptTemplate.version !== version) {
1496
- throw new PromptInvalidFormatError(
1497
- id,
1498
- `File content mismatch: expected id='${id}' version='${version}', got id='${promptTemplate.id}' version='${promptTemplate.version}'`
1499
- );
1500
- }
1501
- if (this.cacheEnabled) {
1502
- this.contentCache.set(cacheKey, promptTemplate);
1503
- }
1504
- return promptTemplate;
1505
- }
1506
- let files;
1507
- try {
1508
- files = await this.fileSystem.readdir(this.directory);
1509
- } catch (error) {
1510
- throw new PromptIOError("list", this.directory, { cause: toErrorCause(error) });
1511
- }
1512
- const versions = [];
1513
- for (const file of files) {
1514
- const parsed = this.parseFileName(file);
1515
- if (parsed && parsed.id === id) {
1516
- versions.push(parsed.version);
1517
- }
1518
- }
1519
- if (versions.length === 0) {
1520
- throw new PromptNotFoundError(id);
1521
- }
1522
- versions.sort((a, b) => compareVersions(b, a));
1523
- const latestVersion = versions[0];
1524
- return this.read(id, latestVersion);
1525
- }
1526
- async write(content) {
1527
- if (this.cacheEnabled) {
1528
- this.contentCache.delete(this.getCacheKey(content.id, content.version));
1529
- }
1530
- const fileName = this.getFileName(content.id, content.version);
1531
- const filePath = path3__namespace.join(this.directory, fileName);
1532
- if (!parseVersion(content.version)) {
1533
- throw new PromptInvalidFormatError(
1534
- content.id,
1535
- `Invalid version format: '${content.version}' (expected semver like '1.0.0')`
1536
- );
1537
- }
1538
- compileTemplate(content.system, content.id);
1539
- compileTemplate(content.userTemplate, content.id);
1540
- const yamlContent = this.serializeContent(content);
1541
- try {
1542
- await this.fileSystem.writeFile(filePath, yamlContent);
1543
- } catch (error) {
1544
- throw new PromptIOError("write", filePath, { cause: toErrorCause(error) });
1545
- }
1546
- }
1547
- };
1548
- function createFilePromptRepository(options) {
1549
- return new FilePromptRepository(options);
1550
- }
1551
-
1552
- // src/provider/types.ts
1553
- var FILE_SOURCE_TYPES = /* @__PURE__ */ new Set(["path", "data", "base64", "url"]);
1554
- function isFileSource(v) {
1555
- return typeof v === "object" && v !== null && FILE_SOURCE_TYPES.has(v.source);
1556
- }
1557
- function isFileSourcePath(v) {
1558
- return v.source === "path";
1559
- }
1560
- function isFileSourceData(v) {
1561
- return v.source === "data";
1562
- }
1563
- function isFileSourceBase64(v) {
1564
- return v.source === "base64";
1565
- }
1566
- function isFileSourceUrl(v) {
1567
- return v.source === "url";
1568
- }
1569
- async function computeFileSourceHash(source) {
1570
- if (source.hash) {
1571
- return source.hash;
1572
- }
1573
- const hash = crypto.createHash("sha256");
1574
- switch (source.source) {
1575
- case "path": {
1576
- const fullPath = path3__namespace.default.isAbsolute(source.path) ? source.path : path3__namespace.default.resolve(process.cwd(), source.path);
1577
- const content = await fs.readFile(fullPath);
1578
- hash.update(content);
1579
- break;
1580
- }
1581
- case "data": {
1582
- hash.update(source.data);
1583
- break;
1584
- }
1585
- case "base64": {
1586
- const buffer = Buffer.from(source.data, "base64");
1587
- hash.update(buffer);
1588
- break;
1589
- }
1590
- case "url": {
1591
- hash.update(source.url);
1592
- break;
1593
- }
1594
- }
1595
- return hash.digest("hex");
1596
- }
1597
-
1598
- // src/provider/file-cache.ts
1599
- var InMemoryFileCache = class {
1600
- cache = /* @__PURE__ */ new Map();
1601
- defaultTTL;
1602
- constructor(options) {
1603
- this.defaultTTL = options?.defaultTTL;
1604
- }
1605
- get(hash) {
1606
- const entry = this.cache.get(hash);
1607
- if (!entry) return null;
1608
- if (entry.expiresAt !== void 0 && Date.now() > entry.expiresAt) {
1609
- this.cache.delete(hash);
1610
- return null;
1611
- }
1612
- return entry.file;
1613
- }
1614
- set(hash, file, ttl) {
1615
- const effectiveTTL = ttl ?? this.defaultTTL;
1616
- const expiresAt = effectiveTTL !== void 0 ? Date.now() + effectiveTTL : void 0;
1617
- this.cache.set(hash, { file, expiresAt });
1618
- }
1619
- delete(hash) {
1620
- this.cache.delete(hash);
1621
- }
1622
- clear() {
1623
- this.cache.clear();
1624
- }
1625
- };
1626
-
1627
- // src/provider/base-provider.ts
1628
- var BaseProvider = class {
1629
- streamingExecution(generator, options) {
1630
- return new StreamingExecutionHost(
1631
- (signal) => this.createStreamingSession(signal),
1632
- generator,
1633
- options?.signal
1634
- );
1635
- }
1636
- /**
1637
- * Execute a non-streaming function with cancellation support.
1638
- * Returns immediately - execution starts in the background.
1639
- */
1640
- simpleExecution(fn, options) {
1641
- return new SimpleExecutionHost(
1642
- (signal) => this.createSimpleSession(signal),
1643
- fn,
1644
- options?.signal
1645
- );
1646
- }
1647
- };
1648
-
1649
- // src/provider/noop-file-manager.ts
1650
- var NoOpFileManager = class {
1651
- upload(_files) {
1652
- throw new FileError("File upload not supported by this provider", {
1653
- code: "UNSUPPORTED_TYPE" /* UNSUPPORTED_TYPE */,
1654
- context: {
1655
- provider: "noop",
1656
- suggestion: "Use a provider with file support (e.g., Google) or pass files inline"
1657
- }
1658
- });
1659
- }
1660
- delete(_fileId) {
1661
- throw new FileError("File delete not supported by this provider", {
1662
- code: "UNSUPPORTED_TYPE" /* UNSUPPORTED_TYPE */,
1663
- context: {
1664
- provider: "noop"
1665
- }
1666
- });
1667
- }
1668
- clear() {
1669
- return Promise.resolve();
1670
- }
1671
- getUploadedFiles() {
1672
- return [];
1673
- }
1674
- };
1675
- var EXTENSION_TO_MIME = {
1676
- ".pdf": "application/pdf",
1677
- ".html": "text/html",
1678
- ".htm": "text/html",
1679
- ".txt": "text/plain",
1680
- ".json": "application/json",
1681
- ".xml": "application/xml",
1682
- ".csv": "text/csv",
1683
- ".png": "image/png",
1684
- ".jpg": "image/jpeg",
1685
- ".jpeg": "image/jpeg",
1686
- ".gif": "image/gif",
1687
- ".webp": "image/webp",
1688
- ".svg": "image/svg+xml",
1689
- ".bmp": "image/bmp",
1690
- ".zip": "application/zip"
1691
- };
1692
- function inferMediaType(filePath) {
1693
- const ext = path3__namespace.extname(filePath).toLowerCase();
1694
- return EXTENSION_TO_MIME[ext];
1695
- }
1696
- function scanForFileSources(input, currentPath = []) {
1697
- if (isFileSource(input)) {
1698
- return [{ part: input, path: currentPath }];
1699
- }
1700
- if (input === null || typeof input !== "object") {
1701
- return [];
1702
- }
1703
- if (Buffer.isBuffer(input) || input instanceof Uint8Array || input instanceof URL) {
1704
- return [];
1705
- }
1706
- const results = [];
1707
- if (Array.isArray(input)) {
1708
- for (let i = 0; i < input.length; i++) {
1709
- results.push(...scanForFileSources(input[i], [...currentPath, i]));
1710
- }
1711
- } else {
1712
- for (const key of Object.keys(input)) {
1713
- results.push(
1714
- ...scanForFileSources(input[key], [
1715
- ...currentPath,
1716
- key
1717
- ])
1718
- );
1719
- }
1720
- }
1721
- return results;
1722
- }
1723
- var DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
1724
- async function resolveFileSource(part, options = {}) {
1725
- const { basePath = process.cwd(), maxSize = DEFAULT_MAX_SIZE } = options;
1726
- if (!isFileSourcePath(part)) {
1727
- return part;
1728
- }
1729
- const fullPath = path3__namespace.isAbsolute(part.path) ? part.path : path3__namespace.resolve(basePath, part.path);
1730
- const stats = await fs.stat(fullPath).catch((err) => {
1731
- throw new FileError(`File not found: ${part.path}`, {
1732
- code: "NOT_FOUND" /* NOT_FOUND */,
1733
- context: { path: part.path, fullPath },
1734
- cause: err
1735
- });
1736
- });
1737
- if (stats.size > maxSize) {
1738
- throw new FileError(`File too large: ${stats.size} bytes > ${maxSize} bytes`, {
1739
- code: "TOO_LARGE" /* TOO_LARGE */,
1740
- context: { path: part.path, size: stats.size, maxSize }
1741
- });
1742
- }
1743
- const buffer = await fs.readFile(fullPath);
1744
- const mediaType = part.mediaType ?? inferMediaType(part.path) ?? "application/octet-stream";
1745
- const filename = part.filename ?? path3__namespace.basename(part.path);
1746
- const result = {
1747
- source: "data",
1748
- data: buffer,
1749
- mediaType,
1750
- filename
1751
- };
1752
- return result;
1753
- }
1754
- function deepClone(value) {
1755
- if (value === null || typeof value !== "object") return value;
1756
- if (Buffer.isBuffer(value)) return Buffer.from(value);
1757
- if (value instanceof URL) return new URL(value.href);
1758
- if (value instanceof Uint8Array) return new Uint8Array(value);
1759
- if (Array.isArray(value)) return value.map(deepClone);
1760
- const result = {};
1761
- for (const key of Object.keys(value)) {
1762
- result[key] = deepClone(value[key]);
1763
- }
1764
- return result;
1765
- }
1766
- function setAtPath(obj, targetPath, value) {
1767
- if (targetPath.length === 0) {
1768
- return value;
1769
- }
1770
- let current = obj;
1771
- for (let i = 0; i < targetPath.length - 1; i++) {
1772
- current = current[targetPath[i]];
1773
- }
1774
- current[targetPath[targetPath.length - 1]] = value;
1775
- return obj;
1776
- }
1777
- async function resolveFileSourcesInInput(input, options = {}) {
1778
- const found = scanForFileSources(input);
1779
- if (found.length === 0) {
1780
- return input;
1781
- }
1782
- const resolved = await Promise.all(found.map(({ part }) => resolveFileSource(part, options)));
1783
- if (found.length === 1 && found[0].path.length === 0) {
1784
- return resolved[0];
1785
- }
1786
- const result = deepClone(input);
1787
- for (let i = 0; i < found.length; i++) {
1788
- setAtPath(result, found[i].path, resolved[i]);
1789
- }
1790
- return result;
1791
- }
1792
- function getFileSourceDisplayInfo(part) {
1793
- switch (part.source) {
1794
- case "path":
1795
- return {
1796
- source: "path",
1797
- description: part.path,
1798
- mediaType: part.mediaType ?? inferMediaType(part.path) ?? "unknown",
1799
- filename: part.filename ?? path3__namespace.basename(part.path)
1800
- };
1801
- case "url":
1802
- return {
1803
- source: "url",
1804
- description: part.url,
1805
- mediaType: part.mediaType ?? "unknown",
1806
- filename: part.filename
1807
- };
1808
- case "base64": {
1809
- const sizeKB = (part.data.length * 3 / 4 / 1024).toFixed(1);
1810
- return {
1811
- source: "base64",
1812
- description: `[base64 data, ~${sizeKB}KB]`,
1813
- mediaType: part.mediaType,
1814
- filename: part.filename
1815
- };
1816
- }
1817
- case "data": {
1818
- const size = Buffer.isBuffer(part.data) ? part.data.length : part.data.length;
1819
- const sizeKB = (size / 1024).toFixed(1);
1820
- return {
1821
- source: "data",
1822
- description: `[Buffer, ${sizeKB}KB]`,
1823
- mediaType: part.mediaType,
1824
- filename: part.filename
1825
- };
1826
- }
1827
- }
1828
- }
1829
- function getFileSourcesDisplayInfo(input) {
1830
- const found = scanForFileSources(input);
1831
- return found.map(({ part }) => getFileSourceDisplayInfo(part));
1832
- }
1833
- function assertValidUploadResponse(response, context) {
1834
- if (!response.name || !response.uri || !response.mimeType) {
1835
- throw new FileError("Invalid upload response from Google API: missing required fields", {
1836
- code: "UPLOAD_ERROR" /* UPLOAD_ERROR */,
1837
- context: {
1838
- ...context,
1839
- hasName: !!response.name,
1840
- hasUri: !!response.uri,
1841
- hasMediaType: !!response.mimeType
1842
- }
1843
- });
1844
- }
1845
- }
1846
- function isImageMediaType(mediaType) {
1847
- return mediaType.startsWith("image/");
1848
- }
1849
- function createPart(uri, mediaType) {
1850
- const url = new URL(uri);
1851
- if (isImageMediaType(mediaType)) {
1852
- return { type: "image", image: url, mediaType };
1853
- }
1854
- return { type: "file", data: url, mediaType };
1855
- }
1856
- var GoogleFileManager = class {
1857
- uploadedFiles = [];
1858
- client;
1859
- cache;
1860
- constructor(apiKey, options) {
1861
- this.client = new genai.GoogleGenAI({ apiKey });
1862
- this.cache = options?.cache ?? null;
1863
- }
1864
- async uploadOne(fileSource, index, hash) {
1865
- if (this.cache) {
1866
- const cached = this.cache.get(hash);
1867
- if (cached) return cached;
1868
- }
1869
- if (fileSource.source === "url") {
1870
- const mediaType = fileSource.mediaType ?? "application/octet-stream";
1871
- const result = {
1872
- id: null,
1873
- part: createPart(fileSource.url, mediaType)
1874
- };
1875
- if (this.cache) {
1876
- this.cache.set(hash, result);
1877
- }
1878
- return result;
1879
- }
1880
- if (fileSource.source === "path") {
1881
- const fullPath = path3__namespace.default.isAbsolute(fileSource.path) ? fileSource.path : path3__namespace.default.resolve(process.cwd(), fileSource.path);
1882
- try {
1883
- const uploaded = await this.client.files.upload({
1884
- file: fullPath,
1885
- config: {
1886
- mimeType: fileSource.mediaType,
1887
- displayName: fileSource.filename ?? path3__namespace.default.basename(fileSource.path)
1888
- }
1889
- });
1890
- assertValidUploadResponse(uploaded, {
1891
- source: "path",
1892
- path: fileSource.path
1893
- });
1894
- const result = {
1895
- id: uploaded.name,
1896
- part: createPart(uploaded.uri, uploaded.mimeType)
1897
- };
1898
- if (this.cache) {
1899
- this.cache.set(hash, result);
1900
- }
1901
- return result;
1902
- } catch (error) {
1903
- if (error instanceof FileError) throw error;
1904
- throw FileError.from(error, "UPLOAD_ERROR" /* UPLOAD_ERROR */, {
1905
- source: "path",
1906
- path: fileSource.path,
1907
- mediaType: fileSource.mediaType
1908
- });
1909
- }
1910
- }
1911
- const buffer = fileSource.source === "base64" ? Buffer.from(fileSource.data, "base64") : fileSource.data;
1912
- const arrayBuffer = buffer.buffer.slice(
1913
- buffer.byteOffset,
1914
- buffer.byteOffset + buffer.byteLength
1915
- );
1916
- const blob = new Blob([arrayBuffer], { type: fileSource.mediaType });
1917
- try {
1918
- const uploaded = await this.client.files.upload({
1919
- file: blob,
1920
- config: {
1921
- mimeType: fileSource.mediaType,
1922
- displayName: fileSource.filename ?? `upload-${Date.now()}-${index}`
1923
- }
1924
- });
1925
- assertValidUploadResponse(uploaded, {
1926
- source: fileSource.source,
1927
- mediaType: fileSource.mediaType
1928
- });
1929
- const result = {
1930
- id: uploaded.name,
1931
- part: createPart(uploaded.uri, uploaded.mimeType)
1932
- };
1933
- if (this.cache) {
1934
- this.cache.set(hash, result);
1935
- }
1936
- return result;
1937
- } catch (error) {
1938
- if (error instanceof FileError) throw error;
1939
- throw FileError.from(error, "UPLOAD_ERROR" /* UPLOAD_ERROR */, {
1940
- source: fileSource.source,
1941
- mediaType: fileSource.mediaType,
1942
- filename: fileSource.filename
1943
- });
1944
- }
1945
- }
1946
- async upload(files) {
1947
- const hashes = await Promise.all(files.map((file) => computeFileSourceHash(file)));
1948
- const results = await Promise.allSettled(
1949
- files.map((file, i) => this.uploadOne(file, i, hashes[i]))
1950
- );
1951
- const successful = [];
1952
- const failed = [];
1953
- for (let i = 0; i < results.length; i++) {
1954
- const result = results[i];
1955
- if (result.status === "fulfilled") {
1956
- successful.push({ file: result.value, hash: hashes[i] });
1957
- } else {
1958
- failed.push(result);
1959
- }
1960
- }
1961
- if (failed.length > 0) {
1962
- await Promise.all(
1963
- successful.filter(({ file }) => file.id !== null).map(async ({ file, hash }) => {
1964
- await this.client.files.delete({ name: file.id }).catch(() => {
1965
- });
1966
- if (this.cache) {
1967
- this.cache.delete(hash);
1968
- }
1969
- })
1970
- );
1971
- const firstError = failed[0].reason;
1972
- throw new FileError(
1973
- `Failed to upload ${failed.length} file(s): ${firstError instanceof Error ? firstError.message : String(firstError)}`,
1974
- {
1975
- code: "UPLOAD_ERROR" /* UPLOAD_ERROR */,
1976
- cause: firstError instanceof Error ? firstError : void 0,
1977
- context: {
1978
- totalFiles: files.length,
1979
- failedCount: failed.length,
1980
- successCount: successful.length
1981
- }
1982
- }
1983
- );
1984
- }
1985
- this.uploadedFiles.push(...successful.filter(({ file }) => file.id !== null).map(({ file }) => file));
1986
- return successful.map(({ file }) => file);
1987
- }
1988
- async delete(fileId) {
1989
- try {
1990
- await this.client.files.delete({ name: fileId });
1991
- this.uploadedFiles = this.uploadedFiles.filter((f) => f.id !== fileId);
1992
- } catch (error) {
1993
- throw FileError.from(error, "DELETE_ERROR" /* DELETE_ERROR */, {
1994
- fileId
1995
- });
1996
- }
1997
- }
1998
- async clear() {
1999
- await Promise.all(
2000
- this.uploadedFiles.filter((f) => f.id !== null).map((f) => this.delete(f.id).catch(() => {
2001
- }))
2002
- );
2003
- this.uploadedFiles = [];
2004
- }
2005
- getUploadedFiles() {
2006
- return [...this.uploadedFiles];
2007
- }
2008
- };
2009
-
2010
- // src/utils/deep-merge.ts
2011
- function isPlainObject(value) {
2012
- return typeof value === "object" && value !== null && !Array.isArray(value);
2013
- }
2014
- function deepMerge(...sources) {
2015
- const result = {};
2016
- for (const source of sources) {
2017
- if (!source) continue;
2018
- for (const key of Object.keys(source)) {
2019
- const existing = result[key];
2020
- const incoming = source[key];
2021
- result[key] = isPlainObject(existing) && isPlainObject(incoming) ? deepMerge(existing, incoming) : incoming;
2022
- }
2023
- }
2024
- return result;
2025
- }
2026
-
2027
- // src/session/usage-extractors.ts
2028
- function mergeUsages(usages) {
2029
- if (usages.length === 0) {
2030
- return createZeroUsage();
2031
- }
2032
- let inputTokens = 0;
2033
- let outputTokens = 0;
2034
- let totalTokens = 0;
2035
- let noCacheTokens = 0;
2036
- let cacheReadTokens = 0;
2037
- let cacheWriteTokens = 0;
2038
- let textTokens = 0;
2039
- let reasoningTokens = 0;
2040
- for (const usage of usages) {
2041
- inputTokens += usage.inputTokens ?? 0;
2042
- outputTokens += usage.outputTokens ?? 0;
2043
- totalTokens += usage.totalTokens ?? 0;
2044
- noCacheTokens += usage.inputTokenDetails?.noCacheTokens ?? 0;
2045
- cacheReadTokens += usage.inputTokenDetails?.cacheReadTokens ?? 0;
2046
- cacheWriteTokens += usage.inputTokenDetails?.cacheWriteTokens ?? 0;
2047
- textTokens += usage.outputTokenDetails?.textTokens ?? 0;
2048
- reasoningTokens += usage.outputTokenDetails?.reasoningTokens ?? 0;
2049
- }
2050
- return {
2051
- inputTokens,
2052
- outputTokens,
2053
- totalTokens,
2054
- inputTokenDetails: {
2055
- noCacheTokens,
2056
- cacheReadTokens,
2057
- cacheWriteTokens
2058
- },
2059
- outputTokenDetails: {
2060
- textTokens,
2061
- reasoningTokens
2062
- }
2063
- };
2064
- }
2065
- function createZeroUsage() {
2066
- return {
2067
- inputTokens: 0,
2068
- outputTokens: 0,
2069
- totalTokens: 0,
2070
- inputTokenDetails: {
2071
- noCacheTokens: 0,
2072
- cacheReadTokens: 0,
2073
- cacheWriteTokens: 0
2074
- },
2075
- outputTokenDetails: {
2076
- textTokens: 0,
2077
- reasoningTokens: 0
2078
- }
2079
- };
2080
- }
2081
- function detectProviderType(modelId) {
2082
- const lowerModel = modelId.toLowerCase();
2083
- if (lowerModel.startsWith("gpt-") || lowerModel === "o1" || lowerModel.startsWith("o1-") || lowerModel === "o3" || lowerModel.startsWith("o3-")) {
2084
- return "openai";
2085
- }
2086
- if (lowerModel.startsWith("gemini")) {
2087
- return "google";
2088
- }
2089
- if (lowerModel.startsWith("claude")) {
2090
- return "anthropic";
2091
- }
2092
- return void 0;
2093
- }
2094
-
2095
- // src/session/types.ts
2096
- var SessionSummary = class _SessionSummary {
2097
- totalLLMUsage;
2098
- llmCallCount;
2099
- llmCalls;
2100
- toolCalls;
2101
- customRecords;
2102
- llmCost;
2103
- additionalCosts;
2104
- metadata;
2105
- /** Cost breakdown by model. Key format: `${provider}/${model}` */
2106
- costByModel;
2107
- startTime;
2108
- constructor(data, startTime) {
2109
- this.startTime = startTime;
2110
- this.totalLLMUsage = data.totalLLMUsage;
2111
- this.llmCallCount = data.llmCalls.length;
2112
- this.llmCalls = Object.freeze([...data.llmCalls]);
2113
- this.toolCalls = Object.freeze([...data.toolCalls]);
2114
- this.customRecords = Object.freeze([...data.customRecords]);
2115
- this.llmCost = data.llmCost;
2116
- this.additionalCosts = Object.freeze([...data.additionalCosts]);
2117
- this.metadata = Object.freeze({ ...data.metadata });
2118
- this.costByModel = Object.freeze({ ...data.costByModel });
2119
- }
2120
- /**
2121
- * Total duration from session start to now (computed dynamically).
2122
- */
2123
- get totalDuration() {
2124
- return Date.now() - this.startTime;
2125
- }
2126
- /**
2127
- * Creates an empty SessionSummary.
2128
- */
2129
- static empty(startTime) {
2130
- return new _SessionSummary(
2131
- {
2132
- totalLLMUsage: createZeroUsage(),
2133
- llmCalls: [],
2134
- toolCalls: [],
2135
- customRecords: [],
2136
- llmCost: 0,
2137
- additionalCosts: [],
2138
- metadata: {},
2139
- costByModel: {}
2140
- },
2141
- startTime
2142
- );
2143
- }
2144
- /**
2145
- * Creates a SessionSummary with custom data for testing purposes.
2146
- * @internal For testing only - do not use in production code.
2147
- */
2148
- static forTest(data) {
2149
- const startTime = data.startTime ?? Date.now() - 1e3;
2150
- return new _SessionSummary(
2151
- {
2152
- totalLLMUsage: data.totalLLMUsage ?? createZeroUsage(),
2153
- llmCalls: data.llmCalls ?? [],
2154
- toolCalls: data.toolCalls ?? [],
2155
- customRecords: data.customRecords ?? [],
2156
- llmCost: data.llmCost ?? 0,
2157
- additionalCosts: data.additionalCosts ?? [],
2158
- metadata: data.metadata ?? {},
2159
- costByModel: data.costByModel ?? {}
2160
- },
2161
- startTime
2162
- );
2163
- }
2164
- /**
2165
- * Total cost of all additional (non-LLM) operations.
2166
- */
2167
- get totalAdditionalCost() {
2168
- return this.additionalCosts.reduce((sum, c) => sum + c.cost, 0);
2169
- }
2170
- /**
2171
- * Total cost including LLM and additional costs.
2172
- */
2173
- get totalCost() {
2174
- return this.llmCost + this.totalAdditionalCost;
2175
- }
2176
- /**
2177
- * Returns a new SessionSummary with an LLM call added.
2178
- */
2179
- withLLMCall(call, newLlmCost, newCostByModel, newTotalUsage) {
2180
- return new _SessionSummary(
2181
- {
2182
- totalLLMUsage: newTotalUsage,
2183
- llmCalls: [...this.llmCalls, call],
2184
- toolCalls: [...this.toolCalls],
2185
- customRecords: [...this.customRecords],
2186
- llmCost: newLlmCost,
2187
- additionalCosts: [...this.additionalCosts],
2188
- metadata: { ...this.metadata },
2189
- costByModel: newCostByModel
2190
- },
2191
- this.startTime
2192
- );
2193
- }
2194
- /**
2195
- * Returns a new SessionSummary with an additional cost recorded.
2196
- */
2197
- withAdditionalCost(cost) {
2198
- return new _SessionSummary(
2199
- {
2200
- totalLLMUsage: this.totalLLMUsage,
2201
- llmCalls: [...this.llmCalls],
2202
- toolCalls: [...this.toolCalls],
2203
- customRecords: [...this.customRecords],
2204
- llmCost: this.llmCost,
2205
- additionalCosts: [...this.additionalCosts, cost],
2206
- metadata: { ...this.metadata },
2207
- costByModel: { ...this.costByModel }
2208
- },
2209
- this.startTime
2210
- );
2211
- }
2212
- /**
2213
- * Returns a new SessionSummary with metadata updated.
2214
- */
2215
- withMetadata(key, value) {
2216
- return new _SessionSummary(
2217
- {
2218
- totalLLMUsage: this.totalLLMUsage,
2219
- llmCalls: [...this.llmCalls],
2220
- toolCalls: [...this.toolCalls],
2221
- customRecords: [...this.customRecords],
2222
- llmCost: this.llmCost,
2223
- additionalCosts: [...this.additionalCosts],
2224
- metadata: { ...this.metadata, [key]: value },
2225
- costByModel: { ...this.costByModel }
2226
- },
2227
- this.startTime
2228
- );
2229
- }
2230
- /**
2231
- * Returns a new SessionSummary with a tool call added.
2232
- */
2233
- withToolCall(call) {
2234
- return new _SessionSummary(
2235
- {
2236
- totalLLMUsage: this.totalLLMUsage,
2237
- llmCalls: [...this.llmCalls],
2238
- toolCalls: [...this.toolCalls, call],
2239
- customRecords: [...this.customRecords],
2240
- llmCost: this.llmCost,
2241
- additionalCosts: [...this.additionalCosts],
2242
- metadata: { ...this.metadata },
2243
- costByModel: { ...this.costByModel }
2244
- },
2245
- this.startTime
2246
- );
2247
- }
2248
- /**
2249
- * Returns a new SessionSummary with a custom record added.
2250
- */
2251
- withCustomRecord(record) {
2252
- return new _SessionSummary(
2253
- {
2254
- totalLLMUsage: this.totalLLMUsage,
2255
- llmCalls: [...this.llmCalls],
2256
- toolCalls: [...this.toolCalls],
2257
- customRecords: [...this.customRecords, record],
2258
- llmCost: this.llmCost,
2259
- additionalCosts: [...this.additionalCosts],
2260
- metadata: { ...this.metadata },
2261
- costByModel: { ...this.costByModel }
2262
- },
2263
- this.startTime
2264
- );
2265
- }
2266
- /**
2267
- * Serializes to plain JSON object for database storage.
2268
- */
2269
- toJSON() {
2270
- return {
2271
- totalDuration: this.totalDuration,
2272
- totalLLMUsage: this.totalLLMUsage,
2273
- llmCallCount: this.llmCallCount,
2274
- llmCalls: [...this.llmCalls],
2275
- toolCalls: [...this.toolCalls],
2276
- customRecords: [...this.customRecords],
2277
- llmCost: this.llmCost,
2278
- additionalCosts: [...this.additionalCosts],
2279
- metadata: { ...this.metadata },
2280
- costByModel: { ...this.costByModel },
2281
- totalCost: this.totalCost,
2282
- totalAdditionalCost: this.totalAdditionalCost
2283
- };
2284
- }
2285
- };
2286
-
2287
- // src/session/simple-session.ts
2288
- var SimpleSession = class {
2289
- defaultLanguageModel;
2290
- modelFactory;
2291
- providerType;
2292
- providerPricing;
2293
- defaultProviderOptions;
2294
- defaultTools;
2295
- defaultGenerationOptions;
2296
- _fileManager;
2297
- logger;
2298
- sessionStartTime;
2299
- signal;
2300
- summary;
2301
- pendingUsagePromises = [];
2302
- onDoneFns = [];
2303
- constructor(options) {
2304
- this.defaultLanguageModel = options.defaultLanguageModel ?? null;
2305
- this.modelFactory = options.modelFactory ?? null;
2306
- this.providerType = options.providerType;
2307
- this.providerPricing = options.providerPricing;
2308
- this.defaultProviderOptions = options.defaultProviderOptions;
2309
- this.defaultTools = options.defaultTools;
2310
- this.defaultGenerationOptions = options.defaultGenerationOptions;
2311
- this._fileManager = options.fileManager;
2312
- this.logger = options.logger ?? noopLogger;
2313
- this.sessionStartTime = options.startTime ?? Date.now();
2314
- this.signal = options.signal;
2315
- this.summary = SessionSummary.empty(this.sessionStartTime);
2316
- }
2317
- getModel(requestedModelId) {
2318
- if (requestedModelId) {
2319
- if (!this.modelFactory) {
2320
- throw new Error(
2321
- `Model '${requestedModelId}' requested but no modelFactory provided. Either use the default model or configure the provider with modelFactory.`
2322
- );
2323
- }
2324
- return this.modelFactory(requestedModelId);
2325
- }
2326
- if (!this.defaultLanguageModel) {
2327
- throw new Error(
2328
- "No model specified and no default model set. Either specify a model in the call or configure the provider with withDefaultModel()."
2329
- );
2330
- }
2331
- return this.defaultLanguageModel;
2332
- }
2333
- extractModelId(model) {
2334
- const modelWithId = model;
2335
- if (!modelWithId.modelId) {
2336
- console.warn(
2337
- '[SimpleSession] Model does not have modelId property, using "unknown". This may affect cost tracking accuracy.'
2338
- );
2339
- }
2340
- return modelWithId.modelId ?? "unknown";
2341
- }
2342
- async generateText(params) {
2343
- const callStartTime = Date.now();
2344
- const { model: requestedModel, providerOptions, tools, ...restParams } = params;
2345
- const languageModel = this.getModel(requestedModel);
2346
- const modelId = this.extractModelId(languageModel);
2347
- const mergedProviderOptions = this.defaultProviderOptions || providerOptions ? deepMerge(this.defaultProviderOptions ?? {}, providerOptions ?? {}) : void 0;
2348
- const mergedTools = this.defaultTools || tools ? { ...this.defaultTools, ...tools } : void 0;
2349
- this.logger.onLLMCallStart?.({
2350
- type: "llm_call_start",
2351
- callType: "generateText",
2352
- modelId,
2353
- timestamp: callStartTime,
2354
- request: { params: restParams }
2355
- });
2356
- try {
2357
- const result = await ai.generateText({
2358
- ...this.defaultGenerationOptions,
2359
- ...restParams,
2360
- tools: mergedTools,
2361
- providerOptions: mergedProviderOptions,
2362
- model: languageModel,
2363
- abortSignal: this.signal
2364
- });
2365
- const callEndTime = Date.now();
2366
- const call = {
2367
- startTime: callStartTime,
2368
- endTime: callEndTime,
2369
- duration: callEndTime - callStartTime,
2370
- usage: result.usage ?? createZeroUsage(),
2371
- type: "generateText",
2372
- model: modelId,
2373
- provider: this.providerType
2374
- };
2375
- this.updateSummaryWithLLMCall(call);
2376
- this.logger.onLLMCallEnd?.({
2377
- type: "llm_call_end",
2378
- callType: "generateText",
2379
- modelId,
2380
- timestamp: callEndTime,
2381
- response: {
2382
- duration: callEndTime - callStartTime,
2383
- usage: result.usage,
2384
- raw: result
2385
- }
2386
- });
2387
- return result;
2388
- } catch (error) {
2389
- const callEndTime = Date.now();
2390
- this.logger.onLLMCallEnd?.({
2391
- type: "llm_call_end",
2392
- callType: "generateText",
2393
- modelId,
2394
- timestamp: callEndTime,
2395
- response: {
2396
- duration: callEndTime - callStartTime,
2397
- raw: null,
2398
- error: error instanceof Error ? error : new Error(String(error))
2399
- }
2400
- });
2401
- throw error;
2402
- }
2403
- }
2404
- streamText(params) {
2405
- const callStartTime = Date.now();
2406
- const { model: requestedModel, providerOptions, tools, ...restParams } = params;
2407
- const languageModel = this.getModel(requestedModel);
2408
- const modelId = this.extractModelId(languageModel);
2409
- const mergedProviderOptions = this.defaultProviderOptions || providerOptions ? deepMerge(this.defaultProviderOptions ?? {}, providerOptions ?? {}) : void 0;
2410
- const mergedTools = this.defaultTools || tools ? { ...this.defaultTools, ...tools } : void 0;
2411
- this.logger.onLLMCallStart?.({
2412
- type: "llm_call_start",
2413
- callType: "streamText",
2414
- modelId,
2415
- timestamp: callStartTime,
2416
- request: { params: restParams }
2417
- });
2418
- const result = ai.streamText({
2419
- ...this.defaultGenerationOptions,
2420
- ...restParams,
2421
- tools: mergedTools,
2422
- providerOptions: mergedProviderOptions,
2423
- model: languageModel,
2424
- abortSignal: this.signal
2425
- });
2426
- const usagePromise = Promise.resolve(result.usage).then((usage) => {
2427
- const callEndTime = Date.now();
2428
- const call = {
2429
- startTime: callStartTime,
2430
- endTime: callEndTime,
2431
- duration: callEndTime - callStartTime,
2432
- usage: usage ?? createZeroUsage(),
2433
- type: "streamText",
2434
- model: modelId,
2435
- provider: this.providerType
2436
- };
2437
- this.updateSummaryWithLLMCall(call);
2438
- this.logger.onLLMCallEnd?.({
2439
- type: "llm_call_end",
2440
- callType: "streamText",
2441
- modelId,
2442
- timestamp: callEndTime,
2443
- response: {
2444
- duration: callEndTime - callStartTime,
2445
- usage,
2446
- raw: result
2447
- }
2448
- });
2449
- return usage;
2450
- });
2451
- this.pendingUsagePromises.push(usagePromise);
2452
- return result;
2453
- }
2454
- get fileManager() {
2455
- return this._fileManager;
2456
- }
2457
- record(data) {
2458
- this.summary = this.summary.withCustomRecord(data);
2459
- }
2460
- recordToolCall(toolCallSummary) {
2461
- this.summary = this.summary.withToolCall(toolCallSummary);
2462
- }
2463
- recordLLMCall(record) {
2464
- const call = {
2465
- ...record,
2466
- type: record.type ?? "manual"
2467
- };
2468
- this.updateSummaryWithLLMCall(call);
2469
- }
2470
- recordAdditionalCost(cost) {
2471
- this.summary = this.summary.withAdditionalCost({
2472
- ...cost,
2473
- timestamp: Date.now()
2474
- });
2475
- }
2476
- setMetadata(keyOrData, value) {
2477
- if (typeof keyOrData === "string") {
2478
- this.summary = this.summary.withMetadata(keyOrData, value);
2479
- } else {
2480
- for (const [k, v] of Object.entries(keyOrData)) {
2481
- this.summary = this.summary.withMetadata(k, v);
2482
- }
2483
- }
2484
- }
2485
- updateSummaryWithLLMCall(call) {
2486
- const newCalls = [...this.summary.llmCalls, call];
2487
- const { totalCost: llmCost, costByModel } = calculateTotalCost(
2488
- newCalls.map((c) => ({ usage: c.usage, model: c.model, provider: c.provider })),
2489
- this.providerPricing
2490
- );
2491
- const newTotalUsage = mergeUsages(newCalls.map((c) => c.usage));
2492
- this.summary = this.summary.withLLMCall(call, llmCost, costByModel, newTotalUsage);
2493
- }
2494
- onDone(fn) {
2495
- this.onDoneFns.push(fn);
2496
- }
2497
- async runOnDoneHooks() {
2498
- const reversedHooks = [...this.onDoneFns].reverse();
2499
- for (const fn of reversedHooks) {
2500
- try {
2501
- await fn();
2502
- } catch (error) {
2503
- console.error("[SimpleSession] onDone hook error:", error);
2504
- }
2505
- }
2506
- }
2507
- async getSummary() {
2508
- await Promise.all(this.pendingUsagePromises);
2509
- return this.summary;
2510
- }
2511
- /**
2512
- * Notifies Logger of execution start.
2513
- * @internal Called by SimpleExecutionHost - not intended for direct use.
2514
- */
2515
- notifyExecutionStart() {
2516
- this._logger.onExecutionStart?.({
2517
- type: "execution_start",
2518
- timestamp: Date.now()
2519
- });
2520
- }
2521
- /**
2522
- * Notifies Logger of execution completion with result data and summary.
2523
- * @param data - The execution result data
2524
- * @param startTime - Execution start timestamp for duration calculation
2525
- * @internal Called by SimpleExecutionHost - not intended for direct use.
2526
- */
2527
- async notifyExecutionDone(data, startTime) {
2528
- const summary = await this.getSummary();
2529
- this._logger.onExecutionDone?.({
2530
- type: "execution_done",
2531
- timestamp: Date.now(),
2532
- duration: Date.now() - startTime,
2533
- data,
2534
- summary
2535
- });
2536
- }
2537
- /**
2538
- * Notifies Logger of execution error with error details and summary (if available).
2539
- * Gracefully handles getSummary() failures - summary will be undefined if it fails.
2540
- * @param error - The error that occurred
2541
- * @param startTime - Execution start timestamp for duration calculation
2542
- * @internal Called by SimpleExecutionHost - not intended for direct use.
2543
- */
2544
- async notifyExecutionError(error, startTime) {
2545
- let summary;
2546
- try {
2547
- summary = await this.getSummary();
2548
- } catch {
2549
- }
2550
- this._logger.onExecutionError?.({
2551
- type: "execution_error",
2552
- timestamp: Date.now(),
2553
- duration: Date.now() - startTime,
2554
- error,
2555
- summary
2556
- });
2557
- }
2558
- get _logger() {
2559
- return this.logger;
2560
- }
2561
- get _startTime() {
2562
- return this.sessionStartTime;
2563
- }
2564
- get _modelId() {
2565
- if (!this.defaultLanguageModel) {
2566
- return "unknown";
2567
- }
2568
- return this.extractModelId(this.defaultLanguageModel);
2569
- }
2570
- };
2571
-
2572
- // src/session/streaming-session.ts
2573
- var StreamingSession = class extends SimpleSession {
2574
- lastEventTime;
2575
- _terminated = false;
2576
- constructor(options) {
2577
- super({
2578
- defaultLanguageModel: options.defaultLanguageModel,
2579
- modelFactory: options.modelFactory,
2580
- providerType: options.providerType,
2581
- providerPricing: options.providerPricing,
2582
- fileManager: options.fileManager,
2583
- logger: options.logger,
2584
- startTime: options.startTime,
2585
- signal: options.signal,
2586
- defaultProviderOptions: options.defaultProviderOptions,
2587
- defaultTools: options.defaultTools,
2588
- defaultGenerationOptions: options.defaultGenerationOptions
2589
- });
2590
- this.lastEventTime = this._startTime;
2591
- this._logger.onExecutionStart?.({
2592
- type: "execution_start",
2593
- timestamp: Date.now()
2594
- });
2595
- }
2596
- /**
2597
- * Emits a streaming event with automatically attached metrics.
2598
- *
2599
- * Reserved types ('complete', 'error') throw at runtime - use session.done()
2600
- * or session.fail() instead.
2601
- *
2602
- * @param event - The event to emit (metrics will be added automatically)
2603
- * @returns The complete event with metrics attached
2604
- * @throws Error when attempting to emit reserved types ('complete', 'error')
2605
- */
2606
- emit(event) {
2607
- if (this._terminated) {
2608
- throw new Error("Session already terminated. Cannot call emit() after a terminal operation.");
2609
- }
2610
- const eventType = event.type;
2611
- if (eventType === "complete" || eventType === "error") {
2612
- throw new Error(
2613
- `Cannot emit reserved type "${eventType}". Use session.done() for completion or session.fail() for errors.`
2614
- );
2615
- }
2616
- return this.emitInternal(event);
2617
- }
2618
- /**
2619
- * Internal emit method - bypasses reserved type check.
2620
- * Used by done() and fail() to emit terminal events.
2621
- */
2622
- emitInternal(event) {
2623
- const metrics = this.createMetrics();
2624
- const fullEvent = { ...event, metrics };
2625
- this._logger.onExecutionEmit?.({
2626
- type: "execution_emit",
2627
- event: fullEvent
2628
- });
2629
- return fullEvent;
2630
- }
2631
- /**
2632
- * Signals successful completion of the streaming execution.
2633
- * Emits a 'complete' event with the result data and session summary.
2634
- * Also triggers Logger.onExecutionDone for observability.
2635
- * @param data - The final result data
2636
- * @returns The complete event with data and summary
2637
- */
2638
- async done(data) {
2639
- if (this._terminated) {
2640
- throw new Error("Session already terminated. Cannot call done() after a terminal operation.");
2641
- }
2642
- this._terminated = true;
2643
- const summary = await this.getSummary();
2644
- this._logger.onExecutionDone?.({
2645
- type: "execution_done",
2646
- timestamp: Date.now(),
2647
- duration: summary.totalDuration,
2648
- data,
2649
- summary
2650
- });
2651
- return this.emitInternal({
2652
- type: "complete",
2653
- data,
2654
- summary
2655
- });
2656
- }
2657
- /**
2658
- * Signals that the streaming execution failed with an error.
2659
- * Emits an 'error' event and triggers Logger.onExecutionError for observability.
2660
- * Gracefully handles getSummary() failures - summary will be undefined if it fails.
2661
- * @param error - The error that caused the failure
2662
- * @param data - Optional partial result data (if any was produced before failure)
2663
- * @returns The error event
2664
- */
2665
- async fail(error, data) {
2666
- if (this._terminated) {
2667
- throw new Error("Session already terminated. Cannot call fail() after a terminal operation.");
2668
- }
2669
- this._terminated = true;
2670
- let summary;
2671
- try {
2672
- summary = await this.getSummary();
2673
- } catch {
2674
- }
2675
- this._logger.onExecutionError?.({
2676
- type: "execution_error",
2677
- timestamp: Date.now(),
2678
- duration: summary?.totalDuration ?? Date.now() - this._startTime,
2679
- error,
2680
- data,
2681
- summary
2682
- });
2683
- const errorEvent = {
2684
- type: "error",
2685
- error
2686
- };
2687
- if (summary) {
2688
- errorEvent.summary = summary;
2689
- }
2690
- if (data !== void 0) {
2691
- errorEvent.data = data;
2692
- }
2693
- return this.emitInternal(errorEvent);
2694
- }
2695
- createMetrics() {
2696
- const now = Date.now();
2697
- const metrics = {
2698
- timestamp: now,
2699
- elapsedMs: now - this._startTime,
2700
- deltaMs: now - this.lastEventTime
2701
- };
2702
- this.lastEventTime = now;
2703
- return metrics;
2704
- }
2705
- };
2706
- function createStreamingSession(options) {
2707
- const session = new StreamingSession({
2708
- defaultLanguageModel: options.defaultLanguageModel,
2709
- providerType: options.providerType,
2710
- fileManager: options.fileManager,
2711
- logger: options.logger ?? noopLogger,
2712
- startTime: options.startTime,
2713
- signal: options.signal
2714
- });
2715
- return session;
2716
- }
2717
-
2718
- // src/provider/google/factory.ts
2719
- var GoogleProvider = class _GoogleProvider extends BaseProvider {
2720
- constructor(config) {
2721
- super();
2722
- this.config = config;
2723
- this.google = google.createGoogleGenerativeAI({ apiKey: config.apiKey });
2724
- }
2725
- google;
2726
- withDefaultModel(modelId) {
2727
- return new _GoogleProvider({ ...this.config, defaultModelId: modelId });
2728
- }
2729
- withLogger(newLogger) {
2730
- return new _GoogleProvider({ ...this.config, logger: newLogger });
2731
- }
2732
- withPricing(pricing) {
2733
- validateProviderPricing(pricing, "google");
2734
- return new _GoogleProvider({ ...this.config, pricingConfig: pricing });
2735
- }
2736
- /**
2737
- * Set default provider-specific options for all LLM calls.
2738
- * These options will be deep-merged with per-call providerOptions.
2739
- *
2740
- * @example
2741
- * ```typescript
2742
- * createGoogleProvider({ apiKey: 'xxx' })
2743
- * .withDefaultModel('gemini-2.0-flash-thinking-exp')
2744
- * .withDefaultOptions({
2745
- * thinkingConfig: { includeThoughts: true, thinkingLevel: 'low' }
2746
- * })
2747
- * ```
2748
- */
2749
- withDefaultOptions(options) {
2750
- return new _GoogleProvider({ ...this.config, defaultOptions: options });
2751
- }
2752
- withDefaultGenerationOptions(options) {
2753
- return new _GoogleProvider({ ...this.config, defaultGenOptions: options });
2754
- }
2755
- /**
2756
- * Enable Google Search grounding for all LLM calls.
2757
- * Allows the model to access real-time web information.
2758
- *
2759
- * @example
2760
- * ```typescript
2761
- * createGoogleProvider({ apiKey: 'xxx' })
2762
- * .withDefaultModel('gemini-2.5-flash')
2763
- * .withSearchEnabled()
2764
- * ```
2765
- */
2766
- withSearchEnabled() {
2767
- return new _GoogleProvider({ ...this.config, searchEnabled: true });
2768
- }
2769
- /**
2770
- * Enable URL Context grounding for all LLM calls.
2771
- * Allows the model to retrieve and use content from URLs in the prompt.
2772
- *
2773
- * @example
2774
- * ```typescript
2775
- * createGoogleProvider({ apiKey: 'xxx' })
2776
- * .withDefaultModel('gemini-2.5-flash')
2777
- * .withUrlContextEnabled()
2778
- * ```
2779
- */
2780
- withUrlContextEnabled() {
2781
- return new _GoogleProvider({ ...this.config, urlContextEnabled: true });
2782
- }
2783
- /**
2784
- * Set a file cache for reusing uploaded files across sessions.
2785
- * If no cache is provided, creates a new InMemoryFileCache.
2786
- *
2787
- * @example
2788
- * ```typescript
2789
- * // Use default InMemoryFileCache
2790
- * createGoogleProvider({ apiKey: 'xxx' })
2791
- * .withFileCache()
2792
- *
2793
- * // Use custom cache with TTL
2794
- * const cache = new InMemoryFileCache({ defaultTTL: 3600000 });
2795
- * createGoogleProvider({ apiKey: 'xxx' })
2796
- * .withFileCache(cache)
2797
- * ```
2798
- */
2799
- withFileCache(cache) {
2800
- return new _GoogleProvider({ ...this.config, fileCache: cache ?? new InMemoryFileCache() });
2801
- }
2802
- getSessionConfig() {
2803
- const { searchEnabled, urlContextEnabled } = this.config;
2804
- const defaultTools = {
2805
- ...searchEnabled && { google_search: this.google.tools.googleSearch({}) },
2806
- ...urlContextEnabled && { url_context: this.google.tools.urlContext({}) }
2807
- };
2808
- const hasDefaultTools = searchEnabled || urlContextEnabled;
2809
- return {
2810
- defaultLanguageModel: this.config.defaultModelId ? this.createModel(this.config.defaultModelId) : null,
2811
- modelFactory: (modelId) => this.createModel(modelId),
2812
- providerType: "google",
2813
- providerPricing: this.config.pricingConfig,
2814
- fileManager: new GoogleFileManager(this.config.apiKey, { cache: this.config.fileCache }),
2815
- logger: this.config.logger,
2816
- defaultProviderOptions: this.config.defaultOptions ? { google: this.config.defaultOptions } : void 0,
2817
- defaultTools: hasDefaultTools ? defaultTools : void 0,
2818
- defaultGenerationOptions: this.config.defaultGenOptions
2819
- };
2820
- }
2821
- createStreamingSession(signal) {
2822
- return new StreamingSession({ ...this.getSessionConfig(), signal });
2823
- }
2824
- createSimpleSession(signal) {
2825
- return new SimpleSession({ ...this.getSessionConfig(), signal });
2826
- }
2827
- /**
2828
- * Type assertion needed because @ai-sdk/google's type signature doesn't
2829
- * include the second parameter, but it's supported at runtime.
2830
- */
2831
- createModel(modelId) {
2832
- if (this.config.safetySettings) {
2833
- return this.google(modelId, { safetySettings: this.config.safetySettings });
2834
- }
2835
- return this.google(modelId);
2836
- }
2837
- };
2838
- function createGoogleProvider(config) {
2839
- return new GoogleProvider({
2840
- apiKey: config.apiKey,
2841
- defaultModelId: null,
2842
- logger: noopLogger,
2843
- safetySettings: config.safetySettings,
2844
- searchEnabled: false,
2845
- urlContextEnabled: false
2846
- });
2847
- }
2848
- var OpenAIProvider = class _OpenAIProvider extends BaseProvider {
2849
- constructor(config) {
2850
- super();
2851
- this.config = config;
2852
- this.openai = openai.createOpenAI({
2853
- apiKey: config.apiKey,
2854
- baseURL: config.baseURL,
2855
- organization: config.organization
2856
- });
2857
- }
2858
- openai;
2859
- withDefaultModel(modelId) {
2860
- return new _OpenAIProvider({ ...this.config, defaultModelId: modelId });
2861
- }
2862
- withLogger(newLogger) {
2863
- return new _OpenAIProvider({ ...this.config, logger: newLogger });
2864
- }
2865
- withPricing(pricing) {
2866
- validateProviderPricing(pricing, "openai");
2867
- return new _OpenAIProvider({ ...this.config, pricingConfig: pricing });
2868
- }
2869
- /**
2870
- * Set default provider-specific options for all LLM calls.
2871
- * These options will be deep-merged with per-call providerOptions.
2872
- *
2873
- * @example
2874
- * ```typescript
2875
- * createOpenAIProvider({ apiKey: 'xxx' })
2876
- * .withDefaultModel('gpt-4o')
2877
- * .withDefaultOptions({
2878
- * reasoningEffort: 'high',
2879
- * parallelToolCalls: true,
2880
- * })
2881
- * ```
2882
- */
2883
- withDefaultOptions(options) {
2884
- return new _OpenAIProvider({ ...this.config, defaultOptions: options });
2885
- }
2886
- withDefaultGenerationOptions(options) {
2887
- return new _OpenAIProvider({ ...this.config, defaultGenOptions: options });
2888
- }
2889
- /**
2890
- * Set a file cache for API consistency with GoogleProvider.
2891
- * Note: OpenAI does not support file caching, so this is a no-op.
2892
- *
2893
- * @example
2894
- * ```typescript
2895
- * createOpenAIProvider({ apiKey: 'xxx' })
2896
- * .withFileCache()
2897
- * ```
2898
- */
2899
- withFileCache(cache) {
2900
- return new _OpenAIProvider({ ...this.config, fileCache: cache });
2901
- }
2902
- getSessionConfig() {
2903
- return {
2904
- defaultLanguageModel: this.config.defaultModelId ? this.openai(this.config.defaultModelId) : null,
2905
- modelFactory: (modelId) => this.openai(modelId),
2906
- providerType: "openai",
2907
- providerPricing: this.config.pricingConfig,
2908
- fileManager: new NoOpFileManager(),
2909
- logger: this.config.logger,
2910
- defaultProviderOptions: this.config.defaultOptions ? { openai: this.config.defaultOptions } : void 0,
2911
- defaultGenerationOptions: this.config.defaultGenOptions
2912
- };
2913
- }
2914
- createStreamingSession(signal) {
2915
- return new StreamingSession({ ...this.getSessionConfig(), signal });
2916
- }
2917
- createSimpleSession(signal) {
2918
- return new SimpleSession({ ...this.getSessionConfig(), signal });
2919
- }
2920
- };
2921
- function createOpenAIProvider(config) {
2922
- return new OpenAIProvider({
2923
- apiKey: config.apiKey,
2924
- defaultModelId: null,
2925
- logger: noopLogger,
2926
- baseURL: config.baseURL,
2927
- organization: config.organization
2928
- });
2929
- }
2930
-
2931
- // src/validation/validation-history.ts
2932
- var ValidationHistory = class {
2933
- attempts = [];
2934
- get nextAttempt() {
2935
- return this.attempts.length + 1;
2936
- }
2937
- get last() {
2938
- return this.attempts.at(-1);
2939
- }
2940
- get all() {
2941
- return this.attempts;
2942
- }
2943
- get failureReasons() {
2944
- return this.attempts.filter((a) => !a.valid && a.reason).map((a) => a.reason);
2945
- }
2946
- get isRetry() {
2947
- return this.attempts.length > 0;
2948
- }
2949
- /** Internal use only - not exposed via ReadonlyValidationHistory. */
2950
- add(result, validation) {
2951
- this.attempts.push({
2952
- result,
2953
- ...validation,
2954
- attempt: this.attempts.length + 1
2955
- });
2956
- }
2957
- };
2958
-
2959
- // src/validation/errors.ts
2960
- var ValidationErrorCode = /* @__PURE__ */ ((ValidationErrorCode2) => {
2961
- ValidationErrorCode2["VALIDATION_EXHAUSTED"] = "VALIDATION_EXHAUSTED";
2962
- return ValidationErrorCode2;
2963
- })(ValidationErrorCode || {});
2964
- var ValidationExhaustedError = class extends AgtlantisError {
2965
- constructor(message, history) {
2966
- super(message, {
2967
- code: "VALIDATION_EXHAUSTED" /* VALIDATION_EXHAUSTED */,
2968
- context: {
2969
- attempts: history.all.length,
2970
- failureReasons: history.failureReasons
2971
- }
2972
- });
2973
- this.history = history;
2974
- this.name = "ValidationExhaustedError";
2975
- }
2976
- };
2977
-
2978
- // src/validation/with-validation.ts
2979
- async function withValidation(execute, options) {
2980
- const { validate, maxAttempts: rawMax, signal, retryDelay, onAttempt } = options;
2981
- const maxAttempts = Math.max(1, rawMax ?? 3);
2982
- const history = new ValidationHistory();
2983
- while (history.nextAttempt <= maxAttempts) {
2984
- signal?.throwIfAborted();
2985
- const result = await execute(history);
2986
- const validation = await validate(result, history);
2987
- history.add(result, validation);
2988
- onAttempt?.(history.last);
2989
- if (validation.valid) {
2990
- return result;
2991
- }
2992
- const hasMoreAttempts = history.nextAttempt <= maxAttempts;
2993
- if (retryDelay && hasMoreAttempts) {
2994
- await new Promise((resolve2) => setTimeout(resolve2, retryDelay));
2995
- }
2996
- }
2997
- throw new ValidationExhaustedError(
2998
- `Validation failed after ${history.all.length} attempts`,
2999
- history
3000
- );
3001
- }
3002
-
3003
- exports.ANTHROPIC_PRICING = ANTHROPIC_PRICING;
3004
- exports.AgtlantisError = AgtlantisError;
3005
- exports.BaseProvider = BaseProvider;
3006
- exports.ConfigurationError = ConfigurationError;
3007
- exports.ConfigurationErrorCode = ConfigurationErrorCode;
3008
- exports.DEFAULT_FALLBACK_PRICING = DEFAULT_FALLBACK_PRICING;
3009
- exports.DEFAULT_MAX_SIZE = DEFAULT_MAX_SIZE;
3010
- exports.DEFAULT_PRICING_CONFIG = DEFAULT_PRICING_CONFIG;
3011
- exports.ERRORS = ERRORS;
3012
- exports.EXTENSION_TO_MIME = EXTENSION_TO_MIME;
3013
- exports.ExecutionError = ExecutionError;
3014
- exports.ExecutionErrorCode = ExecutionErrorCode;
3015
- exports.FileError = FileError;
3016
- exports.FileErrorCode = FileErrorCode;
3017
- exports.FilePromptRepository = FilePromptRepository;
3018
- exports.GOOGLE_PRICING = GOOGLE_PRICING;
3019
- exports.GoogleFileManager = GoogleFileManager;
3020
- exports.GoogleProvider = GoogleProvider;
3021
- exports.InMemoryFileCache = InMemoryFileCache;
3022
- exports.NoOpFileManager = NoOpFileManager;
3023
- exports.OPENAI_PRICING = OPENAI_PRICING;
3024
- exports.ProgressivePattern = ProgressivePattern;
3025
- exports.PromptError = PromptError;
3026
- exports.PromptErrorCode = PromptErrorCode;
3027
- exports.PromptIOError = PromptIOError;
3028
- exports.PromptInvalidFormatError = PromptInvalidFormatError;
3029
- exports.PromptNotFoundError = PromptNotFoundError;
3030
- exports.PromptTemplate = PromptTemplate;
3031
- exports.PromptTemplateError = PromptTemplateError;
3032
- exports.SessionSummary = SessionSummary;
3033
- exports.SimpleExecutionHost = SimpleExecutionHost;
3034
- exports.SimpleSession = SimpleSession;
3035
- exports.StreamingExecutionHost = StreamingExecutionHost;
3036
- exports.StreamingSession = StreamingSession;
3037
- exports.TOOL_CALLING_PROTOCOL = TOOL_CALLING_PROTOCOL;
3038
- exports.ValidationErrorCode = ValidationErrorCode;
3039
- exports.ValidationExhaustedError = ValidationExhaustedError;
3040
- exports.ValidationHistory = ValidationHistory;
3041
- exports.calculateCost = calculateCost;
3042
- exports.calculateCostFromUsage = calculateCostFromUsage;
3043
- exports.calculateTotalCost = calculateTotalCost;
3044
- exports.combineSignals = combineSignals;
3045
- exports.compileTemplate = compileTemplate;
3046
- exports.computeFileSourceHash = computeFileSourceHash;
3047
- exports.configurePricing = configurePricing;
3048
- exports.createFilePromptRepository = createFilePromptRepository;
3049
- exports.createGoogleProvider = createGoogleProvider;
3050
- exports.createHookRunner = createHookRunner;
3051
- exports.createLogger = createLogger;
3052
- exports.createOpenAIProvider = createOpenAIProvider;
3053
- exports.createStreamingSession = createStreamingSession;
3054
- exports.createZeroUsage = createZeroUsage;
3055
- exports.defineProgressivePattern = defineProgressivePattern;
3056
- exports.detectProviderType = detectProviderType;
3057
- exports.determineResultStatus = determineResultStatus;
3058
- exports.getDuration = getDuration;
3059
- exports.getEffectivePricing = getEffectivePricing;
3060
- exports.getFileSourceDisplayInfo = getFileSourceDisplayInfo;
3061
- exports.getFileSourcesDisplayInfo = getFileSourcesDisplayInfo;
3062
- exports.getModelPricing = getModelPricing;
3063
- exports.getPricingConfig = getPricingConfig;
3064
- exports.inferMediaType = inferMediaType;
3065
- exports.isAbortError = isAbortError;
3066
- exports.isFileSource = isFileSource;
3067
- exports.isFileSourceBase64 = isFileSourceBase64;
3068
- exports.isFileSourceData = isFileSourceData;
3069
- exports.isFileSourcePath = isFileSourcePath;
3070
- exports.isFileSourceUrl = isFileSourceUrl;
3071
- exports.mapExecution = mapExecution;
3072
- exports.mapExecutionResult = mapExecutionResult;
3073
- exports.mergeUsages = mergeUsages;
3074
- exports.noopLogger = noopLogger;
3075
- exports.normalizeError = normalizeError;
3076
- exports.resetPricingConfig = resetPricingConfig;
3077
- exports.resolveFileSource = resolveFileSource;
3078
- exports.resolveFileSourcesInInput = resolveFileSourcesInInput;
3079
- exports.scanForFileSources = scanForFileSources;
3080
- exports.validateModelPricing = validateModelPricing;
3081
- exports.validatePricingConfig = validatePricingConfig;
3082
- exports.validateProviderPricing = validateProviderPricing;
3083
- exports.withValidation = withValidation;
3084
- //# sourceMappingURL=index.cjs.map
3085
- //# sourceMappingURL=index.cjs.map