Devin AI c283d884cf fix(agent-proxy): reconnect with events.list backfill so long sessions don't cut off
The Anthropic Managed-Agents SSE stream (`/v1/sessions/{id}/events/stream`)
is not guaranteed to stay open for the life of a multi-turn session.
Inter-turn gaps (e.g. while MCP tools or the next model request run) of
~25s+ are common and can trigger upstream / proxy read timeouts; when
that happens, the SDK's `for await` iterator just ends and the proxy
silently closed the downstream response, leaving the browser with only
the events from the first tool batch.

Implement the official 'consolidation' pattern: treat any upstream
end-of-stream that isn't a terminal `session.status_*` as a transient
drop, fetch what we missed via `sessions.events.list()` (deduped by
event.id), reopen the live stream, and keep going — up to a 20 minute
wall-clock budget so a wedged session can't pin the function forever.

Also switch the wire format from inline-markdown-with-status-comments to
NDJSON, so the React side can render in-flight tool activity in a
separate status banner from the streaming brief. The existing zero-width
heartbeat is replaced by an explicit `{"type":"heartbeat"}` line.

Drop the `agent.tool_use` write-tool special case — the agent now
streams the brief directly via `agent.message` text blocks.

Co-Authored-By: alex <alex@semipublic.co>
2026-05-13 03:20:15 +00:00
2026-05-11 22:27:54 -04:00
2026-05-11 22:27:54 -04:00
2026-05-11 22:27:54 -04:00
2026-05-11 22:27:54 -04:00
2026-05-11 23:28:15 -04:00
2026-05-11 23:28:15 -04:00
2026-05-11 22:27:54 -04:00
2026-05-11 22:27:54 -04:00
2026-05-11 22:27:54 -04:00
2026-05-11 22:27:54 -04:00

PMC Funder Discovery Tool

A React + Vite frontend (Tailwind, Noto Serif) that collects public media station details and streams an Anthropic Managed Agent response back to the browser through a Netlify Functions v2 proxy.

Setup

npm install

Add your Anthropic credentials (in .env for local dev, in the Netlify UI for production):

ANTHROPIC_API_KEY=sk-ant-...
# Optional - if you've provisioned a Managed Agent in the Anthropic console:
ANTHROPIC_AGENT_ID=agent_...
# Optional - override the model:
ANTHROPIC_MODEL=claude-sonnet-4-5

Run locally

npm run dev   # netlify dev (proxies Vite + functions on :8888)

Open http://localhost:8888.

How streaming works

  1. The browser POSTs the form to /.netlify/functions/agent-proxy.
  2. The Netlify v2 function calls anthropic.messages.stream(...) and wraps the upstream iterator in a ReadableStream. Each content_block_delta text chunk is enqueued as plain UTF8 bytes.
  3. The React app reads response.body.getReader() and decodes chunks with TextDecoder, appending them to the result state.
  4. A Thinking flag stays true until the first chunk arrives, then flips to a streaming state with a pulsing cursor.

Files

S
Description
No description provided
Readme 147 KiB
Languages
JavaScript 48.4%
TypeScript 46.1%
CSS 4.4%
HTML 1.1%