























@@ -40,6 +40,9 @@ const STUCK_RUN_MS = 2 * 60 * 60 * 1000;
4040const STAGGER_OFFSET_CACHE_MAX = 4096;
4141const staggerOffsetCache = new Map<string, number>();
424243+type CronAgentTurnPayload = Extract<CronPayload, { kind: "agentTurn" }>;
44+type CronAgentTurnPayloadPatch = Extract<CronPayloadPatch, { kind: "agentTurn" }>;
45+4346/** Default retry delays applied after consecutive cron execution errors. */
4447export const DEFAULT_ERROR_BACKOFF_SCHEDULE_MS = [
454830_000,
@@ -897,6 +900,42 @@ export function applyJobPatch(
897900}
898901}
899902903+function applyAgentTurnToolsAllowPatch(
904+payload: CronAgentTurnPayload,
905+patch: CronAgentTurnPayloadPatch,
906+existing?: CronAgentTurnPayload,
907+): void {
908+if (Array.isArray(patch.toolsAllow)) {
909+payload.toolsAllow = patch.toolsAllow;
910+// Same-kind edits keep the marker only when the default list is unchanged;
911+// kind replacements carry the cron-tool-stamped marker into persistence.
912+if (
913+patch.toolsAllowIsDefault === true &&
914+(!existing || (existing.toolsAllowIsDefault === true && toolsAllowEqual(existing, patch)))
915+) {
916+payload.toolsAllowIsDefault = true;
917+} else {
918+delete payload.toolsAllowIsDefault;
919+}
920+} else if (patch.toolsAllow === null) {
921+delete payload.toolsAllow;
922+delete payload.toolsAllowIsDefault;
923+}
924+}
925+926+function toolsAllowEqual(
927+left: Pick<CronAgentTurnPayload, "toolsAllow">,
928+right: Pick<CronAgentTurnPayloadPatch, "toolsAllow">,
929+): boolean {
930+const rightToolsAllow = right.toolsAllow;
931+return (
932+Array.isArray(left.toolsAllow) &&
933+Array.isArray(rightToolsAllow) &&
934+left.toolsAllow.length === rightToolsAllow.length &&
935+left.toolsAllow.every((toolName, index) => toolName === rightToolsAllow[index])
936+);
937+}
938+900939function mergeCronPayload(existing: CronPayload, patch: CronPayloadPatch): CronPayload {
901940if (patch.kind !== existing.kind) {
902941return buildPayloadFromPatch(patch);
@@ -943,7 +982,7 @@ function mergeCronPayload(existing: CronPayload, patch: CronPayloadPatch): CronP
943982return buildPayloadFromPatch(patch);
944983}
945984946-const next: Extract<CronPayload, { kind: "agentTurn" }> = { ...existing };
985+const next: CronAgentTurnPayload = { ...existing };
947986if (typeof patch.message === "string") {
948987next.message = patch.message;
949988}
@@ -957,11 +996,7 @@ function mergeCronPayload(existing: CronPayload, patch: CronPayloadPatch): CronP
957996} else if (patch.fallbacks === null) {
958997delete next.fallbacks;
959998}
960-if (Array.isArray(patch.toolsAllow)) {
961-next.toolsAllow = patch.toolsAllow;
962-} else if (patch.toolsAllow === null) {
963-delete next.toolsAllow;
964-}
999+applyAgentTurnToolsAllowPatch(next, patch, existing);
9651000if (typeof patch.thinking === "string") {
9661001next.thinking = patch.thinking;
9671002}
@@ -1005,17 +1040,18 @@ function buildPayloadFromPatch(patch: CronPayloadPatch): CronPayload {
10051040throw new Error('cron.update payload.kind="agentTurn" requires message');
10061041}
100710421008-return {
1043+const next: CronAgentTurnPayload = {
10091044kind: "agentTurn",
10101045message: patch.message,
10111046model: typeof patch.model === "string" ? patch.model : undefined,
10121047fallbacks: Array.isArray(patch.fallbacks) ? patch.fallbacks : undefined,
1013-toolsAllow: Array.isArray(patch.toolsAllow) ? patch.toolsAllow : undefined,
10141048thinking: patch.thinking,
10151049timeoutSeconds: patch.timeoutSeconds,
10161050lightContext: patch.lightContext,
10171051allowUnsafeExternalContent: patch.allowUnsafeExternalContent,
10181052};
1053+applyAgentTurnToolsAllowPatch(next, patch);
1054+return next;
10191055}
1020105610211057function mergeCronDelivery(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。