Skip to content

feat(seo): add AI agent events guide - #1388

Merged
lilyshen0722 merged 1 commit into
mainfrom
feat/ai-agent-events
Aug 31, 2026
Merged

lilyshen0722 merged 1 commit into
mainfrom
feat/ai-agent-events

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

Summary

  • publish the static, light-shell guide at /guides/ai-agent-events/
  • add sitemap/canonical Article metadata, hub entry, and four approved reciprocal links
  • cover the client route and placeholder-only acknowledgement curl

Verification

  • node --test scripts/generate-seo-pages.test.mjs
  • npx jest --runInBand src/v2/__tests__/V2Login.test.tsx
  • npm run typecheck
  • npm run build
  • npm test -- --watch=false (86 suites, 485 tests)

@lilyshen0722 lilyshen0722 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Gated at 90b93d6c. Two of the five rows in the event-type table name events that no code in this repository emits. Everything else checks out, and the generator work is clean.

Measured against origin/main efadbc3d:

row status
chat.mention real — 3 literal producers, plus MENTION_EVENT_TYPES
thread.mention real — agentMentionService.ts:144
heartbeat real — producers in registry/admin.ts:435, registry/pod-agents.ts:150, agentStateService.ts:151
task.assigned not an event type
integration.event no producer anywhere in the repo

integration.event appears only in docs-site/agents/events.mdx:89 (with a full JSON example), agents/runtime-protocol.mdx:62, integrations/webhooks.mdx:26. Zero hits in backend/. The real type for that slot is integration.summary, which is produced once in the backend and is a member of TYPING_EVENT_TYPES at agentEventService.ts:351. So the guide is faithful to our docs, and our docs are wrong — the error is inherited, not invented here.

task.assigned is a category error rather than a fiction. It exists, but as an AgentRun.trigger value — models/AgentRun.ts:116 (enum: ['mention','heartbeat','task.assigned','chat.message','pod.join','first_contact','manual']) and nativeRuntimeService.ts:609. Nothing constructs an AgentEvent with that type. The guide's prose commits to the stronger reading — "The task.assigned event carries the task and its current status" — so an agent author following it will poll for an event that never arrives.

The table is also missing the highest-volume real event. message.posted has 6 literal producers and is the whole wake-on-message path; a reader gets a five-row taxonomy that omits it while including two that do not exist.

Why the tests don't catch this, and why that matters here specifically. The new guard is

for (const eventType of ['chat\\.mention','thread\\.mention','task\\.assigned','heartbeat','integration\\.event']) {
  assert.match(eventsHtml, new RegExp(eventType));
}

which pins the string, not the referent. It will stay green forever whether or not the kernel emits any of them — this is exactly the failure mode TASK-074 was filed against, arriving on a page with crawl reach.

Suggested fix, smallest version: integration.eventintegration.summary; drop the task.assigned row or re-label it as a run trigger rather than a polled event; and file the docs-site/agents/events.mdx correction separately, since that is the upstream source and will keep re-seeding this.

What is verified good:

  • payload.deliveryId echoed on ack is exactly the implemented contract — agentsRuntime.ts:11151145, including the isDeliveryNonceRequired gate and the ADR-026 D6 note.
  • Rendered all 24 pages through renderStaticPage in a scratch tree: 0 hits for [object Object], stray undefined, or NaN. node --test scripts/generate-seo-pages.test.mjs is 2/2 on Node 22.
  • assert.doesNotMatch(eventsHtml, /cm_agent_[A-Za-z0-9]{8,}/) is a genuine addition — a real-token leak guard with a shape that would actually fire, not a presence assertion.
  • Base is current main (0 behind), so #1386 is already included and there is no parallel-merge hazard with it.
  • Test & Coverage is still pending; the other 10 are green.

@lilyshen0722
lilyshen0722 merged commit e9d7356 into main Aug 31, 2026
12 checks passed
@lilyshen0722
lilyshen0722 deleted the feat/ai-agent-events branch August 31, 2026 00:13
lilyshen0722 added a commit that referenced this pull request Sep 1, 2026
…e no producer (#1397)

* docs(agents): correct the event vocabulary — two documented types have no producer

`docs-site/agents/events.mdx` and `runtime-protocol.mdx` are the source that
three SEO guides (#1388, #1393, #1396) copied their event tables from, so a
wrong row here reaches public crawlable pages. Verified every row against its
producer at origin/main:

- `integration.event` does not exist. The real types are `integration.summary`
  (telegram/groupme/scheduler) and `discord.summary` for Discord specifically
  (schedulerService.ts:741). The payload is `{summary, integrationId, source}`,
  plus `{trigger, silent}` when scheduled — there is no `data` field.
- `task.assigned` is not an event type. It is an `AgentRun.trigger` value
  (models/AgentRun.ts:116, nativeRuntimeService.ts:609); nothing constructs an
  AgentEvent with it, so a runtime polling GET /events never receives one.
- `message.posted` was missing entirely despite having 6 producers and being
  the whole wake-on-message path.
- The mention payloads carry `content`, not `text` — and `mentions`, `source`,
  `messageType`, `createdAt`, `thread` were undocumented.
- The heartbeat payload does not contain `memoryFiles`, `recentMessages`,
  `pendingTasks` or `context`. It is `{trigger, generatedAt, podId,
  activityHint, policy, content}`, with the steering inline in `content`.
- `DISCORD_GUILD_ID` is read by no application code; the guild id comes from
  the Integration record (discordService.ts:240).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(agents): add the three peer-addressed event types the table still omitted

Follow-up on @pod-architect's review of the parent commit. Their widening holds
— I re-derived each producer rather than taking it on report:

- `agent.ask` (agentAskService.ts:214) and `agent.ask.response` (:281) are
  addressed to an arbitrary `targetAgent` / `ask.fromAgent`, so any BYO runtime
  receives them.
- `ensemble.turn` (agentEnsembleService.ts:285) is addressed to any ensemble
  member.

The load-bearing fact is that GET /events applies no type filter: the query is
`{agentName, instanceId, status:'pending'}` plus an optional podId
(agentEventService.ts:1231). A runtime is delivered every type enqueued against
its identity, so an omission from this table reads as absence and is wrong in
the same way a fictional row is.

`summary.request` and `user.message` stay omitted from the table but are now
named as first-party-only — hardcoded to `commonly-bot` (agentMentionService.ts
:267, routes/summaries.ts:324) and the managed-agents tier
(managedAgentsAdapter.ts:364) respectively.

Also records why both failure directions were silent: `AgentEvent.type` is
`{type: String, required: true}` with no enum (models/AgentEvent.ts:84), so
nothing validates a type name either way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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