Kaynağa Gözat

Merge remote-tracking branch 'origin/master' into docs/post-v3-release-proofreading

# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md
xjt 1 ay önce
ebeveyn
işleme
bbc75b38b2

+ 2 - 2
.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md
-2026-07-10-single-file-executable-sdk-runtime-distribution.md: 4fe9ea3c4073e249a8c961634be9d329b35a3f4e
-2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md: 58b70e6e8968bdfd434e1374a591fc57fd876bce
+2026-07-10-single-file-executable-sdk-runtime-distribution.md: e45f566ee542fdab4ae55b45ff6808169e6e7cf6
+2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md: ca076b62f928bc146d548b0e2996dfd41a2bf1e3

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.md


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
.agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md


+ 2 - 2
.agents/notes/implemented/process/2026-07-23-portable-required-pull-request-ci.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-23-portable-required-pull-request-ci.md
-2026-07-23-portable-required-pull-request-ci.md: b7c637408afa32611c4e70073ddec9aaabfba7f5
-2026-07-23-portable-required-pull-request-ci.zh.md: 42ed1144bcde3380e4522b09f294e836f2d9f200
+2026-07-23-portable-required-pull-request-ci.md: 418f996383ebc08e78cb5b061bfde4b90dd89495
+2026-07-23-portable-required-pull-request-ci.zh.md: ada3cc52e3f6436269969a3ff93b7a2616353337

+ 2 - 2
.agents/notes/implemented/process/2026-07-23-portable-required-pull-request-ci.md

@@ -12,9 +12,9 @@ Billing health, a runner definition's `Ready` state, and a large autoscaling cei
 
 ## Decision
 
-[CI](../../../../.github/workflows/ci.yml) runs the required primary Node 24 jobs, plus the stable `all checks passed` aggregate, on repo-restricted enterprise 32-core pools. The aggregate performs no checkout or repository gate, but sharing the enterprise pool prevents the required verdict from introducing a separate standard-hosted billing dependency after its substantive jobs have already succeeded. The required Windows job runs Windows Node under Wine on standard `ubuntu-latest` for the blocking surfaces; an independent native `windows-2025` job starts automatically but does not participate in the aggregate ([dual Windows decision](2026-08-08-native-windows-pull-request-ci.md)). Standard `ubuntu-latest` jobs retain Node 22.19, Node 26, and Python SDK compatibility, and the serial references remain the complete unsharded cross-platform definitions. Those standard-hosted jobs keep the portable execution boundary observable without duplicating the primary inventory on every pull request.
+[CI](../../../../.github/workflows/ci.yml) runs the required primary Node 24 jobs, plus the stable `all checks passed` aggregate, on repo-restricted enterprise 32-core pools. The aggregate performs no checkout or repository gate, but sharing the enterprise pool prevents the required verdict from introducing a separate standard-hosted billing dependency after its substantive jobs have already succeeded. The required Windows job runs Windows Node under Wine on standard `ubuntu-latest` for the blocking surfaces; an independent native `windows-2025` job starts automatically but does not participate in the aggregate ([dual Windows decision](2026-08-08-native-windows-pull-request-ci.md)). Standard `ubuntu-latest` jobs retain Node 22.19, Node 26, the Python SDK unit suite, and the [release-shaped Linux x64 Python runtime validation](../testing/2026-08-12-required-python-runtime-pull-request-ci.md), while the serial references remain the complete unsharded cross-platform definitions. Those standard-hosted jobs keep the portable execution boundary observable without duplicating the primary inventory on every pull request.
 
-The two Linux primary jobs, Node compatibility, Python SDK, and `windows node 24 / wine blocking` remain dependencies of `all checks passed`; `windows node 24 / native complete` is deliberately absent. Branch protection continues to require `e2e` and `all checks passed`. There is no automatic fallback when a remaining enterprise Linux label cannot allocate: the standard jobs continue to report their own contracts, but they cannot manufacture the missing required result.
+The three Linux primary jobs, Node compatibility, Python SDK unit suite, Python runtime validation, and `windows node 24 / wine blocking` remain dependencies of `all checks passed`; `windows node 24 / native complete` is deliberately absent. Branch protection continues to require `e2e` and `all checks passed`. There is no automatic fallback when a remaining enterprise Linux label cannot allocate: the standard jobs continue to report their own contracts, but they cannot manufacture the missing required result.
 
 The [larger-runner decision](2026-07-22-evidence-based-larger-hosted-runners.md) owns the current primary topology and its measurements. The [serial cross-platform reference](2026-07-21-serial-cross-platform-ci-reference.md) remains the independent standard-hosted completeness check, and the manual larger-runner suites retain size comparisons without expanding the ordinary required matrix.
 

+ 2 - 2
.agents/notes/implemented/process/2026-07-23-portable-required-pull-request-ci.zh.md

@@ -12,9 +12,9 @@ Status: implemented
 
 ## 决策
 
-[CI](../../../../.github/workflows/ci.yml) 在仅限本仓库使用的企业级 32 核运行器池上运行必需的主 Node 24 作业,以及稳定的 `all checks passed` 聚合流程。该聚合流程不执行代码检出或仓库门禁;但让它与所依赖的实质性作业共用企业级运行器池,可以避免这些作业已经成功后,必需判定结果又引入一项单独的标准托管计费依赖。必需的 Windows 作业在标准 `ubuntu-latest` 上通过 Wine 运行 Windows Node,覆盖阻断性检查范围;一个独立的原生 `windows-2025` 作业会自动启动,但不参与聚合流程([双 Windows 决策](2026-08-08-native-windows-pull-request-ci.md))。标准 `ubuntu-latest` 作业保留 Node 22.19、Node 26 和 Python SDK 兼容性,串行参考流程仍是完整且未分片的跨平台定义。这些标准托管作业让可移植执行边界保持可观测,而不必在每个拉取请求中重复主清单。
+[CI](../../../../.github/workflows/ci.yml) 在仅限本仓库使用的企业级 32 核运行器池上运行必需的主 Node 24 作业,以及稳定的 `all checks passed` 聚合流程。该聚合流程不执行代码检出或仓库门禁;但让它与所依赖的实质性作业共用企业级运行器池,可以避免这些作业已经成功后,必需判定结果又引入一项单独的标准托管计费依赖。必需的 Windows 作业在标准 `ubuntu-latest` 上通过 Wine 运行 Windows Node,覆盖阻断性检查范围;一个独立的原生 `windows-2025` 作业会自动启动,但不参与聚合流程([双 Windows 决策](2026-08-08-native-windows-pull-request-ci.md))。标准 `ubuntu-latest` 作业保留 Node 22.19、Node 26、Python SDK 单元测试套件与[发布形态的 Linux x64 Python 运行时验证](../testing/2026-08-12-required-python-runtime-pull-request-ci.md),串行参考流程仍是完整且未分片的跨平台定义。这些标准托管作业让可移植执行边界保持可观测,而不必在每个拉取请求中重复主清单。
 
-两项 Linux 主作业、Node 兼容性、Python SDK 和 `windows node 24 / wine blocking` 继续作为 `all checks passed` 的依赖项;`windows node 24 / native complete` 被刻意排除。分支保护继续要求 `e2e` 和 `all checks passed`。剩余的企业级 Linux 运行器标签无法分配运行器时没有自动后备机制:标准作业会继续报告各自的约定,但无法产出缺失的必需结果。
+三项 Linux 主作业、Node 兼容性、Python SDK 单元测试套件、Python 运行时验证和 `windows node 24 / wine blocking` 继续作为 `all checks passed` 的依赖项;`windows node 24 / native complete` 被刻意排除。分支保护继续要求 `e2e` 和 `all checks passed`。剩余的企业级 Linux 运行器标签无法分配运行器时没有自动后备机制:标准作业会继续报告各自的约定,但无法产出缺失的必需结果。
 
 当前主拓扑及其测量结果以[大型运行器决策](2026-07-22-evidence-based-larger-hosted-runners.md)为准。[跨平台串行参考流程](2026-07-21-serial-cross-platform-ci-reference.md)继续作为独立的标准托管完整性检查,手动大型运行器套件则保留规格比较,同时不扩大普通必需矩阵。
 

+ 6 - 0
.agents/notes/implemented/testing/2026-08-12-required-python-runtime-pull-request-ci.i18n.yaml

@@ -0,0 +1,6 @@
+# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
+# side as of the last confirmed-consistent state. Both languages carry equal authority;
+# after editing either side, bring the other along and re-record with:
+#   pnpm run verify-translation-pairing --write .agents/notes/implemented/testing/2026-08-12-required-python-runtime-pull-request-ci.md
+2026-08-12-required-python-runtime-pull-request-ci.md: 2f5dcac17262bd885049221620a4d9708b083faa
+2026-08-12-required-python-runtime-pull-request-ci.zh.md: 66c81f70d1bf25355425030883ccc4307efbb1ce

+ 31 - 0
.agents/notes/implemented/testing/2026-08-12-required-python-runtime-pull-request-ci.md

@@ -0,0 +1,31 @@
+# Agent Note: Required Python runtime pull-request validation
+
+Status: implemented
+
+English | [中文](2026-08-12-required-python-runtime-pull-request-ci.zh.md)
+
+## Problem
+
+Ordinary pull-request CI runs the complete Python SDK pytest suite against fake runtime peers, while Node snapshots exercise different clients and expected outputs. The real Python client, packaged JSON-RPC executable, executable-specific snapshot, release-shaped wheels, and clean installation meet only in the optional single-executable or Python release workflows. A runtime event change or closure change can therefore merge with a stale Python projection or broken wheel path and fail only when someone later builds a Python release candidate.
+
+## Decision
+
+Every pull request has a required `python-runtime` job in [CI](../../../../.github/workflows/ci.yml). It calls the shared [single-executable builder](../../../../.github/workflows/build-exe-for-python-sdk.yml) for `node24-linux-x64` without a path filter and participates in `all checks passed`. The called workflow builds the real executable, runs all keyless Python full-turn and direct-binary scenarios including the committed executable snapshot, builds the SDK and runtime wheels, installs them into a clean virtual environment, checks the executable and native addon's GLIBC requirements, and runs the installed wheels in a manylinux 2.28 container.
+
+The required job and the [Python publication workflow](../process/2026-08-11-python-publication-workflow.md) use the same builder. Its concurrency key includes the caller workflow, so required CI and an explicit full release validation for the same ref do not cancel each other. The complete linux-x64, linux-arm64, and macos-arm64 matrix remains a release validation because platform-independent runtime, SDK, and snapshot behavior needs one merge-blocking native carrier, while architecture-specific executable, addon, wheel-tag, and deployment-target behavior still needs all release targets before publication.
+
+The executable snapshot normalizes opaque session, message, subagent, and workflow-run identifiers before comparison. A newly persisted workflow event therefore changes the reviewed expected output without making a random run identifier part of that output.
+
+## Alternatives considered
+
+**Run the complete native matrix on every pull request.** This duplicates platform-independent full-turn and snapshot behavior across three jobs and consumes ARM64 Linux and macOS capacity on every change. The publication workflow retains that evidence at the point where all three artifacts are required.
+
+**Run the snapshot against the development Node carrier.** This catches protocol and event projection drift but does not prove pkg assembly, the deployed runtime closure, native addon staging, wheel construction, exact dependency pins, or clean installation. The required Linux executable path covers the published path directly.
+
+**Select the job with path filters or labels.** Python behavior depends on shared agent, session, workflow, subagent, plugin-loading, and packaging code outside `python/`. An incomplete dependency filter recreates the delayed failure, and a label leaves the evidence optional.
+
+## Consequences
+
+Every pull request pays for one standard-hosted Linux executable and wheel build, and `all checks passed` waits for it. This makes the first-party Python distribution a merge-time contract and reuses the release implementation instead of maintaining a smaller substitute pipeline.
+
+One required architecture cannot detect macOS or Linux ARM64 packaging regressions. Explicit full release validation remains mandatory before publication and owns those platform-specific results.

+ 31 - 0
.agents/notes/implemented/testing/2026-08-12-required-python-runtime-pull-request-ci.zh.md

@@ -0,0 +1,31 @@
+# Agent Note: 必需的 Python 运行时拉取请求验证
+
+Status: implemented
+
+[English](2026-08-12-required-python-runtime-pull-request-ci.md) | 中文
+
+## 问题
+
+普通拉取请求 CI 会针对 fake 运行时对端执行完整的 Python SDK pytest 套件,而 Node 快照使用不同的客户端与预期输出。真实 Python 客户端、打包后的 JSON-RPC 可执行文件、exe 专用快照、发布形态 wheel 包与干净安装只在可选的单文件可执行程序工作流或 Python 发布工作流中汇合。因此,运行时事件或闭包发生变化后,陈旧的 Python 投影或损坏的 wheel 包路径仍可能合并,直到后续有人构建 Python 发布候选版本时才失败。
+
+## 决策
+
+每个拉取请求都在 [CI](../../../../.github/workflows/ci.yml) 中运行必需的 `python-runtime` 作业。该作业不使用路径过滤,调用共享的[单文件可执行程序构建器](../../../../.github/workflows/build-exe-for-python-sdk.yml)构建 `node24-linux-x64`,并参与 `all checks passed`。被调用的工作流会构建真实可执行文件,运行全部无密钥 Python 完整轮次和直接二进制场景(包括检入的 exe 快照),构建 SDK 与运行时 wheel 包,将二者安装进干净的虚拟环境,检查可执行文件与原生 addon 的 GLIBC 依赖,并在 manylinux 2.28 容器中运行已安装的 wheel 包。
+
+必需作业与 [Python 发布工作流](../process/2026-08-11-python-publication-workflow.md)共用同一构建器。其并发键包含调用方工作流,因此同一 ref 上的必需 CI 与显式完整发布验证不会互相取消。完整的 linux-x64、linux-arm64 和 macos-arm64 矩阵仍属于发布验证:平台无关的运行时、SDK 与快照行为只需要一个阻断合并的原生载体,而架构相关的可执行文件、addon、wheel 包标签与部署目标行为在发布前仍需要全部发布目标验证。
+
+exe 快照会在比较前规范化不透明的会话、消息、subagent 和工作流运行标识符。因此,新增的持久化工作流事件会改变经过审阅的预期输出,但不会把随机运行标识符写入其中。
+
+## 曾考虑的替代方案
+
+**每个拉取请求都运行完整原生矩阵。** 这会在三个作业中重复平台无关的完整轮次与快照行为,并让每项改动都消耗 ARM64 Linux 和 macOS 容量。Python 发布工作流在需要全部三个产物的环节保留这部分证据。
+
+**针对开发用 Node 载体运行快照。** 这可以捕获协议与事件投影漂移,但不能证明 pkg 组装、部署后的运行时闭包、原生 addon 暂存、wheel 包构建、精确依赖版本与干净安装。必需的 Linux exe 路径直接覆盖发布路径。
+
+**通过路径过滤或标签选择该作业。** Python 行为依赖 `python/` 之外共享的 agent、会话、工作流、subagent、插件加载与打包代码。不完整的依赖过滤会再次造成延迟发现,标签则会让证据保持可选。
+
+## 后果
+
+每个拉取请求都会承担一次标准托管 Linux exe 与 wheel 包构建,`all checks passed` 也会等待该作业。这使第一方 Python 分发成为合并时约定,并复用发布实现,而不维护一条更小的替代流水线。
+
+单一必需架构无法检测 macOS 或 Linux ARM64 打包回归。发布前仍必须执行显式完整发布验证,并由该验证负责这些平台特定结果。

+ 9 - 3
.github/workflows/build-exe-for-python-sdk.yml

@@ -20,6 +20,11 @@ on:
         type: boolean
         required: false
         default: false
+      ci:
+        description: Run as the required Linux x64 Python runtime pull-request check.
+        type: boolean
+        required: false
+        default: false
   workflow_dispatch:
     inputs:
       targets:
@@ -35,8 +40,9 @@ on:
 
 concurrency:
   # Keep the called workflow distinct from its caller's concurrency group;
-  # github.workflow identifies the caller inside a reusable workflow.
-  group: build-single-exe-${{ github.ref }}
+  # github.workflow identifies the caller inside a reusable workflow and keeps
+  # an ordinary CI run from cancelling a full release validation on the same ref.
+  group: build-single-exe-${{ github.workflow }}-${{ github.ref }}
   cancel-in-progress: true
 
 permissions:
@@ -52,7 +58,7 @@ jobs:
   # construct the matrix before the dependent jobs.
   plan:
     name: plan targets
-    if: inputs.release || github.event_name == 'workflow_dispatch' || github.event.label.name == 'build-exe'
+    if: inputs.ci || inputs.release || github.event_name == 'workflow_dispatch' || github.event.label.name == 'build-exe'
     runs-on: ubuntu-latest
     timeout-minutes: 5
     outputs:

+ 13 - 1
.github/workflows/ci.yml

@@ -300,6 +300,18 @@ jobs:
       - name: Run complete keyless Python suite
         run: uv run --python 3.10 --group test --project python/sdk pytest
 
+  # One native target makes the complete release-shaped Python path required
+  # without duplicating platform-independent behavior across the release matrix.
+  # The reusable builder owns the executable, snapshot, wheel, clean-install,
+  # GLIBC, and manylinux checks; release validation retains all native targets.
+  python-runtime:
+    if: github.event_name == 'pull_request'
+    name: python runtime / release-shaped Linux x64
+    uses: ./.github/workflows/build-exe-for-python-sdk.yml
+    with:
+      targets: node24-linux-x64
+      ci: true
+
   # The required pull-request Windows signal: the two blocking win32 surfaces
   # (workspace build, production site) execute with real, checksum-verified
   # Windows Node under Wine on standard hosted Linux. The independent
@@ -895,7 +907,7 @@ jobs:
           && github.event.pull_request.user.login != 'dependabot[bot]'
           && fromJSON('["self-hosted", "linux", "x64", "vm-backup"]')
           || 'ubuntu-latest' }}
-    needs: [node-24, node-24-coverage, node-24-consumers, node-compat, python-sdk, windows]
+    needs: [node-24, node-24-coverage, node-24-consumers, node-compat, python-sdk, python-runtime, windows]
     if: always() && github.event_name == 'pull_request'
     steps:
       - name: Fail if any needed job did not succeed

+ 28 - 1
scripts/ci-workflow.spec.ts

@@ -92,6 +92,26 @@ describe('CI workflow', () => {
     expect(config).not.toContain('packages/lsp/lsp-local/src/instance.ts')
   })
 
+  it('requires one release-shaped Python runtime target on every pull request', () => {
+    const workflow = loadWorkflow('.github/workflows/ci.yml')
+    const pythonRuntime = workflowJob(workflow, 'python-runtime')
+    const aggregate = workflowJob(workflow, 'all-checks-passed')
+    if (!Array.isArray(aggregate.needs)) {
+      throw new TypeError('CI aggregate must define required job dependencies')
+    }
+
+    expect(pythonRuntime).toMatchObject({
+      if: "github.event_name == 'pull_request'",
+      name: 'python runtime / release-shaped Linux x64',
+      uses: './.github/workflows/build-exe-for-python-sdk.yml',
+      with: {
+        targets: 'node24-linux-x64',
+        ci: true,
+      },
+    })
+    expect(aggregate.needs).toContain('python-runtime')
+  })
+
   it('keeps every Vitest project process-isolated on native Windows', () => {
     const config = readFileSync(resolve(root, 'vitest.config.ts'), 'utf8')
 
@@ -220,7 +240,14 @@ describe('Python release workflows', () => {
     const macosCheck = buildSteps.find(step => isRecord(step) && step.name === 'Check macOS deployment target')
     const manylinuxSmoke = buildSteps.find(step => isRecord(step) && step.name === 'Run wheel in a manylinux 2.28 container')
     expect(call.inputs).toHaveProperty('targets')
-    expect(call.inputs).toMatchObject({ release: { type: 'boolean', default: false } })
+    expect(call.inputs).toMatchObject({
+      ci: { type: 'boolean', default: false },
+      release: { type: 'boolean', default: false },
+    })
+    expect(workflow.concurrency).toMatchObject({
+      group: 'build-single-exe-${{ github.workflow }}-${{ github.ref }}',
+    })
+    expect(plan.if).toContain('inputs.ci')
     expect(plan.if).toContain('inputs.release')
     expect(JSON.stringify(plan.steps)).toContain('pep440_version')
     expect(JSON.stringify(workflow)).toContain('macosx_14_0_arm64')

+ 16 - 0
scripts/smoke-python-runtime.py

@@ -792,6 +792,7 @@ def build_snapshot_files(
 ) -> dict[str, str]:
     """Render the SDK result and three persisted logs into stable expected outputs."""
     replacements = [(str(cwd), "{{cwd}}"), (SNAPSHOT_SESSION_ID, "{{parent}}")]
+    replacements.append((snapshot_workflow_run_id(result), "{{workflow-run}}"))
     for index, child_id in enumerate(child_ids, start=1):
         replacements.append((child_id, f"{{{{child-{index}}}}}"))
         agent_id = snapshot_agent_id(result, child_id)
@@ -824,6 +825,21 @@ def build_snapshot_files(
     return files
 
 
+def snapshot_workflow_run_id(result: "RunResult") -> str:
+    """Return the one workflow run id emitted by the advanced scenario."""
+    run_ids: set[str] = set()
+    for event in result.events:
+        event_type = event.get("type")
+        data = event.get("data")
+        if not isinstance(event_type, str) or not event_type.startswith("tool-workflow/"):
+            continue
+        if isinstance(data, dict) and isinstance(data.get("runId"), str):
+            run_ids.add(data["runId"])
+    if len(run_ids) != 1:
+        raise AssertionError(f"advanced snapshot expected one workflow run id: {sorted(run_ids)}")
+    return next(iter(run_ids))
+
+
 def snapshot_agent_id(result: "RunResult", child_id: str) -> str:
     """Find the successful subagent id paired with one child session."""
     for notification in result.notifications:

+ 170 - 66
scripts/snapshots/python-sdk-single-exe/advanced/result.json

@@ -874,9 +874,49 @@
       }
     },
     {
-      "type": "tool/result",
+      "type": "tool-workflow/run-start",
       "seq": 48,
       "time": 0,
+      "data": {
+        "runId": "{{workflow-run}}",
+        "name": "advanced-exe-snapshot"
+      }
+    },
+    {
+      "type": "tool-workflow/agent-start",
+      "seq": 49,
+      "time": 0,
+      "data": {
+        "runId": "{{workflow-run}}",
+        "seq": 1,
+        "label": "workflow-child",
+        "phase": "Delegate",
+        "childId": "{{child-2}}"
+      }
+    },
+    {
+      "type": "tool-workflow/agent-end",
+      "seq": 50,
+      "time": 0,
+      "data": {
+        "runId": "{{workflow-run}}",
+        "seq": 1,
+        "outcome": "completed"
+      }
+    },
+    {
+      "type": "tool-workflow/run-end",
+      "seq": 51,
+      "time": 0,
+      "data": {
+        "runId": "{{workflow-run}}",
+        "stopReason": "completed"
+      }
+    },
+    {
+      "type": "tool/result",
+      "seq": 52,
+      "time": 0,
       "data": {
         "turn": 1,
         "step": 4,
@@ -909,7 +949,7 @@
     },
     {
       "type": "step/end",
-      "seq": 49,
+      "seq": 53,
       "time": 0,
       "data": {
         "turn": 1,
@@ -918,7 +958,7 @@
     },
     {
       "type": "step/start",
-      "seq": 50,
+      "seq": 54,
       "time": 0,
       "data": {
         "turn": 1,
@@ -927,7 +967,7 @@
     },
     {
       "type": "assistant/chunk",
-      "seq": 51,
+      "seq": 55,
       "time": 0,
       "data": {
         "turn": 1,
@@ -941,7 +981,7 @@
     },
     {
       "type": "assistant/chunk",
-      "seq": 52,
+      "seq": 56,
       "time": 0,
       "data": {
         "turn": 1,
@@ -957,7 +997,7 @@
     },
     {
       "type": "assistant/chunk",
-      "seq": 53,
+      "seq": 57,
       "time": 0,
       "data": {
         "turn": 1,
@@ -976,7 +1016,7 @@
     },
     {
       "type": "assistant/chunk",
-      "seq": 54,
+      "seq": 58,
       "time": 0,
       "data": {
         "turn": 1,
@@ -992,7 +1032,7 @@
     },
     {
       "type": "assistant/chunk",
-      "seq": 55,
+      "seq": 59,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1007,7 +1047,7 @@
     },
     {
       "type": "assistant/message",
-      "seq": 56,
+      "seq": 60,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1035,17 +1075,17 @@
         }
       },
       "sourceEventSeqs": [
-        51,
-        52,
-        53,
-        54,
-        55
+        55,
+        56,
+        57,
+        58,
+        59
       ],
       "surfaceOp": "append"
     },
     {
       "type": "tool/call",
-      "seq": 57,
+      "seq": 61,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1057,7 +1097,7 @@
     },
     {
       "type": "tool/result",
-      "seq": 58,
+      "seq": 62,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1085,13 +1125,13 @@
         }
       },
       "sourceEventSeqs": [
-        57
+        61
       ],
       "surfaceOp": "append"
     },
     {
       "type": "step/end",
-      "seq": 59,
+      "seq": 63,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1100,7 +1140,7 @@
     },
     {
       "type": "step/start",
-      "seq": 60,
+      "seq": 64,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1109,7 +1149,7 @@
     },
     {
       "type": "request/header",
-      "seq": 61,
+      "seq": 65,
       "time": 0,
       "data": {
         "header": {
@@ -1141,7 +1181,7 @@
     },
     {
       "type": "assistant/chunk",
-      "seq": 62,
+      "seq": 66,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1155,7 +1195,7 @@
     },
     {
       "type": "assistant/chunk",
-      "seq": 63,
+      "seq": 67,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1169,7 +1209,7 @@
     },
     {
       "type": "assistant/chunk",
-      "seq": 64,
+      "seq": 68,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1186,7 +1226,7 @@
     },
     {
       "type": "assistant/chunk",
-      "seq": 65,
+      "seq": 69,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1202,7 +1242,7 @@
     },
     {
       "type": "assistant/chunk",
-      "seq": 66,
+      "seq": 70,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1217,7 +1257,7 @@
     },
     {
       "type": "assistant/message",
-      "seq": 67,
+      "seq": 71,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1243,17 +1283,17 @@
         }
       },
       "sourceEventSeqs": [
-        62,
-        63,
-        64,
-        65,
-        66
+        66,
+        67,
+        68,
+        69,
+        70
       ],
       "surfaceOp": "append"
     },
     {
       "type": "step/end",
-      "seq": 68,
+      "seq": 72,
       "time": 0,
       "data": {
         "turn": 1,
@@ -1262,7 +1302,7 @@
     },
     {
       "type": "turn/end",
-      "seq": 69,
+      "seq": 73,
       "time": 0,
       "data": {
         "turn": 1,
@@ -2883,6 +2923,21 @@
         }
       }
     },
+    {
+      "method": "session.event",
+      "payload": {
+        "sessionId": "{{parent}}",
+        "event": {
+          "type": "tool-workflow/run-start",
+          "seq": 48,
+          "time": 0,
+          "data": {
+            "runId": "{{workflow-run}}",
+            "name": "advanced-exe-snapshot"
+          }
+        }
+      }
+    },
     {
       "method": "subagent.started",
       "payload": {
@@ -3122,6 +3177,24 @@
         }
       }
     },
+    {
+      "method": "session.event",
+      "payload": {
+        "sessionId": "{{parent}}",
+        "event": {
+          "type": "tool-workflow/agent-start",
+          "seq": 49,
+          "time": 0,
+          "data": {
+            "runId": "{{workflow-run}}",
+            "seq": 1,
+            "label": "workflow-child",
+            "phase": "Delegate",
+            "childId": "{{child-2}}"
+          }
+        }
+      }
+    },
     {
       "method": "session.event",
       "payload": {
@@ -3326,13 +3399,44 @@
         ]
       }
     },
+    {
+      "method": "session.event",
+      "payload": {
+        "sessionId": "{{parent}}",
+        "event": {
+          "type": "tool-workflow/agent-end",
+          "seq": 50,
+          "time": 0,
+          "data": {
+            "runId": "{{workflow-run}}",
+            "seq": 1,
+            "outcome": "completed"
+          }
+        }
+      }
+    },
+    {
+      "method": "session.event",
+      "payload": {
+        "sessionId": "{{parent}}",
+        "event": {
+          "type": "tool-workflow/run-end",
+          "seq": 51,
+          "time": 0,
+          "data": {
+            "runId": "{{workflow-run}}",
+            "stopReason": "completed"
+          }
+        }
+      }
+    },
     {
       "method": "session.event",
       "payload": {
         "sessionId": "{{parent}}",
         "event": {
           "type": "tool/result",
-          "seq": 48,
+          "seq": 52,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3372,7 +3476,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "step/end",
-          "seq": 49,
+          "seq": 53,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3387,7 +3491,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "step/start",
-          "seq": 50,
+          "seq": 54,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3402,7 +3506,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/chunk",
-          "seq": 51,
+          "seq": 55,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3422,7 +3526,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/chunk",
-          "seq": 52,
+          "seq": 56,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3444,7 +3548,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/chunk",
-          "seq": 53,
+          "seq": 57,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3469,7 +3573,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/chunk",
-          "seq": 54,
+          "seq": 58,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3491,7 +3595,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/chunk",
-          "seq": 55,
+          "seq": 59,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3512,7 +3616,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/message",
-          "seq": 56,
+          "seq": 60,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3540,11 +3644,11 @@
             }
           },
           "sourceEventSeqs": [
-            51,
-            52,
-            53,
-            54,
-            55
+            55,
+            56,
+            57,
+            58,
+            59
           ],
           "surfaceOp": "append"
         }
@@ -3556,7 +3660,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "tool/call",
-          "seq": 57,
+          "seq": 61,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3574,7 +3678,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "tool/result",
-          "seq": 58,
+          "seq": 62,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3602,7 +3706,7 @@
             }
           },
           "sourceEventSeqs": [
-            57
+            61
           ],
           "surfaceOp": "append"
         }
@@ -3614,7 +3718,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "step/end",
-          "seq": 59,
+          "seq": 63,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3629,7 +3733,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "step/start",
-          "seq": 60,
+          "seq": 64,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3644,7 +3748,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "request/header",
-          "seq": 61,
+          "seq": 65,
           "time": 0,
           "data": {
             "header": {
@@ -3682,7 +3786,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/chunk",
-          "seq": 62,
+          "seq": 66,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3702,7 +3806,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/chunk",
-          "seq": 63,
+          "seq": 67,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3722,7 +3826,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/chunk",
-          "seq": 64,
+          "seq": 68,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3745,7 +3849,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/chunk",
-          "seq": 65,
+          "seq": 69,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3767,7 +3871,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/chunk",
-          "seq": 66,
+          "seq": 70,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3788,7 +3892,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "assistant/message",
-          "seq": 67,
+          "seq": 71,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3814,11 +3918,11 @@
             }
           },
           "sourceEventSeqs": [
-            62,
-            63,
-            64,
-            65,
-            66
+            66,
+            67,
+            68,
+            69,
+            70
           ],
           "surfaceOp": "append"
         }
@@ -3830,7 +3934,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "step/end",
-          "seq": 68,
+          "seq": 72,
           "time": 0,
           "data": {
             "turn": 1,
@@ -3845,7 +3949,7 @@
         "sessionId": "{{parent}}",
         "event": {
           "type": "turn/end",
-          "seq": 69,
+          "seq": 73,
           "time": 0,
           "data": {
             "turn": 1,

+ 26 - 22
scripts/snapshots/python-sdk-single-exe/advanced/session.jsonl

@@ -47,25 +47,29 @@
 {"type":"assistant/chunk","seq":45,"time":0,"data":{"turn":1,"step":4,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
 {"type":"assistant/message","seq":46,"time":0,"data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\": \"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\", \"meta\": {\"name\": \"advanced-exe-snapshot\", \"description\": \"exercise one packaged workflow child\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"smoke-model"},"id":"{{messageId}}"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[41,42,43,44,45],"surfaceOp":"append"}
 {"type":"tool/call","seq":47,"time":0,"data":{"turn":1,"step":4,"callId":"advanced-workflow","name":"workflow","arguments":"{\"script\": \"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\", \"meta\": {\"name\": \"advanced-exe-snapshot\", \"description\": \"exercise one packaged workflow child\"}}"}}
-{"type":"tool/result","seq":48,"time":0,"data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-exe-snapshot\" completed (1 agent).\nReturn value:\n{\n  \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"{{messageId}}"}},"sourceEventSeqs":[47],"surfaceOp":"append"}
-{"type":"step/end","seq":49,"time":0,"data":{"turn":1,"step":4}}
-{"type":"step/start","seq":50,"time":0,"data":{"turn":1,"step":5}}
-{"type":"assistant/chunk","seq":51,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
-{"type":"assistant/chunk","seq":52,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-unmount","name":"cordis_unmount","argumentsDelta":"{\"id\": \"dyn-1\"}"}}}
-{"type":"assistant/chunk","seq":53,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\": \"dyn-1\"}"}}}}
-{"type":"assistant/chunk","seq":54,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
-{"type":"assistant/chunk","seq":55,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
-{"type":"assistant/message","seq":56,"time":0,"data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\": \"dyn-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"smoke-model"},"id":"{{messageId}}"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[51,52,53,54,55],"surfaceOp":"append"}
-{"type":"tool/call","seq":57,"time":0,"data":{"turn":1,"step":5,"callId":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\": \"dyn-1\"}"}}
-{"type":"tool/result","seq":58,"time":0,"data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-unmount"},"content":[{"type":"tool-result","toolCallId":"advanced-unmount","content":[{"type":"text","text":"Temporary Plugin dyn-1 was unmounted and removed."}],"isError":false}],"role":"user","id":"{{messageId}}"}},"sourceEventSeqs":[57],"surfaceOp":"append"}
-{"type":"step/end","seq":59,"time":0,"data":{"turn":1,"step":5}}
-{"type":"step/start","seq":60,"time":0,"data":{"turn":1,"step":6}}
-{"type":"request/header","seq":61,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"smoke-model","maxTokens":256000,"reasoningEffort":"high"},"adapterDefaults":{"reasoningEffort":true,"maxTokens":true},"system":"{{system}}","tools":["cordis_inspect","cordis_mount","cordis_unmount","run_code","subagent","task_kill","task_list","task_output","workflow"]},"reason":"change"}}
-{"type":"assistant/chunk","seq":62,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
-{"type":"assistant/chunk","seq":63,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"text-delta","index":0,"text":"ADVANCED_EXECUTABLE_OK"}}}
-{"type":"assistant/chunk","seq":64,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_EXECUTABLE_OK"}}}}
-{"type":"assistant/chunk","seq":65,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
-{"type":"assistant/chunk","seq":66,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
-{"type":"assistant/message","seq":67,"time":0,"data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_EXECUTABLE_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"smoke-model"},"id":"{{messageId}}"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[62,63,64,65,66],"surfaceOp":"append"}
-{"type":"step/end","seq":68,"time":0,"data":{"turn":1,"step":6}}
-{"type":"turn/end","seq":69,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}
+{"type":"tool-workflow/run-start","seq":48,"time":0,"data":{"runId":"{{workflow-run}}","name":"advanced-exe-snapshot"}}
+{"type":"tool-workflow/agent-start","seq":49,"time":0,"data":{"runId":"{{workflow-run}}","seq":1,"label":"workflow-child","phase":"Delegate","childId":"{{child-2}}"}}
+{"type":"tool-workflow/agent-end","seq":50,"time":0,"data":{"runId":"{{workflow-run}}","seq":1,"outcome":"completed"}}
+{"type":"tool-workflow/run-end","seq":51,"time":0,"data":{"runId":"{{workflow-run}}","stopReason":"completed"}}
+{"type":"tool/result","seq":52,"time":0,"data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-exe-snapshot\" completed (1 agent).\nReturn value:\n{\n  \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"{{messageId}}"}},"sourceEventSeqs":[47],"surfaceOp":"append"}
+{"type":"step/end","seq":53,"time":0,"data":{"turn":1,"step":4}}
+{"type":"step/start","seq":54,"time":0,"data":{"turn":1,"step":5}}
+{"type":"assistant/chunk","seq":55,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
+{"type":"assistant/chunk","seq":56,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-unmount","name":"cordis_unmount","argumentsDelta":"{\"id\": \"dyn-1\"}"}}}
+{"type":"assistant/chunk","seq":57,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\": \"dyn-1\"}"}}}}
+{"type":"assistant/chunk","seq":58,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
+{"type":"assistant/chunk","seq":59,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
+{"type":"assistant/message","seq":60,"time":0,"data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\": \"dyn-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"smoke-model"},"id":"{{messageId}}"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[55,56,57,58,59],"surfaceOp":"append"}
+{"type":"tool/call","seq":61,"time":0,"data":{"turn":1,"step":5,"callId":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\": \"dyn-1\"}"}}
+{"type":"tool/result","seq":62,"time":0,"data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-unmount"},"content":[{"type":"tool-result","toolCallId":"advanced-unmount","content":[{"type":"text","text":"Temporary Plugin dyn-1 was unmounted and removed."}],"isError":false}],"role":"user","id":"{{messageId}}"}},"sourceEventSeqs":[61],"surfaceOp":"append"}
+{"type":"step/end","seq":63,"time":0,"data":{"turn":1,"step":5}}
+{"type":"step/start","seq":64,"time":0,"data":{"turn":1,"step":6}}
+{"type":"request/header","seq":65,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"smoke-model","maxTokens":256000,"reasoningEffort":"high"},"adapterDefaults":{"reasoningEffort":true,"maxTokens":true},"system":"{{system}}","tools":["cordis_inspect","cordis_mount","cordis_unmount","run_code","subagent","task_kill","task_list","task_output","workflow"]},"reason":"change"}}
+{"type":"assistant/chunk","seq":66,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
+{"type":"assistant/chunk","seq":67,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"text-delta","index":0,"text":"ADVANCED_EXECUTABLE_OK"}}}
+{"type":"assistant/chunk","seq":68,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_EXECUTABLE_OK"}}}}
+{"type":"assistant/chunk","seq":69,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
+{"type":"assistant/chunk","seq":70,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
+{"type":"assistant/message","seq":71,"time":0,"data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_EXECUTABLE_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"smoke-model"},"id":"{{messageId}}"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[66,67,68,69,70],"surfaceOp":"append"}
+{"type":"step/end","seq":72,"time":0,"data":{"turn":1,"step":6}}
+{"type":"turn/end","seq":73,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor