Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{
"name": "infermatrix-copilot",
"source": "./plugins/infermatrix-copilot",
"description": "Maintainer-grounded vLLM-Omni review knowledge over MCP."
"description": "InferMatrixCopilot — governed PR review and release-driven knowledge maintenance over MCP and skills."
}
]
}
2 changes: 1 addition & 1 deletion .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
"name": "infermatrix-copilot",
"source": "plugins/infermatrix-copilot",
"description": "Maintainer-grounded vLLM-Omni review knowledge over MCP."
"description": "Maintainer-grounded vLLM-Omni review and release knowledge updates."
}
]
}
1 change: 1 addition & 0 deletions .github/workflows/vllm-omni-release-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
- adapters/vllm_omni/manifest.yaml
- adapters/vllm_omni/release_baseline.yaml
- doc/VLLM_OMNI_RELEASE_MAINTENANCE.md
- plugins/infermatrix-copilot/skills/imupdate/**
- knowledge/repos/vllm-omni/**
- tools/audit_vllm_omni_release.py
- tools/vllm_omni_release_audit.py
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ vLLM-Omni 的兼容性、正确性和性能问题。
## 快速开始

私有仓库过渡期,克隆后运行一个入口。脚本会自动识别本机的 Codex、Claude Code
和 Cursor,并同时安装 MCP 与 `imreview` Skill。
和 Cursor,并同时安装 MCP、`imreview` 和 `imupdate` Skill。

```text
git clone git@github.com:JiusiServe/InferMatrixCopilot.git
Expand All @@ -35,9 +35,13 @@ install.cmd

```text
/imreview https://github.com/vllm-project/vllm-omni/pull/5172
/imupdate D:\path\to\vllm-omni
/imupdate vllmomni
```

不带地址时,`/imreview` 会审查当前 PR 或本地工作区。
`/imupdate` 接受本地 Git 路径,也接受仓库名、别名或 URL。本地路径直接走机器审计;
名字或别名先由 Agent 找到权威仓库和目标版本,再尽量获取临时 checkout 运行机器审计。

公共市场上线后的安装方法和通用 MCP 配置见 [`doc/MCP.md`](doc/MCP.md)。

Expand All @@ -49,6 +53,13 @@ install.cmd
→ InferMatrixCopilot 返回知识库入口
→ Agent 按改动选择相关模型、组件和通用规则
→ Agent 输出带文件和行号的审查结论

你发起 /imupdate <仓库>
→ 本地路径:直接读取 baseline 和目标仓库 HEAD
→ 仓库名/别名:Agent 先解析权威仓库、版本和可用 checkout
→ 只读审计器对比 Git 对象、注册表、pipeline、deploy 和路径路由
→ Agent 根据报告更新结构事实,不自动生成 owner 规则
→ enforce、知识检查和相关测试确认更新完整
```

代码理解和推理由 Agent 当前模型完成。InferMatrixCopilot 只负责提供知识地图和维护者
Expand Down
6 changes: 5 additions & 1 deletion doc/MCP.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
InferMatrixCopilot 的核心发布物保持一份:

- `plugins/infermatrix-copilot/.mcp.json`:标准 stdio MCP 描述;
- `plugins/infermatrix-copilot/skills/imreview/SKILL.md`:开放 Agent Skills;
- `plugins/infermatrix-copilot/skills/`:开放 Agent Skills;
- Claude、Codex、Cursor 的市场文件只负责把同一个插件展示出来,不包含各自的安装逻辑。

## 私有仓库过渡安装
Expand Down Expand Up @@ -32,6 +32,7 @@ install.cmd

```text
/imreview <PR URL>
/imupdate <local path, repository name, alias, or URL>
```

市场只安装同一份 MCP 与 Skill;不会把逐 Agent 逻辑带回核心包。
Expand All @@ -44,6 +45,7 @@ install.cmd

```text
plugins/infermatrix-copilot/skills/imreview/SKILL.md
plugins/infermatrix-copilot/skills/imupdate/SKILL.md
```

核心 MCP 配置:
Expand Down Expand Up @@ -71,6 +73,8 @@ plugins/infermatrix-copilot/skills/imreview/SKILL.md

```text
/imreview https://github.com/vllm-project/vllm-omni/pull/5172
/imupdate D:\path\to\vllm-omni
/imupdate vllmomni
```

默认 Direct 模式只提供知识库,由 Agent 当前模型完成审查;不会自动评论或推送代码。
31 changes: 30 additions & 1 deletion doc/VLLM_OMNI_RELEASE_MAINTENANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,29 @@ InferMatrixCopilot 的模型清单、代码 owner 路由和源码引用会随着
vLLM-Omni 发版而过期。这个审计只读取两个 Git 提交和本仓库声明,不会 checkout
目标版本,也不会自动修改知识规则。

## 本地运行
## 用户入口

安装 InferMatrixCopilot 后,在 Codex、Claude Code 或 Cursor 中运行:

```text
/imupdate D:\path\to\vllm-omni
/imupdate vllm-omni
/imupdate vllmomni
```

支持三种用法:

1. 本地 Git 路径:直接用 baseline 的 `audited_sha` 对比仓库 `HEAD`,机器审计后
由 Agent 更新知识。
2. 仓库名、别名或 URL:Agent 先解析权威仓库与目标版本,寻找已配置 checkout
或建立临时 clone,再尽量进入同一机器审计流程;无法运行机器审计时必须明确标记
为模型分析,不能宣称 `CLEAN`。选择版本时不得因为 GitHub “latest release”
忽略预发布版本而退回到比当前 baseline 更旧的版本。
3. 下方完整 Python 命令:纯机器规则对比,不调用 LLM,也不修改文件。

`/imupdate` 的可选第二个参数可以指定目标 tag 或 SHA。

## 底层命令

先在 vLLM-Omni checkout 中 fetch 需要比较的 tag 或 SHA,然后运行:

Expand All @@ -30,6 +52,13 @@ python tools/audit_vllm_omni_release.py `
默认 `--mode enforce`:存在未解释漂移时退出 1,输入或 Git 失败时退出 2。
`--mode report-only` 仍报告 `DRIFT`,但退出 0,供定时巡检使用。

底层实现不 checkout 版本:它用 `git rev-parse` 固定两个提交,用
`git diff --name-status -M` 找新增、修改、删除和重命名,再用
`git show <sha>:<path>` 直接读取 Git 对象。Python AST 负责提取模型和
pipeline registry,deploy YAML 直接按提交列举;结果做排序和哈希后与 baseline、
owner 路由、manifest、知识 `sources:` 和 pin 对账,最后输出稳定 JSON。
这个命令只报告证据,不编辑任何文件。

## 更新一个 release

1. 用当前 `release_baseline.yaml` 的 audited SHA 作为 `--from`,新 tag 作为
Expand Down
2 changes: 1 addition & 1 deletion plugins/infermatrix-copilot/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "infermatrix-copilot",
"version": "0.1.0",
"description": "Maintainer-grounded vLLM-Omni review knowledge over MCP.",
"description": "Maintainer-grounded vLLM-Omni review and release knowledge updates.",
"author": {
"name": "JiusiServe",
"url": "https://github.com/JiusiServe"
Expand Down
12 changes: 7 additions & 5 deletions plugins/infermatrix-copilot/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "infermatrix-copilot",
"version": "0.1.0",
"description": "Maintainer-grounded vLLM-Omni review knowledge over MCP.",
"description": "Maintainer-grounded vLLM-Omni review and release knowledge updates.",
"author": {
"name": "JiusiServe",
"url": "https://github.com/JiusiServe"
Expand All @@ -18,17 +18,19 @@
"mcpServers": "./.mcp.json",
"interface": {
"displayName": "InferMatrixCopilot",
"shortDescription": "Review vLLM-Omni changes with maintainer knowledge",
"longDescription": "Use maintainer-grounded vLLM-Omni knowledge to review pull requests and local changes.",
"shortDescription": "Review and update vLLM-Omni knowledge",
"longDescription": "Use maintainer-grounded vLLM-Omni knowledge to review changes and update release-driven facts.",
"developerName": "JiusiServe",
"category": "Developer Tools",
"capabilities": [
"MCP",
"Code review"
"Code review",
"Knowledge maintenance"
],
"websiteURL": "https://github.com/JiusiServe/InferMatrixCopilot",
"defaultPrompt": [
"Review this PR with InferMatrixCopilot."
"Review this PR with InferMatrixCopilot.",
"Update InferMatrixCopilot knowledge from this repository."
]
}
}
2 changes: 1 addition & 1 deletion plugins/infermatrix-copilot/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "infermatrix-copilot",
"displayName": "InferMatrixCopilot",
"version": "0.1.0",
"description": "Maintainer-grounded vLLM-Omni review knowledge over MCP.",
"description": "Maintainer-grounded vLLM-Omni review and release knowledge updates.",
"author": {
"name": "JiusiServe"
},
Expand Down
89 changes: 89 additions & 0 deletions plugins/infermatrix-copilot/skills/imupdate/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
name: imupdate
description: Resolve an upstream repository from a local path, repository name, alias, or URL, then update InferMatrixCopilot's release-driven knowledge. Use when the user invokes /imupdate or $imupdate, asks to sync knowledge after an upstream release, compare vLLM-Omni tags or SHAs, or refresh the release baseline, model catalog, source maps, and manifests.
---

# InferMatrix update

```text
/imupdate <path-or-repository> [target-tag-or-sha]
```

The installed InferMatrixCopilot root is:

```text
{{INFERMATRIX_COPILOT_ROOT}}
```

If that placeholder was not replaced, locate or temporarily clone the
InferMatrixCopilot checkout containing `tools/audit_vllm_omni_release.py`.

## Select the input mode

### Local Git path

When the argument exists and is a Git checkout, use the deterministic audit.
Read `adapters/vllm_omni/release_baseline.yaml`; use
`upstream.audited_sha` as the old revision and the optional target or checkout
`HEAD` as the new revision. Refuse an accidental downgrade when the target is
older than the audited revision. Do not fetch or checkout unless explicitly
asked.

### Repository name, alias, or URL

When the argument is not a local path, use the host model to resolve it:

1. Treat `vllm-omni`, `vllmomni`, `vllm omni`, and
`vllm-project/vllm-omni` as `https://github.com/vllm-project/vllm-omni`.
2. Check the configured repo map and current workspace for a matching checkout.
If found, continue as the local-path mode.
3. Otherwise verify the canonical repository from authoritative GitHub
metadata. Choose the supplied target, otherwise the newest release or tag
that is not older than the audited revision, otherwise the default-branch
HEAD; state that choice. Never silently downgrade because GitHub's "latest
release" can exclude newer prereleases.
4. Prefer a temporary clone and run the deterministic audit. If repository
access or cloning is unavailable, inspect the authoritative source with the
host model, update only source-backed facts, and clearly report that machine
audit/enforce validation was unavailable. Never call that result `CLEAN`.
5. Ask for clarification only when multiple plausible canonical repositories
remain after resolution.

## Audit and update

1. Resolve old and new revisions to full SHAs.
2. Create a temporary JSON path and run the read-only audit in report mode when
a local or temporary Git checkout is available:

```text
python <infermatrix-root>/tools/audit_vllm_omni_release.py \
--from <audited-sha> \
--to <target-sha> \
--repo <upstream-repo> \
--mode report-only \
--json-output <temporary-json>
```

3. Explain the registry, pipeline, deploy, path-routing, source, and pin drift.
Read the relevant upstream diff before changing InferMatrixCopilot.
4. Update only facts proven by the report and source: the release baseline,
model catalog, component source maps, pins, or adapter manifest. Never
generate or rewrite owner rules automatically; report semantic-rule
candidates for human review.
5. When machine audit is available, run the same command with `--mode enforce`,
then run:

```text
python knowledge/tools/check_knowledge_tree.py
python knowledge/tools/check_wiki_lint.py
python -m pytest test/test_release_audit.py test/test_adapters.py \
test/test_routing.py test/test_knowledge_source.py \
test/test_skills_scope.py test/test_capabilities.py -q
```

6. Delete temporary reports and clones. Return the canonical repository, input
mode, old and new SHAs, structural deltas, files changed, validation
results, and any unresolved or model-only findings.

The audit is evidence collection, not the updater. Codex performs the bounded
knowledge edits and must not commit, push, or open a PR unless asked.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "InferMatrix Update"
short_description: "Audit and update release-driven repository knowledge"
default_prompt: "Use $imupdate to resolve a repository path or name and update InferMatrix knowledge."
39 changes: 24 additions & 15 deletions scripts/install_mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@


PROJECT_ROOT = Path(__file__).resolve().parent.parent
SKILL_SOURCE = (
PROJECT_ROOT / "plugins" / "infermatrix-copilot" / "skills" / "imreview"
)
SKILLS_SOURCE = PROJECT_ROOT / "plugins" / "infermatrix-copilot" / "skills"
SERVER_NAME = "infermatrix-copilot"
PACKAGE = (
"infermatrix-copilot[mcp] @ "
Expand Down Expand Up @@ -46,9 +44,23 @@ def _run_quiet(command: Sequence[str]) -> None:
)


def _install_skill(destination: Path) -> None:
destination.parent.mkdir(parents=True, exist_ok=True)
shutil.copytree(SKILL_SOURCE, destination, dirs_exist_ok=True)
def _install_skills(destination_root: Path) -> None:
destination_root.mkdir(parents=True, exist_ok=True)
for source in sorted(path for path in SKILLS_SOURCE.iterdir() if path.is_dir()):
destination = destination_root / source.name
shutil.copytree(source, destination, dirs_exist_ok=True)
for path in destination.rglob("*"):
if not path.is_file():
continue
content = path.read_text(encoding="utf-8")
if "{{INFERMATRIX_COPILOT_ROOT}}" in content:
path.write_text(
content.replace(
"{{INFERMATRIX_COPILOT_ROOT}}",
str(PROJECT_ROOT),
),
encoding="utf-8",
)


def _install_codex(config_root: Path) -> None:
Expand All @@ -60,7 +72,7 @@ def _install_codex(config_root: Path) -> None:
[codex, "mcp", "add", SERVER_NAME, "--", *SERVER_COMMAND],
"Codex MCP registration failed.",
)
_install_skill(config_root / ".codex" / "skills" / "imreview")
_install_skills(config_root / ".codex" / "skills")


def _install_claude(config_root: Path) -> None:
Expand All @@ -83,7 +95,7 @@ def _install_claude(config_root: Path) -> None:
],
"Claude Code MCP registration failed.",
)
_install_skill(config_root / ".claude" / "skills" / "imreview")
_install_skills(config_root / ".claude" / "skills")


def _install_cursor(config_root: Path) -> None:
Expand Down Expand Up @@ -120,18 +132,15 @@ def _install_cursor(config_root: Path) -> None:
json.dumps(config, ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
_install_skill(cursor_root / "skills" / "imreview")
_install_skills(cursor_root / "skills")


def _cursor_installed(config_root: Path) -> bool:
if shutil.which("cursor") or shutil.which("cursor-agent"):
return True
candidates = [
config_root / ".cursor",
Path(os.environ.get("LOCALAPPDATA", ""))
/ "Programs"
/ "cursor"
/ "Cursor.exe",
Path(os.environ.get("LOCALAPPDATA", "")) / "Programs" / "cursor" / "Cursor.exe",
Path("/Applications/Cursor.app"),
]
return any(path.exists() for path in candidates)
Expand Down Expand Up @@ -201,7 +210,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
output = PROJECT_ROOT / "infermatrix-copilot.mcp.json"
_write_generic_config(output)
print(f"No known Agent detected. MCP config written to:\n {output}")
print(f"Portable Skill:\n {SKILL_SOURCE}")
print(f"Portable Skills:\n {SKILLS_SOURCE}")
return 0

failures = []
Expand All @@ -223,7 +232,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
print(f" {failure}", file=sys.stderr)
return 1

print("Restart your Agent, then run: /imreview <PR URL>")
print("Restart your Agent, then run: /imreview <PR URL> or /imupdate <repository>")
return 0


Expand Down
Loading
Loading