modules/coreis the spine (LLM client API, config, tool API, tracing and metrics contracts), designated stable for 1.0; no MiMa baseline is active yet. The agent runtime and guardrails aremodules/agent, the built-in toolsmodules/agent-tools, providers their own modules (modules/openai,modules/anthropic, …), and RAG, memory, MCP, image, speech and observability likewise;build.sbtlists them all. A new module must also be added tohooks/pre-commit. Workspace support sits inmodules/workspace(runner/client/shared), and runnable demos are inmodules/samples.docs/stores documentation;hooks/provides the pre-commit installer. Sources live insrc/main/scala; add version-specific sources undersrc/main/scala-3when needed. See also szork - a demo game showcasing LLM4S agents.
- Compile:
sbt compile. Run examples viasbt "samples/runMain org.llm4s.samples.basic.BasicLLMCallingExample". - Tests:
sbt testfor the full build or module-specific runs (e.g.,sbt core/test). - Pipeline:
sbt buildAllcompiles and tests; slower but mirrors CI. - Formatting/linting:
sbt scalafmtAllis required;sbt scalafixAllis available for extra hygiene. - Dev hook:
./hooks/install.shinstalls a pre-commit that runs scalafmt, compile, and tests.
- Core main code must not read configuration directly. PureConfig/env/system property access lives only in
org.llm4s.config; everywhere else consumes typed settings injected from the app edge. Llm4sConfigis for edge use (samples, CLIs, tests). Any reference to it in core main code is a violation.- Scalafix enforces this across every module's
src/main/scala: uses ofConfigFactory,ConfigSource.default,sys.env, orSystem.getenvare blocked (except insideorg.llm4s.config, which opts out with a// scalafix:offmarker). Tests and runnable mains are exempt.
.scalafmt.confenforces two-space indents, aligned imports/params, and trailing commas; run scalafmt instead of hand-formatting.- Favor immutability, pure functions, and explicit types at module boundaries. Keep logging consistent with existing
org.slf4jusage. - Naming: types
PascalCase, memberscamelCase, constantsSCREAMING_SNAKE_CASE. Tests end withSpecorTestto match neighboring suites.
- Scalatest is primary; Scalamock is available. Integration suites often mix in
ScalaFuturesorBeforeAndAfterAll. - Place tests under
src/test/scala, mirroring the package of the code under test. - Keep version-specific tests inside the owning module only when Scala-version behavior genuinely differs.
- Typical flow:
sbt testfor quick checks orsbt buildAllbefore PR. Coverage (when needed):sbt coverage test coverageReport. - Suites needing an external service live in
modules/itand must declare a tier by class annotation (@Local,@Docker,@Workspace,@Ollama,@Cloudfromorg.llm4s.it.tags);sbt it/itTierCheckfails the build if one does not. Run a tier withsbt testIntegration/testWorkspace/testOllama/testSmoke, and gate onTier.requirerather thanassumesoLLM4S_IT_STRICT=trueruns turn a missing service into a failure.
- We provide structured GitHub templates to streamline contributions and improve issue quality.
- Bug Reports (bug_report.yml): Use for crashes, errors, unexpected behavior. Include environment (Scala, JDK, OS), LLM provider/model, reproduction steps, and error logs.
- Feature Requests (feature_request.yml): Use for new functionality. Describe problem, proposed solution, alternatives considered, and willingness to implement.
- Enhancements (enhancement.yml): Use to improve existing features. Explain current behavior, proposed improvement, benefits, and implementation approach.
- See CONTRIBUTING.md for detailed contribution guidelines and contribution-guidelines.md for advanced patterns.
- Use short, imperative commit subjects (e.g., "Add centralized model metadata system") and include issue/PR refs when relevant.
- Before a PR: run scalafmtAll and tests, update docs for user-facing changes, and add sample commands/output for new workflows.
- PR text should state motivation, key changes, and validation steps. Screenshots only when altering docs/assets; otherwise keep notes concise.
- Always use the structured templates when opening issues or PRs to ensure consistency and completeness.
- Never commit secrets. Providers are configured as named sections under
llm4s.providersin HOCON; keep API keys in env vars or in the untrackedapplication.local.conf, never in a committed file. Each provider module binds its vendor's conventional variable (OPENAI_API_KEY,ANTHROPIC_API_KEY, ...) to the sharedllm4s.credentials.<providerId>.apiKey, which a section without its ownapiKeyuses; a section for a second account binds its own (apiKey = ${?OPENAI_BATCH_API_KEY}), and in production every section should. llm4s reads noLLM_MODEL; seedocs/getting-started/configuration.md#api-keys. - For workspace demos, ensure Docker is running before
sbt docker:publishLocalor workspace samples, and scrub sensitive data from logs.