@turnstileai/sdk 0.1.2 → 0.1.3

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,78 @@
1
- \# @turnstileai/sdk
1
+ # @turnstileai/sdk
2
2
 
3
+ TypeScript SDK for TurnstileAI, a verification-first AI gateway.
3
4
 
5
+ TurnstileAI sits between your application and model providers, then returns
6
+ structured run records with routing, latency, usage, cost, digests, signatures,
7
+ and optional ledger checkpoints.
4
8
 
5
- Official TypeScript SDK for TurnstileAI.
6
-
7
-
8
-
9
- \## Install
10
-
11
-
9
+ ## Install
12
10
 
13
11
  ```bash
14
-
15
12
  npm install @turnstileai/sdk
16
-
17
13
  ```
18
14
 
15
+ ## Quick start
19
16
 
17
+ ```ts
18
+ import OpenAI from "openai";
19
+
20
+ const client = new OpenAI({
21
+ apiKey: process.env.TURNSTILEAI_API_KEY,
22
+ baseURL: "https://api.turnstileai.com/v1"
23
+ });
24
+
25
+ const response = await client.chat.completions.create({
26
+ model: "openrouter/llama-3.1-70b",
27
+ messages: [
28
+ { role: "user", content: "Explain Solana finality simply." }
29
+ ],
30
+ extra_body: {
31
+ checkpoint: true,
32
+ ledger: "solana",
33
+ routeMode: "trust-first"
34
+ }
35
+ });
36
+
37
+ console.log(response.choices.message.content);
38
+ console.log(response.run_record);
39
+ ```
20
40
 
21
- \## Usage
41
+ ## SDK client
22
42
 
43
+ ```ts
44
+ import { TurnstileAI } from "@turnstileai/sdk";
23
45
 
46
+ const client = new TurnstileAI({
47
+ apiKey: process.env.TURNSTILEAI_API_KEY!
48
+ });
24
49
 
25
- ```ts
50
+ const record = await client.records.get("rr_123");
51
+ const verification = await client.records.verify("rr_123");
52
+ const providers = await client.providers.list();
53
+ const usage = await client.usage.overview("month");
54
+ ```
26
55
 
27
- import { hello } from "@turnstileai/sdk";
56
+ ## CLI
28
57
 
58
+ ```bash
59
+ turnstileai auth check --key=ts_live_xxx
60
+ turnstileai record list --key=ts_live_xxx
61
+ turnstileai record verify rr_123 --key=ts_live_xxx
62
+ turnstileai providers list --key=ts_live_xxx
63
+ turnstileai usage overview --key=ts_live_xxx
64
+ ```
29
65
 
66
+ ## Route modes
30
67
 
31
- console.log(hello());
68
+ - `cost-first`
69
+ - `speed-first`
70
+ - `trust-first`
71
+ - `attested-only`
72
+ - `provider-pinned`
73
+ - `budget-guarded`
32
74
 
33
- ```
75
+ ## Ledger modes
34
76
 
77
+ - `none`
78
+ - `solana`
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,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,9 +1,12 @@
1
1
  {
2
2
  "name": "@turnstileai/sdk",
3
- "version": "0.1.2",
4
- "description": "Official TypeScript SDK for TurnstileAI",
3
+ "version": "0.1.3",
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"
@@ -15,12 +18,16 @@
15
18
  "keywords": [
16
19
  "ai",
17
20
  "sdk",
18
- "typescript",
19
21
  "llm",
22
+ "typescript",
20
23
  "turnstileai"
21
24
  ],
22
25
  "license": "MIT",
26
+ "dependencies": {
27
+ "openai": "^6.44.0"
28
+ },
23
29
  "devDependencies": {
30
+ "@types/node": "^26.0.0",
24
31
  "typescript": "^6.0.3"
25
32
  }
26
33
  }