{"_id":"@ai-stats/agent-sdk","_rev":"2-50d6ae1356011296f63eaae288db805a","name":"@ai-stats/agent-sdk","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.1":{"name":"@ai-stats/agent-sdk","version":"0.1.1","license":"MIT","_id":"@ai-stats/agent-sdk@0.1.1","maintainers":[{"name":"daniel-aistats","email":"danielbutler500@gmail.com"}],"homepage":"https://github.com/AI-Stats/AI-Stats#readme","bugs":{"url":"https://github.com/AI-Stats/AI-Stats/issues"},"dist":{"shasum":"a246314dc62f2323031d1fa653ead9437d32583e","tarball":"https://registry.npmjs.org/@ai-stats/agent-sdk/-/agent-sdk-0.1.1.tgz","fileCount":22,"integrity":"sha512-cyU/D8E49CEk/MJnXr21LQN/TkuI613bn+ztSs1ktenYmje3cPbiB+KRamJbCJx+fn0bWURB3vRK+1dRElTtUg==","signatures":[{"sig":"MEUCIHtk6gX087fb8irATG6AgfV80QA8zNV2UvaXySPso0TNAiEAi14ROYFaG29+kr5CWkhQWA3A8fKQWXXpeYmsVkGQuns=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":124722},"main":"./dist/index.js","type":"module","_from":"file:.publish-check/ai-stats-agent-sdk-0.1.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"private":false,"scripts":{"test":"pnpm exec vitest run","build":"pnpm run clean && node ../sdk-ts/node_modules/typescript/bin/tsc -p tsconfig.build.json","clean":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"","pack:dry":"pnpm publish --dry-run --no-git-checks","typecheck":"node ../sdk-ts/node_modules/typescript/bin/tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"daniel-aistats","email":"danielbutler500@gmail.com"},"_resolved":"E:\\ai-stats-public-npm-bootstrap-20260629\\.publish-check\\ai-stats-agent-sdk-0.1.1.tgz","_integrity":"sha512-cyU/D8E49CEk/MJnXr21LQN/TkuI613bn+ztSs1ktenYmje3cPbiB+KRamJbCJx+fn0bWURB3vRK+1dRElTtUg==","repository":{"url":"git+https://github.com/AI-Stats/AI-Stats.git","type":"git","directory":"packages/sdk/agent-sdk-ts"},"_npmVersion":"11.12.1","description":"TypeScript SDK for building agentic applications on top of AI Stats Gateway","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","dependencies":{"@ai-stats/sdk":"2.0.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.0.0","vitest":"^4.1.7","typescript":"^6.0.2","@types/node":"^25.6.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-sdk_0.1.1_1782729733979_0.132706470649248","host":"s3://npm-registry-packages-npm-production"},"deprecated":"AI Stats is now Phaseo. Please migrate to @phaseo/agent-sdk."}},"time":{"created":"2026-06-29T10:42:13.763Z","modified":"2026-07-04T10:44:03.435Z","0.1.1":"2026-06-29T10:42:14.123Z"},"bugs":{"url":"https://github.com/AI-Stats/AI-Stats/issues"},"license":"MIT","homepage":"https://github.com/AI-Stats/AI-Stats#readme","repository":{"url":"git+https://github.com/AI-Stats/AI-Stats.git","type":"git","directory":"packages/sdk/agent-sdk-ts"},"description":"TypeScript SDK for building agentic applications on top of AI Stats Gateway","maintainers":[{"name":"daniel-aistats","email":"danielbutler500@gmail.com"}],"readme":"# AI Stats Agent SDK\r\n\r\n`@ai-stats/agent-sdk` is a TypeScript SDK for building agentic applications on top of AI Stats Gateway.\r\n\r\nIt is not a hosted orchestration platform. The package gives you:\r\n\r\n- agent definitions\r\n- multi-step model and tool loops\r\n- gateway-backed model execution through `createGatewayAgentClient()`\r\n- local runtime tools\r\n- resumable runs from SDK-returned state\r\n- human review pauses and resumes\r\n- structured lifecycle events\r\n- bounded model retries\r\n- per-tool timeouts\r\n- optional concurrent local tool execution with deterministic tool-result ordering\r\n\r\nYou own the surrounding application, any persistence you want around it, queues, and deployment model.\r\n\r\n## State model\r\n\r\nThe SDK does not store runs in any AI Stats-hosted service.\r\n\r\n`run()` returns the full agent state needed to continue later:\r\n\r\n- the current run record\r\n- the completed step records\r\n- the full message history\r\n- the parsed output, if the run completed\r\n\r\nIf your application wants resumability across requests, workers, or process restarts, persist that returned value however your application already persists workflow state.\r\n\r\n## Install\r\n\r\n```bash\r\npnpm add @ai-stats/sdk @ai-stats/agent-sdk\r\n```\r\n\r\n## Quickstart\r\n\r\n```ts\r\nimport {\r\n  createAgent,\r\n  createGatewayAgentClient,\r\n  defineTool,\r\n} from \"@ai-stats/agent-sdk\";\r\n\r\nconst lookupDocs = defineTool({\r\n  id: \"lookup-docs\",\r\n  description: \"Look up an internal docs page by slug.\",\r\n  parameters: {\r\n    type: \"object\",\r\n    properties: {\r\n      slug: { type: \"string\" },\r\n    },\r\n    required: [\"slug\"],\r\n    additionalProperties: false,\r\n  },\r\n  async execute(input: { slug: string }) {\r\n    return {\r\n      slug: input.slug,\r\n      url: `https://docs.ai-stats.phaseo.app/v1/${input.slug}`,\r\n    };\r\n  },\r\n});\r\n\r\nconst agent = createAgent({\r\n  id: \"support-docs-agent\",\r\n  model: \"ai-stats/free\",\r\n  instructions: \"Use tools when helpful and finish with a concise answer.\",\r\n  tools: [lookupDocs],\r\n});\r\n\r\nconst result = await agent.run({\r\n  input: \"Find the docs page for presets and explain when to use them.\",\r\n  client: createGatewayAgentClient({\r\n    clientOptions: {\r\n      apiKey: process.env.AI_STATS_API_KEY!,\r\n    },\r\n  }),\r\n});\r\n\r\nconsole.log(result.output);\r\n```\r\n\r\n## Devtools\r\n\r\nAgent runs can write to the same `.ai-stats-devtools` session format used by `@ai-stats/sdk`.\r\n\r\n```ts\r\nimport { createAgentDevtools } from \"@ai-stats/agent-sdk\";\r\n\r\nconst result = await agent.run({\r\n  input: \"Summarize this ticket.\",\r\n  client,\r\n  devtools: createAgentDevtools({\r\n    directory: \".ai-stats-devtools\",\r\n  }),\r\n});\r\n```\r\n\r\nYou can also enable capture process-wide with `AI_STATS_DEVTOOLS=true` and optionally set `AI_STATS_DEVTOOLS_DIR`.\r\n\r\n## Core concepts\r\n\r\n### Agent definition\r\n\r\nUse `createAgent()` to define:\r\n\r\n- one stable `id`\r\n- instructions\r\n- one model or preset\r\n- a small tool list\r\n- optional output parsing\r\n- optional human review rules\r\n\r\nKeep the first agent narrow. One workflow, one or two tools, one clear output shape.\r\n\r\n### Gateway-backed execution\r\n\r\nUse `createGatewayAgentClient()` when model turns should run through AI Stats Gateway.\r\n\r\nThe adapter can carry gateway-native controls such as:\r\n\r\n- `responseFormat`\r\n- `plugins`\r\n- `gatewayTools`\r\n- `toolChoice`\r\n- `webSearchOptions`\r\n- `providerOptions`\r\n- `promptCacheKey`\r\n- `includeMeta`\r\n\r\nThat lets the surrounding app keep routing, search, structured outputs, and plugin defaults in one place.\r\n\r\n### Application-owned continuation\r\n\r\nIf a workflow pauses for review, or if you want to continue it later, persist the returned `AgentRunResult` in your own application and pass it back to `continueRun()`.\r\n\r\nThe SDK intentionally does not ship persistence adapters or a hosted state backend.\r\n\r\n## Human review\r\n\r\nUse `humanReview` when a run should pause for approval instead of continuing immediately.\r\n\r\n```ts\r\nconst agent = createAgent({\r\n  id: \"support-agent\",\r\n  humanReview: ({ response }) =>\r\n    response.message.content.includes(\"needs approval\")\r\n      ? {\r\n          reason: \"approval_required\",\r\n          payload: { draft: response.message.content },\r\n        }\r\n      : null,\r\n});\r\n```\r\n\r\nContinue the paused run with explicit human input:\r\n\r\n```ts\r\nconst continued = await agent.continueRun({\r\n  run: pausedResult,\r\n  client,\r\n  humanInput: \"Approved. Continue and return the final answer.\",\r\n});\r\n```\r\n\r\n## Output control\r\n\r\nUse `parseOutput` when your application wants one typed final value:\r\n\r\n```ts\r\nconst agent = createAgent<string, { summary: string }>({\r\n  id: \"summary-agent\",\r\n  parseOutput(text) {\r\n    return JSON.parse(text) as { summary: string };\r\n  },\r\n});\r\n```\r\n\r\nFor stricter model behavior, pair that with gateway structured outputs on the adapter:\r\n\r\n```ts\r\nconst client = createGatewayAgentClient({\r\n  clientOptions: { apiKey: process.env.AI_STATS_API_KEY! },\r\n  responseFormat: {\r\n    type: \"json_schema\",\r\n    name: \"agent_answer\",\r\n    schema: {\r\n      type: \"object\",\r\n      properties: {\r\n        summary: { type: \"string\" },\r\n      },\r\n      required: [\"summary\"],\r\n      additionalProperties: false,\r\n    },\r\n  },\r\n  plugins: [{ id: \"response-healing\" }],\r\n});\r\n```\r\n\r\n## Runtime controls\r\n\r\n### Tool timeouts\r\n\r\nUse `timeoutMs` when one local dependency should fail fast instead of hanging the whole run:\r\n\r\n```ts\r\nconst fetchTicket = defineTool({\r\n  id: \"fetch-ticket\",\r\n  timeoutMs: 3_000,\r\n  async execute(input: { ticketId: string }, context) {\r\n    const response = await fetch(`https://internal.example/tickets/${input.ticketId}`, {\r\n      signal: context.signal,\r\n    });\r\n    return await response.json();\r\n  },\r\n});\r\n```\r\n\r\n### Model retries\r\n\r\nUse `modelRetry` when transient model failures should retry before the run is persisted as `failed`:\r\n\r\n```ts\r\nconst agent = createAgent({\r\n  id: \"support-agent\",\r\n  modelRetry: {\r\n    maxRetries: 2,\r\n    backoffMs: 250,\r\n  },\r\n});\r\n```\r\n\r\n### Concurrent local tools\r\n\r\nIf one model turn can safely call several independent local tools, set `toolExecution.toolConcurrency`:\r\n\r\n```ts\r\nconst agent = createAgent({\r\n  id: \"research-agent\",\r\n  toolExecution: {\r\n    toolConcurrency: 3,\r\n  },\r\n  tools: [fetchDocs, fetchStatus, fetchIncidents],\r\n});\r\n```\r\n\r\nThe runtime still persists tool-result messages in tool-call order.\r\n\r\n## Observability\r\n\r\nUse `onEvent` when your application wants lifecycle hooks:\r\n\r\n- `run.started`\r\n- `run.resumed`\r\n- `step.started`\r\n- `step.completed`\r\n- `step.failed`\r\n- `step.cancelled`\r\n- `model.requested`\r\n- `model.completed`\r\n- `model.failed`\r\n- `tool.started`\r\n- `tool.completed`\r\n- `tool.failed`\r\n- `checkpoint.saved`\r\n- `run.waiting_for_human`\r\n- `run.cancelled`\r\n- `run.completed`\r\n- `run.failed`\r\n\r\nIf one step succeeds, the runtime emits `step.completed` after persisting the checkpointed step.\r\nIf model retries happen, the persisted step record exposes `modelAttempts`.\r\nIf a gateway request exposes request correlation data, the step can also persist `requestId` and `nativeResponseId`.\r\n\r\n## Gateway errors\r\n\r\nGateway failures are rethrown as `AgentGatewayError`:\r\n\r\n```ts\r\nimport { AgentGatewayError } from \"@ai-stats/agent-sdk\";\r\n\r\ntry {\r\n  await agent.run({ input, client, store });\r\n} catch (error) {\r\n  if (error instanceof AgentGatewayError) {\r\n    console.error(error.status, error.requestId, error.reason);\r\n  }\r\n  throw error;\r\n}\r\n```\r\n\r\nIf the failure came from the gateway, failed runs and steps also persist `errorDetails`.\r\n\r\n## Included examples\r\n\r\n- `examples/research-brief-agent.ts`\r\n- `examples/support-triage-agent.ts`\r\n- `examples/coding-review-agent.ts`\r\n- `examples/parallel-tool-agent.ts`\r\n\r\n## Scope\r\n\r\nThis package is intentionally an SDK, not a platform:\r\n\r\n- no hosted orchestration\r\n- no bundled remote checkpoint backend\r\n- no opinionated queue or worker runtime\r\n\r\nBuild those parts in your own application around the exported primitives.\r\n","readmeFilename":"README.md"}