JITHarnessExtension#

Create, compose, unload, and save session-local Python tools. See the guide.

class zett_agent.jit_harness.extension.JITHarnessExtension(snapshot=None, *, manage_base_tools=True, max_call_depth=32, error_capacity=100, error_message_chars=4000, call_capacity=2000, inspection_tools=InspectionToolExposure.DEFERRED)[源代码]#

Let a model evolve independent Python tools and text workflows per session.

参数:
  • snapshot (JITHarnessSnapshot | None) -- Initial template, copied independently into every new session.

  • manage_base_tools (bool) -- Enable base-tool unload/load and profiling. False protects application base tools and leaves their handlers unchanged.

  • max_call_depth (int) -- Maximum nested calls, including recursive composition.

  • error_capacity (int) -- Maximum distinct recent errors retained per session.

  • error_message_chars (int) -- Maximum characters retained per error message.

  • call_capacity (int) -- Maximum finished call records retained per session; oldest records are dropped first and lifetime aggregates stay complete.

  • inspection_tools (InspectionToolExposure) -- How the model sees the inspection tools that read source, schemas, statistics, call records, and recent errors.

备注

Opt in only for trusted generated Python. The control tools are ordinary functions on any protocol with function calling. Inspection tools can be deferred, so a provider that supports deferred loading fetches them on demand, while protocols that ignore that flag still receive every definition. Application tools added later in setup or before-model hooks are adopted before dispatch; existing policy removals are not restored.

示例

Enable evolution and explicitly save the resulting toolbox:

config = AgentRunConfig(session_id="my-session")
jit = JITHarnessExtension()
client = await create_agent(model, config=config, tools=[read_file], extensions=[history, jit])
await client.run("Build a reusable file preview tool.")
jit.get_harness("my-session").save("harness.json")
get_harness(session_id)[源代码]#

Return an existing session's toolbox for explicit inspection or saving.

参数:

session_id (str)

返回类型:

JITHarness

forget_session(session_id)[源代码]#

Release an idle in-memory toolbox; this does not delete saved files.

参数:

session_id (str)

返回类型:

None

async on_tool(context)[源代码]#

Rebind current base tools, mount wrappers, and remove unloaded tools.

参数:

context (AgentRunContext)

返回类型:

None

async on_state(context)[源代码]#

Adopt tools registered by later setup hooks before context loading.

参数:

context (AgentRunContext)

返回类型:

None

async on_tool_call(context, call, call_next)[源代码]#

Adopt late before-tool registrations before handler middleware runs.

参数:
返回类型:

ToolResult

async before_tool(context, call)[源代码]#

Announce a management or dynamic tool call before its handler runs.

The event carries identity and classification only. Calls to application base tools emit nothing, and a name this harness has never seen is ignored instead of being reported as a JIT call.

参数:
返回类型:

None

async after_tool(context, call, result, error)[源代码]#

Report the outcome of a management or dynamic tool call.

参数:
返回类型:

None

async on_model_request(context, request, call_next)[源代码]#

Render current guidance afresh, without persisting stale definitions.

参数:
返回类型:

AsyncIterator[ModelEvent]

async on_success(context, result)[源代码]#

Release request bindings while retaining the session's definitions.

参数:
返回类型:

None

async on_error(context, error)[源代码]#

Release bindings after setup, model, or tool-hook failures.

参数:
返回类型:

None

async on_event(context, event)[源代码]#

Detach cancelled requests so late worker calls cannot use a new run.

参数:
返回类型:

None

accept(config, event)#

Handle one external event and report whether it was accepted.

The Agent broadcasts each event to every registered extension. Override this synchronous hook when an extension waits for input from another thread, HTTP request, TUI, or Web UI. The default ignores the event. Config is passed separately and can be None before initialization. Each extension decides whether the supplied identity and payload match its protocol. Return True to include this extension's name in the broadcast result; returning False does not stop later receivers.

参数:
返回类型:

bool

async after_model(context, response)#

Run after the complete assistant message is appended.

参数:
返回类型:

None

async after_run(context, result)#

Run after a successful final answer is appended.

参数:
返回类型:

None

async after_turn(context, result)#

Run once the turn's assistant message and tool results are settled.

result is the assistant message that opened the turn: either the final answer, or the tool-calling message whose ToolMessages were appended. Every requested call is settled first, including calls that failed, and calls that steering skipped, which arrive as unsuccessful or skipped ToolMessages.

Steering that interrupts a turn is accepted while the runtime settles that batch, so its UserMessage is already appended when this hook runs and the steering turn follows as the next turn.

A turn that never completed, because the request failed or was cancelled, has no after_turn call; use on_error and RunCancelledEvent for those paths.

参数:
返回类型:

None

async before_model(context, request)#

Inspect the current request before preprocessing a primary model call.

Request fields are frozen. Change messages through AgentRunContext.add_message() or AgentRunContext.replace_messages(), local tools through context.tools, and provider tools through context.server_tools; the runtime rebuilds these fields before the next hook and before calling the provider. This is a shallow request view, not an immutable copy of each message or tool definition.

示例

Inspect the tools offered in this iteration:

async def before_model(self, context, request):
    offered = {definition.name for definition in request.tools}
    if "write_file" in offered:
        context.add_message(
            SystemMessage(content="Read existing files before editing."),
        )
参数:
返回类型:

None

async before_run(context)#

Run after the transformed user input is appended and published.

参数:

context (AgentRunContext)

返回类型:

None

async before_turn(context)#

Run before this turn's model call.

Runs after before_run() on the first turn and after the previous turn's after_turn() on later ones. Model request assembly, compaction, and before_model() follow this hook, so context edited here reaches the provider.

参数:

context (AgentRunContext)

返回类型:

None

property name: str#

Unique registration identity, defaulting to the concrete class name.

Override with a class attribute or assign an instance name to register independently configured instances of the same extension type.

async on_compact(context)#

Summarize restored context when a caller asks for compaction.

Agent.compact restores the session through on_tool and on_state exactly as a request does, appends no input message, and makes no primary model call: the only work a compaction pass does is what this hook performs. The default does nothing, so an extension with nothing to compact pays nothing.

示例

Usage:

async def on_compact(self, context):
    await self.compact(context)
参数:

context (AgentRunContext)

返回类型:

None

async on_message(context)#

Transform context.input_message after state restoration, before append.

Replace the pending UserMessage to implement externally selected modes. Do not append or persist it here: the runtime appends the final message exactly once after all input hooks finish. before_run sees that message through AgentRunContext.add_message() or AgentRunContext.replace_messages(), and persistence subscribers have already received it.

参数:

context (AgentRunContext)

返回类型:

None

property pending: bool#

Return whether this extension is participating in an active request.

The Agent updates this state for every registered extension, including extensions whose hooks are currently idle. One extension instance may be shared by multiple Agents and sessions; pending remains true until all requests using that instance have finished, failed, or been cancelled. Persistent data retained between requests does not count.