Skip to content

feat: add /provider command for mid-session model pinning (experimental) - #267

Merged
Brian Krabach (bkrabach) merged 1 commit into
mainfrom
feat/provider-pin-command-experimental
Aug 13, 2026
Merged

feat: add /provider command for mid-session model pinning (experimental)#267
Brian Krabach (bkrabach) merged 1 commit into
mainfrom
feat/provider-pin-command-experimental

Conversation

@bkrabach

Copy link
Copy Markdown
Collaborator

Summary

Add /provider command for mid-session model pinning within a conversation scope. Marked experimental.

Key changes:

  • New commands: /provider (status), /provider use <name> (pin), /provider auto (unpin)
  • Refuses with clear error message when orchestrator doesn't register conversation.provider_pin capability
  • Persistent [📌 <name>] prompt indicator, properly composed with existing [mode] indicator
  • (experimental) tag on help/status/confirmations; usage-accuracy caveat in status view
  • Fixed a latent bug found during live testing: _create_prompt_session contained a duplicate get_prompt() closure that ignored the pin getter
    • 48 unit tests passed while the feature silently did not work
    • Added wiring tests that actively fail when bug is reintroduced (6 of 11 fail with bug)
    • Deleted duplicate closure; now correctly invokes pin getter at every prompt render
  • Tests: 1372 passing

Verification: Proven end-to-end in DTU with real interactive TUI and real API calls. Prompt indicator renders correctly in all states (unpinned, pinned, pinned+mode). Cross-reference: amplifier-module-loop-streaming (sibling: capability + event), amplifier-module-hooks-streaming-ui (sibling: footer marker).

- New /provider (status), /provider use <name> (pin), /provider auto (unpin)
- Refuses loudly when orchestrator doesn't register capability (never silently fails)
- Persistent [📌 <name>] prompt indicator, composing with existing [mode] indicator
- (experimental) tagging on help/status/confirmations; usage-accuracy caveat in status view
- Fixed latent bug: _create_prompt_session carried duplicate get_prompt closure that ignored pin getter
  * 48 unit tests passed while feature did not work
  * Added wiring tests that fail against broken code (6 of 11 fail when bug reintroduced)
  * Deleted duplicate; now properly invokes pin getter
- Tests: 1372 passing

Verified end-to-end in DTU with real interactive TUI and multi-vendor API calls.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
@bkrabach
Brian Krabach (bkrabach) marked this pull request as ready for review August 13, 2026 08:23
@bkrabach
Brian Krabach (bkrabach) merged commit 55193bb into main Aug 13, 2026
7 checks passed
@bkrabach
Brian Krabach (bkrabach) deleted the feat/provider-pin-command-experimental branch August 13, 2026 08:23
Brian Krabach (bkrabach) pushed a commit that referenced this pull request Aug 13, 2026
…, terse confirmations

Addresses the feedback from testing that the /provider use/auto confirmations
were 320-char paragraphs explaining that the pin 'takes effect on the NEXT
turn' and that users should check the token-usage line to confirm. That copy
compensated for uncertainty that no longer exists — three persistent surfaces
already do the confirming:

• Prompt indicator: [📌 name]> rendered one line down, persistent
• Per-turn footer badge: · 📌 pinned
• /provider status: full scope + usage caveat

The transition line was the least important of four surfaces and by far the
longest. This redesign reduces noise and applies progressive disclosure:

NEW BEHAVIOR (matches Option 4 from the design review):

First /provider use in a session (two lines, taught once):
  📌 pinned: anthropic-fable
     experimental · scope: this conversation only · /provider for details

Every subsequent pin (one line):
  📌 pinned: openai-fast

Already pinned to that provider (one line):
  📌 already pinned: openai-fast

Unpin when something was pinned (one line):
  unpinned (was openai-fast)

Unpin when nothing was pinned (one line):
  not pinned

CHANGES:

1. /provider use: 320 chars / 5 wrapped lines → 25 chars / 1 line (first pin
   also includes 2-line teach block, one time per session).

2. /provider auto: 284 chars / 4 wrapped lines → 26 chars / 1 line.

3. Three design decisions locked in code:

   a) DELIBERATE ASYMMETRY: use is confirmed by a signal APPEARING, auto by
      one DISAPPEARING (weaker evidence). Unpinning destroys the prompt
      indicator, the only other record of what was pinned. The (was X)
      clause is the single genuinely non-redundant fact in either message.
      Locked by a test with the reason documented.

   b) FORWARD-LOOKING TENSE IS BANNED: every string is past-tense or
      state-descriptive ('pinned', 'unpinned', 'already pinned', 'not pinned')
      — each one true at the instant it prints, because it describes what
      the system was TOLD, not what a model DID. Removed 'takes effect on
      NEXT turn' entirely rather than rewording it. Enforced by runtime
      sweeps and AST checks on the string constants.

   c) NO-OP HONESTY: /provider auto with nothing pinned previously printed
      'unpinned' (untrue), re-pinning an already-pinned provider printed a
      fresh 'pinned' (untrue). Both were plausible-but-false confirmations —
      exactly the failure class this feature exists to prevent. They now
      report 'not pinned' and 'already pinned: X'. The already-pinned path
      still calls pin() so an unmounted provider surfaces its loud error
      instead of a false confirmation.

4. Messages render dim (color carries weight, reads as a receipt not content).
   Provider names are markup-escaped so '[' can't open a style tag.

TESTS: 83 passed (was 71). Full suite: 1384 passed, 1 skipped, 13
deselected, 1 xfailed. All five states verified end-to-end in a real TUI
session; teach line correctly appears once per session; no old verbose text;
no de-emphasis attribute capture (pyte limitation) but luminance difference
measured at ~63% of normal (technically correct, visually dim).

Fixes follow-up to PR #267.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Brian Krabach (bkrabach) added a commit that referenced this pull request Aug 13, 2026
…, terse confirmations (#268)

Addresses the feedback from testing that the /provider use/auto confirmations
were 320-char paragraphs explaining that the pin 'takes effect on the NEXT
turn' and that users should check the token-usage line to confirm. That copy
compensated for uncertainty that no longer exists — three persistent surfaces
already do the confirming:

• Prompt indicator: [📌 name]> rendered one line down, persistent
• Per-turn footer badge: · 📌 pinned
• /provider status: full scope + usage caveat

The transition line was the least important of four surfaces and by far the
longest. This redesign reduces noise and applies progressive disclosure:

NEW BEHAVIOR (matches Option 4 from the design review):

First /provider use in a session (two lines, taught once):
  📌 pinned: anthropic-fable
     experimental · scope: this conversation only · /provider for details

Every subsequent pin (one line):
  📌 pinned: openai-fast

Already pinned to that provider (one line):
  📌 already pinned: openai-fast

Unpin when something was pinned (one line):
  unpinned (was openai-fast)

Unpin when nothing was pinned (one line):
  not pinned

CHANGES:

1. /provider use: 320 chars / 5 wrapped lines → 25 chars / 1 line (first pin
   also includes 2-line teach block, one time per session).

2. /provider auto: 284 chars / 4 wrapped lines → 26 chars / 1 line.

3. Three design decisions locked in code:

   a) DELIBERATE ASYMMETRY: use is confirmed by a signal APPEARING, auto by
      one DISAPPEARING (weaker evidence). Unpinning destroys the prompt
      indicator, the only other record of what was pinned. The (was X)
      clause is the single genuinely non-redundant fact in either message.
      Locked by a test with the reason documented.

   b) FORWARD-LOOKING TENSE IS BANNED: every string is past-tense or
      state-descriptive ('pinned', 'unpinned', 'already pinned', 'not pinned')
      — each one true at the instant it prints, because it describes what
      the system was TOLD, not what a model DID. Removed 'takes effect on
      NEXT turn' entirely rather than rewording it. Enforced by runtime
      sweeps and AST checks on the string constants.

   c) NO-OP HONESTY: /provider auto with nothing pinned previously printed
      'unpinned' (untrue), re-pinning an already-pinned provider printed a
      fresh 'pinned' (untrue). Both were plausible-but-false confirmations —
      exactly the failure class this feature exists to prevent. They now
      report 'not pinned' and 'already pinned: X'. The already-pinned path
      still calls pin() so an unmounted provider surfaces its loud error
      instead of a false confirmation.

4. Messages render dim (color carries weight, reads as a receipt not content).
   Provider names are markup-escaped so '[' can't open a style tag.

TESTS: 83 passed (was 71). Full suite: 1384 passed, 1 skipped, 13
deselected, 1 xfailed. All five states verified end-to-end in a real TUI
session; teach line correctly appears once per session; no old verbose text;
no de-emphasis attribute capture (pyte limitation) but luminance difference
measured at ~63% of normal (technically correct, visually dim).

Fixes follow-up to PR #267.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-authored-by: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Brian Krabach (bkrabach) added a commit that referenced this pull request Aug 13, 2026
Adds comprehensive user-facing documentation for the experimental /provider
model-pinning feature, covering:

- Mental model: each provider entry combines one account + one model
- Worked example with two real Anthropic accounts and four models
- Configuration, naming guidance, and default precedence via priority
- Interactive usage: /provider, /provider use <name>, /provider auto
- Limits: same-vendor only, session-only, top-level-only, orchestrator-dependent
- Comparison table for three related but distinct 'provider' surfaces

All instructions verified against live container with two real Anthropic accounts.

Closes #267 and #268.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-authored-by: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
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.

2 participants