Repository navigation
Lousho × Pi harnesses: native kits, pi provider, piAgent + coding-pi production kit - #405
Merged
Merged
Conversation
…; coding-kit harness (H1) Agent directories learn the rest of createAgent()'s run options: permissionMode, permissions (a serializable rule form - 'when' is a record of argument names to regular expressions, or a predicate in a code config), compaction, limits, plus 'hooks' and 'approve' as paths to files default-exporting the hook(s) / the approver (inline values work in code configs). instructions/<family>.md appends to instructions.md when the resolved model id contains <family>. A 'subagents' override replaces the discovered sub-agent directories, and onPermissionDecision is forwarded. The registry gains a 'kit' item type: one item is a whole agent directory, so its files may sit at any (still safe) relative path. The first kit is coding-kit, the examples/coding-harness baseline expressed as a directory: workspace tools with checkpoint rewind, an allow-listed shell, permission rules, a loop-guard + output-cap hooks file, a test-file-refusing approver, compaction, a cost cap, a fix-failing-test skill and a read-only explorer sub-agent. lousho build --target=node-server (and docker) bundles root hooks.* / approve.* files and resolves the compiled .js sibling, and leaves the install receipt (whose hashes name the .ts sources) out of the bundle. The Cloudflare worker target carries the new options through, refusing 'hooks' / 'approve' file paths (a Worker cannot import files). examples/coding-harness/kit.test.ts installs the kit with lousho add, runs the scripted harness scenario through loadAgentDir (mock provider inherited by the explorer sub-agent), and builds it into a node-server deployment whose POST /chat answers the same task; a live test runs against openrouter/openai/gpt-4o-mini when OPENROUTER_API_KEY is set.
Adds piAgent({ cwd, model, description, permissions, ... }), a Node-only
adapter that runs @earendil-works/pi-coding-agent (new optional peer,
pinned 1.0.2 alongside pi-ai 1.0.3 as dev deps) in process behind the
task tool. Each task call is one Pi session under the task's sessionId,
so taskId resumes and approval resumes reopen the same transcript even
across a restart.
Permission rules (the same PermissionRule shape as createAgent()) gate
every Pi tool_call extension event: deny refuses the call, ask throws
SubagentApprovalPause so the lead pauses durably for approval, and a
resume installs a one-shot exact-match allow for the blocked call (Pi
has no run-blocked-call API; a decision prompt asks the model to
re-issue it). Rejections go in as the next turn's note. Pi usage rolls
into the lead's result.usage and aborts propagate to the session.
Also public: defineRemoteSubagent(impl) registers any RemoteSubagent
implementation for subagents (remoteAgent() now delegates to it), and
SubagentApprovalPause is re-exported for such adapters.
Offline acceptance tests cover delegation, usage rollup, approval
pause/resume, durable resume across a SqliteStore restart, rejection,
denied rm, taskId resume, fork refusal and the non-pausable path; a
skipped live test runs the fixture end to end on OpenRouter under $0.05.
createAgent({ model: 'pi/<pi-provider>/<model>' }) routes calls through
the optional peer @earendil-works/pi-ai (the engine pi-coding-agent runs
on), so pi's whole catalog is usable natively - e.g.
pi/openrouter/openai/gpt-4o-mini for OpenRouter's openai/gpt-4o-mini.
The first slash after 'pi/' splits the nested provider from the model
id, so model ids with slashes work.
- PiProvider: a native LLMProvider lazily loading pi's /compat and
/providers/all entrypoints; a missing package fails with the standard
MissingPeerDependencyError. generate()/stream() use completeSimple/
streamSimple so reasoning, toolChoice and thinkingBudgets map.
- Message adapter: system -> systemPrompt, assistant reasoning blocks ->
thinking parts, tool calls/results linked by id, image bytes/data-URLs
-> pi image parts, http(s) images and file parts degrade to text notes
with a one-time warning.
- Schema adapter: tool parameters (raw JSON Schema, zod 3/4, Standard
Schema, ai jsonSchema() wrappers) -> JSON Schema, converted once.
- Usage: pi's usage (incl. cacheRead and its own cost) maps to
ProviderUsage (new optional costUsd); catalog pricing registers the
model so runs price it via estimateCost().
- Credentials are per nested provider: providerSpec no longer injects
env vars into pi specs (envForInfoOnly); pi resolves each provider's
own env key, and a missing named one fails with
LOUSHO_PROVIDER_MISSING_API_KEY.
- pi's maxRetries is pinned off; withRetry()/withFallback() stay the
only retry layer.
- pi is Node-only: not in WORKER_SUPPORTED_PROVIDERS; the worker entry's
build redirects @earendil-works/pi-ai* to deploy/shims/pi.worker.ts and
tsup keeps the package external on the Node entries.
- Offline suite runs against pi's own faux provider (16 tests); a live
OpenRouter fixture (skipped without OPENROUTER_API_KEY, capped at
$0.05) covers a real coding task, event parity and fallback.
# Conflicts: # examples/coding-harness/README.md
# Conflicts: # CHANGELOG.md # package-lock.json # package.json
# Conflicts: # CHANGELOG.md # api/executor.api.md # api/hooks.api.md # api/mcp.api.md # api/react.api.md # api/svelte.api.md # api/tools.api.md # api/triggers.api.md # api/vue.api.md # api/worker.api.md # package-lock.json # package.json
… handling, doctor dedupe - pin @earendil-works/pi-ai + pi-coding-agent peers/devDeps at exact versions (brief requirement) and align PI_PEER range/accepts + install hints - providerSpec: expose envForInfoOnly on ProviderInfo; init templates emit the right .env.example hint for pi (not Ollama's base-URL text); scaffold pi on ai 7 - doctor: report pi-ai once (provider+feature peer overlap) and stop claiming a default endpoint for pi's nested-provider env var - examples/README: index the coding-harness example - build: raise tsup heap to 8192 - the merged DTS graph no longer fits in 6144
A subagents/<name>/ config may now set "engine": "pi" to become a piAgent() coding sub-agent in the parent's subagents map (the task tool) instead of a delegate_to_<name> tool. Its sessions run in the parent's directory - the shared workspace - with the config's pi/<provider>/<model> id and serializable permissions gating the Pi session's own tool calls. loadAgentDir's new piAgent override injects PiAgentOptions (faux runtimes in tests, sessionDir/agentDir for durable approvals). Worker targets reject engine (Node-only). registry/coding-pi composes all three harnesses into the production candidate: coding-kit's rails (checkpoints, allow-listed shell, permission rules, loop guard, cost cap, family instructions) + pi-provider lead + dir-declared pi coder, installable as one lousho add command. Verified: full suite green, kit-pi offline e2e (mock lead -> task -> faux pi session edits the workspace), and the whole stack live on OpenRouter. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The README now reflects what ships: pi provider in the model-string space, remote sub-agents (remoteAgent/piAgent/defineRemoteSubagent), agent-dir run options and engine:'pi' sub-agent dirs, registry kits, a coding-pi usage snippet, and the Node-only limitation in the status section. llms.txt regenerated. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three coding-agent harnesses, integrated, validated live over OpenRouter, and composed into a production candidate:
7aaac1a6):agent.*config keys (permissionMode,permissions,compaction,hooks,approve,limits),instructions/<family>.md, registrykititem type,registry/coding-kit- e2e throughlousho add→loadAgentDir→lousho build→POST /chat.4ea5259a):pi/<provider>/<model>over@earendil-works/pi-ai@1.0.3(optional peer): complete/stream, message/tool/schema/usage mapping, faux + live tests, worker-bundle shim (Node-only).ee4b55df):piAgent()RemoteSubagentover@earendil-works/pi-coding-agent@1.0.2,defineRemoteSubagent()+SubagentApprovalPauseexported, durable approval pause/resume by session id.17647b88):engine: 'pi'sub-agent directories +registry/coding-pi- the kit on the full Pi stack (pi-provider lead + dir-declared pi coder sharing the workspace), plusloadAgentDir'spiAgentoverride for injecting runtimes/session dirs.Verification
registry:check,api:check,docs:llms:checkall pass.OPENROUTER_API_KEY): coding-kit ✅, pi provider 3/3 ✅, piAgent 10/10 ✅, coding-pi full stack ✅ (pi lead → real Pi coder fixes the fixture,node --testpasses, test file untouched,rmdenied + audited).7f13fe0): agent-directories, providers, sub-agents, registry, changelog pages regenerated; Arabic pages marked pending.Test plan
npx vitest run- full suite greennpm run typecheck && npm run lint && npm run build && npm run registry:check && npm run api:checkOPENROUTER_API_KEY=... npx vitest run examples/coding-harness+vitest.live.config.tssuitesdocs/plan/harness-validation-report.mdGenerated with Devin