Skip to content

Conversation

@tlongwell-block
Copy link
Collaborator

@tlongwell-block tlongwell-block commented Oct 6, 2025

Implements ephemeral context injection at the agent boundary to automatically include timestamp and TODO content in LLM context without modifying conversation history.

Problem

Previously, accessing TODO content required explicit todo__read tool calls, cluttering conversation history and consuming tokens. Timestamps were injected via template variables in system prompts, creating inconsistency across different prompt variants and preventing effective prompt caching.

Solution

MOIM (Minus One Info Message) injects contextual information directly into the recent context during agent message preparation. This injection contains:

  • Current timestamp (always)
  • TODO content from session metadata (when available)
  • Any other extension-provided context via the get_moim() trait method

The injection happens in agent.rs at the message preparation stage, ensuring the context is included in the LLM call but never persisted to storage or returned in conversation history.

Architecture Benefits

  • Zero changes to core data structures (Message, Conversation)
  • No persistence layer modifications
  • Clean extension boundaries via the get_moim() trait method
  • No impact on existing sessions or conversation replay
  • Extensions can opt-in to MOIM by implementing the trait method

Implementation Details

  • ExtensionManager::collect_moim() aggregates MOIM content from all active extensions
  • moim::inject_moim() injects collected MOIM into context
  • TODO extension implements get_moim() to provide task content
  • Timestamp injection moved from template variables to MOIM system

Testing

Comprehensive test coverage in crates/goose/tests/moim_tests.rs with proper test isolation using serial_test for tests that modify environment variables.

Migration

  • Removed todo__read tool (breaking change for recipes using it)
  • Updated todo__write description to reflect automatic availability
  • System prompts now receive timestamp via MOIM instead of template variables
  • Removed {{current_date_time}} template variable from system prompts

User Impact

  • TODO content is now automatically available in context after writing
  • No need to explicitly read TODO content, reducing token usage
  • Cleaner conversation history without repetitive read operations
  • Consistent timestamp availability across all prompt variants

@tlongwell-block tlongwell-block marked this pull request as ready for review October 6, 2025 16:58
Copy link
Collaborator

@DOsinga DOsinga left a comment

Choose a reason for hiding this comment

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

This looks very promising. I'll have another look later, but meanwhile:

  • I think you shouldn't bother with finding an insertion point. you are doing this just before sending it to the provider which means that if you make a mistake we'll get a catastrophic error. I think you want to prefix this to the user message just after:

if let Some(session_config) = &session {

block. that way it doesn't go to the storage, but you also don't change the structure of the conversation. you probably don't need a moim.rs then either

  • I don't think we want a setting for this unless we also have that in the UI and you don't want that. we should not switch this off in the scenario tests as you do right now, we should rerun those and make sure everything is still working

  • can you remove the LLM comments that don't add anything and cut any tests that don't really test anything

@tlongwell-block
Copy link
Collaborator Author

  • I think you shouldn't bother with finding an insertion point. you are doing this just before sending it to the provider which means that if you make a mistake we'll get a catastrophic error. I think you want to prefix this to the user message just after:

if let Some(session_config) = &session {

block. that way it doesn't go to the storage, but you also don't change the structure of the conversation. you probably don't need a moim.rs then either

Unfortunately, counting on the user message would make this useless for recipes. Long-context independent work is where Goose needs this feature the most

@michaelneale
Copy link
Collaborator

if this is adjusting the system message each time - doesn't that mean that there is no prompt caching? (as right at the start the content diverges?) - or do I misunderstand?

@DOsinga
Copy link
Collaborator

DOsinga commented Oct 7, 2025

if this is adjusting the system message each time - doesn't that mean that there is no prompt caching? (as right at the start the content diverges?) - or do I misunderstand?

instead of doing that, it is trying to add a synthetic message to the conversation with changeable info towards the bottom of the conversation.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 8, 2025

PR Preview Action v1.6.0

🚀 View preview at
https://block.github.io/goose/pr-preview/pr-5027/

Built to branch gh-pages at 2025-10-08 13:45 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

* origin/main:
  Art vandelay: Import & Export (#5053)
  docs: misc updates for extensions directory (#5035)
  updating recipe scanner workflows for detecting recipes from forked repos (#5056)
  feat(prompt-library): add Smart Meeting Assistant advanced prompt (#4998) (#5031)
  Allow auto focus and typing while chat is initializing (#5043)
  docs(blog): Add blog for running Goose in containerized envs  (#5052)
* origin/main:
  Improve Rust analysis output for `analyze` tool (#5072)
  Remove duplicate prepare_reply_context call (#5063)
  install react dev tools in development (#4979)
  Doc: Added powershell installation link to the guide (#5012)
  draft of new blog post about automating more automation (#5038)
  Subagent extension selection behavior fix (#5093)
  Add dev and alpha environment indicator (#5092)
  docs: add content carousel (#5086)
  Applied server side call to parse and save recipe (#5022)
  feat(prompt-library): add Code Documentation Migrator intermediate prompt (#4996) (#5051)
  Add Messy Column Fixer recipe (#5062)
  Cleanup temp files (#5081)
  add openmetadata recipe (#5076)
  Fix Hacktoberfest Leaderboard (#5080)
  adding brand guidelines to AGENTS.md (#4887)
  Fix: Prevent cross-contamination of cache data across analysis modes for `analyze` tool (#5075)
  fix: remove circular reference (#5018)
  Introduced a new prompt for content amplification that integrates multi-step workflows using official Goose extensions. Closes Issue #4998 (#5050)
  Add hint for focus mode when used on file paths for `analyze` tool (#5069)
  fix: use dynamic port allocation for OAuth server (#5019)
@tlongwell-block
Copy link
Collaborator Author

@DOsinga can you take a look again? Think I hit your changes

Though, through benchmarking, I found I had to make the message positioning slightly more complicated again in order to get the best results. But just a little

@blackgirlbytes
Copy link
Contributor

hmm, wondering why my team got tagged in this. i dont see any docs changes

…mments, and add JSON schema for todo_write tool
* origin/main: (34 commits)
  Remove some logging (#5631)
  Use session IDs as task IDs for subagents instead of UUIDs (#5398)
  Fix the naming (#5628)
  fix: default tetrate model is broken, replace with haiku-4.5 (#5535) (#5587)
  Fetch less and use the right SHA (#5621)
  feat(ui): add custom macOS dock menu with New Window option (#5099)
  feat: remove hints from recipe prompts (#5622)
  docs: October 2025 Community All-Stars spotlight, Hacktoberfest edition (#5625)
  differentiate debug/release in cache key (#5613)
  Unify subrecipe and subagent execution through shared recipe pipeline (#5082)
  Standardize CLI argument flags and update documentation (#5516)
  Release 1.13.0
  fix: move goosehints/AGENTS.md handling to goose, and out of developer extension (#5575)
  fix: add standard context menu items to prevent empty right-click menu (#5616)
  Bump openapi in prepare-release (#5611)
  docs: add access control section to Developer tutorial (#5615)
  Token state not showing on load, or after message is finished. (#5606)
  Change the other location too (#5608)
  feat(ui): bring back quick launcher (#5144)
  Support platform tools through CLI (#5570)
  ...
}

let conversation_with_moim = super::moim::inject_moim(
conversation.clone(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

this replaces conversation, so I don't think we need to clone here

use chrono::Local;

let timestamp = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
let mut content = format!("<info-msg>\nDatetime: {}\n", timestamp);
Copy link
Collaborator

Choose a reason for hiding this comment

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

a list with join would be more memory effiicient

@michaelneale
Copy link
Collaborator

I think worth pushing on this as I expect it could help performance a lot and also (I expect) gain more with actual prompt caching.

@tlongwell-block
Copy link
Collaborator Author

I think worth pushing on this as I expect it could help performance a lot and also (I expect) gain more with actual prompt caching.

Going to work hard on ensuring safety of this today before merging in and following up on @DOsinga's review. Will try to get it in today

* origin/main: (51 commits)
  Compaction resiliency improvements (#5618)
  docs: ask goose button (#5730)
  Update prompt injection detection metrics (due to errors exporting to datadog) (#5692)
  Spence/icon2 tokyo drift (#5728)
  docs: logs rotation and misc updates (#5727)
  docs: automatic ollama model detection (#5725)
  Fix context progress bar not resetting after /clear command (#5652)
  docs: removing double announcements (#5714)
  docs: mcp sampling support (#5708)
  hackathon banner  (#5710)
  Fix documentation-only change detection for push events (#5712)
  Added transaction commits to multi sql functions in session_manager (#5693)
  fix: improve and simplify tool call chain rendering (#5704)
  Fix: Always show autocompact threshold ui (#5701)
  chore: Update governance to include Discord (#5690)
  Ollama improvements (#5609)
  feat: add Supabase MCP server to registry (#5629)
  Unlist VS Code extension tutorials from MCP and experimental sections (#5677)
  fix: make image processing work in github copilot provider (#5687)
  fix: do not take into account gitignore in developer mcp (#5688)
  ...
…plify todo get_moim. Add tool call/response test for moim. Remove local chrono import.
@tlongwell-block tlongwell-block merged commit 02ca6f7 into main Nov 16, 2025
19 of 20 checks passed
michaelneale added a commit that referenced this pull request Nov 17, 2025
* main:
  scan recipe for security when saving recipe (#5747)
  feat: trying grok for live test (#5732)
  Platform Extension MOIM (Minus One Info Message) (#5027)
  docs: remove hackathon banner (#5756)
  Fix: Recipes respect the quiet flag (#5743)
  docs: update cli commands (#5744)
  Run smoke tests on a free runner (#5745)
  faster, cheaper (pick two): improve CI workflow and switch to free github runner (#5702)
  Compaction resiliency improvements (#5618)
  docs: ask goose button (#5730)
  Update prompt injection detection metrics (due to errors exporting to datadog) (#5692)
  Spence/icon2 tokyo drift (#5728)
  docs: logs rotation and misc updates (#5727)
  docs: automatic ollama model detection (#5725)
  Fix context progress bar not resetting after /clear command (#5652)
  docs: removing double announcements (#5714)
  docs: mcp sampling support (#5708)
Surendhar-N-D pushed a commit to Surendhar-N-D/goose that referenced this pull request Nov 17, 2025
arul-cc pushed a commit to arul-cc/goose that referenced this pull request Nov 17, 2025
aharvard added a commit that referenced this pull request Nov 18, 2025
* origin/main: (60 commits)
  chore: incorporate LF feedback (#5787)
  docs: quick launcher (#5779)
  Bump auto scroll threshold (#5738)
  fix: add one-time cleanup for linux hermit locking issues (#5742)
  Don't show update tray icon if GOOSE_VERSION is set (#5750)
  fix: get win node path from registry (#5731)
  Handle spaces in extension names also (#5770)
  Remove empty settings card for Scheduling Engine (#5771)
  fix windows cli build (#5768)
  fix: Implement a CredentialStore for auth (#5741)
  blog post: How to Successfully Migrate Your App with an AI Agent (#5762)
  Simplify finding `goosed` (#5739)
  More time for goosed (#5746)
  Match lower case (#5763)
  scan recipe for security when saving recipe (#5747)
  feat: trying grok for live test (#5732)
  Platform Extension MOIM (Minus One Info Message) (#5027)
  docs: remove hackathon banner (#5756)
  Fix: Recipes respect the quiet flag (#5743)
  docs: update cli commands (#5744)
  ...
katzdave added a commit that referenced this pull request Nov 18, 2025
* 'main' of github.com:block/goose: (125 commits)
  Document Mistral AI provider (#5799)
  docs: Add Community Stars recipe script and txt file (#5776)
  chore: incorporate LF feedback (#5787)
  docs: quick launcher (#5779)
  Bump auto scroll threshold (#5738)
  fix: add one-time cleanup for linux hermit locking issues (#5742)
  Don't show update tray icon if GOOSE_VERSION is set (#5750)
  fix: get win node path from registry (#5731)
  Handle spaces in extension names also (#5770)
  Remove empty settings card for Scheduling Engine (#5771)
  fix windows cli build (#5768)
  fix: Implement a CredentialStore for auth (#5741)
  blog post: How to Successfully Migrate Your App with an AI Agent (#5762)
  Simplify finding `goosed` (#5739)
  More time for goosed (#5746)
  Match lower case (#5763)
  scan recipe for security when saving recipe (#5747)
  feat: trying grok for live test (#5732)
  Platform Extension MOIM (Minus One Info Message) (#5027)
  docs: remove hackathon banner (#5756)
  ...
BlairAllan pushed a commit to BlairAllan/goose that referenced this pull request Nov 29, 2025
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.

5 participants