@turnstileai/sdk 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,34 +1,99 @@
1
- \# @turnstileai/sdk
1
+ # @turnstileai/sdk
2
2
 
3
+ TypeScript SDK for TurnstileAI.
3
4
 
5
+ TurnstileAI is a verification-focused AI gateway SDK for working with routed model requests, run records, provider health, and usage analytics.
4
6
 
5
- Official TypeScript SDK for TurnstileAI.
7
+ ## Install
6
8
 
9
+ ```bash
10
+ npm install @turnstileai/sdk
11
+ ```
7
12
 
13
+ ## Quick start
8
14
 
9
- \## Install
15
+ ```ts
16
+ import { TurnstileAI } from "@turnstileai/sdk";
10
17
 
18
+ const client = new TurnstileAI({
19
+ apiKey: process.env.TURNSTILEAI_API_KEY!
20
+ });
21
+ ```
11
22
 
23
+ ## Fetch a run record
12
24
 
13
- ```bash
25
+ ```ts
26
+ const record = await client.records.get("rr_123");
27
+ console.log(record);
28
+ ```
14
29
 
15
- npm install @turnstileai/sdk
30
+ ## Verify a run record
31
+
32
+ ```ts
33
+ const verification = await client.records.verify("rr_123");
34
+ console.log(verification.status);
35
+ ```
36
+
37
+ ## List providers
38
+
39
+ ```ts
40
+ const providers = await client.providers.list();
41
+ console.log(providers);
42
+ ```
16
43
 
44
+ ## Usage overview
45
+
46
+ ```ts
47
+ const usage = await client.usage.overview("month");
48
+ console.log(usage);
17
49
  ```
18
50
 
51
+ ## CLI
19
52
 
53
+ After installing globally or linking locally, you can use:
20
54
 
21
- \## Usage
55
+ ```bash
56
+ turnstileai auth check --key=ts_live_xxx
57
+ turnstileai record get rr_123 --key=ts_live_xxx
58
+ turnstileai record list --key=ts_live_xxx
59
+ turnstileai record verify rr_123 --key=ts_live_xxx
60
+ turnstileai providers list --key=ts_live_xxx
61
+ turnstileai usage overview --key=ts_live_xxx
62
+ ```
22
63
 
64
+ ## Route modes
23
65
 
66
+ - `cost-first`
67
+ - `speed-first`
68
+ - `trust-first`
69
+ - `attested-only`
70
+ - `provider-pinned`
71
+ - `budget-guarded`
24
72
 
25
- ```ts
73
+ ## Ledger modes
26
74
 
27
- import { hello } from "@turnstileai/sdk";
75
+ - `none`
76
+ - `solana`
28
77
 
78
+ ## Development
29
79
 
80
+ Build the package:
30
81
 
31
- console.log(hello());
82
+ ```bash
83
+ npm run build
84
+ ```
32
85
 
86
+ Run tests:
87
+
88
+ ```bash
89
+ npm test
33
90
  ```
34
91
 
92
+ ## Publish updates
93
+
94
+ When you change the SDK or README, publish a new version:
95
+
96
+ ```bash
97
+ npm version patch
98
+ npm publish --access public
99
+ ```
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const client_1 = require("./client");
5
+ const errors_1 = require("./errors");
6
+ const args = process.argv.slice(2);
7
+ const command = args[0];
8
+ const subcommand = args[1];
9
+ function readKey() {
10
+ const inline = args.find((arg) => arg.startsWith("--key="));
11
+ if (inline)
12
+ return inline.replace("--key=", "");
13
+ if (process.env.TURNSTILEAI_API_KEY)
14
+ return process.env.TURNSTILEAI_API_KEY;
15
+ console.error("Missing API key. Use --key=ts_... or set TURNSTILEAI_API_KEY");
16
+ process.exit(1);
17
+ }
18
+ function help() {
19
+ console.log(`
20
+ turnstileai <command>
21
+
22
+ Commands:
23
+ auth check
24
+ record get <id>
25
+ record list
26
+ record verify <id>
27
+ providers list
28
+ usage overview
29
+
30
+ Examples:
31
+ turnstileai auth check --key=ts_live_xxx
32
+ turnstileai record verify rr_123 --key=ts_live_xxx
33
+ turnstileai usage overview
34
+ `);
35
+ }
36
+ async function main() {
37
+ if (!command || command === "--help" || command === "-h") {
38
+ help();
39
+ return;
40
+ }
41
+ const apiKey = readKey();
42
+ const client = new client_1.TurnstileAI({ apiKey });
43
+ try {
44
+ if (command === "auth" && subcommand === "check") {
45
+ console.log("Authentication ok");
46
+ return;
47
+ }
48
+ if (command === "record" && subcommand === "get") {
49
+ const id = args[2];
50
+ if (!id) {
51
+ console.error("Usage: turnstileai record get <id>");
52
+ process.exit(1);
53
+ }
54
+ const record = await client.records.get(id);
55
+ console.log(JSON.stringify(record, null, 2));
56
+ return;
57
+ }
58
+ if (command === "record" && subcommand === "list") {
59
+ const records = await client.records.list({ limit: 10 });
60
+ for (const item of records) {
61
+ console.log(`${item.id} ${item.model} ${item.provider} ${item.totalTokens} tokens $${item.costUsd.toFixed(5)}`);
62
+ }
63
+ return;
64
+ }
65
+ if (command === "record" && subcommand === "verify") {
66
+ const id = args[2];
67
+ if (!id) {
68
+ console.error("Usage: turnstileai record verify <id>");
69
+ process.exit(1);
70
+ }
71
+ const result = await client.records.verify(id);
72
+ console.log(`signature: ${result.signatureOk}`);
73
+ console.log(`digest: ${result.digestOk}`);
74
+ console.log(`ledger: ${result.ledgerOk}`);
75
+ console.log(`status: ${result.status}`);
76
+ console.log(result.message);
77
+ return;
78
+ }
79
+ if (command === "providers" && subcommand === "list") {
80
+ const providers = await client.providers.list();
81
+ for (const p of providers) {
82
+ console.log(`${p.label} ${p.trustTier} ${p.uptimePercent}% uptime ${p.avgLatencyMs}ms`);
83
+ }
84
+ return;
85
+ }
86
+ if (command === "usage" && subcommand === "overview") {
87
+ const usage = await client.usage.overview("month");
88
+ console.log(JSON.stringify(usage, null, 2));
89
+ return;
90
+ }
91
+ help();
92
+ }
93
+ catch (err) {
94
+ if (err instanceof errors_1.TurnstileAuthError) {
95
+ console.error(`Auth error: ${err.message}`);
96
+ process.exit(1);
97
+ }
98
+ if (err instanceof errors_1.TurnstileRequestError) {
99
+ console.error(`Request error ${err.statusCode}: ${err.message}`);
100
+ process.exit(1);
101
+ }
102
+ console.error(String(err));
103
+ process.exit(1);
104
+ }
105
+ }
106
+ main();
@@ -0,0 +1,30 @@
1
+ import OpenAI from "openai";
2
+ import type { TurnstileConfig, RunRecord, VerificationResult, ProviderHealth, UsageOverview } from "./types";
3
+ export declare class TurnstileAI {
4
+ private readonly apiKey;
5
+ private readonly baseURL;
6
+ private readonly timeout;
7
+ private readonly http;
8
+ readonly chat: OpenAI["chat"];
9
+ readonly completions: OpenAI["completions"];
10
+ readonly models: OpenAI["models"];
11
+ constructor(config: TurnstileConfig);
12
+ records: {
13
+ get: (recordId: string) => Promise<RunRecord>;
14
+ list: (params?: {
15
+ limit?: number;
16
+ offset?: number;
17
+ model?: string;
18
+ provider?: string;
19
+ }) => Promise<RunRecord[]>;
20
+ verify: (recordId: string) => Promise<VerificationResult>;
21
+ };
22
+ providers: {
23
+ list: () => Promise<ProviderHealth[]>;
24
+ get: (providerId: string) => Promise<ProviderHealth>;
25
+ };
26
+ usage: {
27
+ overview: (period?: "day" | "week" | "month") => Promise<UsageOverview>;
28
+ };
29
+ private request;
30
+ }
package/dist/client.js ADDED
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TurnstileAI = void 0;
7
+ const openai_1 = __importDefault(require("openai"));
8
+ const errors_1 = require("./errors");
9
+ const DEFAULT_BASE_URL = "https://api.turnstileai.com/v1";
10
+ class TurnstileAI {
11
+ constructor(config) {
12
+ this.records = {
13
+ get: async (recordId) => {
14
+ return this.request(`/records/${recordId}`);
15
+ },
16
+ list: async (params) => {
17
+ const qs = new URLSearchParams();
18
+ if (params?.limit)
19
+ qs.set("limit", String(params.limit));
20
+ if (params?.offset)
21
+ qs.set("offset", String(params.offset));
22
+ if (params?.model)
23
+ qs.set("model", params.model);
24
+ if (params?.provider)
25
+ qs.set("provider", params.provider);
26
+ const suffix = qs.toString() ? `?${qs.toString()}` : "";
27
+ return this.request(`/records${suffix}`);
28
+ },
29
+ verify: async (recordId) => {
30
+ return this.request(`/records/${recordId}/verify`);
31
+ },
32
+ };
33
+ this.providers = {
34
+ list: async () => {
35
+ return this.request("/providers");
36
+ },
37
+ get: async (providerId) => {
38
+ return this.request(`/providers/${providerId}`);
39
+ },
40
+ };
41
+ this.usage = {
42
+ overview: async (period = "month") => {
43
+ return this.request(`/usage/overview?period=${period}`);
44
+ },
45
+ };
46
+ if (!config.apiKey) {
47
+ throw new errors_1.TurnstileAuthError("Missing TurnstileAI API key.");
48
+ }
49
+ this.apiKey = config.apiKey;
50
+ this.baseURL = config.baseURL ?? DEFAULT_BASE_URL;
51
+ this.timeout = config.timeout ?? 60000;
52
+ this.http = new openai_1.default({
53
+ apiKey: this.apiKey,
54
+ baseURL: this.baseURL,
55
+ timeout: this.timeout,
56
+ defaultHeaders: {
57
+ "X-TurnstileAI-SDK": "@turnstileai/sdk",
58
+ },
59
+ });
60
+ this.chat = this.http.chat;
61
+ this.completions = this.http.completions;
62
+ this.models = this.http.models;
63
+ }
64
+ async request(path, init) {
65
+ const res = await fetch(`${this.baseURL}${path}`, {
66
+ ...init,
67
+ headers: {
68
+ Authorization: `Bearer ${this.apiKey}`,
69
+ "Content-Type": "application/json",
70
+ "X-TurnstileAI-SDK": "@turnstileai/sdk",
71
+ ...(init?.headers ?? {}),
72
+ },
73
+ });
74
+ if (res.status === 401) {
75
+ throw new errors_1.TurnstileAuthError("Invalid or expired TurnstileAI API key.");
76
+ }
77
+ if (!res.ok) {
78
+ let body = {};
79
+ try {
80
+ body = await res.json();
81
+ }
82
+ catch { }
83
+ throw new errors_1.TurnstileRequestError(body?.message ?? `Request failed with status ${res.status}`, res.status, body?.code);
84
+ }
85
+ return res.json();
86
+ }
87
+ }
88
+ exports.TurnstileAI = TurnstileAI;
@@ -0,0 +1,15 @@
1
+ export declare class TurnstileError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare class TurnstileAuthError extends TurnstileError {
5
+ constructor(message: string);
6
+ }
7
+ export declare class TurnstileRequestError extends TurnstileError {
8
+ statusCode: number;
9
+ code?: string;
10
+ constructor(message: string, statusCode: number, code?: string);
11
+ }
12
+ export declare class TurnstileVerificationError extends TurnstileError {
13
+ recordId: string;
14
+ constructor(message: string, recordId: string);
15
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TurnstileVerificationError = exports.TurnstileRequestError = exports.TurnstileAuthError = exports.TurnstileError = void 0;
4
+ class TurnstileError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "TurnstileError";
8
+ }
9
+ }
10
+ exports.TurnstileError = TurnstileError;
11
+ class TurnstileAuthError extends TurnstileError {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = "TurnstileAuthError";
15
+ }
16
+ }
17
+ exports.TurnstileAuthError = TurnstileAuthError;
18
+ class TurnstileRequestError extends TurnstileError {
19
+ constructor(message, statusCode, code) {
20
+ super(message);
21
+ this.name = "TurnstileRequestError";
22
+ this.statusCode = statusCode;
23
+ this.code = code;
24
+ }
25
+ }
26
+ exports.TurnstileRequestError = TurnstileRequestError;
27
+ class TurnstileVerificationError extends TurnstileError {
28
+ constructor(message, recordId) {
29
+ super(message);
30
+ this.name = "TurnstileVerificationError";
31
+ this.recordId = recordId;
32
+ }
33
+ }
34
+ exports.TurnstileVerificationError = TurnstileVerificationError;
package/dist/index.d.ts CHANGED
@@ -1 +1,3 @@
1
- export declare const hello: () => string;
1
+ export { TurnstileAI } from "./client";
2
+ export { TurnstileError, TurnstileAuthError, TurnstileRequestError, TurnstileVerificationError, } from "./errors";
3
+ export type { TurnstileConfig, InferenceOptions, RunRecord, LedgerCheckpoint, VerificationResult, ProviderHealth, UsageOverview, RouteMode, LedgerMode, TurnstileApiErrorBody, } from "./types";
package/dist/index.js CHANGED
@@ -1,5 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hello = void 0;
4
- const hello = () => "hello from TurnstileAI";
5
- exports.hello = hello;
3
+ exports.TurnstileVerificationError = exports.TurnstileRequestError = exports.TurnstileAuthError = exports.TurnstileError = exports.TurnstileAI = void 0;
4
+ var client_1 = require("./client");
5
+ Object.defineProperty(exports, "TurnstileAI", { enumerable: true, get: function () { return client_1.TurnstileAI; } });
6
+ var errors_1 = require("./errors");
7
+ Object.defineProperty(exports, "TurnstileError", { enumerable: true, get: function () { return errors_1.TurnstileError; } });
8
+ Object.defineProperty(exports, "TurnstileAuthError", { enumerable: true, get: function () { return errors_1.TurnstileAuthError; } });
9
+ Object.defineProperty(exports, "TurnstileRequestError", { enumerable: true, get: function () { return errors_1.TurnstileRequestError; } });
10
+ Object.defineProperty(exports, "TurnstileVerificationError", { enumerable: true, get: function () { return errors_1.TurnstileVerificationError; } });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_test_1 = __importDefault(require("node:test"));
7
+ const strict_1 = __importDefault(require("node:assert/strict"));
8
+ const client_1 = require("../client");
9
+ (0, node_test_1.default)("TurnstileAI throws when apiKey is missing", () => {
10
+ strict_1.default.throws(() => {
11
+ new client_1.TurnstileAI({ apiKey: "" });
12
+ }, /Missing TurnstileAI API key/);
13
+ });
14
+ (0, node_test_1.default)("TurnstileAI creates a client with valid apiKey", () => {
15
+ const client = new client_1.TurnstileAI({ apiKey: "ts_test_123" });
16
+ strict_1.default.ok(client);
17
+ strict_1.default.ok(client.records);
18
+ strict_1.default.ok(client.providers);
19
+ strict_1.default.ok(client.usage);
20
+ });
@@ -0,0 +1,75 @@
1
+ export type RouteMode = "cost-first" | "speed-first" | "trust-first" | "attested-only" | "provider-pinned" | "budget-guarded";
2
+ export type LedgerMode = "none" | "solana";
3
+ export interface TurnstileConfig {
4
+ apiKey: string;
5
+ baseURL?: string;
6
+ timeout?: number;
7
+ defaultRouteMode?: RouteMode;
8
+ defaultLedgerMode?: LedgerMode;
9
+ }
10
+ export interface InferenceOptions {
11
+ checkpoint?: boolean;
12
+ ledger?: LedgerMode;
13
+ routeMode?: RouteMode;
14
+ provider?: string;
15
+ maxSpendUsd?: number;
16
+ tags?: string[];
17
+ }
18
+ export interface LedgerCheckpoint {
19
+ chain: "solana";
20
+ txId: string;
21
+ slot: number;
22
+ explorerUrl: string;
23
+ confirmedAt: string | null;
24
+ }
25
+ export interface RunRecord {
26
+ id: string;
27
+ createdAt: string;
28
+ model: string;
29
+ provider: string;
30
+ inputTokens: number;
31
+ outputTokens: number;
32
+ totalTokens: number;
33
+ latencyMs: number;
34
+ costUsd: number;
35
+ requestDigest: string;
36
+ responseDigest: string;
37
+ signature: string;
38
+ routeMode: RouteMode;
39
+ verified: boolean;
40
+ ledgerCheckpoint: LedgerCheckpoint | null;
41
+ metadata?: Record<string, unknown>;
42
+ }
43
+ export interface VerificationResult {
44
+ recordId: string;
45
+ signatureOk: boolean;
46
+ digestOk: boolean;
47
+ ledgerOk: boolean | null;
48
+ status: "verified" | "pending" | "failed";
49
+ message: string;
50
+ }
51
+ export interface ProviderHealth {
52
+ id: string;
53
+ label: string;
54
+ uptimePercent: number;
55
+ avgLatencyMs: number;
56
+ errorRatePercent: number;
57
+ attested: boolean;
58
+ trustTier: "A+" | "A" | "B+" | "B" | "C";
59
+ lastUpdatedAt: string;
60
+ }
61
+ export interface UsageOverview {
62
+ period: "day" | "week" | "month";
63
+ requests: number;
64
+ verifiedRuns: number;
65
+ totalTokens: number;
66
+ totalCostUsd: number;
67
+ averageLatencyMs: number;
68
+ from: string;
69
+ to: string;
70
+ }
71
+ export interface TurnstileApiErrorBody {
72
+ code?: string;
73
+ message?: string;
74
+ details?: unknown;
75
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,26 +1,34 @@
1
1
  {
2
2
  "name": "@turnstileai/sdk",
3
- "version": "0.1.2",
4
- "description": "Official TypeScript SDK for TurnstileAI",
3
+ "version": "0.1.4",
4
+ "description": "Original TypeScript SDK for TurnstileAI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "turnstileai": "dist/cli.js"
9
+ },
7
10
  "files": [
8
11
  "dist",
9
12
  "README.md"
10
13
  ],
11
14
  "scripts": {
12
15
  "build": "tsc",
16
+ "test": "npm run build && node --test dist/test/**/*.test.js",
13
17
  "prepublishOnly": "npm run build"
14
18
  },
15
19
  "keywords": [
16
20
  "ai",
17
21
  "sdk",
18
- "typescript",
19
22
  "llm",
23
+ "typescript",
20
24
  "turnstileai"
21
25
  ],
22
26
  "license": "MIT",
27
+ "dependencies": {
28
+ "openai": "^4.0.0"
29
+ },
23
30
  "devDependencies": {
24
- "typescript": "^6.0.3"
31
+ "@types/node": "^24.0.0",
32
+ "typescript": "^5.0.0"
25
33
  }
26
34
  }