Skip to content

agents-chat-starter: spawn PUT goes to the durable-streams proxy, so no entity is created and agents never wake #4687

Description

@adityavkk

What happens

Follow the starter's Quick Start, create a room, and send a message. No philosopher ever replies. Nothing reports an error. POST /api/rooms returns {"agentCount": 1} and the spawn PUT returns 201 Created.

The spawn call in examples/agents-chat-starter/src/server/index.ts PUTs to the bare entity path:

const entityUrl = `/${type}/${agentId}`
const putRes = await fetch(`${AGENTS_URL}${entityUrl}`, { method: `PUT`, ... })

On the current agents-server, that path never reaches the entity API. packages/agents-server/src/routing/global-router.ts sends /_electric/* to the internal router and everything else to the durable-streams proxy:

globalRouter.all(`/_electric/*`, internalRouter.fetch)
globalRouter.all(`*`, durableStreamsRouter.fetch)

So the PUT creates a raw durable stream named /socrates/<id> and returns 201. No entity is created, no dispatch subscription is registered, and the agent never wakes. The only route that creates an entity is PUT /_electric/entities/:type/:instanceId (packages/agents-server/src/routing/entities-router.ts).

Repro

Against @electric-ax/agents-server 0.6.3 (run via pnpm dlx, embedded streams, port 4510) with the starter's backend running so the socrates/camus/simone types are registered:

$ curl -s -o /dev/null -w '%{http_code}\n' -X PUT localhost:4510/socrates/repro-bare \
    -H 'content-type: application/json' \
    -d '{"args":{"chatroomId":"repro"},"initialMessage":"You have joined."}'
201

$ curl -s localhost:4510/_electric/entities
# only the principal entity; /socrates/repro-bare is not there

$ curl -s -X PUT localhost:4510/_electric/entities/socrates/repro-entity \
    -H 'content-type: application/json' \
    -d '{"args":{"chatroomId":"repro"},"initialMessage":"You have joined."}'
{"url":"/socrates/repro-entity","type":"socrates","status":"idle","streams":{"main":"/socrates/repro-entity/main"},"dispatch_policy":{"targets":[{"url":"http://localhost:4710/webhook","type":"webhook",...

After the second PUT the entity appears in /_electric/entities, the dispatch webhook is registered, and the first wake runs the handler. Nothing at all happens after the first PUT.

Why it broke

The starter was correct when it was written. At the original Electric Agents commit (#4151), the server matched bare /{type}/{name} paths and spawned on PUT. The routing refactor in #4307 moved entity creation under /_electric/entities and pointed the catch-all at the durable-streams proxy. The starter (added in #4199, before the refactor) kept the old path, so it has been silently broken since #4307. The failure mode is nasty because the proxy answers 201 and the starter's putRes.ok check passes.

Everything else in the repo already uses the canonical path: ctx.spawn through runtime-server-client.ts spawnEntity(), the electric-ax CLI (entity-api.ts), and the conformance DSL, which prefixes /_electric/entities onto every entity request.

Fix

Point the starter's spawn fetch at ${AGENTS_URL}/_electric/entities/${type}/${id}, and fix the same snippet in the starter's AGENTS.md ("Entity Bootstrap" section). PR incoming.

Versions: @electric-ax/agents-server 0.6.3, @electric-ax/agents-runtime 0.6.3, repo main at 9e3af10.

A separate, smaller problem found on the way: pnpm install on a freshly scaffolded copy (npx electric-ax agents init) fails because the template's package.json pins "@electric-ax/agents-runtime": "workspace:*", which does not resolve outside the monorepo. Happy to file that separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions