Skip to main content

eea.genai.core

Develop Master

Core agentic LLM layer for EEA GenAI packages.

Provides the multi-provider LLM client, the agent executor (built on pydantic-ai), the unified enricher interface, MCP toolset integration, and the control-panel-backed settings shared by all eea.genai.* packages.

Main features

  1. ILLMClient utility — multi-provider model wrapper. Supported providers: openai-compatible (LiteLLM, vLLM, any OpenAI API), openai, anthropic, google, ollama. Configured via control panel or env vars (LLM_MODEL, LLM_URL, LLM_API_KEY).

  2. IAgentExecutor utility — runs a pydantic_ai.Agent loop with ZCA-discovered tools, MCP toolsets, structured output, and the enricher pipeline.

  3. IEnricher named utility interface — single abstraction for reusable system/user prompt fragments. Replaces the previous IAgentSkill + IAgentContextProvider split (both kept as aliases).

  4. IAgentTool named utility interface — tool callables exposed to the LLM via pydantic_ai tool calling. Thread-safe Plone site restoration via the site_scope context manager.

  5. IAgentConfiguration named utility interface + base class — ship default agents from Python via ZCML; the control panel agents_json overrides them by name.

  6. Pure-function prompt composition (core.prompts.build_prompts) testable without Plone bootstrap.

  7. MCP server integration with ${VAR} and ${VAR:-default} env expansion, filtered tool refs (server/tool) and full toolset inclusion via mcp_servers.

  8. Typed exceptions (AgentDisabled, AgentNotFound, AgentConfigInvalid, AgentExecutionFailed, EnricherFailed) instead of bare RuntimeError.

  9. validate_agent_config(config) — fail-fast validation of tool, enricher, MCP server, and output-type references at config load time.

  10. Built-in tools: extract_blocks, memory, code_exec, fetch_url.

  11. eea.genai.manage permission for administrative operations.

Install

  • Add eea.genai.core to your requirements.txt.

  • Install the GenericSetup profile to enable the control panel.

Contributed settings and frontend flags

Packages can contribute a schema to the existing GenAI controlpanel by registering a named utility implementing IGenAISettingsSection:

<utility
    name="image"
    factory=".settings.ImageAISettingsSection"
    provides="eea.genai.core.interfaces.IGenAISettingsSection"
/>

The utility supplies a schema and get_public_settings() method. Both classic and REST controlpanels combine the contributed schemas with the core schema. Field names must be unique across sections. Each package installs its own records with the existing core prefix:

<records interface="my.package.interfaces.IMySettings"
         prefix="eea.genai.core.interfaces.IGenAISettings" />

This preserves existing core registry keys and avoids core depending on feature packages. Import newly contributed registry records before opening the extended controlpanel on an existing site. See docs/ADR-001-settings-sections.md for the storage decision.

Public GET /@genai-settings returns only the master switch and explicit package feature payloads:

{"enabled": true, "features": {"image": {"enabled": false}}}

get_public_settings() must return only allowlisted, JSON-compatible values safe for anonymous reading and serialization into SSR HTML. Do not include provider configuration, prompts, MCP configuration, environment values, or credentials. Frontends must combine the master and feature switches. The administrative @controlpanels/genai endpoint remains separate.

Environment variables

  • LLM_MODEL — model identifier (e.g. gpt-4o, claude-sonnet-4-6, llama3). Falls back here if the registry value is empty.

  • LLM_URL — base URL for OpenAI-compatible or Ollama endpoints (e.g. http://localhost:4000/v1). Not used for direct OpenAI/Anthropic/Google providers.

  • LLM_API_KEY — API key for the configured provider.

  • ANTHROPIC_API_KEY, GOOGLE_API_KEY — provider-specific overrides for direct provider mode.

API keys are never stored in the registry.

Quick start

Define an enricher:

from eea.genai.core.interfaces import Enricher

class MyContextEnricher(Enricher):
    description = "Adds dataset summary to the user prompt"

    def user_prompt(self, deps):
        return f"Active dataset: {deps.context.title}"

Register it via ZCML:

<genai:agentSkill name="my_context" class=".enrichers.MyContextEnricher" />

Define an agent:

from eea.genai.core.interfaces import AgentConfiguration

class MyAgent(AgentConfiguration):
    system_prompt = "You are an analyst."
    task_prompt = "Produce a one-paragraph briefing."
    enrichers = ["my_context", "generic_metadata"]
    tools = ["fetch_url"]
    output_type = "my.package.models.Briefing"
    max_iterations = 5

Register it:

<genai:agent name="briefing" class=".agents.MyAgent" />

Run it:

from eea.genai.core.agent import AgentDeps
from eea.genai.core.utils import get_executor

result = get_executor().run_with_agent(
    "briefing",
    user_prompt="Brief me on regional air quality.",
    deps=AgentDeps(context=obj, request=request),
)

Control-panel agents_json overrides Python-defined agents by name without code changes.

See ARCHITECTURE.md in this package for the full reference.

Secret Scanning

This repository uses the Betterleaks GitHub Action to scan the current repository content on every push and pull request. The scan uses the rules in .gitleaks.toml and uploads a betterleaks-report artifact when a finding is detected.

If the optional SMTP secrets are configured, failed scans also send an email to the last commit committer. The workflow expects these repository or organization secrets:

  • SMTP_URL

  • SMTP_PORT (optional, defaults to 25)

  • SMTP_EMAIL

  • SMTP_PASSWORD (optional if the SMTP server does not require authentication)

Port 465 is sent with direct TLS; other ports use the default SMTP handshake. The email includes a short finding summary from the redacted Betterleaks report, including the redacted matched line from each finding.

There are three common outcomes:

  1. Everything is OK. The Betterleaks / Scan for secrets check is green and no action is needed. Regular references to runtime values are OK, for example:

    token_from_cookie = request.cookies.get("auth_token")
  2. A real secret was found. The check is red and the workflow log asks you to download the betterleaks-report artifact. Open the artifact from the GitHub Actions run and check the reported file, line and rule. Remove the committed value, move it to the proper secret store, and rotate it if it was exposed. A report entry looks like this:

    {
      "RuleID": "secret-literal-assignment",
      "File": "src/config.py",
      "StartLine": 12,
      "Secret": "[REDACTED]"
    }
  3. The finding is a false positive. Keep the value only if it is clearly not sensitive, such as a test fixture, placeholder, or public example. Add betterleaks:allow on the same line and include a short explanation in the pull request:

    test_password = "admin"  #betterleaks:allow

Do not add betterleaks:allow to real credentials.

Changelog

1.3 - (2026-10-29)

  • Change: Multimodal enrichers, extensible settings sections, and SSR feature flags [razvanMiu]

  • Feature: packages can contribute settings sections to both GenAI controlpanels through named IGenAISettingsSection utilities, without introducing package-specific dependencies into core.

  • Feature: expose explicitly allowlisted feature flags through public GET @genai-settings for frontend SSR. Administrative configuration is not included in this response.

  • Fix: cap fastmcp<4 and mcp<2 — pydantic-ai 1.107.0 is incompatible with the mcp SDK 2.x (mcp.shared.context.RequestContext was removed) and its unpinned fastmcp>=3.3.0 requirement drifted to fastmcp 4.x -> mcp 2.x, breaking the pydantic_ai.mcp import on fresh installs (issue #305021)

  • Feature: multimodal prompts — enrichers can now contribute non-text content parts (e.g. pydantic_ai ImageUrl) to the agent’s user prompt via Enricher.content_parts() (issue #305021)

  • Feature: agents can opt in to AI-generated summary markers via the summary_markers config key (issue #305021)

  • Feature: agents can cap summary length via the max_summary_length config key — generation is retried once when the model overshoots (consumed by eea.genai.summary.generate) (issue #305021) [razvanMiu refs #305021]

1.2 - (2026-07-02)

  • Change: specify pydantic-ai version [razvanMiu]

1.0 - (2026-05-20)

  • Initial release [avoinea refs #000000]

Metadata

Release files for eea.genai.core 1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for eea.genai.core 1.3
File Size Uploaded Provenance Actions
eea_genai_core-1.3.tar.gz 62.1 kB Without provenance Details for eea_genai_core-1.3.tar.gz

Release files / eea_genai_core-1.3.tar.gz

Download URL eea_genai_core-1.3.tar.gz
Size 62.1 kB
Tags Source
SHA-256 checksum
How to use checksums
a07309641ff3829e3eb177ee090281441070cdc5151ec56532548a04161e16dc
BLAKE2b-256 checksum
How to use checksums
dc5dfbb598916d08b2ea1e70dd04a4f0147562703a298b5ce69d20cff4662007
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Security for eea.genai.core 1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page