Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification

# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-22-unified-send-and-coalesced-user-messages.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-22-unified-send-and-coalesced-user-messages.md
#	.agents/notes/implemented/architecture/2026-07-22-unified-send-and-coalesced-user-messages.zh.md
#	.agents/notes/implemented/feature/2026-07-21-tui-skill-slash-command.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-21-tui-skill-slash-command.md
#	.agents/notes/implemented/feature/2026-07-21-tui-skill-slash-command.zh.md
#	.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.i18n.yaml
#	.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.md
#	.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.zh.md
#	docs/architecture.i18n.yaml
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/core.i18n.yaml
#	docs/core-data-structures/core.md
#	docs/core-data-structures/core.zh.md
#	docs/defensive-patterns.i18n.yaml
#	packages/client/runtime/src/client/sessions/session.ts
#	packages/client/runtime/tests/queue-store.spec.ts
#	packages/context/time-context/tests/time-context.spec.ts
#	packages/context/workspace-context/tests/workspace-context.spec.ts
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/core/agent-loop/README.i18n.yaml
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/README.zh.md
#	packages/core/agent-loop/src/agent.ts
#	packages/core/agent/README.i18n.yaml
#	packages/core/agent/README.md
#	packages/core/agent/README.zh.md
#	packages/core/agent/src/types.ts
#	packages/core/agent/tests/agent.spec.ts
#	packages/core/scope/src/scoped-events.generated.ts
#	packages/goal/command-goal/tests/command-goal.spec.ts
#	packages/goal/goal-session/src/index.ts
#	packages/goal/goal-session/tests/goal-session.spec.ts
#	packages/goal/goal/tests/goal.spec.ts
#	packages/goal/goal/tests/projection.spec.ts
#	packages/goal/tool-goal/tests/tool-goal.spec.ts
#	packages/host/apiproxy/src/api-proxy.ts
#	packages/host/apiproxy/src/api/events.schema.ts
#	packages/host/apiproxy/src/api/events.ts
#	packages/host/apiproxy/tests/api-proxy-workspace.spec.ts
#	packages/llm/llm/README.i18n.yaml
#	packages/llm/llm/README.zh.md
#	packages/llm/llm/src/index.ts
#	packages/pty/pty-local/tests/index.spec.ts
#	packages/pty/pty-local/tests/local.spec.ts
#	packages/pty/pty/tests/service.spec.ts
#	packages/pty/tool-pty/tests/loader-composition.spec.ts
#	packages/pty/tool-pty/tests/tools.spec.ts
#	packages/skill/tool-skill/tests/tool-skill.spec.ts
#	packages/tasks/tasks-local/tests/tasks.spec.ts
#	packages/ui/tui/src/index.ts
#	packages/ui/tui/tests/harness.ts
#	packages/ui/tui/tests/tui.spec.ts
#	scripts/gen-cordis-catalog.ts
#	scripts/type-equiv.manifest.json
This commit is contained in:
_Kerman
2026-07-30 14:04:53 +08:00
1175 changed files with 49683 additions and 8452 deletions

View File

@@ -1,6 +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
# pnpm run verify-translation-pairing --write packages/pty/pty/README.md
README.md: 0f8b8e499dc81ce91e249f44bb38c8cc1af89d3f
README.zh.md: 9158afd6a7c82db27820d94cdbebd4eaa537daab
README.zh.md: 95c6345a8077d072cd22e421d3cfbbc9bf2e89b6

View File

@@ -2,20 +2,20 @@
[English](README.md) | 中文
限定所有者范围的持久 PTY seam。`PtyService` 注册为 `ctx.pty`,生成不透明的会话 id通过具名后端路由创建操作将每个操作限制在完全相同的活跃 `Agent` 内,并在该 agent 或服务释放资源时等待后端完全停稳。
限定所有者范围的持久 PTY seam。`PtyService` 注册为 `ctx.pty`,生成不透明的会话 id通过具名后端路由创建操作将每个操作限制在完全相同的活跃 `Agent` 内,并在该 agent(智能体)或服务 dispose资源释放时等待后端完全停稳。
## 契约
- 后端注册一个稳定的 `type`,并返回尚未发布的 `PtyBackendSession`;失败或取消的设置过程必须清理部分资源。若清理失败,则以 `PtyBackendCleanupError` 拒绝,使注册表能在取消后继续保留该资源
- spawn 取消会保留调用方提供的确切中止原因。后端设置完成后,服务资源释放与所有者消失仍分别对应可供机器路由的不同失败。
- 所有者与服务的资源释放会通过服务有的信号中止尚未发布的设置,并等待后端结算和回滚后才返回。
- 如果回滚关闭失败,或后端报告启动清理失败,资源释放生命周期会以拒绝结束,不会声称已经完全停稳。调用方触发的取消仍收到其确切原因;生命周期触发的回滚失败也会拒绝待完成的 spawn。
- 调用方取消后发生的后端清理失败仍算作所有者活动,直到所有者或服务释放资源并消费、报告该失败,避免生命周期策略把失败的清理误判为完全停稳。
- 后端注册一个稳定的 `type`,并返回尚未发布的 `PtyBackendSession`;失败或取消的设置过程必须清理部分资源。若清理失败,则以 `PtyBackendCleanupError` 拒绝,使注册表能在取消后继续保留该清理失败
- spawn 取消会保留调用方提供的确切中止原因。后端设置完成后,服务 dispose 与所有者消失仍分别对应可供机器路由的不同失败。
- 所有者与服务的 dispose 会通过服务有的信号中止尚未发布的设置,并等待后端结算和回滚后才返回。
- 如果回滚关闭失败,或后端报告启动清理失败,dispose 生命周期会以拒绝结束,不会声称已经完全停稳。调用方触发的取消仍收到其确切原因;生命周期触发的回滚失败也会拒绝待完成的 spawn。
- 调用方取消后发生的后端清理失败仍算作所有者活动,直到所有者或服务 dispose 并消费、报告该失败,避免生命周期策略把失败的清理误判为完全停稳。
- `hasOwnerActivity(owner)` 覆盖从尚未发布的设置到最终关闭的全过程,使生命周期策略能精确限制对应所有者,不受发布竞态影响。
- 成功的 spawn 会发布一个 `PtySessionId`。可选的 `name` 只是所有者本地的显示元数据,绝不代表权限。
- 一个会话最多接受一个活跃的发送操作。读取和信号操作可以观察该发送;在当前操作结算前,另一项发送会失败。
- `PtySendResult.waitReason``sessionStatus` 相互独立。`session_exit` 描述顶层 PTY 进程,而不是任意前台命令。
- `kill()`资源释放只会在后端捕获的进程树完全停稳后完成。清理失败会以拒绝结束,而非声称成功;同时它会清除匹配的后端和注册表限制,使后续关闭能够重试,且不会干扰较新的尝试。
- `kill()` dispose 只会在后端捕获的进程树完全停稳后完成。清理失败会以拒绝结束,而非声称成功;同时它会清除匹配的后端和注册表限制,使后续关闭能够重试,且不会干扰较新的尝试。
该 seam 不包含 `node-pty`、沙箱、工具 schema、提示词、任务或终端渲染策略。实现负责终端机制消费方负责模型呈现和可选的后台任务注册。
@@ -25,7 +25,7 @@
#### 模型看到的内容
没有直接可见内容。此包不注册提示词或工具;可见 schema 和结果文本由 `@deepseek-ai/dsh-tool-pty` 负责。
没有直接可见内容。此包package不注册提示词或工具;可见 schema 和结果文本由 `@deepseek-ai/dsh-tool-pty` 负责。
#### Token 影响
@@ -33,9 +33,9 @@
#### KV Cache 影响
不会直接失效;由具名消费方负责请求前缀变更。
不会直接失效;请求前缀变更由上述消费方负责
## 已知限制与暂缓工作
## 已知限制与暂缓事项
- 会话只存在于进程本地harness 重启后不会恢复。
- 系统有意不支持跨 agent 共享;未来的共享会话设计需要独立的权限契约。

View File

@@ -282,7 +282,7 @@ export class PtyService extends Service {
* @param reason - diagnostic cleanup reason.
* @returns true for a newly closed session, false when the same close is already in flight.
*/
async kill(owner: Agent, id: PtySessionId, reason = 'model request'): Promise<boolean> {
async kill(owner: Agent, id: PtySessionId, reason: string = 'model request'): Promise<boolean> {
const record = this.expectOwned(owner, id)
if (record.closing !== undefined) {
await record.closing

View File

@@ -28,6 +28,8 @@ function stubAgent(ctx: Context, rawId: string): Agent {
status: 'idle',
acceptsNextStep: false,
ctx: scopeFiber.ctx,
send: () => {},
updateInbox: () => 'not-found',
followup: () => {},
steer: () => {},
inject: () => {},