d61700d173
Two dokploy MCP tools declare ttl with the draft-04 "exclusiveMinimum": true. Synthetic validates tool schemas against draft-2020 and rejects the whole request, so every session died on a bodiless 500. Deny those two. Haiku moves to GLM Flash: Qwen3.6-27B rejects Claude Code multi-block system prompt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
77 lines
2.9 KiB
Nix
77 lines
2.9 KiB
Nix
{
|
|
pkgs,
|
|
inputs,
|
|
...
|
|
}:
|
|
# Claude Code pointed at synthetic.new. The three model aliases below are bound
|
|
# to three Synthetic models, so `/model opus|sonnet|haiku` swaps between them
|
|
# live; anything else there is reachable by full id (`/model hf:...`).
|
|
let
|
|
claude = inputs.claude-code.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
|
|
|
# `hf:` ids pin one exact model. The `syn:large:*` aliases in Synthetic's own
|
|
# docs move under you whenever they rotate what "large" means.
|
|
kimi = "hf:moonshotai/Kimi-K3";
|
|
glm = "hf:zai-org/GLM-5.2";
|
|
|
|
# Not Qwen3.6-27B for the haiku slot: its chat template rejects Claude Code's
|
|
# multi-block system prompt with "System message must be at the beginning."
|
|
glmFlash = "hf:zai-org/GLM-4.7-Flash";
|
|
in
|
|
{
|
|
home.packages = [
|
|
(pkgs.writeShellScriptBin "synclaude" ''
|
|
set -euo pipefail
|
|
|
|
if [ -z "''${SYNTHETIC_API_KEY:-}" ] && [ -r "$HOME/.env.claude" ]; then
|
|
set +u
|
|
# Silenced: the file greets missing tooling on stderr, which would
|
|
# otherwise print before every session.
|
|
. "$HOME/.env.claude" >/dev/null 2>&1
|
|
set -u
|
|
fi
|
|
|
|
if [ -z "''${SYNTHETIC_API_KEY:-}" ]; then
|
|
echo "synclaude: SYNTHETIC_API_KEY is not set" >&2
|
|
exit 1
|
|
fi
|
|
|
|
export ANTHROPIC_BASE_URL="https://api.synthetic.new/anthropic"
|
|
export ANTHROPIC_AUTH_TOKEN="$SYNTHETIC_API_KEY"
|
|
export ANTHROPIC_DEFAULT_OPUS_MODEL="${kimi}"
|
|
export ANTHROPIC_DEFAULT_SONNET_MODEL="${glm}"
|
|
export ANTHROPIC_DEFAULT_HAIKU_MODEL="${glmFlash}"
|
|
export CLAUDE_CODE_SUBAGENT_MODEL="${glm}"
|
|
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
|
|
export CLAUDE_CODE_ATTRIBUTION_HEADER=0
|
|
|
|
# ~/.env.claude exports both. ANTHROPIC_MODEL outranks the DEFAULT_* trio
|
|
# above, and ANTHROPIC_API_KEY would send Anthropic's credential to
|
|
# Synthetic.
|
|
unset ANTHROPIC_MODEL ANTHROPIC_API_KEY
|
|
|
|
# These two dokploy tools spell ttl's bound `"exclusiveMinimum": true`,
|
|
# which is draft-04. Synthetic validates against draft-2020, where the key
|
|
# must be a number, and rejects the whole request — a bare 500 with no body
|
|
# when streaming. Every session fails, not just ones that call these.
|
|
broken_tools=(
|
|
mcp__dokploy__dnsProvider-createRecord
|
|
mcp__dokploy__dnsProvider-updateRecord
|
|
)
|
|
|
|
# ~/.claude/settings.json pins model "opus[1m]". The [1m] context-window
|
|
# suffix survives alias resolution and reaches Synthetic as part of the id,
|
|
# which 404s there — so pick the alias explicitly unless the caller did.
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--model | --model=*)
|
|
exec ${claude}/bin/claude --disallowedTools "''${broken_tools[@]}" "$@"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
exec ${claude}/bin/claude --model sonnet --disallowedTools "''${broken_tools[@]}" "$@"
|
|
'')
|
|
];
|
|
}
|