Skip to content

feat(seo): add AI agent Discord integration guide - #1393

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

lilyshen0722 merged 1 commit into
mainfrom
feat/ai-agent-discord-integration

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

Summary

  • adds the crawlable Page 18 Discord integration guide with the approved manual-first rollout and event boundaries
  • keeps credential examples as literal placeholders and adds approved internal plus reciprocal links
  • updates route, static-render, hub-card, and SPA-route tests for 28 pages / 18 guides

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
  • generated Page 18 checked for canonical, sitemap, static-only shell, literal Discord placeholders, and no real runtime token

@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 c00693ba. PASS on the Discord surface — every command and credential it names is real. Two sentences cite our documentation accurately, and the documentation is wrong in both cases.

Verified real, all of it: /commonly-summary, /discord-status, /discord-push, /discord-enable, /discord-disable all resolve to handlers in backend/services/discordService.ts (the switch at :809, the registration block at :854, the command list at :1042). DISCORD_BOT_TOKEN is consumed throughout. No token-shaped strings render — I checked the output for both cm_agent_ and Discord bot-token shapes and got neither.

Finding 1 — integration.event recurs here, and this is the propagation path.

"Commonly's agent event reference includes integration.event for external integration events, with source and data in the payload; its example uses source: "discord"."

That sentence is true as written. docs-site/agents/events.mdx:89 does include it, and its example does use source: "discord". But no code in this repository emits integration.event — the real type is integration.summary (backend/services/agentEventService.ts:351). I filed this as #1391 after #1388 shipped it, and predicted there that the docs-site/ source would re-seed it. This is that recurrence, one PR later.

Ordering consequence worth naming: because the sentence is phrased as a claim about the reference rather than about the runtime, fixing #1391 upstream will make this sentence false. So this guide is coupled to that fix — it is not independent of it.

Finding 2 — DISCORD_GUILD_ID is read by nothing.

"The documented deployment variables also include DISCORD_GUILD_ID for guild-specific commands where the operator needs it."

Also true as a statement about the docs (docs-site/deployment/environment-variables.mdx:60), and also naming something with no consumer. Zero hits in backend/ — control run with DISCORD_BOT_TOKEN on the same query returns hits, so the instrument works. It is wired in k8s/helm/.../backend-deployment.yaml:247 and read by no code.

The guild id is actually resolved from the Integration record, not from the environment — discordService.ts:240:

const guildId =
  integration.platformIntegration?.serverId ||
  integration.config?.serverId;

and the command deployer requires only two variables — deploy-discord-commands.js:51: const required = ["DISCORD_CLIENT_ID", "DISCORD_BOT_TOKEN"];. So an operator following this line will set a variable that does nothing, and may believe guild scoping is env-configured when it is per-integration data.

The pattern across both findings is the same and it is not the author's error. Both sentences are carefully hedged as claims about our documentation, and both are accurate at that level. The defect is upstream: docs-site/ names two things the code does not implement, and a hedge that makes a sentence unfalsifiable also makes it uncorrectable — a reader cannot tell "documented and implemented" from "documented only."

Neither is blocking on its own; #1393 is not less accurate than the docs it cites. But shipping it adds a second crawlable page depending on a doc fix that is already filed and open.

Mechanical: rendered all 28 pages — 0 [object Object], 0 stray undefined. node --test scripts/generate-seo-pages.test.mjs 2/2 on Node 22. Base is current main (0 behind). Test & Coverage passes here; Service Tests (Tier 1 — real DBs) is the one still pending.

@lilyshen0722
lilyshen0722 merged commit c832c31 into main Aug 31, 2026
12 checks passed
@lilyshen0722
lilyshen0722 deleted the feat/ai-agent-discord-integration branch August 31, 2026 01:54
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