feat(commentary): introduce universal rafters-critic for scenario commentary and cadence control
agharsallah
f637227
feat(media): introduce MediaRouter and stubs for image and speech generation
agharsallah
8400d8c
- Implement MediaRouter to resolve media capabilities to providers, supporting both live and offline modes.
- Add StubImageProvider and StubSpeechProvider for deterministic offline media generation.
- Create tools for image rendering and text-to-speech synthesis, integrating with the ToolRegistry.
- Enhance the commentator (rafters-critic) to generate and render media alongside commentary.
- Update UI components to display generated images and audio clips in the feed.
- Ensure tests cover the new media capabilities, including deterministic outputs and capability enforcement.
feat: Update model references to MiniCPM5 and adjust related documentation and tests for transformers 5.x compatibility
agharsallah
cc8e9f2
Refactor local provider to support on-device loading with accelerate
agharsallah
3bcd1af
- Updated the local provider to implement a two-phase loading mechanism for models, separating the download of weights in the parent process from the loading onto the GPU in the worker process.
- Introduced a new function `_ensure_downloaded` to fetch model weights to the on-disk cache without initializing CUDA.
- Replaced the previous loading mechanism with `_ensure_loaded_on_device`, which directly loads models onto the GPU using the `device_map` parameter, ensuring all weights are materialized on the device.
- Updated tests to reflect changes in loading behavior and ensure compliance with ZeroGPU constraints.
- Added `accelerate` as a new dependency in `pyproject.toml` to facilitate the new loading approach.
feat: Add use_cache parameter to support KV cache handling in models and update tests
agharsallah
169b620
Refactor local model configurations and update tests
agharsallah
572f5aa
- Updated local model configurations to use Nemotron-Mini-4B-Instruct instead of NVIDIA-Nemotron-3-Nano-4B-BF16.
- Adjusted tests to reflect changes in model keys and trust_remote_code settings.
- Removed auto_class attribute from LocalModel as it is no longer necessary.
- Implemented compatibility shims for removed predicates in transformers 5.x to ensure backward compatibility with remote code imports.
- Enhanced test coverage for the new compatibility shims and ensured all tests pass.
feat: Update model routing and local provider to support multi-sponsor tiers and auto-class resolution
agharsallah
7a13e4e
feat: Ensure full materialization of model weights to prevent meta tensor issues in ZeroGPU
agharsallah
97f641c
fix: Ensure proper unpacking of BatchEncoding in model generation to prevent AttributeError
agharsallah
0dfc318
feat: Replace llama.cpp backend with in-process transformers backend for local GPU inference
agharsallah
7d636f8
Implement local in-process inference backend for transformers models
agharsallah
c6cdf25
- Introduced `local_catalogue.py` to define small transformers models served in-process on the host's GPU.
- Added `local_provider.py` to handle the in-process model serving logic, including model loading and generation.
- Updated `router.py` to support routing to the new local backend, allowing for in-process execution without HTTP endpoints.
- Created `test_local_backend.py` to cover tests for the local backend, including catalogue validation, capability gating, and router dispatch.
- Removed `test_llamacpp_backend.py` as it is no longer relevant with the introduction of the local backend.
- Adjusted existing tests to ensure compatibility with the new local backend structure.
feat: Implement llama.cpp backend for local inference with GGUF models
agharsallah
0f11b49
Merge remote-tracking branch 'origin/main' into worktree-scenarios
feat: make every scenario arena-grade with a competition contract
agharsallah+1: Codex
0d0c561
Add a validated `competition` block (versus|judged|none) to scenarios,
stamped onto run.started so runs are self-describing and winners attribute
to models. Winners become data, not prose: judges emit a `winner` field
that the reusable JudgedCompetition handler validates against the live cast
(repairing deterministically so the offline stub always names a real
player); ground-truth judges (SpyHost, SproutJudge) decide in code.
Audit the five existing scenarios (The Steeped versus+teams with code-scored
winner; Mystery Roots judged; Open Table gains a table-judge; Thousand Token
Wood and Oracle Grove marked none) and add three competitive scenarios:
Debate Duel and Beat Battle (symmetric seats, different models) and Twenty
Sprouts (code-dealt secret word, deterministic win).
Surface a winner ribbon in the verdict banner only when a winner exists, so
none-kind and legacy runs render byte-identically. Enforce the authoring
checklist in tests/test_scenario_contract.py and document the co…
feat: Implement well-known typed fields for verdicts in output models
agharsallah
ce159dc
- Introduced `_well_known_specs` function to define typed fields for `winner` and `scores` in agent output.
- Updated `build_output_model` to handle new field types, allowing `winner` to be optional and `scores` to default to an empty map.
- Enhanced `json_instruction` to provide specific hints for well-known fields in the output format.
- Modified `FishbowlSession` to derive `winner_kind` and `winning_models` based on verdicts, supporting team-based outcomes.
- Added validation tests for new competition configurations and verdict handling, ensuring proper behavior for both agent and team winners.
- Created comprehensive tests for the new verdict validation logic, including re-ask scenarios and score normalization.
feat: implement per-event model attribution for enhanced event tracking
agharsallah
a71301e
feat: update agent personas and scheduling in YAML configurations; enhance event handling and memory deduplication in core logic
agharsallah
27b304e
feat: update HF model catalogue to prioritize chat-capable model and adjust tests for new routing logic
agharsallah
66f0e23
feat: require live infrastructure for event store and inference, removing offline mode
Wire the observability facade through the load-bearing layers:
- models: llm.call/llm.structured spans with GenAI attrs, token/cost metrics,
full prompt+response captured at DEBUG (litellm, stub, openai-compat, router).
- conductor+governor: run/turn/agent.turn spans, run/turn/agent context binding,
event-append logs, agent-turn latency, governor budget-trip metrics+logs.
- memory: memory.recall + memory.index.search spans; DEBUG-logs the EXACT
salience-ranked memory text (with scores) each agent receives; index hit/latency
metrics and keyword-fallback logging; context.build structure logging.
- ledger/events/projections: per-append log+counter, projection.apply, invalid-kind.
Note: litellm_provider.py carries some pre-existing in-progress changes that ride
along with the instrumentation on this feature branch.
Co-Authored-By: Codex <codex@openai.com>
refactor: tidy HF backend per /simplify review
agharsallah
1f581d5
- inference.backend_available dispatches via each backend's catalogue
has_credentials() — no per-backend name branches; adding a backend to
_BACKENDS now works here for free. modal_catalogue gains has_credentials()
to match hf_catalogue (symmetric contract).
- inference.backend_label() is the single source of backend display names;
the Lab cast render and the topbar chip use it (drop app.py's hardcoded map).
- hf_catalogue builds its entries + by-key index once at import; entries()/
entry_by_key() no longer rebuild the list per call.
- lab._resolve_scenario() centralises the "title or name" lookup repeated
across the cast render, judge/cast re-seed, and collect_world_config.
feat: add Hugging Face inference backend next to Modal
agharsallah
45917c7
Introduce a second, serverless inference backend (Hugging Face Inference
Providers) alongside the self-hosted Modal vLLM endpoints, and surface the
choice in the Fishbowl Lab.
- src/models/hf_catalogue.py: stdlib-only, offline-safe catalogue of small
instruct models (tiny<=4B .. strong<=32B); binding_for yields the same
LiteLLM custom-endpoint form, so the existing transport calls it unchanged.
- src/models/inference.py: one facade unifying Modal + HF behind
entries/binding_for/default_key_for_profile/backend_available. Models are
named by backend-qualified keys ("hf:<repo>"); a bare key means Modal, so
all existing keys/config/tests are untouched.
- router, registry endpoint: expansion, and has_live_credentials now read the
facade (live = any backend configured).
- Fishbowl Lab gains a headline "00 - Inference backend" radio (Modal vs HF)
driving the cast/judge pickers; the topbar chip names the live backend(s).
A composed run forces live on the chosen backend when it…
feat: implement streaming agent responses and enhance conversation flow with repeat guards
agharsallah
0b0d9be
feat(core): add resilient loop and shared blackboard
agharsallah+1: Codex
ba6dd5f
Improve conversation stability and privacy across live scenarios by sharing spoken context, isolating per-agent failures, and hardening structured output parsing.
- Inject a shared WHAT'S BEEN SAID blackboard into agent context
- Continue turns when one agent fails while preserving budget-stop semantics
- Prevent secret leakage in scenario seed/memory rendering
- Harden JSON parsing and salvage logic for reasoning model outputs
- Tune model token budgets and diversify spy cast model tiers
- Add ADR-0023 plus regression tests for context, memory, parsing, and spy flow
Co-authored-by: Codex <codex@openai.com>
feat: Enhance model routing and deployment flexibility
agharsallah
c1656a8
- Introduced `vllm_version` to allow per-model inference stack pinning, enabling models to opt for nightly builds when necessary.
- Updated image building logic to handle model-specific vLLM versions, ensuring compatibility with various architectures.
- Added `model_endpoint` to `AgentManifest` for explicit model binding, allowing agents to route to specific models instead of relying solely on profiles.
- Enhanced `ModelRouter` to resolve specific catalogue models, improving routing accuracy and flexibility.
- Updated UI components in the Fishbowl Lab to support new model selection features, ensuring only deployable models are presented.
- Improved tests to validate new model selection and routing behaviors, ensuring robustness and adherence to expected functionality.
Merge branch 'feat/live-open-table' into feat/live-integration
agharsallah
0a10ebd
# Conflicts:
# src/models/provider.py
feat: add Open Table live-chat scenario (curious/skeptic/host)
agharsallah+1: Codex
01bc5cd
A minimal, live-ready 2-3 agent conversation so the back-and-forth is simple
and obvious: a curious voice, a gently skeptical voice, and a host who nudges
the topic forward every few turns. Staggered ticks (1/1/3) read as real
turn-taking. Coherent offline via curated stub lines + private monologues;
genuinely improvised live (per-agent persona, MODAL_WORKSPACE).
Auto-discovered by the registry — appears in the Lab with no app.py edits.
Co-Authored-By: Codex <codex@openai.com>
Wire the prototype's flagship social-deduction scenario into the live engine,
config-only (no engine edits). Four minds get a secret word — the herd shares
COFFEE, a lone spy holds TEA — and bluff with clues while the mind-reader watches
the spy hide; a host unmasks the seam.
- config/agents/spy-{cara,bex,nil,ovo}.yaml: players emit agent.spoke with the
say-vs-think split; the secret word rides each persona so it never leaks.
- config/agents/spy-host.yaml + SpyHost handler: runs the generic judge turn for
the verdict text, then attaches a structured reveal:[{agent,secret,role}] to the
judge.verdict (same "decorate the emitted event" move as FortuneTeller's omen).
- config/scenarios/the-steeped.yaml: auto-discovered by the registry, surfaced in
the Lab; defaults to the DOCUMENTARIAN narrator.
- provider.py: curated offline lines + per-role mood bias so the bluff lands with
no API key (the spy leans bluffing/panicking).
Also make the Show usable as intended:
- Fix transport h…
feat: add Fishbowl UI presenter layer and say-vs-think engine support
agharsallah+1: Codex
ade9df5
Implements the data foundation (Phases 0-1 of the Fishbowl UI plan) the
Gradio frontend will bind to — all additive, engine left untouched, modularity
preserved (the engine never imports the UI).
- src/ui/fishbowl/: derive_cast_state (per-agent {said,thought,mood} ledger
view), adapter (engine -> say/narrate/poke/verdict + hue/tier/voice/mood with
graceful fallbacks), view_model_at (pure prefix-replay snapshot at any scrubbed
step, with real tokens/rounds from the governor)
- DeterministicTinyModel is now schema-aware, gated on output_extra_fields: it
synthesizes thought/mood offline so the mind-reader works with no API key, while
plain agents stay byte-identical
- AgentManifest gains optional hue/archetype; Conductor.inject_user_event gains an
optional label; cast manifests declare output_extra_fields + presentation metadata
- tests/test_fishbowl.py (15 tests, incl. an offline proof the ledger carries
thought+mood); full suite 277 passed, ruff clean
- docs: manifest-spe…
feat: unify model catalogue and self-hosted routing
agharsallah+1: Codex
9dd6dab
- move model metadata to a shared modal/catalogue.py source of truth and keep modal/registry.py as a compatibility re-export
- add src/models/modal_catalogue.py bridge and resolve config/models.yaml endpoint keys into concrete model/base_url/api_key bindings
- make live-path detection depend on Modal bindings (MODAL_WORKSPACE or MODAL_LLM_BASE_URL) and remove generic cloud-model fallback defaults
- switch memory index default embeddings to local sentence-transformers and document the off-grid behavior
- add ADR-0019 and update architecture/deployment docs, env examples, tests, and lockfile
Co-authored-by: Codex <codex@openai.com>
feat: Instructor-validated structured output on the live path
agharsallah+1: Codex
99293d7
Replace prompt-and-regex JSON with Instructor (Pydantic-validated, retried) on
the live path, wrapping the LiteLLM client; the kind is constrained to may_emit
by construction, so malformed prose can no longer enter the ledger. Degrade
chain: structured -> tolerant parser -> _raw_fallback (offline stub keeps the
parser). Token/cost metering preserved. 226 passed, 1 skipped. ADR-0016.
Co-Authored-By: Codex <codex@openai.com>
feat: LiteLLM gateway routing profiles to Modal-served small models
agharsallah+1: Codex
7df0a45
Add LiteLLMProvider; ModelRouter binds each profile (tiny/fast/balanced/strong)
to its Modal vLLM endpoint (workspace env-templated, not hardcoded) and meters
real token + cost usage into the Governor, making hourly_budget_usd live. Env-
gated; offline keeps the deterministic stub. 212 passed, 1 skipped. ADR-0015.
Co-Authored-By: Codex <codex@openai.com>
feat: update setup instructions and dependencies for uv integration
agharsallah
39e9569
Refactor code structure for improved readability and maintainability
Engine additions (zero scenario edits required):
- EpisodicMemory: per-agent filtered view over the ledger; agents see only their
own actions and globally-visible event kinds, capped at 8 events for small-model
context windows
- ContextBuilder: single point of prompt assembly (persona → scene → memory →
visitor disturbances); changing prompt strategy is now a one-file edit
- Governor: enforces max_turns / max_calls_per_turn / max_total_calls; raises
BudgetExceeded before a runaway cascade can burn quota
Model provider:
- OpenAICompatProvider: works with any OpenAI-compatible endpoint; config via
OPENAI_API_KEY / OPENAI_BASE_URL / MODEL_NAME; falls back to deterministic stub
when no key is present
Agents + scenarios:
- All four Tiny Wood agents use ContextBuilder with rich personas and episodic memory
- New EchoAgent transforms visitor injections through the wood's logic
- Mystery Roots (src/scenarios/mystery_roots.py): convergent blackboard swarm with
ClueGatherer / Hyp…