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 .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
{ "name": "specode", "source": "./plugins/specode", "version": "6.5.0", "description": "Lightweight spec-driven workflow orchestration shell — walks a host agent through requirements → design → tasks → execute → acceptance, delegating each phase to superpowers skills with a first-class specode-native fallback, and landing 4 fixed docs per spec (requirements / design / tasks / implementation-log). Bundles dedicated intake and execute skills (the execution tail — selector, engine dispatch, acceptance — is manually triggerable anytime via /specode:execute), a zero-import task-swarm handoff for parallel execution, and optional locate-oriented experience retrieval.", "category": "development", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["spec","specification","workflow"] },
{ "name": "task-swarm", "source": "./plugins/task-swarm", "version": "0.12.0", "description": "Standalone multi-agent orchestration driven by a pipeline.yml — semantic task groups with cross-group concurrency, forked coders, and per-group reviewer + validator loops (state.json is the single source of truth). specode delegates its execution phase here; also runnable directly via /task-swarm:swarm.", "category": "development", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["task-swarm","multi-agent","orchestration","pipeline"] },
{ "name": "obsidian-wiki","source": "./plugins/obsidian-wiki","version": "2.2.0", "description": "Maintain an Obsidian LLM-Wiki via three skills — a deterministic structure layer (wiki-struct: Home tree / per-dir READMEs / partition pages), content curation (wiki-curate: ingest / curate / lint), and a unified orchestrator (wiki-orchestrate). Generic code + per-vault config in the home-dir registry ~/.config/obsidian-wiki/ (fallback: <vault>/.wiki/config.json), zero hardcoded structure.", "category": "productivity", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["obsidian","llm-wiki","knowledge-base","notes","curation"] },
{ "name": "ragkit", "source": "./plugins/ragkit", "version": "0.2.0", "description": "Standalone knowledge-base RAG plugin (vector/lexical/metadata multi-channel recall).", "category": "database", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["rag","knowledge-base","vector-search","embedding"] }
{ "name": "ragkit", "source": "./plugins/ragkit", "version": "0.2.1", "description": "Standalone knowledge-base RAG plugin (vector/lexical/metadata multi-channel recall).", "category": "database", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["rag","knowledge-base","vector-search","embedding"] }
]
}
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
{
"name": "ragkit",
"source": "./plugins/ragkit",
"version": "0.2.0",
"version": "0.2.1",
"description": "Standalone knowledge-base RAG plugin (vector/lexical/metadata multi-channel recall).",
"category": "database",
"homepage": "https://github.com/qxbyte/pluginhub",
Expand Down
2 changes: 1 addition & 1 deletion .codebuddy-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
{ "name": "specode", "source": "./plugins/specode", "version": "6.5.0", "description": "Lightweight spec-driven workflow orchestration shell — walks a host agent through requirements → design → tasks → execute → acceptance, delegating each phase to superpowers skills with a first-class specode-native fallback, and landing 4 fixed docs per spec (requirements / design / tasks / implementation-log). Bundles dedicated intake and execute skills (the execution tail — selector, engine dispatch, acceptance — is manually triggerable anytime via /specode:execute), a zero-import task-swarm handoff for parallel execution, and optional locate-oriented experience retrieval.", "category": "development", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["spec","specification","workflow"] },
{ "name": "task-swarm", "source": "./plugins/task-swarm", "version": "0.12.0", "description": "Standalone multi-agent orchestration driven by a pipeline.yml — semantic task groups with cross-group concurrency, forked coders, and per-group reviewer + validator loops (state.json is the single source of truth). specode delegates its execution phase here; also runnable directly via /task-swarm:swarm.", "category": "development", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["task-swarm","multi-agent","orchestration","pipeline"] },
{ "name": "obsidian-wiki","source": "./plugins/obsidian-wiki","version": "2.2.0", "description": "Maintain an Obsidian LLM-Wiki via three skills — a deterministic structure layer (wiki-struct: Home tree / per-dir READMEs / partition pages), content curation (wiki-curate: ingest / curate / lint), and a unified orchestrator (wiki-orchestrate). Generic code + per-vault config in the home-dir registry ~/.config/obsidian-wiki/ (fallback: <vault>/.wiki/config.json), zero hardcoded structure.", "category": "productivity", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["obsidian","llm-wiki","knowledge-base","notes","curation"] },
{ "name": "ragkit", "source": "./plugins/ragkit", "version": "0.2.0", "description": "Standalone knowledge-base RAG plugin (vector/lexical/metadata multi-channel recall).", "category": "database", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["rag","knowledge-base","vector-search","embedding"] }
{ "name": "ragkit", "source": "./plugins/ragkit", "version": "0.2.1", "description": "Standalone knowledge-base RAG plugin (vector/lexical/metadata multi-channel recall).", "category": "database", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["rag","knowledge-base","vector-search","embedding"] }
]
}
2 changes: 1 addition & 1 deletion .kimi-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
{ "name": "specode", "source": "./plugins/specode", "version": "6.5.0", "description": "Lightweight spec-driven workflow orchestration shell — walks a host agent through requirements → design → tasks → execute → acceptance, delegating each phase to superpowers skills with a first-class specode-native fallback, and landing 4 fixed docs per spec (requirements / design / tasks / implementation-log). Bundles dedicated intake and execute skills (the execution tail — selector, engine dispatch, acceptance — is manually triggerable anytime via /specode:execute), a zero-import task-swarm handoff for parallel execution, and optional locate-oriented experience retrieval.", "category": "development", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["spec","specification","workflow"] },
{ "name": "task-swarm", "source": "./plugins/task-swarm", "version": "0.12.0", "description": "Standalone multi-agent orchestration driven by a pipeline.yml — semantic task groups with cross-group concurrency, forked coders, and per-group reviewer + validator loops (state.json is the single source of truth). specode delegates its execution phase here; also runnable directly via /task-swarm:swarm.", "category": "development", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["task-swarm","multi-agent","orchestration","pipeline"] },
{ "name": "obsidian-wiki","source": "./plugins/obsidian-wiki","version": "2.2.0", "description": "Maintain an Obsidian LLM-Wiki via three skills — a deterministic structure layer (wiki-struct: Home tree / per-dir READMEs / partition pages), content curation (wiki-curate: ingest / curate / lint), and a unified orchestrator (wiki-orchestrate). Generic code + per-vault config in the home-dir registry ~/.config/obsidian-wiki/ (fallback: <vault>/.wiki/config.json), zero hardcoded structure.", "category": "productivity", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["obsidian","llm-wiki","knowledge-base","notes","curation"] },
{ "name": "ragkit", "source": "./plugins/ragkit", "version": "0.2.0", "description": "Standalone knowledge-base RAG plugin (vector/lexical/metadata multi-channel recall).", "category": "database", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["rag","knowledge-base","vector-search","embedding"] }
{ "name": "ragkit", "source": "./plugins/ragkit", "version": "0.2.1", "description": "Standalone knowledge-base RAG plugin (vector/lexical/metadata multi-channel recall).", "category": "database", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", "keywords": ["rag","knowledge-base","vector-search","embedding"] }
]
}
2 changes: 1 addition & 1 deletion plugins/ragkit/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ragkit",
"version": "0.2.0",
"version": "0.2.1",
"description": "Standalone knowledge-base RAG: chunk + embed + multi-channel recall (vector/lexical/metadata, RRF-fused) over distill-style knowledge-base/ directories.",
"author": {
"name": "xueqiang",
Expand Down
2 changes: 1 addition & 1 deletion plugins/ragkit/.codebuddy-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ragkit",
"version": "0.2.0",
"version": "0.2.1",
"description": "Standalone knowledge-base RAG: chunk + embed + multi-channel recall (vector/lexical/metadata, RRF-fused) over distill-style knowledge-base/ directories.",
"author": { "name": "xueqiang", "email": "xueqiang361@gmail.com" },
"homepage": "https://github.com/qxbyte/pluginhub",
Expand Down
2 changes: 1 addition & 1 deletion plugins/ragkit/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ragkit",
"version": "0.2.0",
"version": "0.2.1",
"description": "Standalone knowledge-base RAG: chunk + embed + multi-channel recall (vector/lexical/metadata, RRF-fused) over distill-style knowledge-base/ directories.",
"author": {
"name": "xueqiang",
Expand Down
2 changes: 1 addition & 1 deletion plugins/ragkit/.kimi-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ragkit",
"version": "0.2.0",
"version": "0.2.1",
"description": "Standalone knowledge-base RAG: chunk + embed + multi-channel recall (vector/lexical/metadata, RRF-fused) over distill-style knowledge-base/ directories.",
"author": {
"name": "xueqiang",
Expand Down
14 changes: 14 additions & 0 deletions plugins/ragkit/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

## Unreleased

## 0.2.1 (2026-07-20) — 云端后端兼容与容错

### Fixed

- **DashScope 兼容模式批大小超限**(`backend.py`):`_BATCH` 由 16 降为 **10**。通义 `text-embedding-v4` 兼容模式单请求硬上限为 10 条,原值 16 会导致 embed/query 报 `400 InvalidParameter`(`batch size ... should not be larger than 10`)。
- **云端向量调用失败导致 query 崩溃**(`pipeline.py` + `ragkit.py`):密钥失效 / 网络抖动 / sidecar 异常时,`_vector_rank` 原会抛异常使整个 query 中断;现捕获为新状态 `vector_error`,**自动降级到词汇+元数据路**,stderr 打印固定提示 + 失败详情,退出码仍为 0,与文档承诺的「无后端时降级仍可用」一致。
- **Windows 下 CLI 测试编码崩溃**(`tests/conftest.py`):`run_cli` 显式 `encoding="utf-8"` + 子进程 `PYTHONIOENCODING`,修复 GBK 默认解码对 UTF-8 中文/emoji 输出的 `UnicodeDecodeError`。

### Added

- **云端 `batch_size` 覆盖**(`backend.py`):`cloud` 配置可加 `"batch_size": <n>` 覆盖默认 10,供 OpenAI 等高上限端点调大以减少请求次数。
- **文档:API key 全局设置 + 强制走云端**(`README.md`、`skills/query/SKILL.md`):补充各平台临时/永久设密钥命令(含 Windows `setx`)、本地已缓存时用 `"backend": "cloud"` 强制云端、`vector_error` 降级信号说明。
- **测试**:`test_pipeline_degrades_on_vector_backend_error`(降级不崩)、`test_cloud_encode_respects_batch_size_override`(batch 覆盖切分),批大小边界测试同步改为 `_BATCH=10`。共 47 passed。

## 0.2.0 (2026-07-20) — 多宿主适配:bootstrap 去宿主绑定 + CodeBuddy/Codex/Kimi 独立 manifest

ragkit 现在同时面向 Claude Code / CodeBuddy / Codex / Kimi 四个宿主。
Expand Down
62 changes: 55 additions & 7 deletions plugins/ragkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,66 @@ export DASHSCOPE_API_KEY=<你的密钥>

内置 preset(`--provider` 可选值):

| preset | model | key_env |
| --- | --- | --- |
| `openai` | text-embedding-3-small | `OPENAI_API_KEY` |
| `qwen` | text-embedding-v4 | `DASHSCOPE_API_KEY` |
| `zhipu` | embedding-3 | `ZHIPUAI_API_KEY` |
| `voyage` | voyage-3 | `VOYAGE_API_KEY` |
| `azure` | text-embedding-3-small | `AZURE_OPENAI_API_KEY` |
| preset | model | key_env | 单请求上限 |
| --- | --- | --- | --- |
| `openai` | text-embedding-3-small | `OPENAI_API_KEY` | 高(可调大 `batch_size`) |
| `qwen` | text-embedding-v4 | `DASHSCOPE_API_KEY` | **10 条/请求**(硬上限) |
| `zhipu` | embedding-3 | `ZHIPUAI_API_KEY` | 视文档 |
| `voyage` | voyage-3 | `VOYAGE_API_KEY` | 视文档 |
| `azure` | text-embedding-3-small | `AZURE_OPENAI_API_KEY` | 高 |

自定义端点:`--base-url <url> --model <model> --key-env <ENV_VAR>`(任何 OpenAI 兼容接口均可)。

密钥只通过环境变量传入,**不落盘**。

#### 设置 API key(按平台)

密钥读取自 `key_env` 指定的环境变量。**临时**(仅当前终端会话有效):

```sh
# macOS / Linux (bash/zsh)
export DASHSCOPE_API_KEY=<你的密钥>
```
```powershell
# Windows PowerShell
$env:DASHSCOPE_API_KEY = "<你的密钥>"
```

**永久 / 全局**(新开终端也生效,推荐):

```powershell
# Windows —— 写入用户环境变量,设完需【新开】终端才生效
setx DASHSCOPE_API_KEY "<你的密钥>"
```
```sh
# macOS / Linux —— 追加到 shell 配置后 source 生效
echo 'export DASHSCOPE_API_KEY=<你的密钥>' >> ~/.zshrc && source ~/.zshrc
```

> ⚠️ 未设置密钥时后端解析会跳过云端;若本地模型也未缓存则降级为词汇+元数据路。
> query 时云端调用失败(密钥失效/网络异常)不再崩溃,**自动降级**并在 stderr 提示。

#### 强制走云端(本地模型已缓存时)

后端解析优先级为「本地已缓存 > 云端」。**若本地已装过模型、但想强制用云端**,在 `<知识库路径>/.ragkit/config.json` 显式指定:

```json
{
"backend": "cloud",
"cloud": { "provider": "qwen", "base_url": "...", "model": "text-embedding-v4", "key_env": "DASHSCOPE_API_KEY" }
}
```

#### 单请求批大小(batch_size)

云端每次请求最多上传 `batch_size` 条文本,默认 **10**(DashScope text-embedding-v4 兼容模式硬上限,超出返回 `400 InvalidParameter`)。OpenAI 等端点上限更高,可在 `cloud` 配置里加 `"batch_size": 64` 减少请求次数、加快 embed:

```json
{ "cloud": { "provider": "openai", "...": "...", "batch_size": 64 } }
```

> 切换后端或改 batch 后,需 `embed --rebuild` 重建索引(向量维度/模型空间不同,旧向量不可混用)。

### 无 uv 时的回退

仅需 numpy,可用系统/项目虚拟环境回退:
Expand Down
10 changes: 7 additions & 3 deletions plugins/ragkit/scripts/rag/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@

DEFAULT_LOCAL_MODEL = "Qwen/Qwen3-Embedding-0.6B"
EXIT_NO_BACKEND = 3
_BATCH = 16
# 单请求最多上传多少条文本。默认 10:DashScope(通义 text-embedding-v4)兼容模式
# 硬上限即 10 条,超出返回 400 InvalidParameter。OpenAI 等端点上限更高,可在
# 云端 config 里加 "batch_size": <n> 覆盖以减少请求次数。
_BATCH = 10

PRESETS = {
"openai": {"base_url": "https://api.openai.com/v1",
Expand Down Expand Up @@ -151,9 +154,10 @@ def _encode_dummy(texts: list[str]):
def _encode_cloud(opts: dict, texts: list[str]):
url = opts["base_url"].rstrip("/") + "/embeddings"
key = os.environ[opts["key_env"]]
batch_size = int(opts.get("batch_size") or _BATCH)
vecs: list = []
for start in range(0, len(texts), _BATCH):
batch = texts[start:start + _BATCH]
for start in range(0, len(texts), batch_size):
batch = texts[start:start + batch_size]
req = urllib.request.Request(
url, method="POST",
headers={"Authorization": f"Bearer {key}",
Expand Down
12 changes: 11 additions & 1 deletion plugins/ragkit/scripts/rag/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
DEFAULT_TOP = 8
ALL_CHANNELS = ["lexical", "metadata", "vector"]

# _vector_rank 里捕获到的向量后端异常详情,供 query_pipeline 透出到输出(stderr 提示用)。
_VECTOR_ERROR_DETAIL: dict = {"msg": ""}


def query_pipeline(kb_root: Path, query: str, top: int = DEFAULT_TOP,
channels_filter: list[str] | None = None) -> dict:
Expand Down Expand Up @@ -37,11 +40,14 @@ def query_pipeline(kb_root: Path, query: str, top: int = DEFAULT_TOP,
rankings["metadata"] = [k for k, _ in md]
channel_scores["metadata"] = dict(md)
if "vector" in active:
_VECTOR_ERROR_DETAIL["msg"] = ""
state, vec = _vector_rank(kb_root, chunks, focus)
out["vector_channel"] = state
if state == "ok":
rankings["vector"] = [k for k, _ in vec]
channel_scores["vector"] = dict(vec)
elif state == "vector_error":
out["vector_error_detail"] = _VECTOR_ERROR_DETAIL["msg"]
fused = fuse.rrf_fuse(rankings)[:top]
for row in fused:
d = docs[row["knowledge_id"]]
Expand Down Expand Up @@ -69,7 +75,11 @@ def _vector_rank(kb_root: Path, chunks: list[dict], focus_text: str):
return "no_backend", []
if backend.model_id(kind, opts) != stored:
return "model_mismatch", []
q = backend.encode(kind, opts, [focus_text])[0]
try:
q = backend.encode(kind, opts, [focus_text])[0]
except Exception as exc: # 云端认证失败/网络抖动/sidecar 崩溃:不整体崩,降级到词汇+元数据路
_VECTOR_ERROR_DETAIL["msg"] = f"{type(exc).__name__}: {exc}"[:200]
return "vector_error", []
sims = vectors @ q
order = np.argsort(-sims)[:TOP_CHUNK_HITS]
best: dict[str, float] = {}
Expand Down
3 changes: 3 additions & 0 deletions plugins/ragkit/scripts/ragkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"no_vectors": "RagKit:索引缺向量(上次 embed 无可用后端),已降级词汇+元数据路;补好后端后重跑 embed。",
"no_backend": "RagKit:无可用向量后端,已降级词汇+元数据路。",
"model_mismatch": "RagKit:当前后端与索引向量模型不一致,向量路已跳过;请 embed --rebuild。",
"vector_error": "RagKit:向量后端调用失败(密钥无效/网络异常等),已降级词汇+元数据路;结果仍有效。请检查密钥或网络后重试。",
"skipped": "",
}

Expand All @@ -42,6 +43,8 @@ def cmd_query(args: argparse.Namespace) -> int:
print(note, file=sys.stderr)
if out["vector_channel"] == "no_backend":
print(backend.no_backend_block(), file=sys.stderr)
elif out["vector_channel"] == "vector_error" and out.get("vector_error_detail"):
print(f" 详情:{out['vector_error_detail']}", file=sys.stderr)
if args.json:
print(json.dumps(out, ensure_ascii=False, indent=1))
else:
Expand Down
Loading
Loading