Instrument your own agent
Put real tool callbacks behind Thoth's policy check and preserve actor context.
Complete Your first governed agent before connecting tools that read private data or change external systems.
1. Define the action and its owner
Choose a distinct agent ID and stable tool names. Start with one read-only tool. Agree with your administrator on the server policy for that action, the initiating identity, and which actions need human approval.
approved_scope describes the intended tool set; adding a name to it does not
create server policy. Use your tenant's supplied endpoint and a runtime execute
key. Keep administrative credentials out of the agent process.
2. Wrap the tool execution path
In the first-agent example, replace the demo.read callback with your own
read-only function, change the agent ID, and set the agreed scope. Pass the
initiating user's verified identity and a session ID for the request. Keep the
mode and failure settings agreed for your deployment.
Choose the adapter that matches how your framework actually executes tools:
| Your execution path | Integration |
|---|---|
Python agent exposing .tools | instrument() |
| Python function map or custom model tool loop | Python SDK: instrument the toolchain, then dispatch through its governed function map |
| LangGraph graph, tools, or ToolNode | LangGraph integration |
| TypeScript tool objects or model tool loop | TypeScript SDK |
| Go function callbacks | Go SDK: WrapTool or a session-scoped wrapper |
| External MCP server used by a desktop client | MCP proxy |
Your model may choose a tool name and arguments. Your application must dispatch that choice through the governed wrapper. Do not retain an alternate route to the original callback. Reject unknown tool names before dispatch.
Python: dispatch a tool through a governed function map
This complete example uses a local document lookup to illustrate a custom
agent loop. Ask your administrator to configure policy for the new agent ID
and read_document tool first. Set THOTH_AGENT_ID to that agreed agent ID
and APP_USER_ID to the identity established by your application. Reuse your
runtime connection variables from the first-agent guide.
Save as my_agent.py in the project where you installed atensec-thoth:
Run python my_agent.py. If policy permits the action, the output is
Welcome to your governed agent. Otherwise inspect the refusal and server
decision; do not retry read_document directly. Replace the local lookup with
a real read-only callback after you verify policy. For a model-specific tool
loop, use the corresponding Python SDK adapter; TypeScript
and Go can reuse the wrapped tool execution pattern from the first-agent guide.
3. Handle decisions without bypassing them
- ALLOW: execute the governed callback and return its result.
- STEP_UP: let the supported SDK approval flow resolve; keep the action paused.
- BLOCK: return a clear refusal or escalate through the approved workflow.
- Service or authentication error: keep fail-open disabled and resolve the failure.
Do not catch an exception and invoke the raw callback as a fallback. Keep policy refusals separate from callback failures in your application's logs and user messages. Avoid exposing keys, hold tokens, or sensitive arguments in those messages.
4. Verify before adding more tools
Test a permitted call and a refused call against your configured policy. Confirm the refused callback never executed. Inspect the reason, agent, actor, session, and correlation identifiers in decision history. If approval is part of your policy, test approval, denial, and expiry before enabling sensitive actions.
Check telemetry delivery separately and verify any receipt or export you intend to use as evidence. Repeat verification when you change tools, policies, SDK releases, or identity handling.
Next, use your SDK reference for framework and lifecycle details, or configure supported governance settings as code.