@botbotgo/agent-harness 0.0.30 → 0.0.31
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.30";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.30";
|
|
@@ -7,13 +7,16 @@ type RunnableLike = {
|
|
|
7
7
|
};
|
|
8
8
|
declare const AGENT_INTERRUPT_SENTINEL_PREFIX = "__agent_harness_interrupt__:";
|
|
9
9
|
declare class RuntimeOperationTimeoutError extends Error {
|
|
10
|
+
readonly operation: string;
|
|
10
11
|
readonly timeoutMs: number;
|
|
11
|
-
|
|
12
|
+
readonly stage: "stream" | "invoke";
|
|
13
|
+
constructor(operation: string, timeoutMs: number, stage?: "stream" | "invoke");
|
|
12
14
|
}
|
|
13
15
|
export declare class AgentRuntimeAdapter {
|
|
14
16
|
private readonly options;
|
|
15
17
|
constructor(options?: RuntimeAdapterOptions);
|
|
16
18
|
private resolveBindingTimeout;
|
|
19
|
+
private resolveStreamIdleTimeout;
|
|
17
20
|
private withTimeout;
|
|
18
21
|
private iterateWithTimeout;
|
|
19
22
|
private materializeModelStream;
|
|
@@ -13,10 +13,14 @@ import { extractMessageText, normalizeMessageContent } from "../utils/message-co
|
|
|
13
13
|
const AGENT_INTERRUPT_SENTINEL_PREFIX = "__agent_harness_interrupt__:";
|
|
14
14
|
const MODEL_SAFE_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
15
15
|
class RuntimeOperationTimeoutError extends Error {
|
|
16
|
+
operation;
|
|
16
17
|
timeoutMs;
|
|
17
|
-
|
|
18
|
+
stage;
|
|
19
|
+
constructor(operation, timeoutMs, stage = operation.includes("stream") ? "stream" : "invoke") {
|
|
18
20
|
super(`${operation} timed out after ${timeoutMs}ms`);
|
|
21
|
+
this.operation = operation;
|
|
19
22
|
this.timeoutMs = timeoutMs;
|
|
23
|
+
this.stage = stage;
|
|
20
24
|
this.name = "RuntimeOperationTimeoutError";
|
|
21
25
|
}
|
|
22
26
|
}
|
|
@@ -127,12 +131,23 @@ export class AgentRuntimeAdapter {
|
|
|
127
131
|
resolveBindingTimeout(binding) {
|
|
128
132
|
return resolveTimeoutMs(binding.langchainAgentParams?.model.init.timeout ?? binding.deepAgentParams?.model.init.timeout);
|
|
129
133
|
}
|
|
130
|
-
|
|
134
|
+
resolveStreamIdleTimeout(binding) {
|
|
135
|
+
const configuredIdleTimeout = resolveTimeoutMs(binding.langchainAgentParams?.model.init.streamIdleTimeout ?? binding.deepAgentParams?.model.init.streamIdleTimeout);
|
|
136
|
+
if (configuredIdleTimeout) {
|
|
137
|
+
return configuredIdleTimeout;
|
|
138
|
+
}
|
|
139
|
+
const invokeTimeout = this.resolveBindingTimeout(binding);
|
|
140
|
+
if (invokeTimeout) {
|
|
141
|
+
return Math.min(invokeTimeout, 15_000);
|
|
142
|
+
}
|
|
143
|
+
return 15_000;
|
|
144
|
+
}
|
|
145
|
+
async withTimeout(producer, timeoutMs, operation, stage = operation.includes("stream") ? "stream" : "invoke") {
|
|
131
146
|
if (!timeoutMs) {
|
|
132
147
|
return Promise.resolve(producer());
|
|
133
148
|
}
|
|
134
149
|
return new Promise((resolve, reject) => {
|
|
135
|
-
const timer = setTimeout(() => reject(new RuntimeOperationTimeoutError(operation, timeoutMs)), timeoutMs);
|
|
150
|
+
const timer = setTimeout(() => reject(new RuntimeOperationTimeoutError(operation, timeoutMs, stage)), timeoutMs);
|
|
136
151
|
Promise.resolve(producer()).then((value) => {
|
|
137
152
|
clearTimeout(timer);
|
|
138
153
|
resolve(value);
|
|
@@ -146,7 +161,7 @@ export class AgentRuntimeAdapter {
|
|
|
146
161
|
const iterator = iterable[Symbol.asyncIterator]();
|
|
147
162
|
try {
|
|
148
163
|
for (;;) {
|
|
149
|
-
const next = await this.withTimeout(() => iterator.next(), timeoutMs, operation);
|
|
164
|
+
const next = await this.withTimeout(() => iterator.next(), timeoutMs, operation, "stream");
|
|
150
165
|
if (next.done) {
|
|
151
166
|
return;
|
|
152
167
|
}
|
|
@@ -251,7 +266,7 @@ export class AgentRuntimeAdapter {
|
|
|
251
266
|
role: "user",
|
|
252
267
|
content: `Original user request:\n${extractMessageText(input)}\n\nTool results:\n${toolContext}`,
|
|
253
268
|
},
|
|
254
|
-
]), this.resolveBindingTimeout(binding), "deepagent synthesis invoke");
|
|
269
|
+
]), this.resolveBindingTimeout(binding), "deepagent synthesis invoke", "invoke");
|
|
255
270
|
return sanitizeVisibleText(extractVisibleOutput(synthesized));
|
|
256
271
|
}
|
|
257
272
|
async resolveModel(model) {
|
|
@@ -470,7 +485,7 @@ export class AgentRuntimeAdapter {
|
|
|
470
485
|
let result;
|
|
471
486
|
try {
|
|
472
487
|
const runnable = await this.create(binding);
|
|
473
|
-
result = (await this.withTimeout(() => runnable.invoke(request, { configurable: { thread_id: threadId } }), this.resolveBindingTimeout(binding), "agent invoke"));
|
|
488
|
+
result = (await this.withTimeout(() => runnable.invoke(request, { configurable: { thread_id: threadId } }), this.resolveBindingTimeout(binding), "agent invoke", "invoke"));
|
|
474
489
|
}
|
|
475
490
|
catch (error) {
|
|
476
491
|
if (resumePayload !== undefined || !isToolCallParseFailure(error)) {
|
|
@@ -478,7 +493,7 @@ export class AgentRuntimeAdapter {
|
|
|
478
493
|
}
|
|
479
494
|
const retriedBinding = this.applyStrictToolJsonInstruction(binding);
|
|
480
495
|
const runnable = await this.create(retriedBinding);
|
|
481
|
-
result = (await this.withTimeout(() => runnable.invoke({ messages: this.buildAgentMessages(history, input) }, { configurable: { thread_id: threadId } }), this.resolveBindingTimeout(retriedBinding), "agent invoke"));
|
|
496
|
+
result = (await this.withTimeout(() => runnable.invoke({ messages: this.buildAgentMessages(history, input) }, { configurable: { thread_id: threadId } }), this.resolveBindingTimeout(retriedBinding), "agent invoke", "invoke"));
|
|
482
497
|
}
|
|
483
498
|
const interruptContent = Array.isArray(result.__interrupt__) && result.__interrupt__.length > 0 ? JSON.stringify(result.__interrupt__) : undefined;
|
|
484
499
|
const extractedOutput = extractVisibleOutput(result);
|
|
@@ -501,7 +516,8 @@ export class AgentRuntimeAdapter {
|
|
|
501
516
|
}
|
|
502
517
|
async *stream(binding, input, threadId, history = []) {
|
|
503
518
|
try {
|
|
504
|
-
const
|
|
519
|
+
const invokeTimeoutMs = this.resolveBindingTimeout(binding);
|
|
520
|
+
const streamIdleTimeoutMs = this.resolveStreamIdleTimeout(binding);
|
|
505
521
|
if (binding.langchainAgentParams) {
|
|
506
522
|
const langchainParams = binding.langchainAgentParams;
|
|
507
523
|
const resolvedModel = (await this.resolveModel(binding.langchainAgentParams.model));
|
|
@@ -516,8 +532,8 @@ export class AgentRuntimeAdapter {
|
|
|
516
532
|
// agent loop and only adds an extra model round-trip before the runnable path.
|
|
517
533
|
if (canUseDirectModelStream && typeof model.stream === "function") {
|
|
518
534
|
let emitted = false;
|
|
519
|
-
const stream = await this.withTimeout(() => model.stream(this.buildRawModelMessages(langchainParams.systemPrompt, history, input)),
|
|
520
|
-
for await (const chunk of this.iterateWithTimeout(stream,
|
|
535
|
+
const stream = await this.withTimeout(() => model.stream(this.buildRawModelMessages(langchainParams.systemPrompt, history, input)), invokeTimeoutMs, "model stream start", "stream");
|
|
536
|
+
for await (const chunk of this.iterateWithTimeout(stream, streamIdleTimeoutMs, "model stream")) {
|
|
521
537
|
const delta = readStreamDelta(chunk);
|
|
522
538
|
if (delta) {
|
|
523
539
|
emitted = true;
|
|
@@ -537,11 +553,11 @@ export class AgentRuntimeAdapter {
|
|
|
537
553
|
const runnable = await this.create(binding);
|
|
538
554
|
const request = { messages: this.buildAgentMessages(history, input) };
|
|
539
555
|
if (typeof runnable.streamEvents === "function") {
|
|
540
|
-
const events = await this.withTimeout(() => runnable.streamEvents(request, { configurable: { thread_id: threadId }, version: "v2" }),
|
|
556
|
+
const events = await this.withTimeout(() => runnable.streamEvents(request, { configurable: { thread_id: threadId }, version: "v2" }), invokeTimeoutMs, "agent streamEvents start", "stream");
|
|
541
557
|
let terminalOutput = "";
|
|
542
558
|
const seenTerminalOutputs = new Set();
|
|
543
559
|
let lastStep = "";
|
|
544
|
-
for await (const event of this.iterateWithTimeout(events,
|
|
560
|
+
for await (const event of this.iterateWithTimeout(events, streamIdleTimeoutMs, "agent streamEvents")) {
|
|
545
561
|
const interruptPayload = extractInterruptPayload(event);
|
|
546
562
|
if (interruptPayload) {
|
|
547
563
|
yield { kind: "interrupt", content: interruptPayload };
|
|
@@ -578,9 +594,9 @@ export class AgentRuntimeAdapter {
|
|
|
578
594
|
}
|
|
579
595
|
}
|
|
580
596
|
if (binding.langchainAgentParams && typeof runnable.stream === "function") {
|
|
581
|
-
const stream = await this.withTimeout(() => runnable.stream(request, { configurable: { thread_id: threadId } }),
|
|
597
|
+
const stream = await this.withTimeout(() => runnable.stream(request, { configurable: { thread_id: threadId } }), invokeTimeoutMs, "agent stream start", "stream");
|
|
582
598
|
let emitted = false;
|
|
583
|
-
for await (const chunk of this.iterateWithTimeout(stream,
|
|
599
|
+
for await (const chunk of this.iterateWithTimeout(stream, streamIdleTimeoutMs, "agent stream")) {
|
|
584
600
|
const delta = readStreamDelta(chunk);
|
|
585
601
|
if (delta) {
|
|
586
602
|
emitted = true;
|
package/dist/runtime/harness.js
CHANGED
|
@@ -628,7 +628,7 @@ export class AgentHarness {
|
|
|
628
628
|
}) };
|
|
629
629
|
return;
|
|
630
630
|
}
|
|
631
|
-
if (error instanceof RuntimeOperationTimeoutError) {
|
|
631
|
+
if (error instanceof RuntimeOperationTimeoutError && error.stage === "invoke") {
|
|
632
632
|
yield { type: "event", event: await this.setRunStateAndEmit(threadId, runId, 4, "failed", {
|
|
633
633
|
previousState: null,
|
|
634
634
|
error: error.message,
|