docs: tighten agent execution contracts

This commit is contained in:
Tianyi Cui
2026-07-19 11:58:55 +08:00
parent cfe9b9617d
commit 9912918a48
12 changed files with 41 additions and 87 deletions

View File

@@ -121,7 +121,7 @@ Every live agent owns a scoped `agent.ctx`. Its registrations shadow globals, re
### Agent Execution Context
`AgentLoop` wraps each concrete driver in process-local `ctx.agentExecution`; child creation and setup stay outside its boundary, and explicit identities remain authoritative. See the [package contract](../packages/core/agent-execution/README.md) and [decision](rfc/implemented/architecture/2026-07-15-agent-execution-context.md).
`AgentLoop` establishes process-local `ctx.agentExecution` around each driver; the [decision](rfc/implemented/architecture/2026-07-15-agent-execution-context.md) owns boundary and explicit-identity rules.
## State

View File

@@ -415,7 +415,7 @@ The [event taxonomy](../architecture.md#event) owns the `agent/*` lifecycle, che
## Agent execution context
`AgentExecution` is the process-local ambient frame established around a concrete driver's lifetime. It holds the exact Agent rather than duplicating Session or step state; ambient presence is neither liveness proof nor authorization.
`AgentExecution` is the process-local ambient frame established around a concrete driver's lifetime. It holds the exact Agent object rather than duplicating Session or step state; ambient presence is neither liveness proof nor authorization.
Source: [`packages/core/agent-execution/src/types.ts`](../../packages/core/agent-execution/src/types.ts)

View File

@@ -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
2026-07-15-agent-execution-context.md: a8d1338a6fc277c3adcd1ed835a54dd0b667ce4b
2026-07-15-agent-execution-context.zh.md: 4cf78ce2c6ecba15eb7ae90479f877ce4e07cfe1
2026-07-15-agent-execution-context.md: 2ea88cddf7a686713157c77ce1d7520082a9da28
2026-07-15-agent-execution-context.zh.md: 1c4e0ba9c3fa787dfa816eff4c5d04cff5c2f7b1

View File

@@ -8,63 +8,41 @@ English | [中文](2026-07-15-agent-execution-context.zh.md)
The harness has two useful but different notions of context. A Cordis `Context` selects services, registration ownership, and lifetime; `agent.ctx` is the flat registration scope owned by one live Agent. Agent and Session identity instead describe the subject of an asynchronous operation. Changing a root `ctx.agent` to mean “whichever Agent is running” would conflate those meanings and fail when one process drives Agents concurrently.
Deep process-local infrastructure still needs a trusted initiating Agent. Capability transports, tracing helpers, loggers, and gateway clients may sit below the explicit loop, tool, and request parameters. Threading `agent` through every private helper adds plumbing, while a process-global mutable slot is incorrect across `await`. Model-visible arguments are also unsuitable because a model must not choose a trusted Session or routing header. This is mandatory control infrastructure rather than optional model-visible context enrichment.
Deep process-local infrastructure sometimes needs a trusted initiating Agent below explicit loop, tool, and request parameters—for example, a host-aware transport, tracing helper, logger, or gateway client. Requiring every private helper to forward `agent` adds repetition, while a process-global mutable slot is incorrect across `await`. Model-visible arguments are unsuitable because a model must not choose a trusted Session or routing header. The carrier is mandatory control infrastructure rather than optional model-visible context.
## Decision
`@deepseek-ai/dsh-agent-execution` provides the mandatory `ctx.agentExecution` service using Node `AsyncLocalStorage`. The frame contains only the exact live Agent:
`@deepseek-ai/dsh-agent-execution` provides the mandatory `ctx.agentExecution` service using Node `AsyncLocalStorage`. The named `AgentExecution` frame contains only the exact Agent object; the [core-data catalog](../../../core-data-structures/core.md#agent-execution-context) owns the literal frame and service types.
```text
export interface AgentExecution {
readonly agent: Agent
}
`current()` reads optionally, `require()` throws `no agent execution context is active`, and `run()` preserves the operation's exact synchronous value or Promise. `run(undefined, operation)` establishes a clearing boundary for work that must not inherit an Agent. Session remains derived as `execution.agent.session`; turn, step, tool call, `signal`, model, `cwd`, sandbox, and authorization stay with their existing owners.
export interface AgentExecutionService {
current(): AgentExecution | undefined
require(): AgentExecution
run<T>(execution: AgentExecution | undefined, operation: () => T): T
}
```
`AgentLoop` injects the service and wraps each concrete driver's complete `runLoop` lifetime in `agentExecution.run({ agent }, ...)`. Concurrent drivers therefore receive independent stores, a child driver shadows its parent, and the parent store returns when the child boundary settles. Creation, persistence load, and unpublished `setup(agentCtx)` remain outside the child's driver boundary: creation initiated by a parent runs under the parent identity, while `agentCtx.agent` explicitly identifies the child.
`current()` is optional, `require()` throws `no agent execution context is active`, and `run()` preserves the operation's exact synchronous value or Promise. `run(undefined, operation)` establishes a real clearing boundary for work that must not inherit an Agent. A comparable implementation observed an uncleared ambient value crossing scheduled work into a later turn; the explicit undefined boundary prevents that class of leak. Session remains derived as `execution.agent.session`; turn, step, tool call, signal, model, cwd, sandbox, and authorization stay with their existing owners.
`AgentLoop` injects the service and wraps each concrete driver's complete `runLoop` lifetime in `agentExecution.run({ agent }, ...)`. Concurrent drivers therefore receive independent stores, a child driver shadows its parent, and the parent store returns when the child boundary settles. Creation, persistence load, and unpublished `setup(agentCtx)` remain outside the child's boundary: creation initiated by a parent runs under the parent identity, while `agentCtx.agent` explicitly identifies the child.
Ambient identity does not replace explicit contracts. `ToolExecution.agent`, `AssembleContext.agent`, `GenerateOptions.sessionId`, task ownership, parent/child requests, `ctx.agent`, `agentCtx.agent`, approval and hook subjects, cwd selection, cancellation, worker/process messages, persistence records, and wire identity remain explicit. A remote boundary materializes the identity it needs into its typed request because ALS is process-local.
Ambient identity does not replace explicit contracts. `ToolExecution.agent`, `AssembleContext.agent`, `GenerateOptions.sessionId`, task ownership, parent/child requests, `ctx.agent`, `agentCtx.agent`, approval and hook subjects, `cwd` selection, cancellation, worker/process messages, persistence records, and wire identity remain explicit. A remote boundary materializes the identity it needs into its typed request because ALS is process-local.
The provider uses an ordered composite effect. Teardown first rejects new boundaries, then removes the service and awaits injected dependents such as AgentLoop, then waits for active returned-Promise boundaries before calling `AsyncLocalStorage.disable()`. `current()` and `require()` remain usable through a retained in-flight service reference while that drain runs; after disposal, retained calls throw `agent execution service is disposed`. Root Context disposal may start sibling fiber teardown concurrently, so active-boundary counting is required in addition to Cordis dependency ordering.
Asynchronous resources created inside `run()` inherit its store even when the returned operation does not await them. Agent-owned foreground work may inherit `{ agent }` but keeps the explicit cancellation and disposal contract of its execution seam. Unrelated timers, queues, and deployment infrastructure start under `run(undefined, operation)` and own an explicit stop. Queue, worker, process, and wire boundaries serialize identity rather than expecting ALS propagation.
`run()` does not own detached work: provider drain tracks only the Promise returned by `operation`. Asynchronous resources created inside the boundary inherit its store until they settle or ALS is disabled, so their owning seam must stop unreturned work explicitly. Agent-owned foreground work returns its lifetime and keeps its cancellation contract. Unrelated timers, queues, and deployment infrastructure start under `run(undefined, operation)`; queue, worker, process, and wire boundaries serialize identity rather than expecting ALS propagation.
A host-aware transport may derive a deployment-owned header such as `X-Harness-Session-Id` from `ctx.agentExecution.require().agent.session.id`; the header is absent from model-visible schema and arguments. No production MCP or Web transport adopts such a header in this decision. A test-double transport proves the trusted boundary without assigning host routing policy to an existing provider-neutral seam.
This decision extends the [Agent registration-scope contract](2026-07-08-agent-scope-contexts.md) and its [runtime design](2026-07-12-agent-scope-runtime-design.md); it does not change their static `agent.ctx` meaning.
## Reference model
| Claude Code | Harness design |
|---|---|
| AppState store | Cordis deployment services and their owned live state |
| QueryEngine | Agent driver plus loop-owned runtime state |
| ToolUseContext | Explicit Agent, tool, and request parameters at capability seams |
| AgentContext ALS | Narrow `AgentExecution` carrier |
| Transcript | Event-sourced `Session` and persistence backends |
## Verification
Service tests pin optional and required reads, synchronous and awaited propagation, overlapping and nested boundaries, explicit clearing, restoration after throw or rejection, exact return identity, drain ordering, and disposed-reference errors. AgentLoop integration tests run overlapping real drivers, nested parent/child creation, agentless direct tool execution, cancellation during provider/root teardown, service restart, and a captured Agent after disposal. Detached-work coverage prevents context leakage without changing existing explicit cancellation contracts.
Service tests pin optional and required reads, exact synchronous and cross-realm Promise identity, overlapping, nested, and cleared boundaries, restoration after throws or rejection, drain ordering, and retained-reference errors. AgentLoop integration pins concurrent and nested drivers, agentless calls, missing-provider activation, service restart, and provider/root teardown. Composition, module-graph, build, and runtime-closure checks keep the provider wired through the default bundle, SDK spine, Python runtime closure, and direct AgentLoop harnesses.
The test-double capability transport derives `X-Harness-Session-Id` internally and asserts that neither its tool schema nor logged arguments contains an identity field. Composition tests and generated catalogs keep the provider present in the default bundle, SDK spine, Python runtime closure, and direct AgentLoop harnesses; a missing provider leaves AgentLoop inactive. Documentation checks keep the repository layout in `AGENTS.md`, the package table in `packages/core/README.md`, and the group description in `packages/README.md` aligned with the mandatory provider.
Only a test-double host-aware transport consumes ambient identity; it derives `X-Harness-Session-Id` internally and verifies that tool schema and logged arguments contain no identity field. The service deliberately does not drain async work omitted from the Promise returned by `operation`; that work remains subject to its owner's explicit stop contract.
## Alternatives considered
**Pass Agent through every function.** Public, worker, process, persistence, and wire boundaries continue to do this, but requiring every process-local private helper to carry Agent adds plumbing without improving trust. ALS is confined to the asynchronous chain inside those explicit boundaries.
**Pass Agent through every function.** Public, worker, process, persistence, and wire boundaries continue to do this, but requiring every process-local private helper to carry Agent adds repetitive forwarding without improving trust. ALS is confined to the asynchronous chain inside those explicit boundaries.
**Make `ctx.agent` dynamic.** `ctx.agent` already means the static Agent associated with an Agent-scoped Cordis context. Changing the root meaning would mix registration and execution scopes and make concurrent behavior surprising.
**Store a complete mutable runtime frame.** Agent, Session, inbox, cancellation, turn, step, tool execution, and persistence already have authoritative owners. Duplicating them would create stale snapshots and another lifecycle. The wrapper leaves room for a separately justified stale-safe label without flattening the store to a bare Agent.
**Store a complete mutable runtime frame.** Agent, Session, inbox, cancellation, turn, step, tool execution, and persistence already have authoritative owners. Duplicating them would create stale snapshots and another lifecycle. A named frame makes the execution-context boundary explicit without duplicating owner state.
**Include a step `AbortSignal`, cwd, sandbox, or authorization.** Their lifetimes and authority do not match the driver boundary, and their existing seams already pass them explicitly. Adding a control capability requires a separate decision and nested lifecycle contract.
**Include a step `AbortSignal`, `cwd`, sandbox, or authorization.** Their lifetimes and authority do not match the driver boundary, and their existing seams already pass them explicitly. Adding a control capability requires a separate decision and nested lifecycle contract.
**Use a process-global `currentAgent`.** Concurrent Agents and subagents overwrite one another across awaited continuations, so a mutable global is correct only under a serialization guarantee the harness does not make.
@@ -76,8 +54,8 @@ The test-double capability transport derives `X-Harness-Session-Id` internally a
Deep infrastructure gains one trusted process-local initiating Agent without widening existing tool and capability requests. Concurrent and nested drivers isolate automatically, AgentLoop stays inactive when the provider is absent, and HMR/root disposal reaches quiescence before ALS is disabled.
The dependency is implicit in function signatures and carries a live capability object. Consumers must restrict it to cross-cutting infrastructure, treat ambient presence as neither liveness nor authorization, and retain explicit cancellation and ownership checks. ALS also has an always-on propagation cost and does not cross worker, process, HTTP, or durable queue boundaries.
The dependency is implicit in function signatures and carries a capability-bearing Agent object. Consumers must restrict it to cross-cutting infrastructure, treat ambient presence as neither liveness nor authorization, and retain explicit cancellation and ownership checks. ALS also has an always-on propagation cost and does not cross worker, process, HTTP, or durable queue boundaries.
The teardown design deliberately accepts Node's [Stability 1 (Experimental)](https://nodejs.org/api/async_context.html#asynclocalstoragedisable) `AsyncLocalStorage.disable()` dependency. Node requires `disable()` before an ALS instance can be garbage-collected, which matters when HMR replaces provider-owned instances; the service state guard prevents a later `run()` from re-entering the instance after disposal.
The frame deliberately omits turn, step, signal, cwd, sandbox, and authorization. A real consumer that cannot use existing explicit fields must justify any refinement separately; a stale copied field may at most mislabel telemetry, never grant control.
The frame deliberately omits turn, step, `signal`, `cwd`, sandbox, and authorization. A real consumer that cannot use existing explicit fields must justify any refinement separately; a stale copied field may at most mislabel telemetry, never grant control.

View File

@@ -8,65 +8,43 @@ Status: implemented
Harness 中存在两种有用但不同的上下文概念。Cordis `Context` 负责选择服务、注册归属和生命周期;`agent.ctx` 是一个存活 Agent 所拥有的扁平注册作用域。Agent 与会话身份描述的则是异步操作主体。若把根 `ctx.agent` 改成「当前正在运行的 Agent」就会混淆这两种含义并在单进程并发驱动多个 Agent 时失效。
进程内深层基础设施仍需要可信的发起 Agent。能力传输层、追踪辅助函数、日志器网关客户端可能位于显式 loop、工具及请求参数的下层。在每个私有辅助函数中传递 `agent`增加管道代码,而进程级可变槽会在 `await` 之间发生并发错误。模型可见参数同样不合适,因为模型不选择可信的会话或路由请求头。它是必载控制基础设施,而不是模型可见的可选上下文增强
进程内深层基础设施有时需要在显式传递的循环、工具及请求参数之下获取可信的发起 Agent,例如宿主感知传输层、追踪辅助函数、日志器网关客户端。要求每个私有辅助函数都转发 `agent`造成重复,而进程级可变槽会在 `await` 发生并发错误。模型可见参数也不适用,因为模型不选择可信的会话或路由请求头。该载体属于必需的控制基础设施,而模型可见的可选上下文。
## 决策
`@deepseek-ai/dsh-agent-execution` 使用 Node `AsyncLocalStorage` 提供必`ctx.agentExecution` 服务。该帧只包含准确的存活 Agent
`@deepseek-ai/dsh-agent-execution` 使用 Node `AsyncLocalStorage` 提供必`ctx.agentExecution` 服务。命名的 `AgentExecution` 帧仅包含同一个 Agent 对象;[核心数据目录](../../../core-data-structures/core.md#agent-execution-context)是帧与服务字面类型定义的真源。
```text
export interface AgentExecution {
readonly agent: Agent
}
`current()` 用于可选读取,`require()` 抛出 `no agent execution context is active``run()` 保留操作返回的同步值或 Promise 本身。`run(undefined, operation)` 会建立清空边界,供不得继承 Agent 的工作使用。会话仍通过 `execution.agent.session` 推导;轮次、步骤、工具调用、`signal`、模型、`cwd`、沙箱和授权继续由现有归属方管理。
export interface AgentExecutionService {
current(): AgentExecution | undefined
require(): AgentExecution
run<T>(execution: AgentExecution | undefined, operation: () => T): T
}
```
`AgentLoop` 注入该服务,并用 `agentExecution.run({ agent }, ...)` 包裹每个具体驱动的完整 `runLoop` 生命周期。因此,并发驱动使用彼此独立的存储,子驱动会遮蔽父驱动,子边界结束后父存储得到恢复。创建、持久化加载和尚未发布的 `setup(agentCtx)` 位于子驱动边界之外:由父 Agent 发起的创建使用父身份,而 `agentCtx.agent` 显式标识子 Agent。
`current()` 执行可选读取,`require()` 抛出 `no agent execution context is active``run()` 保留操作返回的准确同步值或 Promise。`run(undefined, operation)` 会建立真实的清空边界,供不得继承 Agent 的工作使用。一个同类实现曾观察到未清空的隐式值穿过已调度工作泄漏进后续轮次;显式 undefined 边界可以防止这类泄漏。会话仍通过 `execution.agent.session` 推导轮次、步骤、工具调用、signal、模型、cwd、沙箱和授权继续由现有归属方管理
`AgentLoop` 注入该服务,并用 `agentExecution.run({ agent }, ...)` 包裹每个具体驱动的完整 `runLoop` 生命周期。因此,并发驱动使用彼此独立的存储,子驱动会遮蔽父驱动,子边界结束后父存储得到恢复。创建、持久化加载和尚未发布的 `setup(agentCtx)` 位于子边界之外:由父 Agent 发起的创建使用父身份,而 `agentCtx.agent` 显式标识子 Agent。
隐式身份不会取代显式契约。`ToolExecution.agent``AssembleContext.agent``GenerateOptions.sessionId`、任务归属、父子请求、`ctx.agent``agentCtx.agent`、审批与 hook 主体、cwd 选择、取消、worker/进程消息、持久化记录及协议身份都保持显式传递。远程边界会把所需身份写入类型化请求,因为 ALS 只在进程内有效。
隐式身份不会取代显式契约。`ToolExecution.agent``AssembleContext.agent``GenerateOptions.sessionId`、任务归属、父子请求、`ctx.agent``agentCtx.agent`、审批与 hook 主体、`cwd` 选择、取消、worker 和进程消息、持久化记录及协议身份都保持显式传递。远程边界会把所需身份写入类型化请求,因为 ALS 只在进程内有效
提供方使用有序复合 effect。teardown 会先拒绝新边界,再移除服务并等待 AgentLoop 等注入方排空,随后等待活动的返回 Promise 边界,最后调用 `AsyncLocalStorage.disable()`。排空期间,进行中代码可通过保留的服务引用继续调用 `current()``require()`dispose 后,保留引用会抛出 `agent execution service is disposed`。根 Context dispose 可能并发启动同级 fiber 的 teardown因此除 Cordis 依赖顺序外还必须统计活动边界。
`run()` 内创建的异步资源会继承其存储,即使返回的操作没有等待它们。Agent 所拥有的前台工作可以继承 `{ agent }`,但仍使用其执行 seam 的显式取消和 dispose 契约。无关的定时器、队列和部署基础设施在 `run(undefined, operation)` 下启动,并拥有显式停止操作。队列、worker、进程和协议边界必须序列化身份不能期待 ALS 传播。
`run()` 不负责管理脱离返回链的工作:提供方排空只跟踪 `operation` 返回的 Promise。边界内创建的异步资源会继承其存储直到自身结束或 ALS 被禁用;所属 seam 必须显式停止未纳入返回 Promise 的工作。Agent 所前台工作会把完整生命周期纳入返回值,并保留显式取消契约。无关的定时器、队列和部署基础设施在 `run(undefined, operation)` 下启动队列、worker、进程和协议边界必须序列化身份不能期待 ALS 传播。
宿主感知的传输层可以从 `ctx.agentExecution.require().agent.session.id` 推导由部署方拥有的 `X-Harness-Session-Id` 等请求头;模型可见 schema 和参数中不包含该请求头。本决策不让现有生产 MCP 或 Web 传输层采用此请求头。测试替身传输层用于证明可信边界,而不会把宿主路由策略分配给现有的提供方无关 seam。
本决策扩展 [Agent 注册作用域契约](2026-07-08-agent-scope-contexts.md)及其[运行时设计](2026-07-12-agent-scope-runtime-design.md),不会改变其中 `agent.ctx` 的静态含义。
## 参考模型
| Claude Code | Harness 中的设计 |
|---|---|
| AppState store | Cordis 部署服务及其拥有的实时状态 |
| QueryEngine | Agent 驱动及 loop 所拥有的运行时状态 |
| ToolUseContext | 能力边界上的显式 Agent、工具和请求参数 |
| AgentContext ALS | 窄粒度 `AgentExecution` 载体 |
| Transcript | 事件溯源 `Session` 与持久化后端 |
## 验证
服务测试锁定可选与必需读取、同步与跨 `await` 传播、并发嵌套边界、显式清空、throw 或 rejection 后的恢复、准确返回值身份、排空顺序及已 dispose 引用错误。AgentLoop 集成测试覆盖重叠的真实驱动、嵌套父子创建、无 Agent 的直接工具执行、提供方或根 Context teardown 期间的取消、服务重启,以及 Agent dispose 后保留的引用。针对脱离主调用链的异步工作的测试会防止上下文泄漏,同时不改变现有显式取消契约
服务测试锁定可选与必需读取、同步值和跨 realm Promise 的引用身份、并发嵌套及清空边界、同步抛错或 Promise 拒绝后的恢复、排空顺序及保留引用错误。AgentLoop 集成测试锁定并发与嵌套驱动、无 Agent 调用、缺少提供方时的激活行为、服务重启,以及提供方或根 Context 的销毁流程。组合、模块图、构建及运行时闭包检查确保默认组合包、SDK 主干、Python 运行时闭包及直接 AgentLoop harness 都装载提供方
测试替身能力传输层在内部推导 `X-Harness-Session-Id`,并断言工具 schema 与记录参数都不包含身份字段。组合测试和生成目录确保默认 bundle、SDK 主干、Python 运行时闭包及直接 AgentLoop harness 都装载提供方;缺少提供方时 AgentLoop 保持未激活。文档检查确保 `AGENTS.md` 中的仓库布局、`packages/core/README.md` 中的包表,以及 `packages/README.md` 中的分组说明都与该必载提供方保持一致
只有测试替身形式的宿主感知传输层消费隐式身份;它在内部推导 `X-Harness-Session-Id`,并验证工具 schema 与记录参数都不包含身份字段。服务有意不排空 `operation` 返回的 Promise 之外的异步工作;这类工作仍由所属方的显式停止契约管理
## 考虑过的替代方案
**在每个函数中传递 Agent。** 公开、worker、进程、持久化和协议边界继续显式传递但要求每个进程内私有辅助函数都携带 Agent 只会增加管道代码不会提高可信度。ALS 仅限于这些显式边界内部的异步调用链。
**在每个函数中传递 Agent。** 公开、worker、进程、持久化和协议边界继续显式传递但要求每个进程内私有辅助函数都携带 Agent 只会造成重复转发不会提高可信度。ALS 仅限于这些显式边界内部的异步调用链。
**让 `ctx.agent` 变成动态值。** `ctx.agent` 已经表示与 Agent 作用域 Cordis 上下文静态关联的 Agent。改变根上下文的含义会混合注册作用域与执行作用域并让并发行为变得意外。
**保存完整的可变运行时帧。** Agent、会话、inbox、取消、轮次、步骤、工具执行和持久化已经有各自的真源。重复保存会产生陈旧快照和另一套生命周期。包装对象为另行论证的陈旧安全标签保留扩展空间,而不会把存储简化成裸 Agent
**保存完整的可变运行时帧。** Agent、会话、inbox、取消、轮次、步骤、工具执行和持久化已经有各自的真源。重复保存会产生陈旧快照和另一套生命周期。命名帧能够明确标识执行上下文边界,而不重复保存归属方状态
**包含步骤级 `AbortSignal`、cwd、沙箱或授权。** 它们的生命周期权限不匹配驱动边界,而且现有 seam 已经显式传递这些值。新增控制能力需要独立决策和嵌套生命周期契约。
**包含步骤级 `AbortSignal`、`cwd`、沙箱或授权。** 它们的生命周期权限范围与驱动边界不一致,而且现有 seam 已经显式传递这些值。新增控制能力需要独立决策和嵌套生命周期契约。
**使用进程级 `currentAgent`。** 并发 Agent 和 subagent 会在异步 continuation 间相互覆盖,因此可变全局值只在 Harness 不具备的串行保证下才正确。
**使用进程级 `currentAgent`。** 并发 Agent 和 subagent 会在异步延续执行之间相互覆盖,因此可变全局值只在 Harness 不具备的串行保证下才正确。
**从模型可见参数推导身份。** 不能信任模型或用户输入来选择会话、租户或沙箱路由。
@@ -74,10 +52,10 @@ export interface AgentExecutionService {
## 后果
深层基础设施可以获得一个可信的进程内发起 Agent而无需加宽现有工具和能力请求。并发及嵌套驱动会自动隔离缺少提供方时 AgentLoop 保持未激活HMR 或根 Context dispose 会在禁用 ALS 前达到静止状态
深层基础设施可以获得一个可信的进程内发起 Agent而无需加宽现有工具和能力请求。并发及嵌套驱动会自动隔离缺少提供方时 AgentLoop 保持未激活HMR 或根 Context dispose 会在禁用 ALS 前完成排空
该依赖不会出现在函数签名中,并且携带一个存活能力对象。消费方必须将其限制在横切基础设施中把隐式存在视为既不证明存活、也不授予权限并保留显式取消和归属检查。ALS 还有常驻传播成本,也无法跨越 worker、进程、HTTP 或持久化队列边界。
该依赖不会出现在函数签名中,并且携带一个具有控制能力的 Agent 对象。消费方必须将其限制在横切基础设施中把隐式存在视为既不证明存活、也不授予权限并保留显式取消和归属检查。ALS 还有常驻传播成本,也无法跨越 worker、进程、HTTP 或持久化队列边界。
teardown 设计有意接受 Node [Stability 1实验性](https://nodejs.org/api/async_context.html#asynclocalstoragedisable) `AsyncLocalStorage.disable()` 依赖。Node 要求在 ALS 实例可被垃圾回收前调用 `disable()`,这对 HMR 替换提供方所拥有的实例尤为重要;服务状态守卫会阻止 dispose 后通过后续 `run()` 重新进入该实例。
销毁设计有意依赖 Node [Stability 1实验性](https://nodejs.org/api/async_context.html#asynclocalstoragedisable) API `AsyncLocalStorage.disable()`。Node 要求在 ALS 实例可被垃圾回收前调用 `disable()`,这对 HMR 替换提供方所拥有的实例尤为重要;服务状态守卫会阻止 dispose 后通过后续 `run()` 重新进入该实例。
该帧有意省略轮次、步骤、signalcwd、沙箱和授权。若真实消费方无法使用现有显式字段必须另行论证扩展陈旧字段最多只能误标遥测数据绝不能授予控制权。
该帧有意省略轮次、步骤、`signal``cwd`、沙箱和授权。若真实消费方无法使用现有显式字段,必须另行论证扩展;陈旧字段最多只能误标遥测数据,绝不能授予控制权。