Skip to content

feat(metaharness): AnyHarness metaharness skeleton + playground demo (W4) - #69

Merged
devin-ai-integration[bot] merged 2 commits into
v2from
feat/metaharness
Oct 8, 2026
Merged

devin-ai-integration[bot] merged 2 commits into
v2from
feat/metaharness

Conversation

@espetro

@espetro espetro commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

Workstream W4 from .agents/plans/2026-10-07-v2-foundation.md: the AnyHarness metaharness skeleton — the minimal reference harness consumed entirely through our own extension model, doubling as e2e playground + SDK-outreach demo.

Follows the calca @calca/agent-core contract-seam precedent (harness.ts ~59 LOC): AgentHarness / AgentSpec / Capabilities / HarnessRunInput, AI SDK ToolLoopAgent as the loop, capability injection where exec/fs/mcp slots are computer-only.

Changes

packages/metaharness/ (@any-harness/metaharness)

  • src/harness.ts — contract seam: AgentHarness, AgentSpec, Capabilities, HarnessRunInput, StoragePort, SecretPort (BYOK), ExecPort (computer-only slot)
  • src/bridge.ts — bridge protocol v0.1 client surface: BridgeOps table typing all 8 pinned ops (capabilities.negotiate, extensions.list, extensions.get, hooks.invoke, commands.resolve, skills.materialize, tools.call, events.notify), BridgeClient, inProcessBridge() in-process binding, Extension/ExtensionKind/ManifestRef interface pins
  • src/ai-sdk.ts — aiSdkHarness(), ToolLoopAgent adapter forwarding per-run Capabilities into each tool's options.context
  • src/tools.ts — extensionTools(): bridge surfaces (list_extensions, get_extension, call_extension_tool, resolve_command, materialize_skill) + computer_exec; every execute reads capabilities from options.context — absent slots degrade instead of #ifdefing
  • src/harness.test.ts — 4 vitest cases on MockLanguageModelV4: text streaming, capability injection via tool context, bridge tool wiring, computer-only degradation
  • AGENTS.md — seam rules (isomorphic, interface-first, no harness logic, capabilities not globals)

apps/playground/ (@any-harness/playground)

  • src/cli.ts — one-shot (--prompt) + REPL entry; the only file with node:* imports (argv/readline/stdout)
  • src/capabilities.ts — unstorage fs storage, BYOK SecretPort over injected env, stubbed computer-only exec
  • src/host.ts — in-process demo bridge host with canned extensions (commit-smith skill, echo-mcp MCP, review command)
  • src/model.ts — createOpenAICompatible over AI_BASE_URL/AI_API_KEY/AI_MODEL_ID
  • src/run.ts — streamTurn() normalizing stream parts for display

Test plan

  • pnpm --filter @any-harness/metaharness test — 4/4 pass
  • tsc --noEmit clean in metaharness + playground (stub packages have no tsconfig — pre-existing)
  • E2E: one-shot + REPL runs against an OpenAI-compatible endpoint — model calls list_extensions / call_extension_tool through the in-process bridge and renders results
  • Capability matrix updated (if adapter behaviour changed) — n/a
  • Linked to a refined issue in Project 14

Notes

  • Bridge client is in-process only; stdio/HTTP-loopback transports come with the W3 spec + sdk host. demoBridge() is canned data, not a store.
  • Deps: ai (catalog) in metaharness; playground adds unstorage (catalog) + @ai-sdk/openai-compatible@^3 — the one non-catalog dep, justified: ai ships no provider adapter and BYOK demo needs one. @ai-sdk/provider is devDep-only (test types for the mock model).
  • pnpm test at root still fails on the cli/sdk/spec stubs ("no test files") — pre-existing scaffold state, CI marks test continue-on-error.
  • pnpm-lock.yaml committed (repo had none; CI installs --frozen-lockfile).

Link to Devin session: https://app.devin.ai/sessions/fd3e78041312436aa9f8d235e293d94a
Open in Devin Desktop: https://app.devin.ai/desktop/session/fd3e78041312436aa9f8d235e293d94a?variant=devin
Requested by: @espetro

…idge client

AgentHarness/AgentSpec/Capabilities/HarnessRunInput contract (calca
agent-core precedent), aiSdkHarness default impl over AI SDK
ToolLoopAgent, typed BridgeOps table with inProcessBridge binding, and
extensionTools() wiring bridge surfaces + the computer-only exec slot
into the model via injected capabilities. Zero node:* imports.
Runs agent turns through aiSdkHarness with capability injection:
unstorage fs storage, BYOK SecretPort over injected env, in-process
demo bridge host with canned extensions, and a stubbed computer-only
exec slot. node:* imports confined to src/cli.ts (argv/readline/stdout);
@ai-sdk/openai-compatible is the one extra dep (BYOK provider adapter —
ai ships none).
@devin-ai-integration

Copy link
Copy Markdown

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Cursor Bugbot was not present on this PR after the first check poll, so that signal was skipped; no applicable approval policy requires human review, and there are no unresolved automated findings. Human review is not required for merge gating from this automation.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@devin-ai-integration
devin-ai-integration Bot merged commit 05c3839 into v2 Oct 8, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant