The constant core of the workshop — the code-review agent and its runtime, imported unchanged by all three patterns (naive, worker, workflow). Nothing here knows about Render; the substrate decides how the agent is invoked.
The review pipeline:
prepareDiff → filterDiff → [ security ‖ performance ‖ ux? ] → judge
runReview(prUrl, options)— the whole pipeline; returns a verdict, findings, and token usage. Emits progress via anonEventcallback (used by the worker).defineAgent(def)→ anAgentwith an in-process.run(input, ctx).- The agents:
securityReviewer,performanceReviewer,uxReviewer,judge, plusREVIEWERS,selectReviewers(), andhasFrontendFiles(). prepareDiff(pr)— GitHub PR URL → per-file patches (public repos, no auth).filterDiff(patches)— drop noise files before review.parseDecision(text)— judge output →{ verdict, reason, findings }.resolveClient/resolveModelSpec/MODEL_TIERS— provider-agnostic model client overfetch(Anthropic + OpenAI), with a deterministic mock client when no API key is set (orAGENT_MODEL=mock).- Tools:
defineTool,defineMcpSource,getToolRegistry,loadTools,registerTool,resolveTools— drop a file insrc/tools/to register.
src/
review.ts runReview + parseDecision (the orchestration)
agents.ts agent definitions + reviewer selection
agent.ts defineAgent() → in-process .run()
loop.ts the provider-agnostic LLM loop
model.ts Anthropic/OpenAI adapters + MockClient
model-tiers.ts small/medium/large → concrete models
prepareDiff.ts GitHub PR → Patch[]
filterDiff.ts noise filtering
helpers.ts shared utilities (review, patch, model tier)
tool.ts / tool-registry.ts tool helpers + auto-discovered registry
tools/ one file per tool (auto-discovered by loader.ts)
types.ts shared contracts
index.ts public surface
No API key needed — the mock model lets the full pipeline run offline.