feat(persona,agent): move triggers/schedules/watch to agent.ts (defineAgent)

Merged
KH
5mo ago
+1546-611

What

Moves triggers, cron schedules, and relayfile watch rules out of the persona and into the agent (agent.ts), per the May 29 persona-vs-agent architecture decision.

  • Persona = what an agent is: model, harness, skills, mcp, inputs, integration connections (integrations[provider] = { source?, scope? }).
  • Agent (agent.ts) = when/how it fires: triggers, schedules, watch, and the handler — authored with a new typed defineAgent({...}).
// agent.ts
import { defineAgent } from '@agentworkforce/runtime';

export default defineAgent({
  triggers: {
    github: [{ on: 'pull_request.opened' }, { on: 'issue_comment.created', match: '@mention' }],
    slack: [{ on: 'app_mention' }],
  },
  schedules: [{ name: 'nightly', cron: '0 2 * * *' }],
  handler: async (ctx, event) => { /* event.type narrows to the declared triggers */ },
});

Why

The old split coupled "I connect to github" (persona) with "ping me on pull_request.opened" (agent), and the handler had no idea which triggers activated it. One portable agent.ts now fully defines the agent's behavior, and defineAgent narrows the handler's event to exactly the declared triggers/schedules.

Changes

  • persona-kit — remove triggers from PersonaIntegrationConfig and schedules/watch from PersonaSpec; parser hard-throws on persona-level listeners with a migration message. Add AgentSpec + parseAgentSpec, TypedTriggerMap, retarget lintTriggers to AgentSpec, emit agent.schema.json.
  • runtime — new defineAgent (+ isWorkforceAgent, AgentDefinition, AgentEvent) with per-provider trigger autocomplete and best-effort handler event-narrowing; startRunner logs from the agent spec.
  • deploy — extract-agent.ts evaluates defineAgent with the runtime stubbed (fast, side-effect-free) to read listeners; preflight gates on agent listeners + requires every triggered provider to be a declared persona connection; bundle runner reads default.handler; cloud deploy POST gains a top-level agent block; the runtime-credentials request re-merges agent triggers so its scoping contract is unchanged.
  • examples — review-agent / linear-shipper / notion-essay-pr / proactive-issue-resolver / weekly-digest migrated to defineAgent.

Cloud / cross-repo

The wire contract gains a top-level agent block; cloud must read triggers/schedules/watch from agent.* instead of persona.*. Tracked in AgentWorkforce/cloud#1643 (lands lockstep with the persona-kit publish). Sibling agent repos (AgentWorkforce/agents, AgentWorkforce/watchdog-agents) and docs get follow-up PRs once these packages publish.

Test

All workspace packages green (persona-kit 243, runtime 57, deploy 164, cli 211, …). Verified end-to-end by running deploy preflight on examples/review-agent (extracts github×4 + slack×1, integrations [github, slack]). New tests cover: parser rejects persona-level listeners, parseAgentSpec, defineAgent branding + event-narrowing, preflight provider-coverage gate, and the cloud agent block in the POST body.

Note: cli tests must run with an isolated AGENT_WORKFORCE_HOME — a pre-existing test-isolation gap unrelated to this PR.

🤖 Generated with Claude Code