eric-sdk 0.0.1 → 0.0.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,235 +1,301 @@
1
- 📘 Eric SDK (JavaScript + TypeScript)
1
+ # 📘 Eric SDK (JavaScript + TypeScript)
2
2
 
3
- Official SDK for interacting with the Eric AI Policy Engine.
4
- Eric routes user input to the correct AI flow (or a restricted subset of flows) and returns structured, domain-aware results.
3
+ **Official SDK for interacting with Eric AI a governed, deterministic routing layer for AI systems.**
5
4
 
6
- 🚀 Features
5
+ Eric evaluates incoming requests, applies routing constraints, selects the appropriate AI flow, and returns **structured, auditable outputs**.
6
+ Used in **Ingomu**, **EventInterface**, and early enterprise pilots.
7
7
 
8
- Agentic routing with eric.decide()
8
+ ---
9
9
 
10
- Manual flow calls with eric.call(flowName, data)
10
+ ## 🚀 Features
11
11
 
12
- Restricted routing with allowedFlows
12
+ * 🔁 **Governed routing** via `eric.decide()`
13
+ * 🧭 Deterministic flow selection using the **decisionRouter**
14
+ * 🎯 Restricted auto-routing with `allowedFlows`
15
+ * 🔧 Direct flow execution with `eric.call()`
16
+ * 🔒 Public vs Private API key security model
17
+ * 🧠 Domain-aware tone and behavior (events, wellness, business)
18
+ * 🛡️ Domain whitelisting + rate limiting (public keys)
19
+ * 🧱 Strong TypeScript typing
20
+ * 🧰 Production-ready SDK backed by Firebase Cloud Functions
13
21
 
14
- Flow-specific structured responses
22
+ ---
15
23
 
16
- Domain-aware behavior (wellness, events, workplace)
24
+ ## 📦 Installation
17
25
 
18
- Full TypeScript typing
26
+ ```bash
27
+ npm install eric-sdk
28
+ ```
19
29
 
20
- Production-ready — used in Ingomu, EventInterface, and enterprise pilots
30
+ ---
21
31
 
22
- 📦 Installation
23
- npm install eric-sdk
32
+ ## 🔑 API Keys (Important)
33
+
34
+ Eric supports **two types of API keys**, similar to Stripe or OpenAI.
35
+
36
+ ### 🔓 Public Key (`pub_xxx`)
37
+
38
+ Safe for browser usage (Vue, React, etc.)
39
+
40
+ * Rate-limited
41
+ * Domain-whitelisted
42
+ * Restricted to **safe flows only**
43
+
44
+ Allowed flows with a public key:
45
+
46
+ * `decisionRouter`
47
+ * `shortTextSummary`
48
+ * `announcementRewriter`
49
+
50
+ Public keys **cannot** execute admin or sensitive flows.
51
+
52
+ ---
53
+
54
+ ### 🔐 Private Key (`priv_xxx`)
55
+
56
+ Server-to-server only.
57
+
58
+ * Full access to all flows
59
+ * No domain restriction
60
+ * Higher rate limits
61
+ * Intended for trusted backend workloads
62
+
63
+ ⚠️ If a private key leaks, anyone can trigger billable flows — **the owning client is billed**.
64
+ This is the same model used by Stripe, OpenAI, Twilio, and AWS.
65
+
66
+ ---
24
67
 
25
- 🔑 Quick Start — Automatic Flow Selection
68
+ ## 🔧 Quick Start — Governed Auto-Routing
69
+
70
+ ```ts
26
71
  import { EricSDK } from "eric-sdk";
27
72
 
28
73
  const eric = new EricSDK({
29
- apiKey: process.env.ERIC_API_KEY!,
74
+ apiKey: process.env.ERIC_API_KEY!, // pub_ or priv_
30
75
  client: "eventinterface",
31
76
  });
32
77
 
33
78
  const result = await eric.decide({
34
79
  text: "I'm overwhelmed today.",
35
80
  });
81
+ ```
36
82
 
37
- Example output:
83
+ ### Example response
38
84
 
85
+ ```json
39
86
  {
40
87
  "flow": "dailyNudgeGenerator",
41
88
  "type": "structured",
42
89
  "data": {
43
90
  "nudge": "You're building momentum — take a breath and trust your progress."
91
+ },
92
+ "meta": {
93
+ "routingMode": "llm",
94
+ "reason": "Detected emotional distress language"
44
95
  }
45
96
  }
97
+ ```
46
98
 
47
- 🎯 Auto-Routing (Advanced)
48
- 🔹 Decide automatically
49
- const result = await eric.decide({
50
- text: "Can you rewrite this announcement?",
51
- });
52
-
99
+ The `meta` field explains **why** a particular flow was chosen.
53
100
 
54
- Eric chooses the correct flow (announcementRewriter, shortTextSummary, etc.)
101
+ ---
55
102
 
56
- 🔒 Restricting Auto-Routing (allowedFlows)
57
-
58
- You can force Eric to only pick from certain flows.
59
-
60
- Example: only allow announcement rewriting:
103
+ ## 🎯 Auto-Routing with Restrictions
61
104
 
105
+ ```ts
62
106
  const result = await eric.decide({
63
107
  text: this.form.body,
64
108
  allowedFlows: ["announcementRewriter"],
65
109
  userState: {
66
110
  tone: "energetic",
67
- length: 150
68
- }
111
+ length: 150,
112
+ },
69
113
  });
114
+ ```
70
115
 
116
+ ### Guarantees
71
117
 
72
- This guarantees:
118
+ * Eric **must** choose `announcementRewriter`
119
+ * No unrelated flows can be selected
120
+ * Predictable, safe behavior for admin tools
73
121
 
74
- Eric does not pick shortTextSummary
122
+ ---
75
123
 
76
- Eric must choose announcementRewriter
124
+ ## 🔧 Manual Flow Execution (Private Key Only)
77
125
 
78
- If allowedFlows has only one item, it will always choose that one
126
+ ```ts
127
+ const result = await eric.call("speakerPerformanceAnalyzer", {
128
+ speakerName: "Jane Doe",
129
+ feedbackComments: ["Loved the energy!", "Slides were unclear"],
130
+ });
131
+ ```
79
132
 
80
- Example output:
133
+ Use `eric.call()` when:
81
134
 
82
- {
83
- "flow": "announcementRewriter",
84
- "type": "structured",
85
- "data": {
86
- "rewritten": "Heads up! The pool party is now at the yacht club...",
87
- "toneUsed": "energetic"
88
- }
89
- }
135
+ * You already know the exact flow
136
+ * Running batch jobs or scheduled tasks
137
+ * Executing admin or restricted operations
138
+ * Using private server keys
90
139
 
91
- 🔧 Manual Flow Execution
140
+ ---
92
141
 
93
- Use .call() to skip routing and directly invoke any flow:
142
+ ## 🧠 When to Use `decide()` vs `call()`
94
143
 
95
- const result = await eric.call("announcementRewriter", {
96
- announcement: "We moved the meeting.",
97
- tone: "friendly",
98
- length: 200
99
- });
144
+ | Method | Use Case |
145
+ | ------------------------------- | ---------------------------------------------- |
146
+ | `eric.decide()` | Let Eric select the correct flow automatically |
147
+ | `eric.decide({ allowedFlows })` | Auto-routing restricted to a safe list |
148
+ | `eric.call()` | Direct execution when flow is already known |
100
149
 
150
+ ---
101
151
 
102
- Useful for admin panels, batch processing, and scheduled tasks.
152
+ ## 🧱 Full SDK API
103
153
 
104
- 🧠 When to Use What
105
- Method Use When
106
- eric.decide() You want Eric to choose the correct flow automatically
107
- eric.decide({ allowedFlows: [...] }) You want Eric to choose, but only within a safe controlled list
108
- eric.call() You already know which flow to use (like admin tools, backend tasks)
109
- 🧱 Full SDK API
110
- eric.decide(options)
111
- eric.decide({
154
+ ### `eric.decide(options)`
155
+
156
+ ```ts
157
+ {
112
158
  text?: string;
113
159
  userState?: Record<string, any>;
114
160
  topic?: string;
115
161
  allowedFlows?: string[];
116
- });
117
-
162
+ }
163
+ ```
118
164
 
119
165
  Returns:
120
166
 
167
+ ```ts
121
168
  {
122
169
  flow: string;
123
170
  type: "structured" | "text";
124
171
  data: any;
172
+ meta?: {
173
+ routingMode: "direct" | "requestType" | "signature" | "llm" | "forced";
174
+ reason: string;
175
+ };
125
176
  }
177
+ ```
126
178
 
127
- eric.call(flowName, data)
128
- const out = await eric.call("shortTextSummary", {
129
- text: "Make this clearer."
130
- });
131
-
132
-
133
- Equivalent to:
134
-
135
- eric.runFlow({ flow: "shortTextSummary", data: {...} })
136
-
137
- 💬 Examples
138
- Example 1 — Clean up an announcement (EventInterface admin)
139
- const result = await eric.decide({
140
- text: this.form.body,
141
- allowedFlows: ["announcementRewriter"],
142
- userState: {
143
- tone: "energetic",
144
- length: 150,
145
- }
146
- });
179
+ ---
147
180
 
148
- this.aiSummary = result.data.rewritten;
181
+ ### `eric.call(flow, data)`
149
182
 
150
- Example 2 Generate a summary (default)
151
- const result = await eric.decide({
152
- text: "Here is a long announcement, please make it shorter."
153
- });
183
+ Direct execution of a known flow.
154
184
 
185
+ ---
155
186
 
156
- May produce:
187
+ ## 🧩 Supported Flows
157
188
 
158
- shortTextSummary
189
+ ### Common
159
190
 
160
- announcementRewriter
161
- (depends on the text)
191
+ * `decisionRouter`
192
+ * `shortTextSummary`
193
+ * `questionAnswerHelper`
194
+ * `dailyNudgeGenerator`
162
195
 
163
- Example 3 — Force a specific flow
164
- await eric.call("speakerPerformanceAnalyzer", {
165
- speakerName: "Jane Doe",
166
- feedbackComments: ["Loved the energy!", "Slides were unclear"]
167
- });
196
+ ### Wellness
168
197
 
169
- 🧩 Supported Flows
170
- Common
198
+ * `aiCoachFeedback`
199
+ * `personalizedSessionRecommender`
200
+ * `wellnessProgressReporter`
201
+ * `trendInsightReporter`
171
202
 
172
- shortTextSummary
203
+ ### Events
173
204
 
174
- questionAnswerHelper
205
+ * `eventSummaryDigest`
206
+ * `speakerPerformanceAnalyzer`
207
+ * `networkingMatchmaker`
208
+ * `attendeeEngagementReporter`
209
+ * `eventPulseReport`
210
+ * `sessionRecapGenerator`
211
+ * `sponsorValueSummary`
212
+ * `announcementRewriter`
175
213
 
176
- dailyNudgeGenerator
214
+ ### Business
177
215
 
178
- Wellness
216
+ * `leadershipInsight`
217
+ * `feedbackInsightAnalyzer`
218
+ * `performanceReviewAssistant`
219
+ * `teamDynamicsAnalyzer`
220
+ * `productivityCoach`
179
221
 
180
- aiCoachFeedback
222
+ ---
181
223
 
182
- personalizedSessionRecommender
224
+ ## 🌐 Public Key Security Model
183
225
 
184
- wellnessProgressReporter
226
+ Eric’s backend enforces:
185
227
 
186
- trendInsightReporter
228
+ ### ✔ Allowed Flows
187
229
 
188
- Events
230
+ Public keys may only call:
189
231
 
190
- eventSummaryDigest
232
+ * `decisionRouter`
233
+ * `shortTextSummary`
234
+ * `announcementRewriter`
191
235
 
192
- speakerPerformanceAnalyzer
236
+ ---
193
237
 
194
- networkingMatchmaker
238
+ ### ✔ Domain Whitelisting
195
239
 
196
- attendeeEngagementReporter
240
+ Only approved origins can access public keys:
197
241
 
198
- eventPulseReport
242
+ ```json
243
+ [
244
+ "http://localhost:5173",
245
+ "https://eventinterface.com",
246
+ "https://www.eventinterface.com",
247
+ "https://ingomu.com",
248
+ "https://www.ingomu.com"
249
+ ]
250
+ ```
199
251
 
200
- sessionRecapGenerator
252
+ ---
201
253
 
202
- sponsorValueSummary
254
+ ### ✔ Rate Limiting
203
255
 
204
- announcementRewriter
256
+ * Default: **60 requests per minute per IP**
257
+ * Applies only to public keys
258
+ * Enforced automatically by the backend
205
259
 
206
- Business / Workplace
260
+ ---
207
261
 
208
- leadershipInsight
262
+ ## 🛡️ Private Key Rules
209
263
 
210
- feedbackInsightAnalyzer
264
+ Private keys:
211
265
 
212
- performanceReviewAssistant
266
+ * Must be used server-side only
267
+ * Are not domain-restricted
268
+ * Can execute all flows
269
+ * Should be stored in environment variables
270
+ * Are billed per usage
213
271
 
214
- teamDynamicsAnalyzer
272
+ ---
215
273
 
216
- productivityCoach
274
+ ## ⚙️ Configuration
217
275
 
218
- 🌐 Configuration
276
+ ```ts
219
277
  new EricSDK({
220
- apiKey: "YOUR_API_KEY",
221
- client: "your-client-id",
222
- baseUrl: "https://us-central1-eric-ai-prod.cloudfunctions.net/runFlow"
278
+ apiKey: "pub_xxx" | "priv_xxx",
279
+ client: "eventinterface",
280
+ baseUrl: "https://us-central1-eric-ai-prod.cloudfunctions.net/runFlow",
223
281
  });
282
+ ```
224
283
 
225
- 🔧 Local Development
226
- npm link
284
+ > **Note:**
285
+ > Domain context (events, wellness, business) is derived server-side from the client identity and is not required in the SDK configuration.
227
286
 
287
+ ---
228
288
 
229
- In your other project:
289
+ ## 🧪 Local Development
230
290
 
291
+ ```bash
292
+ npm link
293
+ # then in consuming project:
231
294
  npm link eric-sdk
295
+ ```
296
+
297
+ ---
232
298
 
233
- 📄 License
299
+ ## 📄 License
234
300
 
235
- MIT © 2025
301
+ MIT © 2025
package/dist/index.cjs CHANGED
@@ -60,7 +60,6 @@ var EricSDK = class {
60
60
  constructor(options) {
61
61
  this.apiKey = options.apiKey;
62
62
  this.client = options.client;
63
- this.appId = options.appId;
64
63
  this.baseUrl = options.baseUrl ?? "https://us-central1-eric-ai-prod.cloudfunctions.net/runFlow";
65
64
  }
66
65
  /* -------------------------------------------------------------
@@ -71,8 +70,7 @@ var EricSDK = class {
71
70
  flow: flowName,
72
71
  data: {
73
72
  ...data,
74
- client: this.client,
75
- appId: this.appId
73
+ client: this.client
76
74
  }
77
75
  };
78
76
  const res = await import_axios.default.post(this.baseUrl, payload, {
@@ -90,11 +88,10 @@ var EricSDK = class {
90
88
  async decide(data) {
91
89
  const { allowedFlows, ...rest } = data;
92
90
  const payload = {
93
- flow: "policyDecisionMaker",
91
+ flow: "decisionRouter",
94
92
  data: {
95
93
  ...rest,
96
- client: this.client,
97
- appId: this.appId
94
+ client: this.client
98
95
  }
99
96
  };
100
97
  if (allowedFlows) {
package/dist/index.d.cts CHANGED
@@ -1,7 +1,6 @@
1
1
  interface EricClientOptions {
2
2
  apiKey: string;
3
3
  client: string;
4
- appId: "wellness" | "events" | "business";
5
4
  baseUrl?: string;
6
5
  }
7
6
  interface EricResponse {
@@ -12,7 +11,6 @@ interface EricResponse {
12
11
  declare class EricSDK {
13
12
  private apiKey;
14
13
  private client;
15
- private appId;
16
14
  private baseUrl;
17
15
  constructor(options: EricClientOptions);
18
16
  call(flowName: string, data: any): Promise<EricResponse>;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  interface EricClientOptions {
2
2
  apiKey: string;
3
3
  client: string;
4
- appId: "wellness" | "events" | "business";
5
4
  baseUrl?: string;
6
5
  }
7
6
  interface EricResponse {
@@ -12,7 +11,6 @@ interface EricResponse {
12
11
  declare class EricSDK {
13
12
  private apiKey;
14
13
  private client;
15
- private appId;
16
14
  private baseUrl;
17
15
  constructor(options: EricClientOptions);
18
16
  call(flowName: string, data: any): Promise<EricResponse>;
package/dist/index.js CHANGED
@@ -4,7 +4,6 @@ var EricSDK = class {
4
4
  constructor(options) {
5
5
  this.apiKey = options.apiKey;
6
6
  this.client = options.client;
7
- this.appId = options.appId;
8
7
  this.baseUrl = options.baseUrl ?? "https://us-central1-eric-ai-prod.cloudfunctions.net/runFlow";
9
8
  }
10
9
  /* -------------------------------------------------------------
@@ -15,8 +14,7 @@ var EricSDK = class {
15
14
  flow: flowName,
16
15
  data: {
17
16
  ...data,
18
- client: this.client,
19
- appId: this.appId
17
+ client: this.client
20
18
  }
21
19
  };
22
20
  const res = await axios.post(this.baseUrl, payload, {
@@ -34,11 +32,10 @@ var EricSDK = class {
34
32
  async decide(data) {
35
33
  const { allowedFlows, ...rest } = data;
36
34
  const payload = {
37
- flow: "policyDecisionMaker",
35
+ flow: "decisionRouter",
38
36
  data: {
39
37
  ...rest,
40
- client: this.client,
41
- appId: this.appId
38
+ client: this.client
42
39
  }
43
40
  };
44
41
  if (allowedFlows) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eric-sdk",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Official SDK for interacting with the Eric AI Policy Engine",
5
5
  "author": "Rod Bridges",
6
6
  "license": "MIT",
package/src/client.ts CHANGED
@@ -3,7 +3,6 @@ import axios from "axios";
3
3
  export interface EricClientOptions {
4
4
  apiKey: string;
5
5
  client: string; // ingomu, eventinterface, etc.
6
- appId: "wellness" | "events" | "business"; // REQUIRED for policy engine
7
6
  baseUrl?: string;
8
7
  }
9
8
 
@@ -16,13 +15,11 @@ export interface EricResponse {
16
15
  export class EricSDK {
17
16
  private apiKey: string;
18
17
  private client: string;
19
- private appId: string;
20
18
  private baseUrl: string;
21
19
 
22
20
  constructor(options: EricClientOptions) {
23
21
  this.apiKey = options.apiKey;
24
22
  this.client = options.client;
25
- this.appId = options.appId; // <-- FIXED: needed for policy input
26
23
  this.baseUrl =
27
24
  options.baseUrl ??
28
25
  "https://us-central1-eric-ai-prod.cloudfunctions.net/runFlow";
@@ -37,7 +34,6 @@ export class EricSDK {
37
34
  data: {
38
35
  ...data,
39
36
  client: this.client,
40
- appId: this.appId
41
37
  }
42
38
  };
43
39
 
@@ -64,11 +60,10 @@ export class EricSDK {
64
60
  const { allowedFlows, ...rest } = data;
65
61
 
66
62
  const payload: any = {
67
- flow: "policyDecisionMaker",
63
+ flow: "decisionRouter",
68
64
  data: {
69
65
  ...rest,
70
66
  client: this.client,
71
- appId: this.appId
72
67
  }
73
68
  };
74
69