docs(session): clarify working directory ownership and migration
This commit is contained in:
1 parent
7cfb22fc19
commit
549c0b5e37
23 files changed
+51
-29
No files matched your search
+3
-4
@@ -18,7 +18,7 @@ The assembled system prompt had four defects, all of one family: facts the harne
|
||||
|
||||
## Decision
|
||||
|
||||
**One principle: every fact in the prompt has exactly one owner.** The model name and workspace are config/session facts → the harness exposes them as variables and the persona references them. Per-tool semantics and when-to-use → the tool's `description`. Cross-call habits a description cannot carry → the tool package's prompt section. The product name and SDK identity line → the static `harness:identity` section. Deployment role and behavior → the deployment's persona.
|
||||
**One principle: every prompt fact has exactly one owner.** The loop exposes route facts as variables referenced by the persona. The working-directory service supplies the current directory as user context. Per-tool semantics and when-to-use belong to the tool description; cross-call habits belong to its package prompt section. The product name and SDK identity line belong to the static `harness:identity` section. Deployment role and behavior belong to the deployment persona.
|
||||
|
||||
### Assemble context
|
||||
|
||||
@@ -28,7 +28,7 @@ The assembled system prompt had four defects, all of one family: facts the harne
|
||||
|
||||
Plugins register `{{name}}` values through `ctx.systemPrompt.variable(name, provider)`. Assembly resolves them into the waterfall-visible variable map. Rendering rejects unknown own-property references, registered providers that return `undefined`, malformed complete references, and unbalanced references that still contain a closing `}}`; a lone unmatched `{{` remains prose, and substituted values are not rescanned. Registration rejects invalid or duplicate variable names, and section names are unique. Sections may set `interpolate: false` to preserve generated documents literally; `tools:sdk` does so because tool descriptions and schemas may document their own `{{…}}` syntax.
|
||||
|
||||
`dsh-agent-loop` registers the two built-ins, both pure projections of the context agent: `model` (= `options.model`) and `cwd` (= `session.header.cwd`). The example personas write `powered by the {{model}} model` — the model name is stated once, in the `model:` config key. `{{cwd}}` is demonstrated in the ACP example only: every ACP session carries the client's cwd, while config-pre-created stdio agents have none (a persona claiming `{{cwd}}` there fails the turn — by design). The variables stay on the loop plugin (unlike the sections below): they are runtime facts of the agents THIS loop drives, and a replacement loop supplies its own.
|
||||
`dsh-agent-loop` registers `provider` (= `options.provider`) and `model` (= `options.model`) as pure projections of the context agent. Example personas reference `{{model}}` so the route owns the model name. These variables remain on the loop plugin because they describe the agents it drives; a replacement loop supplies its own. The [Session working-directory decision](2026-09-13-session-working-directory.md) owns directory state and its literal user-context placement; the loop does not register `cwd`.
|
||||
|
||||
### Persona as the order-0 section
|
||||
|
||||
@@ -54,7 +54,6 @@ Per-tool semantics and selection guidance live in tool descriptions. Prompt sect
|
||||
## Out of scope
|
||||
|
||||
- Further variables (`date`, platform, git state) — the registry makes each a one-line contribution by whichever plugin owns the fact; none is claimed here.
|
||||
- A config `cwd` for pre-created stdio agents (would let the stdio persona use `{{cwd}}` and partition persistence by real path) — deferred until the session-cwd story is revisited.
|
||||
|
||||
## Shipped invariants
|
||||
|
||||
@@ -68,5 +67,5 @@ Per-tool semantics and selection guidance live in tool descriptions. Prompt sect
|
||||
- Every fact in the assembled prompt now has exactly one owner, and the hand-maintained tool prose in leaf YAML is gone: loading or dropping a tool plugin no longer means editing any deployment's persona.
|
||||
- `{{model}}` reflects `AgentOptions.model` at assembly time. A plugin that switches models in the `agent/request` waterfall makes the prompt's claim stale for that step, and one that SUPPLIES the model there (options.model unset — the loop's documented fallback) leaves the variable valueless at render, failing a `{{model}}` persona before the waterfall runs. Both have the same remedy, and it is the ownership rule itself: the plugin that owns the late-bound model fact states it early on the `system-prompt/assemble` waterfall (`assembly.variables['model'] = …`) — one owner, both statements; a loop test pins the supply path end-to-end. Accepted.
|
||||
- While a bound provider is absent (not yet activated, unloaded, mid-HMR-reload), the subagent tool does not exist and a model request in that window simply lacks it. That is the honest state — the alternative was a registered tool whose description or execution could not be trusted.
|
||||
- Strictness means a persona can fail a turn at render (e.g. `{{cwd}}` on a cwd-less session). The failure is contained — the turn ends `error`, the loop survives — and it is an authoring error we WANT loud.
|
||||
- Strict interpolation rejects missing or valueless variables before a model request. The turn ends with `error` while the loop remains available for later turns; a persona referencing `{{model}}` requires its composing runtime to supply that value.
|
||||
- Inline escapes remain unsupported in interpolated text; literal sections need no escaping. PTC unit tests cover both modes and runtime languages, and the recorded `ptc-turn` scenario preserves tool-template examples in the model-visible prompt.
|
||||
+3
-4
@@ -18,7 +18,7 @@ Status: implemented
|
||||
|
||||
## 决策
|
||||
|
||||
**一条原则:提示词中的每个事实恰好有一个归属方。** 模型名称和工作区是配置/会话事实 → harness 将它们暴露为变量,persona 引用它们。每个工具的语义和何时使用 → 工具的 `description`。description 无法承载的跨调用习惯 → 包的提示词 section。产品名称和 SDK 身份说明 → 静态的 `harness:identity` section。部署角色与行为 → 部署的 persona。
|
||||
**一条原则:提示词中的每个事实恰好有一个归属方。** 循环将路由事实暴露为 persona 引用的变量。工作目录服务通过用户上下文提供当前目录。每个工具的语义和选择指导属于工具描述;跨调用习惯属于其包的提示词 section。产品名称和 SDK 身份说明属于静态的 `harness:identity` section。部署角色与行为属于部署的 persona。
|
||||
|
||||
### 组装上下文
|
||||
|
||||
@@ -28,7 +28,7 @@ Status: implemented
|
||||
|
||||
插件通过 `ctx.systemPrompt.variable(name, provider)` 注册 `{{name}}` 值。组装过程将它们解析到 waterfall 可见的变量映射中。渲染阶段拒绝以下情况:引用未知的自有属性、已注册的提供方返回 `undefined`、格式错误的完整引用、以及仍包含闭合 `}}` 的不平衡引用;孤立的未匹配 `{{` 保留为行文,替换后的值不会被重新扫描。注册阶段拒绝无效或重复的变量名,section 名称也必须唯一。段可设置 `interpolate: false` 来原样保留生成的文档;`tools:sdk` 使用此设置,因为工具描述和 schema 可能会介绍自身的 `{{…}}` 语法。
|
||||
|
||||
`dsh-agent-loop` 注册两个内置变量,均为上下文 agent 的纯投影:`model`(= `options.model`)和 `cwd`(= `session.header.cwd`)。示例 persona 写 `powered by the {{model}} model`——模型名称只在 `model:` 配置键中声明一次。`{{cwd}}` 仅在 ACP 示例中演示:每个 ACP 会话携带客户端的 cwd,而配置预创建的 stdio agent 没有 cwd(在那里声称 `{{cwd}}` 的 persona 会导致该轮次失败——这是有意为之)。变量留在 loop 插件上(不同于下面的 section):它们是本循环驱动的 agent 的运行时事实,替换循环自行提供自己的变量。
|
||||
`dsh-agent-loop` 注册 `provider`(= `options.provider`)和 `model`(= `options.model`),它们都是上下文 agent 的纯投影。示例 persona 引用 `{{model}}`,由路由拥有模型名称。这些变量保留在 loop 插件上,因为它们描述该循环驱动的 agent;替换循环自行提供自己的变量。[Session 工作目录决策](2026-09-13-session-working-directory.zh.md) 拥有目录状态及其字面用户上下文位置;循环不注册 `cwd`。
|
||||
|
||||
### Persona 作为 order-0 section
|
||||
|
||||
@@ -54,7 +54,6 @@ Status: implemented
|
||||
## 不在范围内
|
||||
|
||||
- 更多变量(`date`、platform、git 状态):注册表使每个变量成为拥有该事实的插件的一行贡献;本 Agent Note 不认领任何一个。
|
||||
- 为预创建的 stdio agent 提供配置 `cwd`(可让 stdio persona 使用 `{{cwd}}` 并按真实路径分区持久化):推迟到会话 cwd 方案重新讨论时。
|
||||
|
||||
## 交付的不变式
|
||||
|
||||
@@ -68,5 +67,5 @@ Status: implemented
|
||||
- 组装后的提示词中每个事实现在恰好有一个归属方,leaf YAML 中手工维护的工具行文已消除:加载或卸载一个工具插件不再需要编辑任何部署的 persona。
|
||||
- `{{model}}` 在组装时反映 `AgentOptions.model`。如果一个插件在 `agent/request` waterfall 中切换模型,提示词对该步骤的声明就会过时;如果一个插件在那里提供模型(options.model 未设置——循环文档中记载的回退路径),变量在渲染时无值,包含 `{{model}}` 的 persona 会在 waterfall 运行前失败。两者的补救方式相同,就是归属规则本身:拥有延迟绑定模型事实的插件在 `system-prompt/assemble` waterfall 上提前声明它(`assembly.variables['model'] = …`)——一个归属方,两处声明;一个循环测试端到端固定了 supply 路径。已接受。
|
||||
- 当一个已绑定的提供方不存在时(尚未激活、已卸载、HMR(热模块替换)重载中),subagent 工具不存在,该窗口内的模型请求中不会包含它。这是诚实的状态——替代方案是注册一个 description 或执行都不可信的工具。
|
||||
- 严格性意味着 persona 可能在渲染时导致轮次失败(例如在无 cwd 的会话上使用 `{{cwd}}`)。失败是受控的——该轮次以 `error` 结束,循环存活——且这是一个我们希望明确暴露的撰写错误。
|
||||
- 严格插值在模型请求之前拒绝缺失或无值的变量。该轮次以 `error` 结束,循环仍可服务后续轮次;引用 `{{model}}` 的 persona 要求组合它的运行时提供该值。
|
||||
- 插值文本仍不支持行内转义;字面文本段无需转义。PTC 单元测试覆盖两种模式和运行时语言,录制的 `ptc-turn` 场景在模型可见的提示词中保留工具模板示例。
|
||||
+2
-2
@@ -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-09-13-session-working-directory.md
|
||||
2026-09-13-session-working-directory.md: f98c1a8c082aeb66e765582d32030ea7043928e8
|
||||
2026-09-13-session-working-directory.zh.md: 181dd0cdb6b1272d668a04349fd47abc96e1ab71
|
||||
2026-09-13-session-working-directory.md: af04b67931f99516e54677b5c9a7e8eaf652139f
|
||||
2026-09-13-session-working-directory.zh.md: a948fb02d8cf143891935dc69b6c487d8e6eb3dc
|
||||
@@ -12,12 +12,18 @@ A fixed Session creation directory cannot represent a task that changes checkout
|
||||
|
||||
`dsh-working-directory` owns one logged effective directory per Session. Its projection initializes from the immutable original project and folds `working-directory/change`; consumers read that owner instead of deriving execution paths from the header or sandbox root. Directory changes validate through the filesystem provider, serialize within the Session, and publish only after the new directory is available.
|
||||
|
||||
The built-in `working_directory({ cd? })` tool reads or changes the directory. Required user-context snapshots carry the current value; each committed change attempts to queue a notice through the ordinary Agent inbox. Cancellation or disposal may discard unadmitted notices while the directory event survives for subsequent requests. The original project is the recovery destination when the selected directory disappears. Missing recovery destinations produce an error. Write permissions remain independent.
|
||||
The `dsh-base` composition mounts `working_directory({ cd? })` globally. The tool reads or changes the Session directory, so every Agent preset can select or recover it, including presets without file-editing tools. The Web composition keeps action tools in preset scopes.
|
||||
|
||||
Required user-context snapshots carry the current value; each committed change attempts to queue a notice through the ordinary Agent inbox. Cancellation or disposal may discard unadmitted notices while the directory event survives for subsequent requests. The original project is the recovery destination when the selected directory disappears. Missing recovery destinations produce an error. Write permissions remain independent.
|
||||
|
||||
Subagents capture the parent's current directory or an explicit override and commit their selected directory after inherited history. Existing processes, terminals, and persistent shells keep their process-local directory. Project instructions, skills, and completion follow the effective directory without changing Session identity, grouping, or runtime composition.
|
||||
|
||||
Live Session skill catalogs and file completion validate through the same directory owner. These reads can commit recovery and queue its notice before discovery, keeping discovered files and subsequent operations tied to the committed Session directory. Cold skill catalogs read the recorded projection without activating an Agent.
|
||||
|
||||
File links and command directory labels use result metadata captured when each operation runs, so historical rows remain correct after later directory changes.
|
||||
|
||||
The [prompt-variables note](2026-07-05-prompt-variables-and-tool-guidance-ownership.md) retains strict interpolation, route-variable ownership, and tool-guidance ownership. The [environment-suffix note](../bug-fix/2026-09-06-environment-prompt-suffix.md) retains ordered prefix/suffix placement for deployment, Harness source, and Web guidance. This decision owns directory state and placement in user context.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
**Rewrite the Session header.** The header is immutable identity metadata used by storage, grouping, and permission roots. Rewriting it would conflate current execution state with the original project.
|
||||
@@ -32,4 +38,6 @@ File links and command directory labels use result metadata captured when each o
|
||||
|
||||
The runtime exposes one directory owner and preserves the original project. Consumers migrate together, including filesystem, shell, instructions, skills, subagents, and both SDKs. Directory existence can change outside the harness, so validation and logged recovery occur at use. Required runtime context remains visible even when optional context is suppressed.
|
||||
|
||||
`{{cwd}}` has no loop-provided value; custom personas that depend on that built-in fail strict interpolation. Deployments remove those references using the [system-prompt migration guidance](../../../../packages/core/system-prompt/README.md). When both the current directory and its recovery destination are unavailable, prompt assembly rejects model turns; the [directory service recovery guidance](../../../../packages/session/working-directory/README.md#known-limitations-and-deferred-work) requires restoring the directory or selecting an existing absolute directory through the SDK or host service.
|
||||
|
||||
Verification covers independent Sessions, relative changes, replay, cancellation, recovery, tool disposal, user-context rendering, provider inheritance, and real directory-based operations.
|
||||
@@ -12,12 +12,18 @@ Status: implemented
|
||||
|
||||
`dsh-working-directory` 拥有每个 Session 的一个日志化有效目录。投影从不可变的原始项目初始化,并折叠 `working-directory/change`;消费者读取该服务,而不是从 header 或沙箱根目录派生执行路径。目录变更通过文件系统 provider 验证,在 Session 内串行执行,并只在新目录可用后发布。
|
||||
|
||||
内置 `working_directory({ cd? })` 工具读取或改变目录。必需的用户上下文快照携带当前值;每次已提交变更都会尝试通过普通 Agent 收件箱排入通知。取消或销毁可能丢弃尚未进入请求的通知,但目录事件仍然保留,供后续请求使用。所选目录消失时恢复到原始项目。恢复目录也消失时返回错误。写权限保持独立。
|
||||
`dsh-base` 组合在全局挂载 `working_directory({ cd? })`。该工具读取或改变 Session 目录,使每个 Agent preset 都能选择或恢复它,包括没有文件编辑工具的 preset。Web 组合把操作工具放在 preset 作用域中。
|
||||
|
||||
必需的用户上下文快照携带当前值;每次已提交变更都会尝试通过普通 Agent 收件箱排入通知。取消或销毁可能丢弃尚未进入请求的通知,但目录事件仍然保留,供后续请求使用。所选目录消失时恢复到原始项目。恢复目录也消失时返回错误。写权限保持独立。
|
||||
|
||||
子代理捕获父代理当前目录或显式覆盖值,并在继承历史之后提交选定目录。已有进程、终端和持久 shell 保留进程局部目录。项目指令、技能和补全跟随有效目录,不改变 Session 身份、归属或运行时组合。
|
||||
|
||||
活跃 Session 的技能目录与文件补全通过同一个目录 owner 验证目录。这些读取可在发现操作之前提交恢复并排入通知,使发现的文件与后续操作关联到已提交的 Session 目录。冷态技能目录读取已记录的投影,不激活 Agent。
|
||||
|
||||
文件链接与命令目录标签使用各次操作执行时记录的结果元数据,因此后续目录变更不会使历史记录指向错误的位置。
|
||||
|
||||
[提示词变量记录](2026-07-05-prompt-variables-and-tool-guidance-ownership.zh.md)保留严格插值、路由变量归属与工具指导归属。[环境后缀记录](../bug-fix/2026-09-06-environment-prompt-suffix.zh.md)保留部署、Harness 源码与 Web 指导的有序前缀/后缀位置。本决策拥有目录状态及其用户上下文位置。
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
**改写 Session header。** header 是存储、归属与权限根目录使用的不可变身份元数据。改写它会混淆当前执行状态与原始项目。
|
||||
@@ -32,4 +38,6 @@ Status: implemented
|
||||
|
||||
运行时提供一个目录 owner,并保留原始项目。消费者一起迁移,包括文件系统、shell、指令、技能、子代理和两种 SDK。目录可能在 harness 之外消失,因此在使用时执行验证和日志化恢复。即使可选上下文被禁用,必需运行时上下文也仍然可见。
|
||||
|
||||
`{{cwd}}` 没有循环提供的值;依赖该内置变量的自定义 persona 会触发严格插值错误。部署方按照[系统提示词迁移说明](../../../../packages/core/system-prompt/README.zh.md)移除这些引用。当前目录与恢复目标均不可用时,提示词组装会拒绝模型轮次;[目录服务恢复说明](../../../../packages/session/working-directory/README.zh.md#known-limitations-and-deferred-work)要求恢复目录,或通过 SDK 或 Host 服务选择现有的绝对目录。
|
||||
|
||||
验证覆盖 Session 相互独立、相对路径变更、回放、取消、恢复、工具卸载、用户上下文渲染、provider 继承和真实目录操作。
|
||||
@@ -65,7 +65,7 @@ export interface Config {
|
||||
```ts config-catalog
|
||||
/** User-facing workspace instruction loader configuration. */
|
||||
export interface Config {
|
||||
/** Directory entries that identify the project root while walking upward from the session cwd. */
|
||||
/** Directory entries that identify the project root while walking upward from the current working directory. */
|
||||
projectRootMarkers?: string[]
|
||||
/** UTF-8 byte cap for one rendered baseline or dynamic batch; non-positive or non-finite disables loading. */
|
||||
maxBytes: number
|
||||
|
||||
@@ -67,7 +67,7 @@ export interface Config {
|
||||
```ts config-catalog
|
||||
/** User-facing workspace instruction loader configuration. */
|
||||
export interface Config {
|
||||
/** Directory entries that identify the project root while walking upward from the session cwd. */
|
||||
/** Directory entries that identify the project root while walking upward from the current working directory. */
|
||||
projectRootMarkers?: string[]
|
||||
/** UTF-8 byte cap for one rendered baseline or dynamic batch; non-positive or non-finite disables loading. */
|
||||
maxBytes: number
|
||||
|
||||
@@ -44,7 +44,7 @@ The complete supported method matrix, MCP trust model, update mapping, and stop
|
||||
|
||||
#### What the model sees
|
||||
|
||||
The profile supplies `You are a coding agent powered by the {{model}} model.` before first-party guidance and `Your working directory is {{cwd}}.` in a separate persona suffix. The ACP row's route and each `session/new` cwd resolve the placeholders.
|
||||
The profile supplies `You are a coding agent powered by the {{model}} model.` before first-party guidance; the ACP route resolves `{{model}}`. Each Session receives its current directory in required user-role context from [`dsh-working-directory`](../../session/working-directory/README.md).
|
||||
|
||||
#### Token effect
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ ACP v1 SDK 客户端先初始化 `dsh --profile acp`,再用绝对 `cwd` 与可
|
||||
|
||||
#### 模型看到什么
|
||||
|
||||
profile 在第一方指导之前提供 `You are a coding agent powered by the {{model}} model.`,并在独立的 persona 后缀中提供 `Your working directory is {{cwd}}.`。ACP 配置项的路由与每个 `session/new` 的 cwd 会解析其中的占位符。
|
||||
profile 在第一方指导之前提供 `You are a coding agent powered by the {{model}} model.`;ACP 路由解析 `{{model}}`。每个 Session 通过 [`dsh-working-directory`](../../session/working-directory/README.zh.md) 提供的必需 user-role 上下文接收当前目录。
|
||||
|
||||
#### Token 影响
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ The packaged Python runtime enables the [Office runtime query and skills](../../
|
||||
|
||||
#### What the model sees
|
||||
|
||||
The profile supplies `You are a coding agent powered by the {{model}} model.` before first-party guidance and `Your working directory is {{cwd}}.` in a separate persona suffix. The exact SDK initialization route and session cwd resolve the placeholders. Default file tool schemas include `read`, `write`, and `edit`; they omit `str_replace_editor`.
|
||||
The profile supplies `You are a coding agent powered by the {{model}} model.` before first-party guidance; the SDK initialization route resolves `{{model}}`. Each Session receives its current directory in required user-role context from [`dsh-working-directory`](../../session/working-directory/README.md). Default file tool schemas include `read`, `write`, and `edit`; they omit `str_replace_editor`.
|
||||
|
||||
#### Token effect
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ SDK 使用 base 默认提供的 `read`、`write` 和 `edit`。要添加 `str_rep
|
||||
|
||||
#### 模型看到什么
|
||||
|
||||
profile 在第一方指导之前提供 `You are a coding agent powered by the {{model}} model.`,并在独立的 persona 后缀中提供 `Your working directory is {{cwd}}.`。确切的 SDK 初始化路由与会话 cwd 会解析其中的占位符。默认文件工具 schema 包含 `read`、`write` 和 `edit`,不包含 `str_replace_editor`。
|
||||
profile 在第一方指导之前提供 `You are a coding agent powered by the {{model}} model.`;SDK 初始化路由解析 `{{model}}`。每个 Session 通过 [`dsh-working-directory`](../../session/working-directory/README.zh.md) 提供的必需 user-role 上下文接收当前目录。默认文件工具 schema 包含 `read`、`write` 和 `edit`,不包含 `str_replace_editor`。
|
||||
|
||||
#### Token 影响
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ const RESERVED_PATH_SEGMENTS = new Set(['', '.', '..'])
|
||||
|
||||
/** User-facing workspace instruction loader configuration. */
|
||||
export interface Config {
|
||||
/** Directory entries that identify the project root while walking upward from the session cwd. */
|
||||
/** Directory entries that identify the project root while walking upward from the current working directory. */
|
||||
projectRootMarkers?: string[]
|
||||
/** UTF-8 byte cap for one rendered baseline or dynamic batch; non-positive or non-finite disables loading. */
|
||||
maxBytes: number
|
||||
|
||||
@@ -269,7 +269,7 @@ export function ancestorChain(root: string, cwd: string): string[] {
|
||||
|
||||
/**
|
||||
* Find descendant directories crossed between a cwd and a touched file.
|
||||
* @param root - session cwd that bounds nested discovery.
|
||||
* @param root - current working directory that bounds nested discovery.
|
||||
* @param touchedPath - absolute path or path relative to `root`.
|
||||
* @returns descendant directories from shallowest through the touched file's parent.
|
||||
*/
|
||||
|
||||
@@ -73,6 +73,8 @@ Variables are referenced from section or context text as `{{name}}` and resolved
|
||||
ctx.systemPrompt.variable('response_language', () => 'English')
|
||||
```
|
||||
|
||||
Custom persona templates must not depend on a built-in `{{cwd}}` variable: the loop does not register it, so unresolved references fail prompt assembly before any model request. Remove the `Your working directory is {{cwd}}.` clause from home, profile, or invocation `personaSuffix` settings and preset `suffix` fields, preserving unrelated text. Omit or clear an otherwise empty suffix. The [working-directory service](../../session/working-directory/README.md) supplies the required current-directory context.
|
||||
|
||||
### Contribute tool schemas
|
||||
|
||||
Tool-schema providers are evaluated per assembly and contribute the model-visible `ToolSchema` set; `ToolRuntime` registers itself automatically, so most tools need no manual wiring here. A provider returns the post-restriction visible set plus the pre-restriction name universe used by `toolOrder`.
|
||||
|
||||
@@ -73,6 +73,8 @@ ctx.systemPrompt.section({
|
||||
ctx.systemPrompt.variable('response_language', () => 'English')
|
||||
```
|
||||
|
||||
自定义 persona 模板不得依赖内置 `{{cwd}}` 变量:循环不注册它,因此无法解析的引用会在任何模型请求之前使提示词组装失败。请从 home、profile 或单次调用的 `personaSuffix` 设置以及 preset 的 `suffix` 字段中移除 `Your working directory is {{cwd}}.` 语句,保留无关文本。后缀没有其他内容时,可省略或清空该字段。[工作目录服务](../../session/working-directory/README.zh.md) 提供必需的当前目录上下文。
|
||||
|
||||
### 贡献工具 schema
|
||||
|
||||
工具 schema 提供方在每次组装时求值,并贡献模型可见的 `ToolSchema` 集合;`ToolRuntime` 会自动注册自身,因此大多数工具在此无需手动接线。提供方返回限制后的可见集合,外加 `toolOrder` 使用的限制前名称全集。
|
||||
|
||||
@@ -945,6 +945,8 @@ export class ToolRuntime extends Service {
|
||||
private requirePtcTransport(): ToolDefinition {
|
||||
this.ptcTransport ??= createRunCodeTool(this, {
|
||||
resolveWorkingDirectory: async (exec) => {
|
||||
// Only Agent-owned PTC requires directory state; native registries
|
||||
// and unowned programs can run without this service.
|
||||
if (exec.agent === undefined) return undefined
|
||||
const directories = this.ctx.get('workingDirectory')
|
||||
if (directories === undefined) throw new Error('dsh-tools: run_code with an Agent requires workingDirectory')
|
||||
|
||||
@@ -211,7 +211,7 @@ export function resolveRgPath(): Promise<string> {
|
||||
* creation time becomes `SEARCH_ABORTED` instead.
|
||||
*
|
||||
* @param ctx - the plugin context; execution uses its `subprocess` service.
|
||||
* @param exec - the tool-execution context; supplies the session cwd and the abort signal.
|
||||
* @param exec - the tool-execution context; supplies the owning Agent and the abort signal.
|
||||
* @param toolName - `glob` or `grep`, used in error messages.
|
||||
* @param argv - the ripgrep arguments (every model value an unquoted argv element; no shell layer exists).
|
||||
* @param rawOutputMaxBytes - cap on the complete raw stdout the tool will parse.
|
||||
|
||||
@@ -12,7 +12,7 @@ import { sessionResolveOptions } from './session-cwd.ts'
|
||||
/**
|
||||
* Resolve a model-supplied path, observe absence, and require a regular file.
|
||||
* @param ctx - the plugin context providing filesystem resolution and observation events.
|
||||
* @param exec - the current tool execution, including session cwd and cancellation.
|
||||
* @param exec - the current tool execution, including the owning Agent and cancellation.
|
||||
* @param requestedPath - the raw path supplied to the tool.
|
||||
* @returns the resolved target and its single stat result.
|
||||
*/
|
||||
|
||||
@@ -74,9 +74,9 @@ export class FsSandboxController {
|
||||
/**
|
||||
* The policy to stamp onto this mutation: an approved escalation grant (a
|
||||
* strictly wider retry resolved through `ctx.approval` before anything
|
||||
* executes), else the session's standing mode. Repeating the standing mode
|
||||
* requires no approval. The calling session's cwd is
|
||||
* always carried as the workspace root. Validates the escalation argument
|
||||
* executes), else the Session's standing mode. Repeating the standing mode
|
||||
* requires no approval. The workspace root is the original Session
|
||||
* directory, or the deployment fallback when absent. Validates the escalation argument
|
||||
* pairing first.
|
||||
* @param toolName - the mutating tool's name, for the approval audit trail.
|
||||
* @param args - the call's escalation arguments.
|
||||
|
||||
@@ -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 packages/session/working-directory/README.md
|
||||
README.md: b45feea4cb2b0f48e211f1a1ebc91c6335312ee9
|
||||
README.zh.md: a916990db0d8b73d0ffb14ed50556b2f964859c2
|
||||
README.md: 1f54ad8c9263f7b4fd9b821eb19748d8cb8991e2
|
||||
README.zh.md: ad92f21b59282453ae32c22f50e10a7b39cacd94
|
||||
@@ -77,7 +77,7 @@ Directory transitions append context without replacing the stable system-prompt
|
||||
|
||||
<a id="known-limitations-and-deferred-work"></a>
|
||||
|
||||
- **Missing original project** — recovery fails when the original directory is unavailable; the service does not choose or recreate a repository. Existing shells retain their process-local directories.
|
||||
- **Missing original project** — when the current directory and the original project are both unavailable, prompt assembly rejects every model turn, including chat-only turns. The service does not choose or recreate a repository. Restore the original directory, or use SDK `setWorkingDirectory` (`set_working_directory` in Python) or `ctx.workingDirectory.set` to select an existing absolute directory before retrying. Existing shells retain their process-local directories.
|
||||
|
||||
<a id="dev-note"></a>
|
||||
### Dev Note
|
||||
|
||||
@@ -77,7 +77,7 @@ Session 投影拥有当前目录,并通过 Session observation 暴露它,因
|
||||
|
||||
<a id="known-limitations-and-deferred-work"></a>
|
||||
|
||||
- **原始项目缺失** — 原始目录不可用时恢复失败;服务不会另选或重建仓库。已有 shell 保留各自进程的目录。
|
||||
- **原始项目缺失** — 当前目录与原始项目均不可用时,提示词组装会拒绝每个模型轮次,包括纯聊天轮次。服务不会另选或重建仓库。请先恢复原始目录,或通过 SDK 的 `setWorkingDirectory`(Python 中为 `set_working_directory`)或 `ctx.workingDirectory.set` 选择现有的绝对目录,再重试。已有 shell 保留各自进程的目录。
|
||||
|
||||
<a id="dev-note"></a>
|
||||
### 开发备注
|
||||
|
||||
@@ -5,4 +5,6 @@ composition: web-schedule
|
||||
recording: authored
|
||||
header:
|
||||
class: web-schedule
|
||||
# This catalog-only v3 fixture has no request/header or system/message.
|
||||
# Historical prompt/schema sidecars remain pinned for the UI inventory check.
|
||||
pin: true
|
||||
Reference in new issue
Block a user