Skip to content

feat(kernel): 已装 extension 清单进 system 前缀,支持 EXTENSION.md 声明式描述 - #52

Open
fujiwarazz wants to merge 1 commit into
refactor/hooks-are-user-authorityfrom
feat/extension-listing
Open

feat(kernel): 已装 extension 清单进 system 前缀,支持 EXTENSION.md 声明式描述#52
fujiwarazz wants to merge 1 commit into
refactor/hooks-are-user-authorityfrom
feat/extension-listing

Conversation

@fujiwarazz

Copy link
Copy Markdown
Owner

feat(kernel): 已装 extension 清单进 system 前缀,支持 EXTENSION.md 声明式描述

为什么

模型此前只看到一堆带前缀的工具名(lsp__definition / cron__schedule),看不出它们
成组、也看不出这组解决什么问题。单个工具的 description 表达不了跨工具的那层知识:
什么时候该用这一组、有没有顺序约定、领域术语是什么。

CapabilityProvider 新增必填的 description,拼成一节 放进冻结的 system
前缀,位置在 project_context 与 env 之间——它和 env 一样是「这个运行时的事实」,
而 env 压轴靠近对话。

EXTENSION.md

包根若有 EXTENSION.md,其 frontmatter 的 description 覆盖代码里的字段(改措辞 /
本地化不必改代码)。包根 = 从入口文件往上最近的含 package.json 的目录。

正文 v1 不读,且这是刻意的:每装一个插件就往冻结前缀里常驻一段正文,token 与
信噪比都吃不消。按需展开是 skill 那套机制要解决的问题,不是这里。capability-fs 带了
一份真实的 EXTENSION.md,同时把它自己现存的三个硬伤写在正文里备查。

两处边界

  • description 为空的不进清单——内建六件套与派生 agent 三件套就是这样排除的,
    它们不是 extension,工具本来就直接可见。
  • ⚠️ 插件是动态 import 进来的,TS 校验不到。按旧契约编译的包没有 description,
    loader 兜 undefined 降级成不进清单 + warn。这条不是假想:改完第一次跑测试就崩在
    plugin-dispose 的 fixture 上。

护栏

test/extension-listing.test.ts(13 例)。这一节是模型可见文本,坏了不会有任何测试
自然变红——工具照常能调、对话照常能跑。六处变异全部命中:空 description 也进清单 /
空列表吐空标签 / 清单没拼进前缀 / 清单排到 env 之后 / EXTENSION.md 覆盖被忽略 /
不再兜住旧插件。

⚠️ 「EXTENSION.md 覆盖被忽略」第一轮漏网:我只单测了 readExtensionDoc,解析函数
正确而 loader 没调它照样全绿。补了 fixtures/extpkg/ 这个带 package.json 与
EXTENSION.md 的真实 fixture 包走完整链路才有牙。

真机对照(这一步改模型可见文本,必须做)

⚠️ live eval 的 manifest 没有 extensions 段,那 14 个用例完全没跑到这次的代码
所以另用仓库真实 helios.config.json 起 Kernel 实跑一轮,模型的推理链里直接写着
"System prompt extensions section lists only caps extension package",
并据此正确作答——确认它读到了这一节且措辞取自 EXTENSION.md 而非代码字段。

typecheck 退出码 0;917 passed(+13)。
live 全绿:readonly 35/36,七个专项各 3/3,派生 agent 4/4。
eval set 33 → 36:新增模型可见文本静默退化类(src/prompt/toolCatalog.ts:描述由模板
拼成的废话、空列表仍吐空标签、Date.now() 拼进要复用的前缀砸掉 prompt cache)。
这一类的代码全都能跑、测试也全绿,只有把拼出来的字符串当成产物去读才看得见。

codemod 又踩了同一个坑(第三、四次)

给各实现补 description 的脚本两次把字段插进了 Tool 而不是 CapabilityProvider——
两者字面量形状一样都有 name,而 CapabilityProvider[^=]*=\s*\{ 会从 import 行一路
跨到 const echoTool: Tool = {。第三版改成先定位类型标注紧跟 = { 的那一行、
再取其后最近的 name,并在插入后打印「紧随哪一行」自检。

## 为什么

模型此前只看到一堆带前缀的工具名(lsp__definition / cron__schedule),看不出它们
成组、也看不出这组解决什么问题。单个工具的 description 表达不了**跨工具**的那层知识:
什么时候该用这一组、有没有顺序约定、领域术语是什么。

CapabilityProvider 新增必填的 description,拼成一节 <extensions> 放进冻结的 system
前缀,位置在 project_context 与 env 之间——它和 env 一样是「这个运行时的事实」,
而 env 压轴靠近对话。

## EXTENSION.md

包根若有 EXTENSION.md,其 frontmatter 的 description 覆盖代码里的字段(改措辞 /
本地化不必改代码)。包根 = 从入口文件往上最近的含 package.json 的目录。

**正文 v1 不读**,且这是刻意的:每装一个插件就往冻结前缀里常驻一段正文,token 与
信噪比都吃不消。按需展开是 skill 那套机制要解决的问题,不是这里。capability-fs 带了
一份真实的 EXTENSION.md,同时把它自己现存的三个硬伤写在正文里备查。

## 两处边界

- description 为空的不进清单——内建六件套与派生 agent 三件套就是这样排除的,
  它们不是 extension,工具本来就直接可见。
- ⚠️ 插件是动态 import 进来的,TS 校验不到。按旧契约编译的包没有 description,
  loader 兜 undefined 降级成不进清单 + warn。这条不是假想:改完第一次跑测试就崩在
  plugin-dispose 的 fixture 上。

## 护栏

test/extension-listing.test.ts(13 例)。这一节是模型可见文本,坏了不会有任何测试
自然变红——工具照常能调、对话照常能跑。六处变异全部命中:空 description 也进清单 /
空列表吐空标签 / 清单没拼进前缀 / 清单排到 env 之后 / EXTENSION.md 覆盖被忽略 /
不再兜住旧插件。

⚠️ 「EXTENSION.md 覆盖被忽略」第一轮**漏网**:我只单测了 readExtensionDoc,解析函数
正确而 loader 没调它照样全绿。补了 fixtures/extpkg/ 这个带 package.json 与
EXTENSION.md 的真实 fixture 包走完整链路才有牙。

## 真机对照(这一步改模型可见文本,必须做)

⚠️ live eval 的 manifest 没有 extensions 段,那 14 个用例**完全没跑到这次的代码**。
所以另用仓库真实 helios.config.json 起 Kernel 实跑一轮,模型的推理链里直接写着
"System prompt extensions section lists only caps extension package",
并据此正确作答——确认它读到了这一节且措辞取自 EXTENSION.md 而非代码字段。

typecheck 退出码 0;917 passed(+13)。
live 全绿:readonly 35/36,七个专项各 3/3,派生 agent 4/4。
eval set 33 → 36:新增模型可见文本静默退化类(src/prompt/toolCatalog.ts:描述由模板
拼成的废话、空列表仍吐空标签、Date.now() 拼进要复用的前缀砸掉 prompt cache)。
这一类的代码全都能跑、测试也全绿,只有把拼出来的字符串当成产物去读才看得见。

## codemod 又踩了同一个坑(第三、四次)

给各实现补 description 的脚本两次把字段插进了 Tool 而不是 CapabilityProvider——
两者字面量形状一样都有 name,而 `CapabilityProvider[^=]*=\s*\{` 会从 import 行一路
跨到 `const echoTool: Tool = {`。第三版改成先定位类型标注紧跟 `= {` 的那一行、
再取其后最近的 name,并在插入后打印「紧随哪一行」自检。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant