Skip to content

symfonic.agent

agent

symfonic.agent -- High-level orchestration layer for multi-memory agents.

Integrates symfonic.core (execution engine) and symfonic.memory (5-layer HMS) into a unified, engine-first Python module with an optional FastAPI bridge.

Public API re-exports. Internal modules should not be imported directly.

AgentRequest

Bases: BaseModel

Inbound request for agent execution.

to_scope

to_scope() -> FrameworkTenantScope

Extract a FrameworkTenantScope from this request.

Source code in src/symfonic/agent/types.py
def to_scope(self) -> FrameworkTenantScope:
    """Extract a ``FrameworkTenantScope`` from this request."""
    return FrameworkTenantScope(
        tenant_id=self.tenant_id,
        sub_tenant_id=self.sub_tenant_id,
        namespace=self.namespace,
    )

AgentResponse

Bases: BaseModel

Response from agent execution.

Attachment

Bases: BaseModel

Non-text content to send alongside a query.

The semantic query string is used for HMS hydration and embeddings; attachments are forwarded to the LLM as additional content blocks but do NOT participate in memory hydration or tool routing in v1.

Attributes:

Name Type Description
kind Literal['image', 'document']

Content type -- "image" or "document".

source_type Literal['url', 'base64']

How data is encoded -- "url" (http/https only -- other schemes such as file:// are rejected to prevent SSRF) or "base64".

data str

URL string or base64-encoded content.

media_type str

MIME type (e.g. "image/png", "application/pdf"). Defaults to image/png for kind="image" and application/pdf for kind="document".

filename str | None

Optional filename for documents / PDFs.

FrameworkTenantScope

Bases: TenantScope

Thin subclass of the unified TenantScope for the agent framework layer.

TenantScope in symfonic.core.scope now carries all three fields (tenant_id, sub_tenant_id, namespace), so this subclass only adds extra validation and the backward-compatible converter methods that existing consumers may still call.

from_core_scope classmethod

from_core_scope(scope: TenantScope) -> FrameworkTenantScope

Build from any TenantScope.

Source code in src/symfonic/agent/types.py
@classmethod
def from_core_scope(cls, scope: TenantScope) -> FrameworkTenantScope:
    """Build from any ``TenantScope``."""
    return cls(
        tenant_id=scope.tenant_id,
        sub_tenant_id=scope.sub_tenant_id,
        namespace=scope.namespace,
    )

from_memory_scope classmethod

from_memory_scope(scope: TenantScope) -> FrameworkTenantScope

Build from any TenantScope.

Source code in src/symfonic/agent/types.py
@classmethod
def from_memory_scope(cls, scope: TenantScope) -> FrameworkTenantScope:
    """Build from any ``TenantScope``."""
    return cls(
        tenant_id=scope.tenant_id,
        sub_tenant_id=scope.sub_tenant_id,
        namespace=scope.namespace,
    )

model_post_init

model_post_init(__context: Any) -> None

Validate that sub_tenant_id and namespace are consistent.

Source code in src/symfonic/agent/types.py
def model_post_init(self, __context: Any) -> None:
    """Validate that sub_tenant_id and namespace are consistent."""
    if (
        self.sub_tenant_id is not None
        and self.namespace is not None
        and self.sub_tenant_id != self.namespace
    ):
        raise ValueError(
            "sub_tenant_id and namespace must match when both are provided, "
            "or leave one as None for automatic mapping"
        )

to_core_scope

to_core_scope() -> TenantScope

Return self as TenantScope (identity — no conversion needed).

Source code in src/symfonic/agent/types.py
def to_core_scope(self) -> TenantScope:
    """Return self as ``TenantScope`` (identity — no conversion needed)."""
    return self

to_memory_scope

to_memory_scope() -> TenantScope

Return self as TenantScope (identity — no conversion needed).

Source code in src/symfonic/agent/types.py
def to_memory_scope(self) -> TenantScope:
    """Return self as ``TenantScope`` (identity — no conversion needed)."""
    return self

HydratedMemory

Bases: BaseModel

Typed result from memory hydration.

Returned by SymfonicAgent._hydrate(). Replaces the previous tuple[dict[str, Any], int] return type with a structured model that makes all hydration fields explicit and type-safe.

StreamChunk

Bases: BaseModel

A single streaming event from the agent.

SymfonicAgent

The public symfonic.agent.SymfonicAgent from 11.3: a tombstone.

Constructing it raises :class:EntryPointRemovedError naming SymfonicAgent before any argument is read, exactly as the legacy constructor does, without importing the engine. Its turn methods raise the same error, so an instance made around the constructor (object.__new__) serves no turn either. It is not the legacy class: nothing here reads configuration, holds state or runs a body.

Not in :data:__all__; the public import path is symfonic.agent.

It raises the error directly rather than through :func:_refuse, so the test-only legacy_body patch of :func:_refuse does not reach it: no patch of this module's private hook makes the public name construct, and nothing here imports or hands off to symfonic.agent.engine. A test whose subject is the legacy body imports symfonic.agent.engine.SymfonicAgent explicitly while that module exists.

resume

resume(*args: Any, **kwargs: Any) -> NoReturn

Refuses: SymfonicAgent serves no turn from 11.3.

Source code in src/symfonic/agent/entry_point_removal.py
def resume(self, *args: Any, **kwargs: Any) -> NoReturn:
    """Refuses: ``SymfonicAgent`` serves no turn from 11.3."""
    raise EntryPointRemovedError("SymfonicAgent")

resume_interrupt

resume_interrupt(*args: Any, **kwargs: Any) -> NoReturn

Refuses: SymfonicAgent serves no turn from 11.3.

Source code in src/symfonic/agent/entry_point_removal.py
def resume_interrupt(self, *args: Any, **kwargs: Any) -> NoReturn:
    """Refuses: ``SymfonicAgent`` serves no turn from 11.3."""
    raise EntryPointRemovedError("SymfonicAgent")

run

run(*args: Any, **kwargs: Any) -> NoReturn

Refuses: SymfonicAgent serves no turn from 11.3.

Source code in src/symfonic/agent/entry_point_removal.py
def run(self, *args: Any, **kwargs: Any) -> NoReturn:
    """Refuses: ``SymfonicAgent`` serves no turn from 11.3."""
    raise EntryPointRemovedError("SymfonicAgent")

stream

stream(*args: Any, **kwargs: Any) -> NoReturn

Refuses: SymfonicAgent serves no turn from 11.3.

Source code in src/symfonic/agent/entry_point_removal.py
def stream(self, *args: Any, **kwargs: Any) -> NoReturn:
    """Refuses: ``SymfonicAgent`` serves no turn from 11.3."""
    raise EntryPointRemovedError("SymfonicAgent")

stream_text

stream_text(*args: Any, **kwargs: Any) -> NoReturn

Refuses: SymfonicAgent serves no turn from 11.3.

Source code in src/symfonic/agent/entry_point_removal.py
def stream_text(self, *args: Any, **kwargs: Any) -> NoReturn:
    """Refuses: ``SymfonicAgent`` serves no turn from 11.3."""
    raise EntryPointRemovedError("SymfonicAgent")

stream_typed

stream_typed(*args: Any, **kwargs: Any) -> NoReturn

Refuses: SymfonicAgent serves no turn from 11.3.

Source code in src/symfonic/agent/entry_point_removal.py
def stream_typed(self, *args: Any, **kwargs: Any) -> NoReturn:
    """Refuses: ``SymfonicAgent`` serves no turn from 11.3."""
    raise EntryPointRemovedError("SymfonicAgent")