orchestrator-client 5.7.4 → 5.7.10
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 +313 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +162 -1
- package/dist/index.d.ts +162 -1
- package/dist/index.js +306 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
DEFAULT_FLOW_TIMEOUT_MS: () => DEFAULT_FLOW_TIMEOUT_MS,
|
|
33
34
|
EVENT_ERROR_EVENT_RECORDED: () => EVENT_ERROR_EVENT_RECORDED,
|
|
34
35
|
EVENT_MESSAGE_ADDED: () => EVENT_MESSAGE_ADDED,
|
|
35
36
|
EVENT_MESSAGE_STREAMING: () => EVENT_MESSAGE_STREAMING,
|
|
@@ -41,6 +42,10 @@ __export(index_exports, {
|
|
|
41
42
|
EVENT_TASK_ITERATION_CHANGED: () => EVENT_TASK_ITERATION_CHANGED,
|
|
42
43
|
EVENT_TASK_RESULT_UPDATED: () => EVENT_TASK_RESULT_UPDATED,
|
|
43
44
|
EVENT_TASK_STATUS_CHANGED: () => EVENT_TASK_STATUS_CHANGED,
|
|
45
|
+
Flow: () => Flow,
|
|
46
|
+
FlowCancelledError: () => FlowCancelledError,
|
|
47
|
+
FlowError: () => FlowError,
|
|
48
|
+
FlowTimeoutError: () => FlowTimeoutError,
|
|
44
49
|
Orchestrator: () => Orchestrator,
|
|
45
50
|
OrchestratorAPIError: () => OrchestratorAPIError,
|
|
46
51
|
OrchestratorAsync: () => OrchestratorAsync,
|
|
@@ -54,7 +59,9 @@ __export(index_exports, {
|
|
|
54
59
|
camelToSnake: () => camelToSnake,
|
|
55
60
|
createInsecureFetch: () => createInsecureFetch,
|
|
56
61
|
deepCamelCase: () => deepCamelCase,
|
|
62
|
+
extractJsonFromMessage: () => extractJsonFromMessage,
|
|
57
63
|
loadConfig: () => loadConfig,
|
|
64
|
+
setupDefaultClient: () => setupDefaultClient,
|
|
58
65
|
snakeToCamel: () => snakeToCamel
|
|
59
66
|
});
|
|
60
67
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -232,6 +239,11 @@ var OrchestratorAsync = class {
|
|
|
232
239
|
_makeUrl(path) {
|
|
233
240
|
return `${this._baseUrl}${path}`;
|
|
234
241
|
}
|
|
242
|
+
_makeAbsoluteUrl(path) {
|
|
243
|
+
const raw = this._makeUrl(path);
|
|
244
|
+
const base = typeof globalThis.location !== "undefined" ? globalThis.location.href : void 0;
|
|
245
|
+
return new URL(raw, base);
|
|
246
|
+
}
|
|
235
247
|
async _resolveHeaders() {
|
|
236
248
|
const headers = {};
|
|
237
249
|
if (this._apiKey) {
|
|
@@ -248,7 +260,7 @@ var OrchestratorAsync = class {
|
|
|
248
260
|
return headers;
|
|
249
261
|
}
|
|
250
262
|
async _request(method, path, opts) {
|
|
251
|
-
const url =
|
|
263
|
+
const url = this._makeAbsoluteUrl(path);
|
|
252
264
|
if (opts?.params) {
|
|
253
265
|
for (const [key, value] of Object.entries(opts.params)) {
|
|
254
266
|
if (value !== void 0) {
|
|
@@ -1042,7 +1054,7 @@ var OrchestratorAsync = class {
|
|
|
1042
1054
|
// ------------------------------------------------------------------
|
|
1043
1055
|
async listErrors(params) {
|
|
1044
1056
|
const authHeaders = await this._resolveHeaders();
|
|
1045
|
-
const url =
|
|
1057
|
+
const url = this._makeAbsoluteUrl("/errors");
|
|
1046
1058
|
if (params?.page !== void 0)
|
|
1047
1059
|
url.searchParams.set("page", String(params.page));
|
|
1048
1060
|
if (params?.limit !== void 0)
|
|
@@ -2121,10 +2133,303 @@ var RealtimeClient = class {
|
|
|
2121
2133
|
}
|
|
2122
2134
|
};
|
|
2123
2135
|
|
|
2136
|
+
// src/flow.ts
|
|
2137
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
2138
|
+
"completed",
|
|
2139
|
+
"failed",
|
|
2140
|
+
"cancelled",
|
|
2141
|
+
"translation"
|
|
2142
|
+
]);
|
|
2143
|
+
var DEFAULT_FLOW_TIMEOUT_MS = 6e5;
|
|
2144
|
+
var _defaultClient;
|
|
2145
|
+
var _defaultRealtime;
|
|
2146
|
+
function setupDefaultClient(client, realtime) {
|
|
2147
|
+
_defaultClient = client;
|
|
2148
|
+
_defaultRealtime = realtime;
|
|
2149
|
+
}
|
|
2150
|
+
function getDefaultClient() {
|
|
2151
|
+
if (!_defaultClient) {
|
|
2152
|
+
throw new Error(
|
|
2153
|
+
"No default OrchestratorAsync set. Call setupDefaultClient() during application startup, or pass client to flow.run()."
|
|
2154
|
+
);
|
|
2155
|
+
}
|
|
2156
|
+
return _defaultClient;
|
|
2157
|
+
}
|
|
2158
|
+
function getDefaultRealtime() {
|
|
2159
|
+
return _defaultRealtime;
|
|
2160
|
+
}
|
|
2161
|
+
var FlowError = class extends Error {
|
|
2162
|
+
constructor(message) {
|
|
2163
|
+
super(message);
|
|
2164
|
+
this.name = "FlowError";
|
|
2165
|
+
}
|
|
2166
|
+
};
|
|
2167
|
+
var FlowTimeoutError = class extends FlowError {
|
|
2168
|
+
constructor(message) {
|
|
2169
|
+
super(message);
|
|
2170
|
+
this.name = "FlowTimeoutError";
|
|
2171
|
+
}
|
|
2172
|
+
};
|
|
2173
|
+
var FlowCancelledError = class extends FlowError {
|
|
2174
|
+
constructor(taskId) {
|
|
2175
|
+
super(`Task ${taskId} was cancelled`);
|
|
2176
|
+
this.name = "FlowCancelledError";
|
|
2177
|
+
this.taskId = taskId;
|
|
2178
|
+
}
|
|
2179
|
+
};
|
|
2180
|
+
function extractJsonFromMessage(content) {
|
|
2181
|
+
const cleaned = content.replace(/^\ufeff|\u200b|\u200c|\u200d/, "").trim();
|
|
2182
|
+
if (cleaned.startsWith("{")) {
|
|
2183
|
+
try {
|
|
2184
|
+
return JSON.parse(cleaned);
|
|
2185
|
+
} catch {
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
const start = content.indexOf("{");
|
|
2189
|
+
const end = content.lastIndexOf("}");
|
|
2190
|
+
if (start !== -1 && end !== -1 && end > start) {
|
|
2191
|
+
try {
|
|
2192
|
+
return JSON.parse(content.slice(start, end + 1));
|
|
2193
|
+
} catch {
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
const jsonFenceMatch = content.match(/```(?:json)\s*\n([\s\S]*?)\n```/i);
|
|
2197
|
+
if (jsonFenceMatch) {
|
|
2198
|
+
try {
|
|
2199
|
+
return JSON.parse(jsonFenceMatch[1].trim());
|
|
2200
|
+
} catch {
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
const anyFenceMatch = content.match(/```(?:[\w]*)\s*\n([\s\S]*?)\n```/);
|
|
2204
|
+
if (anyFenceMatch) {
|
|
2205
|
+
try {
|
|
2206
|
+
return JSON.parse(anyFenceMatch[1].trim());
|
|
2207
|
+
} catch {
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
const bareBraceMatch = content.match(/\{[\s\S]*\}/);
|
|
2211
|
+
if (bareBraceMatch) {
|
|
2212
|
+
try {
|
|
2213
|
+
return JSON.parse(bareBraceMatch[0]);
|
|
2214
|
+
} catch {
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
throw new FlowError(
|
|
2218
|
+
"Could not extract a valid JSON object from the agent's final message. The agent did not format its answer as required."
|
|
2219
|
+
);
|
|
2220
|
+
}
|
|
2221
|
+
var Flow = class {
|
|
2222
|
+
constructor() {
|
|
2223
|
+
// -- Workflow-level defaults (override in subclass) --------------------
|
|
2224
|
+
/** Orchestrator workflow type — `"proactive"` by default. */
|
|
2225
|
+
this.workflowId = "proactive";
|
|
2226
|
+
/** Maximum agent turns before the orchestrator forces a failure. */
|
|
2227
|
+
this.maxIterations = 100;
|
|
2228
|
+
/** LLM reasoning budget: `"low"`, `"medium"`, or `"high"`. */
|
|
2229
|
+
this.reasoningEffort = "medium";
|
|
2230
|
+
/**
|
|
2231
|
+
* Maximum milliseconds to wait for the orchestrator task to reach a
|
|
2232
|
+
* terminal state. When exceeded, {@link FlowTimeoutError} is raised.
|
|
2233
|
+
*/
|
|
2234
|
+
this.flowTimeoutMs = DEFAULT_FLOW_TIMEOUT_MS;
|
|
2235
|
+
}
|
|
2236
|
+
/**
|
|
2237
|
+
* Optional system-prompt override.
|
|
2238
|
+
* When set, this replaces the orchestrator's default system prompt.
|
|
2239
|
+
*/
|
|
2240
|
+
get systemPrompt() {
|
|
2241
|
+
return void 0;
|
|
2242
|
+
}
|
|
2243
|
+
/**
|
|
2244
|
+
* Optional developer-prompt override appended after system prompt.
|
|
2245
|
+
*/
|
|
2246
|
+
get developerPrompt() {
|
|
2247
|
+
return void 0;
|
|
2248
|
+
}
|
|
2249
|
+
/**
|
|
2250
|
+
* Restrict which MCP / built-in tools the agent may use.
|
|
2251
|
+
* `undefined` means *all* tools are available. An empty array means
|
|
2252
|
+
* *no* tools — text-only reasoning.
|
|
2253
|
+
*/
|
|
2254
|
+
get availableTools() {
|
|
2255
|
+
return void 0;
|
|
2256
|
+
}
|
|
2257
|
+
/**
|
|
2258
|
+
* Per-task feature toggles sent in the creation request.
|
|
2259
|
+
* By default summaries and translation are disabled since flow
|
|
2260
|
+
* output is typically machine-consumed, not human-read.
|
|
2261
|
+
* Override in subclasses that produce human-facing content.
|
|
2262
|
+
*/
|
|
2263
|
+
get taskOptions() {
|
|
2264
|
+
return { disableSummaries: true, disableTranslation: true };
|
|
2265
|
+
}
|
|
2266
|
+
/**
|
|
2267
|
+
* Override the agent model for this flow.
|
|
2268
|
+
*/
|
|
2269
|
+
get agentModelId() {
|
|
2270
|
+
return void 0;
|
|
2271
|
+
}
|
|
2272
|
+
/**
|
|
2273
|
+
* Override the orchestrator (validation) model for this flow.
|
|
2274
|
+
*/
|
|
2275
|
+
get orchestratorModelId() {
|
|
2276
|
+
return void 0;
|
|
2277
|
+
}
|
|
2278
|
+
/**
|
|
2279
|
+
* Cancel the underlying orchestrator task, if one is running.
|
|
2280
|
+
*
|
|
2281
|
+
* Calling `cancel()` after `run()` has returned is a no-op.
|
|
2282
|
+
* The `run()` promise will reject with {@link FlowCancelledError}
|
|
2283
|
+
* after the orchestrator task transitions to `"cancelled"`.
|
|
2284
|
+
*/
|
|
2285
|
+
async cancel(client) {
|
|
2286
|
+
if (!this._lastTaskId) return;
|
|
2287
|
+
const resolvedClient = client ?? getDefaultClient();
|
|
2288
|
+
await resolvedClient.cancelTask(this._lastTaskId);
|
|
2289
|
+
}
|
|
2290
|
+
// -- Lifecycle ---------------------------------------------------------
|
|
2291
|
+
/**
|
|
2292
|
+
* Execute the flow end-to-end.
|
|
2293
|
+
*
|
|
2294
|
+
* @returns The parsed result.
|
|
2295
|
+
* @throws {FlowError} If the task fails, times out, or cannot be parsed.
|
|
2296
|
+
*/
|
|
2297
|
+
async run(params) {
|
|
2298
|
+
const client = params?.client ?? getDefaultClient();
|
|
2299
|
+
const realtime = params?.realtime ?? getDefaultRealtime();
|
|
2300
|
+
const timeoutMs = params?.timeoutMs ?? this.flowTimeoutMs;
|
|
2301
|
+
console.log(
|
|
2302
|
+
`[Flow] Starting ${this.constructor.name} \u2014 workflow=${this.workflowId} goal=${this.goalPrompt.slice(0, 80)}`
|
|
2303
|
+
);
|
|
2304
|
+
const response = await client.createTask({
|
|
2305
|
+
workflowId: this.workflowId,
|
|
2306
|
+
goalPrompt: this.goalPrompt,
|
|
2307
|
+
systemPrompt: this.systemPrompt,
|
|
2308
|
+
developerPrompt: this.developerPrompt,
|
|
2309
|
+
availableTools: this.availableTools,
|
|
2310
|
+
options: this.taskOptions,
|
|
2311
|
+
maxIterations: this.maxIterations,
|
|
2312
|
+
reasoningEffort: this.reasoningEffort,
|
|
2313
|
+
agentModelId: this.agentModelId,
|
|
2314
|
+
orchestratorModelId: this.orchestratorModelId
|
|
2315
|
+
});
|
|
2316
|
+
this._lastTaskId = response.taskId;
|
|
2317
|
+
const taskId = response.taskId;
|
|
2318
|
+
console.log(
|
|
2319
|
+
`[Flow] Task created \u2014 taskId=${taskId} status=${response.status}`
|
|
2320
|
+
);
|
|
2321
|
+
const status = await this._waitForTerminal(client, taskId, {
|
|
2322
|
+
realtime,
|
|
2323
|
+
timeoutMs
|
|
2324
|
+
});
|
|
2325
|
+
if (status.status === "cancelled") {
|
|
2326
|
+
throw new FlowCancelledError(taskId);
|
|
2327
|
+
}
|
|
2328
|
+
const finalMessage = await this._getFinalMessage(client, taskId);
|
|
2329
|
+
console.log(
|
|
2330
|
+
`[Flow] ${this.constructor.name} completed \u2014 taskId=${taskId} messageLen=${finalMessage.length}`
|
|
2331
|
+
);
|
|
2332
|
+
return this.parseResult(finalMessage);
|
|
2333
|
+
}
|
|
2334
|
+
// -- Completion waiting -----------------------------------------------
|
|
2335
|
+
async _waitForTerminal(client, taskId, opts) {
|
|
2336
|
+
const { realtime, timeoutMs } = opts;
|
|
2337
|
+
const status = await client.getTaskStatus(taskId);
|
|
2338
|
+
if (TERMINAL_STATUSES.has(status.status)) {
|
|
2339
|
+
console.log(
|
|
2340
|
+
`[Flow] Task ${taskId} already terminal \u2014 status=${status.status}`
|
|
2341
|
+
);
|
|
2342
|
+
return status;
|
|
2343
|
+
}
|
|
2344
|
+
if (realtime) {
|
|
2345
|
+
await this._waitViaSocketIO(taskId, realtime, timeoutMs);
|
|
2346
|
+
} else {
|
|
2347
|
+
console.log(
|
|
2348
|
+
`[Flow] No RealtimeClient available \u2014 polling task ${taskId} with backoff (timeout=${timeoutMs}ms)`
|
|
2349
|
+
);
|
|
2350
|
+
await this._waitViaPolling(client, taskId, timeoutMs);
|
|
2351
|
+
}
|
|
2352
|
+
return client.getTaskStatus(taskId);
|
|
2353
|
+
}
|
|
2354
|
+
async _waitViaSocketIO(taskId, realtime, timeoutMs) {
|
|
2355
|
+
realtime.subscribeTask(taskId);
|
|
2356
|
+
return new Promise((resolve, reject) => {
|
|
2357
|
+
const timer = setTimeout(() => {
|
|
2358
|
+
cleanup();
|
|
2359
|
+
reject(
|
|
2360
|
+
new FlowTimeoutError(
|
|
2361
|
+
`Task ${taskId} did not reach a terminal state within ${timeoutMs}ms`
|
|
2362
|
+
)
|
|
2363
|
+
);
|
|
2364
|
+
}, timeoutMs);
|
|
2365
|
+
const handler = (...args) => {
|
|
2366
|
+
const event = args[0] ?? {};
|
|
2367
|
+
if (event.task_id !== taskId) return;
|
|
2368
|
+
const newStatus = event.new_status ?? "";
|
|
2369
|
+
if (TERMINAL_STATUSES.has(newStatus)) {
|
|
2370
|
+
cleanup();
|
|
2371
|
+
resolve();
|
|
2372
|
+
}
|
|
2373
|
+
};
|
|
2374
|
+
const cleanup = () => {
|
|
2375
|
+
clearTimeout(timer);
|
|
2376
|
+
realtime.off("task_status_changed", handler);
|
|
2377
|
+
realtime.unsubscribeTask(taskId);
|
|
2378
|
+
};
|
|
2379
|
+
realtime.on("task_status_changed", handler);
|
|
2380
|
+
});
|
|
2381
|
+
}
|
|
2382
|
+
async _waitViaPolling(client, taskId, timeoutMs) {
|
|
2383
|
+
const deadline = Date.now() + timeoutMs;
|
|
2384
|
+
let delay = 1e3;
|
|
2385
|
+
while (Date.now() < deadline) {
|
|
2386
|
+
const status = await client.getTaskStatus(taskId);
|
|
2387
|
+
if (TERMINAL_STATUSES.has(status.status)) return;
|
|
2388
|
+
await this._sleep(delay);
|
|
2389
|
+
delay = Math.min(Math.round(delay * 1.5), 1e4);
|
|
2390
|
+
}
|
|
2391
|
+
throw new FlowTimeoutError(
|
|
2392
|
+
`Task ${taskId} did not reach a terminal state within ${timeoutMs}ms (polling fallback)`
|
|
2393
|
+
);
|
|
2394
|
+
}
|
|
2395
|
+
// -- Conversation helpers ---------------------------------------------
|
|
2396
|
+
async _getFinalMessage(client, taskId) {
|
|
2397
|
+
const conversation = await client.getTaskConversation(taskId, {
|
|
2398
|
+
includeSummaries: false,
|
|
2399
|
+
excludeArchived: false
|
|
2400
|
+
});
|
|
2401
|
+
const messages = conversation.conversation;
|
|
2402
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
2403
|
+
const msg = messages[i];
|
|
2404
|
+
if (msg.role === "assistant" && msg.content?.trim()) {
|
|
2405
|
+
return msg.content;
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
2409
|
+
const msg = messages[i];
|
|
2410
|
+
if (msg.role === "assistant" && msg.archived && msg.id != null) {
|
|
2411
|
+
const archived = await client.getArchivedMessageContent(taskId, msg.id);
|
|
2412
|
+
if (archived.content?.trim()) {
|
|
2413
|
+
return archived.content;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
const status = await client.getTaskStatus(taskId);
|
|
2418
|
+
throw new FlowError(
|
|
2419
|
+
`No assistant message with content found in task ${taskId}. Status: ${status.status}. Result: ${(status.result ?? "").slice(0, 200) || "empty"}. Messages in conversation: ${messages.length}.`
|
|
2420
|
+
);
|
|
2421
|
+
}
|
|
2422
|
+
// -- Helper -----------------------------------------------------------
|
|
2423
|
+
_sleep(ms) {
|
|
2424
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2425
|
+
}
|
|
2426
|
+
};
|
|
2427
|
+
|
|
2124
2428
|
// src/index.ts
|
|
2125
2429
|
var VERSION = "5.6.0";
|
|
2126
2430
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2127
2431
|
0 && (module.exports = {
|
|
2432
|
+
DEFAULT_FLOW_TIMEOUT_MS,
|
|
2128
2433
|
EVENT_ERROR_EVENT_RECORDED,
|
|
2129
2434
|
EVENT_MESSAGE_ADDED,
|
|
2130
2435
|
EVENT_MESSAGE_STREAMING,
|
|
@@ -2136,6 +2441,10 @@ var VERSION = "5.6.0";
|
|
|
2136
2441
|
EVENT_TASK_ITERATION_CHANGED,
|
|
2137
2442
|
EVENT_TASK_RESULT_UPDATED,
|
|
2138
2443
|
EVENT_TASK_STATUS_CHANGED,
|
|
2444
|
+
Flow,
|
|
2445
|
+
FlowCancelledError,
|
|
2446
|
+
FlowError,
|
|
2447
|
+
FlowTimeoutError,
|
|
2139
2448
|
Orchestrator,
|
|
2140
2449
|
OrchestratorAPIError,
|
|
2141
2450
|
OrchestratorAsync,
|
|
@@ -2149,7 +2458,9 @@ var VERSION = "5.6.0";
|
|
|
2149
2458
|
camelToSnake,
|
|
2150
2459
|
createInsecureFetch,
|
|
2151
2460
|
deepCamelCase,
|
|
2461
|
+
extractJsonFromMessage,
|
|
2152
2462
|
loadConfig,
|
|
2463
|
+
setupDefaultClient,
|
|
2153
2464
|
snakeToCamel
|
|
2154
2465
|
});
|
|
2155
2466
|
//# sourceMappingURL=index.cjs.map
|