electric-sql / electric-sql/electric
agents-chat-starter: spawn PUT goes to the durable-streams proxy, so no entity is created and agents never wake
- Dominant language
- TypeScript
- Stars
- 10.4k
- Forks
- 375
- Avg merge
- 3d 1h
- Merged PRs (30d)
- 18
Description
### 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:
```ts
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:
```ts
globalRouter.all(`/_electric/*`, internalRouter.fetch)
globalRouter.all(`*`, durableStreamsRouter.fetch)
```
So the PUT creates a raw durable stream named `/socrates/` 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:
```console
$ 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 9e3af10c3.
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.
Contributor guide
Research direction
Start with the spawn fetch in examples/agents-chat-starter/src/server/index.ts and the Entity Bootstrap snippet in the starter's AGENTS.md. Compare their request path with the entity route in packages/agents-server/src/routing/entities-router.ts, then run the Quick Start to confirm the entity appears in /_electric/entities and the agent wakes after a message.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100