Skip to content

Chore/trim speculative config - #19

Open
cluster2600 wants to merge 12 commits into
ai-swiss:mainfrom
cluster2600:chore/trim-speculative-config
Open

Chore/trim speculative config#19
cluster2600 wants to merge 12 commits into
ai-swiss:mainfrom
cluster2600:chore/trim-speculative-config

Conversation

@cluster2600

Copy link
Copy Markdown

Summary

Type

  • Fix
  • Feature
  • Docs
  • Refactor / tests / tooling

Checklist

  • npm test green (core + packages)
  • npm run typecheck clean
  • node tools/base.mjs validate --root . → "BASE valide."
  • node tools/base.mjs route-test --root . stable (and the example fixtures, if routing changed)
  • Derived artifacts regenerated if needed (npm run index, base build --write)
  • MCP touched? cd mcp && npm run build && npm test (the build runs tsc; vitest alone does not type-check)
  • Studio touched? cd tools/studio/ui && npm test && npm run build (and npm run e2e for user flows)
  • No em-dashes in French public content; specs/docs updated if behaviour changed
  • A test accompanies any change to verifiable behaviour

cluster2600 and others added 12 commits June 28, 2026 12:14
createMoaModel wraps N proposer models + 1 aggregator and conforms to the
existing LanguageModel port ({ id, complete, stream? }), so it drops in
anywhere a single model is expected.

Flow (Wang et al. 2024 MoA, the shape Hermes' `moa` provider uses):
proposers answer the same request in parallel with tools stripped (text
drafts only), then the aggregator synthesizes the drafts — folded into the
system message as private guidance — with the original tools intact so
tool-calling still works through it. Usage is summed across all models.

No ground-truth judge exists in chat, so the aggregator LLM is the selector,
matching Hermes' design. Resilient to partial proposer failures; throws only
if every proposer fails.

Tested with faux/stub models (no API keys): synthesis, tool-stripping,
partial-failure resilience, usage summation, config validation, streaming.
feat(base-llm): Mixture-of-Agents meta-model
createTriumviratModel implements the inference-time architecture of Sakana
Fugu / TRINITY (arXiv:2512.04695). The name nods to the three roles it
coordinates. Each turn a coordinator picks a model from a swappable pool and
assigns it a role (Thinker plans, Worker executes and is the only role given
tools, Verifier judges the draft and gates termination), looping until
accepted or a turn budget hits.

TRINITY's contribution is a CMA-ES-trained 0.6B coordinator, which can't be
reproduced as a PR, so the default coordinator is prompted (an LLM choosing
model+role+stop) with a deterministic Thinker->Worker->Verifier fallback.
The coordinator.decide seam lets a heuristic or trained coordinator drop in
later with no API change. Conforms to the LanguageModel port, sums usage,
threads the abort signal, recovers from failed role turns.

Tested with stub models (no keys): happy path, reject-then-fix feedback,
budget exhaustion, tool routing, usage summation, prompted-coordinator JSON
path, deterministic fallback, role-failure recovery, abort, config validation.
Add an `ensembles` block to .ai/studio.settings.json so MoA and Triumvirat
are configurable without code. resolveModel checks ensembles before the
provider path: an ensemble entry names a type (moa | triumvirat) plus member
refs, and each member resolves through the existing <provider>/<model>
registry, so the ensemble name then works anywhere a model ref does.

Bad config (missing aggregator/pool, unknown type, unknown provider member)
fails with a clear BAD_REQUEST. Tests cover both ensemble types, a plain
provider ref regression, and each error path. Docs with a resolution diagram.
createLangfuseModel wraps any base-llm model and conforms to the same port
({ id, complete, stream? }), so it composes over a single adapter, a MoA, or
a Triumvirat. Every call is traced to Langfuse: input, output, token usage,
latency, and errors.

Zero new dependencies: no Langfuse SDK, just native fetch against the public
ingestion API (POST /api/public/ingestion, HTTP Basic auth). Ingestion is
fire-and-forget so it never adds latency; flush() drains in-flight sends.
A telemetry failure never breaks the wrapped call (routed to onError).

Keys default to env LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY; self-hosted
via LANGFUSE_HOST. Tested with a fake fetch (no network): trace+generation
emission, usage mapping, error traces, ingestion-failure resilience, env
keys, streaming capture, config validation. Docs with a mermaid sequence
diagram.
- packages/base-llm/README.md: a Composition section linking the MoA,
  Triumvirat, ensembles-settings and Langfuse docs so they are discoverable
  from the package root.
- docs/reference/orchestration-et-supervision.md: a French reference page
  (authoritative) for the docs site, plus its English mirror under docs/en.
  Present-tense, em-dash-free, lexicon/translation/tree gates green.

Makes the new capabilities visible on the default branch and in the rendered
manual once merged.
Orchestration + monitoring: Triumvirat, ensembles, Langfuse, docs
… pass

- Register de (Deutsch) and it (Italiano) locales in the docs-site config.
- Translate all 74 French reference pages to German and Italian under
  docs/de/ and docs/it/, each a body-only mirror with a fr-synced hash that
  matches its French source (the gate that keeps translations from drifting).
- Add mermaid diagrams to the French pages that genuinely describe a flow,
  decision tree, or lifecycle (routing voies, provider selection, adoption,
  expertise lifecycle, ...), mirrored into en/de/it.

All doc gates pass: em-dash, statusless, punctuation, lexicon, translations,
tree. German targets the Swiss German-speaking audience; Italian is natural.
Machine-assisted, so a native review pass is worthwhile before publishing.
docs(i18n): German + Italian translations of all 74 pages + mermaid
Remove speculative options no caller sets: moa synthesisPrompt, triumvirat
rolePrompts, langfuse traceName + metadata (the DEFAULT_* constants stay,
just not overridable). Drop the now-dead synthesisPrompt pass-through in the
ensembles settings and the matching doc rows. Kept langfuse onError (the
error escape hatch) and the triumvirat decide seam (the tests use it).

Net -20 lines, no behaviour change. typecheck + module/settings tests green.
@cluster2600
cluster2600 requested a review from cbardyn as a code owner June 28, 2026 19:59
@cbardyn

cbardyn commented Jul 2, 2026

Copy link
Copy Markdown

Merci pour ce nettoyage, et plus largement pour la série de contributions de ces derniers jours.

Le commit de fond, qui retire les options de configuration non utilisées (synthesisPrompt, rolePrompts, traceName/metadata) en conservant les constantes par défaut et les points d'extension testés, est bon à prendre tel quel.

Un point de cadrage, cependant. La branche n'a pas été rebasée: elle transporte encore l'ensemble des commits d'orchestration (MoA, Triumvirat, Langfuse) et des traductions allemande et italienne, d'où un différentiel de 227 fichiers et de plus de 14 000 lignes pour ce qui se veut un simple allègement. Or ces deux lots font déjà l'objet de propositions dédiées, #17 pour l'orchestration et la supervision, #18 pour l'internationalisation. Cette proposition les reprend donc intégralement, ce qui en fait un sur-ensemble plutôt qu'un correctif ciblé.

Nous préférons traiter chaque sujet dans sa propre proposition, pour deux raisons. D'abord, le wrapper Langfuse ouvre une voie sortante vers un service hébergé (par défaut cloud.langfuse.com, vers lequel sont transmis entrées, sorties et compteurs de jetons): même optionnelle, elle touche notre récit de souveraineté et mérite une revue explicite, qui a sa place dans #17. Ensuite, les traductions assistées gagnent à être relues séparément, comme vous le suggérez vous-même.

Concrètement, pourriez-vous repartir d'une branche fraîche sur le main courant (la 1.1.0 est sortie depuis, le conflit est certain) et n'y garder que le commit d'allègement? Il faudra aussi la mention Signed-off-by sur chaque commit, faute de quoi le contrôle DCO bloque la fusion; un rebase avec l'option de signature règle les deux en une fois. Une fois la branche réduite à son objet, l'intégration continue pourra s'exécuter et nous reverrons le tout avec plaisir.

Merci encore, et n'hésitez pas si un coup de main sur le rebase est utile.

@cbardyn cbardyn added the en attente du contributeur Réponse postée; la prochaine action est côté contributeur (rebase, DCO, discussion) label Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

en attente du contributeur Réponse postée; la prochaine action est côté contributeur (rebase, DCO, discussion)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants