133 lines
5.4 KiB
Nix
133 lines
5.4 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
lib,
|
|
...
|
|
}:
|
|
|
|
let
|
|
# Ces dotfiles ne sont pas un flake (config par channels) : on résout donc
|
|
# les sorties du flake pi.nix à la main, en épinglant le rev.
|
|
# Mise à jour : remplacer le rev par le dernier de https://github.com/lukasl-dev/pi.nix
|
|
pi = builtins.getFlake "github:lukasl-dev/pi.nix/1d37b58675b763ae6c9dc05d62321109066a4126";
|
|
|
|
# Passerelle LLM interne Lundi Matin (LiteLLM), même endpoint et même jeton
|
|
# que la fonction zsh `lmc`. Côté serveur, LM-Code route vers glm-5.2.
|
|
lmcModels = (pkgs.formats.json { }).generate "pi-models.json" {
|
|
providers.lundimatin = {
|
|
baseUrl = "https://llm-core.lundimatin.app";
|
|
api = "anthropic-messages";
|
|
# Résolu à chaque requête : le jeton ne passe pas par le store Nix.
|
|
apiKey = "!cat ${config.home.homeDirectory}/.config/lmc-token";
|
|
# La passerelle renvoie des blocs thinking sans signature ; sans ça pi
|
|
# les dégrade en texte au lieu de les rejouer.
|
|
compat.allowEmptySignature = true;
|
|
models = [
|
|
{
|
|
id = "LM-Code";
|
|
name = "LM-Code (glm-5.2 — Lundi Matin)";
|
|
# reasoning absent : la passerelle fallback sur deepseek côté serveur.
|
|
reasoning = false;
|
|
# Limite réelle mesurée via la passerelle LiteLLM (HTTP 400 ContextWindowExceededError).
|
|
contextWindow = 250000;
|
|
maxTokens = 64000;
|
|
}
|
|
{
|
|
id = "glm-5.2";
|
|
name = "GLM 5.2 — Lundi Matin";
|
|
# Ces alias directs ne passent pas par le shim anthropic de la
|
|
# passerelle : le paramètre `thinking` y déclenche un 400
|
|
# (json_parse_error / ChatCompletionRequest). reasoning = false le
|
|
# retire des requêtes ; passer par LM-Code pour du thinking explicite.
|
|
reasoning = false;
|
|
# Alias direct, sans repli : servi de jour (8h-19h30), 500k de contexte.
|
|
# Hors plage de service, la passerelle renvoie une erreur claire.
|
|
contextWindow = 500000;
|
|
maxTokens = 64000;
|
|
}
|
|
{
|
|
id = "kimi-k3";
|
|
name = "Kimi K3 — Lundi Matin";
|
|
reasoning = false;
|
|
# Alias direct, sans repli : servi de nuit (20h-7h30), 500k de contexte.
|
|
contextWindow = 500000;
|
|
maxTokens = 64000;
|
|
}
|
|
{
|
|
id = "deepseek-v4-flash";
|
|
name = "DeepSeek V4 Flash — Lundi Matin";
|
|
reasoning = true;
|
|
# Limite réelle mesurée via la passerelle LiteLLM (HTTP 400 ContextWindowExceededError).
|
|
contextWindow = 262144;
|
|
maxTokens = 64000;
|
|
}
|
|
{
|
|
id = "qwen3.8-27b";
|
|
name = "Qwen 3.8 27B (vision) — Lundi Matin";
|
|
# reasoning = false : avec thinking.enabled la passerelle/vLLM supprime
|
|
# le bloc thinking (testé), donc on laisse pi ne pas envoyer le
|
|
# paramètre thinking. qwen raisonne alors nativement et emet des
|
|
# blocs thinking a signature vide (deja gere par
|
|
# compat.allowEmptySignature du provider).
|
|
reasoning = false;
|
|
# Modele vision : accepte les images (teste via l'endpoint anthropic
|
|
# /v1/messages, format image.source.base64). Reserve aux analyses
|
|
# d'image : basculer dessus via /model pour cet usage, ou via
|
|
# l'extension vision-proxy pour un routage automatique.
|
|
input = [
|
|
"text"
|
|
"image"
|
|
];
|
|
# Limite reelle mesuree via la passerelle LiteLLM (HTTP 400 :
|
|
# "This model's maximum context length is 250000 tokens").
|
|
contextWindow = 250000;
|
|
maxTokens = 64000;
|
|
}
|
|
{
|
|
id = "qwen3.8-flash-next";
|
|
name = "Qwen 3.8 Flash Next (vision) — Lundi Matin";
|
|
# Meme logique que qwen3.8-27b : thinking.enabled supprime le bloc
|
|
# thinking cote vLLM (teste), donc on laisse pi ne pas envoyer le
|
|
# parametre thinking. Le modele raisonne alors nativement et emet
|
|
# des blocs thinking a signature vide, deja geres par
|
|
# compat.allowEmptySignature du provider.
|
|
reasoning = false;
|
|
# Modele vision : 125B-A5B MoE multimodal (plus rapide et plus
|
|
# puissant que deepseek-v4-flash, qui reste 284B-A13B non multimodal).
|
|
# Bémol : contexte plafonne a 262k, comme deepseek-v4-flash, contre
|
|
# 500k pour glm-5.2 et kimi-k3.
|
|
input = [
|
|
"text"
|
|
"image"
|
|
];
|
|
# Limite reelle mesuree via la passerelle LiteLLM (HTTP 400
|
|
# ContextWindowExceededError a 262145 tokens).
|
|
contextWindow = 262144;
|
|
maxTokens = 64000;
|
|
}
|
|
];
|
|
};
|
|
};
|
|
in
|
|
{
|
|
imports = [ pi.homeModules.default ];
|
|
|
|
programs.pi.coding-agent = {
|
|
enable = true;
|
|
models = lmcModels;
|
|
settings = {
|
|
defaultProvider = "lundimatin";
|
|
defaultModel = "LM-Code";
|
|
};
|
|
};
|
|
|
|
# Le wrapper pi ne copie models.json que s'il n'existe pas déjà (garde-fou du
|
|
# module lukasl-dev/pi.nix, variable modelsPrelude dans coding-agent/options.nix).
|
|
# Pour que ce fichier nix reste l'unique source de vérité, on supprime le
|
|
# models.json utilisateur à chaque activation : pi le recréera depuis le store
|
|
# au prochain lancement.
|
|
home.activation.pi-models-source-of-truth = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
|
$DRY_RUN_CMD rm -f ${config.home.homeDirectory}/.pi/agent/models.json
|
|
'';
|
|
}
|