IM bots
AICodeReviewer can push aggregated review problems to a Feishu or WeCom group
via a custom-bot webhook or a Feishu custom application’s bot. These are summary channels — they receive the
rolled-up review result, not per-line comments. Configure routing in
outputs.routes or per-workspace outputs.summary.
Feishu (飞书)
Section titled “Feishu (飞书)”1. Create a custom bot
Section titled “1. Create a custom bot”- Open the target group → Settings → Group Bots → Add Bot → Custom Bot
- Set the bot name and avatar
- Copy the webhook URL
(
https://open.feishu.cn/open-apis/bot/v2/hook/...) - If you enable signature verification (recommended), copy the signing secret shown in the bot settings
- Click Save
2. Set environment variables
Section titled “2. Set environment variables”# Requiredexport AICR_FEISHU_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx"
# Required only if signature verification is enabled in Feishu bot settingsexport AICR_FEISHU_SECRET="your-signing-secret"3. Configure the output channel
Section titled “3. Configure the output channel”outputs: channels: - name: feishu-code-review kind: feishu_bot webhook_url_env: AICR_FEISHU_WEBHOOK # env var holding the webhook URL secret_env: AICR_FEISHU_SECRET # required if the bot has signature verification mention_author: true # @-mention the commit author mention_fallback: skip # "all" | "skip" when author can't be resolved4. Route review events to Feishu
Section titled “4. Route review events to Feishu”outputs: routes: default: line_comments: [gitea-pr-review] summary: [gitea-pr-review] rules: # Route P4 changelists to Feishu - match: trigger: p4-main target_kind: commit summary: [feishu-code-review]
# Route GitHub push reviews to Feishu. Without a summary route, runs # with problems can be recorded as skipped (skipReason="no_output_publisher"). - match: trigger: github target_kind: push summary: [feishu-code-review]Or pin the channel at the workspace level:
workspaces: instances: p4-main: source_repo: trigger: p4-main repo: "//depot/main" outputs: summary: [feishu-code-review]5. Signature verification
Section titled “5. Signature verification”When signature verification is enabled on the Feishu bot, every request must
include a timestamp and sign field. AICR computes the signature
automatically from the secret named by secret_env:
string_to_sign = timestamp + "\n" + secretsignature = Base64(HMAC-SHA256(key=string_to_sign, message=""))If you see error 19021: sign match fail, verify that the secret_env value
matches the signing secret shown on the Feishu bot configuration page.
6. Card rendering
Section titled “6. Card rendering”AICR sends Feishu cards using the JSON 2.0 schema (card.schema = "2.0",
markdown placed under card.body.elements). Under 2.0, inline code, fenced
code blocks with language parsing, headings, blockquotes, and tables all
render natively. AICR applies toFeishuMarkdown() before dispatch — it only
runs Markdown fixing and blank-line collapse, and does not downgrade
headings to bold or tables to plain text (those 1.0-era transforms break 2.0
rendering). If inline code or code highlighting ever appears as literal
backticks, confirm the channel dispatcher is on the 2.0 schema path.
7. Linked-issue card content
Section titled “7. Linked-issue card content”When the summary route also records the run on an issue-recording channel
(gitea_problem_issue, github_problem_issue, or gitlab_problem_issue),
the Feishu card links the created issue instead of duplicating every problem.
issue_link_card on the feishu_bot/feishu_app channel selects the card
content:
titles(default): headline, problem count, one title line per problem, and the full-report linkbrief: headline, problem count, and the link onlyfull: headline, complete problem sections, and the link
outputs: channels: - name: feishu-code-review kind: feishu_bot webhook_url_env: AICR_FEISHU_WEBHOOK issue_link_card: full # brief | titles (default) | fullFeishu custom application
Section titled “Feishu custom application”Use feishu_app to send reports as a custom application’s bot. Enable the bot
capability, publish the application, and add it to the report group and member
source group. These groups may differ. A direct-message recipient must be within
the application’s availability scope. This outbound integration needs no event
subscription, callback server, or WebSocket connection of its own; enabling the
report card’s re-review button additionally requires an IM connection with
event callbacks for the same application (see
Review card button).
Create the app and grant permissions
Section titled “Create the app and grant permissions”- Create a custom enterprise app in the Developer Console. Under App capabilities → Add capabilities, enable Bot.
- Open Development configuration → Permissions → API permissions and search
for the scope identifiers below. Grant application identity permissions:
AICR uses
tenant_access_tokenand needs no user OAuth authorization. - For profile matching, add the source group’s users or departments under Permissions → Data permissions → Contact permission scope. Group-member access does not expand this scope; app availability is a separate setting.
- Create a version under App release → Version management and release, set its availability, submit it for review and confirm activation. After later permission or availability changes, complete publication and administrator approval as instructed by the console.
- Add the bot to the report group and, when using a directory, the group in
member_directory.chat_id. Allow the bot to speak in the report group. Direct-message recipients must be within the app’s availability scope.
The following scopes cover the APIs AICR calls. Sending reports to chat_id or
open_id alone needs only the first row. Directory association adds group-member access, the contact API
permission and the required profile-field permissions.
| Purpose | Scope identifier | When needed |
|---|---|---|
| Send reports as the app | im:message:send_as_bot |
Required for every feishu_app channel |
| List source-group members | im:chat.members:read |
A directory is configured and mention_author is enabled |
| Call the user-profile API | contact:contact.base:readonly |
Enrich members through GET /contact/v3/users/:user_id |
| Name, English name and alias | contact:user.base:readonly |
Read name, en_name and nickname |
contact:user.email:readonly |
Recommended for matching the email field |
|
| Enterprise email | contact:user.employee:readonly |
Read enterprise_email |
| Mobile number | contact:user.phone:readonly |
Read mobile |
| User ID | contact:user.employee_id:readonly |
Read user_id or use receive_id_type: user_id |
API access and field access are separate checks: contact:user.base:readonly
alone does not grant access to the contact API. The table selects a supported
combination; existing alternative scopes listed by the official API pages do
not require additional broader grants. AICR lists members and renders mentions
with open_id, so mentions do not require mobile numbers or user_id.
email and enterprise_email have different field permissions; enterprise
email also requires the administrator to enable Feishu Mail. Grant all rows
only if you need all supported profile fields, and check that users have filled
in those fields.
Sources: send message,
list group members,
get user information
and app availability.
External users, users outside the contact scope and unauthorized sensitive fields
may remain unavailable. AICR keeps available group data and omits uncertain
mentions. For error 41050, check contact scope; for 230002, check that the
bot is in the recipient group; for 230013, check the direct recipient’s app
availability.
Configure AICR
Section titled “Configure AICR”Set AICR_FEISHU_APP_SECRET in the server environment, then merge this configuration:
outputs: channels: - name: feishu-app-review kind: feishu_app app_id: cli_replace_me app_secret_env: AICR_FEISHU_APP_SECRET receive_id_type: chat_id receive_id: oc_report_group mention_author: true mention_fallback: skip guess_author: true member_directory: chat_id: oc_member_source_group cache_ttl_seconds: 300 user_mappings: "alice-dev-workspace": ou_replace_with_app_open_id routes: default: summary: [feishu-app-review]app_id and receive_id are required. Choose exactly one of app_secret_env
or literal app_secret; database-backed literals use the existing sealing and
masked-edit workflow. receive_id_type defaults to chat_id; open_id,
user_id, union_id and email target individual users. base_url defaults to
https://open.feishu.cn; the only alternative is https://open.larksuite.com.
Do not append /open-apis. Open IDs are application-specific.
Both Feishu channels share built-in feishu-summary.hbs, problem rendering,
JSON 2.0 cards and publish_if_summary as the default zero-problem policy.
Named templates.summary / templates.problem references take precedence.
Workspace lookup checks the channel name, then feishu_app.*, then
feishu_bot.*, then generic templates. A webhook workspace template can
therefore also render application reports. Application sends wrap the card as
a JSON string in the message API’s content field.
With mention_author: true, AICR pages through member_directory.chat_id and
enriches each member with the fields the app may read: name, en_name,
nickname, email, enterprise_email, mobile, open_id, user_id and
union_id. Only these fields are kept in memory. The cache lasts 12 hours by
default; cache_ttl_seconds accepts 0–604800 (7 days), with 0 disabling reuse.
The channel value overrides the global
outputs.author_resolution.directory_cache_ttl_seconds. A new configuration
generation has a separate cache. Both TTL fields support static files and database
configuration, under the usual file ownership rules. Temporary transport, HTTP 429
or HTTP 5xx failures may use an expired snapshot with a diagnostic; the next call
retries. Permission rejections and incomplete member lists invalidate the snapshot.
Zero TTL keeps no snapshot for fallback. Without a usable snapshot the report sends
without mentions. Directory data stays in the host’s publication path and the
dedicated identity call; review MCP tools do not expose the member list. Profiles use at most
four concurrent requests; each request has a 15-second timeout and the refresh
has a 60-second work budget.
Matching uses case-insensitive, Unicode-normalized values in this order:
- Channel-local
user_mappings: exact author email, username, display name or complete P4 submitter workspace to the same app’sopen_id. If a directory is configured, the mapped user must be in that directory. - P4
submitterWorkspaceagainst complete identifier segments separated by punctuation or spaces. For example,build_alice_PCmatches aliasalice;malice_PCdoes not. Short aliases below three characters are excluded here, except Chinese names with at least two characters. A unique workspace match takes precedence over a shared account such asadmin, even if that login matches another member’s email local part. Other providers skip this step. - Full author email against personal or enterprise email.
- Exact username/display name against names, aliases, email local parts, phone numbers or IDs.
- If all rules have no match and
guess_authoris enabled, a dedicated LLM call may associate the submitter with one directory candidate or abstain.
A tier with multiple candidates suppresses the mention without trying weaker
tiers or the model; this includes ambiguous P4 workspaces, even with
mention_fallback: all. The global email blacklist also suppresses it. AICR
does not use the push delivery actor or the analysis service’s P4 workspace.
mention_author defaults to false. Without a directory, only explicit
user_mappings resolve users; global Git login mappings are not Feishu IDs.
Use mention_fallback: skip to avoid notifying everyone on an unmatched author.
guess_author defaults to true for feishu_app. Setting it to false disables
workspace heuristics and the model fallback while retaining explicit mappings
and exact email/name/alias matches. mention_author remains the switch for
actual notifications; when false, neither the directory nor the model is called.
Git output channels retain their platform-native author resolution. Webhook
Feishu and WeCom bots have no member-directory capability and never run this
model association.
For alias owent and work email [email protected], P4 workspace
owent_myrion-pc_6689, independent P4 username owent, or GitHub/Gitea username
owent and that email already match through rules. No model call is needed.
For otherwise unmatched evidence, configure an independent model group:
llm: model_chain: default: - provider: your-existing-provider model: your-review-model role: heavy directory-identity: - provider: your-existing-provider model: your-identity-model role: light author_resolution_model_chain: directory-identityworkspaces: defaults: author_resolution_model_chain: directory-identity instances: your-workspace: author_resolution_model_chain: directory-identityMerge the group into your existing configuration. Selection is workspace
instance → workspace defaults → llm.author_resolution_model_chain →
llm.default_model_chain; it does not inherit the workspace review group.
All three fields support static files and database management. In the dashboard,
use Model groups → Model chains for the global setting and Workspaces
for defaults or instance overrides. Normal database priority/reset and model-group
reference validation apply. Each running task keeps its admitted configuration
generation even if settings are published before its report is sent.
The dedicated identity prompt sends only submitter identity hints and candidate
names, aliases and emails to the selected model provider. Phone numbers, native
directory IDs, credentials, review code and reports are excluded. Candidate keys
are temporary; the host validates membership and renders the mention. Directory
records never enter the main code-review prompt or persistent report state.
Only an allowed candidate with high model confidence is accepted. Ambiguity,
abstention, invalid output, model failure or a 15-second deadline suppresses @
without suppressing the report, including with mention_fallback: all.
The call uses the configured fallback/retry chain, provider limits and shared
run/daily budgets. More than 500 candidates or a serialized input over 64,000
characters skips model analysis entirely; candidates are never silently truncated.
See the configuration reference for field paths.
Directory failures or security-limited membership lists send the report without mentions. Contact lookup failures retain only the available group fields and emit a diagnostic without personal data. A source-group match may not be a member of the report group; actual mention delivery still depends on Feishu’s membership and notification rules. Validate that boundary in your tenant.
The client caches tenant access tokens and refreshes an explicitly rejected token once. HTTP errors, nonzero API codes and missing message receipts fail publication. Delivery may already have occurred after a transport failure. Automatic commit batches persist the send identity and reuse its UUID for up to 59 minutes after the first attempt; SQLite or Redis retains it across restarts. An expired UUID or changed uncertain request blocks resending. Other review paths reuse an in-memory UUID only for the token retry, without restart recovery.
WeCom (企业微信)
Section titled “WeCom (企业微信)”1. Create a group bot
Section titled “1. Create a group bot”- Open the target group → Group Settings → Group Bots → Add Bot
- Set the bot name and avatar
- Copy the webhook URL
(
https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=...) - Click Save
2. Set environment variables
Section titled “2. Set environment variables”# Requiredexport AICR_WECOM_WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx"WeCom group-bot webhooks do not use HMAC signature verification; no secret env var is needed.
3. Configure the output channel
Section titled “3. Configure the output channel”outputs: channels: - name: wecom-ops kind: wecom_bot webhook_url_env: AICR_WECOM_WEBHOOK mention_author: false # @-mention the commit author mention_fallback: skip # "all" | "skip" when author can't be resolved no_problems: { action: suppress } # mentioned_mobile_list: ["+86-13800138000"] # optional: sends one bounded text # reminder; mobile mentions only exist on the text message type4. Route review events to WeCom
Section titled “4. Route review events to WeCom”outputs: routes: default: line_comments: [gitea-pr-review] summary: [gitea-pr-review] rules: # Route P4 changelists to WeCom - match: trigger: p4-main target_kind: commit summary: [wecom-ops]5. Markdown rendering and limits
Section titled “5. Markdown rendering and limits”WeCom group-bot messages support a subset of Markdown: headings, bold, links,
inline code, and blockquotes render natively. Tables are flattened to
plain-text rows. Code fences are preserved. AICR applies
toWeComMarkdown() automatically before dispatch.
Reports keep every problem’s complete message, suggestion and code reference. WeCom webhook Markdown has a 4096-byte UTF-8 limit. Only excess text is truncated, with a notice; the native mention remains. Feishu webhook requests are bounded at 20 KiB and application card requests at 30 KiB, including JSON escaping and request fields. Report links, mentions and card buttons remain. WeCom application reports split into 2048-byte parts.
External member directory (file)
Section titled “External member directory (file)”IM channels without a directory API (wecom_bot, feishu_bot, wecom_app)
can resolve commit authors against a strict YAML/JSON member file and emit
native typed mentions instead of plain @username text:
outputs: channels: - name: wecom-group kind: wecom_bot webhook_url_env: AICR_WECOM_WEBHOOK mention_author: true member_directory: source: file path: ./private/im-members.yaml directory_id: engineering-wecom identity_scope: { kind: wecom_corp, id: ww_example } watch: true # parent-directory watch, default onKeep member files owned by the runtime user, with directory mode 0700 and file
mode 0600. In deploy.sh deployments, /app/data/private maps to the host’s
data/db/private; permission repair preserves this subtree and task backups
under data/db/build.
The member file format is documented in the configuration reference; highlights:
Without a directory, native webhook mentions require explicit
outputs.author_resolution.email_mappings. A VCS login or a Feishu ID does not
identify a WeCom member. For shared P4 accounts, map the complete submitter
workspace through author_mappings, or enable guess_author for unambiguous
workspace matching. File-directory results replace fallback mentions and populate
custom atMentions before rendering. mention_author: false disables directory
matching and dynamic mobile reminders.
- Matching order: exact scoped
vcs_accounts(trigger-isolated), explicitauthor_mappings, then deterministic names/emails — guessing stays OFF unless the channel opts in viaguess_author: true. wecom_useridmembers render<@userid>inline;wecom_mobilemembers get one bounded text reminder (mobiles only work in text messages); Feishu members render typed<at>tags.- The whole file validates or the report ships without mentions — broken directories never fall back to @all. One directory snapshot is pinned per report, including every split part.
- The file path is relative to the main config directory. It must remain under
allowed_root(the config directory by default) after resolving..and symlinks; an absolute path outside that root requires an explicit trusted root. - Names, aliases and emails from the file never enter payloads, prompts or logs beyond the typed mention id.
WeCom custom application
Section titled “WeCom custom application”The wecom_app channel sends the aggregated report through a self-built
application (message/send) to explicit members, departments or tags, or to
one appchat group (appchat/send). Credentials live in an
im.connections entry (literal secrets are sealed in database config;
app_secret_env is preferred):
im: connections: corp-review: kind: wecom_app corp_id: ww_example agent_id: 1000002 app_secret_env: AICR_WECOM_APP_SECRET
outputs: channels: - name: wecom-app kind: wecom_app connection: corp-review target: kind: recipients # members/departments/tags users: [alice_zhang] - name: wecom-group kind: wecom_app connection: corp-review target: kind: appchat # one group created by this application chat_id: exampleChat123Behavior notes:
- The report is WeCom Markdown, split into UTF-8-safe parts of at most
2048 bytes; every part carries its own delivery receipt, and a delivered
part is never resent. Business rejections (
errcode != 0) fail the channel instead of reporting success. - Only the explicit token error codes
40014/42001trigger one token refresh and one retry; timeouts keep the outcomeunknownand never resend. appchattargets require the group to be created by the same application and its visible scope to include the root department — appchat stays unverified when your environment forbids that scope; userecipients.- Message commands and review buttons for IM connections are configured separately (see Managing IM connections).
Review card button (Feishu and WeCom apps)
Section titled “Review card button (Feishu and WeCom apps)”A feishu_app or wecom_app output channel attaches a re-review button
to its report when all of the following hold:
- Feishu: the channel’s
app_idmaps to aim.connectionsFeishu connection with event callbacks enabled and the destination is a group (receive_id_type: chat_id); - WeCom: the channel’s connection has callbacks enabled and the target is
explicit recipients (
target.kind: recipients— only callback-configured apps may send callback cards, and appchat group messages have no card type). The card is sent as one extra message after the Markdown report parts; itstask_idand button key carry only the action id; - both platforms require an enabled command binding allowing the
reviewcommand, covering the report conversation (the receiving group on Feishu, the direct conversation on WeCom) and registering the reviewed repository underrepositories.
The button carries only a server-issued opaque action id (valid for 24 hours). On click the server verifies the real operator, the platform message/task identity, the conversation and the binding authorization before creating a new review request; repeated clicks on the same button return the original request id, while cards forwarded to another conversation, revoked bindings and expired actions are rejected. An action whose send acknowledgement never became durable stays pending and is never activated by a callback’s self-reported source. Channels without a callback surface (WeCom webhook, appchat, …) show no button.
Publication recovery reuses the original action id and acknowledged message; it does not issue a new button for a confirmed send. The action retains its issuance snapshot for audit until consumption or expiry; a click creates its new request under the current configuration snapshot. Without a durable click-time snapshot, the action remains unconsumed.
Receiving message commands (callback and long connection)
Section titled “Receiving message commands (callback and long connection)”Besides sending reports, IM connections can receive @-mention message
commands in groups. Three receive modes are supported today, selected per
connection in im.connections:
im: connections: # WeCom smart robot — event-callback mode wecom-airobot: kind: wecom_aibot corp_id: ww_example callback: enabled: true token_env: AICR_WECOM_AIBOT_TOKEN # callback Token encoding_aes_key_env: AICR_WECOM_AIBOT_AES # callback EncodingAESKey
# WeCom smart robot — long-connection mode (no public callback URL needed) wecom-airobot-lc: kind: wecom_aibot corp_id: ww_example aibot_id: "https://open.work.weixin.qq.com/..." # the robot's bot_id secret_env: AICR_WECOM_AIBOT_LC_SECRET # the robot's Secret
# Feishu custom application — event-callback mode # (platform side: "send events to the developer server") feishu-app: kind: feishu_app app_id: cli_example app_secret_env: AICR_FEISHU_APP_SECRET tenant_key: "xxxx" callback: enabled: true verification_token_env: AICR_FEISHU_VERIFY_TOKEN encrypt_key_env: AICR_FEISHU_ENCRYPT_KEY
# Feishu custom application — long-connection mode # (platform side: "receive events over a long connection"): no callback # configured (or enabled: false); the server dials with app_id+app_secret feishu-app-lc: kind: feishu_app app_id: cli_example app_secret_env: AICR_FEISHU_APP_SECRETPlatform-side callback URLs follow
https://<server-address>/callbacks/im/<connection-id>, for example
https://aicr.example.com/callbacks/im/wecom-airobot. When you save the URL the
platform sends a verification challenge and the server answers per protocol;
afterwards every @-mention message is signature-verified, decrypted, persisted
to the inbox, and only then processed.
Supported command grammar (the aicr prefix, sent after @-mentioning the bot):
aicr help— every receive mode answers immediately with the command help. The WeCom callback mode answers with an encrypted finished stream message in the callback response body (msgtype: "stream"withfinish: true; a plain markdown body is ignored by the platform), the WeCom long connection replies viaaibot_respond_msg, and Feishu replies through its message API.- Query commands (read-only, same binding authorization; lists include only
repositories in the authorized binding unless it enables
allow_all_repositories):aicr projects,aicr reviews [alias],aicr commits <alias> [branch]/aicr prs <alias> [branch](recently trigger-eligible commits / PRs-MRs),aicr detail <alias> <revision>/aicr prdetail <alias> <pr-id>(run detail: status, model, input/output/cache-hit tokens, request count, cost, duration — recent records only),aicr queue(pending tasks with scheduled starts),aicr running(in-flight reviews). For registered repositories, queries match the binding’s workspace, source trigger, and repo reference. Another trigger for the same workspace and repo is outside that binding. aicr chat-id/aicr review <repo> <revision>/aicr status <id>/ the cancel commands — require an enabledim.command_bindingsentry. Authorization checks four dimensions — actor, conversation, connection and command — and the actor matches either an exact principal ({type, id}) or a scope matcher: departments (recursive), tags (the role/user-group carrier), positions, custom fields, Feishu chat membership / departments / job titles, andany(any authenticated actor). Every matcher accepts an optionalexpires_atfor time-boxed temporary authorization. Scope matching resolves against server-side directory snapshots (WeCom needs an enabledwecom_appconnection for the corporate directory; the smart robot’s encrypted userids convert automatically). A missing directory fails that dimension closed; exact principals keep working. Bindings may enableallow_all_repositories: repo aliases then also resolve by workspace id or full repo name against the integrated projects (the onesaicr projectslists), without per-repo registration. Rejected commands echo the actor and conversation identity back to the sender (visible only inside that conversation) — that closes the group whitelist bootstrap loop: @-mention the bot in a group once, take the group id from the rejection reply, and add it to the binding’sconversations(WeCom smart-robot groups have no query API).
Cancel commands (a write operation; the binding’s commands must explicitly
list cancel):
aicr cancel <repo> <revision>— cancels the in-flight/queued tasks of that repository matching a commit-hash prefix or an exact numeric revision.aicr cancel <repo> before <duration>— cancels that repository’s tasks enqueued before now minus the duration; durations are<n><m|h|d>(minutes/hours/days), e.g.2h,30m,3d. An ISO timestamp with an explicit timezone also works, e.g.2026-09-01T00:00:00+08:00.aicr cancel before <duration>— repo-unrestricted, cancels the tasks enqueued before the bound within the binding’s authorized repositories (all repositories when the binding enablesallow_all_repositories).
Cancellation covers queued auto-commit batches
(terminally closed, stream released), running batches (persisted as cancelled
before aborting — output already published stays published), IM review
requests (terminal rejected, with a notification to the requesting
conversation), and leftover in-flight run rows (marked cancelled).
Alias forms require the alias to be registered on the binding (or resolved
via allow_all_repositories); the cancellation scope never exceeds the
binding’s authorized repositories. An explicit alias always limits cancellation
to that repository, even when allow_all_repositories is enabled. Active
webhook and admin reviews can also be aborted through their live run registry.
Cancellation prevents subsequent publication; it cannot undo delivered output.
Reviews deferred outside their execution window are also removed durably.
aicr review stores the request and its configuration snapshot. The server
worker validates the fixed revision and runs the review under the shared
workspace concurrency limit. Git requires a full commit hash reachable from
the configured repository; SVN and P4 require a positive revision number.
A repeated request for the same active workspace, repository and revision
reuses the existing review without consuming the quota for a new request.
aicr status reveals a request only to its original actor on the original
connection and conversation, while its repository remains allowed by the
status binding. An interrupted review recovers per phase: a crash during
analysis retries with persisted backoff (currently at most three recovery
attempts by default before the request fails); a publication interrupted after the
analysis completed resumes publication only from its durable checkpoint
without calling the model again; a publication whose delivery outcome cannot
be proven is reported as publication_unknown and is never automatically
published again.
Malformed publication checkpoints cannot authorize a resend. A checkpoint
over 1 MiB or a failed checkpoint write stops further sends and preserves
the last durable recovery state. Git commit authors come from stored VCS
metadata; the chat operator is recorded separately.
Terminal notifications use the requesting conversation. In WeCom long
connection mode, they use the existing subscribed socket and wait for the
platform send acknowledgement.
A request fails when all publication operations fail or no publisher is configured;
it is partial when some operations publish and others fail.
Transport failures and unprovable delivery remain publication_unknown;
explicit recipient rejection is a failure, and known partial delivery is partial.
Long-connection modes are initiated by the server: aicr serve dials per the
connection table (auto-reconnecting on drops), needing neither a callback URL
nor any callback configuration — WeCom smart robots use the official
WebSocket protocol (aibot_id+secret), Feishu uses the official SDK long
connection (app_id+app_secret). The two WeCom modes are separate robot
entities (each with its own bot_id/credentials) and can coexist; Feishu’s
callback and long-connection modes are mutually exclusive on the platform side
— configure the connection to match the event-receive method chosen in the
developer console.
Common fields
Section titled “Common fields”The IM channel kinds share the common output-channel fields documented in Output channels config. The fields most relevant to IM bots:
| Field | Meaning |
|---|---|
webhook_url_env |
Webhook channels: env var name holding the bot webhook URL |
secret_env |
feishu_bot: env var name holding the signing secret |
mention_author |
true to @-mention the commit author when resolvable |
mention_fallback |
all (mention @all) or skip when the author can’t be resolved |
no_problems |
Zero-problem policy for this channel (publish / suppress / publish_if_summary) |
For routing, target-kind matching, and the zero-problem policy, see Output channels and Output channels config.
Managing IM connections and command bindings
Section titled “Managing IM connections and command bindings”The dashboard Configuration tab includes two entity pages for the IM
integrations: IM connections and IM command bindings. Connections hold
the protocol identity and credentials (wecom_app, wecom_aibot or
feishu_app); command bindings reference a connection and define which typed
actors, conversations and commands may request reviews. Literal credentials
entered in the drawer are sealed at persistence boundaries and never displayed
again; deleting or renaming a connection that a binding or channel references
is rejected atomically by the publish boundary.
These pages manage draft configuration: report sending and all three
receive modes (WeCom smart-robot event callback / long connection, Feishu
application event callback) are live — aicr help answers immediately; the
review commands (review/status) only run once a command binding is enabled,
and bindings stay disabled by default.
See Configuration field reference for the
im.* field contracts.