Merge remote-tracking branch 'origin/master' into worktree/preset-plane-fallout-p1
`minimal` was rewritten upstream into a fixed-prompt PTY surface that now carries its own compaction group, so this branch's token-meter move applies to it too: the row leaves the group and `tokenMeter` leaves the realm, exactly as in the other three presets. Master's header prose is kept whole — the note this branch had added there described a composition that no longer exists. `docs/event-producer-consumer.*` is generated; regenerated after the merge.
This commit is contained in:
@@ -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/preset/agent-presets/README.md
|
||||
README.md: 2c9a16081e93895e40a60378376d0db06e271913
|
||||
README.zh.md: 2598b35f5494f6c56dfc9f1ba08a6784a5087cb6
|
||||
README.md: 98891c8710adc7d72dee20a8466742ee6f649956
|
||||
README.zh.md: 0fcc5fa4d697affc2185b9251c6a60dee6510042
|
||||
|
||||
@@ -73,7 +73,7 @@ A preset may publish display text in an optional `preset.yml` beside its composi
|
||||
|
||||
```yaml
|
||||
name: 极简模式
|
||||
description: 仅提供 bash 与 str_replace_editor 的双工具编码 Agent,用于基准测试和最小复现。
|
||||
description: 仅提供持久 bash 与 str_replace_editor 的双工具编码 Agent。
|
||||
```
|
||||
|
||||
It carries display text ONLY. `id` is the directory name and `trust` comes from the root the preset was discovered under, so neither is writable here — otherwise a locally authored preset could name itself into the shipped set. It is a separate file because the composition is a top-level list of plugin rows: YAML cannot carry sibling keys beside it, and a fake metadata row would hand the Loader something to load.
|
||||
|
||||
@@ -73,7 +73,7 @@ preset 可以在组装文件旁的可选 `preset.yml` 里发布展示文本:
|
||||
|
||||
```yaml
|
||||
name: 极简模式
|
||||
description: 仅提供 bash 与 str_replace_editor 的双工具编码 Agent,用于基准测试和最小复现。
|
||||
description: 仅提供持久 bash 与 str_replace_editor 的双工具编码 Agent。
|
||||
```
|
||||
|
||||
它**只**承载展示文本。`id` 是目录名,`trust` 取自 preset 被发现时所在的根目录,两者都不可写在这里——否则本地创作的 preset 就能把自己命名进随附集合。之所以是独立文件:组装是插件行的顶层列表,YAML 无法在其旁携带同级键,而伪造一个元信息行等于递给 Loader 一个要加载的东西。
|
||||
|
||||
@@ -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/preset/persona/README.md
|
||||
README.md: 789776b32d907f7d217accccbca5508f88de0ed1
|
||||
README.zh.md: 4e28d75bbd4fd22b77a0fa3b18c5f19df08588d8
|
||||
README.md: 742141e65fa8d50b89e6b74e6d21aa8c5bfe98cd
|
||||
README.zh.md: add106adb5b81e45d8c6929a9a0f98b5c0072a01
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
The agent persona as a composable row. One config field, one prompt section.
|
||||
The agent persona as a composable row. It can either shadow the deployment persona or own the complete system prompt.
|
||||
|
||||
[`dsh-system-prompt`](../../core/system-prompt/README.md) owns the deployment persona as its own config and registers that section unconditionally, so a process has exactly one. An [agent preset](../agent-presets/README.md) cannot mount the prompt registry itself — without a row of its own, a preset could change an agent's tools but never its identity. This package is that row.
|
||||
|
||||
@@ -15,8 +15,9 @@ Mounting this row outside an agent scope collides with the registry's own `deplo
|
||||
| Field | Default | Meaning |
|
||||
|---|---|---|
|
||||
| `text` | required | Persona prose rendered as the `deployment:persona` section |
|
||||
| `complete` | `false` | Restore this persona after assembly as the only system-prompt section |
|
||||
|
||||
`text` is a template, like any prompt section: complete `{{…}}` groups resolve strictly against registered prompt variables when the prompt renders, not when it assembles. Empty text still occupies the slot, so it shadows the deployment persona away entirely and then disappears at render.
|
||||
`text` is a template, like any prompt section: complete `{{…}}` groups resolve strictly against registered prompt variables when the prompt renders, not when it assembles. Empty text still occupies the slot, so it shadows the deployment persona away entirely and then disappears at render. With `complete: true`, assembly still resolves contexts, tools, variables, and cooperative listeners, then the prompt registry restores this exact persona as the sole section; no identity, tool guidance, or listener can append prompt text.
|
||||
|
||||
## Model Experience
|
||||
|
||||
@@ -24,11 +25,11 @@ Mounting this row outside an agent scope collides with the registry's own `deplo
|
||||
|
||||
#### What the model sees
|
||||
|
||||
The `deployment:persona` section at order 0, immediately after the harness identity opener, carrying exactly this row's configured `text` with prompt variables resolved. For an agent whose preset mounts this row, it replaces whatever persona the deployment configured.
|
||||
The `deployment:persona` section at order 0, immediately after the harness identity opener, carrying exactly this row's configured `text` with prompt variables resolved. For an agent whose preset mounts this row, it replaces whatever persona the deployment configured. In complete mode, the model sees only this rendered section as its system prompt.
|
||||
|
||||
#### Token effect
|
||||
|
||||
Fixed for a given preset: the persona's own tokens on every request that agent makes, and none for any other agent. Empty text contributes nothing.
|
||||
Fixed for a given preset: the persona's own tokens on every request that agent makes, and none for any other agent. Empty text contributes nothing. Complete mode removes every other system-prompt token for that agent.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
把 agent(智能体)人设做成一个可组装的行:一个配置字段,一个提示词段落。
|
||||
把 agent(智能体)人设做成一个可组装的行:它既可以遮蔽部署级人设,也可以拥有完整系统提示词。
|
||||
|
||||
[`dsh-system-prompt`](../../core/system-prompt/README.md) 以自身配置持有部署级人设,并且无条件注册该段落,因此一个进程只有一份。[agent preset](../agent-presets/README.md) 无法自行挂载提示词注册表——若没有属于自己的行,preset 能改变 agent 的工具,却永远改不了它的身份。本包就是那一行。
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
| 字段 | 默认值 | 含义 |
|
||||
|---|---|---|
|
||||
| `text` | 必填 | 作为 `deployment:persona` 段落渲染的人设文本 |
|
||||
| `complete` | `false` | 组装后将此人设恢复为唯一的系统提示词段落 |
|
||||
|
||||
`text` 与任何提示词段落一样是模板:完整的 `{{…}}` 组在提示词**渲染**时(而非组装时)严格解析为已注册的提示词变量。空文本同样占据该槽位,因此会把部署级人设整个遮蔽掉,然后在渲染时消失。
|
||||
`text` 与任何提示词段落一样是模板:完整的 `{{…}}` 组在提示词**渲染**时(而非组装时)严格解析为已注册的提示词变量。空文本同样占据该槽位,因此会把部署级人设整个遮蔽掉,然后在渲染时消失。启用 `complete: true` 时,组装仍会解析上下文、工具、变量和协作式监听器,之后提示词注册表将这份确切人设恢复为唯一段落;身份、工具引导或监听器都无法追加提示词文本。
|
||||
|
||||
## Model Experience
|
||||
|
||||
@@ -24,11 +25,11 @@
|
||||
|
||||
#### What the model sees
|
||||
|
||||
位于 order 0 的 `deployment:persona` 段落,紧随 harness 身份开场白之后,携带本行配置的 `text`,其中的提示词变量已解析。对于其 preset 挂载了本行的 agent,它会替换部署所配置的任何人设。
|
||||
位于 order 0 的 `deployment:persona` 段落,紧随 harness 身份开场白之后,携带本行配置的 `text`,其中的提示词变量已解析。对于其 preset 挂载了本行的 agent,它会替换部署所配置的任何人设。在完整模式下,模型只会看到这个渲染后的段落作为系统提示词。
|
||||
|
||||
#### Token effect
|
||||
|
||||
对给定 preset 而言是固定的:该 agent 的每次请求都携带人设自身的 token,其他 agent 一个都不带。空文本不贡献任何 token。
|
||||
对给定 preset 而言是固定的:该 agent 的每次请求都携带人设自身的 token,其他 agent 一个都不带。空文本不贡献任何 token。完整模式会移除该 agent 的其他所有系统提示词 token。
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
|
||||
@@ -38,23 +38,27 @@ export interface Config {
|
||||
* variables. Empty text drops the section at render, matching the registry.
|
||||
*/
|
||||
text: string
|
||||
/** Make this persona the complete system prompt, suppressing every other section. */
|
||||
complete?: boolean
|
||||
}
|
||||
|
||||
/** Runtime schema for the persona row. */
|
||||
export const Config: z<Config> = z.object({
|
||||
text: z.string().required(),
|
||||
complete: z.boolean().default(false),
|
||||
})
|
||||
|
||||
/**
|
||||
* Register the persona section for the mounting context's scope.
|
||||
* @param ctx - an agent scope context; an unscoped context collides with the
|
||||
* prompt registry's own persona registration and rejects.
|
||||
* @param config - the persona text.
|
||||
* @param config - the persona text and complete-prompt policy.
|
||||
*/
|
||||
export function apply(ctx: Context, config: Config): void {
|
||||
ctx.effect(() => ctx.systemPrompt.section({
|
||||
name: PERSONA_SECTION,
|
||||
order: PERSONA_ORDER,
|
||||
text: config.text,
|
||||
...(config.complete ? { complete: true } : {}),
|
||||
}), 'persona.section()')
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ export const inject = ['invariants']
|
||||
|
||||
/**
|
||||
* No runtime invariant: this row owns no event stream or mutable runtime data — it registers one
|
||||
* prompt section and the prompt registry owns section identity, shadowing, and disposal.
|
||||
* prompt section and the prompt registry owns identity, complete-prompt enforcement, shadowing,
|
||||
* and disposal.
|
||||
*/
|
||||
const install: InvariantInstaller = () => {}
|
||||
|
||||
|
||||
@@ -85,4 +85,21 @@ describe('the persona row', () => {
|
||||
expect(renderPrompt(await ctx.systemPrompt.assemble({ scope: key })))
|
||||
.toContain('You run on deepseek-v4-pro.')
|
||||
})
|
||||
|
||||
it('makes a complete persona the exact prompt after every other contribution', async () => {
|
||||
const ctx = await harness('deployment identity')
|
||||
const key: ScopeKey = { agent: 'a1' }
|
||||
const scope = createScope(ctx, key)
|
||||
ctx.systemPrompt.section({ name: 'global:extra', order: 100, text: 'global guidance' })
|
||||
|
||||
await scope.ctx.plugin(Persona, { text: 'Only this.', complete: true })
|
||||
scope.ctx.on('system-prompt/assemble', async (assembly, _context, next) => {
|
||||
assembly.sections.push({ name: 'late:extra', text: 'late guidance' })
|
||||
return next()
|
||||
}, { prepend: true })
|
||||
|
||||
const assembly = await ctx.systemPrompt.assemble({ scope: key })
|
||||
expect(assembly.sections).toEqual([{ name: PERSONA_SECTION, text: 'Only this.' }])
|
||||
expect(renderPrompt(assembly)).toBe('Only this.')
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user