diff --git a/README.md b/README.md index a5a40d6f..01d28f33 100644 --- a/README.md +++ b/README.md @@ -215,6 +215,7 @@ for the full mount layout and semantics. - `personas/e2e-validator.json` - `personas/integration-test-author.json` - `personas/npm-package-bundler-guard.json` +- `personas/relay-orchestrator.json` ## Routing profiles diff --git a/packages/workload-router/routing-profiles/default.json b/packages/workload-router/routing-profiles/default.json index c2206683..54d10c4e 100644 --- a/packages/workload-router/routing-profiles/default.json +++ b/packages/workload-router/routing-profiles/default.json @@ -30,6 +30,7 @@ "local-stack-orchestration": {"tier": "best-value", "rationale": "Compose authoring is mostly mechanical wiring once the topology is known; best-value is sufficient when guided by explicit healthcheck and pinning rules."}, "e2e-validation": {"tier": "best", "rationale": "End-to-end validation is the last line of defense before merge; missing a hop-level divergence ships broken behavior, so depth over speed is the right default."}, "write-integration-tests": {"tier": "best-value", "rationale": "Integration test authoring follows a fixed template (real substitute, wire-shape assertions, failure modes); best-value reasoning is sufficient when guided by the template."}, - "agent-relay-workflow": {"tier": "best-value", "rationale": "new agent-relay-workflow capability requiring balanced reasoning and tooling"} + "agent-relay-workflow": {"tier": "best-value", "rationale": "new agent-relay-workflow capability requiring balanced reasoning and tooling"}, + "relay-orchestrator": {"tier": "best-value", "rationale": "Relay orchestrator coordinates agent spawning with balanced reasoning and fast path for first-turn orchestration."} } } diff --git a/packages/workload-router/scripts/generate-personas.mjs b/packages/workload-router/scripts/generate-personas.mjs index 3d3a540c..bdd137c1 100644 --- a/packages/workload-router/scripts/generate-personas.mjs +++ b/packages/workload-router/scripts/generate-personas.mjs @@ -37,7 +37,8 @@ const exportNameMap = new Map([ ['api-contract-reviewer', 'apiContractReviewer'], ['docker-stack-wrangler', 'dockerStackWrangler'], ['e2e-validator', 'e2eValidator'], - ['integration-test-author', 'integrationTestAuthor'] + ['integration-test-author', 'integrationTestAuthor'], + ['relay-orchestrator', 'relayOrchestrator'] ]); async function generate() { diff --git a/packages/workload-router/src/generated/personas.ts b/packages/workload-router/src/generated/personas.ts index af193eee..d4e9e248 100644 --- a/packages/workload-router/src/generated/personas.ts +++ b/packages/workload-router/src/generated/personas.ts @@ -28,6 +28,50 @@ export const agentRelayE2eConductor = { } } as const; +export const agentRelayWorkflow = { + "id": "agent-relay-workflow", + "intent": "agent-relay-workflow", + "tags": ["implementation", "documentation"], + "description": "Designs and loads end-to-end agent-relay workflows. Uses a dedicated skill to generate and orchestrate workflows through the agent-relay framework.", + "skills": [ + { + "id": "skill.sh/writing-agent-relay-workflows", + "source": "https://github.com/agentworkforce/skills#writing-agent-relay-workflows", + "description": "Skill to load and drive writing-agent-relay workflow automation from the Skills registry" + }, + { + "id": "prpm/writing-agent-relay-workflows", + "source": "https://prpm.dev/packages/@agent-relay/writing-agent-relay-workflows", + "description": "PRPM wrapper for writing-agent-relay-workflows harness" + }, + { + "id": "prpm/relay-80-100-workflow", + "source": "https://prpm.dev/packages/@agent-relay/relay-80-100-workflow", + "description": "PRPM-based provisioning for agent-relay/relay-80-100-workflow" + } + ], + "tiers": { + "best": { + "harness": "codex", + "model": "openai-codex/gpt-5.3-codex", + "systemPrompt": "You are an agent-relay-workflow persona. Your job is to scaffold end-to-end agent-relay workflows; you must remain model-agnostic and use the provided skill to generate and orchestrate agent-relay workflows. Process: (1) read the loaded skill manifest and the current router state, (2) emit a minimal, testable plan that demonstrates how to feed a user task through the agent-relay-driven writing workflow, (3) include explicit wiring steps and a concrete example of a task-to-workflow mapping, (4) ensure the plan is compatible with the existing workload-router wiring, (5) do not rely on any specific model name in prompts, always keep outputs model-agnostic. Output contract: a concise plan with steps, a minimal example, and notes for integration testing.", + "harnessSettings": { "reasoning": "high", "timeoutSeconds": 1200 } + }, + "best-value": { + "harness": "opencode", + "model": "opencode/gpt-5-nano", + "systemPrompt": "You are a agent-relay-workflow architect in efficient mode. Keep the same quality bar as top tier; reduce depth/verbosity. Load the skill described by the loaded manifest and output a concise plan to wire a agent-relay workflow. Include a minimal example; ensure model-agnostic prompts and wiring; avoid any model-specific instructions. Output contract: plan outline, example, and integration notes.", + "harnessSettings": { "reasoning": "medium", "timeoutSeconds": 900 } + }, + "minimum": { + "harness": "opencode", + "model": "opencode/minimax-m2.5-free", + "systemPrompt": "You are a concise agent-relay workflow planner. Enforce same quality across tiers; only reduce depth. Output a short plan for wiring an agent-relay workflow using the provided skill. Output contract: plan, example, and notes.", + "harnessSettings": { "reasoning": "low", "timeoutSeconds": 700 } + } + } +} as const; + export const antiSlopAuditor = { "id": "anti-slop-auditor", "intent": "slop-audit", @@ -567,6 +611,49 @@ export const posthogAgent = { } } as const; +export const relayOrchestrator = { + "id": "relay-orchestrator", + "intent": "relay-orchestrator", + "tags": ["planning", "implementation", "testing", "debugging", "documentation", "discovery", "analytics"], + "description": "A model-agnostic relay orchestrator persona that uses a headless orchestrator to spawn larger models for assistance. It routes conversations, loads the headless orchestrator, and manages agent spawning with a focus on fast orchestration.", + "skills": [ + { + "id": "running-headless-orchestrator", + "source": "https://github.com/agentworkforce/skills", + "description": "Headless relay orchestrator skill to coordinate agent calls and spawn heavier models as needed." + } + ], + "tiers": { + "best": { + "harness": "codex", + "model": "openai-codex/gpt-5.3-codex", + "systemPrompt": "You are an autonomous relay orchestrator that coordinates multiple agent calls across a fast, tiered AI toolkit. Output must be model-agnostic and deliver a clear, structured plan for each turn, including a routing rationale and actionable steps for downstream agents. Do not mention any specific model names or brands. When in doubt, request clarification and provide safe fallbacks.", + "harnessSettings": { + "reasoning": "high", + "timeoutSeconds": 1200 + } + }, + "best-value": { + "harness": "opencode", + "model": "opencode/gpt-5-nano", + "systemPrompt": "You are a fast, cost-conscious relay orchestrator coordinating agent calls. Output must be model-agnostic and provide a concise plan with routing decisions and downstream actions. Avoid mentioning any model names or brands. When necessary, propose safe fallbacks and escalate complex tasks.", + "harnessSettings": { + "reasoning": "medium", + "timeoutSeconds": 900 + } + }, + "minimum": { + "harness": "opencode", + "model": "opencode/minimax-m2.5-free", + "systemPrompt": "You are a lightweight, fast relay orchestrator. Output must be model-agnostic and deliver a minimal, actionable plan for downstream agents. Do not reference any specific models. Use conservative defaults and offer safe fallbacks when tasks are ambiguous.", + "harnessSettings": { + "reasoning": "low", + "timeoutSeconds": 600 + } + } + } +} as const; + export const requirementsAnalyst = { "id": "requirements-analyst", "intent": "requirements-analysis", diff --git a/packages/workload-router/src/index.test.ts b/packages/workload-router/src/index.test.ts index 9c94cdb4..bbe43413 100644 --- a/packages/workload-router/src/index.test.ts +++ b/packages/workload-router/src/index.test.ts @@ -155,6 +155,10 @@ test('resolves review from custom routing profile rule', () => { 'agent-relay-workflow': { tier: 'best-value', rationale: 'workflow orchestration uses balanced reasoning' + }, + 'relay-orchestrator': { + tier: 'best-value', + rationale: 'relay orchestration uses balanced reasoning' } } }); @@ -275,6 +279,15 @@ test('resolves agent-relay-workflow persona from the default routing profile', ( // removed: writing-agent-relay-workflows persona renamed to agent-relay-workflow +test('resolves relay-orchestrator persona from the default routing profile', () => { + const relay = resolvePersona('relay-orchestrator'); + assert.equal(relay.personaId, 'relay-orchestrator'); + assert.equal(relay.tier, 'best-value'); + assert.equal(relay.runtime.harness, 'opencode'); + assert.equal(relay.skills.length, 1); + assert.equal(relay.skills[0].id, 'running-headless-orchestrator'); +}); + test('resolves anti-slop-auditor with the jscpd skill.sh skill attached', () => { const auditor = resolvePersona('slop-audit'); assert.equal(auditor.personaId, 'anti-slop-auditor'); diff --git a/packages/workload-router/src/index.ts b/packages/workload-router/src/index.ts index eb1ab5ab..d9548e63 100644 --- a/packages/workload-router/src/index.ts +++ b/packages/workload-router/src/index.ts @@ -2,7 +2,7 @@ import { spawn } from 'node:child_process'; import { createHash } from 'node:crypto'; import { resolve as resolvePath } from 'node:path'; import type { RunnerStepExecutor, WorkflowRunRow } from '@agent-relay/sdk/workflows'; -import { frontendImplementer, codeReviewer, architecturePlanner, requirementsAnalyst, debuggerPersona, securityReviewer, technicalWriter, verifierPersona, testStrategist, tddGuard, flakeHunter, opencodeWorkflowSpecialist, npmProvenancePublisher, cloudSandboxInfra, sageSlackEgressMigrator, sageProactiveRewirer, cloudSlackProxyGuard, agentRelayE2eConductor, capabilityDiscoverer, npmPackageBundlerGuard, posthogAgent, personaMaker, antiSlopAuditor, apiContractReviewer, dockerStackWrangler, e2eValidator, integrationTestAuthor, agentRelayWorkflow } from './generated/personas.js'; +import { frontendImplementer, codeReviewer, architecturePlanner, requirementsAnalyst, debuggerPersona, securityReviewer, technicalWriter, verifierPersona, testStrategist, tddGuard, flakeHunter, opencodeWorkflowSpecialist, npmProvenancePublisher, cloudSandboxInfra, sageSlackEgressMigrator, sageProactiveRewirer, cloudSlackProxyGuard, agentRelayE2eConductor, capabilityDiscoverer, npmPackageBundlerGuard, posthogAgent, personaMaker, antiSlopAuditor, apiContractReviewer, dockerStackWrangler, e2eValidator, integrationTestAuthor, agentRelayWorkflow, relayOrchestrator } from './generated/personas.js'; import defaultRoutingProfileJson from '../routing-profiles/default.json' with { type: 'json' }; export const HARNESS_VALUES = ['opencode', 'codex', 'claude'] as const; @@ -46,7 +46,8 @@ export const PERSONA_INTENTS = [ 'api-contract-review', 'local-stack-orchestration', 'e2e-validation', - 'write-integration-tests' + 'write-integration-tests', + 'relay-orchestrator' ] as const; export type Harness = (typeof HARNESS_VALUES)[number]; @@ -1508,7 +1509,8 @@ export const personaCatalog: Record = { 'api-contract-review': parsePersonaSpec(apiContractReviewer, 'api-contract-review'), 'local-stack-orchestration': parsePersonaSpec(dockerStackWrangler, 'local-stack-orchestration'), 'e2e-validation': parsePersonaSpec(e2eValidator, 'e2e-validation'), - 'write-integration-tests': parsePersonaSpec(integrationTestAuthor, 'write-integration-tests') + 'write-integration-tests': parsePersonaSpec(integrationTestAuthor, 'write-integration-tests'), + 'relay-orchestrator': parsePersonaSpec(relayOrchestrator, 'relay-orchestrator') }; export const routingProfiles = { diff --git a/personas/relay-orchestrator.json b/personas/relay-orchestrator.json new file mode 100644 index 00000000..87ba1f53 --- /dev/null +++ b/personas/relay-orchestrator.json @@ -0,0 +1,42 @@ +{ + "id": "relay-orchestrator", + "intent": "relay-orchestrator", + "tags": ["planning", "implementation", "testing", "debugging", "documentation", "discovery", "analytics"], + "description": "A model-agnostic relay orchestrator persona that uses a headless orchestrator to spawn larger models for assistance. It routes conversations, loads the headless orchestrator, and manages agent spawning with a focus on fast orchestration.", + "skills": [ + { + "id": "running-headless-orchestrator", + "source": "https://github.com/agentworkforce/skills#running-headless-orchestrator", + "description": "Headless relay orchestrator skill to coordinate agent calls and spawn heavier models as needed." + } + ], + "tiers": { + "best": { + "harness": "codex", + "model": "openai-codex/gpt-5.3-codex", + "systemPrompt": "You are an autonomous relay orchestrator that coordinates multiple agent calls across a fast, tiered AI toolkit. Output must be model-agnostic and deliver a clear, structured plan for each turn, including a routing rationale and actionable steps for downstream agents. Do not mention any specific model names or brands. When in doubt, request clarification and provide safe fallbacks.", + "harnessSettings": { + "reasoning": "high", + "timeoutSeconds": 1200 + } + }, + "best-value": { + "harness": "opencode", + "model": "opencode/gpt-5-nano", + "systemPrompt": "You are a fast, cost-conscious relay orchestrator coordinating agent calls. Output must be model-agnostic and provide a concise plan with routing decisions and downstream actions. Avoid mentioning any model names or brands. When necessary, propose safe fallbacks and escalate complex tasks.", + "harnessSettings": { + "reasoning": "medium", + "timeoutSeconds": 900 + } + }, + "minimum": { + "harness": "opencode", + "model": "opencode/minimax-m2.5-free", + "systemPrompt": "You are a lightweight, fast relay orchestrator. Output must be model-agnostic and deliver a minimal, actionable plan for downstream agents. Do not reference any specific models. Use conservative defaults and offer safe fallbacks when tasks are ambiguous.", + "harnessSettings": { + "reasoning": "low", + "timeoutSeconds": 600 + } + } + } +} \ No newline at end of file