@taico/taico 0.7.0 → 0.8.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 (199) hide show
  1. package/README.md +1 -1
  2. package/dist/ai-providers/ai-model-selections.service.js +24 -2
  3. package/dist/ai-providers/ai-model-selections.service.js.map +1 -1
  4. package/dist/ai-providers/ai-provider-authorization-attempt.entity.d.ts +17 -0
  5. package/dist/ai-providers/ai-provider-authorization-attempt.entity.js +90 -0
  6. package/dist/ai-providers/ai-provider-authorization-attempt.entity.js.map +1 -0
  7. package/dist/ai-providers/ai-provider-connection.entity.d.ts +24 -0
  8. package/dist/ai-providers/ai-provider-connection.entity.js +131 -0
  9. package/dist/ai-providers/ai-provider-connection.entity.js.map +1 -0
  10. package/dist/ai-providers/ai-provider-connections.controller.d.ts +15 -0
  11. package/dist/ai-providers/ai-provider-connections.controller.js +167 -0
  12. package/dist/ai-providers/ai-provider-connections.controller.js.map +1 -0
  13. package/dist/ai-providers/ai-provider-models.service.d.ts +5 -2
  14. package/dist/ai-providers/ai-provider-models.service.js +44 -5
  15. package/dist/ai-providers/ai-provider-models.service.js.map +1 -1
  16. package/dist/ai-providers/ai-provider-models.service.spec.d.ts +1 -0
  17. package/dist/ai-providers/ai-provider-models.service.spec.js +110 -0
  18. package/dist/ai-providers/ai-provider-models.service.spec.js.map +1 -0
  19. package/dist/ai-providers/ai-provider.entity.d.ts +1 -0
  20. package/dist/ai-providers/ai-provider.entity.js +5 -0
  21. package/dist/ai-providers/ai-provider.entity.js.map +1 -1
  22. package/dist/ai-providers/ai-providers.controller.d.ts +1 -1
  23. package/dist/ai-providers/ai-providers.controller.js +4 -3
  24. package/dist/ai-providers/ai-providers.controller.js.map +1 -1
  25. package/dist/ai-providers/ai-providers.module.js +30 -4
  26. package/dist/ai-providers/ai-providers.module.js.map +1 -1
  27. package/dist/ai-providers/ai-providers.scopes.d.ts +4 -0
  28. package/dist/ai-providers/ai-providers.scopes.js +4 -0
  29. package/dist/ai-providers/ai-providers.scopes.js.map +1 -1
  30. package/dist/ai-providers/ai-providers.service.d.ts +3 -1
  31. package/dist/ai-providers/ai-providers.service.js +23 -3
  32. package/dist/ai-providers/ai-providers.service.js.map +1 -1
  33. package/dist/ai-providers/chatgpt-subscription/chatgpt-connections.service.d.ts +50 -0
  34. package/dist/ai-providers/chatgpt-subscription/chatgpt-connections.service.js +607 -0
  35. package/dist/ai-providers/chatgpt-subscription/chatgpt-connections.service.js.map +1 -0
  36. package/dist/ai-providers/chatgpt-subscription/chatgpt-oauth.client.d.ts +59 -0
  37. package/dist/ai-providers/chatgpt-subscription/chatgpt-oauth.client.js +247 -0
  38. package/dist/ai-providers/chatgpt-subscription/chatgpt-oauth.client.js.map +1 -0
  39. package/dist/ai-providers/chatgpt-subscription/chatgpt-responses.model.d.ts +21 -0
  40. package/dist/ai-providers/chatgpt-subscription/chatgpt-responses.model.js +298 -0
  41. package/dist/ai-providers/chatgpt-subscription/chatgpt-responses.model.js.map +1 -0
  42. package/dist/ai-providers/chatgpt-subscription/chatgpt-responses.model.spec.d.ts +1 -0
  43. package/dist/ai-providers/chatgpt-subscription/chatgpt-responses.model.spec.js +345 -0
  44. package/dist/ai-providers/chatgpt-subscription/chatgpt-responses.model.spec.js.map +1 -0
  45. package/dist/ai-providers/chatgpt-subscription/chatgpt-subscription.constants.d.ts +16 -0
  46. package/dist/ai-providers/chatgpt-subscription/chatgpt-subscription.constants.js +26 -0
  47. package/dist/ai-providers/chatgpt-subscription/chatgpt-subscription.constants.js.map +1 -0
  48. package/dist/ai-providers/chatgpt-subscription/chatgpt-subscription.errors.d.ts +12 -0
  49. package/dist/ai-providers/chatgpt-subscription/chatgpt-subscription.errors.js +55 -0
  50. package/dist/ai-providers/chatgpt-subscription/chatgpt-subscription.errors.js.map +1 -0
  51. package/dist/ai-providers/chatgpt-subscription/chatgpt-subscription.service.d.ts +15 -0
  52. package/dist/ai-providers/chatgpt-subscription/chatgpt-subscription.service.js +78 -0
  53. package/dist/ai-providers/chatgpt-subscription/chatgpt-subscription.service.js.map +1 -0
  54. package/dist/ai-providers/dto/http/ai-provider-connection.dto.d.ts +30 -0
  55. package/dist/ai-providers/dto/http/ai-provider-connection.dto.js +182 -0
  56. package/dist/ai-providers/dto/http/ai-provider-connection.dto.js.map +1 -0
  57. package/dist/ai-providers/dto/service/ai-providers.service.types.d.ts +32 -1
  58. package/dist/ai-providers/enums/ai-model-job.enum.d.ts +3 -1
  59. package/dist/ai-providers/enums/ai-model-job.enum.js +10 -3
  60. package/dist/ai-providers/enums/ai-model-job.enum.js.map +1 -1
  61. package/dist/ai-providers/enums/ai-provider-connection-status.enum.d.ts +6 -0
  62. package/dist/ai-providers/enums/ai-provider-connection-status.enum.js +11 -0
  63. package/dist/ai-providers/enums/ai-provider-connection-status.enum.js.map +1 -0
  64. package/dist/ai-providers/enums/ai-provider-type.enum.d.ts +4 -1
  65. package/dist/ai-providers/enums/ai-provider-type.enum.js +9 -1
  66. package/dist/ai-providers/enums/ai-provider-type.enum.js.map +1 -1
  67. package/dist/ai-providers/enums/index.d.ts +1 -0
  68. package/dist/ai-providers/enums/index.js +1 -0
  69. package/dist/ai-providers/enums/index.js.map +1 -1
  70. package/dist/ai-providers/errors/ai-providers.errors.d.ts +33 -0
  71. package/dist/ai-providers/errors/ai-providers.errors.js +75 -4
  72. package/dist/ai-providers/errors/ai-providers.errors.js.map +1 -1
  73. package/dist/ai-providers/google-environment.d.ts +1 -0
  74. package/dist/ai-providers/google-environment.js +4 -0
  75. package/dist/ai-providers/google-environment.js.map +1 -1
  76. package/dist/app.module.js +6 -0
  77. package/dist/app.module.js.map +1 -1
  78. package/dist/config/env.config.d.ts +3 -0
  79. package/dist/config/env.config.js +17 -0
  80. package/dist/config/env.config.js.map +1 -1
  81. package/dist/errors/http/error-catalog.js +48 -0
  82. package/dist/errors/http/error-catalog.js.map +1 -1
  83. package/dist/migrations/1761600000000-AiProviderConnections.d.ts +6 -0
  84. package/dist/migrations/1761600000000-AiProviderConnections.js +61 -0
  85. package/dist/migrations/1761600000000-AiProviderConnections.js.map +1 -0
  86. package/dist/migrations/1761700000000-SplitSmallTasksSelection.d.ts +6 -0
  87. package/dist/migrations/1761700000000-SplitSmallTasksSelection.js +32 -0
  88. package/dist/migrations/1761700000000-SplitSmallTasksSelection.js.map +1 -0
  89. package/dist/migrations/1761800000000-ThreadTimers.d.ts +6 -0
  90. package/dist/migrations/1761800000000-ThreadTimers.js +22 -0
  91. package/dist/migrations/1761800000000-ThreadTimers.js.map +1 -0
  92. package/dist/public/assets/index-G5Ht4law.js +118 -0
  93. package/dist/public/assets/index-NjAtMwFI.css +1 -0
  94. package/dist/public/beta/assets/{index-tTf096QG.js → index-BO6PlAsO.js} +30 -30
  95. package/dist/public/beta/index.html +1 -1
  96. package/dist/public/index.html +2 -2
  97. package/dist/public/package.json +4 -4
  98. package/dist/search/index/search-embeddings.service.js +2 -0
  99. package/dist/search/index/search-embeddings.service.js.map +1 -1
  100. package/dist/secrets/secret-storage-format.d.ts +5 -0
  101. package/dist/secrets/secret-storage-format.js +101 -0
  102. package/dist/secrets/secret-storage-format.js.map +1 -0
  103. package/dist/secrets/secret-storage-format.spec.d.ts +1 -0
  104. package/dist/secrets/secret-storage-format.spec.js +32 -0
  105. package/dist/secrets/secret-storage-format.spec.js.map +1 -0
  106. package/dist/secrets/secrets-encryption.service.d.ts +1 -0
  107. package/dist/secrets/secrets-encryption.service.js +3 -0
  108. package/dist/secrets/secrets-encryption.service.js.map +1 -1
  109. package/dist/secrets/secrets.module.js +1 -1
  110. package/dist/secrets/secrets.module.js.map +1 -1
  111. package/dist/threads/agent/chat-model.factory.d.ts +6 -1
  112. package/dist/threads/agent/chat-model.factory.js +32 -8
  113. package/dist/threads/agent/chat-model.factory.js.map +1 -1
  114. package/dist/threads/agent/chat-model.factory.spec.js +143 -4
  115. package/dist/threads/agent/chat-model.factory.spec.js.map +1 -1
  116. package/dist/threads/agent/hooks/compaction.hook.d.ts +1 -0
  117. package/dist/threads/agent/hooks/compaction.hook.js +31 -7
  118. package/dist/threads/agent/hooks/compaction.hook.js.map +1 -1
  119. package/dist/threads/agent/hooks/hooks.spec.js +123 -0
  120. package/dist/threads/agent/hooks/hooks.spec.js.map +1 -1
  121. package/dist/threads/agent/thread-agent-log.service.d.ts +10 -0
  122. package/dist/threads/agent/thread-agent-log.service.js +57 -1
  123. package/dist/threads/agent/thread-agent-log.service.js.map +1 -1
  124. package/dist/threads/agent/thread-agent-tools.factory.d.ts +3 -1
  125. package/dist/threads/agent/thread-agent-tools.factory.js +195 -3
  126. package/dist/threads/agent/thread-agent-tools.factory.js.map +1 -1
  127. package/dist/threads/agent/thread-agent.prompts.d.ts +15 -0
  128. package/dist/threads/agent/thread-agent.prompts.js +29 -1
  129. package/dist/threads/agent/thread-agent.prompts.js.map +1 -1
  130. package/dist/threads/agent/thread-agent.service.js +10 -3
  131. package/dist/threads/agent/thread-agent.service.js.map +1 -1
  132. package/dist/threads/agent/thread-agent.service.spec.js +59 -4
  133. package/dist/threads/agent/thread-agent.service.spec.js.map +1 -1
  134. package/dist/threads/chat.service.d.ts +13 -1
  135. package/dist/threads/chat.service.js +77 -21
  136. package/dist/threads/chat.service.js.map +1 -1
  137. package/dist/threads/chat.service.spec.d.ts +1 -0
  138. package/dist/threads/chat.service.spec.js +150 -0
  139. package/dist/threads/chat.service.spec.js.map +1 -0
  140. package/dist/threads/dto/service/threads.service.types.d.ts +12 -0
  141. package/dist/threads/dto/thread-response.dto.d.ts +2 -0
  142. package/dist/threads/dto/thread-response.dto.js +10 -0
  143. package/dist/threads/dto/thread-response.dto.js.map +1 -1
  144. package/dist/threads/dto/thread-task-subscription-params.dto.d.ts +4 -0
  145. package/dist/threads/dto/thread-task-subscription-params.dto.js +28 -0
  146. package/dist/threads/dto/thread-task-subscription-params.dto.js.map +1 -0
  147. package/dist/threads/dto/thread-timer-params.dto.d.ts +4 -0
  148. package/dist/threads/dto/thread-timer-params.dto.js +28 -0
  149. package/dist/threads/dto/thread-timer-params.dto.js.map +1 -0
  150. package/dist/threads/dto/thread-timer-response.dto.d.ts +13 -0
  151. package/dist/threads/dto/thread-timer-response.dto.js +92 -0
  152. package/dist/threads/dto/thread-timer-response.dto.js.map +1 -0
  153. package/dist/threads/task-subscriptions/thread-task-subscriptions.service.d.ts +8 -0
  154. package/dist/threads/task-subscriptions/thread-task-subscriptions.service.js +14 -0
  155. package/dist/threads/task-subscriptions/thread-task-subscriptions.service.js.map +1 -1
  156. package/dist/threads/thread-state-reconciler.service.js +5 -0
  157. package/dist/threads/thread-state-reconciler.service.js.map +1 -1
  158. package/dist/threads/thread-state-reconciler.service.spec.d.ts +1 -0
  159. package/dist/threads/thread-state-reconciler.service.spec.js +44 -0
  160. package/dist/threads/thread-state-reconciler.service.spec.js.map +1 -0
  161. package/dist/threads/thread-title.service.d.ts +8 -2
  162. package/dist/threads/thread-title.service.js +18 -3
  163. package/dist/threads/thread-title.service.js.map +1 -1
  164. package/dist/threads/thread-title.service.spec.d.ts +1 -0
  165. package/dist/threads/thread-title.service.spec.js +59 -0
  166. package/dist/threads/thread-title.service.spec.js.map +1 -0
  167. package/dist/threads/threads.controller.d.ts +4 -0
  168. package/dist/threads/threads.controller.js +40 -0
  169. package/dist/threads/threads.controller.js.map +1 -1
  170. package/dist/threads/threads.module.js +8 -0
  171. package/dist/threads/threads.module.js.map +1 -1
  172. package/dist/threads/threads.service.d.ts +8 -1
  173. package/dist/threads/threads.service.js +39 -10
  174. package/dist/threads/threads.service.js.map +1 -1
  175. package/dist/threads/timers/thread-timer-firing.entity.d.ts +9 -0
  176. package/dist/threads/timers/thread-timer-firing.entity.js +54 -0
  177. package/dist/threads/timers/thread-timer-firing.entity.js.map +1 -0
  178. package/dist/threads/timers/thread-timer-sweeper.service.d.ts +11 -0
  179. package/dist/threads/timers/thread-timer-sweeper.service.js +62 -0
  180. package/dist/threads/timers/thread-timer-sweeper.service.js.map +1 -0
  181. package/dist/threads/timers/thread-timer.entity.d.ts +17 -0
  182. package/dist/threads/timers/thread-timer.entity.js +87 -0
  183. package/dist/threads/timers/thread-timer.entity.js.map +1 -0
  184. package/dist/threads/timers/thread-timer.enums.d.ts +4 -0
  185. package/dist/threads/timers/thread-timer.enums.js +9 -0
  186. package/dist/threads/timers/thread-timer.enums.js.map +1 -0
  187. package/dist/threads/timers/thread-timers.service.d.ts +26 -0
  188. package/dist/threads/timers/thread-timers.service.js +130 -0
  189. package/dist/threads/timers/thread-timers.service.js.map +1 -0
  190. package/dist/threads/timers/timer-input.d.ts +13 -0
  191. package/dist/threads/timers/timer-input.js +159 -0
  192. package/dist/threads/timers/timer-input.js.map +1 -0
  193. package/dist/threads/timers/timer-input.spec.d.ts +1 -0
  194. package/dist/threads/timers/timer-input.spec.js +92 -0
  195. package/dist/threads/timers/timer-input.spec.js.map +1 -0
  196. package/dist/tsconfig.tsbuildinfo +1 -1
  197. package/package.json +7 -6
  198. package/dist/public/assets/index-ChunDgwd.css +0 -1
  199. package/dist/public/assets/index-DRkJsm_M.js +0 -118
@@ -0,0 +1,298 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UNSUPPORTED_BODY_FIELDS = exports.TOOL_NAMESPACE = void 0;
4
+ exports.sanitizeResponsesBody = sanitizeResponsesBody;
5
+ exports.requireCompletedResponse = requireCompletedResponse;
6
+ exports.createChatgptResponsesModel = createChatgptResponsesModel;
7
+ const ai_1 = require("ai");
8
+ const openai_1 = require("@ai-sdk/openai");
9
+ const ai_providers_errors_1 = require("../errors/ai-providers.errors");
10
+ const chatgpt_subscription_errors_1 = require("./chatgpt-subscription.errors");
11
+ exports.TOOL_NAMESPACE = {
12
+ name: 'taico',
13
+ description: 'Tools for working with Taico tasks, threads and context.',
14
+ };
15
+ exports.UNSUPPORTED_BODY_FIELDS = [
16
+ 'background',
17
+ 'conversation',
18
+ 'max_output_tokens',
19
+ 'max_tool_calls',
20
+ 'metadata',
21
+ 'moderation',
22
+ 'multi_agent',
23
+ 'previous_response_id',
24
+ 'prompt',
25
+ 'prompt_cache_retention',
26
+ 'safety_identifier',
27
+ 'temperature',
28
+ 'top_logprobs',
29
+ 'top_p',
30
+ 'truncation',
31
+ 'user',
32
+ ];
33
+ function sanitizeResponsesBody(body) {
34
+ const sanitized = { ...body, store: false, stream: true };
35
+ for (const field of exports.UNSUPPORTED_BODY_FIELDS) {
36
+ delete sanitized[field];
37
+ }
38
+ if (Array.isArray(sanitized.input)) {
39
+ sanitized.input = sanitized.input.map((item) => item &&
40
+ typeof item === 'object' &&
41
+ item.role === 'system'
42
+ ? { ...item, role: 'developer' }
43
+ : item);
44
+ }
45
+ return sanitized;
46
+ }
47
+ function failureFromEvent(event) {
48
+ const response = (event.response ?? {});
49
+ switch (event.type) {
50
+ case 'response.failed':
51
+ return {
52
+ code: typeof response.error?.code === 'string'
53
+ ? response.error.code
54
+ : chatgpt_subscription_errors_1.STREAM_FAILED,
55
+ message: typeof response.error?.message === 'string'
56
+ ? response.error.message
57
+ : null,
58
+ };
59
+ case 'response.incomplete':
60
+ return {
61
+ code: chatgpt_subscription_errors_1.STREAM_INCOMPLETE,
62
+ message: typeof response.incomplete_details?.reason === 'string'
63
+ ? response.incomplete_details.reason
64
+ : null,
65
+ };
66
+ case 'error': {
67
+ const error = (event.error ?? event);
68
+ return {
69
+ code: typeof error.code === 'string' ? error.code : chatgpt_subscription_errors_1.STREAM_FAILED,
70
+ message: typeof error.message === 'string' ? error.message : null,
71
+ param: typeof error.param === 'string' ? error.param : null,
72
+ };
73
+ }
74
+ default:
75
+ return null;
76
+ }
77
+ }
78
+ function requireCompletedResponse(onOutcome) {
79
+ const decoder = new TextDecoder();
80
+ const encoder = new TextEncoder();
81
+ let buffer = '';
82
+ let completed = false;
83
+ let failed = false;
84
+ const fail = (controller, failure) => {
85
+ failed = true;
86
+ onOutcome(failure);
87
+ controller.error((0, chatgpt_subscription_errors_1.chatgptRequestFailed)(failure));
88
+ };
89
+ return new TransformStream({
90
+ transform(chunk, controller) {
91
+ if (failed) {
92
+ return;
93
+ }
94
+ buffer += decoder.decode(chunk, { stream: true });
95
+ for (;;) {
96
+ const boundary = /\r?\n\r?\n/.exec(buffer);
97
+ if (!boundary) {
98
+ return;
99
+ }
100
+ const frame = buffer.slice(0, boundary.index);
101
+ buffer = buffer.slice(boundary.index + boundary[0].length);
102
+ const data = frame
103
+ .split(/\r?\n/)
104
+ .filter((line) => line.startsWith('data:'))
105
+ .map((line) => line.slice(5).trimStart())
106
+ .join('\n');
107
+ if (data && data !== '[DONE]') {
108
+ let event = null;
109
+ try {
110
+ event = JSON.parse(data);
111
+ }
112
+ catch {
113
+ }
114
+ const failure = event ? failureFromEvent(event) : null;
115
+ if (failure) {
116
+ fail(controller, failure);
117
+ return;
118
+ }
119
+ if (event?.type === 'response.completed') {
120
+ completed = true;
121
+ }
122
+ }
123
+ controller.enqueue(encoder.encode(`${frame}\n\n`));
124
+ }
125
+ },
126
+ flush(controller) {
127
+ if (failed) {
128
+ return;
129
+ }
130
+ if (!completed) {
131
+ fail(controller, { code: chatgpt_subscription_errors_1.STREAM_ENDED_EARLY, message: null });
132
+ return;
133
+ }
134
+ onOutcome(null);
135
+ },
136
+ });
137
+ }
138
+ async function failureFromResponse(response) {
139
+ const text = await response.text().catch(() => '');
140
+ let error = {};
141
+ try {
142
+ const parsed = JSON.parse(text);
143
+ error = parsed.error ?? {};
144
+ }
145
+ catch {
146
+ }
147
+ return {
148
+ code: typeof error.code === 'string' ? error.code : null,
149
+ message: typeof error.message === 'string'
150
+ ? error.message
151
+ : text.slice(0, 300) || null,
152
+ status: response.status,
153
+ param: typeof error.param === 'string' ? error.param : null,
154
+ requestId: response.headers.get('x-request-id'),
155
+ };
156
+ }
157
+ function planFailureIn(error) {
158
+ for (let current = error, depth = 0; current && depth < 5; depth++) {
159
+ if (current instanceof ai_providers_errors_1.AiProviderRequestFailedError) {
160
+ return current;
161
+ }
162
+ current = current.cause;
163
+ }
164
+ return null;
165
+ }
166
+ const planRequestMiddleware = {
167
+ specificationVersion: 'v4',
168
+ transformParams: async ({ params }) => {
169
+ for (const tool of params.tools ?? []) {
170
+ if (tool.type !== 'function') {
171
+ throw (0, chatgpt_subscription_errors_1.chatgptRequestFailed)({
172
+ code: 'subscription_sharing_unsupported_capability',
173
+ message: `Tool ${tool.name} is not a function tool.`,
174
+ param: 'tools',
175
+ });
176
+ }
177
+ }
178
+ return {
179
+ ...params,
180
+ maxOutputTokens: undefined,
181
+ temperature: undefined,
182
+ topP: undefined,
183
+ topK: undefined,
184
+ presencePenalty: undefined,
185
+ frequencyPenalty: undefined,
186
+ seed: undefined,
187
+ tools: params.tools?.map((tool) => tool.type === 'function'
188
+ ? {
189
+ ...tool,
190
+ providerOptions: {
191
+ ...tool.providerOptions,
192
+ openai: {
193
+ ...tool.providerOptions?.openai,
194
+ namespace: exports.TOOL_NAMESPACE,
195
+ },
196
+ },
197
+ }
198
+ : tool),
199
+ providerOptions: {
200
+ ...params.providerOptions,
201
+ openai: {
202
+ ...params.providerOptions?.openai,
203
+ store: false,
204
+ systemMessageMode: 'developer',
205
+ },
206
+ },
207
+ };
208
+ },
209
+ wrapGenerate: async () => {
210
+ throw new Error('The ChatGPT plan only accepts streamed requests. Call streamText() for this model.');
211
+ },
212
+ wrapStream: async ({ doStream }) => {
213
+ let result;
214
+ try {
215
+ result = await doStream();
216
+ }
217
+ catch (error) {
218
+ throw planFailureIn(error) ?? error;
219
+ }
220
+ const reader = result.stream.getReader();
221
+ const stream = new ReadableStream({
222
+ async pull(controller) {
223
+ try {
224
+ const { done, value } = await reader.read();
225
+ if (done) {
226
+ controller.close();
227
+ }
228
+ else if (value.type === 'error') {
229
+ controller.enqueue({
230
+ ...value,
231
+ error: planFailureIn(value.error) ?? value.error,
232
+ });
233
+ }
234
+ else {
235
+ controller.enqueue(value);
236
+ }
237
+ }
238
+ catch (error) {
239
+ controller.error(planFailureIn(error) ?? error);
240
+ }
241
+ },
242
+ cancel: (reason) => reader.cancel(reason),
243
+ });
244
+ return { ...result, stream };
245
+ },
246
+ };
247
+ function createChatgptResponsesModel(input) {
248
+ const baseURL = input.apiBaseUrl.replace(/\/+$/, '');
249
+ const responsesUrl = `${baseURL}/responses`;
250
+ const doFetch = input.fetch ?? fetch;
251
+ const report = (failure) => input.onOutcome?.(failure
252
+ ? (failure.code ??
253
+ (failure.status ? `http_${failure.status}` : 'unknown'))
254
+ : null);
255
+ const guardedFetch = async (target, init) => {
256
+ const url = typeof target === 'string'
257
+ ? target
258
+ : target instanceof URL
259
+ ? target.href
260
+ : target.url;
261
+ if (url !== responsesUrl ||
262
+ init?.method !== 'POST' ||
263
+ typeof init.body !== 'string') {
264
+ throw (0, chatgpt_subscription_errors_1.chatgptRequestFailed)({
265
+ code: 'subscription_sharing_route_not_supported',
266
+ message: null,
267
+ });
268
+ }
269
+ const headers = new Headers(init.headers);
270
+ headers.set('authorization', `Bearer ${await input.getAccessToken()}`);
271
+ headers.set('accept', 'text/event-stream');
272
+ const response = await doFetch(responsesUrl, {
273
+ ...init,
274
+ headers,
275
+ body: JSON.stringify(sanitizeResponsesBody(JSON.parse(init.body))),
276
+ });
277
+ if (!response.ok || !response.body) {
278
+ const failure = await failureFromResponse(response);
279
+ report(failure);
280
+ throw (0, chatgpt_subscription_errors_1.chatgptRequestFailed)(failure);
281
+ }
282
+ return new Response(response.body.pipeThrough(requireCompletedResponse(report)), {
283
+ status: response.status,
284
+ statusText: response.statusText,
285
+ headers: response.headers,
286
+ });
287
+ };
288
+ const openai = (0, openai_1.createOpenAI)({
289
+ apiKey: 'sign-in-with-chatgpt',
290
+ baseURL,
291
+ fetch: guardedFetch,
292
+ });
293
+ return (0, ai_1.wrapLanguageModel)({
294
+ model: openai.responses(input.modelId),
295
+ middleware: planRequestMiddleware,
296
+ });
297
+ }
298
+ //# sourceMappingURL=chatgpt-responses.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatgpt-responses.model.js","sourceRoot":"","sources":["../../../src/ai-providers/chatgpt-subscription/chatgpt-responses.model.ts"],"names":[],"mappings":";;;AA0DA,sDAiBC;AAqDD,4DAsEC;AA0ID,kEA2EC;AA3ZD,2BAA+E;AAC/E,2CAA8C;AAC9C,uEAA6E;AAC7E,+EAMuC;AAM1B,QAAA,cAAc,GAAG;IAC5B,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,0DAA0D;CAC/D,CAAC;AAGE,QAAA,uBAAuB,GAAG;IACrC,YAAY;IACZ,cAAc;IACd,mBAAmB;IACnB,gBAAgB;IAChB,UAAU;IACV,YAAY;IACZ,aAAa;IACb,sBAAsB;IACtB,QAAQ;IACR,wBAAwB;IACxB,mBAAmB;IACnB,aAAa;IACb,cAAc;IACd,OAAO;IACP,YAAY;IACZ,MAAM;CACE,CAAC;AAoBX,SAAgB,qBAAqB,CAAC,IAAmB;IACvD,MAAM,SAAS,GAAkB,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACzE,KAAK,MAAM,KAAK,IAAI,+BAAuB,EAAE,CAAC;QAC5C,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAa,EAAE,EAAE,CACtD,IAAI;YACJ,OAAO,IAAI,KAAK,QAAQ;YACvB,IAA2B,CAAC,IAAI,KAAK,QAAQ;YAC5C,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE;YAChC,CAAC,CAAC,IAAI,CACT,CAAC;IACJ,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CACvB,KAA8B;IAE9B,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAGrC,CAAC;IAEF,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,iBAAiB;YACpB,OAAO;gBACL,IAAI,EACF,OAAO,QAAQ,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ;oBACtC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI;oBACrB,CAAC,CAAC,2CAAa;gBACnB,OAAO,EACL,OAAO,QAAQ,CAAC,KAAK,EAAE,OAAO,KAAK,QAAQ;oBACzC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO;oBACxB,CAAC,CAAC,IAAI;aACX,CAAC;QACJ,KAAK,qBAAqB;YACxB,OAAO;gBACL,IAAI,EAAE,+CAAiB;gBACvB,OAAO,EACL,OAAO,QAAQ,CAAC,kBAAkB,EAAE,MAAM,KAAK,QAAQ;oBACrD,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,MAAM;oBACpC,CAAC,CAAC,IAAI;aACX,CAAC;QACJ,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAIlC,CAAC;YACF,OAAO;gBACL,IAAI,EAAE,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,2CAAa;gBACjE,OAAO,EAAE,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;gBACjE,KAAK,EAAE,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;aAC5D,CAAC;QACJ,CAAC;QACD;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAQD,SAAgB,wBAAwB,CACtC,SAAoD;IAEpD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,MAAM,IAAI,GAAG,CACX,UAAwD,EACxD,OAAwB,EACxB,EAAE;QACF,MAAM,GAAG,IAAI,CAAC;QACd,SAAS,CAAC,OAAO,CAAC,CAAC;QACnB,UAAU,CAAC,KAAK,CAAC,IAAA,kDAAoB,EAAC,OAAO,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC;IAEF,OAAO,IAAI,eAAe,CAAC;QACzB,SAAS,CAAC,KAAK,EAAE,UAAU;YACzB,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAElD,SAAS,CAAC;gBACR,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,OAAO;gBACT,CAAC;gBACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAC9C,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAE3D,MAAM,IAAI,GAAG,KAAK;qBACf,KAAK,CAAC,OAAO,CAAC;qBACd,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;qBAC1C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;qBACxC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEd,IAAI,IAAI,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC9B,IAAI,KAAK,GAAmC,IAAI,CAAC;oBACjD,IAAI,CAAC;wBACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;oBACtD,CAAC;oBAAC,MAAM,CAAC;oBAET,CAAC;oBACD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBACvD,IAAI,OAAO,EAAE,CAAC;wBACZ,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;wBAC1B,OAAO;oBACT,CAAC;oBACD,IAAI,KAAK,EAAE,IAAI,KAAK,oBAAoB,EAAE,CAAC;wBACzC,SAAS,GAAG,IAAI,CAAC;oBACnB,CAAC;gBACH,CAAC;gBAED,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;QACD,KAAK,CAAC,UAAU;YACd,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YACD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,gDAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9D,OAAO;YACT,CAAC;YACD,SAAS,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,QAAkB;IAElB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IACnD,IAAI,KAAK,GAA2D,EAAE,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA6B,CAAC;QAC5D,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;IAET,CAAC;IACD,OAAO;QACL,IAAI,EAAE,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;QACxD,OAAO,EACL,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;YAC/B,CAAC,CAAC,KAAK,CAAC,OAAO;YACf,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI;QAChC,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,KAAK,EAAE,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;QAC3D,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;KAChD,CAAC;AACJ,CAAC;AAGD,SAAS,aAAa,CAAC,KAAc;IACnC,KAAK,IAAI,OAAO,GAAG,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACnE,IAAI,OAAO,YAAY,kDAA4B,EAAE,CAAC;YACpD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,GAAI,OAA+B,CAAC,KAAK,CAAC;IACnD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAOD,MAAM,qBAAqB,GAA4B;IACrD,oBAAoB,EAAE,IAAI;IAC1B,eAAe,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACpC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YACtC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC7B,MAAM,IAAA,kDAAoB,EAAC;oBACzB,IAAI,EAAE,6CAA6C;oBACnD,OAAO,EAAE,QAAQ,IAAI,CAAC,IAAI,0BAA0B;oBACpD,KAAK,EAAE,OAAO;iBACf,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO;YACL,GAAG,MAAM;YACT,eAAe,EAAE,SAAS;YAC1B,WAAW,EAAE,SAAS;YACtB,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,eAAe,EAAE,SAAS;YAC1B,gBAAgB,EAAE,SAAS;YAC3B,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAChC,IAAI,CAAC,IAAI,KAAK,UAAU;gBACtB,CAAC,CAAC;oBACE,GAAG,IAAI;oBACP,eAAe,EAAE;wBACf,GAAG,IAAI,CAAC,eAAe;wBACvB,MAAM,EAAE;4BACN,GAAG,IAAI,CAAC,eAAe,EAAE,MAAM;4BAC/B,SAAS,EAAE,sBAAc;yBAC1B;qBACF;iBACF;gBACH,CAAC,CAAC,IAAI,CACT;YACD,eAAe,EAAE;gBACf,GAAG,MAAM,CAAC,eAAe;gBACzB,MAAM,EAAE;oBACN,GAAG,MAAM,CAAC,eAAe,EAAE,MAAM;oBACjC,KAAK,EAAE,KAAK;oBACZ,iBAAiB,EAAE,WAAW;iBAC/B;aACF;SACF,CAAC;IACJ,CAAC;IAED,YAAY,EAAE,KAAK,IAAI,EAAE;QACvB,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF,CAAC;IACJ,CAAC;IAGD,UAAU,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACjC,IAAI,MAA4C,CAAC;QACjD,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;QACtC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QAEzC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAoB;YACnD,KAAK,CAAC,IAAI,CAAC,UAAU;gBACnB,IAAI,CAAC;oBACH,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;oBAC5C,IAAI,IAAI,EAAE,CAAC;wBACT,UAAU,CAAC,KAAK,EAAE,CAAC;oBACrB,CAAC;yBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;wBAClC,UAAU,CAAC,OAAO,CAAC;4BACjB,GAAG,KAAK;4BACR,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK;yBACjD,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBAC5B,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;YACD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;SAC1C,CAAC,CAAC;QAEH,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC;CACF,CAAC;AAUF,SAAgB,2BAA2B,CACzC,KAAiC;IAEjC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,GAAG,OAAO,YAAY,CAAC;IAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC;IACrC,MAAM,MAAM,GAAG,CAAC,OAA+B,EAAE,EAAE,CACjD,KAAK,CAAC,SAAS,EAAE,CACf,OAAO;QACL,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI;YACX,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC5D,CAAC,CAAC,IAAI,CACT,CAAC;IAEJ,MAAM,YAAY,GAAG,KAAK,EACxB,MAAmC,EACnC,IAAkC,EACf,EAAE;QACrB,MAAM,GAAG,GACP,OAAO,MAAM,KAAK,QAAQ;YACxB,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,MAAM,YAAY,GAAG;gBACrB,CAAC,CAAC,MAAM,CAAC,IAAI;gBACb,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;QACnB,IACE,GAAG,KAAK,YAAY;YACpB,IAAI,EAAE,MAAM,KAAK,MAAM;YACvB,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAC7B,CAAC;YACD,MAAM,IAAA,kDAAoB,EAAC;gBACzB,IAAI,EAAE,0CAA0C;gBAChD,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;QACL,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,MAAM,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;QAE3C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE;YAC3C,GAAG,IAAI;YACP,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAkB,CAAC,CAC9D;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACpD,MAAM,CAAC,OAAO,CAAC,CAAC;YAEhB,MAAM,IAAA,kDAAoB,EAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,IAAI,QAAQ,CACjB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC,EAC3D;YACE,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO,EAAE,QAAQ,CAAC,OAAO;SAC1B,CACF,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC;QAE1B,MAAM,EAAE,sBAAsB;QAC9B,OAAO;QACP,KAAK,EAAE,YAA4B;KACpC,CAAC,CAAC;IAEH,OAAO,IAAA,sBAAiB,EAAC;QACvB,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;QACtC,UAAU,EAAE,qBAAqB;KAClC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ai_1 = require("ai");
4
+ const chatgpt_responses_model_1 = require("./chatgpt-responses.model");
5
+ jest.mock('@taico/errors', () => ({
6
+ ErrorCodes: new Proxy({}, { get: (_target, name) => name }),
7
+ }));
8
+ const API = 'https://api.openai.test/v1';
9
+ const sse = (events) => events
10
+ .map((event) => `event: ${String(event.type)}\ndata: ${JSON.stringify(event)}\n\n`)
11
+ .join('');
12
+ const created = {
13
+ type: 'response.created',
14
+ response: { id: 'resp_1', created_at: 1, model: 'm' },
15
+ };
16
+ const completed = {
17
+ type: 'response.completed',
18
+ response: { usage: { input_tokens: 7, output_tokens: 3, total_tokens: 10 } },
19
+ };
20
+ const text = (value) => [
21
+ {
22
+ type: 'response.output_item.added',
23
+ output_index: 0,
24
+ item: { type: 'message', id: 'msg_1' },
25
+ },
26
+ {
27
+ type: 'response.output_text.delta',
28
+ item_id: 'msg_1',
29
+ output_index: 0,
30
+ delta: value,
31
+ },
32
+ {
33
+ type: 'response.output_item.done',
34
+ output_index: 0,
35
+ item: { type: 'message', id: 'msg_1' },
36
+ },
37
+ ];
38
+ const functionCall = {
39
+ type: 'function_call',
40
+ id: 'fc_1',
41
+ call_id: 'call_1',
42
+ name: 'lookup',
43
+ namespace: chatgpt_responses_model_1.TOOL_NAMESPACE.name,
44
+ arguments: '{"id":"42"}',
45
+ };
46
+ function harness(replies) {
47
+ const requests = [];
48
+ const outcomes = [];
49
+ let tokenCalls = 0;
50
+ const fakeFetch = (async (url, init) => {
51
+ requests.push({
52
+ url,
53
+ headers: new Headers(init.headers),
54
+ body: JSON.parse(init.body),
55
+ });
56
+ const reply = replies.shift();
57
+ if (reply instanceof Response) {
58
+ return reply;
59
+ }
60
+ return new Response(reply ?? sse([created, ...text('ok'), completed]), {
61
+ status: 200,
62
+ headers: { 'content-type': 'text/event-stream' },
63
+ });
64
+ });
65
+ const model = (0, chatgpt_responses_model_1.createChatgptResponsesModel)({
66
+ modelId: 'gpt-plan-large',
67
+ apiBaseUrl: API,
68
+ getAccessToken: async () => `token-${++tokenCalls}`,
69
+ onOutcome: (code) => outcomes.push(code),
70
+ fetch: fakeFetch,
71
+ });
72
+ return { model, requests, outcomes };
73
+ }
74
+ async function run(model, options = {}) {
75
+ let error = null;
76
+ let collected = '';
77
+ const result = (0, ai_1.streamText)({
78
+ model,
79
+ instructions: 'You are Taico.',
80
+ messages: [{ role: 'user', content: 'hello' }],
81
+ onError: () => undefined,
82
+ ...options,
83
+ });
84
+ try {
85
+ for await (const part of result.stream) {
86
+ if (part.type === 'text-delta') {
87
+ collected += part.text;
88
+ }
89
+ if (part.type === 'error') {
90
+ error = part.error;
91
+ }
92
+ }
93
+ }
94
+ catch (thrown) {
95
+ error = thrown;
96
+ }
97
+ return { text: collected, error };
98
+ }
99
+ describe('ChatGPT plan Responses model', () => {
100
+ it('sends a streamed, unstored request with the person’s token and no system input item', async () => {
101
+ const { model, requests, outcomes } = harness([
102
+ sse([created, ...text('Hi there'), completed]),
103
+ ]);
104
+ const { text: answer, error } = await run(model, {
105
+ temperature: 0.2,
106
+ maxOutputTokens: 100,
107
+ topP: 0.9,
108
+ });
109
+ expect(error).toBeNull();
110
+ expect(answer).toBe('Hi there');
111
+ expect(requests).toHaveLength(1);
112
+ const [request] = requests;
113
+ expect(request.url).toBe(`${API}/responses`);
114
+ expect(request.headers.get('authorization')).toBe('Bearer token-1');
115
+ expect(request.body).toMatchObject({
116
+ model: 'gpt-plan-large',
117
+ store: false,
118
+ stream: true,
119
+ });
120
+ for (const field of chatgpt_responses_model_1.UNSUPPORTED_BODY_FIELDS) {
121
+ expect(request.body).not.toHaveProperty(field);
122
+ }
123
+ const roles = request.body.input.map((item) => item.role);
124
+ expect(roles).toEqual(['developer', 'user']);
125
+ expect(JSON.stringify(request.body.input)).toContain('You are Taico.');
126
+ expect(outcomes).toEqual([null]);
127
+ });
128
+ it('puts function tools in a namespace, runs them, and replays the whole exchange', async () => {
129
+ const { model, requests } = harness([
130
+ sse([
131
+ created,
132
+ {
133
+ type: 'response.output_item.added',
134
+ output_index: 0,
135
+ item: { ...functionCall, arguments: '' },
136
+ },
137
+ {
138
+ type: 'response.output_item.done',
139
+ output_index: 0,
140
+ item: { ...functionCall, status: 'completed' },
141
+ },
142
+ completed,
143
+ ]),
144
+ sse([created, ...text('It is 42.'), completed]),
145
+ ]);
146
+ const execute = jest.fn(async () => ({ title: 'The answer' }));
147
+ const { text: answer, error } = await run(model, {
148
+ tools: {
149
+ lookup: (0, ai_1.tool)({
150
+ description: 'Looks something up',
151
+ inputSchema: (0, ai_1.jsonSchema)({
152
+ type: 'object',
153
+ properties: { id: { type: 'string' } },
154
+ required: ['id'],
155
+ }),
156
+ execute,
157
+ }),
158
+ },
159
+ stopWhen: (0, ai_1.isStepCount)(5),
160
+ });
161
+ expect(error).toBeNull();
162
+ expect(answer).toBe('It is 42.');
163
+ expect(execute).toHaveBeenCalledWith({ id: '42' }, expect.anything());
164
+ expect(requests[0].body.tools).toEqual([
165
+ expect.objectContaining({
166
+ type: 'namespace',
167
+ name: chatgpt_responses_model_1.TOOL_NAMESPACE.name,
168
+ tools: [expect.objectContaining({ type: 'function', name: 'lookup' })],
169
+ }),
170
+ ]);
171
+ const second = requests[1];
172
+ expect(second.headers.get('authorization')).toBe('Bearer token-2');
173
+ expect(second.body).not.toHaveProperty('previous_response_id');
174
+ expect(second.body.input).toEqual(expect.arrayContaining([
175
+ expect.objectContaining({
176
+ type: 'function_call',
177
+ call_id: 'call_1',
178
+ name: 'lookup',
179
+ namespace: chatgpt_responses_model_1.TOOL_NAMESPACE.name,
180
+ }),
181
+ expect.objectContaining({
182
+ type: 'function_call_output',
183
+ call_id: 'call_1',
184
+ }),
185
+ ]));
186
+ });
187
+ it('refuses a non-streaming call without sending anything', async () => {
188
+ const { model, requests } = harness([]);
189
+ await expect((0, ai_1.generateText)({ model, prompt: 'hello' })).rejects.toThrow(/streamed requests/);
190
+ expect(requests).toHaveLength(0);
191
+ });
192
+ it('fails with the plan’s usage-limit error when the response fails after some text', async () => {
193
+ const { model, requests, outcomes } = harness([
194
+ sse([
195
+ created,
196
+ ...text('Partial'),
197
+ {
198
+ type: 'response.failed',
199
+ sequence_number: 5,
200
+ response: {
201
+ error: {
202
+ code: 'subscription_sharing_usage_limit_exceeded',
203
+ message: 'limit',
204
+ },
205
+ },
206
+ },
207
+ ]),
208
+ ]);
209
+ const { error } = await run(model);
210
+ expect(error).toMatchObject({
211
+ code: 'AI_PROVIDER_REQUEST_FAILED',
212
+ context: { upstreamCode: 'subscription_sharing_usage_limit_exceeded' },
213
+ });
214
+ expect(error.message).toContain('https://chatgpt.com/settings/usage');
215
+ expect(error.message).toContain('did not switch to another provider');
216
+ expect(requests).toHaveLength(1);
217
+ expect(outcomes).toEqual(['subscription_sharing_usage_limit_exceeded']);
218
+ });
219
+ it('treats an incomplete response as a failure', async () => {
220
+ const { model } = harness([
221
+ sse([
222
+ created,
223
+ ...text('Half an ans'),
224
+ {
225
+ type: 'response.incomplete',
226
+ response: { incomplete_details: { reason: 'max_output_tokens' } },
227
+ },
228
+ ]),
229
+ ]);
230
+ const { error } = await run(model);
231
+ expect(error).toMatchObject({
232
+ context: { upstreamCode: 'response_incomplete' },
233
+ });
234
+ });
235
+ it('treats a stream that ends before response.completed as a failure', async () => {
236
+ const { model, outcomes } = harness([
237
+ sse([created, ...text('Half an ans')]),
238
+ ]);
239
+ const { error } = await run(model);
240
+ expect(error).toMatchObject({
241
+ context: { upstreamCode: 'stream_ended_before_completion' },
242
+ });
243
+ expect(outcomes).toEqual(['stream_ended_before_completion']);
244
+ });
245
+ it.each([
246
+ [429, 'subscription_sharing_usage_limit_exceeded'],
247
+ [503, 'subscription_sharing_usage_unavailable'],
248
+ [403, 'subscription_sharing_user_not_eligible'],
249
+ [400, 'subscription_sharing_unsupported_capability'],
250
+ ])('reports HTTP %i %s once, without retrying', async (status, code) => {
251
+ const { model, requests, outcomes } = harness([
252
+ new Response(JSON.stringify({ error: { code, message: 'no', param: 'tools' } }), {
253
+ status,
254
+ headers: {
255
+ 'content-type': 'application/json',
256
+ 'x-request-id': 'req_9',
257
+ },
258
+ }),
259
+ ]);
260
+ const { error } = await run(model);
261
+ expect(error).toMatchObject({
262
+ code: 'AI_PROVIDER_REQUEST_FAILED',
263
+ context: {
264
+ upstreamCode: code,
265
+ status,
266
+ requestId: 'req_9',
267
+ param: 'tools',
268
+ },
269
+ });
270
+ expect(requests).toHaveLength(1);
271
+ expect(outcomes).toEqual([code]);
272
+ });
273
+ });
274
+ describe('sanitizeResponsesBody', () => {
275
+ it('forces streaming and no storage, and drops what the plan does not accept', () => {
276
+ const sanitized = (0, chatgpt_responses_model_1.sanitizeResponsesBody)({
277
+ model: 'm',
278
+ store: true,
279
+ stream: false,
280
+ previous_response_id: 'resp_0',
281
+ conversation: 'conv_1',
282
+ temperature: 1,
283
+ max_output_tokens: 5,
284
+ metadata: { a: 'b' },
285
+ user: 'someone',
286
+ input: [
287
+ { type: 'message', role: 'system', content: 'be nice' },
288
+ { role: 'user', content: 'hi' },
289
+ ],
290
+ });
291
+ expect(sanitized).toEqual({
292
+ model: 'm',
293
+ store: false,
294
+ stream: true,
295
+ input: [
296
+ { type: 'message', role: 'developer', content: 'be nice' },
297
+ { role: 'user', content: 'hi' },
298
+ ],
299
+ });
300
+ });
301
+ });
302
+ describe('requireCompletedResponse', () => {
303
+ const pipe = async (chunks) => {
304
+ const outcomes = [];
305
+ const source = new ReadableStream({
306
+ start(controller) {
307
+ for (const chunk of chunks) {
308
+ controller.enqueue(new TextEncoder().encode(chunk));
309
+ }
310
+ controller.close();
311
+ },
312
+ });
313
+ const reader = source
314
+ .pipeThrough((0, chatgpt_responses_model_1.requireCompletedResponse)((failure) => outcomes.push(failure)))
315
+ .getReader();
316
+ let output = '';
317
+ for (;;) {
318
+ const { done, value } = await reader.read();
319
+ if (done) {
320
+ break;
321
+ }
322
+ output += new TextDecoder().decode(value);
323
+ }
324
+ return { output, outcomes };
325
+ };
326
+ it('passes a completed stream through, even when events are split across chunks', async () => {
327
+ const whole = sse([created, ...text('ok'), completed]);
328
+ const middle = Math.floor(whole.length / 2);
329
+ const { output, outcomes } = await pipe([
330
+ whole.slice(0, middle),
331
+ whole.slice(middle),
332
+ ]);
333
+ expect(output).toBe(whole);
334
+ expect(outcomes).toEqual([null]);
335
+ });
336
+ it('errors on an error event', async () => {
337
+ await expect(pipe([
338
+ sse([
339
+ created,
340
+ { type: 'error', code: 'server_error', message: 'boom' },
341
+ ]),
342
+ ])).rejects.toMatchObject({ context: { upstreamCode: 'server_error' } });
343
+ });
344
+ });
345
+ //# sourceMappingURL=chatgpt-responses.model.spec.js.map