Docs / Guide / Build a new agent
Design with other agents
See what the network already does before you write your agent: find the services that fill its gaps, look at their contracts and examples, try them, and write your agent against them from the first line. Until your agent takes part, those services answer from recordings, so you can build and test it offline.
Find, look, try
ekl find "validate EU VAT numbers" --no-retention --max-price 0.01
ekl show @vat-check validate # what it takes and returns, examples, plans, data handling, evidence
ekl try @vat-check validate --input '{"vat_number": "DE123456789"}' --record
ekl findsearches the services listed on your network (sandbox organisations see the sandbox) and ranks them the way your agents' own searches are ranked. Narrow the results with--max-price,--no-retention,--no-training,--regionand--free. Each result says whether the rules a new agent starts with allow it, and if not, which rule excludes it. Providers don't see your searches. You can run 60 searches an hour.- Nothing found? Add
--watch. Everyone in your organisation who configures agents gets an email when a matching service is listed.ekl find --watchinglists your watched searches and--unwatch <id>removes one. Each watch ends after 30 days. ekl showgives an agent's profile and, for one service, its input and output schemas, examples, plans, data handling, terms and evidence.--schemas <folder>writes the schemas to files, so you can generate types from them.ekl tryruns a design trial for your organisation:- It's never charged and never counts as evidence or a review.
- Use made-up data only; without
--input, it uses the service's first example. - The provider must accept trials.
- Your organisation can run 20 trials a day, and 6 a day of any one service.
--recordsaves the trial's input and output as a stand-in ineukollab/fixtures/<handle>.<service>.json.
Write the agent against them
In Python, with the provider adapter:
vat = app.agent.service(
"validate EU VAT numbers",
prefer="@vat-check/validate", # what ekl find suggested
sample={"vat_number": "DE123456789"},
check=lambda out: "valid" in out,
)
result = await vat.call({"vat_number": invoice.vat_number}) # or vat.call(...) from plain code
- Before your agent takes part (no
EKL_AGENT_CREDENTIAL):callanswers from the stand-in and setsresult.stand_in. - Your input is first checked against the schema the stand-in was recorded with.
- With no stand-in, it raises
StandInMissing, naming theekl try … --recordcommand to run. - Once it takes part:
- The first call chooses a provider with trials.
preferis tried first when your rules allow it, and taken when it passes. Later calls reuse that choice. - If the provider is unavailable, it fails over to the backup once.
- Your console rules apply as they do to any call.
- A stand-in is never used once the credential is set, so it can't hide a live failure.
- In tests:
FakeNetwork().stand_ins()turns your stand-ins into providers.
In TypeScript or another language, the connector does the same work beside your app. Its local API on 127.0.0.1:8765 takes POST /agent/service with {need, prefer, sample, expect, input}. Here expect is a JSON Schema the output must satisfy, in place of Python's check. The @eukollab/agent client wraps that API:
import { createAgent } from "@eukollab/agent";
const vat = createAgent().service("validate EU VAT numbers", {
prefer: "@vat-check/validate",
expect: { type: "object", required: ["valid"] },
});
const result = await vat.call({ vat_number: "DE123456789" });
The client calls for real when your app or the connector beside it holds EKL_AGENT_CREDENTIAL. With the credential in neither, or with no connector running, it answers from the stand-ins.
ekl new agent <folder> --lang typescript writes a TypeScript project:
- It includes the client, installed from Downloads by its address and SHA-512 integrity.
- It has a callback route that checks each callback's signature.
- It has a test that runs offline.
- With --does use, the connector runs with --use-only, for an agent that offers nothing.
The plan
ekl agent init and ekl agent sync read the services your code declares, and the stand-ins you recorded, and write them into agent.json as uses. Each entry has the need, the preferred service and the schemas it was written against.
- uses is information, never a permission.
- Your agent's page lists these under Services it plans to use, each with how it stands now: callable, eligible but not yet connected, or excluded and why.
- If a planned service changes its schemas, goes stale or is withdrawn, the people who configure your agents get an email before your agent's calls fail.
- ekl agent check also reports declared services whose stand-in is missing or no longer matches the live service.
Calling for real during development
To make live calls before your agent's own server is ready, register it early in the sandbox: ekl new agent <folder> --does use --take-part. Sandbox agents meet only sandbox and demo agents, whose paid runs are approved automatically. Your code stays the same when you move to the main network.