Skip to content

feat: move dynamic context (datetime/location) from system message to trailing message - #9544

Open
SiAgentBuild wants to merge 2 commits into
agno-agi:mainfrom
SiAgentBuild:feat/dynamic-context-trailing-message
Open

SiAgentBuild wants to merge 2 commits into
agno-agi:mainfrom
SiAgentBuild:feat/dynamic-context-trailing-message

Conversation

@SiAgentBuild

Copy link
Copy Markdown
Contributor

Summary

Move add_datetime_to_context and add_location_to_context output from the system message to a separate trailing message appended after history and before the user message. This fixes two issues:

  1. Dynamic context was silently dropped when a custom system_message was set. get_system_message() returns early on the custom system_message branch, skipping the entire <additional_information> block. Users who set both system_message and add_datetime_to_context=True got no time info and no warning.

  2. Dynamic values in the system message broke prompt caching. Prompt caching (Anthropic, OpenAI) matches tokens from the first position forward. Embedding The current time is 2026-08-13 14:22:47.774825+08:00 (microsecond precision by default) in the system message guaranteed a full cache miss on every request, causing the entire system prompt to be re-processed at full cost.

By appending the dynamic context as a separate message near the end of the messages list, the system message and history stay byte-identical across requests, preserving prompt cache hits. The dynamic context also works identically whether or not a custom system_message is set.

Applied to both Agent and Team, sync and async paths.

Closes #9543

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Improvement
  • Model update
  • Other:

Checklist

  • Code complies with style guidelines
  • Ran format/validation scripts (./scripts/format.sh and ./scripts/validate.sh)
  • Self-review completed
  • Documentation updated (comments, docstrings)
  • Examples and guides: Relevant cookbook examples have been included or updated (if applicable)
  • Tested in clean environment
  • Tests added/updated (if applicable)

Duplicate and AI-Generated PR Check

  • I have searched existing open pull requests and confirmed that no other PR already addresses this issue
  • If a similar PR exists, I have explained below why this PR is a better approach

Additional Notes

What changed:

  • agno/agent/_messages.py: Removed datetime/location from get_system_message()'s additional_information. Added _get_dynamic_context_message() that builds a standalone Message(role="system", ...). Injected it in get_run_messages() between history and user message (both sync and async paths).
  • agno/team/_messages.py: Same changes for Team.
  • tests/unit/agent/test_datetime_format.py + tests/unit/team/test_datetime_format.py: Updated tests to target _get_dynamic_context_message() instead of get_system_message(). Added test_datetime_not_in_system_message and test_timezone_identifier.

What did NOT change:

  • The flags themselves (add_datetime_to_context, add_location_to_context, timezone_identifier, datetime_format) — same API, same defaults.
  • The content format (The current time is ..., Your approximate location is ...) — unchanged.
  • add_name_to_context — remains in the system message, as the agent name is persona-level info that doesn't change per turn.

@SiAgentBuild
SiAgentBuild requested a review from a team as a code owner August 13, 2026 06:57
@greptile-apps

greptile-apps Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR moves dynamic datetime and location context out of the stable system prompt and into a per-run trailing message for both Agent and Team execution.

  • Adds shared-style dynamic-context builders for Agent and Team.
  • Injects generated context after history in synchronous and asynchronous paths.
  • Updates datetime-format and timezone tests for the new message construction.

Confidence Score: 3/5

The PR is not safe to merge until dynamic context preserves the primary system prompt across adapters and is excluded from persisted history.

The second system message replaces the primary prompt in multiple supported adapters, while its default persistence settings also feed stale per-turn context into subsequent runs.

Files Needing Attention: libs/agno/agno/agent/_messages.py and libs/agno/agno/team/_messages.py

Important Files Changed

Filename Overview
libs/agno/agno/agent/_messages.py Relocates Agent dynamic context into a second persisted system message, exposing adapter overwrite and stale-history behavior.
libs/agno/agno/team/_messages.py Mirrors the Agent implementation and therefore has the same provider compatibility and persistence defects.
libs/agno/tests/unit/agent/test_datetime_format.py Updates helper-level datetime tests but does not exercise full message serialization or multi-turn persistence.
libs/agno/tests/unit/team/test_datetime_format.py Updates Team helper tests but does not cover adapter handling or persisted history.

Sequence Diagram

sequenceDiagram
  participant Run as Agent/Team run
  participant History as Session history
  participant Builder as Dynamic context builder
  participant Adapter as Model adapter
  Run->>History: Load prior messages
  History-->>Run: System prompt and conversation history
  Run->>Builder: Generate current datetime/location
  Builder-->>Run: Second system-role message
  Run->>Adapter: Send ordered message list
  Note over Adapter: Last-system-only adapters replace the primary prompt
  Adapter-->>Run: Model response
  Run->>History: "Persist messages with add_to_agent_memory=True"
  Note over History: Dynamic context is retained for later turns
Loading

Reviews (1): Last reviewed commit: "feat: move dynamic context (datetime/loc..." | Re-trigger Greptile

Comment thread libs/agno/agno/agent/_messages.py Outdated
if not parts:
return None

return Message(role="system", content="\n".join(parts))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Trailing system message replaces prompt

When datetime or location context is enabled with Google Gemini, Gemini Interactions, or AWS Bedrock, this second system message becomes the adapter's retained system value, replacing the Agent or Team's primary prompt and causing the model to lose its configured instructions and behavioral guidance.

Comment thread libs/agno/agno/agent/_messages.py Outdated
if not parts:
return None

return Message(role="system", content="\n".join(parts))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Dynamic context persists into history

When a persisted Agent or Team session runs multiple turns with dynamic context enabled, this message retains the default add_to_agent_memory=True, so stale datetime or location statements are loaded as history alongside the newly generated values and are exposed through session-message consumers.

SiAgentBuild added a commit to SiAgentBuild/agno that referenced this pull request Aug 13, 2026
Address review feedback on agno-agi#9544:

1. Change role from system to user — adapters like Gemini and Bedrock
   extract the last system message as the primary prompt, which would
   overwrite the agent's configured instructions. Using role=user keeps
   the dynamic context in the message flow without affecting the system
   prompt.

2. Set add_to_agent_memory=False — prevents stale per-turn datetime and
   location values from being persisted and loaded as history in
   subsequent runs.
@SiAgentBuild

Copy link
Copy Markdown
Contributor Author

Both issues addressed in ce31d45:

  1. Trailing system message replaces prompt — Changed role from system to user so adapters (Gemini, Bedrock) that extract system messages won't overwrite the primary system prompt.

  2. Dynamic context persists into history — Set add_to_agent_memory=False so stale per-turn values are not persisted or loaded in subsequent runs.

Tests updated accordingly. All 1061 agent/team unit tests pass, format/validate clean.

… trailing message

Move add_datetime_to_context and add_location_to_context output from the
system message to a separate message appended after history and before the
user message. This fixes two issues:

1. Dynamic context was silently dropped when a custom system_message was set,
   because get_system_message() returns early on that branch.
2. Dynamic values embedded in the system message broke prompt caching on
   every request, since cache matching works from the first token forward.

Applied to both Agent and Team, sync and async paths.

Closes agno-agi#9543
Address review feedback on agno-agi#9544:

1. Change role from system to user — adapters like Gemini and Bedrock
   extract the last system message as the primary prompt, which would
   overwrite the agent's configured instructions. Using role=user keeps
   the dynamic context in the message flow without affecting the system
   prompt.

2. Set add_to_agent_memory=False — prevents stale per-turn datetime and
   location values from being persisted and loaded as history in
   subsequent runs.
@SiAgentBuild
SiAgentBuild force-pushed the feat/dynamic-context-trailing-message branch from 32d8ee9 to c06358a Compare August 25, 2026 08:12
@SiAgentBuild

Copy link
Copy Markdown
Contributor Author

Hi @kausmeows @ysolanky — rebased onto v3.0.0 and resolved the conflict in agent/_messages.py (kept both v3's _resolve_media_storage and the new _get_dynamic_context_message).

Also verified on v3 that add_to_agent_memory=False still excludes the message from persistence, so stale per-turn datetime/location values don't leak into later runs via history.

Agent/team unit suites pass (1453 tests). Ready for review, thanks!

This branch has not been deployed

No deployments
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.

[Feature Request] Append dynamic context (datetime/location) as trailing message instead of embedding in system message

1 participant