Merge remote-tracking branch 'origin/v0.2' into fix/356-stale-turn-admission
This commit is contained in:
@@ -55,6 +55,17 @@ spec:
|
||||
kind: env
|
||||
envName: GH_TOKEN
|
||||
secretKey: GH_TOKEN
|
||||
- tool: github
|
||||
purpose: repository-override-pikainc-pikaoa
|
||||
secretRef:
|
||||
namespace: agentrun-v02
|
||||
name: agentrun-v02-tool-github-repository-overrides
|
||||
keys:
|
||||
- PIKAINC_PIKAOA_GH_TOKEN
|
||||
projection:
|
||||
kind: env
|
||||
envName: UNIDESK_GH_TOKEN_PIKAINC_PIKAOA
|
||||
secretKey: PIKAINC_PIKAOA_GH_TOKEN
|
||||
- tool: unidesk-ssh
|
||||
purpose: ssh-passthrough
|
||||
secretRef:
|
||||
|
||||
@@ -9,6 +9,7 @@ import { MemoryAgentRunStore } from "../../mgr/store.js";
|
||||
import type { JsonRecord } from "../../common/types.js";
|
||||
import { validateAipodSpec } from "../../common/aipod-specs.js";
|
||||
import { validateCreateCommand, validateCreateRun, validatePrimaryWorkspaceContract, validateResourceBundleRef } from "../../common/validation.js";
|
||||
import { renderRunnerJobDryRun } from "../../runner/k8s-job.js";
|
||||
import { classifyGitStderr, resolveGitBundleFetchSource } from "../../runner/resource-bundle.js";
|
||||
import { assertNoSecretLeak, loadArtificerImageRef, type SelfTestCase } from "../harness.js";
|
||||
|
||||
@@ -70,6 +71,19 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
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");
|
||||
const shownToolCredentials = shownItem.toolCredentials as JsonRecord;
|
||||
assert.equal(shownToolCredentials.count, 4);
|
||||
assert.equal(shownToolCredentials.valuesPrinted, false);
|
||||
const shownRepositoryOverride = (shownToolCredentials.items as JsonRecord[]).find((item) => item.purpose === "repository-override-pikainc-pikaoa") as JsonRecord | undefined;
|
||||
assert.deepEqual(shownRepositoryOverride, {
|
||||
tool: "github",
|
||||
purpose: "repository-override-pikainc-pikaoa",
|
||||
name: "agentrun-v02-tool-github-repository-overrides",
|
||||
namespace: "agentrun-v02",
|
||||
keys: ["PIKAINC_PIKAOA_GH_TOKEN"],
|
||||
projection: { kind: "env", envName: "UNIDESK_GH_TOKEN_PIKAINC_PIKAOA", secretKey: "PIKAINC_PIKAOA_GH_TOKEN" },
|
||||
valuesPrinted: false,
|
||||
});
|
||||
const shownImageRef = shownItem.imageRef as JsonRecord;
|
||||
assert.equal(shownImageRef.kind, "env-image-dockerfile");
|
||||
assert.equal(shownImageRef.repoUrl, "git@github.com:pikasTech/agentrun.git");
|
||||
@@ -124,6 +138,17 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
assert.deepEqual(disclosedProviderCredential.secretRef, { name: "agentrun-v02-provider-gpt-pika", namespace: "agentrun-v02", 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);
|
||||
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",
|
||||
keys: ["PIKAINC_PIKAOA_GH_TOKEN"],
|
||||
},
|
||||
projection: { kind: "env", envName: "UNIDESK_GH_TOKEN_PIKAINC_PIKAOA", secretKey: "PIKAINC_PIKAOA_GH_TOKEN" },
|
||||
});
|
||||
assert.equal(toolCredentials.some((item) => item.tool === "unidesk-ssh" && ((item.projection as JsonRecord).envName) === "UNIDESK_SSH_CLIENT_TOKEN"), true);
|
||||
const githubSshCredential = toolCredentials.find((item) => item.tool === "github" && item.purpose === "github-ssh") as JsonRecord | undefined;
|
||||
assert.equal(((githubSshCredential?.projection as JsonRecord).kind), "volume");
|
||||
@@ -141,6 +166,42 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
assert.equal((bundle.requiredSkills as JsonRecord[]).some((item) => item.name === "unidesk-gh"), true);
|
||||
assertNoSecretLeak(rendered);
|
||||
|
||||
const runnerRun = store.createRun(validateCreateRun({
|
||||
tenantId: task.tenantId,
|
||||
projectId: task.projectId,
|
||||
providerId: task.providerId,
|
||||
backendProfile: task.backendProfile,
|
||||
workspaceRef: task.workspaceRef,
|
||||
executionPolicy: task.executionPolicy,
|
||||
resourceBundleRef: task.resourceBundleRef,
|
||||
traceSink: { kind: "self-test", source: "artificer-private-repository-override" },
|
||||
}));
|
||||
const runnerCommand = store.createCommand(runnerRun.id, validateCreateCommand({ type: "turn", payload: { prompt: "验证私有仓凭据投影" } }));
|
||||
const runnerJob = renderRunnerJobDryRun({
|
||||
run: runnerRun,
|
||||
commandId: runnerCommand.id,
|
||||
managerUrl: server.baseUrl,
|
||||
runnerApiKeySecretRef: { name: "agentrun-v02-api-key", key: "HWLAB_API_KEY" },
|
||||
image: "agentrun-selftest:latest",
|
||||
namespace: "agentrun-v02",
|
||||
attemptId: "attempt_artificer_private_repository_override",
|
||||
sourceCommit: "self-test",
|
||||
});
|
||||
const overrideEnv = runnerEnvEntry(runnerJob.manifest as JsonRecord, "UNIDESK_GH_TOKEN_PIKAINC_PIKAOA");
|
||||
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",
|
||||
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" });
|
||||
const runnerToolCredentialSummary = runnerJob.toolCredentials as JsonRecord;
|
||||
assert.equal(runnerToolCredentialSummary.count, 4);
|
||||
assert.equal(runnerToolCredentialSummary.valuesPrinted, false);
|
||||
assert.equal((runnerToolCredentialSummary.items as JsonRecord[]).every((item) => item.valuesPrinted === false), true);
|
||||
assertNoSecretLeak(runnerJob);
|
||||
|
||||
const modelOverride = await client.post("/api/v1/aipod-specs/Artificer/render", { prompt: "override model", model: "gpt-5.4", reasoningEffort: "high" }) as JsonRecord;
|
||||
const modelOverrideTask = modelOverride.queueTask as JsonRecord;
|
||||
const modelOverridePayload = modelOverrideTask.payload as JsonRecord;
|
||||
@@ -292,7 +353,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-gpt-pika-secret-namespace", "aipod-spec-model-defaults", "aipod-spec-model-reasoning-overrides", "aipod-spec-model-override-keeps-provider", "aipod-spec-control-override-fail-closed", "aipod-spec-payload-control-bypass-fail-closed", "aipod-spec-missing-gpt-pika-credential", "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-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-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-v02-runtime-authority", "aipod-spec-gpt-pika-secret-namespace", "aipod-spec-model-defaults", "aipod-spec-model-reasoning-overrides", "aipod-spec-model-override-keeps-provider", "aipod-spec-control-override-fail-closed", "aipod-spec-payload-control-bypass-fail-closed", "aipod-spec-missing-gpt-pika-credential", "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-cancelled-durable-identity", "session-send-aipod-boundary-conflict-fail-closed", "aipod-cli-help"] };
|
||||
} finally {
|
||||
await new Promise<void>((resolve) => server.server.close(() => resolve()));
|
||||
}
|
||||
@@ -311,6 +372,15 @@ console.log(JSON.stringify({ name: spec.metadata.name, hasBunGlobal: typeof glob
|
||||
return JSON.parse(stdout) as JsonRecord;
|
||||
}
|
||||
|
||||
function runnerEnvEntry(manifest: JsonRecord, name: string): JsonRecord | undefined {
|
||||
const spec = manifest.spec as JsonRecord;
|
||||
const template = spec.template as JsonRecord;
|
||||
const podSpec = template.spec as JsonRecord;
|
||||
const containers = podSpec.containers as JsonRecord[];
|
||||
const runner = containers[0] as JsonRecord;
|
||||
return (runner.env as JsonRecord[]).find((item) => item.name === name);
|
||||
}
|
||||
|
||||
async function runCliJson(context: { root: string }, managerUrl: string, args: string[]): Promise<JsonRecord> {
|
||||
const proc = spawn(process.execPath, [`${context.root}/scripts/agentrun-cli.ts`, "--manager-url", managerUrl, ...args], { stdio: ["ignore", "pipe", "pipe"] });
|
||||
const [stdout, stderr, code] = await Promise.all([readStream(proc.stdout), readStream(proc.stderr), new Promise<number | null>((resolve) => proc.on("close", resolve))]);
|
||||
|
||||
Reference in New Issue
Block a user