ResponseStream.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. "use strict";
  2. var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
  3. if (kind === "m") throw new TypeError("Private method is not writable");
  4. if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
  5. if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
  6. return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
  7. };
  8. var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
  9. if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
  10. if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
  11. return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
  12. };
  13. var _ResponseStream_instances, _ResponseStream_params, _ResponseStream_currentResponseSnapshot, _ResponseStream_finalResponse, _ResponseStream_beginRequest, _ResponseStream_addEvent, _ResponseStream_endRequest, _ResponseStream_accumulateResponse;
  14. Object.defineProperty(exports, "__esModule", { value: true });
  15. exports.ResponseStream = void 0;
  16. const error_1 = require("../../error.js");
  17. const EventStream_1 = require("../EventStream.js");
  18. const ResponsesParser_1 = require("../ResponsesParser.js");
  19. class ResponseStream extends EventStream_1.EventStream {
  20. constructor(params) {
  21. super();
  22. _ResponseStream_instances.add(this);
  23. _ResponseStream_params.set(this, void 0);
  24. _ResponseStream_currentResponseSnapshot.set(this, void 0);
  25. _ResponseStream_finalResponse.set(this, void 0);
  26. __classPrivateFieldSet(this, _ResponseStream_params, params, "f");
  27. }
  28. static createResponse(client, params, options) {
  29. const runner = new ResponseStream(params);
  30. runner._run(() => runner._createOrRetrieveResponse(client, params, {
  31. ...options,
  32. headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' },
  33. }));
  34. return runner;
  35. }
  36. async _createOrRetrieveResponse(client, params, options) {
  37. const signal = options?.signal;
  38. if (signal) {
  39. if (signal.aborted)
  40. this.controller.abort();
  41. signal.addEventListener('abort', () => this.controller.abort());
  42. }
  43. __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_beginRequest).call(this);
  44. let stream;
  45. let starting_after = null;
  46. if ('response_id' in params) {
  47. stream = await client.responses.retrieve(params.response_id, { stream: true }, { ...options, signal: this.controller.signal, stream: true });
  48. starting_after = params.starting_after ?? null;
  49. }
  50. else {
  51. stream = await client.responses.create({ ...params, stream: true }, { ...options, signal: this.controller.signal });
  52. }
  53. this._connected();
  54. for await (const event of stream) {
  55. __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_addEvent).call(this, event, starting_after);
  56. }
  57. if (stream.controller.signal?.aborted) {
  58. throw new error_1.APIUserAbortError();
  59. }
  60. return __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_endRequest).call(this);
  61. }
  62. [(_ResponseStream_params = new WeakMap(), _ResponseStream_currentResponseSnapshot = new WeakMap(), _ResponseStream_finalResponse = new WeakMap(), _ResponseStream_instances = new WeakSet(), _ResponseStream_beginRequest = function _ResponseStream_beginRequest() {
  63. if (this.ended)
  64. return;
  65. __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, undefined, "f");
  66. }, _ResponseStream_addEvent = function _ResponseStream_addEvent(event, starting_after) {
  67. if (this.ended)
  68. return;
  69. const maybeEmit = (name, event) => {
  70. if (starting_after == null || event.sequence_number > starting_after) {
  71. this._emit(name, event);
  72. }
  73. };
  74. const response = __classPrivateFieldGet(this, _ResponseStream_instances, "m", _ResponseStream_accumulateResponse).call(this, event);
  75. maybeEmit('event', event);
  76. switch (event.type) {
  77. case 'response.output_text.delta': {
  78. const output = response.output[event.output_index];
  79. if (!output) {
  80. throw new error_1.OpenAIError(`missing output at index ${event.output_index}`);
  81. }
  82. if (output.type === 'message') {
  83. const content = output.content[event.content_index];
  84. if (!content) {
  85. throw new error_1.OpenAIError(`missing content at index ${event.content_index}`);
  86. }
  87. if (content.type !== 'output_text') {
  88. throw new error_1.OpenAIError(`expected content to be 'output_text', got ${content.type}`);
  89. }
  90. maybeEmit('response.output_text.delta', {
  91. ...event,
  92. snapshot: content.text,
  93. });
  94. }
  95. break;
  96. }
  97. case 'response.function_call_arguments.delta': {
  98. const output = response.output[event.output_index];
  99. if (!output) {
  100. throw new error_1.OpenAIError(`missing output at index ${event.output_index}`);
  101. }
  102. if (output.type === 'function_call') {
  103. maybeEmit('response.function_call_arguments.delta', {
  104. ...event,
  105. snapshot: output.arguments,
  106. });
  107. }
  108. break;
  109. }
  110. default:
  111. maybeEmit(event.type, event);
  112. break;
  113. }
  114. }, _ResponseStream_endRequest = function _ResponseStream_endRequest() {
  115. if (this.ended) {
  116. throw new error_1.OpenAIError(`stream has ended, this shouldn't happen`);
  117. }
  118. const snapshot = __classPrivateFieldGet(this, _ResponseStream_currentResponseSnapshot, "f");
  119. if (!snapshot) {
  120. throw new error_1.OpenAIError(`request ended without sending any events`);
  121. }
  122. __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, undefined, "f");
  123. const parsedResponse = finalizeResponse(snapshot, __classPrivateFieldGet(this, _ResponseStream_params, "f"));
  124. __classPrivateFieldSet(this, _ResponseStream_finalResponse, parsedResponse, "f");
  125. return parsedResponse;
  126. }, _ResponseStream_accumulateResponse = function _ResponseStream_accumulateResponse(event) {
  127. let snapshot = __classPrivateFieldGet(this, _ResponseStream_currentResponseSnapshot, "f");
  128. if (!snapshot) {
  129. if (event.type !== 'response.created') {
  130. throw new error_1.OpenAIError(`When snapshot hasn't been set yet, expected 'response.created' event, got ${event.type}`);
  131. }
  132. snapshot = __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, event.response, "f");
  133. return snapshot;
  134. }
  135. switch (event.type) {
  136. case 'response.output_item.added': {
  137. snapshot.output.push(event.item);
  138. break;
  139. }
  140. case 'response.content_part.added': {
  141. const output = snapshot.output[event.output_index];
  142. if (!output) {
  143. throw new error_1.OpenAIError(`missing output at index ${event.output_index}`);
  144. }
  145. if (output.type === 'message') {
  146. output.content.push(event.part);
  147. }
  148. break;
  149. }
  150. case 'response.output_text.delta': {
  151. const output = snapshot.output[event.output_index];
  152. if (!output) {
  153. throw new error_1.OpenAIError(`missing output at index ${event.output_index}`);
  154. }
  155. if (output.type === 'message') {
  156. const content = output.content[event.content_index];
  157. if (!content) {
  158. throw new error_1.OpenAIError(`missing content at index ${event.content_index}`);
  159. }
  160. if (content.type !== 'output_text') {
  161. throw new error_1.OpenAIError(`expected content to be 'output_text', got ${content.type}`);
  162. }
  163. content.text += event.delta;
  164. }
  165. break;
  166. }
  167. case 'response.function_call_arguments.delta': {
  168. const output = snapshot.output[event.output_index];
  169. if (!output) {
  170. throw new error_1.OpenAIError(`missing output at index ${event.output_index}`);
  171. }
  172. if (output.type === 'function_call') {
  173. output.arguments += event.delta;
  174. }
  175. break;
  176. }
  177. case 'response.completed': {
  178. __classPrivateFieldSet(this, _ResponseStream_currentResponseSnapshot, event.response, "f");
  179. break;
  180. }
  181. }
  182. return snapshot;
  183. }, Symbol.asyncIterator)]() {
  184. const pushQueue = [];
  185. const readQueue = [];
  186. let done = false;
  187. this.on('event', (event) => {
  188. const reader = readQueue.shift();
  189. if (reader) {
  190. reader.resolve(event);
  191. }
  192. else {
  193. pushQueue.push(event);
  194. }
  195. });
  196. this.on('end', () => {
  197. done = true;
  198. for (const reader of readQueue) {
  199. reader.resolve(undefined);
  200. }
  201. readQueue.length = 0;
  202. });
  203. this.on('abort', (err) => {
  204. done = true;
  205. for (const reader of readQueue) {
  206. reader.reject(err);
  207. }
  208. readQueue.length = 0;
  209. });
  210. this.on('error', (err) => {
  211. done = true;
  212. for (const reader of readQueue) {
  213. reader.reject(err);
  214. }
  215. readQueue.length = 0;
  216. });
  217. return {
  218. next: async () => {
  219. if (!pushQueue.length) {
  220. if (done) {
  221. return { value: undefined, done: true };
  222. }
  223. return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((event) => (event ? { value: event, done: false } : { value: undefined, done: true }));
  224. }
  225. const event = pushQueue.shift();
  226. return { value: event, done: false };
  227. },
  228. return: async () => {
  229. this.abort();
  230. return { value: undefined, done: true };
  231. },
  232. };
  233. }
  234. /**
  235. * @returns a promise that resolves with the final Response, or rejects
  236. * if an error occurred or the stream ended prematurely without producing a REsponse.
  237. */
  238. async finalResponse() {
  239. await this.done();
  240. const response = __classPrivateFieldGet(this, _ResponseStream_finalResponse, "f");
  241. if (!response)
  242. throw new error_1.OpenAIError('stream ended without producing a ChatCompletion');
  243. return response;
  244. }
  245. }
  246. exports.ResponseStream = ResponseStream;
  247. function finalizeResponse(snapshot, params) {
  248. return (0, ResponsesParser_1.maybeParseResponse)(snapshot, params);
  249. }
  250. //# sourceMappingURL=ResponseStream.js.map