Merge pull request #149 from pikasTech/fix/artificer-direct-ssh-146
修复 Artificer 默认资源装配直连 SSH
This commit is contained in:
@@ -62,8 +62,7 @@ spec:
|
||||
repoUrl: git@github.com:pikasTech/unidesk.git
|
||||
ref: master
|
||||
gitMirror:
|
||||
enabled: true
|
||||
baseUrl: http://git-mirror-http.devops-infra.svc.cluster.local
|
||||
enabled: false
|
||||
bundles:
|
||||
- name: unidesk-skills
|
||||
subpath: .agents/skills
|
||||
|
||||
@@ -60,7 +60,7 @@ spec:
|
||||
- 通过 provider SecretRef `agentrun-v01-provider-sub2api` 获取 `auth.json` 与 `config.toml`。
|
||||
- 通过 `toolCredentials` 获取 UniDesk SSH 透传 token:`agentrun-v01-tool-unidesk-ssh` -> env `UNIDESK_SSH_CLIENT_TOKEN`。
|
||||
- 通过 `toolCredentials` 获取 GitHub SSH 凭据:`agentrun-v01-tool-github-ssh` -> volume `/home/agentrun/.ssh`。
|
||||
- 通过 gitbundle 装配 UniDesk repo 中的 `unidesk-*` skills、AgentRun repo 中的 `tools/trans`、`tools/tran`、`tools/apply_patch`,以及 `agent_skills` repo 中的 `dad-dev`、`cli-spec`、`docs-spec`、`git-spec`。
|
||||
- 通过 GitHub SSH 直接 checkout 多仓库 gitbundle,装配 UniDesk repo 中的 `unidesk-*` skills、AgentRun repo 中的 `tools/trans`、`tools/tran`、`tools/apply_patch`,以及 `agent_skills` repo 中的 `dad-dev`、`cli-spec`、`docs-spec`、`git-spec`;Artificer 默认不依赖 G14 git mirror 的覆盖范围。
|
||||
- 通过 `requiredSkills[]` 在 runner 启动 backend 前校验 `dad-dev` 与 UniDesk 关键 skills 已被 materialize;缺失时必须 `required-skill-unavailable`,不得使用模型默认 skill 猜测。
|
||||
|
||||
## Git mirror
|
||||
@@ -75,6 +75,8 @@ spec:
|
||||
- 非 GitHub URL 不改写,仍按原 `repoUrl` fetch。
|
||||
- materialization event 必须输出 `repoUrl`、`fetchRepoUrl`、`mirrorUsed`、`mirrorBaseUrl`、requested ref/commit 和实际 commit;不得输出 credential 值。
|
||||
|
||||
Artificer 默认 `gitMirror.enabled=false`,依靠 `agentrun-v01-tool-github-ssh` 投影的 SSH 凭据直接拉取 `unidesk`、`agentrun` 和 `agent_skills`。只有明确确认目标 repo 已纳入 G14 mirror cache 的规格,才应显式启用 `gitMirror`。
|
||||
|
||||
## Tool credential projection
|
||||
|
||||
`toolCredentials[]` 支持两类 projection:
|
||||
@@ -118,8 +120,8 @@ CLI:
|
||||
|
||||
## 测试规格
|
||||
|
||||
- A1:`config/aipods/artificer.yaml` 能被 manager list/show/render,render 结果包含 `backendProfile=sub2api`、`model=gpt-5.5`、`reasoningEffort=xhigh`、provider SecretRef、UniDesk SSH env projection、GitHub SSH volume projection、AgentRun runner tools gitbundle 和 gitbundle requiredSkills。
|
||||
- A1:`config/aipods/artificer.yaml` 能被 manager list/show/render,render 结果包含 `backendProfile=sub2api`、`model=gpt-5.5`、`reasoningEffort=xhigh`、provider SecretRef、UniDesk SSH env projection、GitHub SSH volume projection、Artificer `gitMirror.enabled=false`、AgentRun runner tools gitbundle 和 gitbundle requiredSkills。
|
||||
- A2:`queue submit --aipod Artificer --dry-run` 输出标准 `queue-submit-plan`,且 `idempotencyKey`、prompt 与 metadata 被保留。
|
||||
- A3:GitHub URL 在启用 `gitMirror` 后改写到 mirror base URL;非 GitHub URL 不改写。
|
||||
- A3:Artificer 默认 `gitMirror.enabled=false` 时 GitHub URL 保持 SSH fetch;显式启用 `gitMirror` 后 GitHub URL 改写到 mirror base URL;非 GitHub URL 不改写。
|
||||
- A4:runner Job dry-run 支持 tool credential volume mount,并且 response/manifest/event 不泄漏 Secret 明文。
|
||||
- A5:`bun run check` 和 `bun run self-test` 必须覆盖 A1-A4。
|
||||
|
||||
@@ -24,7 +24,7 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
const shownItem = shown.item as JsonRecord;
|
||||
assert.equal(shownItem.backendProfile, "sub2api");
|
||||
assert.equal(((shownItem.model as JsonRecord).model), "gpt-5.5");
|
||||
assert.equal(((shownItem.resourceBundleRef as JsonRecord).gitMirror as JsonRecord).enabled, true);
|
||||
assert.equal(((shownItem.resourceBundleRef as JsonRecord).gitMirror as JsonRecord).enabled, false);
|
||||
|
||||
const rendered = await client.post("/api/v1/aipod-specs/Artificer/render", { prompt: "处理 pikasTech/unidesk#245", idempotencyKey: "selftest-aipod-artificer" }) as JsonRecord;
|
||||
assert.equal(rendered.action, "aipod-spec-render");
|
||||
@@ -42,7 +42,7 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
assert.equal(toolCredentials.some((item) => item.tool === "unidesk-ssh" && ((item.projection as JsonRecord).envName) === "UNIDESK_SSH_CLIENT_TOKEN"), true);
|
||||
assert.equal(toolCredentials.some((item) => item.tool === "github" && ((item.projection as JsonRecord).kind) === "volume" && ((item.projection as JsonRecord).mountPath) === "/home/agentrun/.ssh"), true);
|
||||
const bundle = task.resourceBundleRef as JsonRecord;
|
||||
assert.equal(((bundle.gitMirror as JsonRecord).enabled), true);
|
||||
assert.equal(((bundle.gitMirror as JsonRecord).enabled), false);
|
||||
const bundles = bundle.bundles as JsonRecord[];
|
||||
const toolBundle = bundles.find((item) => item.name === "agentrun-runner-tools") as JsonRecord | undefined;
|
||||
assert.equal(toolBundle?.repoUrl, "git@github.com:pikasTech/agentrun.git");
|
||||
@@ -56,6 +56,9 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
const mirrored = resolveGitBundleFetchSource("git@github.com:pikasTech/unidesk.git", { enabled: true, baseUrl: "http://mirror.example.test/root/" }, {});
|
||||
assert.equal(mirrored.fetchRepoUrl, "http://mirror.example.test/root/pikasTech/unidesk.git");
|
||||
assert.equal(mirrored.mirrorUsed, true);
|
||||
const disabledMirror = resolveGitBundleFetchSource("git@github.com:pikasTech/unidesk.git", { enabled: false, baseUrl: "http://mirror.example.test/root/" }, {});
|
||||
assert.equal(disabledMirror.fetchRepoUrl, "git@github.com:pikasTech/unidesk.git");
|
||||
assert.equal(disabledMirror.mirrorUsed, false);
|
||||
const nonGithub = resolveGitBundleFetchSource("ssh://git@example.test/repo.git", { enabled: true, baseUrl: "http://mirror.example.test" }, {});
|
||||
assert.equal(nonGithub.fetchRepoUrl, "ssh://git@example.test/repo.git");
|
||||
assert.equal(nonGithub.mirrorUsed, false);
|
||||
@@ -72,7 +75,7 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
assert.equal(commands.some((item) => item.includes("aipod-specs render <name>")), true);
|
||||
assert.equal(commands.some((item) => item.includes("queue submit --aipod <name>")), true);
|
||||
assertNoSecretLeak(submitPlan);
|
||||
return { name: "aipod-spec", tests: ["aipod-spec-yaml-parser-runtime-compatible", "aipod-spec-artificer-yaml-render", "aipod-spec-git-mirror-url", "queue-submit-aipod-dry-run", "aipod-cli-help"] };
|
||||
return { name: "aipod-spec", tests: ["aipod-spec-yaml-parser-runtime-compatible", "aipod-spec-artificer-direct-ssh-render", "aipod-spec-git-mirror-url", "queue-submit-aipod-dry-run", "aipod-cli-help"] };
|
||||
} finally {
|
||||
await new Promise<void>((resolve) => server.server.close(() => resolve()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user