Skip to content

feat(examples): pi extension surface for the pi harness on Workers - #2229

Draft
mattzcarey wants to merge 11 commits into
mainfrom
feat/pi-extension-surface
Draft

feat(examples): pi extension surface for the pi harness on Workers#2229
mattzcarey wants to merge 11 commits into
mainfrom
feat/pi-extension-surface

Conversation

@mattzcarey

@mattzcarey mattzcarey commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Brings pi's coding-agent extension API into the Workers pi harness example, with pi holding as much of the code as possible.

  • Vendored extension runtime. ExtensionRunner, ExtensionAPI, the factory loader, slash-command and prompt-template helpers are copied byte-for-byte from earendil-works/pi @ c4b0e35a into examples/next/harnesses/pi/vendor/pi-coding-agent-src/. Stubs live at upstream's relative import paths, a single patch strips jiti/fs from the loader, and pnpm vendor:pi:check (now part of pnpm run check) guards against drift. No upstream changes needed.
  • Hooks and events adapters. Extensions bind to AgentHarness.hooks through one adapter (tool_callbefore_tool, contexttransform_context, before_agent_startbefore_run, …). Harness events feed the extension notification events. Handler failures surface as handler_error on the durable stream.
  • Cloudflare shell. pi's ExecutionEnv (FileSystem & Shell) is implemented over @cloudflare/shell's Workspace with just-bash in the isolate, so pi's own read/write/edit/bash tools run in the Durable Object with no containers.
  • Protocol and client. The Streams WebSocket protocol gains extension_ui_request / extension_ui_settled / extension_ui_response, commands, flags and handler_error frames. The React client renders dialogs, notices, flag toggles and / command autocomplete.
  • Example and docs. Two example extensions (memory guard, /note with a confirm gate behind a flag), a prompt template, README updates, and a living design doc at design/pi-extensions.md including the checklist for folding this into packages/agents.

src/harness/extensions/ and src/harness/env/ never import pi-harness.ts, so they lift into the package later as-is.

Deliberately unsupported

project_trust, user_bash, session_before_switch/fork; newSession/fork/switchSession/reload return cancelled (one durable session per DO). Extension slash commands run out of band, not as durable operations. Shell is just-bash built-ins over a whole-workspace snapshot; containers slot in behind the same ExecutionEnv port.

Test plan

  • pnpm test in examples/next/harnesses/pi: 50 tests across 6 files (harness eviction, execution env, built-in tools, extensions incl. UI round-trip over a real WebSocket, transport, ui-bridge)
  • pnpm run check at root (sherif, exports, vendor drift, oxfmt, oxlint, typecheck of all projects)
  • pnpm build of the example
  • Manual: pnpm run start, try /note remember this, a bash write + read, toggle confirm_destructive and ask for rm, reload mid-turn

Follow-ups

  • Re-vendor when pi's scopes build lands (already planned for the vendor/pi-dev tarballs).
  • packages/think's bash tool has the same sandbox-root deletion bug fixed here in workspace-execution-env.ts (#sync final directory pass); left untouched in this PR.

Devin Review

…onEnv to the pi harness

Phase 1: scripted verbatim vendor of pi coding-agent's extension runtime
(earendil-works/pi@c4b0e35a) with stubs at upstream paths, a loader patch
that drops jiti/fs, MANIFEST.json and pnpm vendor:pi:check.

Phase 2: pi ExecutionEnv over @cloudflare/shell Workspace + just-bash, so
pi's own read/write/edit/bash tools run in the Durable Object.
…tension UI protocol

Phases 3, 4 and 6: PiExtensionRuntime loads inline pi extensions through the
vendored ExtensionRunner, binds them to AgentHarness.hooks, forwards harness
events as extension events, surfaces handler_error, and adds the WebSocket
extension UI bridge, protocol frames, client hook state and dialogs.
…xtensions for the pi harness

Phases 5 and 7: resolve /commands to extension handlers, prompt templates
or skills before durable enqueue; in-memory ResourceLoader; per-lane
extension UI bridges wired to the WebSocket transport; example memory-guard
and notes extensions over a Shell Workspace; README, examples index and
design/pi-extensions.md.
- before_tool fails closed when an extension tool_call handler throws
- prompt() resolves for handled and command receipts instead of polling forever
- lane state is scoped per emit and restored, so notifications hit their own lane
- dialogs with no subscriber reject with NoExtensionUiError instead of a fake decline
- sendMessage with triggerTurn writes one message, not two
- idempotency check runs before any extension side effect
- set_flag only accepts registered flags with the registered type
- Workspace exec no longer deletes /tmp and other sandbox-root content
- partial shell output reaches onStdout before a timeout is reported
- flags reach connecting clients; settled dialogs are announced and stale answers rejected
- in-stream handler_error and lane event frames reach the client notices
- vendor:pi:check runs as part of pnpm run check
@changeset-bot

changeset-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 0f12e25

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 12 potential issues.

3 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟥 Agent sessions lack access control

Agent routes expose model, shell, command, flag, and dialog actions without authorization. Permissive CORS lets arbitrary origins drive known sessions.

(Refers to this code)

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread examples/next/harnesses/pi/src/harness/transport.ts
Comment thread examples/next/harnesses/pi/src/harness/extensions/state.ts Outdated
Comment thread examples/next/harnesses/pi/src/harness/extensions/tools.ts Outdated
Comment thread examples/next/harnesses/pi/src/harness/pi-harness.ts Outdated
Comment thread examples/next/harnesses/pi/src/harness/extensions/events-adapter.ts Outdated
Comment thread examples/next/harnesses/pi/src/harness/extensions/events-adapter.ts Outdated
Comment thread examples/next/harnesses/pi/src/harness/pi-harness.ts Outdated
Comment thread examples/next/harnesses/pi/src/harness/pi-harness.ts
@pkg-pr-new

pkg-pr-new Bot commented Sep 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@2229

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@2229

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@2229

hono-agents

npm i https://pkg.pr.new/hono-agents@2229

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@2229

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@2229

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@2229

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@2229

commit: 0f12e25

- lane scoping via AsyncLocalStorage; extension tools run on their operation's lane
- out-of-band submissions (handled input, extension commands) get a durable
  disposition keyed by operationId, so retries do not rerun side effects
- handled input drains queued extension writes before returning
- before_agent_start receives the assembled system prompt
- agent_end carries the run's messages; session_compact projects the real entry
- dialog answers are accepted only from the lane that owns the request
- client frames validated with typebox schemas
- shell sync failures become ExecutionError; total snapshot byte cap
@mattzcarey

Copy link
Copy Markdown
Contributor Author

Pushed fixes for the Devin review (commit 3884a88):

  • Concurrent lanes / recovered tools: lane scope is now an AsyncLocalStorage context; extension tools run inside their operation's lane, resolved from the durable per-operation writer map.
  • Consumed submissions on retry: out-of-band submissions claim a durable disposition row keyed by operationId before any handler runs; retries return the original receipt.
  • Handled input drains queued extension writes before returning.
  • before_agent_start gets the assembled system prompt; agent_end carries the run's messages; session_compact projects the committed compaction entry (or reports handler_error rather than fabricating).
  • Cross-lane dialog approval: answers are accepted only from the lane that owns the request.
  • Protocol payloads are validated with typebox schemas per frame type.
  • Shell sync failures surface as ExecutionError naming the failed paths; added a total snapshot byte cap (8 MiB default).

Not addressed here: the example has no auth and permissive CORS. That is the pre-existing example access model shared with the other examples/next harnesses and out of scope for this PR.

@agent-think

agent-think Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

⚪ agents import sizes

Measured 336 runtime imports as minified bundles. The primary size is gzip; raw minified size is included for diagnosis. An existing import growing by more than 10% is marked red. This report is informational.

Red Yellow Green Unchanged New Removed
0 0 0 336 0 0

Compared f18a6af6 with 0f12e252. Open workflow run.

No import sizes changed.

All 336 current runtime imports
Status Import Gzip Raw minified
agents#__DO_NOT_USE_WILL_BREAK__agentContext 258.6 KiB 1130.0 KiB
agents#__DO_NOT_USE_WILL_BREAK__withInvocationScope 258.6 KiB 1130.0 KiB
agents#Agent 258.6 KiB 1130.0 KiB
agents#AGENT_TOOL_MILESTONE_PART 258.6 KiB 1130.0 KiB
agents#AGENT_TOOL_PROGRESS_PART 258.6 KiB 1130.0 KiB
agents#buildAgentPath 259.1 KiB 1132.3 KiB
agents#buildAgentUrl 259.3 KiB 1132.7 KiB
agents#callable 258.6 KiB 1130.1 KiB
agents#camelCaseToKebabCase 258.6 KiB 1130.0 KiB
agents#createHeaderBasedEmailResolver 258.8 KiB 1130.4 KiB
agents#DEFAULT_AGENT_STATIC_OPTIONS 258.6 KiB 1130.0 KiB
agents#DurableObjectOAuthClientProvider 258.6 KiB 1130.0 KiB
agents#getAgentByName 258.6 KiB 1130.0 KiB
agents#getCurrentAgent 258.6 KiB 1130.0 KiB
agents#getSubAgentByName 258.9 KiB 1130.7 KiB
agents#isDurableObjectCodeUpdateReset 258.6 KiB 1130.0 KiB
agents#isDurableObjectMemoryLimitReset 258.6 KiB 1130.0 KiB
agents#isDurableObjectStorageReset 258.6 KiB 1130.1 KiB
agents#isPlatformTransientError 258.6 KiB 1130.0 KiB
agents#MCP_SERVER_ID_MAX_LENGTH 258.6 KiB 1130.0 KiB
agents#MessageType 258.8 KiB 1130.3 KiB
agents#normalizeServerId 258.6 KiB 1130.0 KiB
agents#parseSubAgentPath 258.6 KiB 1130.0 KiB
agents#routeAgentEmail 258.9 KiB 1130.7 KiB
agents#routeAgentRequest 259.2 KiB 1131.9 KiB
agents#routeSubAgentRequest 258.8 KiB 1130.6 KiB
agents#SqlError 258.6 KiB 1130.0 KiB
agents#StreamingResponse 258.6 KiB 1130.0 KiB
agents#SUB_PREFIX 258.6 KiB 1130.0 KiB
agents#unstable_callable 258.7 KiB 1130.2 KiB
agents/agent-tools#agentTool 112.5 KiB 538.2 KiB
agents/browser#BrowserConnector 50.5 KiB 176.6 KiB
agents/browser#browserContent 36.3 KiB 127.4 KiB
agents/browser#browserExtract 36.3 KiB 127.4 KiB
agents/browser#browserLinks 36.3 KiB 127.4 KiB
agents/browser#browserMarkdown 36.3 KiB 127.4 KiB
agents/browser#browserPdf 36.3 KiB 127.3 KiB
agents/browser#BrowserRenderingError 36.0 KiB 126.7 KiB
agents/browser#browserScrape 36.3 KiB 127.4 KiB
agents/browser#browserScreenshot 36.3 KiB 127.3 KiB
agents/browser#browserSnapshot 36.3 KiB 127.4 KiB
agents/browser#CdpSession 37.2 KiB 129.8 KiB
agents/browser#CodemodeRuntime 39.6 KiB 139.0 KiB
agents/browser#connectBrowser 37.8 KiB 131.4 KiB
agents/browser#connectBrowserSession 37.5 KiB 130.4 KiB
agents/browser#connectUrl 37.6 KiB 130.5 KiB
agents/browser#createBrowserSession 36.3 KiB 127.5 KiB
agents/browser#DEFAULT_EXEC_SWEEP_IDLE_MS 36.0 KiB 126.6 KiB
agents/browser#DEFAULT_SWEEP_IDLE_MS 36.0 KiB 126.6 KiB
agents/browser#deleteBrowserSession 36.1 KiB 126.9 KiB
agents/browser#DurableBrowserSessionStore 36.4 KiB 127.6 KiB
agents/browser#getBrowserRecording 36.2 KiB 127.1 KiB
agents/browser#listBrowserTargets 36.1 KiB 126.9 KiB
agents/browser#loadCdpSpec 36.6 KiB 128.3 KiB
agents/browser#runQuickAction 36.0 KiB 126.6 KiB
agents/browser/ai#createBrowserRuntime 147.0 KiB 632.8 KiB
agents/browser/ai#createBrowserTools 147.0 KiB 632.9 KiB
agents/browser/ai#createQuickActionTools 122.5 KiB 554.3 KiB
agents/browser/tanstack-ai#createBrowserTools 162.7 KiB 701.7 KiB
agents/channels#ChannelHost 3.3 KiB 9.1 KiB
agents/channels#consumeChunks 237 B 321 B
agents/channels#createUserIdentityStore 1.3 KiB 3.2 KiB
agents/channels#fallback 155 B 160 B
agents/channels#fallbackChannel 893 B 1.9 KiB
agents/channels#fanout 151 B 156 B
agents/channels#fanoutChannel 875 B 1.9 KiB
agents/channels#identityKey 178 B 223 B
agents/channels#isChannelMessageSurface 271 B 452 B
agents/channels#linkChannelIdentities 113 B 99 B
agents/channels#matchesPath 110 B 96 B
agents/channels#routes 307 B 507 B
agents/channels#UserIdentityConflictError 248 B 335 B
agents/channels/ai-sdk#createSendMessageTool 112.2 KiB 537.4 KiB
agents/channels/ai-sdk#toChannelChunks 112.5 KiB 538.4 KiB
agents/channels/email#email 23.5 KiB 75.4 KiB
agents/channels/email#inboundEmail 22.3 KiB 72.3 KiB
agents/channels/slack#slack 5.5 KiB 14.6 KiB
agents/channels/slack#slackWebhook 2.2 KiB 5.1 KiB
agents/channels/tanstack-ai#createSendMessageTool 16.2 KiB 68.4 KiB
agents/channels/telegram#telegram 3.8 KiB 10.3 KiB
agents/channels/telegram#telegramWebhook 1.6 KiB 3.6 KiB
agents/channels/voice#browserVoice 1010 B 2.2 KiB
agents/chat#AbortRegistry 2.5 KiB 8.9 KiB
agents/chat#AGENT_TOOL_STREAM_PROGRESS_BUMP_THROTTLE_MS 2.3 KiB 8.2 KiB
agents/chat#AgentToolProgressEmitter 2.7 KiB 9.5 KiB
agents/chat#AgentToolStreamProgressThrottle 2.4 KiB 8.3 KiB
agents/chat#aiSdkRecoveryCodec 2.3 KiB 8.2 KiB
agents/chat#applyAgentToolEvent 3.2 KiB 11.0 KiB
agents/chat#applyChunkToParts 2.3 KiB 8.2 KiB
agents/chat#applyToolUpdate 2.4 KiB 8.4 KiB
agents/chat#AutoContinuationController 2.3 KiB 8.2 KiB
agents/chat#awaitWithDeadline 2.4 KiB 8.4 KiB
agents/chat#broadcastTransition 3.2 KiB 11.4 KiB
agents/chat#buildChatRecoveringFrame 2.4 KiB 8.4 KiB
agents/chat#buildInClauseStrings 2.4 KiB 8.4 KiB
agents/chat#bumpChatRecoveryProgress 2.4 KiB 8.3 KiB
agents/chat#byteLength 2.5 KiB 8.5 KiB
agents/chat#CHAT_LAST_TERMINAL_KEY 2.3 KiB 8.2 KiB
agents/chat#CHAT_MESSAGE_TYPES 2.3 KiB 8.2 KiB
agents/chat#CHAT_RECOVERING_FLAG_TTL_MS 2.3 KiB 8.2 KiB
agents/chat#CHAT_RECOVERING_KEY 2.3 KiB 8.2 KiB
agents/chat#CHAT_RECOVERY_ALARM_DEBOUNCE_MS 2.3 KiB 8.2 KiB
agents/chat#CHAT_RECOVERY_INCIDENT_KEY_PREFIX 2.3 KiB 8.2 KiB
agents/chat#CHAT_RECOVERY_INCIDENT_TTL_MS 2.3 KiB 8.2 KiB
agents/chat#CHAT_RECOVERY_PROGRESS_KEY 2.3 KiB 8.2 KiB
agents/chat#CHAT_RECOVERY_STABLE_RETRY_DELAY_SECONDS 2.3 KiB 8.2 KiB
agents/chat#CHAT_RECOVERY_TASK_NAME 2.3 KiB 8.2 KiB
agents/chat#CHAT_STREAM_PROGRESS_CREDIT_THROTTLE_MS 2.3 KiB 8.2 KiB
agents/chat#ChatRecoveryEngine 4.4 KiB 15.3 KiB
agents/chat#chatRecoveryTaskRunOptions 2.4 KiB 8.6 KiB
agents/chat#ChatStreamStalledError 2.4 KiB 8.3 KiB
agents/chat#classifyAgentToolChildRecovery 2.4 KiB 8.5 KiB
agents/chat#clearChatTerminal 2.3 KiB 8.3 KiB
agents/chat#clientResolvableToolNames 2.3 KiB 8.3 KiB
agents/chat#ContinuationState 2.7 KiB 9.8 KiB
agents/chat#createAgentToolEventState 2.3 KiB 8.3 KiB
agents/chat#createChatFiberSnapshot 2.5 KiB 8.6 KiB
agents/chat#createChatRecoveryTaskDefinition 2.6 KiB 9.0 KiB
agents/chat#createChatStreams 6.4 KiB 22.0 KiB
agents/chat#createChatTurnTaskDefinition 2.7 KiB 8.9 KiB
agents/chat#createToolsFromClientSchemas 114.3 KiB 545.4 KiB
agents/chat#crossMessageToolResultUpdate 2.4 KiB 8.6 KiB
agents/chat#DEFAULT_CHAT_RECOVERY_MAX_ATTEMPTS 2.3 KiB 8.2 KiB
agents/chat#DEFAULT_CHAT_RECOVERY_MAX_OOM_RETRIES 2.3 KiB 8.2 KiB
agents/chat#DEFAULT_CHAT_RECOVERY_MAX_WORK 2.3 KiB 8.2 KiB
agents/chat#DEFAULT_CHAT_RECOVERY_NO_PROGRESS_TIMEOUT_MS 2.3 KiB 8.2 KiB
agents/chat#DEFAULT_CHAT_RECOVERY_STABLE_TIMEOUT_MS 2.3 KiB 8.2 KiB
agents/chat#DEFAULT_CHAT_RECOVERY_TERMINAL_MESSAGE 2.4 KiB 8.3 KiB
agents/chat#dispatchChatRecoveryToHandoff 3.0 KiB 9.9 KiB
agents/chat#drainInteractionApplies 2.3 KiB 8.3 KiB
agents/chat#enforceRowSizeLimit 3.5 KiB 11.2 KiB
agents/chat#hasIncompleteToolBatch 2.4 KiB 8.6 KiB
agents/chat#interceptAgentToolBroadcast 2.5 KiB 8.7 KiB
agents/chat#isPlatformFailure 2.6 KiB 8.9 KiB
agents/chat#isReplayChunk 2.4 KiB 8.7 KiB
agents/chat#iterateWithStallWatchdog 2.6 KiB 8.8 KiB
agents/chat#KV_DELETE_MAX_KEYS 2.3 KiB 8.2 KiB
agents/chat#listActiveChatRecoveryIncidents 2.4 KiB 8.4 KiB
agents/chat#MAX_BOUND_PARAMS 2.3 KiB 8.2 KiB
agents/chat#MessageType 2.4 KiB 9.0 KiB
agents/chat#normalizeToolInput 2.3 KiB 8.2 KiB
agents/chat#parseProtocolMessage 2.5 KiB 9.0 KiB
agents/chat#partAwaitsClientInteraction 2.4 KiB 8.6 KiB
agents/chat#pausedExecutionUpdate 2.4 KiB 8.4 KiB
agents/chat#pendingChatTerminal 2.3 KiB 8.3 KiB
agents/chat#persistReconstructedOrphan 3.1 KiB 11.0 KiB
agents/chat#PreStreamTurns 2.6 KiB 9.3 KiB
agents/chat#readChatRecoveryProgress 2.3 KiB 8.3 KiB
agents/chat#reconcileMessages 2.8 KiB 9.6 KiB
agents/chat#reconcileOrphanPartial 2.4 KiB 8.5 KiB
agents/chat#recordChatTerminal 2.4 KiB 8.3 KiB
agents/chat#repairInterruptedToolParts 2.6 KiB 9.1 KiB
agents/chat#resolveChatRecoveryConfig 2.6 KiB 8.9 KiB
agents/chat#resolveToolMergeId 2.4 KiB 8.5 KiB
agents/chat#ResumableStream 5.1 KiB 16.8 KiB
agents/chat#ResumeHandshake 3.0 KiB 10.4 KiB
agents/chat#ROW_MAX_BYTES 2.3 KiB 8.2 KiB
agents/chat#runChatRecoveryExhaustion 2.6 KiB 8.9 KiB
agents/chat#sanitizeMessage 2.5 KiB 8.8 KiB
agents/chat#sendIfOpen 2.4 KiB 8.4 KiB
agents/chat#setChatRecovering 2.5 KiB 8.5 KiB
agents/chat#shouldCreditStreamProgress 2.4 KiB 8.3 KiB
agents/chat#STREAM_RESUME_NONE_REASONS 2.3 KiB 8.2 KiB
agents/chat#StreamAccumulator 2.9 KiB 10.7 KiB
agents/chat#StreamProgressCreditThrottle 2.4 KiB 8.3 KiB
agents/chat#SubmitConcurrencyController 2.9 KiB 10.3 KiB
agents/chat#sweepStaleChatRecoveryIncidents 2.4 KiB 8.5 KiB
agents/chat#TextSegmentJoiner 2.7 KiB 9.2 KiB
agents/chat#TIMED_OUT 2.3 KiB 8.2 KiB
agents/chat#toolApprovalUpdate 2.4 KiB 8.5 KiB
agents/chat#toolPartHasSettledResult 2.3 KiB 8.4 KiB
agents/chat#toolResultUpdate 2.4 KiB 8.5 KiB
agents/chat#truncateOlderMessages 3.2 KiB 10.4 KiB
agents/chat#TurnQueue 2.6 KiB 9.2 KiB
agents/chat#unwrapChatFiberSnapshot 2.4 KiB 8.5 KiB
agents/chat#wrapChatFiberSnapshot 2.3 KiB 8.2 KiB
agents/chat-sdk#ChatSdkStateAdapter 261.0 KiB 1141.6 KiB
agents/chat-sdk#ChatSdkStateAgent 260.4 KiB 1139.1 KiB
agents/chat-sdk#createChatSdkState 261.0 KiB 1141.6 KiB
agents/chat-sdk#defaultKeyShard 258.8 KiB 1130.2 KiB
agents/chat-sdk#defaultThreadShard 258.7 KiB 1130.1 KiB
agents/chat/react#detectToolsRequiringConfirmation 3.3 KiB 8.3 KiB
agents/chat/react#extractClientToolSchemas 3.2 KiB 8.3 KiB
agents/chat/react#getAgentMessages 3.4 KiB 8.6 KiB
agents/chat/react#getToolApproval 3.1 KiB 8.0 KiB
agents/chat/react#getToolCallId 3.1 KiB 8.0 KiB
agents/chat/react#getToolInput 3.1 KiB 8.0 KiB
agents/chat/react#getToolOutput 3.1 KiB 8.0 KiB
agents/chat/react#getToolPartState 3.2 KiB 8.2 KiB
agents/chat/react#useAgentChat 132.9 KiB 609.7 KiB
agents/chat/react#WebSocketChatTransport 5.7 KiB 17.1 KiB
agents/chat/transport#WebSocketChatTransport 2.8 KiB 9.2 KiB
agents/client#AgentClient 5.7 KiB 16.6 KiB
agents/client#AgentConnectionError 582 B 993 B
agents/client#agentFetch 4.2 KiB 12.3 KiB
agents/client#createStubProxy 638 B 1.0 KiB
agents/client#DEFAULT_CALL_TIMEOUT_MS 473 B 770 B
agents/client#isTerminalCloseEvent 509 B 822 B
agents/context#AgentContextProvider 412 B 792 B
agents/context#AgentSearchProvider 640 B 1.3 KiB
agents/context#ContextBlocks 87.4 KiB 429.7 KiB
agents/email#createAddressBasedEmailResolver 193 B 227 B
agents/email#createCatchAllEmailResolver 110 B 97 B
agents/email#createHeaderBasedEmailResolver 334 B 492 B
agents/email#createSecureReplyEmailResolver 718 B 1.3 KiB
agents/email#DEFAULT_MAX_AGE_SECONDS 56 B 39 B
agents/email#isAutoReplyEmail 201 B 249 B
agents/email#signAgentHeaders 424 B 812 B
agents/experimental/webmcp#registerWebMcp 85.2 KiB 295.8 KiB
agents/lifecycle#getCurrentAgent 376 B 798 B
agents/lifecycle#Lifecycle 8.3 KiB 25.8 KiB
agents/lifecycle#LifecycleCapability 484 B 975 B
agents/mcp#createLegacyMcpHandler 375.9 KiB 1572.2 KiB
agents/mcp#createMcpHandler 388.2 KiB 1617.4 KiB
agents/mcp#DurableObjectEventStore 342.5 KiB 1430.7 KiB
agents/mcp#ElicitRequestSchema 342.5 KiB 1430.7 KiB
agents/mcp#experimental_createMcpHandler 376.1 KiB 1572.5 KiB
agents/mcp#getMcpAuthContext 342.5 KiB 1430.8 KiB
agents/mcp#MCP_SERVER_ID_MAX_LENGTH 342.5 KiB 1430.7 KiB
agents/mcp#McpAgent 342.5 KiB 1430.7 KiB
agents/mcp#normalizeServerId 342.5 KiB 1430.7 KiB
agents/mcp#RPC_DO_PREFIX 342.5 KiB 1430.7 KiB
agents/mcp#RPCClientTransport 342.5 KiB 1430.7 KiB
agents/mcp#RPCServerTransport 342.5 KiB 1430.7 KiB
agents/mcp#SSEEdgeClientTransport 342.6 KiB 1431.0 KiB
agents/mcp#StreamableHTTPEdgeClientTransport 342.6 KiB 1431.0 KiB
agents/mcp#WorkerTransport 345.8 KiB 1447.6 KiB
agents/mcp/client#getNamespacedData 62.9 KiB 240.0 KiB
agents/mcp/client#MCP_SERVER_ID_MAX_LENGTH 62.9 KiB 239.9 KiB
agents/mcp/client#MCPClientManager 158.6 KiB 702.6 KiB
agents/mcp/client#normalizeServerId 63.0 KiB 240.2 KiB
agents/mcp/do-oauth-client-provider#DurableObjectOAuthClientProvider 2.1 KiB 6.6 KiB
agents/mcp/server#createMcpHandler 80.5 KiB 307.2 KiB
agents/mcp/server#getMcpAuthContext 64.0 KiB 245.5 KiB
agents/observability#channels 259 B 549 B
agents/observability#genericObservability 470 B 1.2 KiB
agents/observability#subscribe 324 B 668 B
agents/observability/ai#wrapAISDK 8.8 KiB 30.5 KiB
agents/react#_testUtils 3.8 KiB 9.5 KiB
agents/react#useAgent 10.8 KiB 31.1 KiB
agents/react#useAgentToolEvents 5.6 KiB 16.8 KiB
agents/routing#getAgentByName 795 B 1.7 KiB
agents/routing#routeAgentRequest 1.6 KiB 3.6 KiB
agents/routing#RoutedAgents 2.4 KiB 6.2 KiB
agents/schedule#getSchedulePrompt 85.8 KiB 424.7 KiB
agents/schedule#scheduleSchema 85.3 KiB 423.6 KiB
agents/schedule#unstable_getSchedulePrompt 85.9 KiB 424.9 KiB
agents/schedule#unstable_scheduleSchema 85.3 KiB 423.6 KiB
agents/schedules#Scheduler 6.8 KiB 22.0 KiB
agents/schedules/parser#getSchedulePrompt 85.8 KiB 424.7 KiB
agents/schedules/parser#scheduleSchema 85.3 KiB 423.6 KiB
agents/sessions#COMPACTION_PREFIX 147 B 160 B
agents/sessions#createCompactFunction 1.7 KiB 4.0 KiB
agents/sessions#isCompactionMessage 177 B 200 B
agents/sessions#Session 2.0 KiB 6.3 KiB
agents/sessions#Sessions 9.5 KiB 34.3 KiB
agents/skills#fromManifest 309.8 KiB 1084.0 KiB
agents/skills#parseSkillFrontmatter 328.4 KiB 1146.2 KiB
agents/skills#parseSkillMarkdown 328.6 KiB 1146.5 KiB
agents/skills#r2 330.2 KiB 1150.4 KiB
agents/skills#runner 369.0 KiB 1297.8 KiB
agents/skills#SkillRegistry 416.4 KiB 1581.7 KiB
agents/skills/compile#compileSkillScript 15.4 KiB 43.4 KiB
agents/skills/compile#isCompilableSkillScript 15.4 KiB 43.3 KiB
agents/streams#DEFAULT_MAX_CHUNK_BYTES 94 B 96 B
agents/streams#sseResponse 857 B 1.6 KiB
agents/streams#StreamClosedError 175 B 212 B
agents/streams#StreamNotFoundError 215 B 276 B
agents/streams#Streams 4.2 KiB 13.8 KiB
agents/streams#StreamSerializationError 171 B 201 B
agents/tasks#DuplicateTaskStepError 328 B 463 B
agents/tasks#MAX_SERIALIZED_BYTES 190 B 232 B
agents/tasks#MissingTaskDefinitionError 358 B 536 B
agents/tasks#NonRetryableError 238 B 308 B
agents/tasks#TaskReplayDivergedError 341 B 483 B
agents/tasks#Tasks 8.9 KiB 31.8 KiB
agents/tasks#TaskSerializationError 258 B 339 B
agents/types#MessageType 211 B 365 B
agents/vite#default 353.8 KiB 1356.1 KiB
agents/voice#addSFUTracks 324 B 424 B
agents/voice#createSFUSession 255 B 306 B
agents/voice#createSFUWebSocketAdapter 331 B 429 B
agents/voice#decodeVarint 157 B 160 B
agents/voice#downsample48kStereoTo16kMono 238 B 324 B
agents/voice#encodePayloadToProtobuf 189 B 279 B
agents/voice#encodeVarint 129 B 122 B
agents/voice#extractPayloadFromProtobuf 271 B 425 B
agents/voice#iterateText 1.6 KiB 3.8 KiB
agents/voice#renegotiateSFUSession 329 B 428 B
agents/voice#SentenceChunker 550 B 1.1 KiB
agents/voice#sfuFetch 294 B 358 B
agents/voice#upsample16kMonoTo48kStereo 211 B 272 B
agents/voice#VOICE_PROTOCOL_VERSION 51 B 31 B
agents/voice#withVoice 9.5 KiB 32.7 KiB
agents/voice#withVoiceInput 4.8 KiB 16.0 KiB
agents/voice#WorkersAIFluxSTT 1.5 KiB 4.3 KiB
agents/voice#WorkersAINova3STT 1.6 KiB 4.3 KiB
agents/voice#WorkersAITTS 682 B 1.4 KiB
agents/voice/client#VOICE_PROTOCOL_VERSION 473 B 768 B
agents/voice/client#VoiceClient 10.1 KiB 31.6 KiB
agents/voice/client#WebSocketVoiceTransport 4.6 KiB 13.3 KiB
agents/voice/errors#logVoiceError 132 B 173 B
agents/voice/errors#toVoiceError 94 B 80 B
agents/voice/errors#voiceErrorMessage 125 B 111 B
agents/voice/errors#VoiceProviderError 190 B 345 B
agents/voice/react#useVoiceAgent 13.6 KiB 42.5 KiB
agents/voice/react#useVoiceInput 13.3 KiB 41.4 KiB
agents/voice/react#WebSocketVoiceTransport 7.4 KiB 21.3 KiB
agents/voice/sfu#addSFUTracks 323 B 424 B
agents/voice/sfu#createSFUSession 254 B 306 B
agents/voice/sfu#createSFUWebSocketAdapter 329 B 429 B
agents/voice/sfu#decodeVarint 155 B 160 B
agents/voice/sfu#downsample48kStereoTo16kMono 236 B 324 B
agents/voice/sfu#encodePayloadToProtobuf 188 B 279 B
agents/voice/sfu#encodeVarint 129 B 122 B
agents/voice/sfu#extractPayloadFromProtobuf 270 B 425 B
agents/voice/sfu#renegotiateSFUSession 329 B 428 B
agents/voice/sfu#sfuFetch 292 B 358 B
agents/voice/sfu#upsample16kMonoTo48kStereo 209 B 272 B
agents/voice/text#iterateText 1.6 KiB 3.8 KiB
agents/voice/text#SentenceChunker 549 B 1.1 KiB
agents/voice/types#VOICE_PROTOCOL_VERSION 51 B 31 B
agents/voice/workers-ai#WorkersAIFluxSTT 1.5 KiB 4.3 KiB
agents/voice/workers-ai#WorkersAINova3STT 1.6 KiB 4.3 KiB
agents/voice/workers-ai#WorkersAITTS 682 B 1.4 KiB
agents/websockets#CALLABLES_RPC_QUERY 12.4 KiB 43.3 KiB
agents/websockets#CALLABLES_RPC_VALUE 12.4 KiB 43.3 KiB
agents/websockets#callablesFromDecorated 12.7 KiB 44.3 KiB
agents/websockets#callablesRpcUrl 12.5 KiB 43.5 KiB
agents/websockets#isCallablesRpcUpgrade 12.4 KiB 43.4 KiB
agents/websockets#WebSockets 17.7 KiB 62.2 KiB
agents/workflows#AgentWorkflow 260.0 KiB 1134.8 KiB
agents/workflows#WorkflowRejectedError 258.7 KiB 1130.2 KiB
agents/x402#normalizeNetwork 14.7 KiB 61.1 KiB
agents/x402#withX402 23.0 KiB 89.2 KiB
agents/x402#withX402Client 104.1 KiB 346.5 KiB

Reported by agent-think[bot].

devin-ai-integration[bot]

This comment was marked as resolved.

- extension tools drain their lane's queued writes before returning a result
- snapshot count and per-file limits refuse to run instead of truncating
- native provider registrations can be unregistered (PiModelRegistry.deleteProvider)
- dialog answers are validated against the requesting method
@mattzcarey

Copy link
Copy Markdown
Contributor Author

Second round pushed (7af288b): extension tools now drain queued writes before returning; snapshot count/per-file limits refuse rather than truncate; native providers can be unregistered; dialog answers are validated against the request's method.

devin-ai-integration[bot]

This comment was marked as resolved.

- tool-registry reconciliation preserves an extension's active tool selection
- ctx.signal carries the hook/tool invocation's abort signal through the lane scope
- provider ids displaced by an extension are restored on unregister
- workspace symlinks are snapshotted into the shell and synced back as links
- frame, prompt, image and text size limits on the wire
- disposition table keeps a bounded newest window
@mattzcarey

Copy link
Copy Markdown
Contributor Author

Third round pushed (645e5da): active-tool selection survives registry refresh; ctx.signal reflects the real invocation abort; displaced host providers are restored on unregister; symlinks are represented in the shell snapshot and synced back; wire size limits (frame/prompt/images/text); bounded disposition retention (newest 1024).

devin-ai-integration[bot]

This comment was marked as resolved.

- workspace sync handles entry type transitions (symlink/file/directory)
- agent_end collects the run's entry ids synchronously at dispatch
- per-lane tool-registry baseline is durable so deploy-time tools activate
- custom resourceLoader skills/prompts feed harness resources and commands
- dynamic registerCommand triggers a commands broadcast
- compaction firstKeptEntryId derived from the retained tail
@mattzcarey

Copy link
Copy Markdown
Contributor Author

Fourth round pushed (225efec): sync handles symlink/file/directory type transitions; agent_end uses entry ids captured synchronously at dispatch; durable per-lane tool baseline so deploy-time tools activate; custom resourceLoader prompts/skills feed resources and commands; dynamic registerCommand broadcasts commands; firstKeptEntryId is derived from the retained tail.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 5 new potential issues.

10 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Comment thread examples/next/harnesses/pi/src/harness/env/workspace-execution-env.ts Outdated
Comment on lines +77 to +80
// The configuration form resolves no models, so leaving the pi-ai
// provider in place would keep serving the registration it replaced.
removeNative(providerOrName);
overlay.set(providerOrName, config);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Configured providers leave hosts active

Registering configuration over a host provider ID makes registerProvider leave the host active. Model lookup still serves the replaced host provider.

Learn more

A configuration-form registration occupies a provider name but intentionally cannot create a pi-ai provider itself. The adapter therefore needs to hide any provider already installed under that name and restore it when the extension unregisters or switches registrations. removeNative only removes providers previously registered through this extension surface, so a host provider is never displaced by the configuration form.

Example: The host configures provider shared, then an extension calls registerProvider("shared", config). registrations() reports the extension registration, but models.getModel("shared", ...) still returns the host's models.

Recommended fix: Track and remove a host provider when the configuration form first takes its ID. Preserve that displaced provider until the overlay is unregistered or replaced, then restore it consistently for both registration forms.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread examples/next/harnesses/pi/src/harness/pi-harness.ts
Comment thread examples/next/harnesses/pi/src/extensions/notes.ts
- sync removes workspace directories deleted under a sandbox root
- config-form provider registration displaces and later restores a host provider
- tool refresh reruns while registrations arrive mid-pass
- shell execs on one environment are serialized
- demo destructive-command gate tokenizes the command line
@mattzcarey

Copy link
Copy Markdown
Contributor Author

Fifth round pushed (4fec249): sandbox-root descendants deleted by a script are removed on sync; config-form provider registration displaces and restores host providers like the native form; tool refresh loops while dirty; exec is serialized per environment; the demo destructive gate tokenizes command words (documented as a UI demo, not a security boundary).

devin-ai-integration[bot]

This comment was marked as resolved.

- usePiSession resets lane-local state when the lane prop changes
- ctx.hasPendingMessages counts durable submissions waiting for the lane driver
@mattzcarey

Copy link
Copy Markdown
Contributor Author

Sixth round pushed (f3885a3): the React hook resets lane-local state on lane change; hasPendingMessages includes intake submissions waiting for the lane driver.

devin-ai-integration[bot]

This comment was marked as resolved.

…ions

Compactions and navigations waiting in intake are operations without a
message, so they no longer flip ctx.hasPendingMessages().
@mattzcarey

Copy link
Copy Markdown
Contributor Author

Pushed 0f12e25: hasPendingMessages now counts only prompt/skill/prompt_template submissions waiting in intake; compaction and navigation are excluded, with a test for the compaction case.

@mattzcarey

Copy link
Copy Markdown
Contributor Author

making draft. this feels like vendoring too much.

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