feat: add aipod spec Artificer assembly

This commit is contained in:
Codex
2026-06-10 17:46:45 +08:00
parent 45df61bd02
commit 6989dc18ef
22 changed files with 2103 additions and 56 deletions
+31 -10
View File
@@ -79,14 +79,26 @@ interface CredentialProjection {
projectionMountPath: string;
}
interface ToolCredentialProjection {
type ToolCredentialProjection = ToolCredentialEnvProjection | ToolCredentialVolumeProjection;
interface ToolCredentialBaseProjection {
tool: string;
purpose: string | null;
secretRef: SecretRef;
}
interface ToolCredentialEnvProjection extends ToolCredentialBaseProjection {
kind: "env";
envName: string;
secretKey: string;
}
interface ToolCredentialVolumeProjection extends ToolCredentialBaseProjection {
kind: "volume";
volumeName: string;
mountPath: string;
}
export function renderRunnerJobDryRun(options: RunnerJobRenderOptions): JsonRecord {
const render = renderRunnerJobManifest({ ...options, dryRun: true });
const manifest = redactTransientEnvInManifest(render.manifest, options.transientEnv ?? []);
@@ -176,6 +188,7 @@ export function renderRunnerJobManifest(options: RunnerJobRenderOptions): { mani
volumeMounts: [
{ name: "runner-home", mountPath: "/home/agentrun" },
...secretRefs.map((item) => ({ name: item.volumeName, mountPath: item.projectionMountPath, readOnly: true })),
...toolCredentialVolumeMounts(toolCredentials),
...(sessionPvc ? [{ name: "agentrun-sessions", mountPath: sessionPvc.mountPath, readOnly: false }] : []),
],
resources: {
@@ -192,6 +205,7 @@ export function renderRunnerJobManifest(options: RunnerJobRenderOptions): { mani
volumes: [
{ name: "runner-home", emptyDir: {} },
...secretRefs.map(secretVolume),
...toolCredentialVolumes(toolCredentials),
...(sessionPvc ? [{ name: "agentrun-sessions", persistentVolumeClaim: { claimName: sessionPvc.pvcName } }] : []),
],
},
@@ -248,7 +262,7 @@ function codexShellSandbox(policy: ExecutionPolicy): string {
}
function toolCredentialEnvVars(items: ToolCredentialProjection[]): JsonRecord[] {
return items.map((item) => ({
return items.filter((item): item is ToolCredentialEnvProjection => item.kind === "env").map((item) => ({
name: item.envName,
valueFrom: {
secretKeyRef: {
@@ -259,6 +273,14 @@ function toolCredentialEnvVars(items: ToolCredentialProjection[]): JsonRecord[]
}));
}
function toolCredentialVolumeMounts(items: ToolCredentialProjection[]): JsonRecord[] {
return items.filter((item): item is ToolCredentialVolumeProjection => item.kind === "volume").map((item) => ({ name: item.volumeName, mountPath: item.mountPath, readOnly: true }));
}
function toolCredentialVolumes(items: ToolCredentialProjection[]): JsonRecord[] {
return items.filter((item): item is ToolCredentialVolumeProjection => item.kind === "volume").map((item) => secretVolume({ profile: item.tool, secretRef: item.secretRef, volumeName: item.volumeName, runtimeMountPath: item.mountPath, projectionMountPath: item.mountPath }));
}
function transientEnvVars(items: RunnerTransientEnv[]): JsonRecord[] {
return items.map((item) => {
if (item.secretRef) {
@@ -318,7 +340,7 @@ function summarizeToolCredentials(items: ToolCredentialProjection[], namespace:
name: item.secretRef.name,
namespace: item.secretRef.namespace ?? namespace,
keys: item.secretRef.keys ?? [],
projection: { kind: "env", envName: item.envName, secretKey: item.secretKey },
projection: item.kind === "env" ? { kind: "env", envName: item.envName, secretKey: item.secretKey } : { kind: "volume", mountPath: item.mountPath },
valuesPrinted: false,
})),
valuesPrinted: false,
@@ -363,13 +385,12 @@ function credentialSecretRef(profile: string, secretRef: SecretRef, namespace: s
function toolCredentialProjections(run: RunRecord, namespace: string): ToolCredentialProjection[] {
const policy: ExecutionPolicy = run.executionPolicy;
const credentials = policy.secretScope.toolCredentials ?? [];
return credentials.map((item) => ({
tool: item.tool,
purpose: item.purpose ?? null,
secretRef: item.secretRef.namespace ? item.secretRef : { ...item.secretRef, namespace },
envName: item.projection.envName,
secretKey: item.projection.secretKey ?? item.secretRef.keys?.[0] ?? item.projection.envName,
}));
return credentials.map((item, index) => {
const secretRef = item.secretRef.namespace ? item.secretRef : { ...item.secretRef, namespace };
const base = { tool: item.tool, purpose: item.purpose ?? null, secretRef };
if (item.projection.kind === "env") return { ...base, kind: "env" as const, envName: item.projection.envName, secretKey: item.projection.secretKey ?? item.secretRef.keys?.[0] ?? item.projection.envName };
return { ...base, kind: "volume" as const, volumeName: sanitizeVolumeName(`tool-${item.tool}-${index}`), mountPath: item.projection.mountPath };
});
}
function secretVolume(item: CredentialProjection): JsonRecord {
+76 -14
View File
@@ -43,6 +43,9 @@ interface MaterializedSkillRef {
interface GitCheckout {
repoUrl: string;
fetchRepoUrl: string;
mirrorUsed: boolean;
mirrorBaseUrl?: string;
commitId: string;
requestedCommitId?: string;
requestedRef?: string;
@@ -50,15 +53,24 @@ interface GitCheckout {
treeId: string;
}
interface GitMirrorConfig {
enabled: true;
baseUrl: string;
}
interface GitBundleSource {
repoUrl: string;
commitId?: string;
ref?: string;
gitMirror?: GitMirrorConfig;
}
interface MaterializedGitBundle {
name: string | null;
repoUrl: string;
fetchRepoUrl: string;
mirrorUsed: boolean;
mirrorBaseUrl: string | null;
commitId: string;
requestedCommitId: string | null;
requestedRef: string | null;
@@ -78,7 +90,8 @@ export async function materializeResourceBundle(resourceBundleRef: ResourceBundl
await rm(assemblyRoot, { recursive: true, force: true });
await mkdir(checkoutRoot, { recursive: true });
await mkdir(workspacePath, { recursive: true });
const defaultSource = defaultGitBundleSource(resourceBundleRef, env);
const gitMirror = gitMirrorConfig(resourceBundleRef, env);
const defaultSource = defaultGitBundleSource(resourceBundleRef, env, gitMirror);
const checkoutCache = new Map<string, Promise<GitCheckout>>();
const checkoutFor = (source: GitBundleSource) => {
const key = stableHash(gitSourceIdentity(source));
@@ -105,6 +118,10 @@ export async function materializeResourceBundle(resourceBundleRef: ResourceBundl
phase: "resource-bundle-materialized",
kind: "gitbundle",
repoUrl: resourceBundleRef.repoUrl,
fetchRepoUrl: defaultCheckout.fetchRepoUrl,
mirrorUsed: defaultCheckout.mirrorUsed,
mirrorBaseUrl: defaultCheckout.mirrorBaseUrl ?? null,
gitMirror: gitMirror ? { enabled: true, baseUrl: gitMirror.baseUrl, valuesPrinted: false } : { enabled: false, baseUrl: null, valuesPrinted: false },
commitId: defaultCheckout.commitId,
requestedCommitId: resourceBundleRef.commitId ?? null,
requestedRef: defaultCheckout.requestedRef ?? null,
@@ -126,32 +143,44 @@ export async function materializeResourceBundle(resourceBundleRef: ResourceBundl
};
}
function defaultGitBundleSource(resourceBundleRef: ResourceBundleRef, env: NodeJS.ProcessEnv): GitBundleSource {
function gitMirrorConfig(resourceBundleRef: ResourceBundleRef, env: NodeJS.ProcessEnv): GitMirrorConfig | undefined {
return normalizeGitMirrorConfig(resourceBundleRef.gitMirror, env);
}
function normalizeGitMirrorConfig(gitMirror: ResourceBundleRef["gitMirror"] | GitMirrorConfig | undefined, env: NodeJS.ProcessEnv): GitMirrorConfig | undefined {
if (!gitMirror || gitMirror.enabled === false) return undefined;
const baseUrl = optionalNonEmpty(gitMirror.baseUrl) ?? optionalNonEmpty(env.AGENTRUN_GIT_MIRROR_BASE_URL) ?? "http://git-mirror-http.devops-infra.svc.cluster.local";
return { enabled: true, baseUrl: baseUrl.replace(/\/+$/u, "") };
}
function defaultGitBundleSource(resourceBundleRef: ResourceBundleRef, env: NodeJS.ProcessEnv, gitMirror?: GitMirrorConfig): GitBundleSource {
const ref = optionalNonEmpty(resourceBundleRef.ref) ?? optionalNonEmpty(env.AGENTRUN_RESOURCE_BUNDLE_REF) ?? optionalNonEmpty(env.AGENTRUN_WORKSPACE_REF) ?? optionalNonEmpty(env.AGENTRUN_WORKSPACE_BRANCH);
if (ref) return { repoUrl: resourceBundleRef.repoUrl, ref };
if (ref) return { repoUrl: resourceBundleRef.repoUrl, ref, ...(gitMirror ? { gitMirror } : {}) };
const commitId = optionalNonEmpty(resourceBundleRef.commitId);
if (commitId) return { repoUrl: resourceBundleRef.repoUrl, commitId };
return { repoUrl: resourceBundleRef.repoUrl, ref: "HEAD" };
if (commitId) return { repoUrl: resourceBundleRef.repoUrl, commitId, ...(gitMirror ? { gitMirror } : {}) };
return { repoUrl: resourceBundleRef.repoUrl, ref: "HEAD", ...(gitMirror ? { gitMirror } : {}) };
}
function bundleGitSource(bundle: ResourceBundleRef["bundles"][number], resourceBundleRef: ResourceBundleRef, defaultSource: GitBundleSource): GitBundleSource {
const repoUrl = bundle.repoUrl ?? resourceBundleRef.repoUrl;
const ref = optionalNonEmpty(bundle.ref);
if (ref) return { repoUrl, ref };
const mirror = defaultSource.gitMirror;
if (ref) return { repoUrl, ref, ...(mirror ? { gitMirror: mirror } : {}) };
const commitId = optionalNonEmpty(bundle.commitId);
if (commitId) return { repoUrl, commitId };
if (commitId) return { repoUrl, commitId, ...(mirror ? { gitMirror: mirror } : {}) };
if (repoUrl === defaultSource.repoUrl) return defaultSource;
if (defaultSource.ref) return { repoUrl, ref: defaultSource.ref };
if (defaultSource.commitId) return { repoUrl, commitId: defaultSource.commitId };
return { repoUrl, ref: "HEAD" };
if (defaultSource.ref) return { repoUrl, ref: defaultSource.ref, ...(mirror ? { gitMirror: mirror } : {}) };
if (defaultSource.commitId) return { repoUrl, commitId: defaultSource.commitId, ...(mirror ? { gitMirror: mirror } : {}) };
return { repoUrl, ref: "HEAD", ...(mirror ? { gitMirror: mirror } : {}) };
}
async function checkoutGitSource(checkoutRoot: string, source: GitBundleSource): Promise<GitCheckout> {
const checkoutPath = path.join(checkoutRoot, stableHash(gitSourceIdentity(source)).slice(0, 16));
const fetch = gitFetchSource(source);
await mkdir(checkoutPath, { recursive: true });
await git(["init"], checkoutPath);
await git(["remote", "remove", "origin"], checkoutPath, { allowFailure: true });
await git(["remote", "add", "origin", source.repoUrl], checkoutPath);
await git(["remote", "add", "origin", fetch.fetchRepoUrl], checkoutPath);
if (source.ref) {
await git(["fetch", "--depth", "1", "origin", source.ref], checkoutPath);
await git(["checkout", "--detach", "FETCH_HEAD"], checkoutPath);
@@ -164,11 +193,41 @@ async function checkoutGitSource(checkoutRoot: string, source: GitBundleSource):
const actualCommit = (await git(["rev-parse", "HEAD"], checkoutPath)).stdout.trim();
if (source.commitId && actualCommit !== source.commitId) throw new AgentRunError("infra-failed", "gitbundle checkout did not land on requested commit", { httpStatus: 500, details: { expectedCommit: source.commitId, actualCommit } });
const treeId = (await git(["rev-parse", "HEAD^{tree}"], checkoutPath)).stdout.trim();
return { repoUrl: source.repoUrl, commitId: actualCommit, ...(source.commitId ? { requestedCommitId: source.commitId } : {}), ...(source.ref ? { requestedRef: source.ref } : {}), checkoutPath, treeId };
return { repoUrl: source.repoUrl, fetchRepoUrl: fetch.fetchRepoUrl, mirrorUsed: fetch.mirrorUsed, ...(fetch.mirrorBaseUrl ? { mirrorBaseUrl: fetch.mirrorBaseUrl } : {}), commitId: actualCommit, ...(source.commitId ? { requestedCommitId: source.commitId } : {}), ...(source.ref ? { requestedRef: source.ref } : {}), checkoutPath, treeId };
}
function gitSourceIdentity(source: GitBundleSource): JsonRecord {
return { repoUrl: source.repoUrl, commitId: source.commitId ?? null, ref: source.ref ?? null };
return { repoUrl: source.repoUrl, commitId: source.commitId ?? null, ref: source.ref ?? null, gitMirror: source.gitMirror ? { enabled: true, baseUrl: source.gitMirror.baseUrl } : null };
}
export function resolveGitBundleFetchSource(repoUrl: string, gitMirror?: ResourceBundleRef["gitMirror"] | GitMirrorConfig, env: NodeJS.ProcessEnv = process.env): { fetchRepoUrl: string; mirrorUsed: boolean; mirrorBaseUrl?: string } {
const mirror = normalizeGitMirrorConfig(gitMirror, env);
if (!mirror) return { fetchRepoUrl: repoUrl, mirrorUsed: false };
const githubPath = githubRepoPath(repoUrl);
if (!githubPath) return { fetchRepoUrl: repoUrl, mirrorUsed: false };
return { fetchRepoUrl: `${mirror.baseUrl}/${githubPath}.git`, mirrorUsed: true, mirrorBaseUrl: mirror.baseUrl };
}
function gitFetchSource(source: GitBundleSource): { fetchRepoUrl: string; mirrorUsed: boolean; mirrorBaseUrl?: string } {
return resolveGitBundleFetchSource(source.repoUrl, source.gitMirror);
}
function githubRepoPath(repoUrl: string): string | null {
const raw = repoUrl.trim();
const scp = /^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/u.exec(raw);
if (scp) return cleanGithubPath(scp[1] ?? "", scp[2] ?? "");
const ssh = /^ssh:\/\/git@(?:github\.com|ssh\.github\.com)(?::\d+)?\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/u.exec(raw);
if (ssh) return cleanGithubPath(ssh[1] ?? "", ssh[2] ?? "");
const http = /^https?:\/\/github\.com\/([^/]+)\/([^/#?]+?)(?:\.git)?\/?$/u.exec(raw);
if (http) return cleanGithubPath(http[1] ?? "", http[2] ?? "");
return null;
}
function cleanGithubPath(owner: string, repo: string): string | null {
const cleanOwner = owner.trim();
const cleanRepo = repo.trim().replace(/\.git$/u, "");
if (!/^[A-Za-z0-9_.-]+$/u.test(cleanOwner) || !/^[A-Za-z0-9_.-]+$/u.test(cleanRepo)) return null;
return `${cleanOwner}/${cleanRepo}`;
}
async function materializeGitBundles(workspacePath: string, resourceBundleRef: ResourceBundleRef, defaultSource: GitBundleSource, defaultCheckout: GitCheckout, checkoutFor: (source: GitBundleSource) => Promise<GitCheckout>): Promise<MaterializedGitBundle[]> {
@@ -187,7 +246,7 @@ async function materializeGitBundles(workspacePath: string, resourceBundleRef: R
await mkdir(path.dirname(target), { recursive: true });
await rm(target, { recursive: true, force: true });
await cp(source, target, { recursive: true, force: true, dereference: false });
items.push({ name: bundle.name ?? null, repoUrl: checkout.repoUrl, commitId: checkout.commitId, requestedCommitId: bundle.commitId ?? resourceBundleRef.commitId ?? null, requestedRef: checkout.requestedRef ?? null, subpath: bundle.subpath, targetPath: bundle.targetPath, sourceKind: sourceStat.isDirectory() ? "directory" : "file", sourceBytes: sourceStat.isFile() ? sourceStat.size : null });
items.push({ name: bundle.name ?? null, repoUrl: checkout.repoUrl, fetchRepoUrl: checkout.fetchRepoUrl, mirrorUsed: checkout.mirrorUsed, mirrorBaseUrl: checkout.mirrorBaseUrl ?? null, commitId: checkout.commitId, requestedCommitId: bundle.commitId ?? resourceBundleRef.commitId ?? null, requestedRef: checkout.requestedRef ?? null, subpath: bundle.subpath, targetPath: bundle.targetPath, sourceKind: sourceStat.isDirectory() ? "directory" : "file", sourceBytes: sourceStat.isFile() ? sourceStat.size : null });
}
return items;
}
@@ -380,6 +439,9 @@ function skillSourceBundle(relativePath: string, bundles: MaterializedGitBundle[
return {
name: match.name,
repoUrl: match.repoUrl,
fetchRepoUrl: match.fetchRepoUrl,
mirrorUsed: match.mirrorUsed,
mirrorBaseUrl: match.mirrorBaseUrl,
commitId: match.commitId,
requestedCommitId: match.requestedCommitId,
requestedRef: match.requestedRef,