ExecutionContext
Defined in: gadgets/types.ts:513
Execution context provided to gadgets during execution.
Contains utilities for cost reporting and LLM access. This parameter is optional for backwards compatibility - existing gadgets without the context parameter continue to work.
Example
Section titled “Example”// Using reportCost() for manual cost reportingconst apiGadget = createGadget({ description: 'Calls external API', schema: z.object({ query: z.string() }), execute: async ({ query }, ctx) => { const result = await callExternalAPI(query); ctx.reportCost(0.001); // Report $0.001 cost return result; },});
// Using ctx.llmist for automatic LLM cost trackingconst summarizer = createGadget({ description: 'Summarizes text using LLM', schema: z.object({ text: z.string() }), execute: async ({ text }, ctx) => { // LLM costs are automatically reported! return ctx.llmist.complete('Summarize: ' + text); },});Properties
Section titled “Properties”agentConfig?
Section titled “agentConfig?”
optionalagentConfig:AgentContextConfig
Defined in: gadgets/types.ts:637
Parent agent configuration for subagents to inherit.
Contains the model and settings of the agent that invoked this gadget. Subagent gadgets (like BrowseWeb) can use this to inherit the parent’s model by default, rather than using hardcoded defaults.
This is optional - it will be undefined for:
- Gadgets executed via CLI
gadget runcommand - Direct gadget testing without agent context
Example
Section titled “Example”execute: async (params, ctx) => { // Inherit parent model unless explicitly specified const model = params.model ?? ctx.agentConfig?.model ?? "sonnet";
const agent = new AgentBuilder(new LLMist()) .withModel(model) .build(); // ...}depth?
Section titled “depth?”
optionaldepth:number
Defined in: gadgets/types.ts:794
Nesting depth of this gadget execution.
- 0 = Root level (direct gadget call from main agent)
- 1 = First-level subagent (gadget called by a gadget)
- 2+ = Deeper nesting
Useful for:
- Conditional behavior based on nesting level
- Logging with appropriate indentation
- Limiting recursion depth
Example
Section titled “Example”execute: async (params, ctx) => { // Prevent infinite recursion if ((ctx.depth ?? 0) > 3) { return "Maximum nesting depth reached"; }
// Log with depth-aware indentation const indent = " ".repeat(ctx.depth ?? 0); console.log(`${indent}Executing at depth ${ctx.depth}`);}hostExports?
Section titled “hostExports?”
optionalhostExports:HostExports
Defined in: gadgets/types.ts:824
Host llmist exports for external gadgets.
External gadgets MUST use these instead of importing from ‘llmist’ to ensure they use the same version as the host CLI, enabling proper tree sharing and feature compatibility.
Use the getHostExports(ctx) helper function to access these exports
with proper error handling.
Example
Section titled “Example”import { getHostExports, Gadget, z } from 'llmist';
class BrowseWeb extends Gadget({...}) { async execute(params, ctx) { const { AgentBuilder } = getHostExports(ctx); const agent = new AgentBuilder() .withParentContext(ctx) .ask(params.task); }}invocationId?
Section titled “invocationId?”
optionalinvocationId:string
Defined in: gadgets/types.ts:677
Unique invocation ID for this gadget execution.
Used by withParentContext() to identify which parent gadget
nested events belong to.
llmist?
Section titled “llmist?”
optionalllmist:CostReportingLLMist
Defined in: gadgets/types.ts:574
Pre-configured LLMist client that automatically reports LLM costs as gadget costs via the reportCost() callback.
All LLM calls made through this client will have their costs automatically tracked and included in the gadget’s total cost.
This property is optional - it will be undefined if:
- The gadget is executed via CLI
gadget runcommand - The gadget is tested directly without agent context
- No LLMist client was provided to the executor
Always check for availability before use: ctx.llmist?.complete(...)
Example
Section titled “Example”execute: async ({ text }, ctx) => { // Check if llmist is available if (!ctx.llmist) { return 'LLM not available in this context'; }
// LLM costs are automatically reported const summary = await ctx.llmist.complete('Summarize: ' + text, { model: 'haiku', });
// Additional manual costs can still be reported ctx.reportCost(0.0001); // Processing overhead
return summary;}logger?
Section titled “logger?”
optionallogger:Logger<ILogObj>
Defined in: gadgets/types.ts:850
Logger instance for structured logging.
External gadgets should use this for logging instead of importing defaultLogger directly. This ensures logs respect the CLI’s configured log level, format, and destination (file/console).
The logger is optional to support standalone gadget execution and testing.
Use optional chaining when logging: ctx.logger?.debug(...).
Example
Section titled “Example”execute: async (params, ctx) => { ctx.logger?.debug("[MyGadget] Starting operation", { itemId: params.id }); // ... do work ... ctx.logger?.info("[MyGadget] Completed successfully"); return "done";}nodeId?
Section titled “nodeId?”
optionalnodeId:string
Defined in: gadgets/types.ts:766
The tree node ID for this gadget execution.
This identifies the current gadget’s node in the execution tree. Use with tree methods to query/aggregate data for this subtree:
tree.getSubtreeCost(nodeId)- total cost including nested callstree.getSubtreeMedia(nodeId)- all media from nested gadgetstree.getSubtreeTokens(nodeId)- token usage breakdowntree.getDescendants(nodeId)- all child nodes
Note: This is distinct from invocationId which identifies the gadget call
(used in conversation history). nodeId is the tree node identifier.
onSubagentEvent()?
Section titled “onSubagentEvent()?”
optionalonSubagentEvent: (event) =>void
Defined in: gadgets/types.ts:705
Callback for subagent gadgets to report internal events to the parent.
When provided, subagent gadgets (like BrowseWeb) can use this callback to report their internal LLM calls and gadget executions in real-time. This enables the parent agent to display subagent progress indicators.
Recommended: Use builder.withParentContext(ctx) instead of calling
this directly - it handles all the forwarding automatically.
Parameters
Section titled “Parameters”Returns
Section titled “Returns”void
Example
Section titled “Example”// In a subagent gadget like BrowseWeb - just ONE LINE needed:execute: async (params, ctx) => { const agent = new AgentBuilder(client) .withModel(model) .withGadgets(Navigate, Click) .withParentContext(ctx) // <-- Enables automatic event forwarding! .ask(task);
for await (const event of agent.run()) { // Events automatically forwarded - just process normally }}signal
Section titled “signal”signal:
AbortSignal
Defined in: gadgets/types.ts:611
Abort signal for cancellation support.
When a gadget times out, this signal is aborted before the TimeoutException is thrown. Gadgets can use this to clean up resources (close browsers, cancel HTTP requests, etc.) when execution is cancelled.
The signal is always provided (never undefined) to simplify gadget code.
Example
Section titled “Example”// Check for abort at key checkpointsexecute: async (params, ctx) => { if (ctx.signal.aborted) return 'Aborted';
await doExpensiveWork();
if (ctx.signal.aborted) return 'Aborted'; return result;}
// Register cleanup handlersexecute: async (params, ctx) => { const browser = await chromium.launch(); ctx.signal.addEventListener('abort', () => browser.close(), { once: true }); // ... use browser}
// Pass to fetch for automatic cancellationexecute: async ({ url }, ctx) => { const response = await fetch(url, { signal: ctx.signal }); return await response.text();}subagentConfig?
Section titled “subagentConfig?”
optionalsubagentConfig:SubagentConfigMap
Defined in: gadgets/types.ts:670
Subagent-specific configuration overrides from CLI config.
Contains per-subagent settings defined in [subagents.Name] or
[profile.subagents.Name] sections of cli.toml. Allows users to
customize subagent behavior without modifying gadget parameters.
Resolution priority (highest to lowest):
- Runtime params (explicit gadget call)
- Profile-level subagent config
- Global subagent config
- Parent model (if “inherit”)
- Package defaults
Example
Section titled “Example”execute: async (params, ctx) => { const subagentConfig = ctx.subagentConfig?.BrowseWeb ?? {};
const model = params.model ?? subagentConfig.model ?? ctx.agentConfig?.model ?? "sonnet";
const maxIterations = params.maxIterations ?? subagentConfig.maxIterations ?? 15; // ...}
optionaltree:ExecutionTree
Defined in: gadgets/types.ts:751
The execution tree tracking all LLM calls and gadget executions.
Subagent gadgets can use the tree to:
- Automatically aggregate costs via
tree.getSubtreeCost(nodeId) - Collect media outputs via
tree.getSubtreeMedia(nodeId) - Query token usage via
tree.getSubtreeTokens(nodeId)
When using withParentContext(ctx), the subagent shares the parent’s tree,
enabling unified cost tracking and progress visibility across all nesting levels.
This is optional - it will be undefined for:
- Gadgets executed via CLI
gadget runcommand - Direct gadget testing without agent context
- Legacy code that hasn’t adopted the ExecutionTree model
Example
Section titled “Example”execute: async (params, ctx) => { // Build subagent with parent context (shares tree) const agent = new AgentBuilder(client) .withParentContext(ctx) .withGadgets(Navigate, Click) .ask(params.task);
for await (const event of agent.run()) { // Process events... }
// After subagent completes, costs are automatically tracked in tree // No need for manual cost aggregation! const subtreeCost = ctx.tree?.getSubtreeCost(ctx.nodeId!);
// Media from all nested gadgets also aggregated const allMedia = ctx.tree?.getSubtreeMedia(ctx.nodeId!);
return { result: "done", media: allMedia };}Methods
Section titled “Methods”reportCost()
Section titled “reportCost()”reportCost(
amount):void
Defined in: gadgets/types.ts:538
Report a cost incurred during gadget execution.
Costs are accumulated and added to the gadget’s total cost. Can be called multiple times during execution. This is summed with any cost returned from the execute() method and any costs from ctx.llmist calls.
Parameters
Section titled “Parameters”amount
Section titled “amount”number
Cost in USD (e.g., 0.001 for $0.001)
Returns
Section titled “Returns”void
Example
Section titled “Example”execute: async (params, ctx) => { await callExternalAPI(params.query); ctx.reportCost(0.001); // $0.001 per API call
await callAnotherAPI(params.data); ctx.reportCost(0.002); // Can be called multiple times
return 'done'; // Total cost: $0.003}