agentivium-core 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentivium_core/__init__.py +50 -0
- agentivium_core/errors/__init__.py +16 -0
- agentivium_core/errors/base.py +18 -0
- agentivium_core/eval/__init__.py +6 -0
- agentivium_core/eval/record.py +17 -0
- agentivium_core/intent/__init__.py +6 -0
- agentivium_core/intent/base.py +28 -0
- agentivium_core/llm/__init__.py +25 -0
- agentivium_core/llm/client.py +30 -0
- agentivium_core/llm/message.py +13 -0
- agentivium_core/llm/prompt.py +27 -0
- agentivium_core/llm/request.py +19 -0
- agentivium_core/llm/response.py +24 -0
- agentivium_core/llm/structured.py +37 -0
- agentivium_core/llm/trace.py +24 -0
- agentivium_core/planner/__init__.py +7 -0
- agentivium_core/planner/action.py +23 -0
- agentivium_core/planner/base.py +20 -0
- agentivium_core/policy/__init__.py +7 -0
- agentivium_core/policy/base.py +20 -0
- agentivium_core/policy/result.py +33 -0
- agentivium_core/py.typed +1 -0
- agentivium_core/tools/__init__.py +6 -0
- agentivium_core/tools/base.py +19 -0
- agentivium_core/trace/__init__.py +6 -0
- agentivium_core/trace/execution.py +28 -0
- agentivium_core-0.2.0.dist-info/METADATA +145 -0
- agentivium_core-0.2.0.dist-info/RECORD +30 -0
- agentivium_core-0.2.0.dist-info/WHEEL +4 -0
- agentivium_core-0.2.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Domain-neutral contracts for Agentivium systems."""
|
|
2
|
+
|
|
3
|
+
from agentivium_core.eval import EvaluationRecord
|
|
4
|
+
from agentivium_core.intent import IntentIR, IntentParser
|
|
5
|
+
from agentivium_core.llm import (
|
|
6
|
+
LLMCallTrace,
|
|
7
|
+
LLMClient,
|
|
8
|
+
LLMMessage,
|
|
9
|
+
LLMRequest,
|
|
10
|
+
LLMResponse,
|
|
11
|
+
LLMUsage,
|
|
12
|
+
MockLLMClient,
|
|
13
|
+
PromptTemplate,
|
|
14
|
+
StructuredOutputParser,
|
|
15
|
+
StructuredOutputSpec,
|
|
16
|
+
)
|
|
17
|
+
from agentivium_core.planner import ActionPlan, Planner
|
|
18
|
+
from agentivium_core.policy import (
|
|
19
|
+
PolicyValidator,
|
|
20
|
+
ValidationIssue,
|
|
21
|
+
ValidationResult,
|
|
22
|
+
)
|
|
23
|
+
from agentivium_core.tools import ToolAdapter
|
|
24
|
+
from agentivium_core.trace import ExecutionTrace
|
|
25
|
+
|
|
26
|
+
__version__ = "0.2.0"
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"ActionPlan",
|
|
30
|
+
"EvaluationRecord",
|
|
31
|
+
"ExecutionTrace",
|
|
32
|
+
"LLMCallTrace",
|
|
33
|
+
"LLMClient",
|
|
34
|
+
"LLMMessage",
|
|
35
|
+
"LLMRequest",
|
|
36
|
+
"LLMResponse",
|
|
37
|
+
"LLMUsage",
|
|
38
|
+
"IntentIR",
|
|
39
|
+
"IntentParser",
|
|
40
|
+
"MockLLMClient",
|
|
41
|
+
"Planner",
|
|
42
|
+
"PolicyValidator",
|
|
43
|
+
"PromptTemplate",
|
|
44
|
+
"StructuredOutputParser",
|
|
45
|
+
"StructuredOutputSpec",
|
|
46
|
+
"ToolAdapter",
|
|
47
|
+
"ValidationIssue",
|
|
48
|
+
"ValidationResult",
|
|
49
|
+
"__version__",
|
|
50
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Agentivium Core exception hierarchy."""
|
|
2
|
+
|
|
3
|
+
from agentivium_core.errors.base import (
|
|
4
|
+
AdapterExecutionError,
|
|
5
|
+
AgentiviumCoreError,
|
|
6
|
+
PolicyValidationError,
|
|
7
|
+
SchemaValidationError,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"AdapterExecutionError",
|
|
12
|
+
"AgentiviumCoreError",
|
|
13
|
+
"PolicyValidationError",
|
|
14
|
+
"SchemaValidationError",
|
|
15
|
+
]
|
|
16
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Base exceptions for system failures in core implementations."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AgentiviumCoreError(Exception):
|
|
5
|
+
"""Base exception for Agentivium Core system failures."""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SchemaValidationError(AgentiviumCoreError):
|
|
9
|
+
"""Raised when a schema cannot be parsed or constructed."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AdapterExecutionError(AgentiviumCoreError):
|
|
13
|
+
"""Raised when a tool adapter fails to produce its output."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class PolicyValidationError(AgentiviumCoreError):
|
|
17
|
+
"""Raised for validator system failures, not domain validation issues."""
|
|
18
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Structured evaluation record schema."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class EvaluationRecord(BaseModel):
|
|
9
|
+
"""A normalized prediction, reference, and metrics record."""
|
|
10
|
+
|
|
11
|
+
sample_id: str
|
|
12
|
+
task: str
|
|
13
|
+
prediction: dict[str, Any]
|
|
14
|
+
gold: dict[str, Any] | None = None
|
|
15
|
+
metrics: dict[str, float] = Field(default_factory=dict)
|
|
16
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
17
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Base intent representation and parser interface."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class IntentIR(BaseModel):
|
|
10
|
+
"""Domain-neutral intermediate representation of a parsed request."""
|
|
11
|
+
|
|
12
|
+
ir_version: str = Field(default="0.1")
|
|
13
|
+
domain: str
|
|
14
|
+
raw_request: str | None = None
|
|
15
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class IntentParser(ABC):
|
|
19
|
+
"""Contract implemented by domain-specific intent parsers."""
|
|
20
|
+
|
|
21
|
+
@abstractmethod
|
|
22
|
+
def parse(
|
|
23
|
+
self,
|
|
24
|
+
request: str,
|
|
25
|
+
context: dict[str, Any] | None = None,
|
|
26
|
+
) -> IntentIR:
|
|
27
|
+
"""Parse a raw request into a structured intent."""
|
|
28
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Provider-neutral LLM contracts."""
|
|
2
|
+
|
|
3
|
+
from agentivium_core.llm.client import LLMClient, MockLLMClient
|
|
4
|
+
from agentivium_core.llm.message import LLMMessage
|
|
5
|
+
from agentivium_core.llm.prompt import PromptTemplate
|
|
6
|
+
from agentivium_core.llm.request import LLMRequest
|
|
7
|
+
from agentivium_core.llm.response import LLMResponse, LLMUsage
|
|
8
|
+
from agentivium_core.llm.structured import (
|
|
9
|
+
StructuredOutputParser,
|
|
10
|
+
StructuredOutputSpec,
|
|
11
|
+
)
|
|
12
|
+
from agentivium_core.llm.trace import LLMCallTrace
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"LLMCallTrace",
|
|
16
|
+
"LLMClient",
|
|
17
|
+
"LLMMessage",
|
|
18
|
+
"LLMRequest",
|
|
19
|
+
"LLMResponse",
|
|
20
|
+
"LLMUsage",
|
|
21
|
+
"MockLLMClient",
|
|
22
|
+
"PromptTemplate",
|
|
23
|
+
"StructuredOutputParser",
|
|
24
|
+
"StructuredOutputSpec",
|
|
25
|
+
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Provider-neutral LLM client contract."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from agentivium_core.llm.request import LLMRequest
|
|
6
|
+
from agentivium_core.llm.response import LLMResponse
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class LLMClient(ABC):
|
|
10
|
+
"""Synchronous text-generation interface implemented outside core."""
|
|
11
|
+
|
|
12
|
+
@abstractmethod
|
|
13
|
+
def generate(self, request: LLMRequest) -> LLMResponse:
|
|
14
|
+
"""Generate a normalized response for the given request."""
|
|
15
|
+
raise NotImplementedError
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class MockLLMClient(LLMClient):
|
|
19
|
+
"""Testing/demo client that returns a fixed response."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, response: str, model: str = "mock") -> None:
|
|
22
|
+
self.response = response
|
|
23
|
+
self.model = model
|
|
24
|
+
|
|
25
|
+
def generate(self, request: LLMRequest) -> LLMResponse:
|
|
26
|
+
return LLMResponse(
|
|
27
|
+
content=self.response,
|
|
28
|
+
model=self.model,
|
|
29
|
+
metadata={"mock": True},
|
|
30
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Provider-neutral LLM message schema."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LLMMessage(BaseModel):
|
|
9
|
+
"""One normalized text message in an LLM request."""
|
|
10
|
+
|
|
11
|
+
role: Literal["system", "user", "assistant", "tool"]
|
|
12
|
+
content: str
|
|
13
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Minimal prompt templating helpers."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
from agentivium_core.llm.message import LLMMessage
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PromptTemplate(BaseModel):
|
|
11
|
+
"""System/user prompt template rendered with Python string formatting."""
|
|
12
|
+
|
|
13
|
+
name: str
|
|
14
|
+
version: str = "0.1"
|
|
15
|
+
system: str
|
|
16
|
+
user_template: str
|
|
17
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
18
|
+
|
|
19
|
+
def render(self, variables: dict[str, Any]) -> list[LLMMessage]:
|
|
20
|
+
"""Render the template as system and user messages."""
|
|
21
|
+
return [
|
|
22
|
+
LLMMessage(role="system", content=self.system),
|
|
23
|
+
LLMMessage(
|
|
24
|
+
role="user",
|
|
25
|
+
content=self.user_template.format(**variables),
|
|
26
|
+
),
|
|
27
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Provider-neutral LLM request schema."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
from agentivium_core.llm.message import LLMMessage
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class LLMRequest(BaseModel):
|
|
11
|
+
"""Normalized request shape for provider/domain LLM clients."""
|
|
12
|
+
|
|
13
|
+
model: str | None = None
|
|
14
|
+
messages: list[LLMMessage]
|
|
15
|
+
temperature: float = 0.0
|
|
16
|
+
max_tokens: int | None = None
|
|
17
|
+
stop: list[str] | None = None
|
|
18
|
+
response_format: dict[str, Any] | None = None
|
|
19
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Provider-neutral LLM response schemas."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LLMUsage(BaseModel):
|
|
9
|
+
"""Optional usage and timing data for an LLM call."""
|
|
10
|
+
|
|
11
|
+
prompt_tokens: int | None = None
|
|
12
|
+
completion_tokens: int | None = None
|
|
13
|
+
total_tokens: int | None = None
|
|
14
|
+
latency_ms: float | None = None
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class LLMResponse(BaseModel):
|
|
18
|
+
"""Normalized text response returned by an LLM client."""
|
|
19
|
+
|
|
20
|
+
content: str
|
|
21
|
+
model: str | None = None
|
|
22
|
+
usage: LLMUsage | None = None
|
|
23
|
+
raw: dict[str, Any] | None = None
|
|
24
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Structured-output contracts and minimal parsing utilities."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from agentivium_core.llm.response import LLMResponse
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class StructuredOutputSpec(BaseModel):
|
|
12
|
+
"""Provider-neutral structured output requirement."""
|
|
13
|
+
|
|
14
|
+
name: str
|
|
15
|
+
output_schema: dict[str, Any] = Field(
|
|
16
|
+
alias="schema",
|
|
17
|
+
description="Provider-neutral schema",
|
|
18
|
+
)
|
|
19
|
+
strict: bool = True
|
|
20
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def schema(self) -> dict[str, Any]: # type: ignore[override]
|
|
24
|
+
"""Return the provider-neutral schema."""
|
|
25
|
+
return self.output_schema
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class StructuredOutputParser:
|
|
29
|
+
"""Minimal structured-output parser."""
|
|
30
|
+
|
|
31
|
+
def parse_json(self, response: LLMResponse) -> dict[str, Any]:
|
|
32
|
+
"""Parse response content as a JSON object."""
|
|
33
|
+
data = json.loads(response.content)
|
|
34
|
+
if not isinstance(data, dict):
|
|
35
|
+
msg = "LLM response content must decode to a JSON object"
|
|
36
|
+
raise TypeError(msg)
|
|
37
|
+
return data
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Provider-neutral LLM call tracing schema."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _utc_now() -> datetime:
|
|
10
|
+
return datetime.now(timezone.utc)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class LLMCallTrace(BaseModel):
|
|
14
|
+
"""Auditable record for one LLM call."""
|
|
15
|
+
|
|
16
|
+
trace_id: str
|
|
17
|
+
created_at: datetime = Field(default_factory=_utc_now)
|
|
18
|
+
provider: str | None = None
|
|
19
|
+
model: str | None = None
|
|
20
|
+
request: dict[str, Any]
|
|
21
|
+
response: dict[str, Any] | None = None
|
|
22
|
+
latency_ms: float | None = None
|
|
23
|
+
error: str | None = None
|
|
24
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Structured next-action plans."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
ActionType = Literal[
|
|
8
|
+
"execute",
|
|
9
|
+
"generate",
|
|
10
|
+
"ask_clarification",
|
|
11
|
+
"repair",
|
|
12
|
+
"reject",
|
|
13
|
+
"defer",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ActionPlan(BaseModel):
|
|
18
|
+
"""A structured decision describing what a system should do next."""
|
|
19
|
+
|
|
20
|
+
action: ActionType
|
|
21
|
+
reason: str | None = None
|
|
22
|
+
payload: dict[str, Any] = Field(default_factory=dict)
|
|
23
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Planner interface."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
from agentivium_core.intent import IntentIR
|
|
6
|
+
from agentivium_core.planner.action import ActionPlan
|
|
7
|
+
from agentivium_core.policy import ValidationResult
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Planner(ABC):
|
|
11
|
+
"""Contract for choosing the next action from intent and validation."""
|
|
12
|
+
|
|
13
|
+
@abstractmethod
|
|
14
|
+
def plan(
|
|
15
|
+
self,
|
|
16
|
+
intent: IntentIR,
|
|
17
|
+
validation: ValidationResult,
|
|
18
|
+
) -> ActionPlan:
|
|
19
|
+
"""Return the system's next structured action."""
|
|
20
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"""Policy validation contracts and structured results."""
|
|
2
|
+
|
|
3
|
+
from agentivium_core.policy.base import PolicyValidator
|
|
4
|
+
from agentivium_core.policy.result import ValidationIssue, ValidationResult
|
|
5
|
+
|
|
6
|
+
__all__ = ["PolicyValidator", "ValidationIssue", "ValidationResult"]
|
|
7
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Policy validator interface."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from agentivium_core.intent import IntentIR
|
|
7
|
+
from agentivium_core.policy.result import ValidationResult
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PolicyValidator(ABC):
|
|
11
|
+
"""Contract implemented by domain-specific policy validators."""
|
|
12
|
+
|
|
13
|
+
@abstractmethod
|
|
14
|
+
def validate(
|
|
15
|
+
self,
|
|
16
|
+
intent: IntentIR,
|
|
17
|
+
policy: dict[str, Any] | None = None,
|
|
18
|
+
) -> ValidationResult:
|
|
19
|
+
"""Validate an intent against optional domain policy."""
|
|
20
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Structured policy validation results."""
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
|
|
7
|
+
IssueSeverity = Literal["info", "warning", "blocking", "critical"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ValidationIssue(BaseModel):
|
|
11
|
+
"""A machine-readable issue found while validating an intent."""
|
|
12
|
+
|
|
13
|
+
code: str
|
|
14
|
+
severity: IssueSeverity
|
|
15
|
+
message: str
|
|
16
|
+
field: str | None = None
|
|
17
|
+
suggestion: str | None = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ValidationResult(BaseModel):
|
|
21
|
+
"""The complete structured output of policy validation."""
|
|
22
|
+
|
|
23
|
+
valid: bool
|
|
24
|
+
issues: list[ValidationIssue] = Field(default_factory=list)
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def blocking(self) -> bool:
|
|
28
|
+
"""Whether any issue prevents execution."""
|
|
29
|
+
|
|
30
|
+
return any(
|
|
31
|
+
issue.severity in {"blocking", "critical"} for issue in self.issues
|
|
32
|
+
)
|
|
33
|
+
|
agentivium_core/py.typed
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Tool adapter interface."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from agentivium_core.intent import IntentIR
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ToolAdapter(ABC):
|
|
10
|
+
"""Contract for translating a valid intent into tool-specific output."""
|
|
11
|
+
|
|
12
|
+
@abstractmethod
|
|
13
|
+
def generate(
|
|
14
|
+
self,
|
|
15
|
+
intent: IntentIR,
|
|
16
|
+
context: dict[str, Any] | None = None,
|
|
17
|
+
) -> Any:
|
|
18
|
+
"""Generate a tool-specific artifact or invocation."""
|
|
19
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Versioned execution trace schema."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from agentivium_core.llm import LLMCallTrace
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _utc_now() -> datetime:
|
|
12
|
+
return datetime.now(timezone.utc)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ExecutionTrace(BaseModel):
|
|
16
|
+
"""Auditable record of the processing lifecycle for one request."""
|
|
17
|
+
|
|
18
|
+
trace_version: str = Field(default="0.1")
|
|
19
|
+
trace_id: str
|
|
20
|
+
created_at: datetime = Field(default_factory=_utc_now)
|
|
21
|
+
domain: str
|
|
22
|
+
raw_request: str | None = None
|
|
23
|
+
intent: dict[str, Any] | None = None
|
|
24
|
+
validation: dict[str, Any] | None = None
|
|
25
|
+
action_plan: dict[str, Any] | None = None
|
|
26
|
+
output: dict[str, Any] | None = None
|
|
27
|
+
llm_calls: list[LLMCallTrace] = Field(default_factory=list)
|
|
28
|
+
metadata: dict[str, Any] = Field(default_factory=dict)
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentivium-core
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Core abstractions for Agentivium agent-native systems.
|
|
5
|
+
Author: Agentivium AI
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Agentivium AI
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Classifier: Development Status :: 3 - Alpha
|
|
29
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
30
|
+
Classifier: Programming Language :: Python :: 3
|
|
31
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
32
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
34
|
+
Classifier: Typing :: Typed
|
|
35
|
+
Requires-Python: >=3.10
|
|
36
|
+
Requires-Dist: pydantic<3,>=2.0
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
|
|
43
|
+
# Agentivium Core
|
|
44
|
+
|
|
45
|
+
`agentivium-core` defines the small, domain-neutral contracts shared by
|
|
46
|
+
Agentivium agent-native systems. It provides typed schemas and abstract
|
|
47
|
+
interfaces for intent parsing, policy validation, planning, tool adaptation,
|
|
48
|
+
provider-neutral LLM calls, execution tracing, and evaluation.
|
|
49
|
+
|
|
50
|
+
It is not an agent runtime, a provider-specific LLM wrapper, or a domain
|
|
51
|
+
implementation. Schedulers, provider clients, policies, and orchestration
|
|
52
|
+
belong in extension packages.
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install agentivium-core
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
For local development:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install -e ".[dev]"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Extend the core
|
|
67
|
+
|
|
68
|
+
Domain packages subclass schemas and implement interfaces:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from agentivium_core.intent import IntentIR, IntentParser
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class MyIntentIR(IntentIR):
|
|
75
|
+
domain: str = "my_domain"
|
|
76
|
+
task: str
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class MyIntentParser(IntentParser):
|
|
80
|
+
def parse(
|
|
81
|
+
self,
|
|
82
|
+
request: str,
|
|
83
|
+
context: dict[str, object] | None = None,
|
|
84
|
+
) -> MyIntentIR:
|
|
85
|
+
return MyIntentIR(raw_request=request, task=request)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The dependency direction stays one-way: domain packages import
|
|
89
|
+
`agentivium_core`; the core never imports a domain package.
|
|
90
|
+
|
|
91
|
+
## Public API
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from agentivium_core.intent import IntentIR, IntentParser
|
|
95
|
+
from agentivium_core.planner import ActionPlan, Planner
|
|
96
|
+
from agentivium_core.policy import (
|
|
97
|
+
PolicyValidator,
|
|
98
|
+
ValidationIssue,
|
|
99
|
+
ValidationResult,
|
|
100
|
+
)
|
|
101
|
+
from agentivium_core.tools import ToolAdapter
|
|
102
|
+
from agentivium_core.trace import ExecutionTrace
|
|
103
|
+
from agentivium_core.eval import EvaluationRecord
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Provider-neutral LLM abstraction
|
|
107
|
+
|
|
108
|
+
`agentivium-core` defines `LLMClient`, `LLMRequest`, `LLMResponse`,
|
|
109
|
+
`PromptTemplate`, `StructuredOutputSpec`, and `LLMCallTrace` so downstream
|
|
110
|
+
packages can use LLMs without coupling core to OpenAI, Anthropic, Gemini,
|
|
111
|
+
Ollama, vLLM, llama.cpp, or any other provider.
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from agentivium_core.llm import (
|
|
115
|
+
LLMClient,
|
|
116
|
+
LLMRequest,
|
|
117
|
+
LLMResponse,
|
|
118
|
+
PromptTemplate,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class MyLocalLLMClient(LLMClient):
|
|
123
|
+
def generate(self, request: LLMRequest) -> LLMResponse:
|
|
124
|
+
return LLMResponse(content='{"intent": "example"}', model="local")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
template = PromptTemplate(
|
|
128
|
+
name="intent_parser",
|
|
129
|
+
system="You extract structured intent.",
|
|
130
|
+
user_template="Request: {request}",
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
messages = template.render({"request": "Run a small MPI job."})
|
|
134
|
+
client = MyLocalLLMClient()
|
|
135
|
+
response = client.generate(LLMRequest(messages=messages))
|
|
136
|
+
print(response.content)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Production provider clients live in domain or provider packages. Core only
|
|
140
|
+
defines the contracts and a `MockLLMClient` for tests and demos.
|
|
141
|
+
|
|
142
|
+
See the [concepts](docs/concepts.md), [API reference](docs/api.md),
|
|
143
|
+
[extension guide](docs/extension_guide.md), and
|
|
144
|
+
[examples](docs/examples.md). The complete v0.1 rationale and boundaries are
|
|
145
|
+
preserved in the original [design guideline](docs/design-guideline.md).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
agentivium_core/__init__.py,sha256=WZpVtYFUL8uwaCQ6FBUrr0mB8v6bxH5MqcYJwx57h-A,1113
|
|
2
|
+
agentivium_core/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
3
|
+
agentivium_core/errors/__init__.py,sha256=ryvPxIWxLPFXf70fEQdXOpLEQizpFMwIPHEBQbHbRXU,324
|
|
4
|
+
agentivium_core/errors/base.py,sha256=ur9r85d5JKQGB4qDMAhwV8Pt2UIwxbzeSdfm8yR9jGc,534
|
|
5
|
+
agentivium_core/eval/__init__.py,sha256=VMYql6xHCbuptqIprPED5lOKhnkb-SmnyF3dQ3SUXWU,117
|
|
6
|
+
agentivium_core/eval/record.py,sha256=rcZXGu9LHr35JrDyba_CGX5b_CcfN-0xtUHA4tM4f40,433
|
|
7
|
+
agentivium_core/intent/__init__.py,sha256=lxdlA4p_63OsBHxFhMXAX2_qTpCGqLQj0ZakUxUaBjQ,148
|
|
8
|
+
agentivium_core/intent/base.py,sha256=e52a8gmUyBLTNMPcLqk1fFc-k83JavSMH5N44jgqrFM,703
|
|
9
|
+
agentivium_core/llm/__init__.py,sha256=YkjQE0w7sieuRibWv57EWb7sRfI4LVcixycr92NiMaU,698
|
|
10
|
+
agentivium_core/llm/client.py,sha256=KayG8Eqj_N6wPq03KYRzW7K1QqEpW-EzUIgyb3JBUuM,892
|
|
11
|
+
agentivium_core/llm/message.py,sha256=1mpLpyxnD--YkzDksz_4Ca7CIvYLGz4sBEKH4B1HTN8,337
|
|
12
|
+
agentivium_core/llm/prompt.py,sha256=461XFnym20b93nzXRBBfk5RtOBl9inJPo00kbricl50,759
|
|
13
|
+
agentivium_core/llm/request.py,sha256=g0p-ZY-mEgYxI6Pjw9efYmE-P0XMhaZD0EdCkPWczdw,524
|
|
14
|
+
agentivium_core/llm/response.py,sha256=E8OZmo4ceNpFyZAyiRsLSwpwcdqAC3jlGZASKIJb4uw,618
|
|
15
|
+
agentivium_core/llm/structured.py,sha256=Pv5hFWrX45F-i7F75ZfsQ9WDdQF8Y4jpxcDb7l5nrOg,1081
|
|
16
|
+
agentivium_core/llm/trace.py,sha256=WV38teQj0Pcb1ARsMj0IVlQY1ZOHaZviloowpcH-Op8,631
|
|
17
|
+
agentivium_core/planner/__init__.py,sha256=xrfJMALtTLSwFPecCpqQ5pBI_sXZ8i81oaY8qDS9ibE,191
|
|
18
|
+
agentivium_core/planner/action.py,sha256=EZZADPbcE3g_2wonvjb2sOYI1T7bxp9orzHJomoZeRQ,447
|
|
19
|
+
agentivium_core/planner/base.py,sha256=K4NQuD2Zo84s3uWEweeNCdWjVT7FSQxNW-VSwg0r5Bk,504
|
|
20
|
+
agentivium_core/policy/__init__.py,sha256=fRN8lx-bGtF5MAED_ARneF6IQfPrUnMeEJ2jKfuk51Q,262
|
|
21
|
+
agentivium_core/policy/base.py,sha256=jKgU8K0HmyxUukZTjNMdXdVLpgz3dMK29GIGVOgrqng,515
|
|
22
|
+
agentivium_core/policy/result.py,sha256=9lD04xKcPb4NV9ghj_h3pEPnJbsp31XOoP8Oixgh_Xo,799
|
|
23
|
+
agentivium_core/tools/__init__.py,sha256=pBMeyduYxiDVTSrV24D-0G39ICwjR_Y4AbXHJ-mmmeE,110
|
|
24
|
+
agentivium_core/tools/base.py,sha256=Yp9eIFH2ceQAP52jD6P9pn9kPzLUPJ5e3NOCvWaDhVc,442
|
|
25
|
+
agentivium_core/trace/__init__.py,sha256=xAjUFteFZI4eY_-yW5ike_lJm9QcDApdm6CBJU08rVE,122
|
|
26
|
+
agentivium_core/trace/execution.py,sha256=Jk108HR-70sCV1sOjAACZ66zmXvs8HPhTvw3VNFXplk,835
|
|
27
|
+
agentivium_core-0.2.0.dist-info/METADATA,sha256=jJNu4du-0UQVarKo07G15WxB-gQfmM4ZqE5fHzRHy4I,4850
|
|
28
|
+
agentivium_core-0.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
29
|
+
agentivium_core-0.2.0.dist-info/licenses/LICENSE,sha256=Y6_XRGKm02xfb7s6v5nqxMR71bP9TglQ4ahfYsOXXK8,1070
|
|
30
|
+
agentivium_core-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Agentivium AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|