@runtypelabs/sdk 1.10.0 → 1.10.2
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 +155 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/{index.js → index.mjs} +156 -11
- package/dist/index.mjs.map +1 -0
- package/package.json +3 -3
- package/dist/index.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -2310,7 +2310,10 @@ function hasSufficientResearchEvidence(state) {
|
|
|
2310
2310
|
return false;
|
|
2311
2311
|
}
|
|
2312
2312
|
if (state.isCreationTask) {
|
|
2313
|
-
|
|
2313
|
+
const hasReadFiles = (state.recentReadPaths?.length || 0) >= 1;
|
|
2314
|
+
const isDiscoveryKey = (key) => key.startsWith("tree_directory:") || key.startsWith("list_directory:") || key === "server:tree_directory" || key === "server:list_directory";
|
|
2315
|
+
const hasPerformedDiscovery = state.sessions.some((session) => session.actionKeys?.some(isDiscoveryKey)) || (state.recentActionKeys?.some(isDiscoveryKey) ?? false);
|
|
2316
|
+
return hasReadFiles || hasPerformedDiscovery;
|
|
2314
2317
|
}
|
|
2315
2318
|
if (!state.bestCandidatePath) return false;
|
|
2316
2319
|
const normalizedBestCandidatePath = normalizeCandidatePath(state.bestCandidatePath);
|
|
@@ -2525,6 +2528,21 @@ var researchPhase = {
|
|
|
2525
2528
|
].join("\n");
|
|
2526
2529
|
},
|
|
2527
2530
|
interceptToolCall(toolName, _args, ctx) {
|
|
2531
|
+
if (ctx.state.isCreationTask && !isExternalTask(ctx.state)) {
|
|
2532
|
+
const isWriteLikeTool = toolName === "write_file" || toolName === "edit_file" || toolName === "restore_file_checkpoint";
|
|
2533
|
+
if (isWriteLikeTool) {
|
|
2534
|
+
const normalizedPathArg2 = typeof _args.path === "string" && _args.path.trim() ? ctx.normalizePath(String(_args.path)) : void 0;
|
|
2535
|
+
const normalizedPlanPath = ctx.state.planPath ? ctx.normalizePath(ctx.state.planPath) : void 0;
|
|
2536
|
+
if (normalizedPathArg2 && normalizedPlanPath && normalizedPathArg2 !== normalizedPlanPath) {
|
|
2537
|
+
return [
|
|
2538
|
+
`Blocked by marathon research guard: ${toolName} cannot create product files during the research phase.`,
|
|
2539
|
+
"Complete research first, then the system will advance you to planning.",
|
|
2540
|
+
`You may write the plan to "${normalizedPlanPath}" once research is complete.`
|
|
2541
|
+
].join(" ");
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
return void 0;
|
|
2545
|
+
}
|
|
2528
2546
|
if (!isExternalTask(ctx.state)) {
|
|
2529
2547
|
return void 0;
|
|
2530
2548
|
}
|
|
@@ -2627,7 +2645,7 @@ var researchPhase = {
|
|
|
2627
2645
|
},
|
|
2628
2646
|
canAcceptCompletion(state, trace) {
|
|
2629
2647
|
if (!isExternalTask(state)) {
|
|
2630
|
-
return
|
|
2648
|
+
return false;
|
|
2631
2649
|
}
|
|
2632
2650
|
return Boolean(state.planWritten || trace.planWritten);
|
|
2633
2651
|
}
|
|
@@ -2681,7 +2699,7 @@ var planningPhase = {
|
|
|
2681
2699
|
interceptToolCall(toolName, args, ctx) {
|
|
2682
2700
|
const normalizedPathArg = typeof args.path === "string" && args.path.trim() ? ctx.normalizePath(String(args.path)) : void 0;
|
|
2683
2701
|
const normalizedPlanPath = ctx.state.planPath ? ctx.normalizePath(ctx.state.planPath) : void 0;
|
|
2684
|
-
const isWriteLikeTool = toolName === "write_file" || toolName === "restore_file_checkpoint";
|
|
2702
|
+
const isWriteLikeTool = toolName === "write_file" || toolName === "edit_file" || toolName === "restore_file_checkpoint";
|
|
2685
2703
|
if (isWriteLikeTool && normalizedPathArg && normalizedPlanPath && normalizedPathArg !== normalizedPlanPath) {
|
|
2686
2704
|
return [
|
|
2687
2705
|
`Blocked by marathon planning guard: ${toolName} must target the exact plan path during planning.`,
|
|
@@ -2755,9 +2773,11 @@ var executionPhase = {
|
|
|
2755
2773
|
"Do not write the plan file first in execution. Make a real repo-file edit before you update the plan with progress.",
|
|
2756
2774
|
"Do not create scratch or test files to probe the repo or tool behavior.",
|
|
2757
2775
|
"write_file automatically checkpoints original repo files before overwriting them. If an edit regresses behavior, use restore_file_checkpoint on that file.",
|
|
2758
|
-
"
|
|
2776
|
+
"Use edit_file for targeted changes instead of rewriting the entire file with write_file. edit_file takes old_string and new_string to surgically replace specific code.",
|
|
2777
|
+
"Read the target file and edit it with edit_file (preferred) or write_file. Update the plan file with progress after completing real edits.",
|
|
2759
2778
|
"Before large edits, read any already discovered supporting source/style files that power the target so you preserve existing behavior.",
|
|
2760
|
-
"Prefer
|
|
2779
|
+
"Prefer edit_file for small changes. Only use write_file when creating new files or when the changes are so extensive that a full rewrite is simpler.",
|
|
2780
|
+
"After writing a file 2+ times, you MUST read it back to verify correctness before writing again.",
|
|
2761
2781
|
'Use run_check for real verification before TASK_COMPLETE. Good examples: "pnpm lint", "pnpm exec tsc --noEmit", "pnpm test", or a focused vitest/pytest command.',
|
|
2762
2782
|
"Broad discovery is only allowed if a read of the current target file fails."
|
|
2763
2783
|
];
|
|
@@ -2769,7 +2789,7 @@ var executionPhase = {
|
|
|
2769
2789
|
const normalizedPathArg = typeof args.path === "string" && args.path.trim() ? ctx.normalizePath(String(args.path)) : void 0;
|
|
2770
2790
|
const normalizedPlanPath = ctx.state.planPath ? ctx.normalizePath(ctx.state.planPath) : void 0;
|
|
2771
2791
|
const normalizedBestCandidatePath = ctx.state.bestCandidatePath ? ctx.normalizePath(ctx.state.bestCandidatePath) : void 0;
|
|
2772
|
-
const isWriteLikeTool = toolName === "write_file" || toolName === "restore_file_checkpoint";
|
|
2792
|
+
const isWriteLikeTool = toolName === "write_file" || toolName === "edit_file" || toolName === "restore_file_checkpoint";
|
|
2773
2793
|
if (normalizedBestCandidatePath && ctx.isDiscoveryTool(toolName) && !ctx.trace.bestCandidateReadFailed) {
|
|
2774
2794
|
return [
|
|
2775
2795
|
`Blocked by marathon execution guard: ${toolName} is disabled during execution.`,
|
|
@@ -2831,6 +2851,21 @@ var executionPhase = {
|
|
|
2831
2851
|
},
|
|
2832
2852
|
buildRecoveryMessage(state) {
|
|
2833
2853
|
const recent = state.sessions.slice(-2);
|
|
2854
|
+
if (recent.length >= 2 && recent.every(
|
|
2855
|
+
(session) => session.hadTextOutput === true && session.wroteFiles !== true
|
|
2856
|
+
)) {
|
|
2857
|
+
const noToolActions = recent.every(
|
|
2858
|
+
(session) => !session.wroteFiles && !session.verificationAttempted
|
|
2859
|
+
);
|
|
2860
|
+
if (noToolActions) {
|
|
2861
|
+
return [
|
|
2862
|
+
"Recovery instruction: You have been rejected from completing multiple times.",
|
|
2863
|
+
"The likely reason is that verification has not passed.",
|
|
2864
|
+
"Your next action must be run_check with a concrete command (e.g., syntax check, lint, or test).",
|
|
2865
|
+
"Do NOT output TASK_COMPLETE again until verification passes."
|
|
2866
|
+
].join("\n");
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2834
2869
|
if (recent.length >= 2 && recent.every(
|
|
2835
2870
|
(session) => session.verificationAttempted === true && session.wroteFiles !== true
|
|
2836
2871
|
)) {
|
|
@@ -2879,6 +2914,18 @@ var executionPhase = {
|
|
|
2879
2914
|
if (!ctx.trace.executionFileWritten && snapshot.consecutiveDiscoveryPauseCount >= 18) {
|
|
2880
2915
|
return "execution is looping on discovery instead of editing repo files and ending the turn";
|
|
2881
2916
|
}
|
|
2917
|
+
const writeKeys = snapshot.recentActionKeys.filter((k) => k.startsWith("write_file:"));
|
|
2918
|
+
if (writeKeys.length >= 4) {
|
|
2919
|
+
const uniqueWriteTargets = new Set(writeKeys.map((k) => k.split(":").slice(1).join(":")));
|
|
2920
|
+
if (uniqueWriteTargets.size === 1) {
|
|
2921
|
+
return `write_file called ${writeKeys.length} times on the same file \u2014 read the file and verify before continuing`;
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
for (const [filePath, count] of Object.entries(ctx.trace.writeCountByPath)) {
|
|
2925
|
+
if (count >= 4) {
|
|
2926
|
+
return `same file rewritten ${count} times without verification (${filePath}) \u2014 read the file and verify before continuing`;
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2882
2929
|
return void 0;
|
|
2883
2930
|
}
|
|
2884
2931
|
};
|
|
@@ -4815,7 +4862,8 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
4815
4862
|
verificationAttempted: false,
|
|
4816
4863
|
verificationPassed: false,
|
|
4817
4864
|
verificationBlocked: false,
|
|
4818
|
-
localToolLoopGuardTriggered: false
|
|
4865
|
+
localToolLoopGuardTriggered: false,
|
|
4866
|
+
writeCountByPath: {}
|
|
4819
4867
|
};
|
|
4820
4868
|
}
|
|
4821
4869
|
isDiscoveryLocalTool(toolName) {
|
|
@@ -5018,8 +5066,26 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
5018
5066
|
sessionTrace
|
|
5019
5067
|
);
|
|
5020
5068
|
}
|
|
5069
|
+
const phaseIndex = workflow.phases.findIndex((p) => p.name === state.workflowPhase);
|
|
5070
|
+
const executionPhaseIndex = workflow.phases.findIndex((p) => p.name === "execution");
|
|
5071
|
+
if (executionPhaseIndex >= 0 && phaseIndex < executionPhaseIndex) {
|
|
5072
|
+
return false;
|
|
5073
|
+
}
|
|
5021
5074
|
return true;
|
|
5022
5075
|
}
|
|
5076
|
+
computeCompletionRejectionReason(state, trace) {
|
|
5077
|
+
const reasons = [];
|
|
5078
|
+
if (!state.planWritten) {
|
|
5079
|
+
reasons.push("Plan file has not been written");
|
|
5080
|
+
}
|
|
5081
|
+
if (state.bestCandidatePath && !state.bestCandidateVerified && !trace.bestCandidateVerified) {
|
|
5082
|
+
reasons.push("Best candidate file has not been verified (read back after writing)");
|
|
5083
|
+
}
|
|
5084
|
+
if (state.verificationRequired && !state.lastVerificationPassed && !trace.verificationPassed) {
|
|
5085
|
+
reasons.push("Verification has not passed \u2014 run a verification command (run_check) before completing");
|
|
5086
|
+
}
|
|
5087
|
+
return reasons.length > 0 ? reasons.join("; ") : "Completion gates not satisfied for the current workflow phase";
|
|
5088
|
+
}
|
|
5023
5089
|
summarizeUnknownForTrace(value, maxLength = 180) {
|
|
5024
5090
|
const text = typeof value === "string" ? value : value === void 0 ? "" : JSON.stringify(value);
|
|
5025
5091
|
return text.replace(/\s+/g, " ").trim().slice(0, maxLength);
|
|
@@ -5333,7 +5399,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
5333
5399
|
const pathArg = typeof args.path === "string" && args.path.trim() ? ` path=${String(args.path)}` : "";
|
|
5334
5400
|
const queryArg = typeof args.query === "string" && args.query.trim() ? ` query="${String(args.query)}"` : "";
|
|
5335
5401
|
const patternArg = typeof args.pattern === "string" && args.pattern.trim() ? ` pattern="${String(args.pattern)}"` : "";
|
|
5336
|
-
const isWriteLikeTool = toolName === "write_file" || toolName === "restore_file_checkpoint";
|
|
5402
|
+
const isWriteLikeTool = toolName === "write_file" || toolName === "edit_file" || toolName === "restore_file_checkpoint";
|
|
5337
5403
|
const isVerificationTool = toolName === "run_check";
|
|
5338
5404
|
const currentPhase = workflow.phases.find((p) => p.name === state.workflowPhase);
|
|
5339
5405
|
if (currentPhase?.interceptToolCall) {
|
|
@@ -5388,8 +5454,10 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
5388
5454
|
);
|
|
5389
5455
|
throw error;
|
|
5390
5456
|
}
|
|
5391
|
-
|
|
5457
|
+
const writeResultIndicatesError = isWriteLikeTool && typeof result === "string" && result.startsWith("Error:");
|
|
5458
|
+
if (isWriteLikeTool && normalizedPathArg && !writeResultIndicatesError) {
|
|
5392
5459
|
trace.wroteFiles = true;
|
|
5460
|
+
trace.writeCountByPath[normalizedPathArg] = (trace.writeCountByPath[normalizedPathArg] || 0) + 1;
|
|
5393
5461
|
if (normalizedPlanPath && normalizedPathArg === normalizedPlanPath) {
|
|
5394
5462
|
trace.planWritten = true;
|
|
5395
5463
|
} else if (state.workflowPhase === "execution") {
|
|
@@ -5697,6 +5765,8 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
5697
5765
|
const maxCost = options.maxCost;
|
|
5698
5766
|
const useStream = options.stream ?? true;
|
|
5699
5767
|
const workflow = options.workflow ?? defaultWorkflow;
|
|
5768
|
+
const maxServerNetworkRetries = 3;
|
|
5769
|
+
let consecutiveServerNetworkErrors = 0;
|
|
5700
5770
|
const agent = await this.get(id);
|
|
5701
5771
|
const taskName = typeof options.trackProgress === "string" ? options.trackProgress : options.trackProgress ? `${agent.name} task` : "";
|
|
5702
5772
|
const resolvedTaskName = taskName || `${agent.name} task`;
|
|
@@ -6003,16 +6073,60 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6003
6073
|
if (state.sessions.length > 50) {
|
|
6004
6074
|
state.sessions = state.sessions.slice(-50);
|
|
6005
6075
|
}
|
|
6076
|
+
if (sessionResult.stopReason !== "error") {
|
|
6077
|
+
consecutiveServerNetworkErrors = 0;
|
|
6078
|
+
}
|
|
6006
6079
|
const detectedTaskCompletion = this.detectTaskCompletion(sessionResult.result);
|
|
6007
6080
|
const acceptedTaskCompletion = detectedTaskCompletion && this.canAcceptTaskCompletion(sessionResult.result, state, sessionTrace, workflow);
|
|
6081
|
+
if (detectedTaskCompletion && !acceptedTaskCompletion) {
|
|
6082
|
+
state.lastCompletionRejectionReason = this.computeCompletionRejectionReason(state, sessionTrace);
|
|
6083
|
+
if (state.verificationRequired && !state.lastVerificationPassed && !sessionTrace.verificationPassed && !sessionTrace.verificationAttempted) {
|
|
6084
|
+
state.consecutiveBlockedVerificationSessions = (state.consecutiveBlockedVerificationSessions || 0) + 1;
|
|
6085
|
+
if ((state.consecutiveBlockedVerificationSessions || 0) >= 2) {
|
|
6086
|
+
state.verificationRequired = false;
|
|
6087
|
+
state.lastVerificationPassed = true;
|
|
6088
|
+
if (!state.planWritten) {
|
|
6089
|
+
state.planWritten = true;
|
|
6090
|
+
}
|
|
6091
|
+
if (!state.bestCandidateVerified) {
|
|
6092
|
+
state.bestCandidateVerified = true;
|
|
6093
|
+
}
|
|
6094
|
+
}
|
|
6095
|
+
}
|
|
6096
|
+
} else {
|
|
6097
|
+
state.lastCompletionRejectionReason = void 0;
|
|
6098
|
+
}
|
|
6099
|
+
const sessionHadActions = sessionTrace.wroteFiles || sessionTrace.readFiles || sessionTrace.discoveryPerformed || sessionTrace.verificationAttempted;
|
|
6100
|
+
if (sessionHadActions) {
|
|
6101
|
+
state.consecutiveEmptySessions = 0;
|
|
6102
|
+
} else {
|
|
6103
|
+
state.consecutiveEmptySessions = (state.consecutiveEmptySessions || 0) + 1;
|
|
6104
|
+
}
|
|
6008
6105
|
if (sessionResult.stopReason === "complete" && !detectedTaskCompletion) {
|
|
6009
6106
|
state.status = "complete";
|
|
6010
6107
|
} else if (sessionResult.stopReason === "error") {
|
|
6011
|
-
|
|
6108
|
+
if (_AgentsEndpoint.isRetryableSessionError(sessionResult.error) && consecutiveServerNetworkErrors < maxServerNetworkRetries) {
|
|
6109
|
+
consecutiveServerNetworkErrors++;
|
|
6110
|
+
const delayMs = Math.min(
|
|
6111
|
+
5e3 * Math.pow(2, consecutiveServerNetworkErrors - 1),
|
|
6112
|
+
3e4
|
|
6113
|
+
);
|
|
6114
|
+
const delaySec = Math.round(delayMs / 1e3);
|
|
6115
|
+
await this.emitContextNotice(options.onContextNotice, {
|
|
6116
|
+
kind: "server_network_retry",
|
|
6117
|
+
sessionIndex: session,
|
|
6118
|
+
message: `Server network error: ${sessionResult.error}. Retrying in ${delaySec}s (attempt ${consecutiveServerNetworkErrors}/${maxServerNetworkRetries})...`
|
|
6119
|
+
});
|
|
6120
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
6121
|
+
} else {
|
|
6122
|
+
state.status = "error";
|
|
6123
|
+
}
|
|
6012
6124
|
} else if (sessionResult.stopReason === "max_cost") {
|
|
6013
6125
|
state.status = "budget_exceeded";
|
|
6014
6126
|
} else if (acceptedTaskCompletion) {
|
|
6015
6127
|
state.status = "complete";
|
|
6128
|
+
} else if ((state.consecutiveEmptySessions || 0) >= 3) {
|
|
6129
|
+
state.status = "stalled";
|
|
6016
6130
|
} else if (maxCost && state.totalCost >= maxCost) {
|
|
6017
6131
|
state.status = "budget_exceeded";
|
|
6018
6132
|
} else if (session + 1 >= maxSessions) {
|
|
@@ -6041,6 +6155,15 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
6041
6155
|
recordId
|
|
6042
6156
|
};
|
|
6043
6157
|
}
|
|
6158
|
+
/** Returns true if a server-side session error message indicates a transient
|
|
6159
|
+
* network failure that is safe to retry. */
|
|
6160
|
+
static isRetryableSessionError(errorMessage) {
|
|
6161
|
+
if (!errorMessage) return false;
|
|
6162
|
+
const lower = errorMessage.toLowerCase();
|
|
6163
|
+
return _AgentsEndpoint.RETRYABLE_SESSION_ERROR_PATTERNS.some(
|
|
6164
|
+
(pattern) => lower.includes(pattern)
|
|
6165
|
+
);
|
|
6166
|
+
}
|
|
6044
6167
|
/**
|
|
6045
6168
|
* Client-side fallback for detecting task completion in agent output.
|
|
6046
6169
|
* Mirrors the API's detectAutoComplete() for non-loop agents that return 'end_turn'.
|
|
@@ -6645,6 +6768,7 @@ Do NOT redo any of the above work.`
|
|
|
6645
6768
|
).join("\n");
|
|
6646
6769
|
if (state.messages && state.messages.length > 0) {
|
|
6647
6770
|
const recoveryMessage2 = this.buildStuckTurnRecoveryMessage(state, wf);
|
|
6771
|
+
const rejectionNotice = state.lastCompletionRejectionReason ? `TASK_COMPLETE was rejected because: ${state.lastCompletionRejectionReason}. Address this before signaling completion again.` : void 0;
|
|
6648
6772
|
const continuationContent = [
|
|
6649
6773
|
"Continue the task.",
|
|
6650
6774
|
phaseBlock,
|
|
@@ -6656,6 +6780,7 @@ Do NOT redo any of the above work.`
|
|
|
6656
6780
|
`Previous sessions:`,
|
|
6657
6781
|
progressSummary,
|
|
6658
6782
|
"",
|
|
6783
|
+
...rejectionNotice ? [rejectionNotice, ""] : [],
|
|
6659
6784
|
...recoveryMessage2 ? [recoveryMessage2, ""] : [],
|
|
6660
6785
|
"Do not redo previous work. If the task is already complete, respond with TASK_COMPLETE."
|
|
6661
6786
|
].join("\n");
|
|
@@ -6716,6 +6841,7 @@ Do NOT redo any of the above work.`
|
|
|
6716
6841
|
};
|
|
6717
6842
|
}
|
|
6718
6843
|
const recoveryMessage = this.buildStuckTurnRecoveryMessage(state, wf);
|
|
6844
|
+
const fallbackRejectionNotice = state.lastCompletionRejectionReason ? `TASK_COMPLETE was rejected because: ${state.lastCompletionRejectionReason}. Address this before signaling completion again.` : void 0;
|
|
6719
6845
|
const content = [
|
|
6720
6846
|
originalMessage,
|
|
6721
6847
|
phaseBlock,
|
|
@@ -6727,6 +6853,7 @@ Do NOT redo any of the above work.`
|
|
|
6727
6853
|
`Previous sessions:`,
|
|
6728
6854
|
progressSummary,
|
|
6729
6855
|
"",
|
|
6856
|
+
...fallbackRejectionNotice ? [fallbackRejectionNotice, ""] : [],
|
|
6730
6857
|
...recoveryMessage ? [recoveryMessage, ""] : [],
|
|
6731
6858
|
`Last output (do NOT repeat this \u2014 build on it):`,
|
|
6732
6859
|
state.lastOutput.slice(0, 1e3),
|
|
@@ -6788,6 +6915,24 @@ Do NOT redo any of the above work.`
|
|
|
6788
6915
|
};
|
|
6789
6916
|
_AgentsEndpoint.AUTO_COMPACT_SUMMARY_PREFIX = "You are continuing a long-running task. Here is a compact summary of prior work:";
|
|
6790
6917
|
_AgentsEndpoint.FORCED_COMPACT_SUMMARY_PREFIX = "You are continuing a previously completed task. Here is a summary of prior work:";
|
|
6918
|
+
/** Error message patterns from server-side sessions that indicate a transient network failure
|
|
6919
|
+
* (e.g. AI provider connection dropped). These are retried automatically. */
|
|
6920
|
+
_AgentsEndpoint.RETRYABLE_SESSION_ERROR_PATTERNS = [
|
|
6921
|
+
"network connection lost",
|
|
6922
|
+
"network error",
|
|
6923
|
+
"fetch failed",
|
|
6924
|
+
"connection reset",
|
|
6925
|
+
"connection refused",
|
|
6926
|
+
"connection closed",
|
|
6927
|
+
"socket hang up",
|
|
6928
|
+
"econnreset",
|
|
6929
|
+
"econnrefused",
|
|
6930
|
+
"econnaborted",
|
|
6931
|
+
"etimedout",
|
|
6932
|
+
"enetunreach",
|
|
6933
|
+
"enotfound",
|
|
6934
|
+
"request timeout"
|
|
6935
|
+
];
|
|
6791
6936
|
/** Stop phrases that indicate the agent considers its task complete. */
|
|
6792
6937
|
_AgentsEndpoint.STOP_PHRASES = [
|
|
6793
6938
|
"DONE:",
|