@puku-ai/sdk 4.0.3 → 4.0.4
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.
- package/README.md +24 -7
- package/dist/index.cjs +85 -0
- package/dist/vendor/_vendor/partial-json-parser/parser.cjs +225 -0
- package/dist/vendor/api-promise.cjs +18 -0
- package/dist/vendor/client.cjs +1013 -0
- package/dist/vendor/core/api-promise.cjs +80 -0
- package/dist/vendor/core/api.cjs +2 -0
- package/dist/vendor/core/credentials.cjs +313 -0
- package/dist/vendor/core/error.cjs +156 -0
- package/dist/vendor/core/middleware.cjs +173 -0
- package/dist/vendor/core/pagination.cjs +215 -0
- package/dist/vendor/core/resource.cjs +11 -0
- package/dist/vendor/core/streaming.cjs +346 -0
- package/dist/vendor/core/uploads.cjs +5 -0
- package/dist/vendor/error.cjs +18 -0
- package/dist/vendor/helpers/beta/environments.cjs +30 -0
- package/dist/vendor/helpers/beta/json-schema.cjs +56 -0
- package/dist/vendor/helpers/beta/mcp.cjs +418 -0
- package/dist/vendor/helpers/beta/memory.cjs +17 -0
- package/dist/vendor/helpers/beta/standard-schema.cjs +57 -0
- package/dist/vendor/helpers/beta/zod.cjs +88 -0
- package/dist/vendor/helpers/index.cjs +7 -0
- package/dist/vendor/helpers/json-schema.cjs +36 -0
- package/dist/vendor/helpers/zod.cjs +77 -0
- package/dist/vendor/index.cjs +54 -0
- package/dist/vendor/internal/builtin-types.cjs +3 -0
- package/dist/vendor/internal/constants.cjs +12 -0
- package/dist/vendor/internal/decoders/jsonl.cjs +40 -0
- package/dist/vendor/internal/decoders/line.cjs +109 -0
- package/dist/vendor/internal/detect-platform.cjs +159 -0
- package/dist/vendor/internal/errors.cjs +42 -0
- package/dist/vendor/internal/file-store.cjs +535 -0
- package/dist/vendor/internal/headers.cjs +119 -0
- package/dist/vendor/internal/message-stream-utils.cjs +33 -0
- package/dist/vendor/internal/node.browser.cjs +21 -0
- package/dist/vendor/internal/node.cjs +55 -0
- package/dist/vendor/internal/parse.cjs +65 -0
- package/dist/vendor/internal/qs/formats.cjs +12 -0
- package/dist/vendor/internal/qs/index.cjs +13 -0
- package/dist/vendor/internal/qs/stringify.cjs +276 -0
- package/dist/vendor/internal/qs/types.cjs +2 -0
- package/dist/vendor/internal/qs/utils.cjs +229 -0
- package/dist/vendor/internal/request-options.cjs +31 -0
- package/dist/vendor/internal/request-signal.cjs +49 -0
- package/dist/vendor/internal/shim-types.cjs +3 -0
- package/dist/vendor/internal/shims.cjs +91 -0
- package/dist/vendor/internal/stainless-helper-header.cjs +90 -0
- package/dist/vendor/internal/stream-utils.cjs +37 -0
- package/dist/vendor/internal/to-file.cjs +95 -0
- package/dist/vendor/internal/types.cjs +3 -0
- package/dist/vendor/internal/uploads.cjs +148 -0
- package/dist/vendor/internal/utils/abort.cjs +24 -0
- package/dist/vendor/internal/utils/async-queue.cjs +69 -0
- package/dist/vendor/internal/utils/backoff.cjs +43 -0
- package/dist/vendor/internal/utils/base64.cjs +37 -0
- package/dist/vendor/internal/utils/bytes.cjs +30 -0
- package/dist/vendor/internal/utils/env.cjs +21 -0
- package/dist/vendor/internal/utils/log.cjs +111 -0
- package/dist/vendor/internal/utils/path.cjs +78 -0
- package/dist/vendor/internal/utils/promise.cjs +17 -0
- package/dist/vendor/internal/utils/query.cjs +41 -0
- package/dist/vendor/internal/utils/sleep.cjs +27 -0
- package/dist/vendor/internal/utils/time.cjs +7 -0
- package/dist/vendor/internal/utils/uuid.cjs +18 -0
- package/dist/vendor/internal/utils/values.cjs +125 -0
- package/dist/vendor/internal/utils.cjs +24 -0
- package/dist/vendor/lib/BetaMessageStream.cjs +665 -0
- package/dist/vendor/lib/MessageStream.cjs +612 -0
- package/dist/vendor/lib/beta-parser.cjs +78 -0
- package/dist/vendor/lib/credentials/credential-chain.cjs +244 -0
- package/dist/vendor/lib/credentials/identity-token.cjs +71 -0
- package/dist/vendor/lib/credentials/oidc-federation.cjs +81 -0
- package/dist/vendor/lib/credentials/token-cache.cjs +113 -0
- package/dist/vendor/lib/credentials/types.cjs +267 -0
- package/dist/vendor/lib/credentials/user-oauth.cjs +129 -0
- package/dist/vendor/lib/credentials.cjs +7 -0
- package/dist/vendor/lib/environments/index.cjs +17 -0
- package/dist/vendor/lib/environments/poller.cjs +226 -0
- package/dist/vendor/lib/environments/worker.cjs +609 -0
- package/dist/vendor/lib/helper-client.cjs +57 -0
- package/dist/vendor/lib/middleware.cjs +779 -0
- package/dist/vendor/lib/parser.cjs +65 -0
- package/dist/vendor/lib/sessions/accumulate.cjs +44 -0
- package/dist/vendor/lib/standard-schema.cjs +44 -0
- package/dist/vendor/lib/tools/BetaRunnableTool.cjs +30 -0
- package/dist/vendor/lib/tools/BetaToolRunner.cjs +500 -0
- package/dist/vendor/lib/tools/CompactionControl.cjs +27 -0
- package/dist/vendor/lib/tools/SessionToolRunner.cjs +740 -0
- package/dist/vendor/lib/tools/ToolError.cjs +46 -0
- package/dist/vendor/lib/transform-json-schema.cjs +113 -0
- package/dist/vendor/pagination.cjs +18 -0
- package/dist/vendor/resource.cjs +18 -0
- package/dist/vendor/resources/beta/agents/agents.cjs +159 -0
- package/dist/vendor/resources/beta/agents/index.cjs +8 -0
- package/dist/vendor/resources/beta/agents/versions.cjs +35 -0
- package/dist/vendor/resources/beta/agents.cjs +18 -0
- package/dist/vendor/resources/beta/beta.cjs +105 -0
- package/dist/vendor/resources/beta/deployment-runs.cjs +54 -0
- package/dist/vendor/resources/beta/deployments.cjs +195 -0
- package/dist/vendor/resources/beta/dreams.cjs +115 -0
- package/dist/vendor/resources/beta/environments/environments.cjs +178 -0
- package/dist/vendor/resources/beta/environments/index.cjs +8 -0
- package/dist/vendor/resources/beta/environments/work.cjs +256 -0
- package/dist/vendor/resources/beta/environments.cjs +18 -0
- package/dist/vendor/resources/beta/files.cjs +123 -0
- package/dist/vendor/resources/beta/index.cjs +38 -0
- package/dist/vendor/resources/beta/memory-stores/index.cjs +10 -0
- package/dist/vendor/resources/beta/memory-stores/memories.cjs +129 -0
- package/dist/vendor/resources/beta/memory-stores/memory-stores.cjs +173 -0
- package/dist/vendor/resources/beta/memory-stores/memory-versions.cjs +80 -0
- package/dist/vendor/resources/beta/memory-stores.cjs +18 -0
- package/dist/vendor/resources/beta/messages/batches.cjs +206 -0
- package/dist/vendor/resources/beta/messages/index.cjs +11 -0
- package/dist/vendor/resources/beta/messages/messages.cjs +189 -0
- package/dist/vendor/resources/beta/messages.cjs +18 -0
- package/dist/vendor/resources/beta/models.cjs +59 -0
- package/dist/vendor/resources/beta/organization/api-keys.cjs +55 -0
- package/dist/vendor/resources/beta/organization/compliance-settings.cjs +51 -0
- package/dist/vendor/resources/beta/organization/external-keys.cjs +118 -0
- package/dist/vendor/resources/beta/organization/federation/federation.cjs +49 -0
- package/dist/vendor/resources/beta/organization/federation/index.cjs +10 -0
- package/dist/vendor/resources/beta/organization/federation/issuers.cjs +168 -0
- package/dist/vendor/resources/beta/organization/federation/rules/index.cjs +8 -0
- package/dist/vendor/resources/beta/organization/federation/rules/rules.cjs +226 -0
- package/dist/vendor/resources/beta/organization/federation/rules/workspaces.cjs +113 -0
- package/dist/vendor/resources/beta/organization/federation/rules.cjs +18 -0
- package/dist/vendor/resources/beta/organization/federation.cjs +18 -0
- package/dist/vendor/resources/beta/organization/index.cjs +24 -0
- package/dist/vendor/resources/beta/organization/invites.cjs +75 -0
- package/dist/vendor/resources/beta/organization/organization.cjs +90 -0
- package/dist/vendor/resources/beta/organization/rate-limits.cjs +30 -0
- package/dist/vendor/resources/beta/organization/service-accounts/index.cjs +8 -0
- package/dist/vendor/resources/beta/organization/service-accounts/service-accounts.cjs +202 -0
- package/dist/vendor/resources/beta/organization/service-accounts/workspaces.cjs +124 -0
- package/dist/vendor/resources/beta/organization/service-accounts.cjs +18 -0
- package/dist/vendor/resources/beta/organization/users.cjs +66 -0
- package/dist/vendor/resources/beta/organization/workspaces/index.cjs +12 -0
- package/dist/vendor/resources/beta/organization/workspaces/members.cjs +101 -0
- package/dist/vendor/resources/beta/organization/workspaces/rate-limits.cjs +33 -0
- package/dist/vendor/resources/beta/organization/workspaces/service-accounts.cjs +188 -0
- package/dist/vendor/resources/beta/organization/workspaces/workspaces.cjs +140 -0
- package/dist/vendor/resources/beta/organization/workspaces.cjs +18 -0
- package/dist/vendor/resources/beta/organization.cjs +18 -0
- package/dist/vendor/resources/beta/sessions/events.cjs +119 -0
- package/dist/vendor/resources/beta/sessions/index.cjs +12 -0
- package/dist/vendor/resources/beta/sessions/resources.cjs +131 -0
- package/dist/vendor/resources/beta/sessions/sessions.cjs +186 -0
- package/dist/vendor/resources/beta/sessions/threads/events.cjs +60 -0
- package/dist/vendor/resources/beta/sessions/threads/index.cjs +8 -0
- package/dist/vendor/resources/beta/sessions/threads/threads.cjs +116 -0
- package/dist/vendor/resources/beta/sessions/threads.cjs +18 -0
- package/dist/vendor/resources/beta/sessions.cjs +18 -0
- package/dist/vendor/resources/beta/skills/index.cjs +8 -0
- package/dist/vendor/resources/beta/skills/skills.cjs +132 -0
- package/dist/vendor/resources/beta/skills/versions.cjs +128 -0
- package/dist/vendor/resources/beta/skills.cjs +18 -0
- package/dist/vendor/resources/beta/tunnels/certificates.cjs +128 -0
- package/dist/vendor/resources/beta/tunnels/index.cjs +8 -0
- package/dist/vendor/resources/beta/tunnels/tunnels.cjs +209 -0
- package/dist/vendor/resources/beta/tunnels.cjs +18 -0
- package/dist/vendor/resources/beta/user-profiles.cjs +117 -0
- package/dist/vendor/resources/beta/vaults/credentials.cjs +176 -0
- package/dist/vendor/resources/beta/vaults/index.cjs +8 -0
- package/dist/vendor/resources/beta/vaults/vaults.cjs +177 -0
- package/dist/vendor/resources/beta/vaults.cjs +18 -0
- package/dist/vendor/resources/beta/webhooks.cjs +32 -0
- package/dist/vendor/resources/beta.cjs +18 -0
- package/dist/vendor/resources/completions.cjs +22 -0
- package/dist/vendor/resources/files.cjs +51 -0
- package/dist/vendor/resources/index.cjs +31 -0
- package/dist/vendor/resources/messages/batches.cjs +160 -0
- package/dist/vendor/resources/messages/index.cjs +8 -0
- package/dist/vendor/resources/messages/messages.cjs +159 -0
- package/dist/vendor/resources/messages.cjs +18 -0
- package/dist/vendor/resources/models.cjs +44 -0
- package/dist/vendor/resources/shared.cjs +3 -0
- package/dist/vendor/resources/skills/index.cjs +8 -0
- package/dist/vendor/resources/skills/skills.cjs +72 -0
- package/dist/vendor/resources/skills/versions.cjs +40 -0
- package/dist/vendor/resources/skills.cjs +18 -0
- package/dist/vendor/resources/top-level.cjs +3 -0
- package/dist/vendor/resources.cjs +17 -0
- package/dist/vendor/streaming.cjs +18 -0
- package/dist/vendor/tools/agent-toolset/fs-util.cjs +193 -0
- package/dist/vendor/tools/agent-toolset/memories.cjs +916 -0
- package/dist/vendor/tools/agent-toolset/node.browser.cjs +147 -0
- package/dist/vendor/tools/agent-toolset/node.cjs +939 -0
- package/dist/vendor/tools/agent-toolset/skills.cjs +325 -0
- package/dist/vendor/tools/agent-toolset/sync-interval.cjs +28 -0
- package/dist/vendor/tools/memory/node.browser.cjs +48 -0
- package/dist/vendor/tools/memory/node.cjs +364 -0
- package/dist/vendor/uploads.cjs +18 -0
- package/dist/vendor/version.cjs +4 -0
- package/package.json +12 -13
- package/sdk.cjs +0 -14271
- package/sdk.cjs.map +0 -149
- package/sdk.d.ts +0 -10866
- package/sdk.mjs +0 -68
- package/sdk.mjs.map +0 -149
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MessageStream = void 0;
|
|
4
|
+
const stainless_helper_header_1 = require("../internal/stainless-helper-header");
|
|
5
|
+
const errors_1 = require("../internal/errors");
|
|
6
|
+
const values_1 = require("../internal/utils/values");
|
|
7
|
+
const error_1 = require("../error");
|
|
8
|
+
const streaming_1 = require("../streaming");
|
|
9
|
+
const parser_1 = require("./parser");
|
|
10
|
+
const message_stream_utils_1 = require("../internal/message-stream-utils");
|
|
11
|
+
function tracksToolInput(content) {
|
|
12
|
+
return content.type === 'tool_use' || content.type === 'server_tool_use';
|
|
13
|
+
}
|
|
14
|
+
class MessageStream {
|
|
15
|
+
messages = [];
|
|
16
|
+
receivedMessages = [];
|
|
17
|
+
#currentMessageSnapshot;
|
|
18
|
+
#params = null;
|
|
19
|
+
controller = new AbortController();
|
|
20
|
+
#connectedPromise;
|
|
21
|
+
#resolveConnectedPromise = () => { };
|
|
22
|
+
#rejectConnectedPromise = () => { };
|
|
23
|
+
#endPromise;
|
|
24
|
+
#resolveEndPromise = () => { };
|
|
25
|
+
#rejectEndPromise = () => { };
|
|
26
|
+
#listeners = {};
|
|
27
|
+
#ended = false;
|
|
28
|
+
#errored = false;
|
|
29
|
+
#aborted = false;
|
|
30
|
+
#catchingPromiseCreated = false;
|
|
31
|
+
#response;
|
|
32
|
+
#request_id;
|
|
33
|
+
#workspace_id;
|
|
34
|
+
#logger;
|
|
35
|
+
constructor(params, opts) {
|
|
36
|
+
this.#connectedPromise = new Promise((resolve, reject) => {
|
|
37
|
+
this.#resolveConnectedPromise = resolve;
|
|
38
|
+
this.#rejectConnectedPromise = reject;
|
|
39
|
+
});
|
|
40
|
+
this.#endPromise = new Promise((resolve, reject) => {
|
|
41
|
+
this.#resolveEndPromise = resolve;
|
|
42
|
+
this.#rejectEndPromise = reject;
|
|
43
|
+
});
|
|
44
|
+
// Don't let these promises cause unhandled rejection errors.
|
|
45
|
+
// we will manually cause an unhandled rejection error later
|
|
46
|
+
// if the user hasn't registered any error listener or called
|
|
47
|
+
// any promise-returning method.
|
|
48
|
+
this.#connectedPromise.catch(() => { });
|
|
49
|
+
this.#endPromise.catch(() => { });
|
|
50
|
+
this.#params = params;
|
|
51
|
+
this.#logger = opts?.logger ?? console;
|
|
52
|
+
}
|
|
53
|
+
get response() {
|
|
54
|
+
return this.#response;
|
|
55
|
+
}
|
|
56
|
+
get request_id() {
|
|
57
|
+
return this.#request_id;
|
|
58
|
+
}
|
|
59
|
+
get workspace_id() {
|
|
60
|
+
return this.#workspace_id;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Returns the `MessageStream` data, the raw `Response` instance and the ID of the request,
|
|
64
|
+
* returned vie the `request-id` header which is useful for debugging requests and resporting
|
|
65
|
+
* issues to PukuAI.
|
|
66
|
+
*
|
|
67
|
+
* This is the same as the `APIPromise.withResponse()` method.
|
|
68
|
+
*
|
|
69
|
+
* This method will raise an error if you created the stream using `MessageStream.fromReadableStream`
|
|
70
|
+
* as no `Response` is available.
|
|
71
|
+
*/
|
|
72
|
+
async withResponse() {
|
|
73
|
+
this.#catchingPromiseCreated = true;
|
|
74
|
+
const response = await this.#connectedPromise;
|
|
75
|
+
if (!response) {
|
|
76
|
+
throw new Error('Could not resolve a `Response` object');
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
data: this,
|
|
80
|
+
response,
|
|
81
|
+
request_id: response.headers.get('request-id'),
|
|
82
|
+
workspace_id: response.headers.get('puku-workspace-id'),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Intended for use on the frontend, consuming a stream produced with
|
|
87
|
+
* `.toReadableStream()` on the backend.
|
|
88
|
+
*
|
|
89
|
+
* Note that messages sent to the model do not appear in `.on('message')`
|
|
90
|
+
* in this context.
|
|
91
|
+
*/
|
|
92
|
+
static fromReadableStream(stream) {
|
|
93
|
+
const runner = new MessageStream(null);
|
|
94
|
+
runner._run(() => runner._fromReadableStream(stream));
|
|
95
|
+
return runner;
|
|
96
|
+
}
|
|
97
|
+
static createMessage(messages, params, options, { logger } = {}) {
|
|
98
|
+
const runner = new MessageStream(params, { logger });
|
|
99
|
+
for (const message of params.messages) {
|
|
100
|
+
runner._addMessageParam(message);
|
|
101
|
+
}
|
|
102
|
+
runner.#params = { ...params, stream: true };
|
|
103
|
+
runner._run(() => runner._createMessage(messages, { ...params, stream: true }, { ...options, headers: { ...options?.headers, [stainless_helper_header_1.STAINLESS_HELPER_METHOD_HEADER]: 'stream' } }));
|
|
104
|
+
return runner;
|
|
105
|
+
}
|
|
106
|
+
_run(executor) {
|
|
107
|
+
executor().then(() => {
|
|
108
|
+
this._emitFinal();
|
|
109
|
+
this._emit('end');
|
|
110
|
+
}, this.#handleError);
|
|
111
|
+
}
|
|
112
|
+
_addMessageParam(message) {
|
|
113
|
+
this.messages.push(message);
|
|
114
|
+
}
|
|
115
|
+
_addMessage(message, emit = true) {
|
|
116
|
+
this.receivedMessages.push(message);
|
|
117
|
+
if (emit) {
|
|
118
|
+
this._emit('message', message);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async _createMessage(messages, params, options) {
|
|
122
|
+
const signal = options?.signal;
|
|
123
|
+
let abortHandler;
|
|
124
|
+
if (signal) {
|
|
125
|
+
if (signal.aborted)
|
|
126
|
+
this.controller.abort();
|
|
127
|
+
abortHandler = this.controller.abort.bind(this.controller);
|
|
128
|
+
signal.addEventListener('abort', abortHandler);
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
this.#beginRequest();
|
|
132
|
+
const { response, data: stream } = await messages
|
|
133
|
+
.create({ ...params, stream: true }, { ...options, signal: this.controller.signal })
|
|
134
|
+
.withResponse();
|
|
135
|
+
this._connected(response);
|
|
136
|
+
for await (const event of stream) {
|
|
137
|
+
this.#addStreamEvent(event);
|
|
138
|
+
}
|
|
139
|
+
if (stream.controller.signal?.aborted) {
|
|
140
|
+
throw new error_1.APIUserAbortError();
|
|
141
|
+
}
|
|
142
|
+
this.#endRequest();
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
if (signal && abortHandler) {
|
|
146
|
+
signal.removeEventListener('abort', abortHandler);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
_connected(response) {
|
|
151
|
+
if (this.ended)
|
|
152
|
+
return;
|
|
153
|
+
this.#response = response;
|
|
154
|
+
this.#request_id = response?.headers.get('request-id');
|
|
155
|
+
this.#workspace_id = response?.headers.get('puku-workspace-id');
|
|
156
|
+
this.#resolveConnectedPromise(response);
|
|
157
|
+
this._emit('connect');
|
|
158
|
+
}
|
|
159
|
+
get ended() {
|
|
160
|
+
return this.#ended;
|
|
161
|
+
}
|
|
162
|
+
get errored() {
|
|
163
|
+
return this.#errored;
|
|
164
|
+
}
|
|
165
|
+
get aborted() {
|
|
166
|
+
return this.#aborted;
|
|
167
|
+
}
|
|
168
|
+
abort() {
|
|
169
|
+
this.controller.abort();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Adds the listener function to the end of the listeners array for the event.
|
|
173
|
+
* No checks are made to see if the listener has already been added. Multiple calls passing
|
|
174
|
+
* the same combination of event and listener will result in the listener being added, and
|
|
175
|
+
* called, multiple times.
|
|
176
|
+
* @returns this MessageStream, so that calls can be chained
|
|
177
|
+
*/
|
|
178
|
+
on(event, listener) {
|
|
179
|
+
const listeners = this.#listeners[event] || (this.#listeners[event] = []);
|
|
180
|
+
listeners.push({ listener });
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Removes the specified listener from the listener array for the event.
|
|
185
|
+
* off() will remove, at most, one instance of a listener from the listener array. If any single
|
|
186
|
+
* listener has been added multiple times to the listener array for the specified event, then
|
|
187
|
+
* off() must be called multiple times to remove each instance.
|
|
188
|
+
* @returns this MessageStream, so that calls can be chained
|
|
189
|
+
*/
|
|
190
|
+
off(event, listener) {
|
|
191
|
+
const listeners = this.#listeners[event];
|
|
192
|
+
if (!listeners)
|
|
193
|
+
return this;
|
|
194
|
+
const index = listeners.findIndex((l) => l.listener === listener);
|
|
195
|
+
if (index >= 0)
|
|
196
|
+
listeners.splice(index, 1);
|
|
197
|
+
return this;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Adds a one-time listener function for the event. The next time the event is triggered,
|
|
201
|
+
* this listener is removed and then invoked.
|
|
202
|
+
* @returns this MessageStream, so that calls can be chained
|
|
203
|
+
*/
|
|
204
|
+
once(event, listener) {
|
|
205
|
+
const listeners = this.#listeners[event] || (this.#listeners[event] = []);
|
|
206
|
+
listeners.push({ listener, once: true });
|
|
207
|
+
return this;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* This is similar to `.once()`, but returns a Promise that resolves the next time
|
|
211
|
+
* the event is triggered, instead of calling a listener callback.
|
|
212
|
+
* @returns a Promise that resolves the next time given event is triggered,
|
|
213
|
+
* or rejects if an error is emitted. (If you request the 'error' event,
|
|
214
|
+
* returns a promise that resolves with the error).
|
|
215
|
+
*
|
|
216
|
+
* Example:
|
|
217
|
+
*
|
|
218
|
+
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
219
|
+
*/
|
|
220
|
+
emitted(event) {
|
|
221
|
+
return new Promise((resolve, reject) => {
|
|
222
|
+
this.#catchingPromiseCreated = true;
|
|
223
|
+
if (event !== 'error')
|
|
224
|
+
this.once('error', reject);
|
|
225
|
+
this.once(event, resolve);
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
async done() {
|
|
229
|
+
this.#catchingPromiseCreated = true;
|
|
230
|
+
await this.#endPromise;
|
|
231
|
+
}
|
|
232
|
+
get currentMessage() {
|
|
233
|
+
return this.#currentMessageSnapshot;
|
|
234
|
+
}
|
|
235
|
+
#getFinalMessage() {
|
|
236
|
+
if (this.receivedMessages.length === 0) {
|
|
237
|
+
throw new error_1.PukuError('stream ended without producing a Message with role=assistant');
|
|
238
|
+
}
|
|
239
|
+
return this.receivedMessages.at(-1);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* @returns a promise that resolves with the the final assistant Message response,
|
|
243
|
+
* or rejects if an error occurred or the stream ended prematurely without producing a Message.
|
|
244
|
+
* If structured outputs were used, this will be a ParsedMessage with a `parsed_output` field.
|
|
245
|
+
*/
|
|
246
|
+
async finalMessage() {
|
|
247
|
+
await this.done();
|
|
248
|
+
return this.#getFinalMessage();
|
|
249
|
+
}
|
|
250
|
+
#getFinalText() {
|
|
251
|
+
if (this.receivedMessages.length === 0) {
|
|
252
|
+
throw new error_1.PukuError('stream ended without producing a Message with role=assistant');
|
|
253
|
+
}
|
|
254
|
+
const textBlocks = this.receivedMessages
|
|
255
|
+
.at(-1)
|
|
256
|
+
.content.filter((block) => block.type === 'text')
|
|
257
|
+
.map((block) => block.text);
|
|
258
|
+
if (textBlocks.length === 0) {
|
|
259
|
+
throw new error_1.PukuError('stream ended without producing a content block with type=text');
|
|
260
|
+
}
|
|
261
|
+
return textBlocks.join(' ');
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* @returns a promise that resolves with the the final assistant Message's text response, concatenated
|
|
265
|
+
* together if there are more than one text blocks.
|
|
266
|
+
* Rejects if an error occurred or the stream ended prematurely without producing a Message.
|
|
267
|
+
*/
|
|
268
|
+
async finalText() {
|
|
269
|
+
await this.done();
|
|
270
|
+
return this.#getFinalText();
|
|
271
|
+
}
|
|
272
|
+
#handleError = (error) => {
|
|
273
|
+
this.#errored = true;
|
|
274
|
+
if ((0, errors_1.isAbortError)(error)) {
|
|
275
|
+
error = new error_1.APIUserAbortError();
|
|
276
|
+
}
|
|
277
|
+
if (error instanceof error_1.APIUserAbortError) {
|
|
278
|
+
this.#aborted = true;
|
|
279
|
+
return this._emit('abort', error);
|
|
280
|
+
}
|
|
281
|
+
if (error instanceof error_1.PukuError) {
|
|
282
|
+
return this._emit('error', error);
|
|
283
|
+
}
|
|
284
|
+
if (error instanceof Error) {
|
|
285
|
+
const pukuError = new error_1.PukuError(error.message);
|
|
286
|
+
// @ts-ignore
|
|
287
|
+
pukuError.cause = error;
|
|
288
|
+
return this._emit('error', pukuError);
|
|
289
|
+
}
|
|
290
|
+
return this._emit('error', new error_1.PukuError(String(error)));
|
|
291
|
+
};
|
|
292
|
+
_emit(event, ...args) {
|
|
293
|
+
// make sure we don't emit any MessageStreamEvents after end
|
|
294
|
+
if (this.#ended)
|
|
295
|
+
return;
|
|
296
|
+
if (event === 'end') {
|
|
297
|
+
this.#ended = true;
|
|
298
|
+
this.#resolveEndPromise();
|
|
299
|
+
}
|
|
300
|
+
const listeners = this.#listeners[event];
|
|
301
|
+
if (listeners) {
|
|
302
|
+
this.#listeners[event] = listeners.filter((l) => !l.once);
|
|
303
|
+
listeners.forEach(({ listener }) => listener(...args));
|
|
304
|
+
}
|
|
305
|
+
if (event === 'abort') {
|
|
306
|
+
const error = args[0];
|
|
307
|
+
if (!this.#catchingPromiseCreated && !listeners?.length) {
|
|
308
|
+
Promise.reject(error);
|
|
309
|
+
}
|
|
310
|
+
this.#rejectConnectedPromise(error);
|
|
311
|
+
this.#rejectEndPromise(error);
|
|
312
|
+
this._emit('end');
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
if (event === 'error') {
|
|
316
|
+
// NOTE: _emit('error', error) should only be called from #handleError().
|
|
317
|
+
const error = args[0];
|
|
318
|
+
if (!this.#catchingPromiseCreated && !listeners?.length) {
|
|
319
|
+
// Trigger an unhandled rejection if the user hasn't registered any error handlers.
|
|
320
|
+
// If you are seeing stack traces here, make sure to handle errors via either:
|
|
321
|
+
// - runner.on('error', () => ...)
|
|
322
|
+
// - await runner.done()
|
|
323
|
+
// - await runner.final...()
|
|
324
|
+
// - etc.
|
|
325
|
+
Promise.reject(error);
|
|
326
|
+
}
|
|
327
|
+
this.#rejectConnectedPromise(error);
|
|
328
|
+
this.#rejectEndPromise(error);
|
|
329
|
+
this._emit('end');
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
_emitFinal() {
|
|
333
|
+
const finalMessage = this.receivedMessages.at(-1);
|
|
334
|
+
if (finalMessage) {
|
|
335
|
+
this._emit('finalMessage', this.#getFinalMessage());
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
#beginRequest() {
|
|
339
|
+
if (this.ended)
|
|
340
|
+
return;
|
|
341
|
+
this.#currentMessageSnapshot = undefined;
|
|
342
|
+
}
|
|
343
|
+
#addStreamEvent(event) {
|
|
344
|
+
if (this.ended)
|
|
345
|
+
return;
|
|
346
|
+
const messageSnapshot = this.#accumulateMessage(event);
|
|
347
|
+
this._emit('streamEvent', event, messageSnapshot);
|
|
348
|
+
switch (event.type) {
|
|
349
|
+
case 'content_block_delta': {
|
|
350
|
+
const content = messageSnapshot.content.at(-1);
|
|
351
|
+
switch (event.delta.type) {
|
|
352
|
+
case 'text_delta': {
|
|
353
|
+
if (content.type === 'text') {
|
|
354
|
+
this._emit('text', event.delta.text, content.text || '');
|
|
355
|
+
}
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
case 'citations_delta': {
|
|
359
|
+
if (content.type === 'text') {
|
|
360
|
+
this._emit('citation', event.delta.citation, content.citations ?? []);
|
|
361
|
+
}
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
case 'input_json_delta': {
|
|
365
|
+
if (tracksToolInput(content) && this.#listeners.inputJson?.length) {
|
|
366
|
+
this._emit('inputJson', event.delta.partial_json, content.input);
|
|
367
|
+
}
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
case 'thinking_delta': {
|
|
371
|
+
if (content.type === 'thinking') {
|
|
372
|
+
this._emit('thinking', event.delta.thinking, content.thinking);
|
|
373
|
+
}
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
case 'signature_delta': {
|
|
377
|
+
if (content.type === 'thinking') {
|
|
378
|
+
this._emit('signature', content.signature);
|
|
379
|
+
}
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
default:
|
|
383
|
+
(0, values_1.checkNever)(event.delta);
|
|
384
|
+
}
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
case 'message_stop': {
|
|
388
|
+
this._addMessageParam(messageSnapshot);
|
|
389
|
+
this._addMessage((0, parser_1.maybeParseMessage)(messageSnapshot, this.#params, { logger: this.#logger }), true);
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
case 'content_block_stop': {
|
|
393
|
+
this._emit('contentBlock', messageSnapshot.content.at(-1));
|
|
394
|
+
break;
|
|
395
|
+
}
|
|
396
|
+
case 'message_start': {
|
|
397
|
+
this.#currentMessageSnapshot = messageSnapshot;
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
case 'content_block_start':
|
|
401
|
+
case 'message_delta':
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
#endRequest() {
|
|
406
|
+
if (this.ended) {
|
|
407
|
+
throw new error_1.PukuError(`stream has ended, this shouldn't happen`);
|
|
408
|
+
}
|
|
409
|
+
const snapshot = this.#currentMessageSnapshot;
|
|
410
|
+
if (!snapshot) {
|
|
411
|
+
throw new error_1.PukuError(`request ended without sending any chunks`);
|
|
412
|
+
}
|
|
413
|
+
this.#currentMessageSnapshot = undefined;
|
|
414
|
+
return (0, parser_1.maybeParseMessage)(snapshot, this.#params, { logger: this.#logger });
|
|
415
|
+
}
|
|
416
|
+
async _fromReadableStream(readableStream, options) {
|
|
417
|
+
const signal = options?.signal;
|
|
418
|
+
let abortHandler;
|
|
419
|
+
if (signal) {
|
|
420
|
+
if (signal.aborted)
|
|
421
|
+
this.controller.abort();
|
|
422
|
+
abortHandler = this.controller.abort.bind(this.controller);
|
|
423
|
+
signal.addEventListener('abort', abortHandler);
|
|
424
|
+
}
|
|
425
|
+
try {
|
|
426
|
+
this.#beginRequest();
|
|
427
|
+
this._connected(null);
|
|
428
|
+
const stream = streaming_1.Stream.fromReadableStream(readableStream, this.controller);
|
|
429
|
+
for await (const event of stream) {
|
|
430
|
+
this.#addStreamEvent(event);
|
|
431
|
+
}
|
|
432
|
+
if (stream.controller.signal?.aborted) {
|
|
433
|
+
throw new error_1.APIUserAbortError();
|
|
434
|
+
}
|
|
435
|
+
this.#endRequest();
|
|
436
|
+
}
|
|
437
|
+
finally {
|
|
438
|
+
if (signal && abortHandler) {
|
|
439
|
+
signal.removeEventListener('abort', abortHandler);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Mutates this.#currentMessage with the current event. Handling the accumulation of multiple messages
|
|
445
|
+
* will be needed to be handled by the caller, this method will throw if you try to accumulate for multiple
|
|
446
|
+
* messages.
|
|
447
|
+
*/
|
|
448
|
+
#accumulateMessage(event) {
|
|
449
|
+
let snapshot = this.#currentMessageSnapshot;
|
|
450
|
+
if (event.type === 'message_start') {
|
|
451
|
+
if (snapshot) {
|
|
452
|
+
throw new error_1.PukuError(`Unexpected event order, got ${event.type} before receiving "message_stop"`);
|
|
453
|
+
}
|
|
454
|
+
return event.message;
|
|
455
|
+
}
|
|
456
|
+
if (!snapshot) {
|
|
457
|
+
throw new error_1.PukuError(`Unexpected event order, got ${event.type} before "message_start"`);
|
|
458
|
+
}
|
|
459
|
+
switch (event.type) {
|
|
460
|
+
case 'message_stop':
|
|
461
|
+
return snapshot;
|
|
462
|
+
case 'message_delta':
|
|
463
|
+
snapshot.stop_reason = event.delta.stop_reason;
|
|
464
|
+
snapshot.stop_sequence = event.delta.stop_sequence;
|
|
465
|
+
snapshot.stop_details = event.delta.stop_details;
|
|
466
|
+
snapshot.usage.output_tokens = event.usage.output_tokens;
|
|
467
|
+
if (event.delta.container != null) {
|
|
468
|
+
snapshot.container = event.delta.container;
|
|
469
|
+
}
|
|
470
|
+
// The remaining usage counters are cumulative whole-message totals that are
|
|
471
|
+
// omitted when they don't apply, so overwrite when present and never add.
|
|
472
|
+
if (event.usage.input_tokens != null) {
|
|
473
|
+
snapshot.usage.input_tokens = event.usage.input_tokens;
|
|
474
|
+
}
|
|
475
|
+
if (event.usage.cache_creation_input_tokens != null) {
|
|
476
|
+
snapshot.usage.cache_creation_input_tokens = event.usage.cache_creation_input_tokens;
|
|
477
|
+
}
|
|
478
|
+
if (event.usage.cache_read_input_tokens != null) {
|
|
479
|
+
snapshot.usage.cache_read_input_tokens = event.usage.cache_read_input_tokens;
|
|
480
|
+
}
|
|
481
|
+
if (event.usage.server_tool_use != null) {
|
|
482
|
+
snapshot.usage.server_tool_use = event.usage.server_tool_use;
|
|
483
|
+
}
|
|
484
|
+
if (event.usage.output_tokens_details != null) {
|
|
485
|
+
snapshot.usage.output_tokens_details = event.usage.output_tokens_details;
|
|
486
|
+
}
|
|
487
|
+
return snapshot;
|
|
488
|
+
case 'content_block_start':
|
|
489
|
+
snapshot.content.push({ ...event.content_block });
|
|
490
|
+
return snapshot;
|
|
491
|
+
case 'content_block_delta': {
|
|
492
|
+
const snapshotContent = snapshot.content.at(event.index);
|
|
493
|
+
switch (event.delta.type) {
|
|
494
|
+
case 'text_delta': {
|
|
495
|
+
if (snapshotContent?.type === 'text') {
|
|
496
|
+
snapshot.content[event.index] = {
|
|
497
|
+
...snapshotContent,
|
|
498
|
+
text: (snapshotContent.text || '') + event.delta.text,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
503
|
+
case 'citations_delta': {
|
|
504
|
+
if (snapshotContent?.type === 'text') {
|
|
505
|
+
snapshot.content[event.index] = {
|
|
506
|
+
...snapshotContent,
|
|
507
|
+
citations: [...(snapshotContent.citations ?? []), event.delta.citation],
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
break;
|
|
511
|
+
}
|
|
512
|
+
case 'input_json_delta': {
|
|
513
|
+
if (snapshotContent && tracksToolInput(snapshotContent)) {
|
|
514
|
+
const jsonBuf = (snapshotContent[message_stream_utils_1.JSON_BUF_PROPERTY] || '') + event.delta.partial_json;
|
|
515
|
+
snapshot.content[event.index] = (0, message_stream_utils_1.withLazyInput)(snapshotContent, jsonBuf);
|
|
516
|
+
}
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
case 'thinking_delta': {
|
|
520
|
+
if (snapshotContent?.type === 'thinking') {
|
|
521
|
+
snapshot.content[event.index] = {
|
|
522
|
+
...snapshotContent,
|
|
523
|
+
thinking: snapshotContent.thinking + event.delta.thinking,
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
break;
|
|
527
|
+
}
|
|
528
|
+
case 'signature_delta': {
|
|
529
|
+
if (snapshotContent?.type === 'thinking') {
|
|
530
|
+
snapshot.content[event.index] = {
|
|
531
|
+
...snapshotContent,
|
|
532
|
+
signature: event.delta.signature,
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
default:
|
|
538
|
+
(0, values_1.checkNever)(event.delta);
|
|
539
|
+
}
|
|
540
|
+
return snapshot;
|
|
541
|
+
}
|
|
542
|
+
case 'content_block_stop': {
|
|
543
|
+
const snapshotContent = snapshot.content.at(event.index);
|
|
544
|
+
if (snapshotContent && tracksToolInput(snapshotContent) && message_stream_utils_1.JSON_BUF_PROPERTY in snapshotContent) {
|
|
545
|
+
Object.defineProperty(snapshotContent, 'input', {
|
|
546
|
+
value: snapshotContent.input,
|
|
547
|
+
enumerable: true,
|
|
548
|
+
configurable: true,
|
|
549
|
+
writable: true,
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
return snapshot;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
[Symbol.asyncIterator]() {
|
|
557
|
+
const pushQueue = [];
|
|
558
|
+
const readQueue = [];
|
|
559
|
+
let done = false;
|
|
560
|
+
this.on('streamEvent', (event) => {
|
|
561
|
+
const reader = readQueue.shift();
|
|
562
|
+
if (reader) {
|
|
563
|
+
reader.resolve(event);
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
pushQueue.push(event);
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
this.on('end', () => {
|
|
570
|
+
done = true;
|
|
571
|
+
for (const reader of readQueue) {
|
|
572
|
+
reader.resolve(undefined);
|
|
573
|
+
}
|
|
574
|
+
readQueue.length = 0;
|
|
575
|
+
});
|
|
576
|
+
this.on('abort', (err) => {
|
|
577
|
+
done = true;
|
|
578
|
+
for (const reader of readQueue) {
|
|
579
|
+
reader.reject(err);
|
|
580
|
+
}
|
|
581
|
+
readQueue.length = 0;
|
|
582
|
+
});
|
|
583
|
+
this.on('error', (err) => {
|
|
584
|
+
done = true;
|
|
585
|
+
for (const reader of readQueue) {
|
|
586
|
+
reader.reject(err);
|
|
587
|
+
}
|
|
588
|
+
readQueue.length = 0;
|
|
589
|
+
});
|
|
590
|
+
return {
|
|
591
|
+
next: async () => {
|
|
592
|
+
if (!pushQueue.length) {
|
|
593
|
+
if (done) {
|
|
594
|
+
return { value: undefined, done: true };
|
|
595
|
+
}
|
|
596
|
+
return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk) => (chunk ? { value: chunk, done: false } : { value: undefined, done: true }));
|
|
597
|
+
}
|
|
598
|
+
const chunk = pushQueue.shift();
|
|
599
|
+
return { value: chunk, done: false };
|
|
600
|
+
},
|
|
601
|
+
return: async () => {
|
|
602
|
+
this.abort();
|
|
603
|
+
return { value: undefined, done: true };
|
|
604
|
+
},
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
toReadableStream() {
|
|
608
|
+
const stream = new streaming_1.Stream(this[Symbol.asyncIterator].bind(this), this.controller);
|
|
609
|
+
return stream.toReadableStream();
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
exports.MessageStream = MessageStream;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.maybeParseBetaMessage = maybeParseBetaMessage;
|
|
4
|
+
exports.parseBetaMessage = parseBetaMessage;
|
|
5
|
+
const error_1 = require("../core/error");
|
|
6
|
+
function getOutputFormat(params) {
|
|
7
|
+
// Prefer output_format (deprecated) over output_config.format for backward compatibility
|
|
8
|
+
return params?.output_format ?? params?.output_config?.format;
|
|
9
|
+
}
|
|
10
|
+
function maybeParseBetaMessage(message, params, opts) {
|
|
11
|
+
const outputFormat = getOutputFormat(params);
|
|
12
|
+
if (!params || !('parse' in (outputFormat ?? {}))) {
|
|
13
|
+
return {
|
|
14
|
+
...message,
|
|
15
|
+
content: message.content.map((block) => {
|
|
16
|
+
if (block.type === 'text') {
|
|
17
|
+
const parsedBlock = Object.defineProperty({ ...block }, 'parsed_output', {
|
|
18
|
+
value: null,
|
|
19
|
+
enumerable: false,
|
|
20
|
+
});
|
|
21
|
+
return Object.defineProperty(parsedBlock, 'parsed', {
|
|
22
|
+
get() {
|
|
23
|
+
opts.logger.warn('The `parsed` property on `text` blocks is deprecated, please use `parsed_output` instead.');
|
|
24
|
+
return null;
|
|
25
|
+
},
|
|
26
|
+
enumerable: false,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return block;
|
|
30
|
+
}),
|
|
31
|
+
parsed_output: null,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return parseBetaMessage(message, params, opts);
|
|
35
|
+
}
|
|
36
|
+
function parseBetaMessage(message, params, opts) {
|
|
37
|
+
let firstParsedOutput = null;
|
|
38
|
+
const content = message.content.map((block) => {
|
|
39
|
+
if (block.type === 'text') {
|
|
40
|
+
const parsedOutput = parseBetaOutputFormat(params, block.text);
|
|
41
|
+
if (firstParsedOutput === null) {
|
|
42
|
+
firstParsedOutput = parsedOutput;
|
|
43
|
+
}
|
|
44
|
+
const parsedBlock = Object.defineProperty({ ...block }, 'parsed_output', {
|
|
45
|
+
value: parsedOutput,
|
|
46
|
+
enumerable: false,
|
|
47
|
+
});
|
|
48
|
+
return Object.defineProperty(parsedBlock, 'parsed', {
|
|
49
|
+
get() {
|
|
50
|
+
opts.logger.warn('The `parsed` property on `text` blocks is deprecated, please use `parsed_output` instead.');
|
|
51
|
+
return parsedOutput;
|
|
52
|
+
},
|
|
53
|
+
enumerable: false,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return block;
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
...message,
|
|
60
|
+
content,
|
|
61
|
+
parsed_output: firstParsedOutput,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function parseBetaOutputFormat(params, content) {
|
|
65
|
+
const outputFormat = getOutputFormat(params);
|
|
66
|
+
if (outputFormat?.type !== 'json_schema') {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
if ('parse' in outputFormat) {
|
|
71
|
+
return outputFormat.parse(content);
|
|
72
|
+
}
|
|
73
|
+
return JSON.parse(content);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
throw new error_1.PukuError(`Failed to parse structured output: ${error}`);
|
|
77
|
+
}
|
|
78
|
+
}
|