The agent core

The counsel loop

The reasoning core is one pure function with no SDK imports and no network of its own. Every dependency is injected, which is what makes the whole turn testable with fakes.

#Parsing intent

Before the model sees a token, the agent builds a deterministic frame for the turn — same text in, same frame out — because that frame is what the prompt and the recommendation extractor both ground against. The model gets to choose and explain; it never gets to invent the numbers.

packages/agent/src/intent.tsts
export interface ParsedIntent {
  goal: 'bridge' | 'swap' | 'yield' | 'unknown';
  fromChain: ChainName | null;
  toChain: ChainName | null;   // null = "the best I can reach" — the agent picks
  fromAsset: AssetSymbol | null;
  toAsset: AssetSymbol | null;
  amount: string | null;       // decimal string in units of fromAsset
  risk: RiskTolerance | null;
}

Goal detection is intentionally ordered: yield intent dominates, so “move 500 USDC into the best ETH yield” is a yield goal, not a bridge — even though it contains the word “move.” That precedence is what makes the canonical demo sentence route correctly. Routes themselves come from a RouteProvider interface: a deterministic heuristic ships now, and real Bungee/Socket quoting slots in behind the same interface without touching the loop.

#The counsel turn

The whole algorithm is nine steps, and step 5 is the one that matters most:

packages/agent/src/counsel.tsts
export async function counselTurn(input, deps): Promise<AgentTurn> {
  const turnId = deps.newTurnId();
  const now = deps.now();

  const memory   = await deps.memory.loadStrategy(input.userId);   // 1. hot cache; never blocks on 0G
  const parsed   = parseIntent(input.intent);                      // 2. structured frame
  const routeCtx = deps.routes.context(parsed);                    //    cross-chain options
  const messages = buildPrompt(input.intent, memory, routeCtx);    // 3. intent + memory + routes

  const inference = await deps.compute.infer(messages);            // 4. inference via 0G Compute (TEE)

  const verification = await deps.compute.verify({                 // 5. TEE attestation — REAL result only
    provider: inference.provider, answer: inference.answer, chatId: inference.chatId,
  });
  const inferenceReceipt = { /* ... */ valid: verification.valid };  //    never hardcoded true

  const recommendation = extractRecommendation(inference.answer, routeCtx);  // 6. grounded in routeCtx
  const facts = deps.memory.consolidate({ /* ... */ });            // 7. distill durable facts (pure)
  const memoryReceipt = await deps.memory.commit(input.userId, facts);  // 8. cache now, 0G upload async

  return { turnId, answer: inference.answer, recommendation, inferenceReceipt, memoryReceipt };  // 9.
}

The verified flag is driven by the real verification result and nothing else. A turn whose TEE check fails is returned with the flag set to false. The answer is never thrown away, and an unverified call is never presented as verified — the UI gates the “Sworn” badge on exactly this flag.

#Grounded recommendations

The most dangerous thing an AI DeFi agent can do is hallucinate a number and render it as fact. Sworn makes that impossible: the model picks a direction and writes the rationale, but every figure shown is read back from the matching route candidate, never from the model’s text.

packages/agent/src/recommendation.tsts
export function extractRecommendation(answer, routeCtx): Recommendation | null {
  if (routeCtx.candidates.length === 0) return null;

  const choice = parseModelChoice(answer);          // reads the model's fenced json choice
  if (choice === 'no-recommendation') return null;  // honor a clarifying question

  const candidate = choice ? matchCandidate(choice, routeCtx.candidates) : null;
  const grounded  = candidate ?? defaultCandidate(routeCtx);   // best by risk tier

  return candidateToRecommendation(grounded, choice);          // numbers from candidate, prose from model
}
Design note
Two halves, both required

The inference receipt proves the model ran in an enclave; the grounding discipline proves the numbers came from the route layer, not a hallucination. An attested model that is free to invent figures is still dangerous; a grounded number with no attestation is still unverifiable. Sworn ships both.

#Why it is testable

Because every dependency is a parameter — the compute client, the memory port, the route provider, the clock, the id source — a complete turn runs with a fake compute client, an in-memory store, and a frozen clock, asserting the receipts and the grounded recommendation without a single network call. Seven tests cover the agent package; three more in the API exercise the same loop against the real service wiring.