synalinks-providers/SKILL.md
Use when integrating Synalinks with LM providers — picking the right model prefix (openai/, anthropic/, ollama/, groq/, cohere/, openrouter/, bedrock/, deepseek/, together_ai/, doubleword/, hosted_vllm/ (alias vllm/), gemini/, xai/, mistral/, azure/), env vars per provider, structured-output dispatch (constrained json_schema vs tool-call), local OpenAI-compatible servers (LMStudio, vLLM) requiring litellm.register_model and a dummy OPENAI_API_KEY, and OpenRouter embeddings (LiteLLM doesn't support them — use OpenRouterEmbeddingModel).
npx skillsauth add synalinks/synalinks-skills synalinks-providersInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Configuring LanguageModel and EmbeddingModel for various providers, plus the few cases that still need extra setup (local servers, OpenRouter embeddings).
As of Synalinks v0.8.006+, structured output works out of the box for all listed cloud providers — no patches required.
| Provider | Prefix | Env var | Dispatch path |
|----------|--------|---------|---------------|
| OpenAI | openai/ | OPENAI_API_KEY | constrained json_schema |
| Azure OpenAI | azure/ | AZURE_API_KEY + base | constrained json_schema |
| Anthropic | anthropic/ | ANTHROPIC_API_KEY | response_format (LiteLLM auto-routes) |
| Ollama | ollama/ | (local, no key) | constrained json_schema |
| Mistral | mistral/ | MISTRAL_API_KEY | constrained json_schema |
| Gemini | gemini/ | GEMINI_API_KEY | constrained json_schema |
| xAI | xai/ | XAI_API_KEY | constrained json_schema |
| Groq | groq/ | GROQ_API_KEY | tool-call structured output |
| Cohere | cohere/ | COHERE_API_KEY | tool-call structured output |
| OpenRouter | openrouter/ | OPENROUTER_API_KEY | tool-call structured output |
| Bedrock | bedrock/ | AWS_ACCESS_KEY_ID etc. | tool-call structured output |
| DeepSeek | deepseek/ | DEEPSEEK_API_KEY | constrained json_schema |
| Together AI | together_ai/ | TOGETHER_AI_API_KEY | constrained json_schema |
| Doubleword | doubleword/ | OPENAI_API_KEY (Doubleword key) | rewritten to openai/ w/ api_base |
| LMStudio / vLLM | openai/<name> + api_base | dummy OPENAI_API_KEY | requires litellm.register_model |
| vLLM (native) | hosted_vllm/ (alias vllm/) | (local; HOSTED_VLLM_API_BASE opt) | constrained json_schema |
The vllm/ prefix is rewritten to hosted_vllm/ internally. When hosted_vllm/ is used without an explicit api_base, Synalinks reads HOSTED_VLLM_API_BASE (default http://localhost:8000).
response_format with json_schema): preferred when the provider natively supports OpenAI-style structured output. The model is forced to emit valid JSON matching the schema.structured_output is registered with the schema as its parameters; the provider's tool-calling forces the model to "call" it. Used for providers that lack native JSON schema (Cohere, most Bedrock models) or proxy heterogeneous backends with mixed support (OpenRouter).You don't pick the path — Synalinks dispatches based on the model prefix.
LanguageModel and EmbeddingModel both subclass Module (so they support hooks) and accept arbitrary **default_kwargs that are forwarded to every call; per-call kwargs override the instance defaults.
lm = synalinks.LanguageModel(
model="openai/gpt-4o-mini",
temperature=0.6,
top_p=0.95,
top_k=40,
max_tokens=2048,
reasoning_effort="medium", # forwarded only if litellm.supports_reasoning(model)
)
em = synalinks.EmbeddingModel(
model="openai/text-embedding-3-small",
dimensions=512,
)
fallback= accepts a string, a config dict, or an existing LanguageModel / EmbeddingModel instance — it is auto-coerced via the package-level get():
lm = synalinks.LanguageModel(
model="anthropic/claude-sonnet-4-5",
fallback="openai/gpt-4o-mini", # string is fine
)
When all retries fail and a fallback is set, the original call is replayed against the fallback with the user-supplied kwargs (instance defaults are not re-applied).
synalinks.set_default_language_model(identifier) and synalinks.set_default_embedding_model(identifier) register a default usable across the framework (e.g. by Generator, optimizers, rewards). String identifiers are persisted to ~/.synalinks/synalinks.json; dicts and instances are kept in-process only.
synalinks.set_default_language_model("openai/gpt-4o-mini")
synalinks.set_default_embedding_model("openai/text-embedding-3-small")
# Read back (lazy-constructs from a persisted string on first access)
lm = synalinks.default_language_model()
em = synalinks.default_embedding_model()
Pass None to clear.
import os
os.environ["OPENAI_API_KEY"] = "..."
lm = synalinks.LanguageModel(model="openai/gpt-4o-mini")
os.environ["ANTHROPIC_API_KEY"] = "..."
lm = synalinks.LanguageModel(model="anthropic/claude-sonnet-4-5")
os.environ["GROQ_API_KEY"] = "..."
lm = synalinks.LanguageModel(model="groq/llama-3.1-8b-instant")
os.environ["OPENROUTER_API_KEY"] = "..."
lm = synalinks.LanguageModel(model="openrouter/anthropic/claude-3-haiku")
os.environ["COHERE_API_KEY"] = "..."
lm = synalinks.LanguageModel(model="cohere/command-r-plus")
os.environ["DEEPSEEK_API_KEY"] = "..."
lm = synalinks.LanguageModel(model="deepseek/deepseek-chat")
os.environ["TOGETHER_AI_API_KEY"] = "..."
lm = synalinks.LanguageModel(model="together_ai/meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo")
os.environ["AWS_ACCESS_KEY_ID"] = "..."
os.environ["AWS_SECRET_ACCESS_KEY"] = "..."
os.environ["AWS_REGION_NAME"] = "us-east-1"
lm = synalinks.LanguageModel(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
The doubleword/ prefix is rewritten to openai/ internally with api_base="https://api.doubleword.ai/v1" — so it goes through the strict-schema OpenAI path.
os.environ["OPENAI_API_KEY"] = "<doubleword key>"
lm = synalinks.LanguageModel(model="doubleword/qwen-qwen3-5-397b-a17b-fp8-dottxt")
Local servers that don't ship to LiteLLM's pricing database still need three things:
OPENAI_API_KEY (any non-empty string)litellm.register_model({...}) to give it max_tokens and zero costsapi_base pointing at the local serverimport os, litellm, synalinks
os.environ["OPENAI_API_KEY"] = "lm-studio"
litellm.register_model({
"openai/ibm/granite-4-h-tiny": {
"max_tokens": 4096,
"input_cost_per_token": 0.0,
"output_cost_per_token": 0.0,
"litellm_provider": "openai",
"mode": "chat",
}
})
lm = synalinks.LanguageModel(
model="openai/ibm/granite-4-h-tiny",
api_base="http://localhost:1234/v1",
)
Why: LiteLLM tracks API costs internally. Without registration it returns None for unknown models; Synalinks's cost arithmetic then fails.
Helper: scripts/lmstudio_setup.py wraps this into a one-liner.
For vLLM, the hosted_vllm/ prefix may also work without registration (it routes through the constrained-schema path). If it doesn't, fall back to the LMStudio recipe.
LiteLLM does not support OpenRouter embeddings. Use OpenRouterEmbeddingModel (direct API calls):
from openrouter_embeddings import OpenRouterEmbeddingModel
em = OpenRouterEmbeddingModel(
"qwen/qwen3-embedding-8b",
provider={"only": ["nebius"], "allow_fallbacks": False},
)
result = await em(["Hello, world!"])
# {"embeddings": [[0.02, 0.006, ...]]}
OpenRouterEmbeddingModel is OMEGA-compatible — it coerces non-string leaves to strings (needed because tree.flatten() over trainable variables may yield non-strings). See synalinks-optimizers.
Helper: scripts/openrouter_embeddings.py
OpenRouter lets you pin a request to a specific backend. Pass provider via LiteLLM's extra_body — LanguageModel's **default_kwargs forwards it to every call:
lm = synalinks.LanguageModel(
model="openrouter/meta-llama/llama-3.1-8b-instruct",
extra_body={"provider": {"only": ["DeepInfra"], "allow_fallbacks": False}},
)
(For pre-**default_kwargs versions, see the legacy patch in scripts/openrouter_patch_legacy.py for an instance-aware routing setup.)
| Error | Cause | Fix |
|-------|-------|-----|
| LM provider 'X' not supported | Old Synalinks version | Upgrade to ≥ 0.8.006 |
| litellm.NotFoundError on local model | Model not registered | litellm.register_model({...}) |
| Cost arithmetic fails on local model | LiteLLM returns None for cost | Register with zero costs |
| OpenRouter embeddings 404 | Using LiteLLM | Use OpenRouterEmbeddingModel |
| Groq returns invalid JSON | Schema mismatch | Inspect with synalinks.enable_logging() |
| Anthropic structured output fails | Old LiteLLM version | Upgrade litellm |
Earlier Synalinks versions required monkey-patches for Groq and OpenRouter. Those scripts remain in this skill for historical reference but shouldn't be needed today:
scripts/groq_patch_legacy.py — strips tool_calls from messages, switches Groq to json_schema modescripts/openrouter_patch_legacy.py — registers openrouter/ prefix, supports per-instance provider routingCurrent users: just upgrade Synalinks. The dispatcher handles all of this natively.
OpenRouterEmbeddingModelLanguageModel, EmbeddingModel basicsOpenRouterEmbeddingModel for OMEGAdevelopment
Use when training Synalinks programs — program.compile() / fit() / evaluate() / predict(), validation_split, validation_data, batch_size, epochs, callbacks (ProgramCheckpoint, custom Callback subclasses), History, in-context reinforcement learning workflow. For reward functions see synalinks-rewards; for optimizer internals see synalinks-optimizers.
development
Use when configuring or writing Synalinks reward functions and metrics — ExactMatch, CosineSimilarity, LMAsJudge, ProgramAsJudge, RewardFunctionWrapper, custom reward functions (async, register_synalinks_serializable), in_mask / out_mask filtering, F1Score / FBetaScore / BinaryF1Score / ListF1Score metrics, MeanMetricWrapper, or whenever you're shaping the signal that drives optimization.
development
Use when building or composing a Synalinks Program — the four building APIs (Functional, Sequential, Subclassing, Mixed), Input nodes, multi-input/multi-output graphs, the call/build lifecycle, training=True/False semantics, summary, get_module, plot_program, save/load, get_state_tree/set_state_tree, get_config/from_config and custom serialization. For DataModel/Field, JSON operators (+ & | ^ ~), and LanguageModel/EmbeddingModel basics see synalinks-core. For inner modules see synalinks-modules; for compile/fit/evaluate/predict see synalinks-training.
development
Use when picking, configuring, or tuning a Synalinks optimizer — RandomFewShot (nb_min_examples, nb_max_examples, sampling, sampling_temperature), OMEGA (Dominated Novelty Search, mutation/crossover, k_nearest_fitter, population_size, mutation_temperature, crossover_temperature, selection_temperature, merging_rate, algorithm "dns" vs "ga", selection "softmax"/"best"/"random", reasoning_effort), or evolutionary / quality-diversity prompt optimization in general.