Skip to main content

AGENTICSTAR Platform SDK

Enterprise AI Agent Infrastructure SDK for building autonomous agent systems.

Installation

Requires Python 3.11+.

# Core (minimal) — Events / Storage paths / Metering / Auth / Security が使える
pip install agenticstar-platform

# With specific modules
pip install agenticstar-platform[db]           # PostgreSQL
pip install agenticstar-platform[rag]          # Qdrant + Embedding
pip install agenticstar-platform[storage]      # Azure Blob, S3, GCS
pip install agenticstar-platform[storage-azure] # Azure Blob only (AzureBlobStorageClient)
pip install agenticstar-platform[storage-aws]   # AWS S3 only (S3StorageClient)
pip install agenticstar-platform[storage-gcp]   # GCS only (GCSStorageClient)
pip install agenticstar-platform[memory]       # Semantic memory (Mem0)
pip install agenticstar-platform[security]     # PII detection
pip install agenticstar-platform[webhook]      # aiohttp (WebhookEventHandler)
pip install agenticstar-platform[all]          # All modules

Extra を入れていないコンポーネントに触れると、必要な extra を示す ImportError が出ます (生の ModuleNotFoundError は出しません)。

ImportError: 'PostgreSQLManager' requires the 'db' extra of agenticstar-platform.
Install it with:  pip install 'agenticstar-platform[db]'  (missing dependency: No module named 'asyncpg')

Storage の provider client も同じ契約です。StorageConfig / StoragePaths 等の core 型は extra なしで import でき、AzureBlobStorageClientstorage-azure)/ S3StorageClientstorage-aws)/ GCSStorageClientstorage-gcp)は シンボル取得の時点で(constructor まで遅延せず)対応する extra を案内します。 from agenticstar_platform import S3StorageClientfrom agenticstar_platform.storage import S3StorageClient のどちらの経路でも 成功・失敗の境界は同一です。

Quick Start

1. 最小のエージェント(外部サービス不要・コピーしてそのまま動く)

エージェントのロジック・LLM・フレームワークは利用者が自由に選ぶもので、SDK は提供しません。 SDK が担当するのは「進捗と結果をフロントエンドへ届ける」などの基盤部分です。 まずは外部サービスなしで、進捗イベント → 終端イベントまでを一本通します。

hello_agent.py:

import asyncio

from agenticstar_platform import EventEmitter, EventType, create_json_handler


async def my_agent(emitter: EventEmitter, request: str) -> None:
    """あなたのエージェント本体。ロジックは自由(LangChain / OpenAI Agents SDK / 自作)。"""
    await emitter.emit_event(EventType.PHASE_START, f"received: {request}")
    try:
        answer = request.upper()  # ここを実際の処理に置き換える
        await emitter.emit_event(EventType.COMPLETION_SUCCESS, answer)
    except Exception as e:
        # 終端イベントは必ず 1 回送る(送らないとフロントの表示が完了しない)
        await emitter.emit_event(EventType.COMPLETION_FAILURE, str(e))


async def main() -> None:
    emitter = EventEmitter(execution_id="demo-001", handler=create_json_handler())
    asyncio.create_task(my_agent(emitter, "hello agenticstar"))

    # COMPLETION_SUCCESS / COMPLETION_FAILURE を受け取ると自動で終了する
    async for chunk in emitter.consume_events():
        print(chunk)  # create_json_handler は改行を含まないので print で 1 行にする


if __name__ == "__main__":
    asyncio.run(main())
pip install agenticstar-platform
python hello_agent.py

出力(create_json_handler() は JSON 行、create_sse_handler() は SSE 形式を返します):

{"event_type": "phase_start", "execution_id": "demo-001", "message": "received: hello agenticstar", "timestamp": 1785162261.27}
{"event_type": "completion_success", "execution_id": "demo-001", "message": "HELLO AGENTICSTAR", "timestamp": 1785162261.27}

answer = ... の行を raise RuntimeError("upstream timeout") に変えると、 completion_failure が終端イベントとして出ます。

なお emit_event() はキューに積むだけです。上の例のように consume_events() を回さない 構成(SSE を使わない場合)では、EventEmitter.drain() を呼ばないとハンドラーが発火しません。

2. 同じ関数を Marketplace 互換で動かす(runner)

ローカルで動いた agent 関数は、run_marketplace_agent に渡すだけでそのまま Marketplace 互換の終端ライフサイクルで実行できます。identity (EXECUTION_ID 等)の受領・検証、入力メッセージの取得、結果の DB 保存、 webhook 通知、終端イベント(何が起きても正確に 1 回)、cleanup は runner が 担い、agent 側には一切書きません。

marketplace_agent.py:

from agenticstar_platform import run_marketplace_agent


async def my_agent(emitter, message: str) -> str:
    """あなたのエージェント本体。ロジックは自由(LangChain / OpenAI Agents SDK / 自作)。"""
    return message.upper()  # ここを実際の処理に置き換える


if __name__ == "__main__":
    run_marketplace_agent(my_agent)
pip install 'agenticstar-platform[runner]'
python marketplace_agent.py

環境変数契約:

変数 誰が設定するか 必須
EXECUTION_ID / CONVERSATION_ID / USER_ID / MESSAGE_ID Marketplace executor が Pod 起動時に注入
REQUEST_SOURCE / AGENT_ID 同上(任意)
DB_HOST / DB_PORT / DB_DATABASE / DB_USER / DB_PASSWORD エージェント登録時の env var 設定(PostgreSQLConfig.from_env() 契約)
WEBHOOK_URL エージェント登録時の env var 設定

終端イベントの規約:

  • agent 関数の戻り値が completion_success の本文として保存・通知されます
  • agent 関数が例外を投げると completion_failure に収束します(traceback はログのみ、イベント本文には出ません)
  • ローカルサンプルのように agent 関数が自分で終端イベントを emit する形でも二重送信にはなりません(同じ関数が両方で動きます)
  • 必須 env が欠けている場合は agent を呼ばずに MarketplaceRunnerConfigError で停止します

低レベル API が必要な場合(handler 構成を自分で組みたい場合)は、従来どおり create_marketplace_handler(data_access, webhook_url, user_id, conversation_id, message_id) (DB 保存 + webhook 通知の複合ハンドラー、[db] + [webhook] extra が必要)を EventEmitter に直接渡してください。

2.5 Local Integration Lab(credential 不要で DB / RAG / storage まで体験)

Hello World の次段として、PostgreSQL・Qdrant・S3 互換 storage・決定論的 offline embedding を version 固定の Docker Compose で起動し、synthetic 文書の ingest → retrieve → artifact/result persist → terminal outcome を 1 コマンドで 完走する lab を同梱しています。cloud account・production credential・.env 手編集は不要です(必要なのは Docker と Python 3.11+ だけ)。

lab はパッケージに同梱されており、PyPI からのインストールだけで実行できます:

pip install 'agenticstar-platform[lab]'
python -m agenticstar_platform.lab     # 診断は同コマンド + doctor、破棄は --reset

artifact のローカルコピーは実行時 cwd の agenticstar-lab-artifacts/ に 置かれます。詳細は agenticstar_platform/lab/README.md を参照してください。

3. 基盤コンポーネントの初期化

以下は各コンポーネントの初期化例です(抜粋。実行には対応する外部サービスの 接続情報・資格情報と、該当 extra のインストールが必要です)。

from agenticstar_platform import (
    # Database
    PostgreSQLManager, ApiPostgreSQLManager, PostgreSQLConfig, DataAccess,
    # RAG (Vector DB + Embedding)
    QdrantManager, QdrantConfig, EmbeddingGenerator, EmbeddingConfig,
    # Storage
    AzureBlobStorageClient, AzureBlobConfig,
    # Events
    EventEmitter, EventType,
    # Auth
    AgenticStarAuthClient, AgenticStarAuthConfig,
    # Memory
    SemanticMemoryClient, SemanticMemoryConfig,
)

# Example: Initialize SDK components
async def main():
    # Database (direct connection)
    db_config = PostgreSQLConfig.from_toml("config.toml", section="database")
    manager = PostgreSQLManager(db_config)
    da = DataAccess(manager)
    await da.initialize()
    users = await da.fetch_all("SELECT * FROM users WHERE active = $1", (True,))

    # Database (HTTP API)
    db_config = PostgreSQLConfig(api_url="https://your-api.example.com/db")
    manager = ApiPostgreSQLManager(db_config, token_provider=lambda: "your-token")
    da = DataAccess(manager)
    users = await da.fetch_all("SELECT * FROM users WHERE active = $1", (True,))

    # RAG System
    embedding_config = EmbeddingConfig.from_toml("config.toml", section="rag.embedding")
    embedding_gen = EmbeddingGenerator(embedding_config)

    qdrant_config = QdrantConfig.from_toml("config.toml", section="rag.qdrant")
    async with QdrantManager(qdrant_config, embedding_gen) as qdrant:
        results = await qdrant.search("How to use the SDK?", limit=5)

    # Storage (uses from_dict, not from_toml)
    storage_config = AzureBlobConfig.from_dict({
        "bucket_name": "your-container",
        "connection_string": "your-connection-string",
    })
    storage = AzureBlobStorageClient(storage_config)

Modules

Module Extra Description
db [db] PostgreSQL data access layer with Azure AD support
rag [rag] Qdrant vector database and Azure OpenAI / OpenAI-compatible embedding integration
storage [storage] / [storage-azure] / [storage-aws] / [storage-gcp] Multi-cloud storage (Azure Blob, S3, GCS)
auth (core) AgenticStar Auth API client (authentication, user management, MCP tokens)
memory [memory] Semantic memory (Mem0 + Qdrant)
security [security] PII detection (Azure Presidio, AWS Bedrock Guardrails / Comprehend, GCP DLP)
events (core) Event type definitions for streaming
common (core) Shared utilities (secret masking, validation)

Auth Module

from agenticstar_platform.auth import AgenticStarAuthClient, AgenticStarAuthConfig

# From config.toml [auth.agenticstar] section
config = AgenticStarAuthConfig.from_config("config.toml")
client = AgenticStarAuthClient(config)

# Get user info
user = await client.get_user(user_id="user-001")

# Get MCP tokens
tokens = await client.get_mcp_tokens(user_id="user-001")

Memory Module

Semantic memory powered by Mem0 + Qdrant (requires pip install agenticstar-platform[memory]):

from agenticstar_platform.memory import SemanticMemoryClient, SemanticMemoryConfig

config = SemanticMemoryConfig.from_toml("config.toml")
memory = SemanticMemoryClient(config)

# Add memory (methods are synchronous; only cleanup() is async)
memory.add(
    [{"role": "user", "content": "User prefers dark mode"}],
    user_id="user-001",
)

# Search memory
results = memory.search("user preferences", user_id="user-001")

Storage Module

Note: AzureBlobConfig uses from_dict() (not from_toml()):

from agenticstar_platform.storage import AzureBlobStorageClient, AzureBlobConfig

config = AzureBlobConfig.from_dict({
    "bucket_name": "your-container",
    "connection_string": "DefaultEndpointsProtocol=https;...",
    "prefix": "uploads/",
})
client = AzureBlobStorageClient(config)
result = await client.upload_file("local/file.pdf", prefix="docs/")

Telemetry / LLM Usage Tracking (Marketplace)

TelemetryAccess (under db module) writes records to the ai_telemetry table. Unknown fields are stored in the metadata jsonb column automatically — no schema migration is required to add new tracking dimensions.

For Marketplace agents that wrap LLM calls, the SDK defines recommended field names for token and model usage. Following this convention enables cross-agent cost / utilization analytics in shared dashboards.

from agenticstar_platform.db import TelemetryAccess

telemetry = TelemetryAccess(data_access)

# After an LLM call from your custom agent:
response = await openai_client.chat.completions.create(...)

await telemetry.save_telemetry({
    "conversation_id": conversation_id,
    "agent_type": "my_marketplace_agent",
    "service": "my-agent-service",
    "operation": "generate_response",
    "duration_ms": elapsed_ms,
    "success": True,

    # Recommended convention fields (stored automatically in metadata jsonb)
    "prompt_tokens": response.usage.prompt_tokens,
    "completion_tokens": response.usage.completion_tokens,
    "total_tokens": response.usage.total_tokens,
    "model": "azure/gpt-4.1",  # LiteLLM-style identifier
})

Recommended convention fields

Field Type Source Notes
prompt_tokens int usage.prompt_tokens (OpenAI / LiteLLM compatible) Input tokens
completion_tokens int usage.completion_tokens Output tokens
total_tokens int usage.total_tokens Sum
model str LiteLLM-style: azure/gpt-4.1, bedrock/anthropic.claude-3-5-sonnet, openai/gpt-4o, etc. Provider/model identifier

These fields are not known columns — they land in metadata jsonb automatically. No SDK code change, no DB schema migration. Use the recommended names so that your data joins with platform-level analytics.

Known columns (reserved field names)

The following keys are written to their own ai_telemetry columns instead of metadata. Any other key lands in metadata jsonb.

timestamp, service, operation, duration_ms, conversation_id, intent_type, confidence_score, tools_used, success, agent_type, agent_level, task_complexity, current_message, context_summary, suggested_approach, conversation_goal, final_content, metadata

tools_used is an integer column holding a count:

  • int is stored as-is; a list / tuple is normalized to its length.
  • Not measured is NULL; measured-and-zero is 0 — the two are kept distinct.
  • Values the column cannot hold (a breakdown list, a wrong type, or a value outside the PostgreSQL integer range) are additionally kept under metadata.tools_used, so nothing is lost. The column value itself never fails a telemetry write; a raw value kept in metadata follows the same JSON-serializability rule as any other metadata field.

tools_used became a known column in 0.5.38 (use 0.5.39 or later). Before that it fell through to metadata; if you read metadata->>'tools_used' for plain integer counts, read the column instead.

Cross-agent analytics example

-- Per-model token usage in the last 30 days
SELECT
  metadata->>'model' AS model,
  agent_type,
  SUM((metadata->>'prompt_tokens')::int)     AS total_prompt_tokens,
  SUM((metadata->>'completion_tokens')::int) AS total_completion_tokens,
  COUNT(*)                                    AS invocations,
  AVG(duration_ms)::int                       AS avg_duration_ms
FROM ai_telemetry
WHERE timestamp > NOW() - INTERVAL '30 days'
  AND metadata ? 'prompt_tokens'
GROUP BY model, agent_type
ORDER BY total_prompt_tokens DESC;

Updated in SDK ≥ 0.5.15: Cost conversion is no longer out of scope. The new Metering module (UsageMeter) below computes cost via a pluggable engine (litellm by default — its community-maintained price map solves the "changes too frequently" problem; graceful NULL when litellm is absent). TelemetryAccess remains the place for agent operational telemetry (intent / tools / duration → ai_telemetry); UsageMeter is the dedicated per-LLM-call cost ledger. Use whichever fits; they are complementary.

Metering Module — UsageMeter (SDK ≥ 0.5.15)

Dedicated LLM usage & cost infrastructure: computes cost from an LLM response/usage and records one row per call to llm_usage_ledger, with a daily rollup (llm_usage_daily) and cost-visualization queries. Pure infra — agent-logic agnostic, identical for self-hosted and Marketplace BYO (in-process; no proxy/header coupling).

  • Pluggable cost: default uses litellm (completion_cost / cost_per_token) — reflects long-context, prompt-cache and tier pricing. If litellm is absent, tokens are still recorded (cost_usd = NULL). Pass cost_fn=... to override.
  • DB: any handle exposing execute_query(query, params) -> {success, data, error} (the SDK's DataAccess / PostgreSQLManager).
  • Usage status (SDK ≥ 0.5.21): each row records usage_status (present/missing); when usage is absent, pass missing_reason= (e.g. provider_omitted / stream_interrupted). It is stored on the row (not just logs) so offline exports can tell cost_usd IS NULL (unpriced) vs usage_status='missing' vs true-zero apart. Present rows always store NULL (no contradiction).
from agenticstar_platform.metering import UsageMeter

meter = UsageMeter(db=data_access)
await meter.ensure_schema()                        # create ledger/daily/rollup if absent (idempotent)

# Record one LLM call (cost computed automatically; fire-and-forget safe)
await meter.record(
    model="gpt-5.5", response=resp, endpoint="chat/completions",
    labels={"execution_id": eid, "message_id": mid, "conversation_id": cid, "user_id": uid},
)

# ...or wrap the call so it records on completion
resp = await meter.track(model="gpt-5.5", labels=ids)(litellm.acompletion)(**params)

# Cost only (no record)
usd = UsageMeter.cost_usd("gpt-5.5", response=resp)

# Daily rollup + cost visualization (for dashboards / billing)
await meter.rollup_recent()
rows = await meter.daily_cost(by="model", since_days=30)   # by = "model" | "user" | "agent" | "day"

Schema (ensure_schema): llm_usage_ledger — one row per call (execution / message / conversation / user, model, in/out/total/cached tokens, usage_status + missing_reason, cost_usd, currency) — plus llm_usage_daily (rollup) and rollup_llm_usage_daily(day). The default DDL is portable (any PostgreSQL); at scale, partition llm_usage_ledger monthly (e.g. pg_partman).

Audit Module — ActionAudit / GatewayActionAudit (SDK ≥ 0.5.31)

Dedicated action-audit ledger infrastructure: records agent-side action events (approvals, tool authorizations, policy violations, kill-switch, external-agent egress) into append-only ledgers (agent_action_audit / llm_gateway_action_audit). Distinct from metering by its write guarantees — this is an audit trail, not telemetry. Pure infra, no extra dependencies (stdlib only, available in the core install).

  • Callers pass no raw content (usage contract): never hand prompts / tool arguments to the ledger — one-way them with canonical_digest() (SHA-256) into payload_digest. The SDK performs no automatic secret detection or redaction. Field caps (reason truncated to 300 chars, payload_digest must be 64 lowercase-hex chars or it is dropped, metadata over 2KB of key-sorted JSON replaced by {truncated, size_bytes, digest}, always deep-copied) bound the blast radius of accidental leakage — they are not leak prevention by themselves.
  • Three write modes: record() = at-least-once while the process lives (bounded retry, then the sanitized row is spilled as JSON to a log line tagged action_audit_spill for manual reconcile) / record_sync() = audit-before-act (raises ActionAuditWriteError on DB write failure — an approval that cannot be audited must not take effect) / record_nowait() = fire-and-forget for hot paths (strong task refs, backlog capped at 512 — overflow spills instead of blocking; pre-start cancellation also spills; best-effort — lost if the process dies abruptly).
  • approval.* events require actor_ref (missing it raises ValueError synchronously).

Guardrail Alerts — GuardrailAlertWriter / GuardrailAlertAggregates (SDK ≥ 0.5.32)

Producer writers for the Admin-facing guardrail alert triage view (guardrail_alerts) and the unlinked daily aggregates (guardrail_alert_daily_aggregates). Non-authoritative operational view — the authority remains the action-audit ledger. Same delivery contract as the audit writers (bounded FAF + retry → spill → drain).

  • No end-user identity: the row schema has no user-id column by design; the aggregates writer takes no correlation-id arguments at all (structural unlinking).
  • SelfHarm never appears on rows: normalized detection (case / space / _ / - variants, str-Enum .value) raises ValueError synchronously; SelfHarm-only detections are recorded as aggregates only. Row policy_outcome is blocked-only in Phase 1.
  • Idempotent rows: event_key (v2:{surface}:{correlation_kind}:{correlation}:{decision_point}:{outcome})
    • ON CONFLICT (event_key) DO NOTHING — replays never clobber Admin lifecycle state.
  • Grants differ per table: rows = producer INSERT-only; aggregates = INSERT + UPDATE(count) + SELECT(count) (the UPSERT references the existing counter). Severities are measured Azure category severities (2/4/6) — do not substitute thresholds; aggregate counts are approximate (at-least-once may double-count).
  • DB: any handle exposing execute_query(query, params) -> {success, data, error} (the SDK's DataAccess / PostgreSQLManager).
from agenticstar_platform.audit import ActionAudit, GatewayActionAudit, canonical_digest

audit = ActionAudit(db=data_access, source="my-agent", system_version=image_tag)  # source = name of the writing component
await audit.ensure_schema()                       # provisioning (owner role): create ledger + indexes, add newer columns to older tables

# Hot path (tool authorization etc.): fire-and-forget
audit.record_nowait(
    event_type="tool.access", actor_type="agent", decision="deny",
    resource="bash", action="execute", reason="blocked_command",
    conversation_id=cid, execution_id=eid,
    payload_digest=canonical_digest({"command": cmd}),
)

# Approval (audit-before-act): abort the action if this raises
await audit.record_sync(
    event_type="approval.granted", actor_type="human", actor_ref=approver_id,
    decision="granted", resource=tool_name, conversation_id=cid,
)

await audit.aclose()                              # shutdown: drain pending writes (timeout → cancel + spill)

gw = GatewayActionAudit(db=gateway_da)            # LLM Gateway policy decisions (virtual-key identity)
await gw.record(event_type="policy.mcp_stripped", decision="stripped",
                virtual_key_id=vk, request_id=rid)

Schema (ensure_schema): agent_action_audit (source, event_type, actor, decision, reason, policy, correlation ids, payload_digest, metadata jsonb, row_hash) and llm_gateway_action_audit (virtual key, request ids, event/decision, detail_digest, row_hash). ensure_schema applies REVOKE UPDATE/DELETE best-effort; for production append-only enforcement use a dedicated insert-only role.

Event vocabulary: event_type is a free string; the names the platform's views aggregate are listed in KNOWN_EVENT_TYPES (with one-line meanings) — e.g. tool.access / tool.invoked / tool.effect (tool governance), context.manifest / plan.revised / data.access (provenance), hitl.requested / approval.* / gate.resolved (human touchpoints), verification.completed, delivery.*, runtime.*. actor_kind is a closed vocabulary (ACTOR_KINDS); reference_keys(**refs) builds the correlation keys for metadata (project_id / run_id / step_id / item_id / tool_call_id / root_execution_id). The columns added in 1.0.0a1 (actor_kind, project_id, root_execution_id, source_event_id) are optional on record*(); on a database that lacks them the writer falls back to the legacy insert once and keeps going (and switches back after ensure_schema() adds them). ensure_schema() needs the table owner role: run it once when provisioning; the runtime writer only needs INSERT. Pre-existing duplicate source_event_id values block the UNIQUE index (deduplicate first); once it exists, a duplicate write makes record() return False (spilled) and record_sync() raise.

Policy Module — agenticstar_platform.policy (SDK ≥ 1.0.0a1)

Pure computation (no I/O, no agent framework): decide allow / forbid for a tool call from a two-layer policy.

  • Layers: a tenant policy (L1Policy: default profile, an unremovable floor of forbidden patterns, whether rationale bodies may be retained, version) and a project policy (ProjectPolicy: profile, deny / allow patterns, gate settings). tighten_merge(l1, project) combines them with two guarantees: the tenant floor can never be removed, and the project profile can never be looser than the tenant default. A strict project's allow list permits the listed write / destructive tools only within what the tenant L1 profile permits (since 1.0.0a3 l1_profile: it never re-enables an operation class the L1 profile forbids, e.g. destructive under a guarded tenant) — put anything that must stay forbidden regardless of profile into the tenant floor.
  • Profiles: open (everything allowed) < guarded (destructive forbidden) < strict (allowlist: reads allowed, writes / destructive only when explicitly allowed and only within what the tenant L1 profile itself permits — a project strict allowlist never re-enables an operation class the L1 profile forbids, e.g. destructive under L1 guarded; 1.0.0a3 l1_profile).
  • evaluate(policy, tool, op_class, ...) returns a Decision(mode, reason, policy_version, unregistered). The caller classifies the tool (op_class = read / write / destructive, or None for unknown); dry_run=True forbids everything but reads; mcp_server="x" matches both mcp:x:<tool> and <tool>.
  • Snapshots: EffectivePolicy.to_dict() / from_dict() round-trip and digest (SHA-256) let you record which policy a run was evaluated under and verify it later.
from agenticstar_platform.policy import L1Policy, ProjectPolicy, tighten_merge, evaluate

l1 = L1Policy.from_row({"version": 3, "default_profile": "guarded", "floor": {"forbid": ["mcp:*:delete_*"]}})
# allow patterns match tool names (plain tool names or "mcp:<server>:<tool>"), not operation classes
project = ProjectPolicy.from_json({"profile": "strict", "allow": ["write_file", "mcp:gitlab:create_*"]})
policy = tighten_merge(l1, project, project_id="p1")

decision = evaluate(policy, "delete_repo", "destructive", mcp_server="gitlab")
assert decision.mode == "forbid" and decision.reason == "floor"   # the tenant floor wins, nobody can loosen it
decision = evaluate(policy, "create_issue", "write", mcp_server="gitlab")
assert decision.mode == "allow"                                     # explicitly allowed under strict
print(policy.digest)                        # store next to the run for later verification

Platform Class Example

Below is an example of a Platform class that wraps SDK components for your agent system:

"""
Platform class example - Using AGENTICSTAR Platform SDK
"""
import asyncio
from dataclasses import dataclass
from typing import Optional

from agenticstar_platform import (
    PostgreSQLManager, PostgreSQLConfig, DataAccess,
    QdrantManager, QdrantConfig,
    EmbeddingGenerator, EmbeddingConfig,
    EventEmitter, EventType,
    SemanticMemoryClient, SemanticMemoryConfig,
    AzureBlobStorageClient, AzureBlobConfig,
    AgenticStarAuthClient, AgenticStarAuthConfig,
)


@dataclass
class PlatformConfig:
    """Platform configuration"""
    db_config: PostgreSQLConfig
    qdrant_config: QdrantConfig
    embedding_config: EmbeddingConfig
    storage_config: Optional[AzureBlobConfig] = None
    memory_config: Optional[SemanticMemoryConfig] = None
    auth_config: Optional[AgenticStarAuthConfig] = None

    @classmethod
    def from_toml(cls, path: str) -> "PlatformConfig":
        """Load all configurations from TOML file"""
        return cls(
            db_config=PostgreSQLConfig.from_toml(path, section="database"),
            qdrant_config=QdrantConfig.from_toml(path, section="rag.qdrant"),
            embedding_config=EmbeddingConfig.from_toml(path, section="rag.embedding"),
            storage_config=AzureBlobConfig.from_dict({
                # Load from environment or config
                "bucket_name": "your-container",
                "connection_string": "your-connection-string",
            }),
            auth_config=AgenticStarAuthConfig.from_config(path),
        )


class AgentPlatform:
    """
    Platform class wrapping SDK components.

    Example:
        >>> config = PlatformConfig.from_toml("config.toml")
        >>> platform = AgentPlatform(config)
        >>> await platform.initialize()
        >>>
        >>> # Use database
        >>> users = await platform.db.fetch_all("SELECT * FROM users")
        >>>
        >>> # Use RAG
        >>> results = await platform.search_knowledge("How to deploy?")
        >>>
        >>> # Clean up
        >>> await platform.cleanup()
    """

    def __init__(self, config: PlatformConfig):
        self.config = config
        self._db: Optional[DataAccess] = None
        self._qdrant: Optional[QdrantManager] = None
        self._embedding: Optional[EmbeddingGenerator] = None
        self._storage: Optional[AzureBlobStorageClient] = None
        self._memory: Optional[SemanticMemoryClient] = None
        self._auth: Optional[AgenticStarAuthClient] = None

    async def initialize(self) -> None:
        """Initialize all SDK components"""
        # Database
        db_manager = PostgreSQLManager(self.config.db_config)
        self._db = DataAccess(db_manager)
        await self._db.initialize()

        # Embedding generator
        self._embedding = EmbeddingGenerator(self.config.embedding_config)

        # Vector DB (RAG)
        self._qdrant = QdrantManager(self.config.qdrant_config, self._embedding)
        await self._qdrant.initialize()

        # Storage (optional)
        if self.config.storage_config:
            self._storage = AzureBlobStorageClient(self.config.storage_config)

        # Memory (optional)
        if self.config.memory_config:
            self._memory = SemanticMemoryClient(self.config.memory_config)

        # Auth (optional)
        if self.config.auth_config:
            self._auth = AgenticStarAuthClient(self.config.auth_config)

    @property
    def db(self) -> DataAccess:
        if not self._db:
            raise RuntimeError("Platform not initialized. Call initialize() first.")
        return self._db

    @property
    def qdrant(self) -> QdrantManager:
        if not self._qdrant:
            raise RuntimeError("Platform not initialized. Call initialize() first.")
        return self._qdrant

    @property
    def storage(self) -> Optional[AzureBlobStorageClient]:
        return self._storage

    @property
    def memory(self) -> Optional[SemanticMemoryClient]:
        return self._memory

    @property
    def auth(self) -> Optional[AgenticStarAuthClient]:
        return self._auth

    async def search_knowledge(self, query: str, limit: int = 10):
        return await self.qdrant.search(query, limit=limit)

    async def cleanup(self) -> None:
        """Clean up all resources"""
        if self._qdrant:
            await self._qdrant.close()
        if self._db:
            await self._db.close()
        if self._storage:
            await self._storage.close()
        if self._memory:
            await self._memory.cleanup()

Configuration (config.toml example)

[database]
host = "your-postgresql.postgres.database.azure.com"
port = 5432
database = "agenticai"
username = "admin"
password = "your-password"
use_azure_ad = false
pool_min_size = 2
pool_max_size = 10
# api_url = "https://your-api.example.com/db"  # Set for HTTP API mode

[database.azure_ad]
tenant_id = "your-tenant-id"
client_id = "your-client-id"
client_secret = "your-client-secret"

[auth.agenticstar]
base_url = "https://auth.agenticstar.tm.softbank.jp"
api_key = ""
timeout = 30.0
max_retries = 3

[rag.embedding]
# provider = "azure" (default): Azure OpenAI deployments path
base_url = "https://your-openai.openai.azure.com/"
api_key = "your-api-key"
model = "text-embedding-3-small"
dimensions = 1536

# OpenAI-compatible endpoints (e.g. embed-v-4-0 on Azure AI inference) — SDK >= 0.5.24:
# [rag.embedding]
# provider = "openai"
# base_url = "https://your-resource.services.ai.azure.com/models"  # include /models
# api_key = "your-api-key"
# model = "embed-v-4-0"   # "openai/embed-v-4-0" also accepted (prefix is stripped)
# dimensions = 1536       # api_version is not used with provider = "openai"

[rag.qdrant]
url = "http://localhost:6333"
collection_name = "knowledge_base"
vector_size = 1536

[storage.azure]
bucket_name = "your-container"
connection_string = "DefaultEndpointsProtocol=https;..."
prefix = "uploads/"

[memory.llm]
model = "azure/gpt-4"
api_key = "your-api-key"
base_url = "https://your-openai.openai.azure.com/"
api_version = "2024-02-15-preview"

[memory.embedder]
model = "azure/text-embedding-ada-002"
api_key = "your-api-key"
base_url = "https://your-openai.openai.azure.com/"
api_version = "2024-02-15-preview"

# OpenAI-compatible embedder (e.g. embed-v-4-0 on Azure AI inference) — SDK >= 0.5.24:
# [memory.embedder]
# model = "openai/embed-v-4-0"
# api_key = "your-api-key"
# base_url = "https://your-resource.services.ai.azure.com/models"  # include /models;
#                       # without base_url the client would connect to api.openai.com

API Reference

Generated API documentation is available under docs/ (pdoc). The developer portal SDK guides are the narrative reference.

Changelog

1.0.0 (2026-09-13) — ASTER 3.0 GA(1.0.0a3 + 0.5.41 の統合)

  • 1.0.0a3(3.0: policy l1_profile / schema 2、audit の 3.0 列、ensure_schema の 3.0 列)に、0.5.41 の PostgreSQLManager.execute_query() の結果セット判定を Describe ベースにする修正WITH … SELECT / VALUES / TABLE の行喪失、agentcore#330)を取り込み、1.0.0 として確定。1.0.0a3 からの API 変更なし(policy の保存形 = schema 2、digest 互換)。feature_3 → feature の統合に伴い、autonomous / executor の pin をこの版に揃える(PO 2026-09-13)。

1.0.0a3 (2026-09-09) — policy: プロジェクトの allowlist はテナントの許可範囲を広げない

  • EffectivePolicyl1_profile(テナント L1 の default_profile)を追加し、schema_version2 に上げた。to_dict()l1_profile が入り、from_dict()l1_profile 必須・profilel1_profile より緩い保存形を拒否する(1.0.0a2 の保存形 = schema 1 は読めない。fail-closed)。digest は新しい保存形で計算されるので、両側(解決する側 / 判定する側)を同じ版にそろえること。
  • evaluate(): strict の allowlist は L1 が profile で禁じない操作クラスにだけ効く。L1=guarded(destructive を forbid)のテナントで project を strict + allow にしても destructive は forbid(理由 profile)のまま。project を重ねた許可集合は L1 単独の許可集合の部分集合になる(L1=strict の allowlist は L1 の機構そのものなので write / destructive とも効く)。
  • profile_permits(profile, op_class) を export(profile が単独でその操作クラスを許しうるか)。
  • 切替手順(非互換): 解決する側(executor / cli-api)と判定する側(worker)の版が違う間は、相手の保存形を読めず fail-closed(新しい実行が全 forbid)になる。worker は実行開始時に一度だけ policy を束縛するので、旧 worker で実行中の処理には拒否は届かない。切替は fire を止める → in-flight を完走させる(warm pool の旧 Pod を drain)→ executor / cli-api / worker のイメージを同時に切り替える → 再開 の順で行い、片側だけの先行切替はしない。

1.0.0a2 (2026-09-07) — 公開面の整理(低レベル API としての一貫性)

  • ActionAudit(source=...): source は「書き手のコンポーネント名(任意の文字列)」。エラー文と docstring から内部の配備名(worker / cli-api)の前提を外した。
  • ensure_schema() が作る表に 1.0.0a1 で追加した 4 列(actor_kind / project_id / root_execution_id / source_event_id)と index(source_event_id の partial UNIQUE、project_id(root_execution_id, occurred_at, id))を含めた。旧 SDK が作った表には ACTION_AUDIT_UPGRADE_DDLADD COLUMN IF NOT EXISTS)で列を足し、旧 INSERT に落ちていた writer も新 INSERT に戻す。owner ロールで初期化時に 1 回呼ぶ(実行時の writer は INSERT 権限だけ)。migration 管理の環境では従来どおり migration が正。
  • KNOWN_EVENT_TYPES(既知の event_type と意味)を追加(情報提供。強制しない)。ACTION_AUDIT_DDL / ACTION_AUDIT_INDEXES / ACTION_AUDIT_UPGRADE_DDL を export。
  • agenticstar_platform.policy の説明を製品の言葉に書き直し(内部の endpoint / 表名 / 要件番号への依存を外した)。tighten_merge の保証を正確に記載(floor は外せない・profile は緩められない。strict の allowlist は明示した tool を許す)。README に Policy Module の節を追加。

1.0.0a1 (2026-09-07) — ASTER 3.0 alpha(旧 0.6.0 予定分)

  • ASTER 3.0 Phase A — audit(R-B2 / R-B4 / R-B6)
    • agent_action_audit の 3.0 列を writer が書く: actor_kind(閉語彙 agent / human / system / human_external / unknown。省略時は actor_type から写像)、project_id(UUID)、root_execution_id(TEXT)、source_event_id(重複除去キー。^[A-Za-z0-9_.:@+-]{1,160}$)。既存の呼び出し形(actor_type のみ)はそのまま通る。
    • worker 発(actor_kind='agent')で actor_ref が無い行は ActionAudit(agent_ref=...) の値(既定 agent:<source>)を自動付与(nullable にしない)。人 / system の決定イベント(approval.* に加え gate.resolved / content.deleted / forensic.* / policy.changed / item.quarantine_released / workitem.*)は actor_ref 必須(欠落は ValueError)。
    • 旧 DDL 互換: 3.0 列が無い DB では UndefinedColumn を 1 回検出して legacy INSERT(19 列)に固定する(新 SDK を先に配っても監査行を失わない。DDL 適用後は再起動で新列に戻る)。
    • reference_keys(**refs): metadata に入れる参照キー(project_id / run_id / step_id / item_id / tool_call_id / root_execution_id)の生成。
    • row_hash の正規化仕様を ROW_HASH_SPEC.md に明文化し、front / admin の Node 実装向け fixture(row_hash_fixture.json)を同梱。ハッシュ規則自体は不変(新列は None 除外規則で従来行と同じ値になる)。
  • agenticstar_platform.policy(新規、R-C1 / R-C2): tighten_merge(L1, project)(2 層・floor 不変・profile は厳しい方)、EffectivePolicyto_dict / from_dict / digest = annotation agenticstar.io/policy-snapshot)、evaluate()(instructions/00 §7 の優先順位: 取得不能 → forbid / floor・明示 forbid / 評価不能 / unknown(open・guarded は allow + unregistered、strict・委譲・予行演習は forbid)/ 分類あり → open 全 allow・guarded は destructive forbid・strict は allowlist)。executor と cli-api / worker が同じ実装を使う。
  • 前提 DDL: dbmigration 01 Phase A(A-8 監査列)。sbtestfeature には 2026-09-07 に expand 部分を投入済み。
  • 版の考え方(alpha 期間の方針。1.0.0 GA で終了): 3.0 の SDK は 1.0.0aN(alpha)→ 1.0.0bN1.0.0rcN1.0.0 の pre-release 系列で配布した。1.0.0(2026-09-13)は final 版なので、>=0.5 のような範囲指定の更新対象になる(既存の BYOA runner が範囲 pin なら次回の更新で 1.0.0 を取る。policy の保存形は schema 2 = 1.0.0a3 と同じ、execute_query は 0.5.41 の修正込み)。取り込む側は従来どおり exact pin(==1.0.0)を推奨。pip / uv は final 版(0.5.x)が存在する限り pre-release を 範囲指定(>=0.5)では選ばないため、既存顧客の BYOA runner に 3.0 alpha が自動で入ることはない(pre-release しか存在しない要求では例外的に選ばれる = PEP 440 の規則)。取り込む側は ==1.0.0a1 と明示 pin する(exact pin なら --pre 不要)。

0.5.41 (2026-09-09)

  • Fix: PostgreSQLManager.execute_query()WITH ... SELECT / VALUES / TABLE の行を黙って捨てていた問題を修正(agentcore#330) — 結果セットの有無をクエリ文字列の先頭語(SELECT で始まるか / RETURNING を含むか)で判定していたため、先頭が SELECT でない行返却文は conn.execute() 側へ流れ、{"success": True, "data": {"result": "SELECT 1"}} のように行が失われていた(エラー無し)。判定を PostgreSQL の Describe 結果(PreparedStatement.get_attributes()、または行が返ったこと)に置き換え、結果セットを持つ文は先頭語に関係なく List[Dict] を返す。0 列の結果セット(SELECT FROM t)も行があれば [{}, ...] として保持する(0 列かつ 0 行は結果セットと区別できず {"result": "SELECT 0"} になる既知のエッジ。列を 1 つ以上返せば通常の [])。
    • 後方互換: 結果セットを持たない文(INSERT/UPDATE/DELETE/DDL)は従来どおり {"result": "<status>"}; 区切りの複数文は、旧実装で simple protocol に流れていた経路(パラメータ無し・先頭が SELECT でなく RETURNING を含まない)だけ従来どおり実行し status dict を返す。それ以外の複数文(SELECT 1; SELECT 2 やパラメータ付き)は従来と同じく DB_QUERY_ERROR複数文は行を返さない(行返却文が含まれていそうな場合は warning ログ)。行が必要なら 1 文ずつ呼ぶこと。
    • 実装は無名 prepared statement(prepare(query, name=""))を使い、asyncpg 0.29/0.30 でも従来の conn.fetch() と同じ経路(PgBouncer transaction pooling でも名前付き statement を残さない)。command_timeout は prepare と fetch で共有し、従来どおり 1 クエリ分の予算のまま。
    • 挙動差分: RETURNING 無しの data-modifying CTE(WITH ... INSERT ...)は旧実装では RETURNING 文字列の有無に依存して [] になることがあったが、結果セットが無いので status dict になる。RETURNING を含む列名・コメントによる誤判定も無くなる。
    • 回帰テスト: sdk/tests/db/test_manager_execute_query_dispatch.py(オフライン)。実 PostgreSQL 16 でも asyncpg 0.30 / 0.31 の両方で CTE / VALUES / TABLE / 0 列 SELECT / SHOW / EXPLAIN / INSERT / UPDATE / DDL / 複数文 / NUL パラメータの各経路と pg_prepared_statements が増えないことを確認済み。
    • DataAccess.execute_query()、autonomous cli-api の /db/executeUnifiedDataAccess → 本メソッド。SDK 側の ApiPostgreSQLManager はこのエンドポイントを呼ぶ HTTP クライアント)はいずれも本メソッドに委譲しているので同時に解消される。

0.5.40 (2026-09-01)

  • Guardrail Alerts: 分類詳細化(molt#1415 フォローアップ)
    • SOURCE_SURFACESagent_worker を追加(pod worker 面の producer 用)。guardrail_alerts / 集計の両 writer で受理。
    • guardrail_alertspolicy_category 列(閉語彙) を追加 — regex / LLM semantic 層の攻撃方式分類(prompt_injection / system_prompt_extraction / implementation_access / credential_request / file_system_access / security_bypass / custom_policy / unclassified)。GuardrailAlertWriter は閉語彙外の値を ValueError で同期拒否する(自由文・rule 名の流入防止)。既存デプロイの列追加・CHECK 差し替えは dbmigration 側 migration の責務(ensure_schema の DDL は新規作成時のみ反映)。
    • SelfHarm 防波堤の再帰走査を prompt_shield_origin / policy_category にも適用。
  • Security: PromptShieldResultuser_prompt_attack / documents_attack を追加 — direct(userPrompt)/ indirect(documents)の攻撃経路内訳。従来はウィンドウ横断で OR に潰しており guardrail_alerts.prompt_shield_origin を埋める手段がなかった。両フィールドは optional(None = 未取得。False = 評価済み非検知と区別)。attack_detected の判定は不変(後方互換)。

0.5.39 (2026-08-27)

  • Fix: tools_used の metadata 退避判定で生値を比較していた問題を修正(0.5.38 の追補) — 退避要否を != で判定していたため、生値の __eq__ が呼ばれていた。numpy 配列のように真偽が曖昧な型では例外になり、telemetry 保存がまるごと失敗しうる。判定を型ベース(plain int かつ列へ格納できたか)に変更し、生値には一切比較を行わない。
  • Fix: metadata へ退避する際に setdefault を使っていたため、metadata['tools_used'] が既にある場合に top-level の生値が失われていた — 0.5.37 以前は未知フィールドの代入で top-level 値が metadata 側の同名キーを上書きしていたため、その動作へ揃えた(上書き代入)。
  • Docs: README の known columns 節から「不正値で書き込みが失敗することはない」という過剰な記述を削除。保証されるのは「列の値が原因で INSERT が落ちないこと」であり、metadata へ退避した生値の JSON 化は他の metadata フィールドと同じ制約に従う。

0.5.38 は上記2点を含むため 0.5.39 の使用を推奨(0.5.38 でも tools_used 列への保存自体は動作する)。

0.5.38 (2026-08-27)

  • Fix: ai_telemetry.tools_used が named column に入らず metadata へ落ちていた問題を修正TelemetryAccess.save_telemetry()known_fields / INSERT 文に tools_used が無く、producer が算出した使用ツール数が jsonb 側へ流れて列は常に NULL だった。結果、この列を読む監査 UI / 外部ログ API(toolsUsed)が常時空欄になっていた。列(integer)へ直接保存するよう修正し、list_telemetry() の SELECT にも追加。
    • 型契約を固定: int / list / tuple を受け付け、list・tuple は要素数へ正規化する(呼び出し側が「回数」と「一覧」のどちらを渡しても列は int)。
    • 未計測は NULL、計測した上で 0 回だった場合は 0 として区別する。bool / 負値 / PostgreSQL integer の範囲外 / 解釈不能な型は列を汚さず NULL(範囲外を送って INSERT ごと失敗させない = telemetry 保存失敗で行を丸ごと失わない)。
    • 後方互換: 列が生値を完全に表現できない場合(list の内訳・型違い・範囲外)は生値を metadata.tools_used へ残すため、0.5.37 以前に metadata へ入っていた情報は失われない。plain int の場合のみ列が完全な表現なので metadata へは重複させない。
    • 過去行の backfill は行わない。
    • ⚠️ この列を読む API 利用者向け: 値は「ツール名のカンマ区切り文字列」ではなく 使用ツール数(integer) で、ツールを使わなかった実行は null ではなく 0 を返す(null は未計測の意味)。
    • 併せて README §Telemetry に known columns(予約フィールド名)一覧 を追加。

0.5.37 (2026-08-27)

  • Fix: OpenAI 互換 LLM 変換で明示 base_url を Mem0 の openai_base_url へ保持convert_llm_to_mem0() の openai 分岐が base_url を捨てていたため、private gateway 指定時でも Mem0 の fallback で memory add が公式 api.openai.com へ向かい得た(機能停止 + credential 誤送信境界)。embedder 変換(v0.5.24 で対応済み)と同一契約に揃え、LLM/embedder の endpoint parity を offline regression テストで固定(sdk/tests/memory/test_semantic_converter_base_url.py)。base_url 未指定時の公式 OpenAI fallback と他プロバイダ分岐は不変。

0.5.36 (2026-08-26)

  • Fix: memory の LLM/Embedder 変換ロジック二重実装を解消(モジュール関数へ一本化)SemanticMemoryClient_normalize_provider / _parse_model_string / _get_api_key / _convert_llm_to_mem0 / _convert_embedder_to_mem0 を同名モジュール関数への委譲に変更。二重実装のドリフトによる実バグ2件を修正(発見元: 利用チームのコードレビュー報告 = agentcore #307):
    • SemanticMemoryClient 経由の openai 互換 embedder で base_urlopenai_base_url として引き渡されず、公式 api.openai.com へ接続してしまう問題(公開 convert_embedder_to_mem0 にのみ入っていた v0.5.24 fix を client 実使用経路にも適用)
    • 公開 convert_llm_to_mem0 の azure 変換に gpt-5.x 分類 fix(model キーの mem0_classification_model() 正規化)が無く、Azure gpt-5.x デプロイで mem0 が max_tokens を送出して HTTP 400 になる問題(instance メソッド側にのみ入っていた fix を公開関数にも適用)
  • Fix: SemanticMemoryClient.cleanup() docstring から async with 例を削除 — async context manager は未実装のため、記載例に従うと TypeError になっていた。
  • Fix: _ensure_qdrant_collection が作成する QdrantClient を close するように(クライアント初期化ごとの接続リーク解消)。

0.5.35 (2026-08-25)

  • Feat: Local Integration Lab をパッケージ同梱pip install 'agenticstar-platform[lab]' + python -m agenticstar_platform.lab だけで、PostgreSQL / Qdrant / S3 互換 storage (MinIO) を version 固定 Docker Compose で起動し、synthetic 文書の ingest → retrieve → artifact/result persist → terminal outcome を credential 不要で完走できる(doctor サブコマンドで read-only 診断、--reset で破棄)。cloud account・production credential・.env 手編集は不要。詳細は Quick Start §2.5 と agenticstar_platform/lab/README.md
  • Fix: QdrantManager 非 auth 経路で QdrantConfig.check_compatibility が黙殺されていた問題を修正 — auth_token_provider なしの経路では設定値が QdrantClient へ渡らず、check_compatibility=False を指定しても client/server の version check(と version ずれ時の警告)が常に実行されていた。
  • Change: [rag] / [all] extra の qdrant-client floor を >=1.13.0 — 1.12 以前の qdrant-client は check_compatibility 引数を受け付けないため(auth 経路は従来から 1.12 以前で TypeError になっていた既存不整合の修正を兼ねる)。

0.5.34 (2026-08-24)

  • Feat: MCP トークンの expires_at=null(期限なし)を受理 — MCP 認証プロファイル 3 本柱化で追加された個人トークン (PAT, custom_config.authMode='api_token') は長期/無期限のため、供給 API (chatboardlogin) が expires_at: null を明示返却する。従来の get_mcp_tokens() は expires_at 欠損を INVALID_TOKEN_DATA として当該 provider のトークンを破棄していたため、PAT が一切利用できなかった。MCPTokenInfo.expires_atOptional[datetime] = None に緩め(None = 期限なし)、client 側は null / キー欠損を正常形として受理する。null 以外の不正値は provider 単位の INVALID_EXPIRES_AT統一(意図的なエラーコード変更: 空文字・0 等の falsy は従来 INVALID_TOKEN_DATA、truthy な非文字列は従来 broad except へ漏れて取得全体が UNKNOWN_ERROR になっていた)。cli-api と worker の両方が本バージョンで揃って初めて PAT が通る(トークンは cli-api → worker の 2 段で同モデル検証されるため)。

0.5.33 (2026-08-21)

  • Fix: rollup_llm_usage_daily() の複数レプリカ同時実行による llm_usage_daily_pkey 衝突を解消(autonomous #2098)— 複数レプリカが毎時タイマーで rollup を並走させると、READ COMMITTED 下で後発の DELETE が先発コミット前の行を見えず 0 行削除 → INSERT が PK 衝突していた(stg 実測 38件/24h)。SQL 関数冒頭に pg_try_advisory_xact_lock(hashtext('rollup_llm_usage_daily'), p_day - date '2000-01-01') ガードを追加し、ロックを取れなかった側は skip(勝ち側が同一 ledger から同一集計を書くため冗長)。関数は ensure_schema() の CREATE OR REPLACE で配布されるため、ensure_schema() を実行するコンポーネント(cli-api 等)が 0.5.33 で起動して初めて DB に反映される点に注意(旧版コンポーネントの再起動は旧定義へ巻き戻すため、混在期間後に pg_get_functiondef で確認推奨)。

0.5.32 (2026-08-12)

  • Guardrail Alerts writer を追加GuardrailAlertWriter / GuardrailAlertAggregates、molt#1415 Phase1-A)— Admin トリアージ用 guardrail_alerts(非権威的運用ビュー・権威は行為監査台帳)と非連結日次集計 guardrail_alert_daily_aggregates の公開 producer writer。行スキーマに利用者 ID 列なし・SelfHarm は行構築を同期 ValueError で拒否(表記ゆれ正規化 + str-Enum .value 対応)し集計のみへ、という PO 決定(AI 倫理レビュー)を構造的に強制。event_key v2 冪等(replay が Admin lifecycle を巻き戻さない、実 DB 検証済み)。severity はカテゴリ別実測値(threshold 代用禁止)。権限は行 = INSERT のみ / 集計 = INSERT + UPDATE(count) + SELECT(count)。配送は行為監査と同一の bounded FAF + spill 契約。

0.5.31 (2026-08-10)

  • 行為監査モジュール agenticstar_platform.audit を追加ActionAudit / GatewayActionAudit / ActionAuditWriteError / canonical_digest)— 承認・ツール認可・ポリシー違反・キルスイッチ・外部エージェント呼び出し等の行為イベントを append-only 台帳(agent_action_audit / llm_gateway_action_audit)へ記録する純インフラ。書き込みモードは 3 種: record() = プロセス生存中 at-least-once(bounded retry → 失敗時は action_audit_spill マーカー付きログ行へサニタイズ済み row を JSON 出力)/ record_sync() = audit-before-act(DB 書き込み失敗時 ActionAuditWriteError 送出 — 監査に書けない承認は成立させない)/ record_nowait() = ホットパス用 fire-and-forget(backlog 上限 512、開始前 cancel も spill 退避。プロセス即死時は失われうる best-effort)。本文は digest 化して渡す使用契約(canonical_digest)+ フィールド上限(reason 300 字截断 / payload_digest は 64 桁小文字 hex のみ / metadata 2KB 超は digest 化 + deep-copy 正規化)で誤混入時の被害量を制限(機密の自動検出・redaction は行わない)。approval.*actor_ref 必須(欠落は同期 ValueError)。追加依存なし(標準ライブラリのみ・core に同梱)。

0.5.30 (2026-08-07)

  • Fix: run_marketplace_agent / arun_marketplace_agentdata_access 省略時に必ず AttributeError で落ちる問題を修正db_config / PostgreSQLConfig.from_env() フォールバック経路が生の PostgreSQLConfigDataAccess へ渡していたため、'PostgreSQLConfig' object has no attribute 'initialize' で agent 未実行のまま即死していました(0.5.29 のドキュメント通りの最小構成 run_marketplace_agent(my_agent) が全滅する致命バグ)。create_postgresql_manager(config) でマネージャ化してから接続するよう修正。api_url(DB_API_PROXY_URL)設定時は runner が token_provider を供給できないため、明示的に MarketplaceRunnerConfigError を送出します。フォールバック経路の回帰テストを tests/runner/test_marketplace_runner_db_fallback.py に追加(0.5.29 の contract テストは全ケースで data_access= を注入していたため本経路のカバレッジがゼロでした)。

0.5.29 (2026-08-01)

  • Marketplace runner を追加run_marketplace_agent / arun_marketplace_agent, molt #1409) — ローカルで動いた agent 関数をそのまま Marketplace 互換の終端ライフサイクル(identity 検証 → 入力取得 → 実行 → 結果保存/webhook → terminal を正確に 1 回 → cleanup)へ渡せます。従来この main ボイラープレートは開発者の手書きで、終端イベントの送り漏れ・二重送信は開発者品質に依存していました。identity env(EXECUTION_ID 等)の欠落時は agent を呼ばずに MarketplaceRunnerConfigError で停止します。pip install 'agenticstar-platform[runner]'(新 extra: db + webhook 相当)。契約は tests/runner/ の contract テストで固定(success / agent 例外 / 入力取得失敗 / 保存失敗 / webhook 失敗の 5 分岐 × terminal exactly-once)。

0.5.26 (2026-07-27)

  • [security] から boto3[security-aws] へ分離 — 0.5.25 で AWSSecurityClient のために [security] へ boto3 を追加しましたが、[storage-azure,security] を pin している Desktop ビルドは boto3 を意図的に外して 30MB 削減しているため、そこへ boto3 が戻ってしまいます。AWS 系の Content Safety を使う場合は pip install 'agenticstar-platform[security-aws]' を指定してください([all] には従来どおり含まれます)。

0.5.25 (2026-07-27)

Packaging: 軽量インストールが実際に機能するようになりました(従来は [all] 以外が壊れていました)。

  • import agenticstar_platform が core install で成功する__init__.py が全モジュールを無条件 import していたため、pip install agenticstar-platform(core)は ModuleNotFoundError: asyncpg[db]ModuleNotFoundError: openaiimport 自体が失敗していました。PEP 562 の遅延 import に変更し、pyproject の extra 分割どおりに動作します。公開 API 名・import の書き方は変更ありません。
  • extra 不足が actionable なエラーになる — 生の ModuleNotFoundError ではなく「どの extra を入れれば直るか」を示します。実装内部の import ミスや循環 import を extra 不足と誤診しないよう、変換対象はその extra が担う依存が実際に無い場合に限定しています。
  • WebhookEventHandler / create_marketplace_handler は aiohttp 不在をシンボル取得時に検出 — 従来は aiohttp が無くてもオブジェクトを生成でき、実行時にログを残して webhook を送らず沈黙していました。
  • pydantic>=2.0.0 を core 依存に追加auth モジュールが使用しているにもかかわらず未宣言で、[all] では他パッケージの推移的依存で偶然動いていました。
  • [security]boto3 を追加AWSSecurityClient(Comprehend / Bedrock Guardrails)に必須ですが未宣言でした。
  • [all][security] の依存(google-cloud-dlp / google-cloud-aiplatform)を包含[all] なのに GCPSecurityClient が使えない状態を解消しました。
  • README の Quick Start が実行可能に — 従来は async def main() を定義するだけで呼び出しがなく、コピーしても何も起きませんでした。外部サービス不要で progress → terminal outcome まで通る最小例に差し替え、README 本文からコードを抽出して実行する drift テストを追加しています。

0.5.24 (2026-07-21)

RAG/Memory: OpenAI-compatible embedding endpoints (embed-v-4-0 class) support.

  • RAG: EmbeddingConfig gains a provider field ("azure" default / "openai")provider = "openai" targets OpenAI-compatible endpoints such as embed-v-4-0 on Azure AI inference (base_url must include /models; api_version is not used). Model strings with a LiteLLM-style prefix (azure/... / openai/...) derive the provider automatically and the prefix is stripped from the deployment/model name.
  • Memory: convert_embedder_to_mem0() passes openai_base_url for the openai provider — when [memory.embedder] uses an openai/... model with base_url set, the Mem0 embedder now connects to that endpoint. ⚠️ Without this release, the base_url was silently dropped and the client connected to api.openai.com, causing 401s with non-OpenAI keys.
  • RAG: embedding inputs are truncated with a model-aware token budget — 8,000 tokens for 8k-class models, a 100k sanity cap for long-context embed-v* models; disallowed_special=() so special-token literals (e.g. <|endoftext|>) in documents cannot crash encoding; character-based fallback when tiktoken is unavailable.

0.5.23 (2026-07-09)

Security: Azure PII detection batching and quota-aware 429 retry (LLM Gateway 502/504 incident fix).

  • Security: detect_pii_batch() — Azure PII calls are batched at 5 documents/request — all sliding windows across the input texts are packed into a single documents array (Azure sync PII allows 5 docs/request), cutting Azure call volume by up to 5×. Long conversation histories previously issued one Azure call per text element (a captured 743-message request = 1,314 calls vs the S0 limit of 300 req/min), exhausting the quota in a single request. SecurityClientBase gains a sequential default implementation, so AWS / GCP clients inherit the API unchanged. detect_pii() is now a single-text wrapper over the batch path — external behavior (fail-closed empty string, error codes, signature) is unchanged.
  • Security: Azure PII 429s are retried honoring Retry-After, then abort with RATE_LIMITED — throttled requests are retried (default 2 retries, AGENTICSTAR_AZURE_LANG_429_RETRIES, delay capped at 5s). If throttling persists, the remaining batch chunks are aborted (no further quota pressure) and unresolved texts fail with error_code="RATE_LIMITED", letting callers surface 429 + Retry-After to their clients instead of a retry-inducing 502. Previously any non-200 (including 429) failed closed immediately with no retry.
  • Security: fail-closed hardening for partial batch responses — a 200 response missing a submitted document (absent from both documents and errors) now fails that text closed instead of silently passing it through unscanned.

0.5.22 (2026-07-08)

Security (GCP Content Safety), RAG error hierarchy, and DB identifier validation.

  • Security: GCP Content Safety gains a Vertex AI Safety Filters path (+ Gemini judge)GCPSecurityClient can now moderate content via Vertex AI safety filters across all Marketplace regions, with a Gemini-based semantic judge as an additional layer. Adds google-cloud-aiplatform>=1.60.0 to the [security] extra. (#1952)
  • Security: guardrail input-inspection window count is now env-configurable — the number of sliding windows scanned on large inputs is tunable, relaxing the earlier "large-input tail not inspected" gap (P3-1).
  • RAG: QdrantConfigError folded into the VectorStoreError hierarchy; initialize() is idempotent — init-failure wrapping now passes already-typed exceptions through (config errors are no longer mislabeled), and calling initialize() on an existing collection re-ensures the payload indexes instead of raising. (#1938)
  • DB: identifier validation consolidated into common.validation; errors returned as a uniform dictselect_one returning None on error is now documented, and identifier-validation failures return a consistent shape. (#1959)

0.5.21 (2026-06-25)

Metering: persist missing_reason on the ledger.

  • UsageMeter.record(..., missing_reason=...) + new missing_reason column on llm_usage_ledger — the usage-missing reason (provider_omitted / stream_interrupted / …) is now stored on the row (previously logs only), so offline exports can distinguish cost_usd IS NULL (unpriced) vs usage_status='missing' vs true-zero. Present rows store NULL (no contradiction). ensure_schema() adds the column idempotently (ADD COLUMN IF NOT EXISTS) — backward-compatible, propagates to existing monthly partitions; no change to existing columns.

0.5.20 (2026-06-24)

Metering: billing-clean cost storage + cache-read fallback.

  • round_cost_usd helper + UsageMeter.record stores cost as a rounded Decimal — avoids float-repr drift (0.00089999…) in the cost_usd numeric column; 8-dp rounding does not change billing sums, and NaN/Inf are stored as NULL. Exported from both agenticstar_platform and agenticstar_platform.metering.
  • extract_usage reads top-level cache_read_input_tokens as an additional cached_tokens fallback (complements the 0.5.19 details-based extraction), improving cache-aware cost on the token-only path. No public API change.

0.5.19 (2026-06-20)

Metering cost-accuracy fixes (cache-aware). Supersedes 0.5.18.

  • default_cost_fn fallback applies prompt-cache pricing — passes cache_read_input_tokens / cache_creation_input_tokens to litellm.cost_per_token when completion_cost(response) is unavailable, so cache-heavy calls are no longer priced at the full input rate.
  • extract_usage covers Responses API + cache-creation — reads cached_tokens from input_tokens_details (Responses) as well as prompt_tokens_details (Chat), and propagates cache_creation_input_tokens (Anthropic). Previously cached tokens on Responses calls were missed on the token-only/fallback path. No public API change.

0.5.17 (2026-06-19)

  • Security: AWS PII detection now defaults to Bedrock Guardrails (multilingual)AWSSecurityConfig gains a pii_service field ("bedrock_guardrails" default / "comprehend" legacy). AWS detect_pii() routes through Bedrock Guardrails sensitiveInformationPolicy by default, fixing multilingual (including Japanese) PII masking — Amazon Comprehend DetectPiiEntities only supports en / es (previously ja etc. slipped through and raised a ValidationException). ⚠️ Behavior change: with the new default, AWS PII requires guardrail_id to be set (otherwise it returns NOT_CONFIGURED); set pii_service="comprehend" to keep the legacy en/es path. Configs that already set pii_service explicitly are unaffected.

0.5.16 (2026-06-14)

Marketplace SDK reliability fixes (surfaced while building agents from the guides alone):

  • Config: from_toml() resolves ${ENV} placeholders and uses the stdlib tomllib (no external toml dependency). host = "${POSTGRESQL_HOST}"-style values in config.toml are expanded from the environment; unresolved placeholders are left intact. Supports ${VAR} and ${VAR:-default}.
  • Memory: mem0 2.x compatibilitySemanticMemoryClient.search() / get_all() now use mem0 2.x filters / top_k internally (the public user_id / limit arguments are unchanged). Azure gpt-5.x / o-series memory models no longer fail with max_tokens is not supported (the unsupported parameter is suppressed; the real Azure deployment is still targeted). mem0ai is pinned to >=2.0.0,<3.0.0.
  • Events: EventEmitter.drain() — drives registered handlers (e.g. the marketplace webhook handler) for non-SSE flows. emit_event(...) only enqueues; without an SSE consume_events() loop, call drain() so handlers actually fire (previously emit + cleanup silently dropped events). The [webhook] extra now includes aiohttp (required by WebhookEventHandler); [all] includes it too.
  • Storage: StoragePaths.input_uploads_prefix(user_id, conversation_id, message_id) — builds the owner-scoped prefix (users/{user_id}/uploads/{conv}/{msg}) for input attachments uploaded from the chat UI. Use with download_objects_by_prefix.
  • Runtime: wait_for_egress() — waits for the egress sidecar to accept connections before the first outbound call, avoiding a startup race that could skip first-turn input moderation / PII.
  • PodRuntime: injectable self scale-downPodRuntime(..., scale_down_callback=...); when omitted and no bundled scaler is present, scale-down is skipped cleanly instead of raising No module named 'src'.

0.5.15 (2026-06-13)

  • New: Metering module (UsageMeter) — dedicated LLM usage & cost ledger. meter.record(...) computes cost from a response/usage and writes one row per call to llm_usage_ledger; rollup_recent() / daily_cost(...) provide daily aggregation and cost-visualization queries; ensure_schema() creates the (portable) tables/rollup function idempotently. Cost is pluggable — default default_cost_fn uses litellm if installed (long-context / cache / tier aware), gracefully records tokens-only (cost_usd = NULL) when litellm is absent, and cost_fn= overrides. Agent-logic agnostic; identical for self-hosted and Marketplace BYO. Exports: UsageMeter, default_cost_fn, extract_usage.

0.5.7 (2026-05-10)

  • Security: PII confidence threshold per-calldetect_pii() now accepts an optional confidence_threshold parameter on Azure / AWS / GCP clients (and the SecurityClientProtocol / SecurityClientBase). Passing None falls back to the value in *SecurityConfig.pii_confidence_threshold. This lets a single long-lived SecurityClient instance serve callers that need different thresholds, instead of constructing a new client per request. Backward compatible — existing callers that omit the new argument get the previous behavior.
  • Security: GCP threshold now respects configGCPSecurityClient.detect_pii() previously hardcoded a LIKELY (likelihood ≥ 4) cutoff and ignored GCPSecurityConfig.pii_confidence_threshold. It now compares likelihood / 5.0 against the configured threshold, matching Azure / AWS behavior. With the default pii_confidence_threshold = 0.7 the effective cutoff stays at likelihood ≥ 4, so most callers see no change. Callers that had set pii_confidence_threshold below 0.7 will start seeing additional POSSIBLE (likelihood 3) findings.
  • Reuse the client to avoid leaksAzureSecurityClient (and AWS/GCP equivalents) hold an httpx.AsyncClient (TLS context + connection pool) internally. Construct one client per process and call await client.close() on shutdown (or use async with); creating a new client per request without closing leaks resources.

0.5.2 (2026-03-28)

  • Memory: Removed episodic memory (Graphiti/FalkorDB)episodic.py was unused dead code. SDK now provides semantic memory (Mem0) only.
  • Extras: [semantic] / [episodic] replaced with [memory] — unified extra for Mem0-based semantic memory.
  • Extras: [all] no longer includes graphiti-core[falkordb].
  • README updated to reflect episodic memory removal.

0.5.0 (2026-03-25)

Breaking Changes:

  • DB: DataAccess now takes a manager instance instead of (config, use_proxy, token_provider). Callers create PostgreSQLManager or ApiPostgreSQLManager and pass it directly.
  • DB: use_proxy parameter removed from DataAccess, create_postgresql_manager().
  • DB: api_proxy_url renamed to api_url in PostgreSQLConfig.
  • DB: ApiPostgreSQLManager exported as public API for HTTP API access.

Improvements:

  • DB: is_initialized() method added to both PostgreSQLManager and ApiPostgreSQLManager.
  • Qdrant: prefer_grpc / check_compatibility are now explicit QdrantConfig fields (no longer hardcoded based on auth_token_provider).
  • Error messages no longer reference use-case specific terms (CLI/Desktop mode).

0.4.0 (2026-03-21)

  • Security: Prompt Shield documents trimming - check_prompt_shield() now trims each document to 10,000 characters to comply with Azure API limits. Previously, WebFetch results exceeding 10,000 characters were blocked even without violations.
  • Security: PII detection language support - detect_pii() now accepts a language parameter (default: "ja") for accurate multi-language PII detection. Previously hardcoded to Japanese.
  • Security: Protocol/ABC updated - SecurityClientProtocol and SecurityClientBase updated with language parameter in detect_pii().

0.3.2

  • Storage module: Multi-cloud support (Azure Blob, S3, GCS)
  • Auth module: AgenticStar Auth API client
  • Memory module: Semantic memory (Mem0)

Version

1.0.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agenticstar_platform-1.0.0.tar.gz (822.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agenticstar_platform-1.0.0-py3-none-any.whl (271.5 kB view details)

Uploaded Python 3

File details

Details for the file agenticstar_platform-1.0.0.tar.gz.

File metadata

  • Download URL: agenticstar_platform-1.0.0.tar.gz
  • Upload date:
  • Size: 822.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for agenticstar_platform-1.0.0.tar.gz
Algorithm Hash digest
SHA256 50b80093ac7b4326478b11df0c301308baea7787d74fba70ac60efbfb64569d5
MD5 f219ea21b0f2f043a584ec67547b906d
BLAKE2b-256 56c03a56240d043d1fb142f1968f0645d5110c0c345b30e57c3c7f75b830f6c2

See more details on using hashes here.

File details

Details for the file agenticstar_platform-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for agenticstar_platform-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b9c4363c039151edfc5e0de40bc17a1bb1c489a08f22a7422c1c995c8f5b9b64
MD5 fab3d17f3e0201be630a10bc76e9abd0
BLAKE2b-256 3dce0c2fc5768fd8c975d030e85af75999b7d8776d9da467be6e939e6c30f818

See more details on using hashes here.

Release history Release notifications | RSS feed

1.0.2

2 files

1.0.1

2 files

This release

1.0.0 This release

2 files

0.5.41

2 files

0.5.40

2 files

0.5.39

2 files

0.5.38

2 files

0.5.37

2 files

0.5.36

2 files

0.5.35

2 files

0.5.34

2 files

0.5.33

2 files

0.5.32

2 files

0.5.31

2 files

0.5.30

2 files

0.5.29

2 files

0.5.28

2 files

0.5.27

2 files

0.5.26

2 files

0.5.25

2 files

0.5.24

2 files

0.5.23

2 files

0.5.22

2 files

0.5.21

2 files

0.5.20

2 files

0.5.19

2 files

0.5.18

2 files

0.5.17

2 files

0.5.16

2 files

0.5.15

2 files

0.5.14

2 files

0.5.13

2 files

0.5.12

2 files

0.5.11

2 files

0.5.10

2 files

0.5.9

2 files

0.5.8

2 files

0.5.7

2 files

0.5.6

2 files

0.5.5

2 files

0.5.4

2 files

0.5.3

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

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