docs: align HWLAB assembly to HWPOD
This commit is contained in:
@@ -33,7 +33,7 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
image: "127.0.0.1:5000/agentrun/agentrun-mgr@sha256:1111111111111111111111111111111111111111111111111111111111111111",
|
||||
attemptId: "attempt_selftest",
|
||||
sourceCommit: "self-test",
|
||||
transientEnv: [{ name: "HWLAB_DEVICE_POD_SESSION_TOKEN", value: "test-token-material", sensitive: true }],
|
||||
transientEnv: [{ name: "HWLAB_API_KEY", value: "hwl_live_selftest", sensitive: true }],
|
||||
});
|
||||
assert.equal(rendered.dryRun, true);
|
||||
assert.equal(rendered.mutation, false);
|
||||
@@ -42,8 +42,8 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
assertRunnerJobUsesWritableCodexHome(rendered.manifest as JsonRecord, context.codexHome, "codex-0", "/var/run/agentrun/secrets/codex-0");
|
||||
assertRunnerJobUsesToolCredential(rendered, "GH_TOKEN", "agentrun-v01-tool-github-pr", "GH_TOKEN");
|
||||
assertRunnerJobUsesToolCredential(rendered, "UNIDESK_SSH_CLIENT_TOKEN", "agentrun-v01-tool-unidesk-ssh", "UNIDESK_SSH_CLIENT_TOKEN");
|
||||
assert.equal(runnerEnvValue(rendered.manifest as JsonRecord, "HWLAB_DEVICE_POD_SESSION_TOKEN"), "REDACTED");
|
||||
assert.deepEqual((((rendered.transientEnv as JsonRecord).names) as string[]), ["HWLAB_DEVICE_POD_SESSION_TOKEN"]);
|
||||
assert.equal(runnerEnvValue(rendered.manifest as JsonRecord, "HWLAB_API_KEY"), "REDACTED");
|
||||
assert.deepEqual((((rendered.transientEnv as JsonRecord).names) as string[]), ["HWLAB_API_KEY"]);
|
||||
assertNoSecretLeak(rendered);
|
||||
|
||||
await assert.rejects(
|
||||
@@ -117,9 +117,7 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
|
||||
commandId: jobItem.commandId,
|
||||
attemptId: "attempt_selftest_create",
|
||||
transientEnv: [
|
||||
{ name: "HWLAB_DEVICE_POD_SESSION_TOKEN", value: "test-token-material", sensitive: true },
|
||||
{ name: "HWLAB_CLOUD_API_URL", value: "http://cloud.test", sensitive: true },
|
||||
{ name: "HWLAB_DEVICE_POD_API_URL", value: "http://device-pod.test", sensitive: true },
|
||||
{ name: "HWLAB_API_KEY", value: "hwl_live_selftest", sensitive: true },
|
||||
{ name: "HWLAB_RUNTIME_API_URL", value: "http://runtime-api.test", sensitive: true },
|
||||
{ name: "HWLAB_RUNTIME_WEB_URL", value: "http://runtime-web.test", sensitive: true },
|
||||
{ name: "HWLAB_RUNTIME_NAMESPACE", value: "hwlab-v02", sensitive: true },
|
||||
@@ -132,11 +130,11 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
|
||||
});
|
||||
assert.equal((created as { mutation?: unknown }).mutation, true);
|
||||
assert.equal(((created as JsonRecord).retention as JsonRecord).ttlSecondsAfterFinished, 86_400);
|
||||
assert.deepEqual((((created as JsonRecord).transientEnv as JsonRecord).names) as string[], ["HWLAB_DEVICE_POD_SESSION_TOKEN", "HWLAB_CLOUD_API_URL", "HWLAB_DEVICE_POD_API_URL", "HWLAB_RUNTIME_API_URL", "HWLAB_RUNTIME_WEB_URL", "HWLAB_RUNTIME_NAMESPACE", "HWLAB_RUNTIME_LANE", "HWLAB_RUNTIME_ENDPOINT_SOURCE", "HWLAB_RUNTIME_ENDPOINT_LOCKED", "HWLAB_CODE_AGENT_ASSEMBLED_RUNTIME", "UNIDESK_MAIN_SERVER_IP"]);
|
||||
assert.deepEqual((((created as JsonRecord).transientEnv as JsonRecord).names) as string[], ["HWLAB_API_KEY", "HWLAB_RUNTIME_API_URL", "HWLAB_RUNTIME_WEB_URL", "HWLAB_RUNTIME_NAMESPACE", "HWLAB_RUNTIME_LANE", "HWLAB_RUNTIME_ENDPOINT_SOURCE", "HWLAB_RUNTIME_ENDPOINT_LOCKED", "HWLAB_CODE_AGENT_ASSEMBLED_RUNTIME", "UNIDESK_MAIN_SERVER_IP"]);
|
||||
const manifest = JSON.parse(await readFile(createdManifest, "utf8")) as JsonRecord;
|
||||
assert.equal((manifest.spec as JsonRecord).ttlSecondsAfterFinished, 86_400);
|
||||
assert.equal(runnerEnvValue(manifest, "HWLAB_DEVICE_POD_SESSION_TOKEN"), "test-token-material");
|
||||
assert.equal(runnerEnvValue(manifest, "HWLAB_CLOUD_API_URL"), "http://cloud.test");
|
||||
assert.equal(runnerEnvValue(manifest, "HWLAB_API_KEY"), "hwl_live_selftest");
|
||||
assert.equal(runnerEnvValue(manifest, "HWLAB_RUNTIME_API_URL"), "http://runtime-api.test");
|
||||
assert.equal(runnerEnvValue(manifest, "HWLAB_CODE_AGENT_ASSEMBLED_RUNTIME"), "1");
|
||||
assert.equal(runnerEnvValue(manifest, "UNIDESK_MAIN_SERVER_IP"), "https://unidesk.example.test");
|
||||
assertRunnerJobUsesToolCredential({ manifest, toolCredentials: (created as JsonRecord).toolCredentials } as JsonRecord, "GH_TOKEN", "agentrun-v01-tool-github-pr", "GH_TOKEN");
|
||||
|
||||
@@ -48,7 +48,10 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
|
||||
const assemblyBundle: LocalBundle = {
|
||||
...bundle,
|
||||
promptRefs: [{ name: "hwlab-v02-runtime", path: "internal/agent/prompts/hwlab-v02-runtime.md", inject: "thread-start", required: true }],
|
||||
skillRefs: [{ name: "device-pod-cli", path: "skills/device-pod-cli/SKILL.md", required: true, aggregateAs: "device-pod-cli" }],
|
||||
skillRefs: [
|
||||
{ name: "hwpod-cli", path: "skills/hwpod-cli/SKILL.md", required: true, aggregateAs: "hwpod-cli" },
|
||||
{ name: "hwpod-ctl", path: "skills/hwpod-ctl/SKILL.md", required: true, aggregateAs: "hwpod-ctl" },
|
||||
],
|
||||
};
|
||||
const first = await createHwlabRun(client, context, bundle, "hwlab-session-1", "hello bundle", "hwlab-command-1");
|
||||
const created = await client.post(`/api/v1/runs/${first.runId}/runner-jobs`, { commandId: first.commandId, idempotencyKey: "hwlab-trace-1" }) as JsonRecord;
|
||||
@@ -86,7 +89,7 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
|
||||
const hwpod = await execFile(path.join(resourceBin, "hwpod"), ["profile", "list"]);
|
||||
assert.match(hwpod.stdout, /"argv":\["profile","list"\]/u);
|
||||
await writeFile(path.join(resourceBin, "blocked"), "#!/usr/bin/env sh\necho existing\n", "utf8");
|
||||
const blockedRun = await createHwlabRun(client, context, { ...bundle, toolAliases: [{ name: "blocked", path: "tools/device-pod-cli.mjs", kind: "node-script" }] }, "hwlab-session-blocked-alias", "blocked alias", "hwlab-command-blocked-alias");
|
||||
const blockedRun = await createHwlabRun(client, context, { ...bundle, toolAliases: [{ name: "blocked", path: "tools/hwpod-cli.mjs", kind: "node-script" }] }, "hwlab-session-blocked-alias", "blocked alias", "hwlab-command-blocked-alias");
|
||||
const blockedResult = await runOnce({ managerUrl: server.baseUrl, runId: blockedRun.runId, codexCommand: context.fakeCodexCommand, codexArgs: context.fakeCodexArgs, codexHome: context.codexHome, env: { CODEX_HOME: context.codexHome, AGENTRUN_WORKSPACE_ROOT: path.join(context.tmp, "workspaces-blocked"), AGENTRUN_RESOURCE_BIN_PATH: resourceBin }, oneShot: true });
|
||||
assert.equal(blockedResult.terminalStatus, "blocked");
|
||||
assert.equal(blockedResult.failureKind, "schema-invalid");
|
||||
@@ -115,7 +118,10 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
|
||||
const firstAssemblyInput = turnInputText(assemblyInputs[0]);
|
||||
const secondAssemblyInput = turnInputText(assemblyInputs[1]);
|
||||
assert.match(firstAssemblyInput, /HWLAB v0\.2 runtime prompt self-test/u);
|
||||
assert.match(firstAssemblyInput, /device-pod-cli/u);
|
||||
assert.match(firstAssemblyInput, /hwpod-cli/u);
|
||||
assert.match(firstAssemblyInput, /hwpod-ctl/u);
|
||||
assert.match(firstAssemblyInput, /hwpod-compiler-cli/u);
|
||||
assert.match(firstAssemblyInput, /hwpod-node-ops/u);
|
||||
assert.match(firstAssemblyInput, /hwpod/u);
|
||||
assert.match(firstAssemblyInput, /list visible bundle skills/u);
|
||||
assert.match(secondAssemblyInput, /second turn should resume/u);
|
||||
@@ -128,10 +134,10 @@ console.log(JSON.stringify({ apiVersion: manifest.apiVersion, kind: manifest.kin
|
||||
const assemblyEnvelope = await client.get(`/api/v1/runs/${assemblyRun.runId}/commands/${assemblyRun.commandId}/result`) as JsonRecord;
|
||||
const assemblyResource = assemblyEnvelope.resourceBundleRef as JsonRecord;
|
||||
assert.deepEqual(((assemblyResource.promptRefs as JsonRecord).names), ["hwlab-v02-runtime"]);
|
||||
assert.deepEqual(((assemblyResource.skillRefs as JsonRecord).names), ["device-pod-cli"]);
|
||||
assert.deepEqual(((assemblyResource.skillRefs as JsonRecord).names), ["hwpod-cli", "hwpod-ctl"]);
|
||||
const assemblyMaterialized = assemblyResource.materialized as JsonRecord;
|
||||
assert.deepEqual(((assemblyMaterialized.promptRefs as JsonRecord).names), ["hwlab-v02-runtime"]);
|
||||
assert.deepEqual(((assemblyMaterialized.skillRefs as JsonRecord).names), ["device-pod-cli"]);
|
||||
assert.deepEqual(((assemblyMaterialized.skillRefs as JsonRecord).names), ["hwpod-cli", "hwpod-ctl"]);
|
||||
assert.equal(((assemblyMaterialized.initialPrompt as JsonRecord).available), true);
|
||||
assertNoSecretLeak(assemblyEnvelope);
|
||||
|
||||
@@ -215,31 +221,43 @@ async function createLocalGitBundle(context: SelfTestContext): Promise<LocalBund
|
||||
await execFile("git", ["init"], { cwd: repo });
|
||||
await writeFile(path.join(repo, "README.md"), "HWLAB bundle self-test\n", "utf8");
|
||||
await mkdir(path.join(repo, "tools"), { recursive: true });
|
||||
await writeFile(path.join(repo, "tools", "device-pod-cli.mjs"), "console.log(JSON.stringify({ ok: true, cli: 'hwpod-selftest', argv: process.argv.slice(2) }));\n", "utf8");
|
||||
await writeFile(path.join(repo, "tools", "hwpod-cli.mjs"), "console.log(JSON.stringify({ ok: true, cli: 'hwpod-cli-selftest', argv: process.argv.slice(2) }));\n", "utf8");
|
||||
await mkdir(path.join(repo, "internal", "agent", "prompts"), { recursive: true });
|
||||
await writeFile(path.join(repo, "internal", "agent", "prompts", "hwlab-v02-runtime.md"), [
|
||||
"HWLAB v0.2 runtime prompt self-test",
|
||||
"Use the hwpod alias for device-pod work.",
|
||||
"Do not invent fallback hardware paths.",
|
||||
"HWPOD means target device, workspace, debug probe, and io probe.",
|
||||
"Use hwpod-cli and hwpod-ctl through the hwpod alias for HWLAB work.",
|
||||
"Compile D601-F103-V2 through hwpod-cli -> hwpod-compiler-cli -> /v1/hwpod-node-ops -> hwpod-node.",
|
||||
"Do not invent fallback hardware paths or legacy profile routes.",
|
||||
].join("\n"), "utf8");
|
||||
await mkdir(path.join(repo, "skills", "device-pod-cli", "scripts"), { recursive: true });
|
||||
await writeFile(path.join(repo, "skills", "device-pod-cli", "SKILL.md"), [
|
||||
await mkdir(path.join(repo, "skills", "hwpod-cli", "scripts"), { recursive: true });
|
||||
await writeFile(path.join(repo, "skills", "hwpod-cli", "SKILL.md"), [
|
||||
"---",
|
||||
"name: device-pod-cli",
|
||||
"description: Use hwpod for HWLAB device-pod compile, status, job polling, and output inspection.",
|
||||
"name: hwpod-cli",
|
||||
"description: Use hwpod for HWLAB HWPOD compile, status, job polling, and output inspection.",
|
||||
"---",
|
||||
"# device-pod-cli",
|
||||
"Run `hwpod` from PATH for all device-pod operations.",
|
||||
"# hwpod-cli",
|
||||
"Run `hwpod` from PATH for HWPOD compile and execution operations.",
|
||||
].join("\n"), "utf8");
|
||||
await writeFile(path.join(repo, "skills", "device-pod-cli", "scripts", "device-pod-cli.mjs"), "console.log(JSON.stringify({ ok: true, cli: 'device-pod-skill-selftest' }));\n", "utf8");
|
||||
await execFile("git", ["add", "README.md", "tools/device-pod-cli.mjs", "internal/agent/prompts/hwlab-v02-runtime.md", "skills/device-pod-cli/SKILL.md", "skills/device-pod-cli/scripts/device-pod-cli.mjs"], { cwd: repo });
|
||||
await writeFile(path.join(repo, "skills", "hwpod-cli", "scripts", "hwpod-cli.mjs"), "console.log(JSON.stringify({ ok: true, cli: 'hwpod-cli-skill-selftest' }));\n", "utf8");
|
||||
await mkdir(path.join(repo, "skills", "hwpod-ctl", "scripts"), { recursive: true });
|
||||
await writeFile(path.join(repo, "skills", "hwpod-ctl", "SKILL.md"), [
|
||||
"---",
|
||||
"name: hwpod-ctl",
|
||||
"description: Inspect and control HWLAB HWPOD runtime state, node jobs, probes, and traces.",
|
||||
"---",
|
||||
"# hwpod-ctl",
|
||||
"Use hwpod-ctl for HWPOD runtime inspection and control-plane state.",
|
||||
].join("\n"), "utf8");
|
||||
await writeFile(path.join(repo, "skills", "hwpod-ctl", "scripts", "hwpod-ctl.mjs"), "console.log(JSON.stringify({ ok: true, cli: 'hwpod-ctl-skill-selftest' }));\n", "utf8");
|
||||
await execFile("git", ["add", "README.md", "tools/hwpod-cli.mjs", "internal/agent/prompts/hwlab-v02-runtime.md", "skills/hwpod-cli/SKILL.md", "skills/hwpod-cli/scripts/hwpod-cli.mjs", "skills/hwpod-ctl/SKILL.md", "skills/hwpod-ctl/scripts/hwpod-ctl.mjs"], { cwd: repo });
|
||||
await execFile("git", ["-c", "user.email=selftest@example.invalid", "-c", "user.name=AgentRun SelfTest", "commit", "-m", "bundle selftest"], { cwd: repo });
|
||||
const { stdout } = await execFile("git", ["rev-parse", "HEAD"], { cwd: repo });
|
||||
return { repoUrl: repo, commitId: stdout.trim() };
|
||||
}
|
||||
|
||||
async function createHwlabRun(client: ManagerClient, context: SelfTestContext, bundle: LocalBundle, sessionId: string, prompt: string, idempotencyKey: string, timeoutMs = 15_000): Promise<{ runId: string; commandId: string }> {
|
||||
const toolAliases = bundle.toolAliases ?? [{ name: "hwpod", path: "tools/device-pod-cli.mjs", kind: "node-script" }];
|
||||
const toolAliases = bundle.toolAliases ?? [{ name: "hwpod", path: "tools/hwpod-cli.mjs", kind: "node-script" }];
|
||||
const resourceBundleRef: ResourceBundleRef = { kind: "git", repoUrl: bundle.repoUrl, commitId: bundle.commitId, toolAliases, submodules: false, lfs: false };
|
||||
if (bundle.promptRefs) resourceBundleRef.promptRefs = bundle.promptRefs;
|
||||
if (bundle.skillRefs) resourceBundleRef.skillRefs = bundle.skillRefs;
|
||||
|
||||
Reference in New Issue
Block a user