指南 · 扩展包

编写 klink 扩展包(klink.plugins)

klink 只发机制;你的工艺数据和自家工具可以住在你自己的 pip 包里,通过 klink.plugins entry point 接入,不改 klink 一行代码。

1. 为什么写扩展包

klink 只发机制;你的工艺数据和自家工具可以住在你自己的 pip 包里,不改 klink 一行就接入。实验室或 PDK 供应商发布一个包;任何人把它装在 klayout-klink 旁边,就能在 klink.find_tools 里看到供应商的工具,并按名字解析供应商的 profile / 器件库 / recipe / 叠层。

2. 最小可用包

两个文件。pyproject.toml:

[project]
name = "acme-pdk-klink"
version = "0.1.0"
dependencies = ["klayout-klink"]

[project.entry-points."klink.plugins"]
acme = "acme_pdk.klink_ext:register"

acme_pdk/klink_ext.py:

from acme_pdk.process import ACME_2M_PROFILE     # 你的数据,你的包

def hello(ctx, arguments):
    # ctx 是 MCP bridge:ctx._client 可达 live KLayout 会话
    return {"greeting": f"hello {arguments.get('who', 'world')}"}

def register(hook):
    hook.add_domain(
        "acme_pdk", title="ACME PDK",
        summary="ACME 的工艺数据与辅助工具",
        usage="用 klink.ext.get_resource('profile', 'acme_2m') 解析 "
              "profile;acme_pdk.hello 是冒烟检查。")
    hook.add_tool(
        "acme_pdk.hello", hello,
        description="ACME 扩展的冒烟检查",
        input_schema={"type": "object",
                      "properties": {"who": {"type": "string"}}},
        domain="acme_pdk")
    hook.add_profile("acme_2m", ACME_2M_PROFILE)

acme-pdk-klink 装在 klink 旁边,重启 MCP server,然后:

  • klink.find_tools(无参)会列出 acme_pdk 域和它的工具数;domain="acme_pdk" 返回你的 usage 文本——你的扩展享有与内置域相同的渐进式披露。
  • acme_pdk.hello 像任何内置工具一样可调用。
  • 任何示例或脚本可用 klink.ext.get_resource("profile", "acme_2m") 拿到你的 ProcessProfile

3. 你能贡献什么

hook 调用贡献说明
add_tool(名, handler, description=, input_schema=, domain=)一个 MCP 工具名字必须命名空间化 <token>.<名>;内置前缀(view.shape.routing.……)保留,占用会被拒
add_domain(token, title=, summary=, usage=)一个 find_toolsusage 字符串就是你的 skill 式配方,按需披露
add_profile(名, 对象) / add_devices / add_recipe / add_stack命名资源klink.ext.get_resource(kind, 名) 解析;示例和流程借此拿到你的工艺数据

Handler 遵循本地工具契约:handler(ctx, arguments) 返回可 JSON 序列化的 dict;ctx 是 MCP bridge(其 _client 是已连接的 KLinkClient)。贡献的工具应遵守与内置相同的设计规则——一次调用一个用户意图、错误即指令、先校验后改动。

4. 故障隔离(包坏了会怎样)

发现是惰性(首次使用)且按包隔离的:

  • 导入失败或 register() 抛异常的扩展会被完整回滚(不存在注册一半的工具),并记录为点名该包和错误的失败条目;
  • 其它扩展和所有内置工具不受影响——MCP server 绝不因坏扩展而崩;
  • klink.status 报告 extensions 块:已装包及其贡献、失败清单。预期的工具不见时先查它。
  • 扩展安装时,klink 的工具清单与素装逐字节一致——机制不用就零开销。

5. 验证你的包

  1. klayout-klinkpip install -e . 你的扩展。
  2. klink.status → 你的包出现在 extensions.installed,failures 为空。
  3. klink.find_tools → 你的域带正确计数出现;调一次你的工具。
  4. python -c "from klink import ext; print(ext.get_resource('profile', '<名>'))"
  5. 卸载再查:一切干净消失。

工艺纯净律同样适用于你:数字(层号、尺寸、z 表)放你包里的数据模块,显式传进 klink API——你的扩展正是"自带工艺的 example"模式的发行版形态。