Skip to content

Pin the HistoryProvider contract and add the context-message opt-in #60

Description

@shibayan

Motivation

External HistoryProvider implementations (file, blob, database) all rest on behaviour that is
currently exercised only through the in-memory provider. Most of the contract already holds; this
issue closes the gaps, adds the one option the reference implementations offer and writes the
contract down for implementers.

Already pinned by tests

  • saveMessages receives only the messages new to that turn — no full-history resend
    (saves history once per run, not once per tool round, does not grow history geometrically,
    never re-saves messages it injected itself).
  • getMessages runs before every other context provider
    (runs in registration order, history first).
  • A failed run reaches afterRun with the error, and the default provider stores nothing for it.

Gaps to close

  1. A mock-provider suite asserting the above as a contract, independent of the in-memory
    implementation, plus getMessages returning oldest-first.
  2. A test pinning that a failed turn stores nothing, so an implementer cannot read "afterRun was
    called" as "store what you have".
  3. TSDoc on HistoryProvider stating the contract: append-only, oldest-first, what is stored by
    default, and the failure semantics.

Opt-in for context-provider messages

What is stored by default differs across the reference implementations:

stored by default
.NET, Go caller input and context-provider injected messages (only history-sourced messages are filtered out)
Python caller input only; store_context_messages opts in
this framework caller input only; no opt-in exists

The Python behaviour is the one to follow: keep the current default, and add the opt-in that is
missing. That needs two things.

  • The messages other context providers injected for the run have to be readable from
    ProviderAfterRunContext; today they live in the run accumulator and never reach afterRun.
  • A history provider option that stores them, defaulting to off. Python also allows narrowing the
    opt-in to named source ids (store_context_from), which is worth matching so a provider can
    persist retrieved documents from one source without persisting everything injected.

This is a public API addition, so the surface change is settled before the contract documentation
promises it.

Acceptance criteria

  • The contract suite above runs against a mock provider.
  • With the opt-in off (the default), injected context messages are not stored; with it on, they
    are, and narrowing by source id selects among them.
  • The documented contract matches what the tests assert.

Metadata

Metadata

Assignees

No one assigned

    Labels

    coreUsage: [Issues, PRs], Target: packages/coredocumentationUsage: [Issues, PRs], Target: documentation changes

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions