diff --git a/README.md b/README.md index 9828480..741980f 100644 --- a/README.md +++ b/README.md @@ -240,7 +240,7 @@ agentworkforce --version 1. `./.agentworkforce/workforce/personas/*.json` — project-local 2. Configured persona source dirs. Default: `~/.agentworkforce/workforce/personas/*.json` - 3. Internal built-in system personas in `/personas/` (currently `persona-maker`) + 3. Internal built-in system personas in `/personas/` (currently `persona-maker`, `persona-improver`, and `nango-function-builder`) - Launch metadata is recorded by default for launched sessions; opt out with `--no-launch-metadata` or `AGENTWORKFORCE_LAUNCH_METADATA=0`. - `list` — print the catalog of personas from the cascade (cwd → @@ -337,9 +337,9 @@ First-party examples: - `@agentrelay/personas` is owned by the Relay repo and contains Relay-specific personas such as `relay-orchestrator`. -`persona-maker` remains part of the internal built-in distribution. You do not -need to install `@agentworkforce/personas-core` before running -`agentworkforce create`. +`persona-maker`, `persona-improver`, and `nango-function-builder` remain part +of the internal built-in distribution. You do not need to install +`@agentworkforce/personas-core` before running `agentworkforce create`. `install` is a copy utility. Use it when a project should own and edit its persona files. `sources add ` is separate: it points the cascade at a live @@ -462,6 +462,8 @@ for the full mount layout and semantics. ## Personas - `personas/persona-maker.json` +- `personas/persona-improver.json` +- `personas/nango-function-builder.json` The built-in catalog is intentionally limited to required internal/system personas. Optional reusable personas are distributed through persona packs: diff --git a/packages/workload-router/README.md b/packages/workload-router/README.md index 85543fc..a9914e7 100644 --- a/packages/workload-router/README.md +++ b/packages/workload-router/README.md @@ -18,11 +18,11 @@ resolved persona and grouped install metadata. Nothing is installed, spawned, or written to disk — run `install.commandString` yourself when you are ready to materialize the persona's skills. -`usePersona` resolves only the internal built-in catalog (`persona-maker` / -`persona-authoring`). Optional personas such as `code-reviewer` and -`frontend-implementer` are distributed through installable persona packs and -should be loaded through the CLI/source cascade, then passed to `useSelection` -or `materializeSkillsFor`. +`usePersona` resolves only the internal built-in catalog (`persona-maker`, +`persona-improver`, and `nango-function-builder`). Optional personas such as +`code-reviewer` and `frontend-implementer` are distributed through installable +persona packs and should be loaded through the CLI/source cascade, then passed +to `useSelection` or `materializeSkillsFor`. ```ts import { usePersona } from '@agentworkforce/workload-router'; diff --git a/packages/workload-router/routing-profiles/default.json b/packages/workload-router/routing-profiles/default.json index dca495c..144a98e 100644 --- a/packages/workload-router/routing-profiles/default.json +++ b/packages/workload-router/routing-profiles/default.json @@ -26,6 +26,7 @@ "posthog": {"tier": "best-value", "rationale": "PostHog queries are interactive analytics lookups; best-value is sufficient and keeps latency low when chatting with the MCP server."}, "persona-authoring": {"tier": "best", "rationale": "New personas must satisfy a fixed conventions checklist (five wiring files, model-agnostic prompts, tier-isolation) before they typecheck; missing any step ships a broken routing entry, so depth over speed is the right default."}, "persona-improvement": {"tier": "best-value", "rationale": "Mining a finished session for high-leverage persona edits is constrained pattern matching against a fixed schema; best-value reasoning is sufficient and keeps the post-session prompt latency low."}, + "nango-function-building": {"tier": "best-value", "rationale": "Nango function work is implementation-heavy but guided by a fixed skill, integration templates, compile, and dryrun workflow; best-value is the default unless provider behavior is ambiguous."}, "slop-audit": {"tier": "best", "rationale": "Slop auditing reads across a diff or subtree and classifies findings into a multi-category taxonomy; missed slop ships unchanged, so depth over speed is the right default."}, "api-contract-review": {"tier": "best", "rationale": "Contract review catches silent breaking changes between deployed services; missing a discriminant collision or enum widening ships incidents, so depth over speed is the right default."}, "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."}, diff --git a/packages/workload-router/routing-profiles/schema.json b/packages/workload-router/routing-profiles/schema.json index f46f3d1..b973c87 100644 --- a/packages/workload-router/routing-profiles/schema.json +++ b/packages/workload-router/routing-profiles/schema.json @@ -10,7 +10,7 @@ "intents": { "type": "object", "additionalProperties": false, - "required": ["implement-frontend", "review", "architecture-plan", "requirements-analysis", "debugging", "security-review", "documentation", "verification", "test-strategy", "tdd-enforcement", "flake-investigation", "opencode-workflow-correctness", "npm-provenance", "cloud-sandbox-infra", "sage-slack-egress-migration", "sage-proactive-rewire", "cloud-slack-proxy-guard", "sage-cloud-e2e-conduction", "capability-discovery", "npm-package-compat", "posthog", "persona-authoring", "agent-relay-workflow", "slop-audit", "api-contract-review", "local-stack-orchestration", "e2e-validation", "write-integration-tests"], + "required": ["implement-frontend", "review", "architecture-plan", "requirements-analysis", "debugging", "security-review", "documentation", "verification", "test-strategy", "tdd-enforcement", "flake-investigation", "opencode-workflow-correctness", "npm-provenance", "cloud-sandbox-infra", "sage-slack-egress-migration", "sage-proactive-rewire", "cloud-slack-proxy-guard", "sage-cloud-e2e-conduction", "capability-discovery", "npm-package-compat", "posthog", "persona-authoring", "persona-improvement", "nango-function-building", "agent-relay-workflow", "slop-audit", "api-contract-review", "local-stack-orchestration", "e2e-validation", "write-integration-tests", "relay-orchestrator"], "properties": { "implement-frontend": { "$ref": "#/definitions/rule" }, "review": { "$ref": "#/definitions/rule" }, @@ -34,12 +34,15 @@ "npm-package-compat": { "$ref": "#/definitions/rule" }, "posthog": { "$ref": "#/definitions/rule" }, "persona-authoring": { "$ref": "#/definitions/rule" }, + "persona-improvement": { "$ref": "#/definitions/rule" }, + "nango-function-building": { "$ref": "#/definitions/rule" }, "agent-relay-workflow": { "$ref": "#/definitions/rule" }, "slop-audit": { "$ref": "#/definitions/rule" }, "api-contract-review": { "$ref": "#/definitions/rule" }, "local-stack-orchestration": { "$ref": "#/definitions/rule" }, "e2e-validation": { "$ref": "#/definitions/rule" }, - "write-integration-tests": { "$ref": "#/definitions/rule" } + "write-integration-tests": { "$ref": "#/definitions/rule" }, + "relay-orchestrator": { "$ref": "#/definitions/rule" } } } }, diff --git a/packages/workload-router/scripts/generate-personas.mjs b/packages/workload-router/scripts/generate-personas.mjs index 7c1efc5..7ce5ca9 100644 --- a/packages/workload-router/scripts/generate-personas.mjs +++ b/packages/workload-router/scripts/generate-personas.mjs @@ -11,7 +11,8 @@ const outputFile = path.join(repoRoot, 'packages/workload-router/src/generated/p const exportNameMap = new Map([ ['persona-maker', 'personaMaker'], - ['persona-improver', 'personaImprover'] + ['persona-improver', 'personaImprover'], + ['nango-function-builder', 'nangoFunctionBuilder'] ]); /** diff --git a/packages/workload-router/src/generated/personas.ts b/packages/workload-router/src/generated/personas.ts index 10084b0..3a7fcfc 100644 --- a/packages/workload-router/src/generated/personas.ts +++ b/packages/workload-router/src/generated/personas.ts @@ -1,6 +1,63 @@ // AUTO-GENERATED by packages/workload-router/scripts/generate-personas.mjs // Do not edit by hand. Source of truth: /personas/*.json +export const nangoFunctionBuilder = { + "id": "nango-function-builder", + "intent": "nango-function-building", + "tags": [ + "implementation", + "testing", + "discovery" + ], + "description": "Builds and validates Nango TypeScript actions and syncs locally, using NangoHQ integration templates, provider docs, and dryrun evidence before handoff.", + "skills": [ + { + "id": "building-nango-functions-locally", + "source": "https://github.com/NangoHQ/skills#building-nango-functions-locally", + "description": "Canonical workflow for local Zero YAML TypeScript Nango actions and syncs, including checkpoint strategy, dryrun validation, generated tests, and deploy readiness." + } + ], + "tiers": { + "best": { + "harness": "codex", + "model": "openai-codex/gpt-5.3-codex", + "systemPrompt": "You are a Nango function builder. Build deployable TypeScript Nango actions or syncs in the current repo using the declared Nango skill and the NangoHQ integration-templates repository as source material. For sync work, complete the checkpoint strategy gate before editing: identify the change source, checkpoint schema, how it changes provider requests or resume state, whether the provider still walks the full dataset, and the delete strategy. Confirm the project is Zero YAML TypeScript, register files in index.ts, compile with Nango, and run dryrun validation with the supplied providerConfigKey, connection id, environment, metadata, input, and checkpoint. If live dryrun is blocked by missing provider config, connection, or credentials, preserve compile/test evidence and report the exact blocker. Keep edits scoped and do not deploy unless explicitly requested.", + "harnessSettings": { + "reasoning": "high", + "timeoutSeconds": 1200, + "sandboxMode": "workspace-write", + "approvalPolicy": "on-request", + "workspaceWriteNetworkAccess": true + } + }, + "best-value": { + "harness": "codex", + "model": "openai-codex/gpt-5.3-codex", + "systemPrompt": "You are a Nango function builder. Use the declared Nango skill plus NangoHQ integration-templates to add or update TypeScript Nango actions or syncs. For syncs, decide the checkpoint and deletion strategy before editing, then implement the function, register it in index.ts, run Nango compile, and run dryrun validation with the supplied connection details. If dryrun cannot reach the cloud provider config or connection, report the exact missing external state and keep local compile/test evidence.", + "harnessSettings": { + "reasoning": "medium", + "timeoutSeconds": 900, + "sandboxMode": "workspace-write", + "approvalPolicy": "on-request", + "workspaceWriteNetworkAccess": true + } + }, + "minimum": { + "harness": "codex", + "model": "openai-codex/gpt-5.3-codex", + "systemPrompt": "You are a Nango function builder for small, well-scoped edits. Apply the declared Nango skill, reference NangoHQ integration-templates, keep the sync checkpoint/delete strategy explicit, update registration, run Nango compile, and attempt dryrun validation with the supplied connection details. Report precise external blockers.", + "harnessSettings": { + "reasoning": "low", + "timeoutSeconds": 600, + "sandboxMode": "workspace-write", + "approvalPolicy": "on-request", + "workspaceWriteNetworkAccess": true + } + } + }, + "agentsMdContent": "# Nango Function Builder\n\nYou build or update Nango TypeScript functions with local evidence. Start by installing or materializing the `building-nango-functions-locally` skill from `https://github.com/NangoHQ/skills#building-nango-functions-locally` and follow it as the operating checklist. The declared persona skill is materialized by the workload-router dry-run/session launcher through `npx -y skills add https://github.com/NangoHQ/skills --skill building-nango-functions-locally -y`; if you must install it manually in a scratch session, the equivalent command is `npx skills add NangoHQ/skills -s building-nango-functions-locally`. Do not run either installer against the repo root.\n\nBefore writing a sync, state the sync strategy gate in your working notes: the provider change source, checkpoint schema, how the checkpoint changes requests or resume state, whether the request still walks the full dataset, and the deletion strategy. If a full refresh is necessary, cite the provider limitation that blocks changed-row checkpoints.\n\nUse `https://github.com/NangoHQ/integration-templates/` as the source of implementation patterns. Prefer copying endpoint shape, pagination style, cloud-id discovery, OAuth accessible-resource lookup, schema casing, and Nango runtime idioms from the closest template before inventing a new pattern.\n\nBefore choosing providerConfigKeys or dryrun connections, discover what already exists in Nango with the API or CLI rather than relying on memory. List provider configs/integrations, then inspect the target connection for the same environment and record the providerConfigKey, connection id, and environment you will pass to `npx nango dryrun`.\n\nConfirm the Nango project format before editing. It must be a Zero YAML TypeScript project with `.nango/`, no `nango.yaml`, function files under `/actions` or `/syncs`, and side-effect imports with `.js` extensions in `index.ts`.\n\nValidate in this order whenever practical: run Nango compile, run `npx nango dryrun