Documentation Index
Fetch the complete documentation index at: https://docs.simplefunctions.dev/llms.txt
Use this file to discover all available pages before exploring further.
This guide starts from a blank TypeScript project and ends with:
- SDK install
- strict manifest inspection
- API-keyed
world.read
- Agent v0 direct tool execution
- Agent v0 streaming
- local trace record/replay
- Agent v1
query()
- semi-realtime
watch
1. Install
npm init -y
npm install @spfunctions/sdk@0.1.0-alpha.0 @spfunctions/agent@0.1.0-alpha.0
Use Node 18 or newer.
2. Set Keys
For SDK data calls and Agent live execution:
export SF_API_KEY="sf_..."
For Agent v1 model-loop examples:
export OPENROUTER_API_KEY="..."
Do not put long-lived keys in browser bundles. Use these packages from server-side TypeScript, background jobs, local agent harnesses, or trusted notebooks.
3. Inspect The Strict Contract Without A Key
/api/contracts/tools is the SDK and Agent contract truth.
import { SimpleFunctions } from "@spfunctions/sdk"
const sf = new SimpleFunctions({
baseUrl: "https://simplefunctions.dev",
})
const manifest = await sf.manifest.list()
const world = await sf.manifest.get("world.read")
const legacy = await sf.manifest.get("get_world_state")
console.log(manifest.schemaVersion)
console.log(world?.name)
console.log(legacy)
Expected:
0.3.0-draft
world.read
null
get_world_state is a broad compatibility name, not a canonical SDK/Agent tool.
4. Make The First SDK Data Call
import { SimpleFunctions } from "@spfunctions/sdk"
const sf = new SimpleFunctions({
baseUrl: "https://simplefunctions.dev",
apiKey: process.env.SF_API_KEY,
})
const world = await sf.world.get()
console.log(world.asOf)
console.log(world.regime?.label)
console.log(world.salient?.slice(0, 3).map(item => item.label))
If no API key is configured, this call throws MissingApiKeyError because world.read is cost-bearing and not anonymously allowlisted.
5. Search And Inspect Markets
const search = await sf.markets.search({
query: "Fed CPI",
venue: "kalshi",
limit: 5,
})
for (const market of search.markets ?? []) {
console.log(market.ticker, market.title, market.price)
}
const firstTicker = search.markets?.[0]?.ticker
if (firstTicker) {
const detail = await sf.markets.get(firstTicker)
const history = await sf.markets.history(firstTicker)
console.log(detail.title)
console.log(history)
}
6. Handle Errors
import {
MissingApiKeyError,
PermissionDeniedError,
SimpleFunctionsRateLimitError,
} from "@spfunctions/sdk"
try {
await sf.theses.list()
} catch (error) {
if (error instanceof MissingApiKeyError) {
console.error("missing key", error.tool, error.reason)
} else if (error instanceof PermissionDeniedError) {
console.error("permission denied", error.requestId)
} else if (error instanceof SimpleFunctionsRateLimitError) {
console.error("rate limited")
} else {
throw error
}
}
7. Create An Agent v0 Direct Runner
import { SimpleFunctions } from "@spfunctions/sdk"
import { SimpleFunctionsAgent } from "@spfunctions/agent"
const sf = new SimpleFunctions({
baseUrl: "https://simplefunctions.dev",
apiKey: process.env.SF_API_KEY,
})
const agent = new SimpleFunctionsAgent({
client: sf,
policy: {
maxSideEffect: "none",
maxCostEffect: "api_cost",
},
})
The policy above allows world.read and other normal API-cost read calls. It blocks search, venue, and LLM-cost tools unless you raise maxCostEffect.
const result = await agent.call("world.read", {})
console.log(result.tool)
console.log(result.output)
Typed wrapper:
const result = await agent.tools.world.read({})
Streaming:
for await (const event of agent.stream("world.read", {})) {
console.log(event.type, event.runId, event.callId)
}
import type { AgentToolInput, AgentToolName } from "@spfunctions/agent"
const name: AgentToolName = "markets.search"
const input: AgentToolInput<"markets.search"> = {
query: "oil geopolitics",
limit: 5,
}
const searchAgent = new SimpleFunctionsAgent({
client: sf,
policy: {
maxSideEffect: "none",
maxCostEffect: "search_cost",
},
})
await searchAgent.call(name, input)
10. Record And Replay A Trace
import { FileTraceStore, ReplayMissError } from "@spfunctions/agent"
const trace = new FileTraceStore("./sf-agent.trace.jsonl")
await agent.tools.world.read({}, { trace })
const replay = new SimpleFunctionsAgent({
client: new SimpleFunctions({ baseUrl: "https://simplefunctions.dev" }),
mode: "replayOnly",
trace: new FileTraceStore("./sf-agent.trace.jsonl"),
})
const replayed = await replay.tools.world.read({})
console.log(replayed.replayed)
try {
await replay.tools.world.delta({ since: "1h" })
} catch (error) {
if (error instanceof ReplayMissError) {
console.log("Replay miss. No live call was made.")
}
}
11. Run Agent v1 Query
import { OpenRouterProvider, query } from "@spfunctions/agent/v1"
const provider = new OpenRouterProvider({
apiKey: process.env.OPENROUTER_API_KEY,
})
for await (const message of query({
prompt: "Summarize what prediction markets imply about Fed cuts.",
options: {
provider,
model: "anthropic/claude-haiku-4.5",
maxTurns: 3,
maxBudgetUsd: 0.25,
},
})) {
console.log(message.type)
}
import { createSimpleFunctionsBuiltinTools, query } from "@spfunctions/agent/v1"
const tools = createSimpleFunctionsBuiltinTools(sf)
for await (const message of query({
prompt: "Find markets related to inflation and explain the top signal.",
options: {
provider,
tools,
allowedTools: ["markets.search", "market.inspect", "world.read"],
maxTurns: 4,
maxBudgetUsd: 0.50,
},
})) {
console.log(message.type)
}
import { watch } from "@spfunctions/agent/v1"
for await (const tick of watch.ticks({
tickers: ["KXEXAMPLE"],
cadence: "5min",
cycles: 1,
})) {
console.log(tick.ticker, tick.price, tick.delta)
}
Watch sources can also feed query():
for await (const message of query({
prompt: "React to these ticks and inspect anything surprising.",
options: {
provider,
watch: [
{ kind: "ticks", tickers: ["KXEXAMPLE"], cadence: "5min" },
],
tools: createSimpleFunctionsBuiltinTools(sf),
allowedTools: ["market.inspect", "world.read"],
maxTurns: 4,
},
})) {
console.log(message.type)
}
14. Remember The Boundaries
| Surface | Scope |
|---|
@spfunctions/sdk | Typed data and contract client |
@spfunctions/agent v0 | Governed direct runner |
@spfunctions/agent/v1 | Alpha model-loop runtime |
sf agent --tool | CLI wrapper for direct tool semantics |
/api/contracts/tools | Strict canonical SDK/Agent truth |
/api/tools | Broad hosted compatibility inventory |
| MCP | Broad client adapter, not SDK truth |
The alpha packages do not expose every CLI command, every API route, or every MCP tool. They expose the strict governed subset first.