nolo-cli 0.164.0-alpha.5 → 0.165.0-alpha.1
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/{_executeModel-M5PGAD3Z.js → _executeModel-CNWZMBTW.js} +21 -21
- package/{accountResolver-55EDKEIK.js → accountResolver-JS7QDNNL.js} +1 -1
- package/{agentDeleteCommand-FNLCIWA7.js → agentDeleteCommand-XSMZJNQ6.js} +27 -27
- package/{agentEmailCommands-SBPLOOIY.js → agentEmailCommands-TCLCOLOI.js} +28 -28
- package/{agentListCommands-GOCGOQUB.js → agentListCommands-4I4FZVVV.js} +44 -21
- package/{agentMachineCommands-L7NY3BCY.js → agentMachineCommands-CAU6REHD.js} +14 -14
- package/{agentRecordCommands-GHQNXIVM.js → agentRecordCommands-NDSOSZES.js} +27 -27
- package/{agentRunCommand-2QU75CBD.js → agentRunCommand-E7OCABMM.js} +28 -28
- package/{agentRuntimeLocal-J6I63NZC.js → agentRuntimeLocal-BCZRYS5T.js} +11 -11
- package/{agentSlice-JOVX3KY3.js → agentSlice-2WTAYXEB.js} +1 -1
- package/{appDeleteCommands-KKLAK2UR.js → appDeleteCommands-CTBLT5TG.js} +16 -16
- package/{appDeployCommands-PXWK4FAX.js → appDeployCommands-IORMXV5D.js} +16 -16
- package/{appDeployStatusCommands-3NGWDZTX.js → appDeployStatusCommands-PWMDFYJ6.js} +16 -16
- package/{appGetCommands-APWYPEO3.js → appGetCommands-VG3LGNBO.js} +16 -16
- package/{appListCommands-OP7IRALO.js → appListCommands-GLIOZCTD.js} +16 -16
- package/{authCommand-3Z52KJID.js → authCommand-OVBMDPIF.js} +1 -1
- package/{chunk-ZU4J4GRW.js → chunk-3FDRNFCZ.js} +3 -3
- package/{chunk-5E5VB7PS.js → chunk-5N23SKBR.js} +10 -9
- package/{chunk-U34KT53V.js → chunk-6BNW7WC4.js} +1 -1
- package/{chunk-MLEANT7D.js → chunk-6HAE54KH.js} +2 -2
- package/{chunk-L2JMH4I5.js → chunk-6LYCXISC.js} +6 -3
- package/{chunk-QXZH5UDF.js → chunk-7NKZA46B.js} +2 -2
- package/{chunk-EFGBXVOC.js → chunk-ANI67WCB.js} +2 -2
- package/{chunk-QA2C5NKI.js → chunk-ASSNAASW.js} +1 -1
- package/{chunk-DE3RG4GV.js → chunk-BAAJVNIW.js} +2 -2
- package/{chunk-ZMVXHANW.js → chunk-BYGWUVRX.js} +1 -1
- package/{chunk-TDMS3H4D.js → chunk-D2RSMFM5.js} +3 -3
- package/{chunk-4L4K6YR7.js → chunk-DI7ZFGDQ.js} +1 -1
- package/{chunk-YVPQATSC.js → chunk-GPLUFN2E.js} +7 -1
- package/{chunk-Y2UYLA5L.js → chunk-H7GI62DA.js} +5 -5
- package/{chunk-F3SOW2EU.js → chunk-HEC32F3G.js} +1 -1
- package/{chunk-W7FGZRLK.js → chunk-I72LPLCP.js} +1 -1
- package/{chunk-2MWKM3NP.js → chunk-IQ37RGA5.js} +5 -5
- package/{chunk-GVGQKI6E.js → chunk-JGQTUD55.js} +85 -33
- package/chunk-JLR5NWP2.js +548 -0
- package/{chunk-ZZDVBZOP.js → chunk-K3NJW7LY.js} +6 -4
- package/{chunk-CNWKLQRL.js → chunk-KSTEXKL6.js} +70 -36
- package/{chunk-5IKRTRRR.js → chunk-MCGCC5BA.js} +1 -1
- package/{chunk-IPQ3W3CZ.js → chunk-NERECMOR.js} +10 -10
- package/{chunk-YTWGTCVW.js → chunk-NPTROADE.js} +14 -14
- package/{chunk-JGXBS3CI.js → chunk-PV3HYKQX.js} +8 -8
- package/{chunk-ZKBZLQTG.js → chunk-QG7BPUGN.js} +3 -3
- package/{chunk-3N5VQFR7.js → chunk-QKZV2CVE.js} +2 -2
- package/{chunk-6MXDOUMH.js → chunk-R4BMKAR5.js} +70 -8
- package/{chunk-RBMYJSZF.js → chunk-RVHXF55T.js} +2 -2
- package/{chunk-TT644UJD.js → chunk-SAZSXMTR.js} +1 -1
- package/{chunk-3M52COK5.js → chunk-SLAZGVZN.js} +71 -3
- package/{chunk-2AB2HA4M.js → chunk-TDX2L4W2.js} +8 -2
- package/{chunk-DJ2BOPJY.js → chunk-TQGP2LAX.js} +1 -1
- package/{chunk-OC72ZET2.js → chunk-U7LNNRZJ.js} +10 -10
- package/{chunk-647HBTHJ.js → chunk-VPHDNJWW.js} +2 -2
- package/{chunk-35CEDQD6.js → chunk-WYU4H7EV.js} +139 -29
- package/{chunk-N665S3Z2.js → chunk-XI677N45.js} +2 -2
- package/{chunk-WYJTNSVL.js → chunk-XKVWXU6D.js} +35 -4
- package/{chunk-ULQAD7ZY.js → chunk-YKTAUOS7.js} +1 -1
- package/{chunk-BL4HFN6L.js → chunk-YL26TH2V.js} +1 -1
- package/{chunk-4JCAW7TO.js → chunk-Z2LMCNOD.js} +2 -2
- package/{commandRegistry-6VNTR43G.js → commandRegistry-BJDH4622.js} +49 -49
- package/{contentThunks-7JLGMPNX.js → contentThunks-BV5O7L2Y.js} +5 -5
- package/{cooldownCommands-JFKTYS2D.js → cooldownCommands-NS63RGBO.js} +2 -2
- package/{createAgentAutomationAction-WSQ3VZ3X.js → createAgentAutomationAction-TBWN2KX2.js} +5 -5
- package/{createDialogAction-4SHMWQYD.js → createDialogAction-WPVWZ3VX.js} +6 -6
- package/{createPageAction-GHYKDASE.js → createPageAction-ZFEXCZLK.js} +6 -6
- package/{dialogCommands-3W6AIUXT.js → dialogCommands-M4H4OOEW.js} +15 -15
- package/{dialogSlice-YXRGO7UV.js → dialogSlice-KGVUUVND.js} +4 -4
- package/{docCreateCommands-KQHQNLRX.js → docCreateCommands-7A2RHGYU.js} +14 -14
- package/{docDeleteCommands-O3DWFX2W.js → docDeleteCommands-SWNITY6F.js} +15 -15
- package/{docReadCommands-2U2BUONC.js → docReadCommands-J3PXXPPB.js} +14 -14
- package/{docStore-2U6GZMDG.js → docStore-YS6GP4CJ.js} +1 -1
- package/{docUpdateCommands-MF3C52XI.js → docUpdateCommands-2PFIC67Z.js} +14 -14
- package/{handleSendMessageAction-SK6Q2N7Z.js → handleSendMessageAction-NCHW43LP.js} +24 -11
- package/index.js +4 -4
- package/{localRuntimeAdapter-IIGPBSU6.js → localRuntimeAdapter-4EQNCW4N.js} +27 -25
- package/{machineCommands-2SN3XNMT.js → machineCommands-AFXYNIRI.js} +26 -26
- package/{machineWsRunDispatch-DQE55BK5.js → machineWsRunDispatch-2VR24KZ2.js} +26 -26
- package/package.json +1 -1
- package/{readlineWorkspace-VM35JAR6.js → readlineWorkspace-5J2JEAGZ.js} +31 -31
- package/{runAgentClientLoop-FR7N5TID.js → runAgentClientLoop-ISO62FYI.js} +19 -19
- package/{spaceCommands-NDPGHDMD.js → spaceCommands-3GWTIOI2.js} +14 -14
- package/{streamAgentChatTurn-YHZNWDWS.js → streamAgentChatTurn-MPMB3V3Q.js} +23 -23
- package/{tools-AEPUZOZ2.js → tools-G6OMRLGU.js} +13 -13
- package/{tuiSummaryLlmCaller-FESHBDTT.js → tuiSummaryLlmCaller-FQOEF4IE.js} +3 -3
- package/{updateDialogTitleAction-QERIYNOM.js → updateDialogTitleAction-WDG2WGZJ.js} +5 -5
- package/{workloadLifecycle-6O6PMISX.js → workloadLifecycle-MZ2V5L43.js} +1 -1
- package/chunk-3MZAGMYY.js +0 -239
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
// packages/ai/tools/agent/quotaCircuitBreaker.ts
|
|
2
|
+
var QUOTA_ERROR_PATTERNS = [
|
|
3
|
+
/429/,
|
|
4
|
+
/quota/i,
|
|
5
|
+
/access_terminated_error/i,
|
|
6
|
+
/(?:weekly|monthly)\s*(?:\([^)]*\)\s*)?usage\s+limit/i,
|
|
7
|
+
/rate\s*limit/i,
|
|
8
|
+
/too\s*many\s*requests/i,
|
|
9
|
+
/额度/,
|
|
10
|
+
/上限/,
|
|
11
|
+
/用尽/,
|
|
12
|
+
/CliProviderQuotaError/i
|
|
13
|
+
];
|
|
14
|
+
function isCliProviderQuotaErrorShape(error) {
|
|
15
|
+
if (!error || typeof error !== "object") return false;
|
|
16
|
+
const e = error;
|
|
17
|
+
return e.name === "CliProviderQuotaError" || typeof e.message === "string" && e.message.startsWith("[QUOTA_LIMITED:");
|
|
18
|
+
}
|
|
19
|
+
function isQuotaExhaustedError(error) {
|
|
20
|
+
if (!error) return false;
|
|
21
|
+
if (isCliProviderQuotaErrorShape(error)) return true;
|
|
22
|
+
if (error instanceof Error) {
|
|
23
|
+
return QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(error.message));
|
|
24
|
+
}
|
|
25
|
+
if (typeof error === "string") {
|
|
26
|
+
return QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(error));
|
|
27
|
+
}
|
|
28
|
+
const maybeStatus = error.status;
|
|
29
|
+
const maybeStatusCode = error.statusCode;
|
|
30
|
+
const status = typeof maybeStatus === "number" ? maybeStatus : maybeStatusCode;
|
|
31
|
+
if (status === 429) return true;
|
|
32
|
+
if (status === 403) {
|
|
33
|
+
const message = extractMessage(error);
|
|
34
|
+
return QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(message));
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
function extractMessage(error) {
|
|
39
|
+
if (typeof error === "string") return error;
|
|
40
|
+
if (error instanceof Error) return error.message;
|
|
41
|
+
if (error && typeof error === "object") {
|
|
42
|
+
const m = error.message;
|
|
43
|
+
return typeof m === "string" ? m : "";
|
|
44
|
+
}
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
function parseResetsInMs(text) {
|
|
48
|
+
if (!text) return void 0;
|
|
49
|
+
const sanitized = text.replace(/\btrace[\s_-]?id\b[^)\n]*/gi, " ").replace(/\b[0-9a-f]{16,}\b/gi, " ");
|
|
50
|
+
const unitMs = (n, unit) => {
|
|
51
|
+
if (/^d/.test(unit)) return n * 24 * 3600 * 1e3;
|
|
52
|
+
if (/^h/.test(unit)) return n * 3600 * 1e3;
|
|
53
|
+
if (/^m/.test(unit)) return n * 60 * 1e3;
|
|
54
|
+
if (/^s/.test(unit)) return n * 1e3;
|
|
55
|
+
return NaN;
|
|
56
|
+
};
|
|
57
|
+
const re = /(\d+)\s*(d(?:ay|ays)?|h(?:r|rs|our|ours)?|m(?:in|ins|inute|inutes)?|s(?:ec|ecs|econd|econds)?)/gi;
|
|
58
|
+
const MAX_SINGLE_MATCH_MS = 7 * 24 * 3600 * 1e3;
|
|
59
|
+
let totalMs = 0;
|
|
60
|
+
let matched = false;
|
|
61
|
+
let m;
|
|
62
|
+
while ((m = re.exec(sanitized)) !== null) {
|
|
63
|
+
const ms = unitMs(Number(m[1]), m[2]);
|
|
64
|
+
if (!Number.isFinite(ms) || ms > MAX_SINGLE_MATCH_MS) continue;
|
|
65
|
+
totalMs += ms;
|
|
66
|
+
matched = true;
|
|
67
|
+
}
|
|
68
|
+
return matched ? totalMs : void 0;
|
|
69
|
+
}
|
|
70
|
+
var DEFAULT_QUOTA_BREAKER_MS = 6 * 3600 * 1e3;
|
|
71
|
+
var DEFAULT_AGENT_NOT_FOUND_BREAKER_MS = 15 * 60 * 1e3;
|
|
72
|
+
|
|
73
|
+
// packages/ai/agent/agentAvailabilityShared.ts
|
|
74
|
+
var DEFAULT_PROVIDER_RETRY_MS = 5 * 60 * 1e3;
|
|
75
|
+
var THIN_RATE_LIMIT_COOLDOWN_MS = 60 * 1e3;
|
|
76
|
+
var MAX_COOLDOWN_MS = 24 * 60 * 60 * 1e3;
|
|
77
|
+
function clampCooldownDeadline(at, now) {
|
|
78
|
+
const min = now;
|
|
79
|
+
const max = now + MAX_COOLDOWN_MS;
|
|
80
|
+
return Math.min(Math.max(at, min), max);
|
|
81
|
+
}
|
|
82
|
+
function shouldClearCooldownFromQuota(entry, quota, now) {
|
|
83
|
+
if (!(typeof entry.nextAvailableAt === "number" && entry.nextAvailableAt > now)) return false;
|
|
84
|
+
if (typeof entry.markedAt !== "number" || !Number.isFinite(entry.markedAt)) return false;
|
|
85
|
+
if (!quota || !(quota.observedAt > entry.markedAt)) return false;
|
|
86
|
+
const subscriptionWindows = quota.windows.filter((window) => window.scope === "5h" || window.scope === "7d");
|
|
87
|
+
if (subscriptionWindows.length === 0) return false;
|
|
88
|
+
if (quota.windows.some((window) => window.scope !== "5h" && window.scope !== "7d" && (window.remaining === 0 || typeof window.utilization === "number" && window.utilization >= 0.95))) return false;
|
|
89
|
+
return subscriptionWindows.every((window) => {
|
|
90
|
+
const hasUtilization = typeof window.utilization === "number";
|
|
91
|
+
const hasRemaining = typeof window.remaining === "number";
|
|
92
|
+
if (!hasUtilization && !hasRemaining) return false;
|
|
93
|
+
return (!hasUtilization || window.utilization < 0.95) && (!hasRemaining || window.remaining > 0);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function isAgentUnavailableNow(agent, now = Date.now()) {
|
|
97
|
+
const at = agent?.nextAvailableAt;
|
|
98
|
+
return typeof at === "number" && Number.isFinite(at) && at > now;
|
|
99
|
+
}
|
|
100
|
+
var QUOTA_SNAPSHOT_STALE_MS = 2 * 60 * 60 * 1e3;
|
|
101
|
+
function isAdmissibleQuotaSnapshot(quota, now = Date.now()) {
|
|
102
|
+
if (!quota || typeof quota !== "object") return false;
|
|
103
|
+
const observedAt = quota.observedAt;
|
|
104
|
+
if (typeof observedAt !== "number" || !Number.isFinite(observedAt)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
return now - observedAt <= QUOTA_SNAPSHOT_STALE_MS;
|
|
108
|
+
}
|
|
109
|
+
function resolveAgentAvailability(agent, now = Date.now()) {
|
|
110
|
+
const quota = agent?.quota;
|
|
111
|
+
const isAdmissible = isAdmissibleQuotaSnapshot(quota, now);
|
|
112
|
+
const hasObservedAt = Boolean(quota) && typeof quota?.observedAt === "number" && Number.isFinite(quota.observedAt);
|
|
113
|
+
const hasWindows = Boolean(
|
|
114
|
+
quota && Array.isArray(quota.windows) && quota.windows.length > 0
|
|
115
|
+
);
|
|
116
|
+
const hasValidQuota = isAdmissible && hasWindows;
|
|
117
|
+
if (hasValidQuota) {
|
|
118
|
+
let hasActiveRemainingZero = false;
|
|
119
|
+
let hasActiveUtilizationHigh = false;
|
|
120
|
+
let hasWindowResetPending = false;
|
|
121
|
+
let maxResetAt;
|
|
122
|
+
for (const w of quota.windows) {
|
|
123
|
+
const inspected = inspectQuotaWindowExhaustion(w, now);
|
|
124
|
+
if (!inspected) continue;
|
|
125
|
+
if (inspected.resetAt !== void 0 && inspected.resetAt > now) {
|
|
126
|
+
if (inspected.remainingZero) hasActiveRemainingZero = true;
|
|
127
|
+
if (inspected.utilizationHigh) hasActiveUtilizationHigh = true;
|
|
128
|
+
maxResetAt = maxResetAt !== void 0 ? Math.max(maxResetAt, inspected.resetAt) : inspected.resetAt;
|
|
129
|
+
} else {
|
|
130
|
+
hasWindowResetPending = true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (hasActiveRemainingZero || hasActiveUtilizationHigh) {
|
|
134
|
+
return {
|
|
135
|
+
status: "quota_exhausted",
|
|
136
|
+
reason: hasActiveRemainingZero ? "quota_remaining_zero" : "quota_utilization_high",
|
|
137
|
+
...maxResetAt !== void 0 ? { resetAt: maxResetAt } : {}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (hasWindowResetPending) {
|
|
141
|
+
return {
|
|
142
|
+
status: "unverified",
|
|
143
|
+
reason: "quota_window_reset"
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const isRateLimited = typeof agent?.nextAvailableAt === "number" && Number.isFinite(agent.nextAvailableAt) && agent.nextAvailableAt > now;
|
|
148
|
+
if (isRateLimited) {
|
|
149
|
+
return {
|
|
150
|
+
status: "rate_limited",
|
|
151
|
+
reason: "cooldown_active"
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (!hasObservedAt || !hasWindows) {
|
|
155
|
+
return {
|
|
156
|
+
status: "unverified",
|
|
157
|
+
reason: "no_quota_snapshot"
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (!isAdmissible) {
|
|
161
|
+
return {
|
|
162
|
+
status: "unverified",
|
|
163
|
+
reason: "stale_quota_snapshot"
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
status: "available",
|
|
168
|
+
reason: "quota_ok"
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function readRetryAfterTimestamp(body, now) {
|
|
172
|
+
if (!body || typeof body !== "object") return void 0;
|
|
173
|
+
const root = body;
|
|
174
|
+
const raw = root.retryAfter ?? root.retry_after ?? root["Retry-After"];
|
|
175
|
+
if (typeof raw === "number" && Number.isFinite(raw)) {
|
|
176
|
+
return raw > 1e12 ? raw : now + Math.max(0, raw) * 1e3;
|
|
177
|
+
}
|
|
178
|
+
if (typeof raw === "string") {
|
|
179
|
+
const seconds = Number(raw.trim());
|
|
180
|
+
if (Number.isFinite(seconds)) return now + Math.max(0, seconds) * 1e3;
|
|
181
|
+
const date = Date.parse(raw);
|
|
182
|
+
if (Number.isFinite(date)) return date;
|
|
183
|
+
}
|
|
184
|
+
return void 0;
|
|
185
|
+
}
|
|
186
|
+
function readResetTimestamp(body, now) {
|
|
187
|
+
if (!body || typeof body !== "object") return void 0;
|
|
188
|
+
const root = body;
|
|
189
|
+
const error = root.error && typeof root.error === "object" ? root.error : root;
|
|
190
|
+
if (Array.isArray(error.details)) {
|
|
191
|
+
for (const item of error.details) {
|
|
192
|
+
if (!item || typeof item !== "object") continue;
|
|
193
|
+
const retryDelay = item.retryDelay;
|
|
194
|
+
if (typeof retryDelay === "string") {
|
|
195
|
+
const ms = parseResetsInMs(retryDelay);
|
|
196
|
+
if (typeof ms === "number" && Number.isFinite(ms)) return now + ms;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const details = !Array.isArray(error.details) && error.details && typeof error.details === "object" ? error.details : void 0;
|
|
201
|
+
const raw = error.resets_at ?? error.resetsAt ?? details?.resets_at ?? details?.resetsAt;
|
|
202
|
+
if (typeof raw === "number" && Number.isFinite(raw)) {
|
|
203
|
+
return raw > 1e12 ? raw : raw * 1e3;
|
|
204
|
+
}
|
|
205
|
+
if (typeof raw === "string") {
|
|
206
|
+
const parsed = Date.parse(raw);
|
|
207
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
208
|
+
}
|
|
209
|
+
return void 0;
|
|
210
|
+
}
|
|
211
|
+
function parseResetAtText(value, now) {
|
|
212
|
+
const m = value.match(
|
|
213
|
+
/resets?\s+at\s+(\d{4}-\d{2}-\d{2}(?:[T ]\d{2}:\d{2}(?::\d{2})?(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)?)/i
|
|
214
|
+
);
|
|
215
|
+
if (!m?.[1]) return void 0;
|
|
216
|
+
const parsed = Date.parse(m[1]);
|
|
217
|
+
return Number.isFinite(parsed) && parsed > now ? parsed : void 0;
|
|
218
|
+
}
|
|
219
|
+
function matchesPeriodicUsageLimitText(text) {
|
|
220
|
+
return /(?:weekly|monthly)\s*(?:\([^)]*\)\s*)?usage\s+limit/i.test(text);
|
|
221
|
+
}
|
|
222
|
+
function isQuotaLimited403Body(body) {
|
|
223
|
+
const text = typeof body === "string" ? body : JSON.stringify(body ?? "");
|
|
224
|
+
return matchesPeriodicUsageLimitText(text) || /access_terminated_error/i.test(text) || /(?:quota|usage)\s+(?:is\s+)?(?:exhausted|depleted|used\s+up|reached)/i.test(text) || /(?:quota|usage).{0,40}\b(?:reset|resets)\s+at\b/i.test(text);
|
|
225
|
+
}
|
|
226
|
+
function parseExplicitAvailableAt(body, now, headers) {
|
|
227
|
+
const headerRetryAfter = headers && typeof headers.get === "function" ? headers.get("retry-after") : headers?.["retry-after"] ?? headers?.["Retry-After"];
|
|
228
|
+
const retryAfter = headerRetryAfter ? readRetryAfterTimestamp({ retryAfter: headerRetryAfter }, now) : readRetryAfterTimestamp(body, now);
|
|
229
|
+
if (retryAfter !== void 0 && retryAfter > now) {
|
|
230
|
+
return clampCooldownDeadline(retryAfter, now);
|
|
231
|
+
}
|
|
232
|
+
const absolute = readResetTimestamp(body, now);
|
|
233
|
+
if (absolute !== void 0 && absolute > now) {
|
|
234
|
+
return clampCooldownDeadline(absolute, now);
|
|
235
|
+
}
|
|
236
|
+
const text = typeof body === "string" ? body : JSON.stringify(body ?? "");
|
|
237
|
+
const absoluteFromText = parseResetAtText(text, now);
|
|
238
|
+
if (absoluteFromText !== void 0) {
|
|
239
|
+
return clampCooldownDeadline(absoluteFromText, now);
|
|
240
|
+
}
|
|
241
|
+
if (matchesPeriodicUsageLimitText(text)) {
|
|
242
|
+
return clampCooldownDeadline(now + MAX_COOLDOWN_MS, now);
|
|
243
|
+
}
|
|
244
|
+
const relativeMs = parseResetsInMs(text);
|
|
245
|
+
if (relativeMs !== void 0) {
|
|
246
|
+
return clampCooldownDeadline(now + relativeMs, now);
|
|
247
|
+
}
|
|
248
|
+
return void 0;
|
|
249
|
+
}
|
|
250
|
+
var QUOTA_EXHAUSTED_TEXT_RE = /insufficient[_ ]?quota|quota\s*(?:(?:is|has|been|was|now|fully|completely|already|entirely)\s+)*(?:limit\s+)?(?:exhausted|depleted|used\s*up|reached|exceeded)|usage\s*limit\s*(?:reached|exceeded|exhausted)|(?:\b(?:weekly|monthly|5-?hour|5h|7-?day|7d)\s*(?:\([^)]*\)\s*)?limit\s*(?:reached|exceeded|exhausted|depleted)\b)|(?:reached|exceeded)\s+your\s+.*?(?:usage\s+)?limit|exceeded\s*your\s*(?:current\s*)?quota|insufficient[_\s-]?(?:balance|credits?)|balance\s*(?:is\s*)?(?:insufficient|too\s*low)|(?:额度|配额|用量)(?:已|已经|也)?(?:用尽|耗尽|用完|超限|不足)|(?:已达|已达到|超出|超过)[^。;,\n]{0,12}(?:用量上限|配额上限|额度上限)|余额(?:不足|不够|已用尽|已耗尽)/i;
|
|
251
|
+
var NEGATED_QUOTA_TEXT_RE = /\b(?:not|no\s+longer|never|haven't|hasn't|isn't|aren't)\s+(?:(?:currently|really|actually|yet)\s+)?(?:quota\s+exhausted|limit\s+exhausted|exhausted|depleted|used\s*up|reached|exceeded|out\s+of\s+quota)\b/i;
|
|
252
|
+
var CAPACITY_SATURATED_TEXT_RE = /\b(?:is\s+at\s+capacity|at\s+capacity|capacity\s*(?:is\s*)?(?:saturated|exceeded|unavailable)|overloaded|over\s*capacity)\b/i;
|
|
253
|
+
var NEGATED_CAPACITY_TEXT_RE = /\b(?:not|no\s+longer|never)\s+(?:(?:currently|really|actually|yet)\s+)?(?:at\s+capacity|capacity\s*(?:is\s*)?(?:saturated|exceeded|unavailable)|overloaded|over\s*capacity)\b/i;
|
|
254
|
+
function isQuotaExhaustedText(body) {
|
|
255
|
+
const text = typeof body === "string" ? body : JSON.stringify(body ?? "");
|
|
256
|
+
if (!text) return false;
|
|
257
|
+
if (NEGATED_QUOTA_TEXT_RE.test(text)) return false;
|
|
258
|
+
return QUOTA_EXHAUSTED_TEXT_RE.test(text) || isQuotaLimited403Body(text);
|
|
259
|
+
}
|
|
260
|
+
function isCapacitySaturatedRateLimit(body, now, headers) {
|
|
261
|
+
if (parseExplicitAvailableAt(body, now, headers) !== void 0) return false;
|
|
262
|
+
const text = typeof body === "string" ? body : JSON.stringify(body ?? "");
|
|
263
|
+
if (!text) return false;
|
|
264
|
+
if (isQuotaExhaustedText(text)) return false;
|
|
265
|
+
if (NEGATED_CAPACITY_TEXT_RE.test(text)) return false;
|
|
266
|
+
return CAPACITY_SATURATED_TEXT_RE.test(text);
|
|
267
|
+
}
|
|
268
|
+
function resolveNextAvailableAt(body, now, headers) {
|
|
269
|
+
const parsed = parseExplicitAvailableAt(body, now, headers);
|
|
270
|
+
return parsed ?? clampCooldownDeadline(now + DEFAULT_PROVIDER_RETRY_MS, now);
|
|
271
|
+
}
|
|
272
|
+
function resolveAvailabilityAction(status, body, now, headers) {
|
|
273
|
+
if (status === 403 && isQuotaLimited403Body(body)) {
|
|
274
|
+
return { kind: "mark", nextAvailableAt: resolveNextAvailableAt(body, now, headers) };
|
|
275
|
+
}
|
|
276
|
+
if (status >= 200 && status < 300) return { kind: "clear" };
|
|
277
|
+
if (status === 429) {
|
|
278
|
+
if (isCapacitySaturatedRateLimit(body, now, headers)) {
|
|
279
|
+
return { kind: "mark", nextAvailableAt: now + THIN_RATE_LIMIT_COOLDOWN_MS };
|
|
280
|
+
}
|
|
281
|
+
return { kind: "mark", nextAvailableAt: resolveNextAvailableAt(body, now, headers) };
|
|
282
|
+
}
|
|
283
|
+
if (status >= 500) {
|
|
284
|
+
return { kind: "mark", nextAvailableAt: now + DEFAULT_PROVIDER_RETRY_MS };
|
|
285
|
+
}
|
|
286
|
+
return { kind: "noop" };
|
|
287
|
+
}
|
|
288
|
+
function mergeAvailabilityDeadline(currentDeadline, nextAvailableAt) {
|
|
289
|
+
return typeof currentDeadline === "number" && Number.isFinite(currentDeadline) ? Math.max(currentDeadline, nextAvailableAt) : nextAvailableAt;
|
|
290
|
+
}
|
|
291
|
+
var PROBE_INTERVAL_MS = 10 * 60 * 1e3;
|
|
292
|
+
function resolveCooldownGate(input, now) {
|
|
293
|
+
const nextAvailableAt = input.nextAvailableAt;
|
|
294
|
+
if (typeof nextAvailableAt !== "number" || !Number.isFinite(nextAvailableAt) || nextAvailableAt <= now) {
|
|
295
|
+
return "open";
|
|
296
|
+
}
|
|
297
|
+
const lastProbeAt = input.lastProbeAt;
|
|
298
|
+
if (typeof lastProbeAt !== "number" || !Number.isFinite(lastProbeAt)) {
|
|
299
|
+
return "probe";
|
|
300
|
+
}
|
|
301
|
+
return now - lastProbeAt >= PROBE_INTERVAL_MS ? "probe" : "blocked";
|
|
302
|
+
}
|
|
303
|
+
function isPublicOrSystemAgentRecord(agent) {
|
|
304
|
+
if (!agent || typeof agent !== "object") return false;
|
|
305
|
+
for (const keyField of ["agentKey", "key", "id", "dbKey", "privateKey"]) {
|
|
306
|
+
const rawKey = agent[keyField];
|
|
307
|
+
if (typeof rawKey === "string") {
|
|
308
|
+
const trimmed = rawKey.trim();
|
|
309
|
+
if (trimmed.startsWith("agent-pub-") || trimmed.startsWith("agent-system-")) {
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
function resolveAgentOwnerUserId(agent) {
|
|
317
|
+
if (!agent || typeof agent !== "object") return void 0;
|
|
318
|
+
if (isPublicOrSystemAgentRecord(agent)) {
|
|
319
|
+
return void 0;
|
|
320
|
+
}
|
|
321
|
+
for (const field of ["ownerUserId", "userId", "ownerId"]) {
|
|
322
|
+
const value = agent[field];
|
|
323
|
+
if (typeof value === "string") {
|
|
324
|
+
const trimmed = value.trim();
|
|
325
|
+
if (trimmed === "system" || trimmed === "pub") continue;
|
|
326
|
+
if (trimmed) return trimmed;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
for (const keyField of ["agentKey", "key", "id", "dbKey", "privateKey"]) {
|
|
330
|
+
const rawKey = agent[keyField];
|
|
331
|
+
if (typeof rawKey === "string") {
|
|
332
|
+
const trimmed = rawKey.trim();
|
|
333
|
+
if (trimmed.startsWith("agent-")) {
|
|
334
|
+
const m = /^agent-([^-]+)-.+$/.exec(trimmed);
|
|
335
|
+
if (m?.[1] && m[1] !== "pub" && m[1] !== "system") {
|
|
336
|
+
return m[1];
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return void 0;
|
|
342
|
+
}
|
|
343
|
+
function resolveCredentialCandidateKeys(key) {
|
|
344
|
+
if (!key) return [];
|
|
345
|
+
const trimmed = key.trim();
|
|
346
|
+
if (!trimmed) return [];
|
|
347
|
+
const candidates = [trimmed];
|
|
348
|
+
const atIndex = trimmed.lastIndexOf("@");
|
|
349
|
+
if (atIndex > 0) {
|
|
350
|
+
const legacyKey = trimmed.slice(0, atIndex).trim();
|
|
351
|
+
if (legacyKey && legacyKey !== trimmed) candidates.push(legacyKey);
|
|
352
|
+
}
|
|
353
|
+
return candidates;
|
|
354
|
+
}
|
|
355
|
+
function resolveCredentialKey(agent) {
|
|
356
|
+
if (!agent || typeof agent !== "object") return void 0;
|
|
357
|
+
if (isPublicOrSystemAgentRecord(agent)) return void 0;
|
|
358
|
+
let rawRef;
|
|
359
|
+
for (const field of ["apiKeyRef", "credentialRef"]) {
|
|
360
|
+
const value = agent[field];
|
|
361
|
+
if (typeof value === "string") {
|
|
362
|
+
const trimmed = value.trim();
|
|
363
|
+
if (trimmed) {
|
|
364
|
+
rawRef = trimmed;
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (!rawRef) return void 0;
|
|
370
|
+
if (rawRef.includes("@")) return rawRef;
|
|
371
|
+
const owner = resolveAgentOwnerUserId(agent);
|
|
372
|
+
return owner ? `${rawRef}@${owner}` : rawRef;
|
|
373
|
+
}
|
|
374
|
+
function resolveCredentialKeyWithFallback(agent) {
|
|
375
|
+
if (isPublicOrSystemAgentRecord(agent)) return void 0;
|
|
376
|
+
const byRef = resolveCredentialKey(agent);
|
|
377
|
+
if (byRef) return byRef;
|
|
378
|
+
if (!agent || typeof agent !== "object") return void 0;
|
|
379
|
+
const endpoint = agent.customProviderUrl;
|
|
380
|
+
if (typeof endpoint === "string") {
|
|
381
|
+
const trimmed = endpoint.trim();
|
|
382
|
+
if (trimmed) {
|
|
383
|
+
try {
|
|
384
|
+
const origin = new URL(trimmed).origin;
|
|
385
|
+
if (origin && origin !== "null") return `custom-endpoint:${origin}`;
|
|
386
|
+
} catch {
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
const key = agent.key;
|
|
391
|
+
if (typeof key === "string" && key.trim()) return `custom-agent:${key.trim()}`;
|
|
392
|
+
return void 0;
|
|
393
|
+
}
|
|
394
|
+
var AUTH_ERROR_TEXT_RE = /\b(?:unauthorized|unauthenticated|authentication_error|invalid_api_key|invalid_token|bad_api_key|access_denied)\b/i;
|
|
395
|
+
var BALANCE_ERROR_TEXT_RE = /\b(?:insufficient_balance|wallet balance|coding_plan_exhausted|payment_required|arrears)\b|余额不足|额度已用尽且钱包|充值/i;
|
|
396
|
+
var TEXT_5H_WINDOW_RE = /\b(?:5h|5-hour|5\s*hours?|5\s*hrs?)\b/i;
|
|
397
|
+
var TEXT_WEEKLY_WINDOW_RE = /\b(?:weekly|monthly|7d|7-day|7\s*days?|30-day|month(?:ly)?|week(?:ly)?)\b/i;
|
|
398
|
+
function inspectQuotaWindowExhaustion(window, now) {
|
|
399
|
+
if (!window || typeof window !== "object") return void 0;
|
|
400
|
+
const w = window;
|
|
401
|
+
const scope = typeof w.scope === "string" ? w.scope.toLowerCase() : "";
|
|
402
|
+
const windowSeconds = typeof w.limit_window_seconds === "number" ? w.limit_window_seconds : typeof w.window_seconds === "number" ? w.window_seconds : void 0;
|
|
403
|
+
const usedPercent = typeof w.used_percent === "number" ? w.used_percent : typeof w.utilization === "number" ? w.utilization * 100 : void 0;
|
|
404
|
+
const remaining = typeof w.remaining === "number" ? w.remaining : void 0;
|
|
405
|
+
const isZero = remaining === 0;
|
|
406
|
+
const isHigh = typeof usedPercent === "number" && Number.isFinite(usedPercent) && usedPercent >= 95;
|
|
407
|
+
if (!isZero && !isHigh) return void 0;
|
|
408
|
+
let scopeType = "limit";
|
|
409
|
+
if (scope === "5h" || scope.includes("5h") || scope.includes("5-hour") || windowSeconds === 18e3) {
|
|
410
|
+
scopeType = "5h";
|
|
411
|
+
} else if (scope === "7d" || scope === "weekly" || scope === "monthly" || scope.includes("7d") || scope.includes("week") || scope.includes("month") || windowSeconds === 604800 || windowSeconds === 2592e3) {
|
|
412
|
+
scopeType = "weekly";
|
|
413
|
+
}
|
|
414
|
+
let resetAt;
|
|
415
|
+
if (typeof w.resetAt === "number" && Number.isFinite(w.resetAt)) {
|
|
416
|
+
resetAt = w.resetAt;
|
|
417
|
+
} else if (typeof w.reset_at === "number" && Number.isFinite(w.reset_at)) {
|
|
418
|
+
resetAt = w.reset_at >= 1e12 ? w.reset_at : w.reset_at * 1e3;
|
|
419
|
+
} else if (typeof w.resets_at === "number" && Number.isFinite(w.resets_at)) {
|
|
420
|
+
resetAt = w.resets_at >= 1e12 ? w.resets_at : w.resets_at * 1e3;
|
|
421
|
+
}
|
|
422
|
+
const hasResetAt = typeof resetAt === "number" && Number.isFinite(resetAt);
|
|
423
|
+
if (hasResetAt && resetAt <= now) {
|
|
424
|
+
return {
|
|
425
|
+
isExhausted: true,
|
|
426
|
+
isActive: false,
|
|
427
|
+
isResetPending: true,
|
|
428
|
+
scopeType,
|
|
429
|
+
resetAt,
|
|
430
|
+
remainingZero: isZero,
|
|
431
|
+
utilizationHigh: isHigh
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
if (hasResetAt && resetAt > now) {
|
|
435
|
+
return {
|
|
436
|
+
isExhausted: true,
|
|
437
|
+
isActive: true,
|
|
438
|
+
isResetPending: false,
|
|
439
|
+
scopeType,
|
|
440
|
+
resetAt,
|
|
441
|
+
remainingZero: isZero,
|
|
442
|
+
utilizationHigh: isHigh
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
return {
|
|
446
|
+
isExhausted: true,
|
|
447
|
+
isActive: true,
|
|
448
|
+
isResetPending: true,
|
|
449
|
+
scopeType,
|
|
450
|
+
remainingZero: isZero,
|
|
451
|
+
utilizationHigh: isHigh
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
function resolveWindowFromQuotaSnapshot(quota, now = Date.now()) {
|
|
455
|
+
if (!isAdmissibleQuotaSnapshot(quota, now)) return void 0;
|
|
456
|
+
const q = quota;
|
|
457
|
+
const rateLimitRoot = q.rate_limit && typeof q.rate_limit === "object" ? q.rate_limit : q;
|
|
458
|
+
for (const winKey of ["primary_window", "secondary_window"]) {
|
|
459
|
+
const inspected = inspectQuotaWindowExhaustion(rateLimitRoot[winKey], now);
|
|
460
|
+
if (inspected?.isActive && inspected.scopeType !== "limit") return inspected.scopeType;
|
|
461
|
+
}
|
|
462
|
+
if (Array.isArray(q.windows)) {
|
|
463
|
+
let hasLimit = false;
|
|
464
|
+
for (const win of q.windows) {
|
|
465
|
+
const inspected = inspectQuotaWindowExhaustion(win, now);
|
|
466
|
+
if (inspected?.isActive) {
|
|
467
|
+
if (inspected.scopeType === "5h" || inspected.scopeType === "weekly") return inspected.scopeType;
|
|
468
|
+
if (inspected.scopeType === "limit") hasLimit = true;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (hasLimit) return "limit";
|
|
472
|
+
}
|
|
473
|
+
for (const winKey of ["primary_window", "secondary_window"]) {
|
|
474
|
+
const inspected = inspectQuotaWindowExhaustion(rateLimitRoot[winKey], now);
|
|
475
|
+
if (inspected?.isActive && inspected.scopeType === "limit") {
|
|
476
|
+
return "limit";
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return void 0;
|
|
480
|
+
}
|
|
481
|
+
function classifyFailureSubclass(input, now = Date.now()) {
|
|
482
|
+
let status;
|
|
483
|
+
let rawMessage = "";
|
|
484
|
+
let body;
|
|
485
|
+
let headers;
|
|
486
|
+
let quota;
|
|
487
|
+
if (typeof input === "string") {
|
|
488
|
+
rawMessage = input;
|
|
489
|
+
} else if (input && typeof input === "object") {
|
|
490
|
+
const rec = input;
|
|
491
|
+
status = typeof rec.status === "number" ? rec.status : typeof rec.statusCode === "number" ? rec.statusCode : void 0;
|
|
492
|
+
rawMessage = typeof rec.message === "string" ? rec.message : typeof rec.message === "string" ? rec.message : "";
|
|
493
|
+
body = rec.body ?? ("status" in rec || "message" in rec ? void 0 : input);
|
|
494
|
+
headers = rec.headers;
|
|
495
|
+
quota = rec.quota;
|
|
496
|
+
}
|
|
497
|
+
const bodyText = typeof body === "string" ? body : JSON.stringify(body ?? "");
|
|
498
|
+
const fullText = `${rawMessage} ${bodyText}`.trim();
|
|
499
|
+
if (status === 401) return "auth";
|
|
500
|
+
if (status === 402) return "balance";
|
|
501
|
+
if (status === 403 && !isQuotaLimited403Body(fullText)) return "auth";
|
|
502
|
+
if (AUTH_ERROR_TEXT_RE.test(fullText) && !isQuotaExhaustedText(fullText) && !BALANCE_ERROR_TEXT_RE.test(fullText)) {
|
|
503
|
+
return "auth";
|
|
504
|
+
}
|
|
505
|
+
if (BALANCE_ERROR_TEXT_RE.test(fullText)) {
|
|
506
|
+
return "balance";
|
|
507
|
+
}
|
|
508
|
+
const targetForCapacity = typeof body === "object" && body !== null ? { ...body, rawMessage, message: fullText } : fullText;
|
|
509
|
+
if (isCapacitySaturatedRateLimit(targetForCapacity, now, headers)) {
|
|
510
|
+
return "capacity";
|
|
511
|
+
}
|
|
512
|
+
const quotaWindowFromSnapshot = resolveWindowFromQuotaSnapshot(quota, now) ?? resolveWindowFromQuotaSnapshot(body, now);
|
|
513
|
+
const hasConfirmedQuotaExhaustion = quotaWindowFromSnapshot !== void 0 || status === 403 && isQuotaLimited403Body(fullText) && !NEGATED_QUOTA_TEXT_RE.test(fullText) || isQuotaExhaustedText(fullText);
|
|
514
|
+
if (hasConfirmedQuotaExhaustion) {
|
|
515
|
+
if (quotaWindowFromSnapshot === "5h" || !NEGATED_QUOTA_TEXT_RE.test(fullText) && TEXT_5H_WINDOW_RE.test(fullText)) {
|
|
516
|
+
return "quota_5h";
|
|
517
|
+
}
|
|
518
|
+
if (quotaWindowFromSnapshot === "weekly" || !NEGATED_QUOTA_TEXT_RE.test(fullText) && TEXT_WEEKLY_WINDOW_RE.test(fullText)) {
|
|
519
|
+
return "quota_weekly";
|
|
520
|
+
}
|
|
521
|
+
return "quota_limit";
|
|
522
|
+
}
|
|
523
|
+
const isRateLimitLike = status === 429 || /\b(?:rate.?limit|too many requests|throttl(?:ed|ing)|resource_exhausted)\b/i.test(
|
|
524
|
+
fullText
|
|
525
|
+
);
|
|
526
|
+
if (isRateLimitLike) {
|
|
527
|
+
return "rate_limit";
|
|
528
|
+
}
|
|
529
|
+
return "unknown";
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export {
|
|
533
|
+
QUOTA_ERROR_PATTERNS,
|
|
534
|
+
isQuotaExhaustedError,
|
|
535
|
+
DEFAULT_PROVIDER_RETRY_MS,
|
|
536
|
+
shouldClearCooldownFromQuota,
|
|
537
|
+
isAgentUnavailableNow,
|
|
538
|
+
resolveAgentAvailability,
|
|
539
|
+
isQuotaExhaustedText,
|
|
540
|
+
isCapacitySaturatedRateLimit,
|
|
541
|
+
resolveAvailabilityAction,
|
|
542
|
+
mergeAvailabilityDeadline,
|
|
543
|
+
PROBE_INTERVAL_MS,
|
|
544
|
+
resolveCooldownGate,
|
|
545
|
+
resolveCredentialCandidateKeys,
|
|
546
|
+
resolveCredentialKeyWithFallback,
|
|
547
|
+
classifyFailureSubclass
|
|
548
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AGENT_SELECTION_PRIORITY_INSTRUCTIONS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SLAZGVZN.js";
|
|
4
4
|
import {
|
|
5
5
|
canonicalizeToolNames
|
|
6
6
|
} from "./chunk-5EBLANFT.js";
|
|
@@ -106,10 +106,12 @@ var CREDENTIAL_HYGIENE_RULE = `--- \u51ED\u636E\u7EAA\u5F8B ---
|
|
|
106
106
|
var PARALLEL_DISPATCH_DEFAULT_RULE = [
|
|
107
107
|
"\u3010\u5E76\u884C\u662F\u9ED8\u8BA4 \xB7 \u6D3E\u53D1\u7EAA\u5F8B\u3011",
|
|
108
108
|
"\u9ED8\u8BA4\u5E76\u884C\uFF0C\u4E0D\u662F\u9ED8\u8BA4\u4E32\u884C\uFF1A\u51E1\u65E0\u6587\u4EF6\u4EA4\u96C6\u3001\u65E0\u771F\u5B9E\u6570\u636E\u4F9D\u8D56\u7684\u72EC\u7ACB\u5DE5\u4F5C\uFF08\u591A\u4EFD\u72EC\u7ACB brief\u3001\u591A\u4E2A\u72EC\u7ACB\u63A2\u67E5/\u68C0\u7D22\u3001\u591A\u5904\u72EC\u7ACB\u6587\u4EF6\u6539\u52A8\uFF09\uFF0C\u5FC5\u987B\u5728**\u540C\u4E00\u8F6E tool_call \u91CC\u4E00\u6B21\u6027\u5E76\u53D1\u6D3E\u53D1**\uFF0C\u4E0D\u8981\u4E00\u4E2A\u63A5\u4E00\u4E2A\u7B49\u7ED3\u679C\u3002\u5224\u636E\u662F\u300C\u4F9D\u8D56\u5757\u662F\u5426\u4E3A\u7A7A\u300D\uFF0C\u4E0D\u662F\u300C\u4E3B\u7EBF\u662F\u5426\u5B8C\u6210\u300D\u3002",
|
|
109
|
-
"\
|
|
110
|
-
"\u7981\u6B62\u7528\
|
|
109
|
+
"\u6D3E\u53D1\u524D\u9010\u5BF9\u6838\u5BF9\u4EFB\u52A1\uFF0C\u5217\u51FA\u4F9D\u8D56\u5757\uFF1A\u524D\u7F6E\u4EFB\u52A1 \u2192 \u540E\u7F6E\u4EFB\u52A1\u3001\u4F9D\u8D56\u7C7B\u522B\u3001\u5177\u4F53\u4F9D\u8D56\u9879\uFF1B\u4F9D\u8D56\u5757\u4E3A\u7A7A\u7684\u4EFB\u52A1\u7EC4\u6210\u5E76\u53D1\u7EC4\uFF0C\u5728\u540C\u4E00\u8F6E\u4E00\u6B21\u6027\u6D3E\u53D1\uFF0C\u4E0D\u7B49\u5176\u4ED6\u7EC4\u5B8C\u6210\u3002\u53EA\u4E32\u884C\u5316\u6709\u4F9D\u8D56\u7684\u90A3\u6761\u8DEF\u5F84\uFF0C\u4E0D\u628A\u5C40\u90E8\u4F9D\u8D56\u6269\u5927\u6210\u6574\u6279\u7B49\u5F85\u3002",
|
|
110
|
+
"\u7981\u6B62\u8BE2\u95EE\u7528\u6237\u300C\u5148\u505A\u54EA\u4E2A\u300D\u300C\u8981\u4E0D\u8981\u5E76\u53D1\u300D\u300C\u5148\u505A A \u8FD8\u662F B\u300D\uFF1A\u5BF9\u5DF2\u83B7\u6388\u6743\u3001\u76EE\u6807\u660E\u786E\u7684\u72EC\u7ACB\u4EFB\u52A1\uFF0C\u8FD9\u4E9B\u95EE\u9898\u662F\u5728\u628A\u672C\u8BE5\u7F16\u6392\u8005\u505A\u7684\u5224\u65AD\u63A8\u7ED9\u7528\u6237\uFF0C\u5FC5\u987B\u81EA\u884C\u5224\u5B9A\u5E76\u53D1\uFF0C\u4E0D\u7B49\u5F85\u7528\u6237\u518D\u6B21\u8BB8\u53EF\u3002\u53EA\u6709\u76EE\u6807\u53D6\u820D\u3001\u8D39\u7528\u3001\u6743\u9650\u6216\u4E0D\u53EF\u9006\u540E\u679C\u786E\u9700\u7528\u6237\u51B3\u5B9A\u65F6\u624D\u8BE2\u95EE\uFF0C\u4E0D\u5F97\u501F\u6B64\u628A\u72EC\u7ACB\u4EFB\u52A1\u7684\u6392\u5E8F\u9000\u56DE\u7ED9\u7528\u6237\u3002",
|
|
111
|
+
"\u53EA\u6709\u771F\u5B9E\u4F9D\u8D56\u624D\u5141\u8BB8\u4E32\u884C\uFF0C\u4E14\u5FC5\u987B\u80FD\u6307\u540D\u5177\u4F53\u4F9D\u8D56\u9879\uFF08\u4E0B\u9762\u56DB\u8005\u4E4B\u4E00\uFF09\uFF1A\u2460 \u6587\u4EF6\u51B2\u7A81\uFF08\u5199\u51B2\u7A81\uFF1A\u5E76\u884C\u4FEE\u6539\u540C\u4E00\u6587\u4EF6\uFF0C\u987B\u6307\u51FA\u6587\u4EF6\u8DEF\u5F84\uFF1B\u4EC5\u5171\u540C\u8BFB\u53D6\u540C\u4E00\u6587\u4EF6\u4E0D\u6784\u6210\u51B2\u7A81\uFF09\uFF1B\u2461 \u63A5\u53E3\u5951\u7EA6\u4F9D\u8D56\uFF08\u987B\u6307\u51FA\u63A5\u53E3\u540D\u6216 schema\uFF0C\u4EE5\u53CA\u5C1A\u672A\u786E\u5B9A\u3001\u4F1A\u5F71\u54CD\u53E6\u4E00\u4EFB\u52A1\u7684\u5951\u7EA6\uFF1B\u4EC5\u4F7F\u7528\u540C\u4E00\u7A33\u5B9A\u63A5\u53E3\u4E0D\u6784\u6210\u4F9D\u8D56\uFF09\uFF1B\u2462 \u51ED\u8BC1\u6216\u914D\u989D\u51C6\u5165\u51B2\u7A81\uFF08\u987B\u6307\u51FA\u51ED\u8BC1\u6216\u914D\u989D\u540D\u79F0\u3001\u4E0A\u6E38 429 \u51B7\u5374\u3001\u72EC\u5360\u8D44\u6E90\u6216\u9501\uFF0C\u4EE5\u53CA\u5B9E\u9645\u4E92\u65A5\u6216\u9650\u9891\u7EA6\u675F\uFF1B\u4EC5\u5171\u4EAB\u51ED\u8BC1\u4E0D\u6784\u6210\u51C6\u5165\u51B2\u7A81\uFF0C\u4E0D\u5F97\u56DE\u663E\u51ED\u636E\u503C\uFF09\uFF1B\u2463 \u4FE1\u606F\u4F9D\u8D56\uFF08\u987B\u6307\u51FA\u524D\u7F6E\u4EFB\u52A1\u5C1A\u672A\u4EA7\u51FA\u7684\u5177\u4F53\u7ED3\u679C\uFF0C\u4EE5\u53CA\u540E\u7F6E\u4EFB\u52A1\u5982\u4F55\u4EE5\u5B83\u4E3A\u8F93\u5165\uFF09\u3002\u6307\u4E0D\u51FA\u4E0A\u9762\u4EFB\u4F55\u4E00\u9879\uFF0C\u5C31\u5FC5\u987B\u5E76\u884C\u3002",
|
|
112
|
+
"\u7981\u6B62\u7528\u8FD9\u4E9B\u7406\u7531\u4E32\u884C\uFF1A\u300C\u7B49\u540C\u4E00\u6761\u901A\u9053\u7A7A\u95F2\u300D\u300C\u7B49\u540C\u4E00\u4E2A agent \u7A7A\u95F2\u300D\u300C\u7B49\u4E3B\u7EBF/\u524D\u4E00\u4E2A\u4EFB\u52A1\u5B8C\u6210\u300D\u300C\u7B49\u524D\u4E00\u4E2A\u505A\u5B8C\u300D\u300C\u7B49\u67D0\u4E2A HIGH \u4FEE\u5B8C\u300D\u300C\u7B49\u4E0A\u4E0B\u6587\u4E0D\u6DF7\u300D\u300C\u907F\u514D\u4E0A\u4E0B\u6587\u6DF7\u300D\u300C\u5E76\u884C\u534F\u8C03\u6210\u672C\u9AD8\u300D\u2014\u2014\u540C\u4E00\u4E2A\u6267\u884C\u901A\u9053\u5141\u8BB8\u5E76\u53D1 fork\uFF0Crun \u5B9E\u4F8B\u4E4B\u95F4\u65E0\u4E0A\u4E0B\u6587\u5171\u4EAB\uFF1B\u4E00\u4E2A HIGH \u53EA\u963B\u585E\u5B83\u6240\u5728\u7684\u90A3\u6761\u8DEF\u5F84\uFF0C\u4E0D\u963B\u585E\u65E0\u5173\u5DE5\u4F5C\u3002 \u4E5F\u4E0D\u8981\u65B0\u589E\u300C\u5355\u98DE\u884C\u961F\u5217 / \u540C agent \u590D\u7528\u9501\u300D\u8FD9\u7C7B\u4EE5\u4E32\u884C\u4E3A\u524D\u63D0\u7684\u6267\u884C\u901A\u9053\u5047\u8BBE\u6765\u6362\u300C\u4FDD\u5B88\u300D\u3002",
|
|
111
113
|
"\u4E0E\u9879\u76EE\u89C4\u5219\u6216 skill \u51B2\u7A81\u65F6\uFF0C\u9ED8\u8BA4\u5148\u5E76\u884C\u3001\u518D\u56DE\u9000\uFF1A\u4EFB\u4F55\u300C\u5148 A \u518D B\u300D\u7684\u987A\u5E8F\u8981\u6C42\uFF0C\u53EA\u6709\u5728\u80FD\u6307\u540D\u5177\u4F53\u4F9D\u8D56\u9879\uFF08\u54EA\u4E2A\u6587\u4EF6\u3001\u54EA\u4EFD\u5951\u7EA6\u3001\u54EA\u4EFD\u51ED\u8BC1\u3001\u54EA\u6761\u4E0A\u6E38\uFF09\u65F6\u624D\u6210\u7ACB\uFF1B\u5426\u5219\u6309\u5E76\u884C\u6267\u884C\uFF0C\u5E76\u628A\u8BE5\u51B2\u7A81\u5982\u5B9E\u544A\u8BC9\u7528\u6237\uFF0C\u4E0D\u5F97\u628A\u987A\u5E8F\u5047\u8BBE\u5F53\u9ED8\u8BA4\u3002",
|
|
112
|
-
"\u6D3E\u53D1\u65F6\u5728\u56DE\u590D\u91CC\u5199\u51FA\u300C\u5E76\u53D1\u7EC4 / \u4E32\u884C\u7406\u7531\u300D\
|
|
114
|
+
"\u6D3E\u53D1\u65F6\u5728\u56DE\u590D\u91CC\u5199\u51FA\u300C\u5E76\u53D1\u7EC4 / \u4E32\u884C\u7406\u7531\u300D\uFF1A\u5E76\u53D1\u7EC4\u5217\u51FA\u540C\u8F6E\u6D3E\u53D1\u7684\u4EFB\u52A1\uFF1B\u4E32\u884C\u7406\u7531\u5FC5\u987B\u5199\u660E\u524D\u7F6E\u4EFB\u52A1 \u2192 \u540E\u7F6E\u4EFB\u52A1\u3001\u4F9D\u636E\u4E0A\u8FF0\u54EA\u6761\u4F9D\u8D56\u3001\u5177\u4F53\u6587\u4EF6 / \u63A5\u53E3\u5951\u7EA6 / \u51C6\u5165\u7EA6\u675F / \u8F93\u5165\u7ED3\u679C\uFF0C\u4EE5\u53CA\u4F55\u65F6\u89E3\u9664\u4F9D\u8D56\u3002\u65E0\u6CD5\u586B\u51FA\u5177\u4F53\u4F9D\u8D56\u9879\uFF0C\u5C31\u4E0D\u5F97\u4E32\u884C\uFF0C\u6539\u4E3A\u540C\u8F6E\u5E76\u53D1\u3002"
|
|
113
115
|
].join("\n");
|
|
114
116
|
|
|
115
117
|
// packages/agent-runtime/dispatchBackendPolicy.ts
|