Merge pull request #366 from pikasTech/fix/release-artificer-credentials

修复 Artificer release 凭据绑定
This commit is contained in:
Lyon
2026-07-15 23:23:38 +08:00
committed by GitHub
3 changed files with 62 additions and 59 deletions
+17 -14
View File
@@ -3,15 +3,15 @@ kind: AipodSpec
metadata:
name: Artificer
displayName: Artificer
description: UniDesk distributed development agent assembled from AgentRun v0.2 YAML.
description: UniDesk distributed development agent assembled for the AgentRun release lane.
labels:
agentrun.pikastech.local/lane: v0.2
agentrun.pikastech.local/lane: release
agentrun.pikastech.local/purpose: distributed-development
spec:
tenantId: unidesk
projectId: pikasTech/unidesk
queue: commander
lane: v0.2
lane: release
priority: 50
providerId: NC01
upstreams:
@@ -19,8 +19,8 @@ spec:
backendProfile: gpt-pika
providerCredential:
secretRef:
namespace: agentrun-v02
name: agentrun-v02-provider-gpt-pika
namespace: agentrun-release
name: agentrun-release-provider-gpt-pika
keys:
- auth.json
- config.toml
@@ -28,8 +28,8 @@ spec:
backendProfile: grok
providerCredential:
secretRef:
namespace: agentrun-v02
name: agentrun-v02-provider-grok
namespace: agentrun-release
name: agentrun-release-provider-grok
keys:
- auth.json
- config.toml
@@ -66,7 +66,8 @@ spec:
- tool: github
purpose: github-pr
secretRef:
name: agentrun-v01-tool-github-pr
namespace: agentrun-release
name: agentrun-release-tool-github-pr
keys:
- GH_TOKEN
projection:
@@ -76,8 +77,8 @@ spec:
- tool: github
purpose: repository-override-pikainc-pikaoa
secretRef:
namespace: agentrun-v02
name: agentrun-v02-tool-github-repository-overrides
namespace: agentrun-release
name: agentrun-release-tool-github-repository-overrides
keys:
- PIKAINC_PIKAOA_GH_TOKEN
projection:
@@ -87,7 +88,8 @@ spec:
- tool: unidesk-ssh
purpose: ssh-passthrough
secretRef:
name: agentrun-v01-tool-unidesk-ssh
namespace: agentrun-release
name: agentrun-release-tool-unidesk-ssh
keys:
- UNIDESK_SSH_CLIENT_TOKEN
projection:
@@ -97,7 +99,8 @@ spec:
- tool: github
purpose: github-ssh
secretRef:
name: agentrun-v01-tool-github-ssh
namespace: agentrun-release
name: agentrun-release-tool-github-ssh
keys:
- id_ed25519
- known_hosts
@@ -114,7 +117,7 @@ spec:
targetPath: .agents/skills
- name: agentrun-runner-tools
repoUrl: git@github.com:pikasTech/agentrun.git
ref: v0.2
ref: release
subpath: tools
targetPath: tools
- name: dad-dev-skill
@@ -170,4 +173,4 @@ spec:
source: config/aipods/artificer.yaml
dispatchDefaults:
runnerJob:
namespace: agentrun-v02
namespace: agentrun-release
+33 -33
View File
@@ -31,13 +31,13 @@ const selfTest: SelfTestCase = async (context) => {
: { stdout: "{}", stderr: "", exitCode: 0 },
},
runnerJobDefaults: {
namespace: "agentrun-v02",
managerUrl: "http://agentrun-mgr.agentrun-v02.svc.cluster.local:8080",
namespace: "agentrun-release",
managerUrl: "http://agentrun-mgr.agentrun-release.svc.cluster.local:8080",
image: "agentrun-selftest:latest",
serviceAccountName: "agentrun-v02-runner",
jobNamePrefix: "agentrun-v02-runner",
runnerApiKeySecretRef: { name: "agentrun-v02-api-key", key: "HWLAB_API_KEY" },
lane: "v0.2",
serviceAccountName: "agentrun-release-runner",
jobNamePrefix: "agentrun-release-runner",
runnerApiKeySecretRef: { name: "agentrun-release-api-key", key: "HWLAB_API_KEY" },
lane: "release",
},
});
try {
@@ -55,7 +55,7 @@ const selfTest: SelfTestCase = async (context) => {
const shownItem = shown.item as JsonRecord;
assert.equal(shownItem.backendProfile, "gpt-pika");
assert.equal(shownItem.providerId, "NC01");
assert.equal(shownItem.lane, "v0.2");
assert.equal(shownItem.lane, "release");
assert.equal(((shownItem.model as JsonRecord).model), "gpt-5.6-sol");
assert.equal(((shownItem.model as JsonRecord).reasoningEffort), "medium");
assert.deepEqual(shownItem.gitIdentity, {
@@ -70,11 +70,11 @@ const selfTest: SelfTestCase = async (context) => {
const shownProviderCredentials = shownItem.providerCredentials as JsonRecord;
assert.equal(shownProviderCredentials.count, 2);
const shownProviderCredential = (shownProviderCredentials.items as JsonRecord[]).find((item) => item.profile === "gpt-pika");
assert.equal(shownProviderCredential?.name, "agentrun-v02-provider-gpt-pika");
assert.equal(shownProviderCredential?.namespace, "agentrun-v02");
assert.equal(shownProviderCredential?.name, "agentrun-release-provider-gpt-pika");
assert.equal(shownProviderCredential?.namespace, "agentrun-release");
const shownGrokCredential = (shownProviderCredentials.items as JsonRecord[]).find((item) => item.profile === "grok");
assert.equal(shownGrokCredential?.name, "agentrun-v02-provider-grok");
assert.equal(shownGrokCredential?.namespace, "agentrun-v02");
assert.equal(shownGrokCredential?.name, "agentrun-release-provider-grok");
assert.equal(shownGrokCredential?.namespace, "agentrun-release");
const shownRouting = shownItem.modelRouting as JsonRecord;
assert.deepEqual(shownRouting.default, { upstream: "pika", model: "gpt-5.6-sol", reasoningEffort: "medium", valuesPrinted: false });
assert.equal((shownRouting.exact as JsonRecord[]).some((item) => item.model === "grok" && item.upstream === "grok" && item.reasoningEffort === "xhigh"), true);
@@ -85,8 +85,8 @@ const selfTest: SelfTestCase = async (context) => {
assert.deepEqual(shownRepositoryOverride, {
tool: "github",
purpose: "repository-override-pikainc-pikaoa",
name: "agentrun-v02-tool-github-repository-overrides",
namespace: "agentrun-v02",
name: "agentrun-release-tool-github-repository-overrides",
namespace: "agentrun-release",
keys: ["PIKAINC_PIKAOA_GH_TOKEN"],
projection: { kind: "env", envName: "UNIDESK_GH_TOKEN_PIKAINC_PIKAOA", secretKey: "PIKAINC_PIKAOA_GH_TOKEN" },
valuesPrinted: false,
@@ -103,7 +103,7 @@ const selfTest: SelfTestCase = async (context) => {
const task = rendered.queueTask as JsonRecord;
assert.equal(task.backendProfile, "gpt-pika");
assert.equal(task.providerId, "NC01");
assert.equal(task.lane, "v0.2");
assert.equal(task.lane, "release");
assert.equal(task.idempotencyKey, "selftest-aipod-artificer");
const workspaceRef = task.workspaceRef as JsonRecord;
assert.deepEqual(workspaceRef, { kind: "opaque", path: "." });
@@ -116,7 +116,7 @@ const selfTest: SelfTestCase = async (context) => {
const runnerDefaults = ((rendered.dispatchDefaults as JsonRecord).runnerJob as JsonRecord);
assert.equal(((runnerDefaults.imageRef as JsonRecord).kind), "env-image-dockerfile");
assert.equal(((runnerDefaults.imageRef as JsonRecord).dockerfilePath), "deploy/container/Containerfile");
assert.equal(runnerDefaults.namespace, "agentrun-v02");
assert.equal(runnerDefaults.namespace, "agentrun-release");
const taskPayload = task.payload as JsonRecord;
assert.equal(taskPayload.model, "gpt-5.6-sol");
assert.equal(taskPayload.reasoningEffort, "medium");
@@ -139,22 +139,22 @@ const selfTest: SelfTestCase = async (context) => {
const secretScope = policy.secretScope as JsonRecord;
const providerCredentials = secretScope.providerCredentials as JsonRecord[];
const providerCredential = providerCredentials.find((item) => item.profile === "gpt-pika") as JsonRecord | undefined;
assert.equal(((providerCredential?.secretRef as JsonRecord).name), "agentrun-v02-provider-gpt-pika");
assert.equal(((providerCredential?.secretRef as JsonRecord).namespace), "agentrun-v02");
assert.equal(((providerCredential?.secretRef as JsonRecord).name), "agentrun-release-provider-gpt-pika");
assert.equal(((providerCredential?.secretRef as JsonRecord).namespace), "agentrun-release");
assert.deepEqual(((providerCredential?.secretRef as JsonRecord).keys), ["auth.json", "config.toml"]);
assert.equal(runnerDefaults.namespace, (providerCredential?.secretRef as JsonRecord).namespace, "runner Pod and gpt-pika Secret must share a namespace");
const disclosedProviderCredential = modelResolution.providerCredential as JsonRecord;
assert.equal(disclosedProviderCredential.profile, "gpt-pika");
assert.deepEqual(disclosedProviderCredential.secretRef, { name: "agentrun-v02-provider-gpt-pika", namespace: "agentrun-v02", keys: ["auth.json", "config.toml"], valuesPrinted: false });
assert.deepEqual(disclosedProviderCredential.secretRef, { name: "agentrun-release-provider-gpt-pika", namespace: "agentrun-release", keys: ["auth.json", "config.toml"], valuesPrinted: false });
const toolCredentials = secretScope.toolCredentials as JsonRecord[];
assert.equal(toolCredentials.some((item) => item.tool === "github" && ((item.projection as JsonRecord).kind) === "env" && ((item.projection as JsonRecord).envName) === "GH_TOKEN" && ((item.secretRef as JsonRecord).name) === "agentrun-v01-tool-github-pr"), true);
assert.equal(toolCredentials.some((item) => item.tool === "github" && ((item.projection as JsonRecord).kind) === "env" && ((item.projection as JsonRecord).envName) === "GH_TOKEN" && ((item.secretRef as JsonRecord).name) === "agentrun-release-tool-github-pr"), true);
const repositoryOverride = toolCredentials.find((item) => item.tool === "github" && item.purpose === "repository-override-pikainc-pikaoa") as JsonRecord | undefined;
assert.deepEqual(repositoryOverride, {
tool: "github",
purpose: "repository-override-pikainc-pikaoa",
secretRef: {
namespace: "agentrun-v02",
name: "agentrun-v02-tool-github-repository-overrides",
namespace: "agentrun-release",
name: "agentrun-release-tool-github-repository-overrides",
keys: ["PIKAINC_PIKAOA_GH_TOKEN"],
},
projection: { kind: "env", envName: "UNIDESK_GH_TOKEN_PIKAINC_PIKAOA", secretKey: "PIKAINC_PIKAOA_GH_TOKEN" },
@@ -169,7 +169,7 @@ const selfTest: SelfTestCase = async (context) => {
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");
assert.equal(toolBundle?.ref, "v0.2");
assert.equal(toolBundle?.ref, "release");
assert.equal(toolBundle?.subpath, "tools");
assert.equal(toolBundle?.targetPath, "tools");
assert.equal((bundle.requiredSkills as JsonRecord[]).some((item) => item.name === "dad-dev"), true);
@@ -191,9 +191,9 @@ const selfTest: SelfTestCase = async (context) => {
run: runnerRun,
commandId: runnerCommand.id,
managerUrl: server.baseUrl,
runnerApiKeySecretRef: { name: "agentrun-v02-api-key", key: "HWLAB_API_KEY" },
runnerApiKeySecretRef: { name: "agentrun-release-api-key", key: "HWLAB_API_KEY" },
image: "agentrun-selftest:latest",
namespace: "agentrun-v02",
namespace: "agentrun-release",
attemptId: "attempt_artificer_private_repository_override",
sourceCommit: "self-test",
});
@@ -201,11 +201,11 @@ const selfTest: SelfTestCase = async (context) => {
assert.ok(overrideEnv, "Artificer runner Job must project the repository override credential");
assert.equal(overrideEnv.value, undefined);
assert.deepEqual(((overrideEnv.valueFrom as JsonRecord).secretKeyRef), {
name: "agentrun-v02-tool-github-repository-overrides",
name: "agentrun-release-tool-github-repository-overrides",
key: "PIKAINC_PIKAOA_GH_TOKEN",
});
const defaultGithubEnv = runnerEnvEntry(runnerJob.manifest as JsonRecord, "GH_TOKEN");
assert.deepEqual(((defaultGithubEnv?.valueFrom as JsonRecord).secretKeyRef), { name: "agentrun-v01-tool-github-pr", key: "GH_TOKEN" });
assert.deepEqual(((defaultGithubEnv?.valueFrom as JsonRecord).secretKeyRef), { name: "agentrun-release-tool-github-pr", key: "GH_TOKEN" });
const runnerToolCredentialSummary = runnerJob.toolCredentials as JsonRecord;
assert.equal(runnerToolCredentialSummary.count, 4);
assert.equal(runnerToolCredentialSummary.valuesPrinted, false);
@@ -239,7 +239,7 @@ const selfTest: SelfTestCase = async (context) => {
assert.equal(grokResolution.backendProfileSource, "model-routing-exact");
assert.equal(grokCredentials.length, 1);
assert.equal(grokCredentials[0]?.profile, "grok");
assert.equal(((grokCredentials[0]?.secretRef as JsonRecord).name), "agentrun-v02-provider-grok");
assert.equal(((grokCredentials[0]?.secretRef as JsonRecord).name), "agentrun-release-provider-grok");
assert.equal(grokCredentials.some((item) => item.profile === "gpt-pika"), false);
assertNoSecretLeak(grokOverride);
@@ -268,8 +268,8 @@ const selfTest: SelfTestCase = async (context) => {
assert.throws(() => validateAipodSpec(missingCredentialDocument, "selftest-missing-grok-credential"), /providerCredential/u);
const missingKeyDocument = structuredClone(originalSpecDocument);
((((missingKeyDocument.spec as JsonRecord).upstreams as JsonRecord).grok as JsonRecord).providerCredential as JsonRecord).secretRef = {
namespace: "agentrun-v02",
name: "agentrun-v02-provider-grok",
namespace: "agentrun-release",
name: "agentrun-release-provider-grok",
keys: ["auth.json"],
};
assert.throws(() => validateAipodSpec(missingKeyDocument, "selftest-missing-grok-key"), /missing required keys/u);
@@ -290,7 +290,7 @@ const selfTest: SelfTestCase = async (context) => {
legacySpec.model = { model: "gpt-5.6-sol", reasoningEffort: "medium" };
(((legacySpec.executionPolicy as JsonRecord).secretScope as JsonRecord).providerCredentials) = [{
profile: "gpt-pika",
secretRef: { namespace: "agentrun-v02", name: "agentrun-v02-provider-gpt-pika", keys: ["auth.json", "config.toml"] },
secretRef: { namespace: "agentrun-release", name: "agentrun-release-provider-gpt-pika", keys: ["auth.json", "config.toml"] },
}];
assert.equal(validateAipodSpec(legacySingleUpstreamDocument, "selftest-legacy-single-upstream").spec.backendProfile, "gpt-pika");
const payloadDefaultsBypassDocument = structuredClone(originalSpecDocument);
@@ -341,14 +341,14 @@ const selfTest: SelfTestCase = async (context) => {
assert.equal(sendPlanData.profile, "gpt-pika");
assert.equal((sendPlanData.modelResolution as JsonRecord).model, "gpt-5.4");
assert.equal((sendPlanData.modelResolution as JsonRecord).reasoningEffort, "medium");
assert.equal((((sendPlanData.modelResolution as JsonRecord).providerCredential as JsonRecord).secretRef as JsonRecord).name, "agentrun-v02-provider-gpt-pika");
assert.equal((((sendPlanData.modelResolution as JsonRecord).providerCredential as JsonRecord).secretRef as JsonRecord).name, "agentrun-release-provider-gpt-pika");
const grokSendPlan = await runCliJson(context, server.baseUrl, ["sessions", "send", "--aipod", "Artificer", "--prompt", "dry-run grok session", "--model", "grok", "--no-runner-job", "--dry-run"]);
const grokSendPlanData = grokSendPlan.data as JsonRecord;
assert.equal(grokSendPlanData.profile, "grok");
assert.equal((grokSendPlanData.modelResolution as JsonRecord).upstreamId, "grok");
assert.equal((grokSendPlanData.modelResolution as JsonRecord).matchedBy, "exact");
assert.equal((((grokSendPlanData.modelResolution as JsonRecord).providerCredential as JsonRecord).secretRef as JsonRecord).name, "agentrun-v02-provider-grok");
assert.equal((((grokSendPlanData.modelResolution as JsonRecord).providerCredential as JsonRecord).secretRef as JsonRecord).name, "agentrun-release-provider-grok");
const cancelledSessionId = "sess_artificer_cancelled_cli_selftest";
const cancelledConversationId = "conv_artificer_cancelled_cli_selftest";
@@ -415,7 +415,7 @@ const selfTest: SelfTestCase = async (context) => {
assert.equal((storedTask.payload as JsonRecord).model, "gpt-5.6-sol");
assert.equal((storedTask.payload as JsonRecord).reasoningEffort, "medium");
assert.deepEqual((storedTask.payload as JsonRecord).modelConfig, taskPayload.modelConfig);
return { name: "aipod-spec", tests: ["aipod-spec-yaml-parser-runtime-compatible", "aipod-spec-artificer-image-ref-render", "aipod-spec-artificer-v02-runtime-authority", "aipod-spec-multi-upstream-secret-summary", "aipod-spec-legacy-single-upstream-compatible", "aipod-spec-model-defaults", "aipod-spec-model-reasoning-overrides", "aipod-spec-model-default-fallback", "aipod-spec-grok-exact-route", "aipod-spec-selected-provider-only", "aipod-spec-invalid-route-fail-closed", "aipod-spec-control-override-fail-closed", "aipod-spec-payload-control-bypass-fail-closed", "aipod-spec-durable-task-model-snapshot", "aipod-spec-primary-workspace-contract", "aipod-spec-artificer-github-url-render", "aipod-spec-artificer-github-ssh-required-keys", "aipod-spec-artificer-private-repository-override", "aipod-spec-artificer-private-repository-override-runner-projection", "aipod-spec-git-mirror-url", "git-fetch-stderr-classification", "resource-bundle-source-authority-validation", "resource-bundle-target-conflict-validation", "queue-submit-aipod-dry-run", "session-send-aipod-model-dry-run", "session-send-aipod-grok-dry-run", "session-send-aipod-cancelled-durable-identity", "session-send-aipod-boundary-conflict-fail-closed", "aipod-cli-help"] };
return { name: "aipod-spec", tests: ["aipod-spec-yaml-parser-runtime-compatible", "aipod-spec-artificer-image-ref-render", "aipod-spec-artificer-release-runtime-authority", "aipod-spec-multi-upstream-secret-summary", "aipod-spec-legacy-single-upstream-compatible", "aipod-spec-model-defaults", "aipod-spec-model-reasoning-overrides", "aipod-spec-model-default-fallback", "aipod-spec-grok-exact-route", "aipod-spec-selected-provider-only", "aipod-spec-invalid-route-fail-closed", "aipod-spec-control-override-fail-closed", "aipod-spec-payload-control-bypass-fail-closed", "aipod-spec-durable-task-model-snapshot", "aipod-spec-primary-workspace-contract", "aipod-spec-artificer-github-url-render", "aipod-spec-artificer-github-ssh-required-keys", "aipod-spec-artificer-private-repository-override", "aipod-spec-artificer-private-repository-override-runner-projection", "aipod-spec-git-mirror-url", "git-fetch-stderr-classification", "resource-bundle-source-authority-validation", "resource-bundle-target-conflict-validation", "queue-submit-aipod-dry-run", "session-send-aipod-model-dry-run", "session-send-aipod-grok-dry-run", "session-send-aipod-cancelled-durable-identity", "session-send-aipod-boundary-conflict-fail-closed", "aipod-cli-help"] };
} finally {
await new Promise<void>((resolve) => server.server.close(() => resolve()));
}
@@ -17,13 +17,13 @@ const selfTest: SelfTestCase = async (context) => {
store: new MemoryAgentRunStore(),
aipodSpecDir: path.join(context.root, "config", "aipods"),
runnerJobDefaults: {
namespace: "agentrun-v02",
managerUrl: "http://agentrun-mgr.agentrun-v02.svc.cluster.local:8080",
namespace: "agentrun-release",
managerUrl: "http://agentrun-mgr.agentrun-release.svc.cluster.local:8080",
image: "agentrun-selftest:latest",
serviceAccountName: "agentrun-v02-runner",
jobNamePrefix: "agentrun-v02-runner",
runnerApiKeySecretRef: { name: "agentrun-v02-api-key", key: "HWLAB_API_KEY" },
lane: "v0.2",
serviceAccountName: "agentrun-release-runner",
jobNamePrefix: "agentrun-release-runner",
runnerApiKeySecretRef: { name: "agentrun-release-api-key", key: "HWLAB_API_KEY" },
lane: "release",
},
});
try {
@@ -176,14 +176,14 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
taskId: task.id,
input: { idempotencyKey: "artificer-model-retry", reason: "verify durable model payload" },
defaults: {
namespace: "agentrun-v02",
managerUrl: "http://agentrun-mgr.agentrun-v02.svc.cluster.local:8080",
runnerApiKeySecretRef: { name: "agentrun-v02-api-key", key: "HWLAB_API_KEY" },
namespace: "agentrun-release",
managerUrl: "http://agentrun-mgr.agentrun-release.svc.cluster.local:8080",
runnerApiKeySecretRef: { name: "agentrun-release-api-key", key: "HWLAB_API_KEY" },
image: "127.0.0.1:5000/agentrun/agentrun-mgr@sha256:1111111111111111111111111111111111111111111111111111111111111111",
sourceCommit: "self-test",
serviceAccountName: "agentrun-v02-runner",
jobNamePrefix: "agentrun-v02-runner",
lane: "v0.2",
serviceAccountName: "agentrun-release-runner",
jobNamePrefix: "agentrun-release-runner",
lane: "release",
kubectlCommand: fakeKubectl,
},
});