Skip to content

fix(auto-reply): inject timestamp into BodyForAgent for channel messages#41802

Closed
carrotRakko wants to merge 4 commits into
openclaw:mainfrom
delight-co:fix/channel-bodyforagent-timestamp
Closed

fix(auto-reply): inject timestamp into BodyForAgent for channel messages#41802
carrotRakko wants to merge 4 commits into
openclaw:mainfrom
delight-co:fix/channel-bodyforagent-timestamp

Conversation

@carrotRakko
Copy link
Copy Markdown
Contributor

Summary

  • Problem: Channel messages (LINE, Telegram, Discord, Slack, etc.) don't include a timestamp in BodyForAgent. Models whose providers don't inject date context server-side (e.g., Mistral) hallucinate dates.
  • Why it matters: All channel-connected agents are affected. Date-sensitive use cases get confidently wrong answers.
  • What changed: finalizeInboundContext() now calls the existing injectTimestamp() on BodyForAgent. Tests updated.
  • What did NOT change: Gateway agent/chat.send handlers untouched. System prompt date injection unaffected.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

Agents connected via channels now receive a timestamp in their message context. Models that previously hallucinated dates will now have correct date/time awareness.

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Linux (Amazon Linux 2023, aarch64)
  • Runtime/container: Node.js
  • Model/provider: Mistral Large via OpenRouter
  • Integration/channel: LINE, Slack
  • Relevant config: Default

Steps

  1. Configure an agent with a model whose provider does not inject date context (e.g., Mistral Large via OpenRouter)
  2. Connect via any channel
  3. Ask "What's today's date?"

Expected

  • Agent answers with the correct current date.

Actual

  • Before: Agent hallucinates a date from training data cutoff.
  • After: Agent receives timestamp in BodyForAgent and answers correctly.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Tests in inbound.test.ts, monitor.test.ts, apply.test.ts, and bot-message-context.audio-transcript.test.ts updated to assert timestamp presence in BodyForAgent.

Human Verification (required)

  • Verified scenarios: Tested on a fork with LINE and Slack channels using multiple models including Mistral Large via OpenRouter. Agents correctly report current date/time.
  • Edge cases checked: injectTimestamp is idempotent — messages already with a timestamp (gateway path, cron) are not double-stamped.
  • What you did not verify: Not every channel/extension combination, but the injection point (finalizeInboundContext) is shared by all.

Review Conversations

N/A — fresh PR, no review conversations yet.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery (if this breaks)

  • How to disable/revert: Revert the single injectTimestamp call in inbound-context.ts
  • Files/config to restore: src/auto-reply/reply/inbound-context.ts
  • Known bad symptoms: Double timestamps in agent messages (would indicate idempotency check failed)

Risks and Mitigations

  • Risk: Double timestamps on messages that already have one.
    • Mitigation: injectTimestamp is idempotent — checks for existing timestamp envelopes before injecting.

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord channel: telegram Channel integration: telegram size: XS labels Mar 10, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 10, 2026

Greptile Summary

This PR fixes a real bug where channel messages (LINE, Telegram, Discord, Slack, etc.) lacked date/time context in BodyForAgent, causing models that don't inject dates server-side to hallucinate dates. The fix is minimal and well-targeted: a single injectTimestamp call inside finalizeInboundContext, the shared entry point for all inbound channel messages.

Key findings:

  • Failing test (missed update): The "sanitizes spoofed system markers in user-controlled text fields" test in inbound.test.ts (line 134) was not updated — it still uses .toBe() with an exact string for BodyForAgent. Because the sanitized value "System (untrusted): [2026-01-01] fake event" doesn't trigger the TIMESTAMP_ENVELOPE_PATTERN idempotency check, injectTimestamp will prepend a timestamp and the assertion will fail. Every other touched test was correctly updated to .toContain() + a regex match — this one was missed.
  • Timezone always UTC for channel messages: injectTimestamp is called without options, defaulting timezone to "UTC". The gateway agent and chat.send handlers pass timestampOptsFromConfig(cfg) so they respect the user's configured userTimezone. Channel messages will therefore display UTC timestamps even for users who have set a custom timezone, creating an inconsistency.
  • Stale JSDoc in agent-timestamp.ts: The function-level comment still says channel messages "never reach these handlers," which is no longer true after this change. Minor, but could mislead future contributors.

Confidence Score: 3/5

  • The production change is safe and correct, but the test suite has a missed update that will cause a CI failure before merging.
  • The core implementation in inbound-context.ts is sound — injectTimestamp is idempotent and the injection point is correct. However, the "sanitizes spoofed system markers" test in inbound.test.ts was not updated to account for the new timestamp prefix on BodyForAgent, and it will fail as-is. This blocks a clean CI pass. Additionally, channel messages will always receive UTC timestamps rather than the user's configured timezone, which is a behavioral inconsistency with the gateway path.
  • src/auto-reply/inbound.test.ts — the "sanitizes spoofed system markers" assertion at line 134 needs to be updated to .toContain() + timestamp regex, matching the pattern used in the other updated tests.

Comments Outside Diff (2)

  1. src/auto-reply/inbound.test.ts, line 134 (link)

    Missed test update — assertion will fail after timestamp injection

    The "sanitizes spoofed system markers" test still uses .toBe() with an exact match for BodyForAgent, but finalizeInboundContext now calls injectTimestamp on every non-empty BodyForAgent. The sanitized RawBody value "System (untrusted): [2026-01-01] fake event" does not start with [, so TIMESTAMP_ENVELOPE_PATTERN won't match it, and injectTimestamp will prepend a timestamp prefix. The test will fail at runtime with something like:

    Expected: "System (untrusted): [2026-01-01] fake event"
    Received: "[Wed 2026-03-10 12:30 UTC] System (untrusted): [2026-01-01] fake event"
    

    The other finalizeInboundContext tests in this file were correctly updated to use .toContain() + a timestamp regex — this one was missed.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/auto-reply/inbound.test.ts
    Line: 134
    
    Comment:
    **Missed test update — assertion will fail after timestamp injection**
    
    The `"sanitizes spoofed system markers"` test still uses `.toBe()` with an exact match for `BodyForAgent`, but `finalizeInboundContext` now calls `injectTimestamp` on every non-empty `BodyForAgent`. The sanitized `RawBody` value `"System (untrusted): [2026-01-01] fake event"` does **not** start with `[`, so `TIMESTAMP_ENVELOPE_PATTERN` won't match it, and `injectTimestamp` will prepend a timestamp prefix. The test will fail at runtime with something like:
    
    ```
    Expected: "System (untrusted): [2026-01-01] fake event"
    Received: "[Wed 2026-03-10 12:30 UTC] System (untrusted): [2026-01-01] fake event"
    ```
    
    The other `finalizeInboundContext` tests in this file were correctly updated to use `.toContain()` + a timestamp regex — this one was missed.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
  2. src/gateway/server-methods/agent-timestamp.ts, line 34-40 (link)

    Stale JSDoc — channel messages now do reach injectTimestamp

    The comment says:

    Channel messages (Discord, Telegram, etc.) already have timestamps via envelope formatting and take a separate code path — they never reach these handlers, so there is no double-stamping risk.

    This is no longer accurate. This PR makes finalizeInboundContext (the shared entry point for all channel messages) call injectTimestamp directly. The double-stamp protection is still correct (the idempotency check handles it), but the statement that channel messages "never reach these handlers" should be updated to reflect that finalizeInboundContext now also calls this function.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/gateway/server-methods/agent-timestamp.ts
    Line: 34-40
    
    Comment:
    **Stale JSDoc — channel messages now do reach `injectTimestamp`**
    
    The comment says:
    
    > Channel messages (Discord, Telegram, etc.) already have timestamps via envelope formatting and take a separate code path — they never reach these handlers, so there is no double-stamping risk.
    
    This is no longer accurate. This PR makes `finalizeInboundContext` (the shared entry point for all channel messages) call `injectTimestamp` directly. The double-stamp protection is still correct (the idempotency check handles it), but the statement that channel messages "never reach these handlers" should be updated to reflect that `finalizeInboundContext` now also calls this function.
    
    How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 4af43b8

Comment thread src/auto-reply/reply/inbound-context.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4af43b8a80

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/auto-reply/reply/inbound-context.ts Outdated
@openclaw-barnacle openclaw-barnacle Bot added channel: matrix Channel integration: matrix gateway Gateway runtime size: S and removed size: XS labels Mar 10, 2026
@carrotRakko
Copy link
Copy Markdown
Contributor Author

All three Greptile findings addressed in 70d778f:

  1. Missed test (inbound.test.ts L134): Fixed — assertion changed to .toContain() to handle timestamp prefix. Also fixed the Matrix extension test (handler.body-for-agent.test.ts) which failed in CI for the same reason.

  2. Timezone always UTC: Added timestampOpts?: TimestampInjectionOptions to FinalizeInboundContextOptions. Callers that have config access can now pass timezone-aware options via opts.timestampOpts. Callers without config continue to get UTC (non-breaking).

  3. Stale JSDoc: Updated to reflect that finalizeInboundContext now also calls injectTimestamp.

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 70d778f5d0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/auto-reply/reply/inbound-context.ts Outdated
@delight-ai-agent delight-ai-agent force-pushed the fix/channel-bodyforagent-timestamp branch from 70d778f to 4ba11a2 Compare March 16, 2026 17:20
@aisle-research-bot
Copy link
Copy Markdown

aisle-research-bot Bot commented Mar 16, 2026

🔒 Aisle Security Analysis

We found 2 potential security issue(s) in this PR:

# Severity Title
1 🟡 Medium User-controlled timestamp envelope can spoof/override trusted time context in LLM prompts
2 🔵 Low Timestamp spoofing via bracketed prefix bypassing injectTimestamp idempotency check

1. 🟡 User-controlled timestamp envelope can spoof/override trusted time context in LLM prompts

Property Value
Severity Medium
CWE CWE-345
Location src/gateway/server-methods/agent-timestamp.ts:17-48

Description

finalizeInboundContext() now prepends a timestamp to BodyForAgent via injectTimestamp(). However, injectTimestamp() intentionally skips injection when the message already looks like it has a timestamp envelope.

Because the detection is purely pattern-based on the untrusted message text, an attacker can craft a message starting with a bracketed date/time (or channel-like envelope) to:

  • Prevent insertion of the real, trusted timestamp
  • Make attacker-controlled text appear system/channel-generated, increasing prompt-injection authority
  • Potentially manipulate time-sensitive agent behavior (e.g., “today is …”, daily routines, time-based logic) by supplying a fake timestamp at the start of the message

Vulnerable logic (pattern-based trust of untrusted content):

const TIMESTAMP_ENVELOPE_PATTERN = /^\[.*\d{4}-\d{2}-\d{2} \d{2}:\d{2}/;
...
if (TIMESTAMP_ENVELOPE_PATTERN.test(message)) {
  return message;
}

This becomes more impactful after the change because channel messages now also go through finalizeInboundContext() timestamp injection.

Recommendation

Do not decide whether to inject trusted time context based solely on user-controlled message text.

Safer approaches:

  1. Always inject a trusted timestamp, even if the message already begins with a bracketed date/time. If double-stamping is a concern for channel envelopes, drive idempotency from trusted metadata (e.g., a boolean flag like ctx.HasTrustedEnvelopeTimestamp set by the channel adapter), not regexes over untrusted text.

  2. If you must keep text-based idempotency, make spoofing harder and preserve trusted time by adding an explicit trusted marker:

// Always provide trusted time context in a distinct, non-spoofable way
return `Current time (trusted): ${formatted} ${timezone}\n` + message;
  1. Alternatively, if a bracketed timestamp is present, still inject the trusted timestamp but keep both, clearly labeling the trusted one:
return `[${dow} ${formatted}] (trusted) ${message}`;

Key point: ensure the model always receives a clearly trusted timestamp that the user cannot suppress or convincingly spoof.


2. 🔵 Timestamp spoofing via bracketed prefix bypassing injectTimestamp idempotency check

Property Value
Severity Low
CWE CWE-345
Location src/auto-reply/reply/inbound-context.ts:79-89

Description

finalizeInboundContext now injects a timestamp prefix into BodyForAgent for all inbound contexts. However, injectTimestamp will skip injection whenever the message already begins with any bracketed text containing a YYYY-MM-DD HH:MM substring.

This creates a trust-boundary confusion / spoofing issue:

  • Input (attacker-controlled): BodyForAgent commonly comes from the raw inbound user message (e.g., Discord/Telegram/LINE message text).
  • Bypass: an attacker can start their message with a fake timestamp prefix like [Wed 2099-01-01 00:00 UTC] ....
  • Result: injectTimestamp treats the attacker text as an existing “system” timestamp envelope and returns it unchanged, so the agent sees the attacker-chosen timestamp (or no true timestamp at all).
  • Impact: downstream LLM reasoning may treat the prefix as authoritative time context (scheduling, “today” reasoning, time-based policies/workflows, etc.), enabling time-context manipulation.

Vulnerable flow excerpt:

  • finalizeInboundContext stamps BodyForAgent:
if (normalized.BodyForAgent) {
  const stampOpts = { ...opts.timestampOpts };
  if (normalized.Timestamp) {
    stampOpts.now ??= new Date(normalized.Timestamp);
  }
  normalized.BodyForAgent = injectTimestamp(normalized.BodyForAgent, stampOpts);
}
  • injectTimestamp skips when a leading bracketed timestamp-like string is present:
// Already has an envelope or injected timestamp
if (TIMESTAMP_ENVELOPE_PATTERN.test(message)) {
  return message;
}

where

const TIMESTAMP_ENVELOPE_PATTERN = /^\[.*\d{4}-\d{2}-\d{2} \d{2}:\d{2}/;

Recommendation

Do not treat user text that merely resembles a timestamp envelope as proof that a trusted timestamp is already present.

Safer options:

  1. Use a non-spoofable sentinel/structured field for agent time context (preferred):

    • Provide timestamp via a structured, trusted metadata channel (e.g., a dedicated system block / separate field) rather than embedding it in user text.
  2. If a prefix must be used, make idempotency detection only recognize OpenClaw-generated prefixes (not any bracketed date):

// Example: only skip if the prefix includes an explicit OpenClaw marker.
const OPENCLAW_TS_PREFIX = /^\[OpenClaw time: [A-Za-z]{3} \d{4}-\d{2}-\d{2} \d{2}:\d{2}[^\]]*\] /;

export function injectTimestamp(message: string, opts?: TimestampInjectionOptions): string {
  if (!message.trim()) return message;// Skip only for OpenClaw-generated timestamps (not user-crafted lookalikes)
  if (OPENCLAW_TS_PREFIX.test(message)) return message;

  const now = opts?.now ?? new Date();
  const timezone = opts?.timezone ?? "UTC";
  const formatted = formatZonedTimestamp(now, { timeZone: timezone });
  if (!formatted) return message;

  const dow = new Intl.DateTimeFormat("en-US", { timeZone: timezone, weekday: "short" }).format(now);
  return `[OpenClaw time: ${dow} ${formatted}] ${message}`;
}

If you also need to avoid double-stamping channel envelopes, ensure channel envelope formatting uses the same explicit marker, or carry the timestamp out-of-band instead of relying on textual heuristics.


Analyzed PR: #41802 at commit 48c0dcf

Last updated on: 2026-03-22T14:25:11Z

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ba11a23d0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/auto-reply/reply/inbound-context.ts Outdated
@carrotRakko
Copy link
Copy Markdown
Contributor Author

@aisle-research-bot Thanks for the analysis. The idempotency check in injectTimestamp does rely on text pattern matching against user-controlled input, which is a valid observation.

However, we consider this outside the scope of this PR for the following reasons:

  1. Pre-existing code: The TIMESTAMP_ENVELOPE_PATTERN and CRON_TIME_PATTERN checks are existing logic in injectTimestamp. This PR only adds a new call site — it does not introduce or modify the idempotency mechanism itself.

  2. Low practical impact: The attack surface is a user crafting a message that suppresses their own agent's timestamp injection. This is comparable to other inherent trust boundaries in LLM systems (e.g., user-supplied text that mimics system markers), where the user is effectively "attacking" their own session.

  3. Hardening is a separate concern: Tightening the patterns (bounded header length, anchored cron prefix, etc.) would be a worthwhile improvement to injectTimestamp itself, but is orthogonal to the bug this PR fixes (channel messages missing timestamps in BodyForAgent).

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

@delight-ai-agent delight-ai-agent force-pushed the fix/channel-bodyforagent-timestamp branch from 4ba11a2 to 4ce88d3 Compare March 20, 2026 09:54
@openclaw-barnacle openclaw-barnacle Bot added size: XS and removed channel: matrix Channel integration: matrix size: S labels Mar 20, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ce88d34f5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/auto-reply/reply/inbound-context.ts Outdated
Comment thread src/auto-reply/reply/inbound-context.ts Outdated
Mitsuyuki Osabe added 3 commits March 22, 2026 13:33
Channel messages set `BodyForAgent` to raw text without a timestamp.
Agents prioritize `BodyForAgent` over `Body`, so the envelope timestamp
in `Body` is never seen by the agent. Models whose providers don't
inject date context server-side (e.g. Mistral) hallucinate dates from
their training data cutoff.

`finalizeInboundContext` now calls `injectTimestamp` on `BodyForAgent`
after normalization. This is the shared path that all channels and
extensions pass through — one change covers all built-in channels
(LINE, Telegram, Discord, Slack, Signal, iMessage, WhatsApp) and all
extensions. `injectTimestamp` is idempotent: it skips messages that
already have a timestamp envelope or a cron timestamp.

Closes openclaw#25334

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)
Tests for media understanding (audio/image), Telegram audio transcript,
and Discord button clicks now expect the timestamp prefix in
BodyForAgent, matching the pattern established in inbound.test.ts.

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)
- Add timestampOpts to FinalizeInboundContextOptions so callers with
  config access can pass timezone-aware options to injectTimestamp
- Fix missed test assertion in inbound.test.ts (sanitize spoofed markers)
- Fix Matrix extension BodyForAgent test to handle timestamp prefix
- Update agent-timestamp.ts JSDoc to reflect finalizeInboundContext usage

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)
@delight-ai-agent delight-ai-agent force-pushed the fix/channel-bodyforagent-timestamp branch from 4ce88d3 to 58a27d6 Compare March 22, 2026 13:36
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 58a27d6add

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/auto-reply/reply/inbound-context.ts Outdated
When channel message processing is delayed (slow media/link
understanding), injectTimestamp's new Date() can diverge from the
original message time in ctx.Timestamp. Use the event timestamp
when available; fall back to processing time otherwise.

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)
@steipete
Copy link
Copy Markdown
Contributor

Closing this as implemented after Codex review.

Current main already gives inbound channel turns timestamp context through the structured inbound-metadata prompt path, so this PR's BodyForAgent timestamp injection is redundant against the shipped architecture.

What I checked:

  • Prompt path already prepends inbound metadata: runPreparedReply() prepends buildInboundUserContextPrefix(...) to the user prompt body on every reply path, so timestamp context is supplied before the message body without rewriting BodyForAgent. (src/auto-reply/reply/get-reply-run.ts:389)
  • Inbound metadata includes conversation timestamp: buildInboundUserContextPrefix() includes timestamp: formatConversationTimestamp(ctx.Timestamp, envelope) in the conversation-info block. (src/auto-reply/reply/inbound-meta.ts:194)
  • Timestamp behavior is covered by tests: Current tests assert that the inbound user-context prefix includes a formatted timestamp and honors user timezone settings. (src/auto-reply/reply/inbound-meta.test.ts:370)
  • Channel adapters already populate inbound event timestamps: Representative channel handlers pass event timestamps into the shared context: Telegram msg.date, Slack message.ts, and Discord message.timestamp. (extensions/telegram/src/bot-message-context.session.ts:364)
  • Current architecture prefers structured metadata over plaintext envelopes: The channel runtime types mark plaintext inbound envelopes as deprecated and explicitly prefer BodyForAgent plus structured user-context blocks, which is the path current main uses. (src/plugins/runtime/types-channel.ts:95)
  • Latest release already contains the same prompt-side implementation: The v2026.4.22 release commit already prepends buildInboundUserContextPrefix(...) in get-reply-run.ts, so this behavior is not just on unreleased main. (src/auto-reply/reply/get-reply-run.ts:389, 00bd2cf7a376)

So I’m closing this as already implemented rather than keeping a duplicate issue open.

Review notes: reviewed against bae7b54a85b1; fix evidence: commit 00bd2cf7a376.

@steipete steipete closed this Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord channel: telegram Channel integration: telegram gateway Gateway runtime size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Channel messages lack timestamp in BodyForAgent — models hallucinate dates

2 participants