feat: add agent runtime skeleton
This commit is contained in:
@@ -2,6 +2,40 @@
|
||||
set -eu
|
||||
|
||||
repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
|
||||
mkdir -p "$repo_root/skills"
|
||||
commit_id="${1:-}"
|
||||
|
||||
echo "HWLAB skills directory ready: $repo_root/skills"
|
||||
mkdir -p "$repo_root/skills/hwlab-agent-runtime/references"
|
||||
mkdir -p "$repo_root/skills/hwlab-agent-runtime/assets"
|
||||
|
||||
cat > "$repo_root/skills/hwlab-agent-runtime/SKILL.md" <<EOF
|
||||
---
|
||||
name: hwlab-agent-runtime
|
||||
description: Build and validate the HWLAB agent-mgr and agent-worker runtime skeleton, including session lifecycle, workspace volume bookkeeping, trace events, evidence records, and explicit skills commitId handling.
|
||||
---
|
||||
|
||||
# HWLAB Agent Runtime
|
||||
|
||||
Use this skill when working on HWLAB agent runtime skeletons.
|
||||
|
||||
- Keep the control plane long-lived and worker execution session-scoped.
|
||||
- Model the lifecycle as create, start, trace, finish, cleanup.
|
||||
- Always carry explicit evidence record fields through the run plan.
|
||||
- Use repo-local skills artifacts only when a commitId is supplied explicitly.
|
||||
- Do not infer or fall back to external skill sources.
|
||||
EOF
|
||||
|
||||
cat > "$repo_root/skills/hwlab-agent-runtime/references/runtime.md" <<EOF
|
||||
# Runtime Notes
|
||||
|
||||
- agent-mgr owns session creation and trace emission.
|
||||
- agent-worker owns worker session execution and cleanup.
|
||||
- Each agent session gets its own workspace volume identity.
|
||||
- Evidence records must expose projectId, operationId, kind, uri, sha256, serviceId, environment, and createdAt.
|
||||
- Skills deployment artifacts require an explicit commitId.
|
||||
EOF
|
||||
|
||||
if [ -n "$commit_id" ]; then
|
||||
printf '%s\n' "$commit_id" > "$repo_root/skills/hwlab-agent-runtime/.commit-id"
|
||||
fi
|
||||
|
||||
echo "HWLAB skills directory ready: $repo_root/skills/hwlab-agent-runtime"
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
|
||||
async function parseJSONFiles(dir) {
|
||||
async function parseJSONFiles(dir, { requireSchema = true } = {}) {
|
||||
const entries = await readdir(path.join(repoRoot, dir), { withFileTypes: true });
|
||||
const parsed = [];
|
||||
for (const entry of entries) {
|
||||
@@ -23,13 +23,36 @@ async function parseJSONFiles(dir) {
|
||||
const relativePath = path.join(dir, entry.name);
|
||||
const raw = await readFile(path.join(repoRoot, relativePath), "utf8");
|
||||
const doc = JSON.parse(raw);
|
||||
assert.ok(doc.$schema, `${relativePath} missing $schema`);
|
||||
assert.ok(doc.$id, `${relativePath} missing $id`);
|
||||
if (requireSchema) {
|
||||
assert.ok(doc.$schema, `${relativePath} missing $schema`);
|
||||
assert.ok(doc.$id, `${relativePath} missing $id`);
|
||||
}
|
||||
parsed.push({ relativePath, doc });
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
async function parseJSONSchemaFiles(dir) {
|
||||
const parsed = [];
|
||||
for (const item of await parseJSONFiles(dir, { requireSchema: false })) {
|
||||
if (!item.doc.$schema || !item.doc.$id) {
|
||||
continue;
|
||||
}
|
||||
parsed.push(item);
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
async function parseDeployManifest(relativePath) {
|
||||
const raw = await readFile(path.join(repoRoot, relativePath), "utf8");
|
||||
const doc = JSON.parse(raw);
|
||||
assert.equal(doc.manifestVersion, "v1", `${relativePath} manifestVersion`);
|
||||
assert.equal(doc.environment, ENVIRONMENT_DEV, `${relativePath} environment`);
|
||||
assert.ok(doc.commitId, `${relativePath} commitId`);
|
||||
assert.ok(Array.isArray(doc.services) && doc.services.length >= 1, `${relativePath} services`);
|
||||
return doc;
|
||||
}
|
||||
|
||||
function assertUnique(name, values) {
|
||||
assert.equal(new Set(values).size, values.length, `${name} must be unique`);
|
||||
}
|
||||
@@ -91,8 +114,9 @@ function assertEnvelopeValidation() {
|
||||
);
|
||||
}
|
||||
|
||||
const schemas = await parseJSONFiles("protocol/schemas");
|
||||
const deploySchemas = await parseJSONFiles("deploy");
|
||||
const schemas = await parseJSONSchemaFiles("protocol/schemas");
|
||||
const deploySchemas = await parseJSONSchemaFiles("deploy");
|
||||
const deployManifest = await parseDeployManifest("deploy/deploy.json");
|
||||
const docsByName = new Map([...schemas, ...deploySchemas].map((item) => [path.basename(item.relativePath), item.doc]));
|
||||
|
||||
assert.ok(schemas.length >= 13, "expected protocol schemas");
|
||||
@@ -102,5 +126,8 @@ assertUnique("tables", TABLES);
|
||||
assertCommonSchema(docsByName.get("common.json"));
|
||||
assertDeploySchema(docsByName.get("deploy.schema.json"));
|
||||
assertEnvelopeValidation();
|
||||
assert.equal(deployManifest.services.some((service) => service.serviceId === "hwlab-agent-mgr"), true);
|
||||
assert.equal(deployManifest.services.some((service) => service.serviceId === "hwlab-agent-worker"), true);
|
||||
assert.equal(deployManifest.services.some((service) => service.serviceId === "hwlab-agent-skills"), true);
|
||||
|
||||
console.log(`validated ${schemas.length + deploySchemas.length} JSON files and ${SERVICE_IDS.length} service ids`);
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
echo "HWLAB worker entrypoint placeholder"
|
||||
repo_root="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
|
||||
workspace_root="${HWLAB_WORKSPACE_ROOT:-/workspace}"
|
||||
agent_session_id="${HWLAB_AGENT_SESSION_ID:-agent_local}"
|
||||
project_id="${HWLAB_PROJECT_ID:-prj_local}"
|
||||
skill_commit_id="${HWLAB_SKILL_COMMIT_ID:-}"
|
||||
|
||||
mkdir -p "$workspace_root"
|
||||
|
||||
echo "HWLAB worker starting"
|
||||
echo "repo=$repo_root"
|
||||
echo "workspace=$workspace_root"
|
||||
echo "agentSessionId=$agent_session_id"
|
||||
echo "projectId=$project_id"
|
||||
if [ -n "$skill_commit_id" ]; then
|
||||
echo "skillsCommitId=$skill_commit_id"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
|
||||
Reference in New Issue
Block a user