jeevesagent.core¶
Layer-free primitives: types, protocols, errors, IDs.
Submodules¶
Exceptions¶
Invalid, missing, or revoked API credentials. |
|
A run was halted because a budget limit was hit. |
|
A user-driven interruption (signal, timeout) ended the run. |
|
Invalid or unresolvable configuration passed to |
|
The provider's safety system blocked the request or response. |
|
A certified value failed its freshness policy. |
|
The request was malformed or violated the provider's API |
|
Emitted when a memory query is likely to silently miss data |
|
Base class for all harness errors. |
|
A certified value failed its lineage policy. |
|
An MCP transport, handshake, or protocol error. |
|
The memory backend failed an operation. |
|
A call to the underlying model adapter failed. |
|
The model's final answer did not validate against the supplied |
|
A model call failed in a way that retrying will not fix. |
|
A tool call was denied by the permission layer or a user hook. |
|
The provider returned a 429 / quota-exhausted response. |
|
The durable runtime journal is unreadable or inconsistent. |
|
The sandbox refused or failed to execute a tool. |
|
A tool invocation failed at the tool's own boundary. |
|
A model call failed in a way that may succeed on retry. |
Classes¶
An immutable, signed entry in the audit log. |
|
Resource governance — tokens, calls, cost, wall clock. |
|
Result of a budget check before each step. |
|
A value carrying provenance metadata for freshness/lineage checks. |
|
Text-to-vector embedding model used by the memory subsystem. |
|
A single (input, decisions, tool calls, output) tuple from history. |
|
A single observable record from a running session. |
|
Enum where members are also (and must be) strings |
|
A semantic claim extracted from one or more episodes. |
|
Aggregator over user-registered lifecycle callbacks. |
|
Tiered memory: working blocks, episodic store, semantic graph. |
|
An in-context memory block, pinned to every prompt. |
|
A single chat message in the model's conversation. |
|
LLM provider interface. One adapter per lab (Anthropic, OpenAI, ...). |
|
A single chunk from a streaming model call. |
|
Outcome of a permission check or pre-tool hook. |
|
Decides whether a tool call is allowed. |
|
Enum where members are also (and must be) strings |
|
Typed, immutable context for one agent run. |
|
Final outcome of an |
|
Durable execution. Wraps every side effect in a journal entry. |
|
Handle to an open durable session held by a |
|
Isolation layer for tool execution. |
|
Resolution and redaction of named secrets. |
|
A trace span handle. Concrete telemetry adapters return their own |
|
OpenTelemetry-compatible tracing/metrics surface. |
|
A model-emitted request to invoke a tool. |
|
Schema description of a tool the model can call. |
|
Tool registry change notification (MCP listChanged etc.). |
|
MCP-aware tool registry. Lazy-loads schemas on demand. |
|
Outcome of a tool invocation. |
|
Token and cost accounting for a model call. |
|
Context manager that installs a |
Functions¶
|
Stable hash of arbitrary JSON-serializable parts. |
|
Return the |
|
Return a fresh ULID, optionally prefixed for readability. |
Package Contents¶
- exception jeevesagent.core.AuthenticationError(message: str, *, cause: BaseException | None = None)[source]¶
Bases:
PermanentModelErrorInvalid, missing, or revoked API credentials.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.BudgetExceeded(reason: str)[source]¶
Bases:
JeevesAgentErrorA run was halted because a budget limit was hit.
Initialize self. See help(type(self)) for accurate signature.
- reason¶
- exception jeevesagent.core.CancelledByUser[source]¶
Bases:
JeevesAgentErrorA user-driven interruption (signal, timeout) ended the run.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.ConfigError[source]¶
Bases:
JeevesAgentErrorInvalid or unresolvable configuration passed to
Agent.Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.ContentFilterError(message: str, *, cause: BaseException | None = None)[source]¶
Bases:
PermanentModelErrorThe provider’s safety system blocked the request or response.
Typically a permanent failure for the same prompt; users may rephrase but the framework should not silently retry.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.FreshnessError[source]¶
Bases:
JeevesAgentErrorA certified value failed its freshness policy.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.InvalidRequestError(message: str, *, cause: BaseException | None = None)[source]¶
Bases:
PermanentModelErrorThe request was malformed or violated the provider’s API contract — bad parameters, oversized prompt, unknown model name, etc. Fix the request, don’t retry.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.IsolationWarning[source]¶
Bases:
UserWarningEmitted when a memory query is likely to silently miss data because the caller forgot to pass
user_id.Concrete trigger: a backend’s
recall/recall_factsruns withuser_id=Noneagainst a store whose persisted records include at least one non-Noneuser_id— the partition is safe (the anonymous bucket and named-user buckets are isolated), but the developer probably wired up multi-tenancy somewhere and forgot to passuser_idhere, so they will see suspiciously empty recall results.Subclass of
UserWarningso it goes through Python’s standardwarningsfilter machinery — apps can silence, promote-to-error, or log it however they want, e.g.:import warnings from jeevesagent import IsolationWarning warnings.simplefilter("error", IsolationWarning) # raise on hit
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.JeevesAgentError[source]¶
Bases:
ExceptionBase class for all harness errors.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.LineageError[source]¶
Bases:
JeevesAgentErrorA certified value failed its lineage policy.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.MCPError[source]¶
Bases:
JeevesAgentErrorAn MCP transport, handshake, or protocol error.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.MemoryStoreError[source]¶
Bases:
JeevesAgentErrorThe memory backend failed an operation.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.ModelError(message: str, *, cause: BaseException | None = None)[source]¶
Bases:
JeevesAgentErrorA call to the underlying model adapter failed.
Base of the model-error taxonomy: catch this to handle every model failure regardless of whether it is transient or permanent. The SDK exception that triggered the classification is attached via
__cause__(andcause) so debug code can still inspect the raw error.Initialize self. See help(type(self)) for accurate signature.
- cause = None¶
- exception jeevesagent.core.OutputValidationError(message: str, *, raw: str, schema: type, cause: BaseException | None = None)[source]¶
Bases:
JeevesAgentErrorThe model’s final answer did not validate against the supplied
output_schema.Raised by
Agent.run()when the caller passedoutput_schema=and the model’s final assistant text could not be parsed/validated as the requested Pydantic model — even after the optional one-shot “retry with the validation error” turn.Carries the raw model output (
raw), the underlying Pydanticpydantic.ValidationError(cause, also exposed via__cause__), and the schema that was being targeted (schema) so callers can build whatever recovery strategy they need (re-prompt with extra examples, fall back to free-text, etc.).Initialize self. See help(type(self)) for accurate signature.
- cause = None¶
- raw¶
- schema¶
- exception jeevesagent.core.PermanentModelError(message: str, *, cause: BaseException | None = None)[source]¶
Bases:
ModelErrorA model call failed in a way that retrying will not fix.
Wrong API key, malformed request, content-filter rejection, deprecated model name, etc. The retry layer raises these immediately without backoff so callers can fail fast and surface the real problem.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.PermissionDenied(tool: str, reason: str)[source]¶
Bases:
JeevesAgentErrorA tool call was denied by the permission layer or a user hook.
Initialize self. See help(type(self)) for accurate signature.
- reason¶
- tool¶
- exception jeevesagent.core.RateLimitError(message: str, *, retry_after: float | None = None, cause: BaseException | None = None)[source]¶
Bases:
TransientModelErrorThe provider returned a 429 / quota-exhausted response.
Carries
retry_afterwhen the provider supplied one. Subclass ofTransientModelErrorso generic transient handlers cover it; catchRateLimitErrorspecifically when you need to surface “slow down” to the caller (e.g. propagate a 429 to your own clients).Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.RuntimeJournalError[source]¶
Bases:
JeevesAgentErrorThe durable runtime journal is unreadable or inconsistent.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.SandboxError[source]¶
Bases:
JeevesAgentErrorThe sandbox refused or failed to execute a tool.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.ToolError[source]¶
Bases:
JeevesAgentErrorA tool invocation failed at the tool’s own boundary.
Initialize self. See help(type(self)) for accurate signature.
- exception jeevesagent.core.TransientModelError(message: str, *, retry_after: float | None = None, cause: BaseException | None = None)[source]¶
Bases:
ModelErrorA model call failed in a way that may succeed on retry.
Covers HTTP 5xx responses, network errors, timeouts, and provider-side rate limits. The retry layer treats this family as retryable and applies backoff.
retry_after(in seconds) carries a provider-supplied hint when one is available — e.g. anRetry-AfterHTTP header on a 429 response. The retry layer respects the larger of the policy’s computed backoff andretry_afterso we never wait less than the provider asked for.Initialize self. See help(type(self)) for accurate signature.
- retry_after = None¶
- class jeevesagent.core.AuditEntry(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelAn immutable, signed entry in the audit log.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- model_config¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- timestamp: datetime.datetime¶
- class jeevesagent.core.Budget[source]¶
Bases:
ProtocolResource governance — tokens, calls, cost, wall clock.
- async allows_step() jeevesagent.core.types.BudgetStatus[source]¶
- class jeevesagent.core.BudgetStatus(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelResult of a budget check before each step.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- classmethod blocked_(reason: str) BudgetStatus[source]¶
- classmethod ok_() BudgetStatus[source]¶
- classmethod warn_(reason: str) BudgetStatus[source]¶
- model_config¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- state: Literal['ok', 'warn', 'blocked']¶
- class jeevesagent.core.CertifiedValue(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelA value carrying provenance metadata for freshness/lineage checks.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- fetched_at: datetime.datetime¶
- model_config¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- valid_until: datetime.datetime | None = None¶
- value: Any¶
- class jeevesagent.core.Embedder[source]¶
Bases:
ProtocolText-to-vector embedding model used by the memory subsystem.
- class jeevesagent.core.Episode(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelA single (input, decisions, tool calls, output) tuple from history.
user_idis the framework-managed namespace partition. Episodes persisted with oneuser_idvalue are never visible to memory recall queries scoped to a differentuser_id.Noneis its own bucket — the “anonymous / single-tenant” namespace — and does not see episodes belonging to a non-Noneuser_id(and vice versa). Set automatically fromRunContextby the agent loop; pass explicitly when constructing episodes outside a run.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- occurred_at: datetime.datetime = None¶
- class jeevesagent.core.Event(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelA single observable record from a running session.
Carries a discriminator (
kind) plus a free-form payload. Construct via the class methods to ensure consistent shapes.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- classmethod architecture_event(session_id: str, name: str, **data: Any) Event[source]¶
Generic architecture-progress event.
nameis a namespaced string identifying the source architecture and the kind of progress (e.g."self_refine.critique","reflexion.lesson_persisted","router.classified").datais merged into the payload alongsidenameso consumers can pattern-match onnameand read structured fields off the rest.
- classmethod budget_exceeded(session_id: str, status: BudgetStatus) Event[source]¶
- classmethod budget_warning(session_id: str, status: BudgetStatus) Event[source]¶
- classmethod error(session_id: str, exc: BaseException) Event[source]¶
- classmethod model_chunk(session_id: str, chunk: ModelChunk) Event[source]¶
- classmethod tool_result(session_id: str, result: ToolResult) Event[source]¶
- at: datetime.datetime = None¶
- class jeevesagent.core.EventKind[source]¶
Bases:
enum.StrEnumEnum where members are also (and must be) strings
Initialize self. See help(type(self)) for accurate signature.
- ARCHITECTURE_EVENT = 'architecture_event'¶
Generic architecture-progress event. Carries a namespaced
namein the payload (e.g."self_refine.critique","reflexion.lesson_persisted","router.classified") so each architecture can stream its own progress signal without expandingEventKind.
- BUDGET_EXCEEDED = 'budget_exceeded'¶
- BUDGET_WARNING = 'budget_warning'¶
- COMPLETED = 'completed'¶
- ERROR = 'error'¶
- MEMORY_RECALL = 'memory_recall'¶
- MEMORY_WRITE = 'memory_write'¶
- MODEL_CHUNK = 'model_chunk'¶
- PERMISSION_ASK = 'permission_ask'¶
- PERMISSION_DECISION = 'permission_decision'¶
- STARTED = 'started'¶
- TOOL_CALL = 'tool_call'¶
- TOOL_RESULT = 'tool_result'¶
- class jeevesagent.core.Fact(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelA semantic claim extracted from one or more episodes.
Bi-temporal:
valid_from/valid_untiltracks when the fact was true in the world;recorded_attracks when we learned it.user_idis the framework-managed namespace partition. Facts persisted with oneuser_idvalue are never visible to recall queries scoped to a differentuser_id. Set automatically fromRunContextby the agent loop / consolidator; pass explicitly when constructing facts outside a run.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- recorded_at: datetime.datetime = None¶
- valid_from: datetime.datetime = None¶
- valid_until: datetime.datetime | None = None¶
- class jeevesagent.core.HookHost[source]¶
Bases:
ProtocolAggregator over user-registered lifecycle callbacks.
- async on_event(event: jeevesagent.core.types.Event) None[source]¶
- async post_tool(call: jeevesagent.core.types.ToolCall, result: jeevesagent.core.types.ToolResult) None[source]¶
- async pre_tool(call: jeevesagent.core.types.ToolCall) jeevesagent.core.types.PermissionDecision[source]¶
- class jeevesagent.core.Memory[source]¶
Bases:
ProtocolTiered memory: working blocks, episodic store, semantic graph.
- async append_block(name: str, content: str) None[source]¶
Append to a named block, creating it if absent.
- async recall(query: str, *, kind: str = 'episodic', limit: int = 5, time_range: tuple[datetime.datetime, datetime.datetime] | None = None, user_id: str | None = None) list[jeevesagent.core.types.Episode][source]¶
Retrieve episodes (or facts, when
kind='semantic').When
user_idis supplied, results are restricted to episodes stored with that exactuser_idvalue.Noneis its own bucket (the “anonymous / single-tenant” namespace) — episodes stored withuser_id=Noneare never visible to a query withuser_id="alice"and vice versa. Backends MUST honour this filter to preserve the framework’s multi-tenant safety contract.
- async recall_facts(query: str, *, limit: int = 5, valid_at: datetime.datetime | None = None, user_id: str | None = None) list[jeevesagent.core.types.Fact][source]¶
Retrieve bi-temporal facts matching
query.Backends that don’t expose a fact store return
[]. The agent loop calls this directly rather than duck-typing onmemory.factsso backends without fact support don’t need any opt-out mechanism.user_idfilters by namespace partition with the same semantics asrecall():Noneis its own bucket and does not cross-contaminate with non-None values.
- async remember(episode: jeevesagent.core.types.Episode) str[source]¶
Persist an episode. Returns the episode ID.
- async session_messages(session_id: str, *, user_id: str | None = None, limit: int = 20) list[jeevesagent.core.types.Message][source]¶
Return the most-recent
limituser/assistant turns from the conversation identified bysession_id, in order (oldest first).This is the conversation-continuity primitive — the agent loop calls it at the top of every run so that reusing a
session_idactually continues the chat (the model sees previous turns as realMessagehistory) rather than starting fresh and relying solely on semantic recall.user_idMUST be respected by backends as a hard namespace partition: messages persisted under oneuser_idare never visible to a query scoped to a different one. Backends without persisted message logs return[]— the agent loop falls back to the semantic-recall path in that case.
- async working() list[jeevesagent.core.types.MemoryBlock][source]¶
All in-context blocks. Pinned to every prompt.
- class jeevesagent.core.MemoryBlock(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelAn in-context memory block, pinned to every prompt.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- updated_at: datetime.datetime = None¶
- class jeevesagent.core.Message(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelA single chat message in the model’s conversation.
tool_callsis populated on assistant messages that emitted tool calls in the previous turn — real provider adapters (Anthropictool_useblocks, OpenAItool_callsarray) need to reconstruct the right wire format from this.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- model_config¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class jeevesagent.core.Model[source]¶
Bases:
ProtocolLLM provider interface. One adapter per lab (Anthropic, OpenAI, …).
The required surface is
stream(...)— every adapter must implement it. Adapters MAY additionally overridecomplete(...)with a non-streaming (single-shot) call; if not,completefalls back to consuming the stream internally and assembling the full response, which is correct but slower (per-chunk wire + parsing overhead). Architectures usecompleteon the non-streaming hot path (agent.run()) andstreamwhen a consumer is reading fromagent.stream().- stream(messages: list[jeevesagent.core.types.Message], *, tools: list[jeevesagent.core.types.ToolDef] | None = None, temperature: float = 1.0, max_tokens: int | None = None) collections.abc.AsyncIterator[jeevesagent.core.types.ModelChunk][source]¶
Stream completion chunks. Each chunk is text, tool_call, or finish.
- class jeevesagent.core.ModelChunk(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelA single chunk from a streaming model call.
Discriminated by
kind. Exactly one of the optional fields is set depending on the kind.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- kind: Literal['text', 'tool_call', 'finish']¶
- class jeevesagent.core.PermissionDecision(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelOutcome of a permission check or pre-tool hook.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- classmethod allow_(reason: str | None = None) PermissionDecision[source]¶
- classmethod ask_(reason: str | None = None) PermissionDecision[source]¶
- classmethod deny_(reason: str) PermissionDecision[source]¶
- decision: Literal['allow', 'deny', 'ask']¶
- model_config¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class jeevesagent.core.Permissions[source]¶
Bases:
ProtocolDecides whether a tool call is allowed.
- async check(call: jeevesagent.core.types.ToolCall, *, context: collections.abc.Mapping[str, Any]) jeevesagent.core.types.PermissionDecision[source]¶
- class jeevesagent.core.Role[source]¶
Bases:
enum.StrEnumEnum where members are also (and must be) strings
Initialize self. See help(type(self)) for accurate signature.
- ASSISTANT = 'assistant'¶
- SYSTEM = 'system'¶
- TOOL = 'tool'¶
- USER = 'user'¶
- class jeevesagent.core.RunContext[source]¶
Typed, immutable context for one agent run.
Set once at the start of
Agent.run()and propagated to every architecture, tool, hook, sub-agent, and memory operation via acontextvars.ContextVar. The framework treatsuser_idandsession_idas first-class fields (typed, namespaced);metadatais an opaque bag for app-specific keys the framework does not interpret.Construct one directly when you need to spawn work outside an active run with explicit scope:
ctx = RunContext(user_id="alice", session_id="conv_42") async with set_run_context(ctx): await my_tool(...)
Inside an agent run, prefer
get_run_context()over constructing a new one — that gives you the live context the framework set up.- with_overrides(*, user_id: str | None | _Sentinel = _Sentinel.UNSET, session_id: str | None | _Sentinel = _Sentinel.UNSET, run_id: str | _Sentinel = _Sentinel.UNSET, metadata: collections.abc.Mapping[str, Any] | _Sentinel = _Sentinel.UNSET) RunContext[source]¶
Return a new context with selected fields replaced.
Used by multi-agent architectures when spawning sub-agents that need to inherit most of the parent’s context but with a derived
session_idor augmentedmetadata. The sentinel makes “leave this field unchanged” distinguishable from “explicitly set this field toNone”.
- metadata: collections.abc.Mapping[str, Any]¶
Free-form application context. Use this for keys the framework does not need to understand — locale, request id, feature flags, tenant id beyond
user_id, etc. Read inside tools / hooks viaget_run_context().metadata.
- run_id: str = ''¶
Unique identifier for this single
Agent.run()invocation. Distinct fromsession_id(which identifies a conversation that may span many runs). Auto-set byAgent.run(); an explicit value passed in by the caller is overridden.
- session_id: str | None = None¶
Conversation thread identifier. Reusing the same
session_idacross calls signals “continue this conversation” — the framework will rehydrate prior session messages so the model sees real chat history, not just memory recall.Nonemeans “fresh conversation”; the framework auto-generates one insideAgent.run()if not supplied.
- user_id: str | None = None¶
Namespace for memory recall + persistence.
Noneis the “anonymous / single-tenant” bucket; episodes / facts stored withuser_id=Nonenever see episodes / facts stored with a non-Noneuser_idand vice versa. The framework treats this as a hard partition key, not a soft filter.
- class jeevesagent.core.RunResult(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelFinal outcome of an
Agent.runcall.outputis always the raw assistant text (the JSON itself when a structured-output schema was supplied).parsedis the validated Pydantic instance — populated only when the caller passedoutput_schema=toAgent.run(). Use whichever fits the call site:# free-form text run result = await agent.run("summarise this PDF") print(result.output) # structured-output run result = await agent.run(prompt, output_schema=Invoice) invoice: Invoice = result.parsed # typed, validated
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- property duration: datetime.timedelta¶
Wall-clock latency between
started_atandfinished_at.
- finished_at: datetime.datetime¶
- model_config¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- parsed: Any | None = None¶
The validated Pydantic instance when
output_schema=was supplied toAgent.run();Noneotherwise. Typed asAnyto keep the runtime type free; the call site has the schema and can cast or annotate as needed.
- started_at: datetime.datetime¶
- class jeevesagent.core.Runtime[source]¶
Bases:
ProtocolDurable execution. Wraps every side effect in a journal entry.
- session(session_id: str) contextlib.AbstractAsyncContextManager[RuntimeSession][source]¶
Open or resume a durable session.
- async signal(session_id: str, name: str, payload: Any) None[source]¶
Send an external signal (e.g., human approval) to a session.
- async step(name: str, fn: collections.abc.Callable[Ellipsis, collections.abc.Awaitable[Any]], *args: Any, idempotency_key: str | None = None, **kwargs: Any) Any[source]¶
Execute
fnas a journaled step. Replays cached on resume.
- stream_step(name: str, fn: collections.abc.Callable[Ellipsis, collections.abc.AsyncIterator[Any]], *args: Any, **kwargs: Any) collections.abc.AsyncIterator[Any][source]¶
Execute a streaming step. Replays the aggregate on resume.
- class jeevesagent.core.RuntimeSession[source]¶
Bases:
ProtocolHandle to an open durable session held by a
Runtime.
- class jeevesagent.core.Sandbox[source]¶
Bases:
ProtocolIsolation layer for tool execution.
- async execute(tool: jeevesagent.core.types.ToolDef, args: collections.abc.Mapping[str, Any]) jeevesagent.core.types.ToolResult[source]¶
- with_filesystem(root: str) contextlib.AbstractAsyncContextManager[None][source]¶
Temporary filesystem sandbox for the duration of the context.
- class jeevesagent.core.Span(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelA trace span handle. Concrete telemetry adapters return their own representation; this is the value-object contract for in-process use.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- started_at: datetime.datetime = None¶
- class jeevesagent.core.Telemetry[source]¶
Bases:
ProtocolOpenTelemetry-compatible tracing/metrics surface.
- trace(name: str, **attrs: Any) contextlib.AbstractAsyncContextManager[jeevesagent.core.types.Span][source]¶
- class jeevesagent.core.ToolCall(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelA model-emitted request to invoke a tool.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- class jeevesagent.core.ToolDef(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelSchema description of a tool the model can call.
Mirrors the JSON-Schema-flavored shape used across MCP and provider APIs.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- model_config¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class jeevesagent.core.ToolEvent(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelTool registry change notification (MCP listChanged etc.).
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- at: datetime.datetime = None¶
- kind: Literal['added', 'removed', 'updated']¶
- class jeevesagent.core.ToolHost[source]¶
Bases:
ProtocolMCP-aware tool registry. Lazy-loads schemas on demand.
- async call(tool: str, args: collections.abc.Mapping[str, Any], *, call_id: str = '') jeevesagent.core.types.ToolResult[source]¶
Invoke
toolwithargs. Thecall_idis propagated into the returnedToolResultso the loop can correlate results with the originating model-emitted call.
- watch() collections.abc.AsyncIterator[jeevesagent.core.types.ToolEvent][source]¶
Notifications when the tool list changes (MCP listChanged).
- class jeevesagent.core.ToolResult(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelOutcome of a tool invocation.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- classmethod denied_(call_id: str, reason: str, **kwargs: Any) ToolResult[source]¶
- classmethod error_(call_id: str, message: str, **kwargs: Any) ToolResult[source]¶
- classmethod success(call_id: str, output: Any, **kwargs: Any) ToolResult[source]¶
- output: Any = None¶
- started_at: datetime.datetime = None¶
- class jeevesagent.core.Usage(/, **data: Any)[source]¶
Bases:
pydantic.BaseModelToken and cost accounting for a model call.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- model_config¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class jeevesagent.core.set_run_context(context: RunContext)[source]¶
Context manager that installs a
RunContextfor the duration of anasync withblock.The framework uses this internally inside
Agent.run()to expose the live context to tools and hooks. Application code rarely needs it, but it is the supported way to invoke a tool outside an agent loop with explicit scope — for example in background workers that share tool implementations with the agent:async with set_run_context(RunContext(user_id="alice")): await some_tool(...)
Behaves correctly under structured concurrency: nested
async withblocks restore the prior context on exit, andanyiotask-group spawns inherit the active context automatically.
- jeevesagent.core.deterministic_hash(*parts: Any) str[source]¶
Stable hash of arbitrary JSON-serializable parts.
Used as an idempotency key for journaled steps. The hash is stable across processes and Python versions because the input is canonicalised via
json.dumps(..., sort_keys=True).
- jeevesagent.core.get_run_context() RunContext[source]¶
Return the
RunContextfor the currently-running agent.Inside an active
Agent.run()call this returns the live context withuser_id,session_id,run_id, andmetadatapopulated. Outside any active run (test code, direct@toolinvocation, REPL exploration) this returns the default emptyRunContext— never raises.Tools that need scope information call this rather than taking extra parameters:
@tool async def fetch_user_orders() -> str: ctx = get_run_context() return await db.query("orders", user_id=ctx.user_id)