Skip to content

Weather Tool LLM Loop

Define one weather tool and let an LLM turn call it before producing a final answer.

A Cloudflare agent facade with get_current_weather, one LLM route, and a submit call that returns a tool-informed answer.

  1. Define the weather tool:

    import { defineTool } from "@agent-os/kernel/tools";
    import { Schema } from "effect";
    const getCurrentWeather = defineTool({
    name: "get_current_weather",
    description: "Get the current weather for a city.",
    args: Schema.Struct({ city: Schema.String }),
    authority: "weather.read",
    admit: () => ({ ok: true }),
    execute: ({ city }) => ({
    city,
    temperatureC: 22,
    condition: "sunny",
    }),
    });
  2. Register the tool in the same defineAgentDO facade as the LLM route:

    export const AgentDO = defineAgentDO<Env>({
    bindings: [
    endpoint<Env>("llm").from((env) => env.LLM_ENDPOINT),
    credential<Env>("llm-key").from((env) => env.LLM_KEY),
    ],
    llms: {
    default: openAIChat({
    model: "gpt-4.1-mini",
    endpoint: "llm",
    credential: "llm-key",
    }),
    },
    tools: [getCurrentWeather],
    scopeRefForScope: (scope) => ({ kind: "conversation", scopeId: scope }),
    });
  3. Submit a user turn through the facade:

    const result = await agent.submit({
    intent: "What is the weather in Lisbon?",
    input: {},
    deliver: "weather.answer.ready",
    budget: { maxTurns: 3 },
    });
  4. Keep weather facts in the tool implementation. Do not put provider material, API keys, raw provider responses, or resolved endpoint URLs into ledger events.

The deterministic local proof for this tutorial used a fake LLM transport and verified this sequence:

request 1 includes get_current_weather
LLM returns get_current_weather({ city: "Lisbon" })
runtime executes the tool
request 2 includes the tool result
LLM returns "Lisbon is sunny and 22 C."
weather.answer.ready is delivered

A live provider checkpoint is a separate opt-in smoke: run it only after the provider endpoint, credential, and model are declared from one source.

Tighten the tool contract with tool schema and authority.