ADIL EDGE SDK · INTEGRATION EXAMPLES
Register tools. Confirm actions.
Each example adapts the accepted SDK source as of the current candidate; the three interfaces behave the same way. Neither the Eco V1.1 A3b model nor the SDK is publicly released: there is no download, package or installer, and nothing on this page announces one.
Python: a read-only and a state-changing tool
The first request runs the read-only tool because the user wrote the city. The timer request produces a proposal that waits for your decision.
from adil_edge_sdk.native import NativeEdge
def decide(p) -> bool:
# Show the person the stored tool, arguments and effect. Deny by default.
print(f"proposal: {p.tool} {p.arguments} effect={p.effect} ungrounded={p.ungrounded}")
return input("approve? [y/N] ").strip().lower() == "y"
with NativeEdge(model, sha) as edge:
agent = edge.agent()
agent.register_tool("get_forecast", "Get the weather forecast for a city.",
{"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"], "additionalProperties": False},
lambda args, ctx: {"city": args["city"], "high": 17, "conditions": "light rain"})
agent.register_tool("set_timer", "Start a countdown timer.",
{"type": "object", "properties": {"minutes": {"type": "integer", "minimum": 1}}, "required": ["minutes"], "additionalProperties": False},
lambda args, ctx: {"status": "started", "minutes": args["minutes"]}, effect="state_changing")
for message in ("What is the weather in Oslo?", "Set a timer for 18 minutes."):
out = agent.run(message)
while out.kind == "action_proposal": # the host decides: ask the person, deny by default
out = agent.confirm(out.proposal, approve=decide(out.proposal))
print(f"{message!r} -> {out.kind}: {out.text or out.reason}")TypeScript / Node.js
Node starts the engine in a separate host process, so NativeHost is asynchronous and must be closed.
import { NativeHost } from "@thynkr/adil-edge-sdk"; // provisional package name; not published
import type { Proposal } from "@thynkr/adil-edge-sdk";
async function decide(p: Proposal): Promise<boolean> {
// Show the person the stored tool, arguments and effect. Deny by default (no terminal means no approval).
console.log(`proposal: ${p.tool} ${JSON.stringify(p.arguments)} effect=${p.effect}`);
return false; // replace with your own confirmation interface
}
const host = await NativeHost.open({ model, sha256 });
try {
const agent = await host.agent();
await agent.registerTool({
name: "get_forecast", description: "Get the weather forecast for a city.",
parameters: { type: "object", properties: { city: { type: "string" } }, required: ["city"], additionalProperties: false },
handler: async (args) => ({ city: args.city, high: 17, conditions: "light rain" }),
});
await agent.registerTool({
name: "set_timer", description: "Start a countdown timer.", effect: "state_changing",
parameters: { type: "object", properties: { minutes: { type: "integer", minimum: 1 } }, required: ["minutes"], additionalProperties: false },
handler: async (args) => ({ status: "started", minutes: args.minutes }),
});
let out = await agent.run("Set a timer for 18 minutes.");
while (out.kind === "action_proposal") out = await agent.confirm(out.proposal!, await decide(out.proposal!));
console.log(out.kind, out.text ?? out.reason);
} finally {
await host.close();
}C and C++
In C, your callbacks are plain functions. Check every returned status, and dispose of handles in reverse order.
/* After engine, session and agent creation (see the quick start): */
adil_tool_def td; memset(&td, 0, sizeof td); td.struct_size = sizeof td;
td.name = "set_timer"; td.description = "Start a countdown timer.";
td.parameters_json = "{\"type\":\"object\",\"properties\":{\"minutes\":{\"type\":\"integer\",\"minimum\":1}},\"required\":[\"minutes\"],\"additionalProperties\":false}";
td.effect = ADIL_EFFECT_STATE_CHANGING; /* always waits for the host */
td.callback = set_timer; /* your function; the engine calls it only after approval */
adil_agent_register_tool(agent, &td, err, sizeof err);
adil_outcome_kind kind; char *out = NULL;
adil_status st = adil_agent_run(agent, "Set a timer for 18 minutes.", &kind, &out);
if (st == ADIL_OK && kind == ADIL_OUTCOME_ACTION_PROPOSAL) {
/* Parse "id" and "digest" from the outcome JSON with your own JSON parser, show the proposal to the person, then: */
st = adil_agent_confirm(agent, id, digest, person_approved ? ADIL_DECISION_APPROVE : ADIL_DECISION_DENY, &kind, &out);
/* A proposal resolves exactly once: confirming it again returns ADIL_E_CONFIRMATION. */
}
adil_string_free(out);Before you adapt these
- The handlers return fixed data. In a real application they validate their inputs again and enforce your own authorisation.
- The examples decide for the person only by denying. Build a real confirmation interface that shows the tool, arguments, destination and scope, and approve one proposal at a time.
- Register any tool that reads private data or sends data out of the process as confirmation-required.
- These are candidate interfaces and may change before release.