feat(runtime): track user-level Pi configuration with the provider key templated
Mirrors ~/.pi/agent/ as the authoritative copy. models.json becomes
models.json.template with ${ZENMUX_API_KEY} substituted; the real value stays
in secrets/zenmux.env, which is untracked and enforced by the pre-commit guard.
Excluded with rationale: auth.json, trust.json, models-store.json, sessions/,
herdr-agent-state.ts (installer-managed, overwritten on reinstall) and the
third-party skills under ~/.agents/skills.
Recorded during migration: the configured fallback model zenmux/x-ai/grok-4.6 is
absent from models.json, so pi falls back to an undeclared custom model id with
no context window, cost table or thinkingLevelMap. Fixing that is a behaviour
change and is deferred rather than folded into this zero-change migration.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# Pi User-Level Runtime Configuration
|
||||
|
||||
Authoritative copy of the **user-global** Pi configuration that lives at
|
||||
`~/.pi/agent/` on the host. Scenario-specific configuration lives in
|
||||
`../scenarios/`.
|
||||
|
||||
Deploy with:
|
||||
|
||||
```bash
|
||||
../scripts/deploy-runtime.sh # dry run
|
||||
../scripts/deploy-runtime.sh --apply
|
||||
```
|
||||
|
||||
## Contents
|
||||
|
||||
| Path | Live target | Notes |
|
||||
|---|---|---|
|
||||
| `agent/settings.json` | `~/.pi/agent/settings.json` | No credentials. |
|
||||
| `agent/models.json.template` | `~/.pi/agent/models.json` | Rendered; `${ZENMUX_API_KEY}` comes from `../secrets/zenmux.env`. Mode `0600`. |
|
||||
| `agent/extensions/pi-memo-trust.ts` | `~/.pi/agent/extensions/` | Grants project trust to the memo-inbox workspace only. |
|
||||
| `agent/prompts/*.md` | `~/.pi/agent/prompts/` | Interactive prompt templates. Gateways pass `--no-prompt-templates`, so these are for human use only. |
|
||||
|
||||
## Deliberately not tracked
|
||||
|
||||
| Path | Why |
|
||||
|---|---|
|
||||
| `~/.pi/agent/auth.json` | OAuth/API credential store. Empty on this host but still excluded on principle. |
|
||||
| `~/.pi/agent/trust.json` | Host-local trust decisions; machine state, not configuration. |
|
||||
| `~/.pi/agent/models-store.json` | Downloaded model catalogue cache; regenerated by `pi update --models`. |
|
||||
| `~/.pi/agent/sessions/` | Conversation history. |
|
||||
| `~/.pi/agent/extensions/herdr-agent-state.ts` | Installed and overwritten by herdr (`HERDR_INTEGRATION_ID=pi`). Managing it here would fight the installer. It is inert unless `HERDR_ENV=1`, but it is still **loaded and parsed on every pi start**, which is one reason every scenario must pass `--no-extensions`. |
|
||||
| `~/.agents/skills/{find-skills,modsearch,summarize}` | Third-party skills installed by other tooling. Not authored here. They leak into any scenario that omits `--no-skills` — see `../docs/isolation-baseline.md`. |
|
||||
|
||||
## Observations recorded during migration (2026-08-27)
|
||||
|
||||
1. **The fallback model is not declared.** `models.json` contains only
|
||||
`openai/gpt-5.6-luna`, while the Curator service is configured with
|
||||
`CURATOR_PI_FALLBACK_MODEL=zenmux/x-ai/grok-4.6`. Pi therefore emits
|
||||
`Model not found … Using custom model id` on every fallback, and the
|
||||
fallback runs without a declared context window, cost table or
|
||||
`thinkingLevelMap`. Cost and token accounting for fallback turns is
|
||||
consequently unavailable. Adding the model is a behaviour change and is
|
||||
therefore **not** part of the zero-change migration; it is tracked as a
|
||||
follow-up.
|
||||
|
||||
2. `settings.json` sets `defaultProvider: zenmux`,
|
||||
`defaultModel: openai/gpt-5.6-luna`, `defaultThinkingLevel: high`. Gateways
|
||||
override all three on the command line, so these only affect interactive use.
|
||||
|
||||
3. `settings.json` carries no `compaction` block, so the defaults apply
|
||||
(`enabled: true`, `reserveTokens: 16384`, `keepRecentTokens: 20000`). With a
|
||||
1,050,000-token context window auto-compaction effectively never fires; each
|
||||
gateway must rotate sessions itself.
|
||||
|
||||
4. `trust.json` trusts only `/home/claw/pi-workspaces/memo-inbox`. The Curator
|
||||
workspace is not trusted and relies on `--approve` per run.
|
||||
@@ -0,0 +1,21 @@
|
||||
import type {
|
||||
ExtensionAPI,
|
||||
ProjectTrustEventResult,
|
||||
} from "@earendil-works/pi-coding-agent";
|
||||
import { realpathSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const MEMO_WORKSPACE = "/home/claw/pi-workspaces/memo-inbox";
|
||||
|
||||
export default function piMemoTrust(pi: ExtensionAPI) {
|
||||
pi.on("project_trust", async (event): Promise<ProjectTrustEventResult> => {
|
||||
try {
|
||||
if (realpathSync(resolve(event.cwd)) === realpathSync(MEMO_WORKSPACE)) {
|
||||
return { trusted: "yes", remember: true };
|
||||
}
|
||||
} catch {
|
||||
// Fall through to Pi's normal trust decision for every other path.
|
||||
}
|
||||
return { trusted: "undecided" };
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"providers": {
|
||||
"zenmux": {
|
||||
"name": "ZenMux",
|
||||
"baseUrl": "https://zenmux.ai/api/v1",
|
||||
"api": "openai-responses",
|
||||
"apiKey": "${ZENMUX_API_KEY}",
|
||||
"authHeader": true,
|
||||
"models": [
|
||||
{
|
||||
"id": "openai/gpt-5.6-luna",
|
||||
"name": "GPT-5.6 Luna (ZenMux)",
|
||||
"reasoning": true,
|
||||
"thinkingLevelMap": {
|
||||
"off": "none",
|
||||
"minimal": "low",
|
||||
"low": "low",
|
||||
"medium": "medium",
|
||||
"high": "high",
|
||||
"xhigh": "xhigh",
|
||||
"max": "xhigh"
|
||||
},
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 0.2,
|
||||
"output": 1.2,
|
||||
"cacheRead": 0.02,
|
||||
"cacheWrite": 0.25,
|
||||
"tiers": [
|
||||
{
|
||||
"inputTokensAbove": 272000,
|
||||
"input": 0.4,
|
||||
"output": 1.8,
|
||||
"cacheRead": 0.04,
|
||||
"cacheWrite": 0.5
|
||||
}
|
||||
]
|
||||
},
|
||||
"contextWindow": 1050000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
description: 创建 Google Calendar 日历事项(Pi Memo)
|
||||
argument-hint: "<日期、时间和事项>"
|
||||
---
|
||||
|
||||
这是 Pi Memo Inbox 的 `/calendar` 快捷入口,等价于“日历事项”。
|
||||
|
||||
仅在当前会话加载了 `pi-memo-inbox` skill 时执行;否则说明该命令只适用于 Pi Memo Topic,不要采取任何操作。
|
||||
|
||||
请把下面的用户内容作为 `calendar`,并严格遵循 `pi-memo-inbox` skill 的时间确认和 Google Calendar 创建规则:
|
||||
|
||||
${ARGUMENTS}
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
description: 记录到今天的 Journal(Pi Memo)
|
||||
argument-hint: "<内容>"
|
||||
---
|
||||
|
||||
这是 Pi Memo Inbox 的 `/memo` 快捷入口,等价于“记一下”。
|
||||
|
||||
仅在当前会话加载了 `pi-memo-inbox` skill 时执行;否则说明该命令只适用于 Pi Memo Topic,不要采取任何操作。
|
||||
|
||||
请把下面的用户内容按 `record` 或 `idea` 分类,并严格遵循 `pi-memo-inbox` skill 的上下文补全、确认、写入和同步规则:
|
||||
|
||||
${ARGUMENTS}
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
description: 添加到今天的 Journal 待办(Pi Memo)
|
||||
argument-hint: "<待办内容>"
|
||||
---
|
||||
|
||||
这是 Pi Memo Inbox 的 `/todo` 快捷入口,等价于“待办事项”。
|
||||
|
||||
仅在当前会话加载了 `pi-memo-inbox` skill 时执行;否则说明该命令只适用于 Pi Memo Topic,不要采取任何操作。
|
||||
|
||||
请把下面的用户内容作为 `todo`,并严格遵循 `pi-memo-inbox` skill 的上下文补全、确认、写入和同步规则:
|
||||
|
||||
${ARGUMENTS}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"defaultProvider": "zenmux",
|
||||
"defaultModel": "openai/gpt-5.6-luna",
|
||||
"defaultThinkingLevel": "high",
|
||||
"lastChangelogVersion": "0.84.2",
|
||||
"theme": "dark"
|
||||
}
|
||||
Reference in New Issue
Block a user