@gabrielsmartin/orbit-sdk 0.4.4 → 0.5.1

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,12 +1,12 @@
1
1
  # @gabrielsmartin/orbit-sdk
2
2
 
3
- > Stop blasting every query at GPT-4o. Route intelligently. Save up to 98%.
3
+ > The AI operating system layer. Route intelligently. Save up to 98%.
4
4
 
5
- A small, fast, rule-based router for choosing between LLMs. Open source. No magic. ~200 lines of tuned heuristics that you can fork and customize.
5
+ Every query has a fingerprint. Complexity, creativity, urgency, domain, emotional weight. Right now you're blasting every one of them at GPT-4o. ORBIT reads the fingerprint in milliseconds and picks the right model — automatically, invisibly, without you thinking about it.
6
6
 
7
- **What it is:** ORBIT reads your query, classifies it across 8 axes, and tells you which model to use. You make the API call ORBIT just picks the model.
7
+ **What it is:** ORBIT classifies queries across 8 axes and tells you which model to use. You make the API call. ORBIT picks the model. Zero proxy. Zero black box. Fully deterministic — you can read every routing rule in `fingerprint.js`.
8
8
 
9
- **What it isn't:** a proxy, a black box, or a neural network. It's fast deterministic rules — safety-critical routes (emotional content, crisis) always win, everything else is heuristic.
9
+ **What it isn't:** a proxy, an API wrapper, or a neural network. It's fast, auditable rules — safety-critical routes (emotional content, crisis) always win, everything else is heuristic.
10
10
 
11
11
  ```bash
12
12
  npm install @gabrielsmartin/orbit-sdk
@@ -37,7 +37,7 @@ import orbit from '@gabrielsmartin/orbit-sdk'
37
37
  // Route a query — returns decision instantly, no network call
38
38
  const { model, reason, savings } = orbit.route("write a haiku about recursion")
39
39
  // model.name → "Claude Sonnet"
40
- // model.id → "claude-sonnet-3-5"
40
+ // model.id → "claude-sonnet-4-6"
41
41
  // reason → "High creativity — Claude Sonnet for open-ended generation."
42
42
  // savings.reductionPct → 50
43
43
 
@@ -141,31 +141,44 @@ const stats = orbit.stats()
141
141
 
142
142
  ## Hosted API
143
143
 
144
- Free to try, no auth required:
144
+ Sign up at [orbitai.gtll.app](https://orbitai.gtll.app) to get your API key, then:
145
145
 
146
146
  ```bash
147
147
  curl -X POST https://api.gtll.app/orbitRoute \
148
148
  -H "Content-Type: application/json" \
149
- -d '{"query": "write a haiku about recursion"}'
149
+ -H "x-neural-secret: your-api-key" \
150
+ -d '{"complexity": 7, "domain": "code", "signal": "777", "api_key": "orbit_..."}'
150
151
  ```
151
152
 
152
153
  **Pricing:**
153
154
 
154
155
  | Tier | Price | Limit |
155
156
  |------|-------|-------|
156
- | Free | $0/mo | 100 queries/day |
157
- | Pro | **$9/mo** · founding rate, locked forever | Unlimited |
158
- | Team | **$49/mo** · founding rate, locked forever | Unlimited · 5 seats |
157
+ | Free | $0/mo | 1,000 queries/month |
158
+ | Pro | $19/mo | Unlimited · all models |
159
+ | Team | $99/mo | Unlimited · 5 seats |
159
160
 
160
- → [Get Pro](https://buy.stripe.com/7sY14mdHYbTE3DT4PIbwk00) · [Get Team](https://buy.stripe.com/9B67sKfQ6bTE0rHgyqbwk01)
161
+ **[Upgrade to Pro — $19/mo](https://buy.stripe.com/6oE5kF3Yz5Co06s9AB)** · [Get Team](https://buy.stripe.com/9B67sKfQ6bTE0rHgyqbwk01)
162
+
163
+ Dashboard + usage stats at [orbitai.gtll.app](https://orbitai.gtll.app)
161
164
 
162
165
  ---
163
166
 
167
+ ## The Resonance Vision
168
+
169
+ ORBIT is the open-source core of **Resonance** — the AI operating system layer.
170
+
171
+ Every enterprise AI team is bleeding on token costs. A 50-person team running 1,000 queries/day at GPT-4o spends ~$202,500/year on tokens. With signal-aware routing, that drops to ~$57,700. Resonance captures 15% of savings — you keep the rest.
172
+
173
+ The signal layer is what makes this defensible. `777` queries generate ground-truth labels: "this type of query needs Claude." `333` labels: "this can run on Gemini Flash." At scale, that's a cross-model performance database no individual model provider can build. Only a model-agnostic layer builds this moat.
174
+
175
+ **ORBIT is the open-source foundation. The routing engine learns from every signal.**
176
+
164
177
  ## Research backing
165
178
 
166
179
  - **RouteLLM (ICLR 2025, UC Berkeley):** intelligent routing achieves 85% cost reduction at 95% quality vs always-GPT-4o
167
- - **OpenRouter** ($500M+ valuation) proves the market. ORBIT adds the classification layer.
168
- - **Martian** (Accenture-backed) proves enterprises pay for routing. ORBIT is the open version.
180
+ - **OpenRouter** ($500M+ valuation) proves the market exists. ORBIT adds the classification layer OpenRouter doesn't have.
181
+ - **Martian** (Accenture-backed) proves enterprises pay for routing intelligence. ORBIT is the open, developer-first version.
169
182
 
170
183
  ---
171
184
 
@@ -173,8 +186,10 @@ curl -X POST https://api.gtll.app/orbitRoute \
173
186
 
174
187
  - [x] v0.1.x — 8-axis classification, 6-model routing matrix
175
188
  - [x] v0.3.x — Signal-aware routing (777/555/333), hosted gateway
176
- - [ ] v0.4.0 — API key gated usage dashboard
177
- - [ ] v0.5.0 — Embedding-based fallback for ambiguous queries
189
+ - [x] v0.4.x — API key gated usage dashboard
190
+ - [x] v0.5.0 — Embedding-based fallback for ambiguous queries + Pro tier unlock
191
+ - [ ] v0.6.0 — Multi-provider streaming passthrough (OpenAI / Anthropic / Gemini)
192
+ - [ ] v0.7.0 — Team API keys + usage aggregation dashboard
178
193
  - [ ] v1.0.0 — Enterprise API + savings-share pricing
179
194
 
180
195
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gabrielsmartin/orbit-sdk",
3
- "version": "0.4.4",
3
+ "version": "0.5.1",
4
4
  "description": "Rule-based LLM router. Classifies queries across 8 axes and picks the optimal model. Fast, deterministic, zero dependencies.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -13,10 +13,12 @@
13
13
  },
14
14
  "files": [
15
15
  "src",
16
+ "scripts",
16
17
  "README.md"
17
18
  ],
18
19
  "scripts": {
19
- "test": "node test.js"
20
+ "test": "node test.js",
21
+ "postinstall": "node scripts/postinstall.cjs"
20
22
  },
21
23
  "keywords": [
22
24
  "ai",
@@ -26,6 +28,7 @@
26
28
  "anthropic",
27
29
  "gemini",
28
30
  "orbit",
31
+ "resonance",
29
32
  "cost-optimization",
30
33
  "model-routing",
31
34
  "selective-model-matching",
@@ -33,7 +36,9 @@
33
36
  "claude",
34
37
  "gemini-flash",
35
38
  "grok",
36
- "ai-infrastructure"
39
+ "ai-infrastructure",
40
+ "token-optimization",
41
+ "llm-router"
37
42
  ],
38
43
  "author": "Gabriel Martin <gabriel@gtll.app>",
39
44
  "license": "MIT",
@@ -41,7 +46,7 @@
41
46
  "type": "git",
42
47
  "url": "https://github.com/gtllco/orbit.git"
43
48
  },
44
- "homepage": "https://orbitai.gtll.app",
49
+ "homepage": "https://github.com/gtllco/orbit",
45
50
  "bugs": {
46
51
  "url": "https://github.com/gtllco/orbit/issues"
47
52
  },
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // Fires on `npm install @gabrielsmartin/orbit-sdk`
5
+ // Captures install signal → ORBIT gateway → Supabase
6
+ // Non-blocking, silently fails, no PII
7
+
8
+ const https = require('https');
9
+ const os = require('os');
10
+
11
+ const payload = JSON.stringify({
12
+ action: 'npm_install',
13
+ package: '@gabrielsmartin/orbit-sdk',
14
+ version: require('../package.json').version,
15
+ node: process.version,
16
+ platform: process.platform,
17
+ arch: process.arch,
18
+ ts: new Date().toISOString(),
19
+ });
20
+
21
+ const req = https.request({
22
+ hostname: 'api.gtll.app',
23
+ path: '/npmPing',
24
+ method: 'POST',
25
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) },
26
+ timeout: 3000,
27
+ }, () => {});
28
+
29
+ req.on('error', () => {});
30
+ req.on('timeout', () => req.destroy());
31
+ req.write(payload);
32
+ req.end();
33
+
34
+ console.log('\n\x1b[35m ⊙ ORBIT SDK installed\x1b[0m');
35
+ console.log('\x1b[2m Get your free API key + routing analytics:\x1b[0m');
36
+ console.log('\x1b[36m https://orbitai.gtll.app\x1b[0m\n');
@@ -9,7 +9,11 @@
9
9
  const COMPLEXITY_SIGNALS = [
10
10
  'architect','distributed','implement','design','optimize','analyze',
11
11
  'complex','system','algorithm','concurrent','scale','infrastructure',
12
- 'microservice','kubernetes','terraform','recursive','refactor'
12
+ 'microservice','kubernetes','terraform','recursive','refactor',
13
+ 'rate limit','concurren','async','thread','cache','shard','partition',
14
+ 'replicate','encrypt','auth','oauth','webhook','pipeline','stream',
15
+ 'batch','migration','rollback','schema','index','transaction','latency',
16
+ 'throughput','bottleneck','profil','benchmark','test','spec'
13
17
  ];
14
18
 
15
19
  const CREATIVITY_SIGNALS = [
@@ -46,11 +50,11 @@ export function fingerprint(text) {
46
50
 
47
51
  // Complexity (0-10): reasoning depth required
48
52
  const complexitySignals = COMPLEXITY_SIGNALS.filter(s => t.includes(s)).length;
49
- const questionDepth = (t.match(/\b(why|how|explain|compare|tradeoff|pros|cons|difference|analyze)\b/g) || []).length;
53
+ const questionDepth = (t.match(/\b(why|how|explain|compare|tradeoff|tradeoffs|versus|vs|pros|cons|difference|analyze|evaluate|review|audit)\b/g) || []).length;
50
54
  const complexity = Math.min(10, Math.round(
51
- complexitySignals * 2 +
55
+ complexitySignals * 2.5 +
52
56
  questionDepth * 1.5 +
53
- (wordCount > 30 ? 3 : wordCount > 15 ? 1.5 : 0)
57
+ (wordCount > 20 ? 3 : wordCount > 10 ? 1.5 : 0)
54
58
  ));
55
59
 
56
60
  // Creativity (0-10): open-ended vs deterministic
package/src/index.d.ts CHANGED
@@ -32,12 +32,15 @@ export interface SavingsInfo {
32
32
  }
33
33
 
34
34
  export interface RoutingDecision {
35
- model: ModelInfo;
35
+ model: ModelInfo | null;
36
36
  reason: string;
37
37
  rule: string;
38
- scores: QueryScores;
39
- savings: SavingsInfo;
38
+ signal: '777' | '555' | '333' | null;
39
+ signal_reason: string | null;
40
+ scores: QueryScores | null;
41
+ savings: SavingsInfo | null;
40
42
  timestamp: string;
43
+ blocked: boolean;
41
44
  }
42
45
 
43
46
  export interface OrbitConfig {
@@ -55,6 +58,7 @@ export interface RouteOptions {
55
58
  cost_tolerance?: 'low' | 'medium' | 'high';
56
59
  estimated_tokens?: number;
57
60
  blocked_models?: string[];
61
+ signal?: '777' | '555' | '333' | null;
58
62
  }
59
63
 
60
64
  export interface SessionStats {
package/src/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * @gabrielsmartin/orbit-sdk
3
3
  * Rule-based LLM router. Fast, deterministic, zero dependencies.
4
4
  * Picks the right model — you make the API call.
5
- *
5
+ *
6
6
  * https://github.com/gtllco/orbit
7
7
  * 777 · 555 · 333
8
8
  */
@@ -13,13 +13,14 @@ import { route, calculateSavings, MODEL_MATRIX } from './router.js';
13
13
  export { fingerprint, applySignalBias, route, calculateSavings, MODEL_MATRIX };
14
14
 
15
15
  const GATEWAY_URL = 'https://api.gtll.app/orbitSignup';
16
+ const ANON_QUERY_LIMIT = 10;
16
17
 
17
18
  /**
18
19
  * OrbitClient — the main class
19
- *
20
+ *
20
21
  * @example
21
22
  * import { OrbitClient } from '@gabrielsmartin/orbit-sdk'
22
- *
23
+ *
23
24
  * const orbit = new OrbitClient({ apiKey: 'your-key' })
24
25
  * const { model, reason, scores } = orbit.route("explain quantum entanglement")
25
26
  * // → { model: { name: 'Claude Sonnet', id: 'claude-sonnet-3-5', ... }, reason: '...', ... }
@@ -46,12 +47,30 @@ export class OrbitClient {
46
47
  /**
47
48
  * Route a query to the optimal model (local, <1ms).
48
49
  * ORBIT picks the model — your code makes the API call.
49
- *
50
+ *
50
51
  * @param {string} text - The query or prompt text
51
52
  * @param {Object} options - Per-query overrides: { cost_tolerance, signal, estimated_tokens, blocked_models }
52
- * @returns {{ model, reason, rule, scores, savings, timestamp }}
53
+ * @returns {{ model, reason, rule, scores, savings, timestamp, blocked }}
53
54
  */
54
55
  route(text, options = {}) {
56
+ this._stats.total_queries++;
57
+
58
+ // Hard gate: unauthenticated users blocked after ANON_QUERY_LIMIT queries
59
+ if (!this.config.apiKey && this._stats.total_queries > ANON_QUERY_LIMIT) {
60
+ this._telemetry(text, { model: null, rule: 'unauthenticated_limit', scores: null, savings: null }, 'unauthenticated_limit').catch(() => {});
61
+ return {
62
+ model: null,
63
+ reason: 'Rate limit — get a free API key at orbitai.gtll.app',
64
+ rule: 'unauthenticated_limit',
65
+ signal: null,
66
+ signal_reason: null,
67
+ scores: null,
68
+ savings: null,
69
+ timestamp: new Date().toISOString(),
70
+ blocked: true,
71
+ };
72
+ }
73
+
55
74
  let scores = fingerprint(text);
56
75
 
57
76
  if (options.cost_tolerance) {
@@ -77,52 +96,53 @@ export class OrbitClient {
77
96
  scores,
78
97
  savings,
79
98
  timestamp: new Date().toISOString(),
99
+ blocked: false,
80
100
  };
81
101
 
82
- // Stats
83
- this._stats.total_queries++;
84
102
  this._stats.total_savings += savings.savings;
85
103
  const modelName = decision.model.name;
86
104
  this._stats.model_usage[modelName] = (this._stats.model_usage[modelName] || 0) + 1;
87
105
 
88
106
  if (this.config.log) {
89
107
  console.log(`[ORBIT] → ${decision.model.name} | ${decision.rule} | saved $${savings.savings.toFixed(5)} (${savings.reductionPct}% vs GPT-4o)`);
90
-
91
- // Nudge unauthenticated users toward API key
92
- if (!this.config.apiKey && this._stats.total_queries === 3) {
93
- console.warn(`[ORBIT] Free tier: 100 API queries/day. Get your key → https://api.gtll.app/orbitSignup (POST { action: "get_key", email })`);
94
108
  }
109
+
110
+ // Nudge unauthenticated users at query 5
111
+ if (!this.config.apiKey && this._stats.total_queries === 5) {
112
+ console.warn(`\n\x1b[35m[ORBIT] You've routed 5 queries — unlock full analytics + higher limits.\x1b[0m`);
113
+ console.warn(`\x1b[36m → https://orbitai.gtll.app\x1b[0m\n`);
114
+ this._telemetry(text, result, 'unauthenticated_nudge').catch(() => {});
95
115
  }
96
116
 
97
117
  if (this.config.on_route) {
98
118
  this.config.on_route(result);
99
119
  }
100
120
 
101
- // Fire telemetry to gateway (non-blocking, best-effort)
102
- if (this.config.apiKey) {
103
- this._telemetry(text, result).catch(() => {});
104
- }
121
+ // Fire telemetry on every query (non-blocking, best-effort)
122
+ this._telemetry(text, result).catch(() => {});
105
123
 
106
124
  return result;
107
125
  }
108
126
 
109
127
  /**
110
128
  * Send a routing decision to the ORBIT gateway for usage tracking.
111
- * Only fires if apiKey is set. Non-blocking.
129
+ * Non-blocking, best-effort.
112
130
  * @private
113
131
  */
114
- async _telemetry(query, decision) {
132
+ async _telemetry(query, decision, event_type = 'sdk_route') {
115
133
  try {
116
134
  await fetch(GATEWAY_URL, {
117
135
  method: 'POST',
118
136
  headers: { 'Content-Type': 'application/json' },
119
137
  body: JSON.stringify({
120
- query,
121
- api_key: this.config.apiKey,
122
- model_selected: decision.model.name,
123
- rule: decision.rule,
124
- signal: decision.scores?.signal || null,
125
- savings_pct: decision.savings.reductionPct,
138
+ action: event_type,
139
+ api_key: this.config.apiKey || null,
140
+ model_selected: decision.model?.name || null,
141
+ rule: decision.rule || null,
142
+ signal: decision.scores?.signal_applied || null,
143
+ savings_pct: decision.savings?.reductionPct || null,
144
+ total_queries: this._stats.total_queries,
145
+ sdk_version: '0.5.0',
126
146
  }),
127
147
  });
128
148
  } catch (_) {
@@ -151,7 +171,7 @@ export class OrbitClient {
151
171
 
152
172
  /**
153
173
  * Default singleton client — zero config, ready to use
154
- *
174
+ *
155
175
  * @example
156
176
  * import orbit from '@gabrielsmartin/orbit-sdk'
157
177
  * const { model, reason } = orbit.route("write a haiku about recursion")