Joye Dev

Back

Voyager 业务线学习:Agent 平台任务的预算终止、submission 续跑与可交付状态契约

这条业务线解决的是一个平台 API 特有的可交付性问题:浏览器会话在 Agent turn 因 step/token budget 停住后,可以由用户按 Continue;无人值守的 Platform Agent Task 只有“创建任务”和“轮询状态”两个外部动作,没有人会替它按按钮。旧路径因此可能把已经写入文…


source_automation: voyager-merged-pr run_date: 2026-08-07 anchor_pr_number: 5754 pr_number: 5754 pr_title: “fix(agent): carry an unattended platform task past its step budget” pr_url: https://github.com/adastralab-ai/voyager/pull/5754 author: “Horcrux / magicismight” merged_at: “2026-08-07T04:50:49Z” modules:

  • backend/workers/agent/src/agent.ts
  • packages/site/src/app/(main)/_agent/chat/_components/AgentMessageList.tsx
  • backend/workers/agent/src/turnBoundary.ts
  • backend/workers/agent/src/creationRouter.ts
  • backend/workers/agent/src/agentProfile.ts
  • backend/workers/agent/src/routes/platformAgentTasks.ts
  • backend/go/apps/api/handler/platform.go
  • backend/go/internal/agentworker
  • idl/typespec/services/platform.tsp files_changed: 2 changed_files:
  • backend/workers/agent/src/agent.ts
  • packages/site/src/app/(main)/_agent/chat/_components/AgentMessageList.tsx learning_tags:
  • agent-runtime
  • unattended-platform-task
  • step-budget
  • auto-continuation
  • durable-object-storage
  • submission-lifecycle
  • recovery-boundary
  • status-api
  • finish-reason
  • turn-boundary
  • prompt-routing
  • test-strategy business_line: “Agent 平台任务的预算终止、submission 续跑与可交付状态契约” related_prs: [5410, 5427, 5708, 5725, 5727] related_prior_prs: [5425] line_stage: “预算耗尽从正常完成中分离 (#5410) -> 平台 status 要求完成原因 (#5427) -> 续跑前扩大单轮预算 (#5725) -> 未完成 turn 保留工具与无人路由边界 (#5708/#5727) -> submission 级自动 Continue、running 保持与有限续跑 (#5754)” open_questions:
  • “#5754 没有新增自动化测试;现有 worker route 测试只 mock startPlatformTask/getPlatformTaskStatus,Go contract 测试只验证 status union,尚未证明真实 DO 在 budget -> Continue -> recovery -> poll 链上的行为。”
  • “计数器先写入 Durable Object storage、再创建下一条 submission;两步之间如果 isolate 丢失,状态回退逻辑能避免永久报告 not_started,但不会自动重试丢掉的 Continue,最多可能留下少交付且 finishReason=budget 的结果。”
  • “platformTaskContext() 从 bounded this.messages 找首条 user message,而 getAdminTranscript() 明确读取完整 history;连续 5 次续跑、大量 tool parts 或 transcript 窗口裁剪后,fileId context 是否仍能可靠传入下一轮需要部署级验证。”
  • “初始平台任务把 delegation token 和过期时间存进 DO,startPlatformTask() 又清空 connectionCookie;最多 6 个 turn 的长链是否总能在 token TTL 内完成,过期时无人值守任务如何重新授权,代码和契约没有单独证明。”
  • “MAX_PLATFORM_CONTINUATIONS=5 是固定成本/无限循环保护,但没有把 continuation count 或‘达到自动续跑上限’暴露给调用方;调用方只能从 completed + finishReason=budget 推断仍可能是部分交付。”
  • “continuePlatformTask() 依赖当前 submission 在 onChatResponse hook 中仍为 running;SDK submission settle、DO recovery 和浏览器重新打开同一 chat 的竞态没有集成测试,需确认不会过早把无人任务交给人工 Continue。” feishu_doc_url: null github_repository: joyehuang/ai-agent-field-notes github_path: outputs/voyager-daily-pr-study/2026-08-07-pr-5754-agent-platform-task-auto-continuation.md voyager_merge_commit: 2aaf1e3d20d3a3dcd8596086cad4f061f7b895c3 voyager_origin_main_snapshot: 2aaf1e3d20d3a3dcd8596086cad4f061f7b895c3

业务线概览#

这条业务线解决的是一个平台 API 特有的可交付性问题:浏览器会话在 Agent turn 因 step/token budget 停住后,可以由用户按 Continue;无人值守的 Platform Agent Task 只有“创建任务”和“轮询状态”两个外部动作,没有人会替它按按钮。旧路径因此可能把已经写入文件的半成品报告成 completed,调用方拿到的只是第一轮预算买到的页面。

本次范围不是单纯增加步数,也不是把 UI 的 Continue 文案复制到 worker。它把几层契约接起来:

  • Worker runtime 先把 step budget 的边界写成 finishReason: "budget",并将其与 length 一起定义为可续跑终态;
  • 平台任务用 Durable Object 内的 submission 作为“这一条无人任务链仍然开放”的身份,而不是依赖某一轮的 request id;
  • 每次可续跑 turn 结束前,worker 最多自动提交 5 个新的 Continue turn;
  • 状态查询在整条续跑链完成前保持 running,调用方不会在中间轮询到一个“completed + budget”的半成品;
  • 浏览器路径仍保留人工 Continue,并把预算耗尽和中途异常拆成不同提示。

今日锚点是 #5754。它把 #5425 学习记录留下的开放问题——“step budget 对无人 platform task 没有用户可点击 Continue”——推进到了 submission 级编排。它没有改变公开 Platform API 的请求形状,改变的是 Agent DO 内部怎样把同一个 API task 继续向前推进。

今日锚点#

字段内容
PR#5754 fix(agent): carry an unattended platform task past its step budget
作者Horcrux / magicismight
merge 时间2026-08-07 14:50:49 AEST / 2026-08-07T04:50:49Z
Voyager merge commit2aaf1e3d20d3a3dcd8596086cad4f061f7b895c3
变更规模2 个文件,110 additions / 10 deletions
选择理由它是 Melbourne 当天已 merge 且未出现在学习日志中的 Agent 运行时候选;PR body 给出真实平台任务少交付数据,diff 又能直接连接 budget metadata、submission 生命周期、状态轮询和站点恢复状态。

正式关联的 #5410、#5427、#5708、#5725、#5727 以及锚点 #5754 的 merge commit 均已用 git merge-base --is-ancestor <commit> origin/main 验证。本文行号以本次读取的 origin/main snapshot 2aaf1e3d20d3a3dcd8596086cad4f061f7b895c3 为准。

演进时间线#

阶段PR 与真实代码变化改变的层形成的契约
budget 终态显式化#5410,2026-07-29T14:05:10Z,merge bac24a3bf653ac882c64d06149ba5f58c383ebf0Think stop condition / Agent transcript自定义 stopWhen 在 step 边界检查最后一步是否仍为 tool-calls;是则写 runtime.budgetExhausted,最终 metadata 为 interrupted: truefinishReason: "budget",不写 finishTime,不生成 suggestions。
平台 status 能表达“完成但被截断”#5427,2026-07-31T13:19:22Z,merge 370d7b50657999cfd11b333fcd93ac6ac7732639TypeSpec / Go handler / Worker client / contract testcompleted 不再携带可有可无的 errorCode;完成结果必须有 finishReasonbudget/length/content-filter 明确表示文件可能是部分交付。缺少原因时 Go API 返回 502,而不是伪装成干净完成。
单轮预算上调#5725,2026-08-06T12:52:10Z,merge 59b499ebf3e006fdc51de26009a112d5cdf047f1Agent runtime configurationMAX_STEP_COUNT 从 50 提到 100,减少复杂多页任务在单轮内触顶的频率;PR 同时承认成本、延迟和 credit exposure 可能最多翻倍,并要求用 agent_usage 观察 51–100 步的边际收益。它没有解决无人任务最终仍会触顶的问题。
续跑 turn 不再被当成 chat-only#5708,2026-08-06T11:34:47Z,merge 4838c0b6e8d68896b1a236874174500c3b289700Transcript/tool boundaryhasUnfinishedWork() 同时识别未结算 tool、recovery 标记和 interrupted metadata;“上一轮是否还欠活”与“当前 turn 是否仍在飞”分开,后续 Continue 才不会因文字看起来像聊天而被剥光工具。新增单测覆盖 abandoned write_page 和用户主动 abort 的区别。
无人任务的路由边界#5727,2026-08-07T00:57:17Z,merge c41212e558e864d573c10e0bfa6f5d83d11c1ea0Creation router / prompt profile / eval harnessresolveTurnCreation() 对 unattended 的 ask 路由选择可构建的 design,并把 routeToBuild 传给真实 DO 与 eval;避免 headless caller 进入需要用户回答的 request_user_choice 分支。prompt scope 和 workspace feature 也进入同一条 eval 路径。
今日锚点:submission 级自动续跑#5754,2026-08-07T04:50:49Z,merge 2aaf1e3d20d3a3dcd8596086cad4f061f7b895c3Agent DO storage / inherited submission API / site recovery copychatId#continue-N 表示同一平台链,只有当前 submission 仍为 running 且 turn 是 length/budget 才自动发 Continue;计数上限 5,状态查询跟随最新或前一条 submission,用户调用方在链结束前持续看到 running

这条线的因果关系#

#5410 让“预算耗尽”成为可识别的 runtime 事实,#5427 才能把它安全地暴露给 Platform API;#5725 只是减少触顶频率,#5708/#5727 则保证人工或自动的 Continue 仍进入有工具、可产出的 turn。#5754 最后把浏览器需要点击的恢复动作移到无人任务自己的 submission 生命周期里,并用硬上限把它关掉。

当前架构与数据流#

flowchart LR
  A["PAT 调用 POST /api/platform/v1/agent-tasks"] --> B["Go 创建 file + chat"]
  B --> C["Go 签发 delegation token"]
  C --> D["Worker internal POST"]
  D --> E["Agent DO startPlatformTask"]
  E --> F["submission chatId / initial prompt"]
  F --> G["Think turn: maxSteps + stopWhen"]
  G --> H["onChatResponse 写 transcript metadata"]
  H --> I{"finishReason length/budget?"}
  I -->|否| J["submission settle,任务终态"]
  I -->|是| K{"current submission still running?"}
  K -->|否| J
  K -->|是| L["storage counter + submit Continue"]
  L --> G
  D2["GET /api/platform/v1/agent-tasks/{chatId}"] --> M["Go -> Worker status"]
  M --> N["current submission or previous fallback"]
  N --> O["running until chain settles"]
  H --> P["Browser transcript + AgentMessageList"]
  P --> Q["manual Continue / retry copy"]
plaintext
  1. 公共 API 与身份。 Go 的 PlatformServiceCreateAgentTask 先按 PAT workspace 创建空 file 和 chat,再签发仅用于 Agent worker 的 delegation token;backend/go/apps/api/handler/platform.go:100-154chatId/prompt/tier 转给 agentworker。GET 先验证 PAT 对 chat 的可见性,再查询同一个 worker(同文件 :157-194)。
  2. Worker 入口。 backend/workers/agent/src/routes/platformAgentTasks.ts:134-189 重新校验 delegation、workspace 和 chat ownership;POST 调用 Agent.startPlatformTask(),GET 调用 getPlatformTaskStatus()。它没有引入第二个任务队列,Durable Object chat 仍是执行和 transcript 的权威边界。
  3. 初始 submission。 Agent.startPlatformTask() 将 token、workspace/user auth 和平台 tier 写入 DO storage,再用 submissionId: this.name 提交初始 prompt(backend/workers/agent/src/agent.ts:1095-1128)。#5754 新增的 continuation id 是 ${chatId}#continue-${n},因此一轮 request recovery 换 request id 不会改变平台任务链身份。
  4. 预算与 transcript。 当前 stepBudget 是普通 turn 的 MAX_STEP_COUNT=100,chat-only 才是 1;stopWhen 在同一个数值上停止,并在边界最后一步仍为 tool-calls 时设置 runtime.budgetExhaustedbackend/workers/agent/src/agent.ts:1612-1663)。onChatResponse 再把它归一化为 finishReason,写入 assistant message metadata。
  5. 自动续跑。 onChatResponseresult.status === "completed" 后、普通 suggestions/debit 之前调用 continuePlatformTask()backend/workers/agent/src/agent.ts:1901-1950)。因此 length/budget 的已落地副作用会先持久化,随后才启动下一轮;error、用户 abort 和 content-filter 不会走这条自动分支。
  6. 轮询语义。 counter 指向的 submission 若尚不存在,getPlatformTaskStatus() 会退回 counter - 1 的 row,避免“已经开始过却永远 not_started”;只要当前 row 是 pending/running,公共 status 就是 running。最终 completed 仍带 finishReason,由 #5427 的 discriminated schema 让调用方决定是否接受部分交付。

关键代码#

1. 预算判断和终态分类必须在同一条 runtime 边界#

来源:PR #5410,当前 origin/mainbackend/workers/agent/src/agent.ts:1612-1663:1901-1950

const stepBudget = chatOnly ? 1 : MAX_STEP_COUNT;

stopWhen: ({ steps }) => {
  if (steps.length < stepBudget) return false;
  runtime.budgetExhausted = steps.at(-1)?.finishReason === "tool-calls";
  return true;
},

const isResumable = finishReason === "length" || finishReason === "budget";
if (result.status === "completed" && isResumable) {
  await this.continuePlatformTask();
}
plaintext

代码事实是:框架停止与 metadata 记录共享 stepBudget,且自动续跑只接受 length/budget。合理推断是,这避免了 worker 通过“看到 UI 中断状态”猜测是否应重试,也避免把正常完成、用户 stop 和内部 error 错误地变成无人重试。

2. API 把“completed”与“完整交付”拆开#

来源:PR #5427idl/typespec/services/platform.tsp:44-96backend/go/apps/api/handler/platform.go:196-225

model CompletedPlatformAgentTask {
  status: "completed";
  finishReason: PlatformAgentTaskFinishReason;
}

union PlatformAgentTaskStatusResponse {
  not_started: NotStartedPlatformAgentTask,
  running: RunningPlatformAgentTask,
  completed: CompletedPlatformAgentTask,
  failed: FailedPlatformAgentTask,
}
plaintext
case agentworker.PlatformTaskCompleted:
    if status.FinishReason == "" {
        return body, errors.WrapNew("agent worker reported a completed task with no finish reason")
    }
plaintext

这层契约的价值在于:#5754 可以在最终只剩一份部分文件时诚实返回 completed + budget,而不会为了复用旧状态把它变成 failed 或默认为 stop。它也把“缺少完成原因”当作 worker/API contract fault,而不是让调用方误收结果。

3. 续跑身份绑定 submission,不绑定某一轮 request#

来源:PR #5754backend/workers/agent/src/agent.ts:1131-1181

private platformSubmissionId(continuations: number): string {
  return continuations === 0
    ? this.name
    : `${this.name}#continue-${continuations}`;
}

const submission = await this.inspectSubmission(
  this.platformSubmissionId(continuations),
);
if (submission?.status !== "running") return;
if (continuations >= MAX_PLATFORM_CONTINUATIONS) return;

await this.ctx.storage.put(PLATFORM_CONTINUATION_STORAGE_KEY, next);
await this.submitMessages(messages, {
  submissionId: this.platformSubmissionId(next),
});
plaintext

PR body 明确把 submission 作为链身份:DO recovery 可能用新的 request id 重跑 turn,但 submission 仍未 settle。代码还用 storage counter 作为跨 isolate 的上限;如果计数器写失败就停止,优先保证不会无限续跑。

4. Continue 必须穿过 turn-boundary 和 unattended 路由#

来源:PR #5708PR #5727,当前 backend/workers/agent/src/turnBoundary.ts:11-49backend/workers/agent/src/creationRouter.ts:111-135backend/workers/agent/src/agent.ts:1412-1462

export function hasUnfinishedWork(previousAssistant?: AgentUIMessage) {
  if (previousAssistant?.metadata?.aborted === true) return false;
  if (continuesUnfinishedTurn(previousAssistant?.metadata)) return true;
  return (previousAssistant?.parts ?? []).some(
    (part) => isToolUIPart(part) && !toolPartHasSettledResult(part),
  );
}

const routeToBuild =
  input.unattended && input.route === "ask" ? "design" : input.route;
plaintext

前一段保证有 interrupted/budget 的上一轮不会把自动 Continue 当作无工具聊天;后一段保证 headless task 不会停在等人回答的 ask。这两个判断解决的是不同问题:一个恢复 turn 的能力集合,一个决定无人任务能否拥有可执行的 creation workflow;把它们合并成一个 isUnattended if 会失去各自的回归边界。

5. status fallback 修复的是可观测性断点,不是事务提交#

来源:PR #5754backend/workers/agent/src/agent.ts:1193-1235

const submission =
  (await this.inspectSubmission(this.platformSubmissionId(continuations))) ??
  (continuations > 0
    ? await this.inspectSubmission(this.platformSubmissionId(continuations - 1))
    : null);

if (!submission) return { status: "not_started" };
if (submission.status === "pending" || submission.status === "running") {
  return { status: "running" };
}
plaintext

这里的设计点是把 counter 先于下一 row 存储造成的短暂空洞转成“读取已知上一条链”,而不是把已经启动的 API task 伪装成从未开始。它没有做到两阶段提交:如果 DO 在 storage.put(next) 后、submitMessages() 前丢失,fallback 只保住状态可读性,不能证明下一轮一定创建成功。

工程取舍#

状态边界与兼容性#

  • 公开 API 不变,内部 identity 增加。 POST /api/platform/v1/agent-tasks 和 GET 的 URL、请求参数都没有在 #5754 里改动;新增的是 DO 内部 submission id 和 storage counter。已有调用方只需继续轮询,不需要理解 #continue-N
  • completed 不等于“完整”。 #5427 的 schema 把 finish reason 放在 completed variant;budget/length 是已落盘但可能未完成的工作,content-filter 是另一种不可自动续跑的终态。调用方必须读取 finishReason,不能只看 HTTP 200 或 status。
  • 自动与人工恢复分开。 #5754 只对 platform submission 自动发 Continue;浏览器用户仍根据 AgentMessageList 的 metadata 决定操作,不会因为一个普通网页 turn 触顶就自动消耗 5 轮。
  • 旧 transcript 兼容。 finishReason 仍是消息 metadata 中的可选字段,历史没有该字段时沿用原来的 interrupted/normal 推断;本次没有双写旧 API 形状,也没有数据迁移。

可靠性与并发#

  • 选择 submission 而不是 request id。 这是最重要的边界:一次 DO recovery 可以重跑同一逻辑 turn 并产生新 request id,但平台任务的外部轮询对象仍是同一条 submission chain。按 request id 去重会在 recovery 后误以为任务已经结束或启动第二条链。
  • 有限续跑控制成本。 MAX_PLATFORM_CONTINUATIONS=5 加上 storage counter 把理论上最多 6 个 turn(初始 1 + 自动 5)固定下来。结合 #5725 的单轮上限 100,最坏的模型/tool step 数可能明显高于单次请求;这是为交付完整度付出的成本上界,不应被“自动成功”文案掩盖。
  • 副作用顺序是可恢复但非原子的。 onChatResponse 先 flush page delivery、checkpoint sandbox、upsert transcript,再尝试续跑;因此已经创建的页不会因下一轮 submission 创建失败而被回滚。代价是 continuation 失败时可能留下可继续但未自动继续的文件,需要观测和人工入口兜底。
  • 上下文复用优先于重新发 prompt。 continuation 只发送文本 Continue,并从首条 user message 复制 file context;它依赖 transcript、working files 和已提交页面作为恢复事实,避免重复生成初始 prompt 的副作用。
  • 路由与工具集合必须保持同一判定。 #5708/#5727 同时收紧真实 DO 与 eval route 的 routeToBuild、workspace features、active tools 和 hasUnfinishedWork;否则自动续跑可能只在生产有工具,测试却走 chat-only,或者反过来。

测试策略与验证边界#

  • 已有分层证据。 #5410 的真实本地 DO 验证检查了 budget metadata;#5427 的 Go contract test 覆盖 completed + budget、缺少 finishReason 时 502 和 status union;#5708 新增 turnBoundary.test.ts;#5727 新增 5 条 chat-only eval case 与 unattended/workspace feature 变量。
  • 锚点本身没有测试文件。 #5754 diff 只改 agent.tsAgentMessageList.tsx,没有加入 Agent DO、submission 或 counter 的单测。PR body 的验证计划要求完整本地栈、临时降低 MAX_STEP_COUNT、轮询多页任务、触发第 6 次上限、验证浏览器不会自动续跑以及检查两种文案;这些是待执行的手工/部署验证,不应等同于已提交的自动化回归。
  • 当前 route test 不是链路证明。 backend/workers/agent/src/routes/platformAgentTasks.test.ts:20-31,84-177 里的 Agent DO 是 mock;它能证明 HTTP 认证和 RPC 委托,但不能证明 onChatResponse 的 hook 顺序、真实 inspectSubmission 状态或 Cloudflare isolate 丢失窗口。Go contract test backend/go/apps/api/contract_test/platform/agent_tasks_test.go:210-279 也只验证 status union。

和最近学习记录的关系#

我会怎么吸收#

  1. 先定义业务链的稳定 identity,再定义重试。 如果 recovery 会换 request id,重试/续跑应绑定用户真正轮询的 submission、job 或 workflow,而不是绑定一次 HTTP/WS 请求。
  2. 在停止决策处记录原因,并让 downstream 复用同一分类。 finishReason 同时驱动 transcript、模型下一轮提示、站点 affordance、平台 status 和自动续跑,避免每一层凭症状重新猜测。
  3. 为无人值守路径显式搬运用户动作,同时设硬上限。 把“用户会点 Continue”的交互假设移到 orchestrator 后,必须同时设计最大次数、成本暴露、最终状态和人工兜底。
  4. 用 discriminated contract 阻断含糊终态。 completed 缺少 finishReason 时直接报 contract fault,比默认 stop 更安全;下游才能把“HTTP 成功”和“交付完整”分开。
  5. 测试 crash window,而不只测分支。 对“counter 已写、submission 未建”“DO recovery 换 request id”“连续 5 次后 status”“用户重新打开 chat”做真实 DO/worker/API 验证,才能证明状态机而不只是证明 helper 返回值。

边界、风险与未解问题#

已由代码确认的边界#

  • 自动续跑只在 result.status === "completed"finishReasonlength/budget 时触发;用户 abort、worker error、content-filter 不会自动重试。
  • 只有当前 platform submission 状态是 running 才会创建下一条 submission;普通浏览器打开同一 chat 后,已 settle 的 platform row 不会再被误认为无人任务链。
  • 续跑次数由 DO storage counter 限制为 5;计数写入失败会停止,而不是无界地继续。
  • 公共 API 的 completed 仍可能是部分交付;finishReason=budget 是调用方必须处理的信号,不是失败码。

仍需确认的风险#

  • 两步写入窗口。 counter 与 submission 没有事务;fallback 能避免错误的 not_started,但不能确保 Continue 被重发。应增加可观测事件或 durable retry,而不是把 fallback 当成 exactly-once 证明。
  • 上下文窗口。 platformTaskContext()this.messages 找首条 user message,而长 transcript 的完整读取路径是 session.getHistory();应确认最大 continuation 链仍会携带 fileId、workspace context 和正确的 page focus。
  • 授权时长。 一条链可能执行初始 turn 加 5 次续跑,且每轮有最多 100 steps;需要用真实 PAT/delegation TTL 和 provider latency 验证后台链是否会在中途失去 refresh 能力。
  • 成本/质量信号。 当前代码存了 continuation counter,但没有把每次自动续跑、累计 steps、最终交付页数和第 6 次 budget 终态作为一组可查询指标;无法仅凭 diff 判断五次是否足够,或是否只是把成本推迟到更晚的部分交付。
  • 恢复竞态。 #5496/#5503 已显示 DO reset 与客户端重连会放大异常路径;需要验证 automatic Continue、DO recovery、status poll 和人工 Continue 不会同时创建两个逻辑链。
  • 测试缺口。 本次缺少真实 Cloudflare Workflow/DO integration、真实平台 API 多页任务、浏览器 reload/人工接管和 token expiry 覆盖;PR body 的手工计划仍待在目标环境执行。

候选说明#

本次先按 Australia/Melbourne 的 2026-08-07 合并窗口筛选,并读取外部 study-log.jsonl 去重;#5754 不在既有 anchor 列表中。今天同时有 #5759(billing/device plan)、#5761(前端低 ROI 测试清理)、#5404(scenario catalog)和多条 Agent eval/UI 修复,但它们要么是计费/产品目录线,要么没有自然串起平台任务状态、submission 或 step-budget 的至少两个代码层。

其中 #5727 与 #5754 的业务线关系很强,但它作为同日较早合入的“无人路由/工具能力前置”被纳入 related PR,而不是另选为 anchor。今天已有合适且未重复的 anchor,因此没有扩大到 2026-08-06 以外的候选窗口;#5725/#5708 只作为同一条线最近的前置演进引用。

GitHub 文档#

  • 报告文件:outputs/voyager-daily-pr-study/2026-08-07-pr-5754-agent-platform-task-auto-continuation.md
  • 目标仓库:joyehuang/ai-agent-field-notes
  • Voyager 锚点:PR #5754
  • Voyager merge commit:2aaf1e3d20d3a3dcd8596086cad4f061f7b895c3
  • 本报告正文、索引和后续提交以目标 GitHub 仓库为唯一持久化来源。

🗂️ 这是知识库中的🔬 研究。

内容可能仍在补充或修订中。

← Back