orchestrator-client 5.7.4 → 5.7.12
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/dist/index.cjs +341 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +163 -1
- package/dist/index.d.ts +163 -1
- package/dist/index.js +334 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -171,6 +171,11 @@ var OrchestratorAsync = class {
|
|
|
171
171
|
_makeUrl(path) {
|
|
172
172
|
return `${this._baseUrl}${path}`;
|
|
173
173
|
}
|
|
174
|
+
_makeAbsoluteUrl(path) {
|
|
175
|
+
const raw = this._makeUrl(path);
|
|
176
|
+
const base = typeof globalThis.location !== "undefined" ? globalThis.location.href : void 0;
|
|
177
|
+
return new URL(raw, base);
|
|
178
|
+
}
|
|
174
179
|
async _resolveHeaders() {
|
|
175
180
|
const headers = {};
|
|
176
181
|
if (this._apiKey) {
|
|
@@ -187,7 +192,7 @@ var OrchestratorAsync = class {
|
|
|
187
192
|
return headers;
|
|
188
193
|
}
|
|
189
194
|
async _request(method, path, opts) {
|
|
190
|
-
const url =
|
|
195
|
+
const url = this._makeAbsoluteUrl(path);
|
|
191
196
|
if (opts?.params) {
|
|
192
197
|
for (const [key, value] of Object.entries(opts.params)) {
|
|
193
198
|
if (value !== void 0) {
|
|
@@ -981,7 +986,7 @@ var OrchestratorAsync = class {
|
|
|
981
986
|
// ------------------------------------------------------------------
|
|
982
987
|
async listErrors(params) {
|
|
983
988
|
const authHeaders = await this._resolveHeaders();
|
|
984
|
-
const url =
|
|
989
|
+
const url = this._makeAbsoluteUrl("/errors");
|
|
985
990
|
if (params?.page !== void 0)
|
|
986
991
|
url.searchParams.set("page", String(params.page));
|
|
987
992
|
if (params?.limit !== void 0)
|
|
@@ -1775,6 +1780,11 @@ var RealtimeClient = class {
|
|
|
1775
1780
|
this._socket = null;
|
|
1776
1781
|
this._handlers = /* @__PURE__ */ new Map();
|
|
1777
1782
|
this._connected = false;
|
|
1783
|
+
// Every room joined through any API (subscribeTask, joinRooms, subscribe(),
|
|
1784
|
+
// subscribeEvents, etc.) is tracked here so it can be replayed on reconnect.
|
|
1785
|
+
// Server-side room membership is tied to the socket connection and is lost
|
|
1786
|
+
// on disconnect — the full set must be re-emitted on every reconnect.
|
|
1787
|
+
this._rooms = /* @__PURE__ */ new Set();
|
|
1778
1788
|
// Multi-subscriber room-diffing state (mirrors WebSocketProvider)
|
|
1779
1789
|
this._subscriptions = /* @__PURE__ */ new Map();
|
|
1780
1790
|
this._currentRooms = /* @__PURE__ */ new Set();
|
|
@@ -1811,6 +1821,10 @@ var RealtimeClient = class {
|
|
|
1811
1821
|
this._socket.on("connect", () => {
|
|
1812
1822
|
this._connected = true;
|
|
1813
1823
|
this._currentRooms = /* @__PURE__ */ new Set();
|
|
1824
|
+
if (this._rooms.size > 0) {
|
|
1825
|
+
this._socket?.emit("join", { rooms: [...this._rooms] });
|
|
1826
|
+
this._currentRooms = new Set(this._rooms);
|
|
1827
|
+
}
|
|
1814
1828
|
this._syncRooms();
|
|
1815
1829
|
});
|
|
1816
1830
|
this._socket.on("disconnect", () => {
|
|
@@ -1868,7 +1882,9 @@ var RealtimeClient = class {
|
|
|
1868
1882
|
*/
|
|
1869
1883
|
subscribeTask(taskId) {
|
|
1870
1884
|
if (!this._socket) throw new Error("RealtimeClient not connected");
|
|
1871
|
-
|
|
1885
|
+
const room = `task:${taskId}`;
|
|
1886
|
+
this._socket.emit("join", { rooms: [room] });
|
|
1887
|
+
this._rooms.add(room);
|
|
1872
1888
|
}
|
|
1873
1889
|
/**
|
|
1874
1890
|
* Unsubscribe from realtime events for a specific task.
|
|
@@ -1876,7 +1892,9 @@ var RealtimeClient = class {
|
|
|
1876
1892
|
*/
|
|
1877
1893
|
unsubscribeTask(taskId) {
|
|
1878
1894
|
if (!this._socket) throw new Error("RealtimeClient not connected");
|
|
1879
|
-
|
|
1895
|
+
const room = `task:${taskId}`;
|
|
1896
|
+
this._socket.emit("leave", { rooms: [room] });
|
|
1897
|
+
this._rooms.delete(room);
|
|
1880
1898
|
}
|
|
1881
1899
|
/**
|
|
1882
1900
|
* Subscribe to event-type-scoped rooms.
|
|
@@ -1886,6 +1904,7 @@ var RealtimeClient = class {
|
|
|
1886
1904
|
if (!this._socket) throw new Error("RealtimeClient not connected");
|
|
1887
1905
|
const rooms = eventTypes.map((t) => `event:${t}`);
|
|
1888
1906
|
this._socket.emit("join", { rooms });
|
|
1907
|
+
for (const r of rooms) this._rooms.add(r);
|
|
1889
1908
|
}
|
|
1890
1909
|
/**
|
|
1891
1910
|
* Unsubscribe from event-type-scoped rooms.
|
|
@@ -1894,6 +1913,7 @@ var RealtimeClient = class {
|
|
|
1894
1913
|
if (!this._socket) throw new Error("RealtimeClient not connected");
|
|
1895
1914
|
const rooms = eventTypes.map((t) => `event:${t}`);
|
|
1896
1915
|
this._socket.emit("leave", { rooms });
|
|
1916
|
+
for (const r of rooms) this._rooms.delete(r);
|
|
1897
1917
|
}
|
|
1898
1918
|
/**
|
|
1899
1919
|
* Subscribe to the `all` broadcast room (receives all events).
|
|
@@ -1901,20 +1921,25 @@ var RealtimeClient = class {
|
|
|
1901
1921
|
subscribeAll() {
|
|
1902
1922
|
if (!this._socket) throw new Error("RealtimeClient not connected");
|
|
1903
1923
|
this._socket.emit("join", { rooms: ["all"] });
|
|
1924
|
+
this._rooms.add("all");
|
|
1904
1925
|
}
|
|
1905
1926
|
/**
|
|
1906
1927
|
* Subscribe to a locale-specific room.
|
|
1907
1928
|
*/
|
|
1908
1929
|
subscribeLocale(locale) {
|
|
1909
1930
|
if (!this._socket) throw new Error("RealtimeClient not connected");
|
|
1910
|
-
|
|
1931
|
+
const room = `locale:${locale}`;
|
|
1932
|
+
this._socket.emit("join", { rooms: [room] });
|
|
1933
|
+
this._rooms.add(room);
|
|
1911
1934
|
}
|
|
1912
1935
|
/**
|
|
1913
1936
|
* Unsubscribe from a locale-specific room.
|
|
1914
1937
|
*/
|
|
1915
1938
|
unsubscribeLocale(locale) {
|
|
1916
1939
|
if (!this._socket) throw new Error("RealtimeClient not connected");
|
|
1917
|
-
|
|
1940
|
+
const room = `locale:${locale}`;
|
|
1941
|
+
this._socket.emit("leave", { rooms: [room] });
|
|
1942
|
+
this._rooms.delete(room);
|
|
1918
1943
|
}
|
|
1919
1944
|
/**
|
|
1920
1945
|
* Join arbitrary rooms by name.
|
|
@@ -1922,6 +1947,7 @@ var RealtimeClient = class {
|
|
|
1922
1947
|
joinRooms(rooms) {
|
|
1923
1948
|
if (!this._socket) throw new Error("RealtimeClient not connected");
|
|
1924
1949
|
this._socket.emit("join", { rooms });
|
|
1950
|
+
for (const r of rooms) this._rooms.add(r);
|
|
1925
1951
|
}
|
|
1926
1952
|
/**
|
|
1927
1953
|
* Leave arbitrary rooms by name.
|
|
@@ -1929,6 +1955,7 @@ var RealtimeClient = class {
|
|
|
1929
1955
|
leaveRooms(rooms) {
|
|
1930
1956
|
if (!this._socket) throw new Error("RealtimeClient not connected");
|
|
1931
1957
|
this._socket.emit("leave", { rooms });
|
|
1958
|
+
for (const r of rooms) this._rooms.delete(r);
|
|
1932
1959
|
}
|
|
1933
1960
|
// ------------------------------------------------------------------
|
|
1934
1961
|
// Multi-subscriber API (mirrors WebSocketProvider room-diffing)
|
|
@@ -1986,6 +2013,8 @@ var RealtimeClient = class {
|
|
|
1986
2013
|
const toLeave = [...this._currentRooms].filter((r) => !needed.has(r));
|
|
1987
2014
|
if (toJoin.length) socket.emit("join", { rooms: toJoin });
|
|
1988
2015
|
if (toLeave.length) socket.emit("leave", { rooms: toLeave });
|
|
2016
|
+
for (const r of toJoin) this._rooms.add(r);
|
|
2017
|
+
for (const r of toLeave) this._rooms.delete(r);
|
|
1989
2018
|
this._currentRooms = needed;
|
|
1990
2019
|
}
|
|
1991
2020
|
/**
|
|
@@ -2060,9 +2089,302 @@ var RealtimeClient = class {
|
|
|
2060
2089
|
}
|
|
2061
2090
|
};
|
|
2062
2091
|
|
|
2092
|
+
// src/flow.ts
|
|
2093
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
2094
|
+
"completed",
|
|
2095
|
+
"failed",
|
|
2096
|
+
"cancelled",
|
|
2097
|
+
"translation"
|
|
2098
|
+
]);
|
|
2099
|
+
var DEFAULT_FLOW_TIMEOUT_MS = 6e5;
|
|
2100
|
+
var _defaultClient;
|
|
2101
|
+
var _defaultRealtime;
|
|
2102
|
+
function setupDefaultClient(client, realtime) {
|
|
2103
|
+
_defaultClient = client;
|
|
2104
|
+
_defaultRealtime = realtime;
|
|
2105
|
+
}
|
|
2106
|
+
function getDefaultClient() {
|
|
2107
|
+
if (!_defaultClient) {
|
|
2108
|
+
throw new Error(
|
|
2109
|
+
"No default OrchestratorAsync set. Call setupDefaultClient() during application startup, or pass client to flow.run()."
|
|
2110
|
+
);
|
|
2111
|
+
}
|
|
2112
|
+
return _defaultClient;
|
|
2113
|
+
}
|
|
2114
|
+
function getDefaultRealtime() {
|
|
2115
|
+
return _defaultRealtime;
|
|
2116
|
+
}
|
|
2117
|
+
var FlowError = class extends Error {
|
|
2118
|
+
constructor(message) {
|
|
2119
|
+
super(message);
|
|
2120
|
+
this.name = "FlowError";
|
|
2121
|
+
}
|
|
2122
|
+
};
|
|
2123
|
+
var FlowTimeoutError = class extends FlowError {
|
|
2124
|
+
constructor(message) {
|
|
2125
|
+
super(message);
|
|
2126
|
+
this.name = "FlowTimeoutError";
|
|
2127
|
+
}
|
|
2128
|
+
};
|
|
2129
|
+
var FlowCancelledError = class extends FlowError {
|
|
2130
|
+
constructor(taskId) {
|
|
2131
|
+
super(`Task ${taskId} was cancelled`);
|
|
2132
|
+
this.name = "FlowCancelledError";
|
|
2133
|
+
this.taskId = taskId;
|
|
2134
|
+
}
|
|
2135
|
+
};
|
|
2136
|
+
function extractJsonFromMessage(content) {
|
|
2137
|
+
const cleaned = content.replace(/^\ufeff|\u200b|\u200c|\u200d/, "").trim();
|
|
2138
|
+
if (cleaned.startsWith("{")) {
|
|
2139
|
+
try {
|
|
2140
|
+
return JSON.parse(cleaned);
|
|
2141
|
+
} catch {
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
const start = content.indexOf("{");
|
|
2145
|
+
const end = content.lastIndexOf("}");
|
|
2146
|
+
if (start !== -1 && end !== -1 && end > start) {
|
|
2147
|
+
try {
|
|
2148
|
+
return JSON.parse(content.slice(start, end + 1));
|
|
2149
|
+
} catch {
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
const jsonFenceMatch = content.match(/```(?:json)\s*\n([\s\S]*?)\n```/i);
|
|
2153
|
+
if (jsonFenceMatch) {
|
|
2154
|
+
try {
|
|
2155
|
+
return JSON.parse(jsonFenceMatch[1].trim());
|
|
2156
|
+
} catch {
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
const anyFenceMatch = content.match(/```(?:[\w]*)\s*\n([\s\S]*?)\n```/);
|
|
2160
|
+
if (anyFenceMatch) {
|
|
2161
|
+
try {
|
|
2162
|
+
return JSON.parse(anyFenceMatch[1].trim());
|
|
2163
|
+
} catch {
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
const bareBraceMatch = content.match(/\{[\s\S]*\}/);
|
|
2167
|
+
if (bareBraceMatch) {
|
|
2168
|
+
try {
|
|
2169
|
+
return JSON.parse(bareBraceMatch[0]);
|
|
2170
|
+
} catch {
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
throw new FlowError(
|
|
2174
|
+
"Could not extract a valid JSON object from the agent's final message. The agent did not format its answer as required."
|
|
2175
|
+
);
|
|
2176
|
+
}
|
|
2177
|
+
var Flow = class {
|
|
2178
|
+
constructor() {
|
|
2179
|
+
// -- Workflow-level defaults (override in subclass) --------------------
|
|
2180
|
+
/** Orchestrator workflow type — `"proactive"` by default. */
|
|
2181
|
+
this.workflowId = "proactive";
|
|
2182
|
+
/** Maximum agent turns before the orchestrator forces a failure. */
|
|
2183
|
+
this.maxIterations = 100;
|
|
2184
|
+
/** LLM reasoning budget: `"low"`, `"medium"`, or `"high"`. */
|
|
2185
|
+
this.reasoningEffort = "medium";
|
|
2186
|
+
/**
|
|
2187
|
+
* Maximum milliseconds to wait for the orchestrator task to reach a
|
|
2188
|
+
* terminal state. When exceeded, {@link FlowTimeoutError} is raised.
|
|
2189
|
+
*/
|
|
2190
|
+
this.flowTimeoutMs = DEFAULT_FLOW_TIMEOUT_MS;
|
|
2191
|
+
}
|
|
2192
|
+
/**
|
|
2193
|
+
* Optional system-prompt override.
|
|
2194
|
+
* When set, this replaces the orchestrator's default system prompt.
|
|
2195
|
+
*/
|
|
2196
|
+
get systemPrompt() {
|
|
2197
|
+
return void 0;
|
|
2198
|
+
}
|
|
2199
|
+
/**
|
|
2200
|
+
* Optional developer-prompt override appended after system prompt.
|
|
2201
|
+
*/
|
|
2202
|
+
get developerPrompt() {
|
|
2203
|
+
return void 0;
|
|
2204
|
+
}
|
|
2205
|
+
/**
|
|
2206
|
+
* Restrict which MCP / built-in tools the agent may use.
|
|
2207
|
+
* `undefined` means *all* tools are available. An empty array means
|
|
2208
|
+
* *no* tools — text-only reasoning.
|
|
2209
|
+
*/
|
|
2210
|
+
get availableTools() {
|
|
2211
|
+
return void 0;
|
|
2212
|
+
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Per-task feature toggles sent in the creation request.
|
|
2215
|
+
* By default summaries and translation are disabled since flow
|
|
2216
|
+
* output is typically machine-consumed, not human-read.
|
|
2217
|
+
* Override in subclasses that produce human-facing content.
|
|
2218
|
+
*/
|
|
2219
|
+
get taskOptions() {
|
|
2220
|
+
return { disableSummaries: true, disableTranslation: true };
|
|
2221
|
+
}
|
|
2222
|
+
/**
|
|
2223
|
+
* Override the agent model for this flow.
|
|
2224
|
+
*/
|
|
2225
|
+
get agentModelId() {
|
|
2226
|
+
return void 0;
|
|
2227
|
+
}
|
|
2228
|
+
/**
|
|
2229
|
+
* Override the orchestrator (validation) model for this flow.
|
|
2230
|
+
*/
|
|
2231
|
+
get orchestratorModelId() {
|
|
2232
|
+
return void 0;
|
|
2233
|
+
}
|
|
2234
|
+
/**
|
|
2235
|
+
* Cancel the underlying orchestrator task, if one is running.
|
|
2236
|
+
*
|
|
2237
|
+
* Calling `cancel()` after `run()` has returned is a no-op.
|
|
2238
|
+
* The `run()` promise will reject with {@link FlowCancelledError}
|
|
2239
|
+
* after the orchestrator task transitions to `"cancelled"`.
|
|
2240
|
+
*/
|
|
2241
|
+
async cancel(client) {
|
|
2242
|
+
if (!this._lastTaskId) return;
|
|
2243
|
+
const resolvedClient = client ?? getDefaultClient();
|
|
2244
|
+
await resolvedClient.cancelTask(this._lastTaskId);
|
|
2245
|
+
}
|
|
2246
|
+
// -- Lifecycle ---------------------------------------------------------
|
|
2247
|
+
/**
|
|
2248
|
+
* Execute the flow end-to-end.
|
|
2249
|
+
*
|
|
2250
|
+
* @returns The parsed result.
|
|
2251
|
+
* @throws {FlowError} If the task fails, times out, or cannot be parsed.
|
|
2252
|
+
*/
|
|
2253
|
+
async run(params) {
|
|
2254
|
+
const client = params?.client ?? getDefaultClient();
|
|
2255
|
+
const realtime = params?.realtime ?? getDefaultRealtime();
|
|
2256
|
+
const timeoutMs = params?.timeoutMs ?? this.flowTimeoutMs;
|
|
2257
|
+
console.log(
|
|
2258
|
+
`[Flow] Starting ${this.constructor.name} \u2014 workflow=${this.workflowId} goal=${this.goalPrompt.slice(0, 80)}`
|
|
2259
|
+
);
|
|
2260
|
+
const response = await client.createTask({
|
|
2261
|
+
workflowId: this.workflowId,
|
|
2262
|
+
goalPrompt: this.goalPrompt,
|
|
2263
|
+
systemPrompt: this.systemPrompt,
|
|
2264
|
+
developerPrompt: this.developerPrompt,
|
|
2265
|
+
availableTools: this.availableTools,
|
|
2266
|
+
options: this.taskOptions,
|
|
2267
|
+
maxIterations: this.maxIterations,
|
|
2268
|
+
reasoningEffort: this.reasoningEffort,
|
|
2269
|
+
agentModelId: this.agentModelId,
|
|
2270
|
+
orchestratorModelId: this.orchestratorModelId
|
|
2271
|
+
});
|
|
2272
|
+
this._lastTaskId = response.taskId;
|
|
2273
|
+
const taskId = response.taskId;
|
|
2274
|
+
console.log(
|
|
2275
|
+
`[Flow] Task created \u2014 taskId=${taskId} status=${response.status}`
|
|
2276
|
+
);
|
|
2277
|
+
const status = await this._waitForTerminal(client, taskId, {
|
|
2278
|
+
realtime,
|
|
2279
|
+
timeoutMs
|
|
2280
|
+
});
|
|
2281
|
+
if (status.status === "cancelled") {
|
|
2282
|
+
throw new FlowCancelledError(taskId);
|
|
2283
|
+
}
|
|
2284
|
+
const finalMessage = await this._getFinalMessage(client, taskId);
|
|
2285
|
+
console.log(
|
|
2286
|
+
`[Flow] ${this.constructor.name} completed \u2014 taskId=${taskId} messageLen=${finalMessage.length}`
|
|
2287
|
+
);
|
|
2288
|
+
return this.parseResult(finalMessage);
|
|
2289
|
+
}
|
|
2290
|
+
// -- Completion waiting -----------------------------------------------
|
|
2291
|
+
async _waitForTerminal(client, taskId, opts) {
|
|
2292
|
+
const { realtime, timeoutMs } = opts;
|
|
2293
|
+
const status = await client.getTaskStatus(taskId);
|
|
2294
|
+
if (TERMINAL_STATUSES.has(status.status)) {
|
|
2295
|
+
console.log(
|
|
2296
|
+
`[Flow] Task ${taskId} already terminal \u2014 status=${status.status}`
|
|
2297
|
+
);
|
|
2298
|
+
return status;
|
|
2299
|
+
}
|
|
2300
|
+
if (realtime) {
|
|
2301
|
+
await this._waitViaSocketIO(taskId, realtime, timeoutMs);
|
|
2302
|
+
} else {
|
|
2303
|
+
console.log(
|
|
2304
|
+
`[Flow] No RealtimeClient available \u2014 polling task ${taskId} with backoff (timeout=${timeoutMs}ms)`
|
|
2305
|
+
);
|
|
2306
|
+
await this._waitViaPolling(client, taskId, timeoutMs);
|
|
2307
|
+
}
|
|
2308
|
+
return client.getTaskStatus(taskId);
|
|
2309
|
+
}
|
|
2310
|
+
async _waitViaSocketIO(taskId, realtime, timeoutMs) {
|
|
2311
|
+
realtime.subscribeTask(taskId);
|
|
2312
|
+
return new Promise((resolve, reject) => {
|
|
2313
|
+
const timer = setTimeout(() => {
|
|
2314
|
+
cleanup();
|
|
2315
|
+
reject(
|
|
2316
|
+
new FlowTimeoutError(
|
|
2317
|
+
`Task ${taskId} did not reach a terminal state within ${timeoutMs}ms`
|
|
2318
|
+
)
|
|
2319
|
+
);
|
|
2320
|
+
}, timeoutMs);
|
|
2321
|
+
const handler = (...args) => {
|
|
2322
|
+
const event = args[0] ?? {};
|
|
2323
|
+
if (event.task_id !== taskId) return;
|
|
2324
|
+
const newStatus = event.new_status ?? "";
|
|
2325
|
+
if (TERMINAL_STATUSES.has(newStatus)) {
|
|
2326
|
+
cleanup();
|
|
2327
|
+
resolve();
|
|
2328
|
+
}
|
|
2329
|
+
};
|
|
2330
|
+
const cleanup = () => {
|
|
2331
|
+
clearTimeout(timer);
|
|
2332
|
+
realtime.off("task_status_changed", handler);
|
|
2333
|
+
realtime.unsubscribeTask(taskId);
|
|
2334
|
+
};
|
|
2335
|
+
realtime.on("task_status_changed", handler);
|
|
2336
|
+
});
|
|
2337
|
+
}
|
|
2338
|
+
async _waitViaPolling(client, taskId, timeoutMs) {
|
|
2339
|
+
const deadline = Date.now() + timeoutMs;
|
|
2340
|
+
let delay = 1e3;
|
|
2341
|
+
while (Date.now() < deadline) {
|
|
2342
|
+
const status = await client.getTaskStatus(taskId);
|
|
2343
|
+
if (TERMINAL_STATUSES.has(status.status)) return;
|
|
2344
|
+
await this._sleep(delay);
|
|
2345
|
+
delay = Math.min(Math.round(delay * 1.5), 1e4);
|
|
2346
|
+
}
|
|
2347
|
+
throw new FlowTimeoutError(
|
|
2348
|
+
`Task ${taskId} did not reach a terminal state within ${timeoutMs}ms (polling fallback)`
|
|
2349
|
+
);
|
|
2350
|
+
}
|
|
2351
|
+
// -- Conversation helpers ---------------------------------------------
|
|
2352
|
+
async _getFinalMessage(client, taskId) {
|
|
2353
|
+
const conversation = await client.getTaskConversation(taskId, {
|
|
2354
|
+
includeSummaries: false,
|
|
2355
|
+
excludeArchived: false
|
|
2356
|
+
});
|
|
2357
|
+
const messages = conversation.conversation;
|
|
2358
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
2359
|
+
const msg = messages[i];
|
|
2360
|
+
if (msg.role === "assistant" && msg.content?.trim()) {
|
|
2361
|
+
return msg.content;
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
2365
|
+
const msg = messages[i];
|
|
2366
|
+
if (msg.role === "assistant" && msg.archived && msg.id != null) {
|
|
2367
|
+
const archived = await client.getArchivedMessageContent(taskId, msg.id);
|
|
2368
|
+
if (archived.content?.trim()) {
|
|
2369
|
+
return archived.content;
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
const status = await client.getTaskStatus(taskId);
|
|
2374
|
+
throw new FlowError(
|
|
2375
|
+
`No assistant message with content found in task ${taskId}. Status: ${status.status}. Result: ${(status.result ?? "").slice(0, 200) || "empty"}. Messages in conversation: ${messages.length}.`
|
|
2376
|
+
);
|
|
2377
|
+
}
|
|
2378
|
+
// -- Helper -----------------------------------------------------------
|
|
2379
|
+
_sleep(ms) {
|
|
2380
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2381
|
+
}
|
|
2382
|
+
};
|
|
2383
|
+
|
|
2063
2384
|
// src/index.ts
|
|
2064
2385
|
var VERSION = "5.6.0";
|
|
2065
2386
|
export {
|
|
2387
|
+
DEFAULT_FLOW_TIMEOUT_MS,
|
|
2066
2388
|
EVENT_ERROR_EVENT_RECORDED,
|
|
2067
2389
|
EVENT_MESSAGE_ADDED,
|
|
2068
2390
|
EVENT_MESSAGE_STREAMING,
|
|
@@ -2074,6 +2396,10 @@ export {
|
|
|
2074
2396
|
EVENT_TASK_ITERATION_CHANGED,
|
|
2075
2397
|
EVENT_TASK_RESULT_UPDATED,
|
|
2076
2398
|
EVENT_TASK_STATUS_CHANGED,
|
|
2399
|
+
Flow,
|
|
2400
|
+
FlowCancelledError,
|
|
2401
|
+
FlowError,
|
|
2402
|
+
FlowTimeoutError,
|
|
2077
2403
|
Orchestrator,
|
|
2078
2404
|
OrchestratorAPIError,
|
|
2079
2405
|
OrchestratorAsync,
|
|
@@ -2087,7 +2413,9 @@ export {
|
|
|
2087
2413
|
camelToSnake,
|
|
2088
2414
|
createInsecureFetch,
|
|
2089
2415
|
deepCamelCase,
|
|
2416
|
+
extractJsonFromMessage,
|
|
2090
2417
|
loadConfig,
|
|
2418
|
+
setupDefaultClient,
|
|
2091
2419
|
snakeToCamel
|
|
2092
2420
|
};
|
|
2093
2421
|
//# sourceMappingURL=index.js.map
|