@yhong91/cpac 0.1.18 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cpac.js +78 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -316,7 +316,7 @@ Pi 扩展尊重 `PI_CODING_AGENT_DIR` 环境变量。
|
|
|
316
316
|
cpac kimi install
|
|
317
317
|
```
|
|
318
318
|
|
|
319
|
-
它在 `~/.kimi-code/config.toml` 追加一个由 CPAC 管理的块,注册 `cpac` OpenAI 兼容 provider,并把 CPA 目录里的每个模型映射为一个 `cpac/<模型名>`
|
|
319
|
+
它在 `~/.kimi-code/config.toml` 追加一个由 CPAC 管理的块,注册 `cpac` OpenAI 兼容 provider,并把 CPA 目录里的每个模型映射为一个 `cpac/<模型名>` 条目。带 `supported_reasoning_levels` 的模型会写入 `capabilities`、`support_efforts` 和 `default_effort`,否则 Kimi 只给 Claude 名套内置 thinking profile,其它模型会停在 thinking off 且无法改 effort。`base_url` 指向 Codex 注入使用的 loopback 代理,因此密钥不落盘;代理未运行时 install 会提示先执行 `cpac inject`。卸载与状态:
|
|
320
320
|
|
|
321
321
|
```bash
|
|
322
322
|
cpac kimi uninstall
|
package/dist/cpac.js
CHANGED
|
@@ -402,6 +402,9 @@ export async function pickSpawnModels(config) {
|
|
|
402
402
|
export function tomlString(value) {
|
|
403
403
|
return JSON.stringify(value);
|
|
404
404
|
}
|
|
405
|
+
function tomlStringArray(values) {
|
|
406
|
+
return `[ ${values.map(tomlString).join(", ")} ]`;
|
|
407
|
+
}
|
|
405
408
|
export function dominantEol(content) {
|
|
406
409
|
const crlf = (content.match(/\r\n/g) ?? []).length;
|
|
407
410
|
if (crlf === 0)
|
|
@@ -1751,6 +1754,30 @@ export function isKimiConfigInstalled() {
|
|
|
1751
1754
|
return false;
|
|
1752
1755
|
}
|
|
1753
1756
|
}
|
|
1757
|
+
function isCpacTableHeader(line) {
|
|
1758
|
+
const header = line.match(/^\[([^\]]+)\]\s*$/);
|
|
1759
|
+
if (!header)
|
|
1760
|
+
return false;
|
|
1761
|
+
const name = header[1];
|
|
1762
|
+
return (name === "providers.cpac" ||
|
|
1763
|
+
name.startsWith("providers.cpac.") ||
|
|
1764
|
+
/^models\.(?:"cpac\/|'cpac\/)/.test(name));
|
|
1765
|
+
}
|
|
1766
|
+
// Kimi may rewrite config.toml and drop our comment markers, leaving the
|
|
1767
|
+
// [providers.cpac] / [models."cpac/..."] tables behind. A later install would
|
|
1768
|
+
// then append a second copy and make the file invalid TOML.
|
|
1769
|
+
function stripOrphanCpacTables(content) {
|
|
1770
|
+
const eol = content.includes("\r\n") ? "\r\n" : "\n";
|
|
1771
|
+
const out = [];
|
|
1772
|
+
let skipping = false;
|
|
1773
|
+
for (const line of content.split(/\r?\n/)) {
|
|
1774
|
+
if (/^\[[^\]]+\]\s*$/.test(line))
|
|
1775
|
+
skipping = isCpacTableHeader(line);
|
|
1776
|
+
if (!skipping)
|
|
1777
|
+
out.push(line);
|
|
1778
|
+
}
|
|
1779
|
+
return out.join(eol).replace(/(?:\r?\n){3,}/g, `${eol}${eol}`);
|
|
1780
|
+
}
|
|
1754
1781
|
function writeKimiBlock(path, block) {
|
|
1755
1782
|
let content = existsSync(path) ? readFileSync(path, "utf8") : "";
|
|
1756
1783
|
content = content.replace(kimiBlockRegex, "");
|
|
@@ -1761,6 +1788,7 @@ function writeKimiBlock(path, block) {
|
|
|
1761
1788
|
const orphan = content.indexOf(KIMI_BLOCK_START);
|
|
1762
1789
|
if (orphan !== -1)
|
|
1763
1790
|
content = content.slice(0, orphan);
|
|
1791
|
+
content = stripOrphanCpacTables(content);
|
|
1764
1792
|
if (block) {
|
|
1765
1793
|
content = `${content}${content && !content.endsWith("\n") ? "\n" : ""}${block}\n`;
|
|
1766
1794
|
}
|
|
@@ -1768,6 +1796,40 @@ function writeKimiBlock(path, block) {
|
|
|
1768
1796
|
const mode = existsSync(path) ? statSync(path).mode & 0o7777 : 0o600;
|
|
1769
1797
|
atomicWrite(path, Buffer.from(content), mode);
|
|
1770
1798
|
}
|
|
1799
|
+
const KIMI_REASONING_EFFORTS = new Set([
|
|
1800
|
+
"minimal",
|
|
1801
|
+
"low",
|
|
1802
|
+
"medium",
|
|
1803
|
+
"high",
|
|
1804
|
+
"xhigh",
|
|
1805
|
+
"max",
|
|
1806
|
+
"ultra",
|
|
1807
|
+
]);
|
|
1808
|
+
function kimiSupportEfforts(row) {
|
|
1809
|
+
const levels = row.supported_reasoning_levels;
|
|
1810
|
+
if (!Array.isArray(levels))
|
|
1811
|
+
return [];
|
|
1812
|
+
const seen = new Set();
|
|
1813
|
+
const efforts = [];
|
|
1814
|
+
for (const level of levels) {
|
|
1815
|
+
const effort = typeof level === "string"
|
|
1816
|
+
? level
|
|
1817
|
+
: objectValue(level) && typeof level.effort === "string"
|
|
1818
|
+
? level.effort
|
|
1819
|
+
: undefined;
|
|
1820
|
+
if (!effort || !KIMI_REASONING_EFFORTS.has(effort) || seen.has(effort))
|
|
1821
|
+
continue;
|
|
1822
|
+
seen.add(effort);
|
|
1823
|
+
efforts.push(effort);
|
|
1824
|
+
}
|
|
1825
|
+
return efforts;
|
|
1826
|
+
}
|
|
1827
|
+
function kimiInputHasImage(row) {
|
|
1828
|
+
const modalities = row.input_modalities;
|
|
1829
|
+
if (!Array.isArray(modalities))
|
|
1830
|
+
return true;
|
|
1831
|
+
return modalities.some((value) => value === "image");
|
|
1832
|
+
}
|
|
1771
1833
|
export async function installKimiConfig(config) {
|
|
1772
1834
|
const apiKey = await resolveApiKey(config.api_key_env);
|
|
1773
1835
|
const catalog = await fetchCatalog(config.cpa_url, apiKey);
|
|
@@ -1797,10 +1859,25 @@ export async function installKimiConfig(config) {
|
|
|
1797
1859
|
const context = typeof row.context_window === "number" && row.context_window > 0
|
|
1798
1860
|
? Math.floor(row.context_window)
|
|
1799
1861
|
: 200000;
|
|
1800
|
-
|
|
1862
|
+
const efforts = kimiSupportEfforts(row);
|
|
1863
|
+
const capabilities = [
|
|
1864
|
+
...(efforts.length > 0 ? ["thinking"] : []),
|
|
1865
|
+
"tool_use",
|
|
1866
|
+
...(kimiInputHasImage(row) ? ["image_in"] : []),
|
|
1867
|
+
];
|
|
1868
|
+
lines.push("", `[models."cpac/${slug}"]`, 'provider = "cpac"', `model = ${tomlString(slug)}`, `max_context_size = ${context}`, `capabilities = ${tomlStringArray(capabilities)}`);
|
|
1801
1869
|
if (typeof row.display_name === "string" && row.display_name.trim()) {
|
|
1802
1870
|
lines.push(`display_name = ${tomlString(row.display_name)}`);
|
|
1803
1871
|
}
|
|
1872
|
+
if (efforts.length > 0) {
|
|
1873
|
+
lines.push(`support_efforts = ${tomlStringArray(efforts)}`);
|
|
1874
|
+
const defaultEffort = typeof row.default_reasoning_level === "string" &&
|
|
1875
|
+
efforts.includes(row.default_reasoning_level)
|
|
1876
|
+
? row.default_reasoning_level
|
|
1877
|
+
: undefined;
|
|
1878
|
+
if (defaultEffort)
|
|
1879
|
+
lines.push(`default_effort = ${tomlString(defaultEffort)}`);
|
|
1880
|
+
}
|
|
1804
1881
|
}
|
|
1805
1882
|
lines.push(KIMI_BLOCK_END);
|
|
1806
1883
|
const target = kimiConfigPath();
|