Sign In

@spfunctions/agent

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@spfunctions/agent

SimpleFunctions Agent SDK.

latest
npmnpm
Version
1.0.2
Version published
Weekly downloads
146
-6.41%
Maintainers
1
Weekly downloads
 
Created
Source

@spfunctions/agent

Agent SDK for SimpleFunctions market-intelligence agents.

Install the stable packages:

npm install @spfunctions/sdk@1.0.0 @spfunctions/agent@1.0.0

This package is not a browser runtime, CLI shell wrapper, or MCP runtime. It is a TypeScript agent runtime for prediction-market applications that need model streaming, strict SimpleFunctions tools, semi-realtime watch inputs, policy hooks, trace, replay, and explicitly policy-gated Kalshi or Polymarket execution.

Five-minute path

The primary surface is Cursor-style:

import { Agent } from "@spfunctions/agent/v1"

const agent = await Agent.create({
  apiKey: process.env.SF_API_KEY,
  openRouterApiKey: process.env.OPENROUTER_API_KEY,
  model: { id: "anthropic/claude-haiku-4.5" },
})

const run = agent.send("Read world state and summarize the largest market moves.")

for await (const event of run.stream()) {
  console.log(event.type)
}

const prior = await Agent.getRun(run.id, { agentId: run.agentId })
await prior?.wait()

Agent.create({ apiKey }) mounts read-only SimpleFunctions strict tools by default. Write tools are not mounted unless you explicitly opt into them with builtinTools: "all" or a named allowlist. If no provider is passed, the runtime uses openRouterApiKey, options.env.OPENROUTER_API_KEY, or process.env.OPENROUTER_API_KEY when available.

The run handle supports:

  • run.stream() for ordered SDK messages
  • run.wait() for a cached event array
  • run.cancel() for interruption
  • run.status for pending, running, completed, cancelled, or failed
  • Agent.getRun(run.id, { agentId }) for same-process reconnect
  • agent.send(prompt, { onDelta, onStep }) for callback-style harnesses

Market-native primitives

Generic coding-agent SDKs give an agent files, shell, and editor control. SimpleFunctions gives an agent market context:

  • strict canonical tools from /api/contracts/tools
  • world.read, markets.search, market.inspect, market.candles, markets.screen, regime.scan, calendar.list, index.current, contagion.scan, crossvenue.pairs, query.ask, econ.query, gov.query, and user-scoped reads through an API-keyed SDK client
  • watch.ticks() and watch.world() as cancellable semi-realtime async inputs
  • canUseTool() and hooks for permission, input shrinking, and cost control
  • file-local sessions and replayable traces
import { Agent, OpenRouterProvider, watch } from "@spfunctions/agent/v1"

const agent = await Agent.create({
  apiKey: process.env.SF_API_KEY,
  provider: new OpenRouterProvider({
    apiKey: process.env.OPENROUTER_API_KEY,
    maxTokens: 1024,
  }),
  model: "anthropic/claude-haiku-4.5",
  options: {
    watch: [
      { kind: "ticks", tickers: ["KXEXAMPLE"], cadence: "5min" },
    ],
    maxTurns: 4,
    maxBudgetUsd: 0.50,
    maxOutputTokens: 768,
    canUseTool(toolName, input) {
      if (toolName === "markets.search" && typeof input === "object" && input) {
        return { behavior: "allow", updatedInput: { ...input, limit: 5 } }
      }
      return { behavior: "allow" }
    },
  },
})

for await (const tick of watch.ticks({
  tickers: ["KXEXAMPLE"],
  cadence: "5min",
  cycles: 1,
  apiKey: process.env.SF_API_KEY,
})) {
  console.log(tick.type, tick.ticker, tick.price)
}

watch.ticks() reads live SimpleFunctions market inspection prices when you pass an API key or client. Without one, it emits a deterministic synthetic: true development tick; production agents should pass apiKey, client, or a custom fetchSnapshot.

Tool loop surface

For Anthropic-style consumers, the package also exports query(), startup(), tool(), createSdkMcpServer(), session helpers, OpenRouterProvider, and createSimpleFunctionsBuiltinTools() from the root package and from @spfunctions/agent/v1.

import { SimpleFunctions } from "@spfunctions/sdk"
import {
  OpenRouterProvider,
  createSimpleFunctionsBuiltinTools,
  query,
} from "@spfunctions/agent/v1"

const sf = new SimpleFunctions({
  baseUrl: "https://simplefunctions.dev",
  apiKey: process.env.SF_API_KEY,
})

for await (const message of query({
  prompt: "Watch macro markets and explain any large move. Do not write or trade.",
  options: {
    provider: new OpenRouterProvider({ apiKey: process.env.OPENROUTER_API_KEY }),
    model: "anthropic/claude-haiku-4.5",
    tools: createSimpleFunctionsBuiltinTools(sf),
    allowedTools: ["world.read", "markets.search", "market.inspect", "market.candles"],
    maxTurns: 4,
    maxBudgetUsd: 0.50,
  },
})) {
  console.log(message.type)
}

query() yields ordered SDKMessage events: system, user, assistant, stream_event, tool_result, status, and final result messages depending on the run. The returned Query supports interrupt(), setModel(), setPermissionMode(), setMcpServers(), streamInput(), close(), and initializationResult().

OpenRouterProvider defaults to max_tokens=512. Set new OpenRouterProvider({ maxTokens }) for a provider-wide default, or options.maxOutputTokens for a single agent run that needs a longer memo.

Low-level direct runner

The package still exports SimpleFunctionsAgent for deterministic direct tool execution, trace recording, replay-only runs, and compatibility with sf agent --tool semantics. It is the low-level primitive underneath some tests and examples, not the main agent product surface.

import { SimpleFunctions } from "@spfunctions/sdk"
import { FileTraceStore, SimpleFunctionsAgent } from "@spfunctions/agent"

const sf = new SimpleFunctions({
  baseUrl: "https://simplefunctions.dev",
  apiKey: process.env.SF_API_KEY,
})

const direct = new SimpleFunctionsAgent({
  client: sf,
  policy: { maxSideEffect: "none", maxCostEffect: "api_cost" },
  trace: new FileTraceStore("./sf-agent.trace.jsonl"),
})

await direct.tools.world.read({})

Live execution is disabled by default. Applications must opt in with both side-effect and cost ceilings plus trade guardrails:

const executionAgent = new SimpleFunctionsAgent({
  client: sf,
  policy: {
    maxSideEffect: "live_trade",
    maxCostEffect: "venue_request_cost",
    trade: {
      allowedVenues: ["kalshi"],
      allowedTickers: ["KXFED-27APR-T3.50"],
      maxQuantity: 2,
      maxOrderCostCents: 100,
      requireLimitPrice: true,
      allowRuntimeStart: true,
      confirmToken: "operator-approved",
    },
  },
})

await executionAgent.tools.execution.place({
  ticker: "KXFED-27APR-T3.50",
  action: "buy",
  quantity: 1,
  limitPrice: 32,
  confirm: "operator-approved",
})

For Polymarket, the same tool accepts venue: "polymarket" plus a CLOB tokenId or marketId and an explicit limit price. Add venue and jurisdiction guardrails in the policy when your application needs compliance controls:

const polyAgent = new SimpleFunctionsAgent({
  client: sf,
  policy: {
    maxSideEffect: "live_trade",
    maxCostEffect: "venue_request_cost",
    trade: {
      allowedVenues: ["polymarket"],
      blockedJurisdictions: ["US", "FR"],
      requireJurisdiction: true,
      maxQuantity: 2,
      maxOrderCostCents: 100,
      requireLimitPrice: true,
    },
  },
})

await polyAgent.tools.execution.place({
  venue: "polymarket",
  tokenId: "POLYMARKET_CLOB_TOKEN_ID",
  action: "buy",
  quantity: 1,
  limitPrice: 32,
  jurisdiction: "CA",
})

execution.place uses SDK runtime orchestration before creating the intent. Set trade.allowRuntimeStart: false to require an already-running runtime, or pass runtime: { mode: "none" } for an explicit intent-only workflow.

No-key direct modes are intentionally narrow: inspectOnly can inspect strict contracts and replayOnly can replay existing traces. Replay misses never fall through to live execution.

Maintainer smokes

npm --prefix packages/agent run pack:smoke
npm --prefix packages/agent run smoke:quickstart
npm --prefix packages/agent run smoke:product-grade
npm --prefix packages/agent run smoke:live
npm --prefix packages/agent run smoke:registry-latest

Without SF_API_KEY, live sections print SKIP and exit successfully. With a key, the smokes call production world.read, verify broad legacy names stay non-canonical, record redacted traces, and replay them offline. Scripts do not write API keys to disk.

The Agent package publishes only dist/ and README.md. Build output omits source maps and declaration maps, and package-surface tests reject stale source-map artifacts before release.

Cookbook examples

  • examples/watch-iran-oil.ts watches semi-realtime market ticks and summarizes sharp moves.
  • examples/market-monitor.ts is the shortest Agent SDK path for world state, market search, market inspection, policy gates, and JSONL trace.
  • examples/trace-replay.ts records a redacted trace, replays world.read offline, and proves replay misses fail with ReplayMissError.
  • examples/thesis-monitor.ts evaluates a thesis against live world/regime context.
  • examples/calibration-loop.ts collects markets and computes a simple calibration signal.
  • examples/subagent-handoff.ts runs a coordinator with specialist subagents.
  • examples/mcp-bridge.ts exposes the strict Agent-callable read subset through a local stdio MCP bridge.

FAQs

Package last updated on 27 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts