@simplr-ai/ai 1.0.0

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/dist/openai.js ADDED
@@ -0,0 +1,290 @@
1
+ // src/errors.ts
2
+ var SimplrError = class extends Error {
3
+ status;
4
+ body;
5
+ constructor(message, status, body) {
6
+ super(message);
7
+ this.name = "SimplrError";
8
+ this.status = status;
9
+ this.body = body;
10
+ }
11
+ };
12
+
13
+ // src/client.ts
14
+ var DEFAULT_BASE_URL = "https://api.simplr.sh";
15
+ var DEFAULT_TIMEOUT_MS = 15e3;
16
+ function resolve(config) {
17
+ if (!config?.apiKey) throw new Error("@simplr-ai/ai: `apiKey` is required");
18
+ const fetchImpl = config.fetch ?? globalThis.fetch;
19
+ if (typeof fetchImpl !== "function") {
20
+ throw new Error(
21
+ "@simplr-ai/ai: no global fetch available \u2014 use Node 18+ or pass `fetch` in config"
22
+ );
23
+ }
24
+ return {
25
+ apiKey: config.apiKey,
26
+ baseUrl: (config.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, ""),
27
+ timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,
28
+ fetchImpl
29
+ };
30
+ }
31
+ async function apiRequest(cfg, method, path, body) {
32
+ const controller = new AbortController();
33
+ const timer = setTimeout(() => controller.abort(), cfg.timeoutMs);
34
+ try {
35
+ const res = await cfg.fetchImpl(`${cfg.baseUrl}${path}`, {
36
+ method,
37
+ headers: { "Content-Type": "application/json", "X-API-Key": cfg.apiKey },
38
+ body: body !== void 0 ? JSON.stringify(body) : void 0,
39
+ signal: controller.signal
40
+ });
41
+ const text = await res.text();
42
+ let parsed;
43
+ try {
44
+ parsed = text ? JSON.parse(text) : void 0;
45
+ } catch {
46
+ parsed = text;
47
+ }
48
+ if (!res.ok) {
49
+ const message = parsed && (parsed.message || parsed.error) || `Simplr API error ${res.status}`;
50
+ throw new SimplrError(message, res.status, parsed);
51
+ }
52
+ return parsed && typeof parsed === "object" && "content" in parsed ? parsed.content : parsed;
53
+ } catch (err) {
54
+ if (err instanceof SimplrError) throw err;
55
+ if (err instanceof Error && err.name === "AbortError") {
56
+ throw new SimplrError(`Request to ${path} timed out after ${cfg.timeoutMs}ms`, 0, null);
57
+ }
58
+ throw new SimplrError(err instanceof Error ? err.message : "Network error", 0, null);
59
+ } finally {
60
+ clearTimeout(timer);
61
+ }
62
+ }
63
+ var SimplrClient = class {
64
+ cfg;
65
+ constructor(config) {
66
+ this.cfg = resolve(config);
67
+ }
68
+ /** POST /v1/check — identity/fraud check. */
69
+ check(input) {
70
+ return apiRequest(this.cfg, "POST", "/v1/check", input);
71
+ }
72
+ /** POST /v1/orders — order fraud scoring. */
73
+ scoreOrder(input) {
74
+ return apiRequest(this.cfg, "POST", "/v1/orders", input);
75
+ }
76
+ /** GET /v1/check/phone/intelligence/{phone} — stored phone intelligence. */
77
+ phoneIntelligence(phone) {
78
+ return apiRequest(
79
+ this.cfg,
80
+ "GET",
81
+ `/v1/check/phone/intelligence/${encodeURIComponent(phone)}`
82
+ );
83
+ }
84
+ /** POST /v1/check/phone/report — report a real-world phone outcome. */
85
+ reportPhone(input) {
86
+ return apiRequest(this.cfg, "POST", "/v1/check/phone/report", input);
87
+ }
88
+ };
89
+
90
+ // src/schemas.ts
91
+ import { z } from "zod";
92
+ var checkIdentitySchema = z.object({
93
+ email: z.string().email().optional().describe("The user's email address to evaluate (e.g. for signup/login risk)."),
94
+ phone: z.string().optional().describe("The user's phone number in E.164 format (e.g. +14155552671)."),
95
+ event_type: z.string().optional().describe(
96
+ "The lifecycle event being scored, e.g. 'signup', 'login', 'checkout', 'password_reset'. Helps tune the risk model."
97
+ ),
98
+ event_id: z.string().optional().describe("Your own idempotency / correlation id for this event, if any."),
99
+ metadata: z.record(z.unknown()).optional().describe(
100
+ "Arbitrary extra context about the event (e.g. { ip: '1.2.3.4', user_id: 'u_123' }). Free-form key/value object."
101
+ )
102
+ }).describe(
103
+ "Provide at least one of `email` or `phone`. Returns a fraud/identity risk assessment for the given user or event."
104
+ );
105
+ var scoreOrderSchema = z.object({
106
+ order_id: z.string().describe("Your unique identifier for this order."),
107
+ external_id: z.string().optional().describe("An optional secondary id (e.g. your payment-processor reference)."),
108
+ amount: z.number().describe("The order total as a number in the order's currency (e.g. 129.99)."),
109
+ currency: z.string().describe("ISO 4217 currency code, e.g. 'USD', 'EUR', 'GBP'."),
110
+ fingerprint_hash: z.string().optional().describe(
111
+ "Device fingerprint hash from a prior identity check, if available, to link the order to a device."
112
+ ),
113
+ metadata: z.record(z.unknown()).optional().describe("Arbitrary extra order context (items, shipping, customer id, etc.).")
114
+ }).describe(
115
+ "Score a placed order for payment/transaction fraud risk. Returns a risk_score and risk_level for the order."
116
+ );
117
+ var phoneIntelligenceSchema = z.object({
118
+ phone: z.string().describe(
119
+ "The phone number to look up, in E.164 format (e.g. +14155552671). It will be URL-encoded."
120
+ )
121
+ }).describe(
122
+ "Fetch stored risk intelligence for a phone number (carrier, line type, SIM-swap signals, prior outcomes). Read-only, no side effects."
123
+ );
124
+ var reportPhoneOutcomeSchema = z.object({
125
+ phone: z.string().describe("The phone number the outcome applies to, in E.164 format."),
126
+ outcome: z.enum([
127
+ "fraud",
128
+ "sim_swap_fraud",
129
+ "account_takeover",
130
+ "spam",
131
+ "bot",
132
+ "legitimate"
133
+ ]).describe(
134
+ "The confirmed real-world outcome for this phone: 'legitimate' (good actor), 'fraud', 'sim_swap_fraud', 'account_takeover', 'spam', or 'bot'."
135
+ ),
136
+ check_id: z.string().optional().describe("The id of the original check this outcome relates to, if known."),
137
+ confidence: z.number().min(0).max(1).optional().describe("Your confidence in the reported outcome, 0.0\u20131.0."),
138
+ metadata: z.record(z.unknown()).optional().describe("Arbitrary extra context about how the outcome was determined.")
139
+ }).describe(
140
+ "Report a confirmed real-world outcome for a phone number back to Simplr. This is a feedback/training signal that improves future scoring \u2014 only call it once you actually know the outcome."
141
+ );
142
+
143
+ // src/tools.ts
144
+ var RISK_LEVEL_DOC = "The result includes `risk_score` (0\u2013100, higher = riskier) and `risk_level` (one of 'low', 'medium', 'high', 'critical').";
145
+ function createSimplrToolDescriptors(config) {
146
+ const client = new SimplrClient(config);
147
+ return {
148
+ simplr_check_identity: {
149
+ name: "simplr_check_identity",
150
+ description: "Assess the fraud/identity risk of a user or event using their email and/or phone. Use this for signups, logins, password resets, or any moment you need to decide whether to trust, challenge (e.g. step-up auth), or block a user. " + RISK_LEVEL_DOC,
151
+ inputSchema: checkIdentitySchema,
152
+ execute: (args) => client.check(args)
153
+ },
154
+ simplr_score_order: {
155
+ name: "simplr_score_order",
156
+ description: "Score a placed order/transaction for payment fraud risk given its amount, currency, and ids. Use this at checkout or post-purchase review to decide whether to approve, hold for manual review, or reject an order. " + RISK_LEVEL_DOC,
157
+ inputSchema: scoreOrderSchema,
158
+ execute: (args) => client.scoreOrder(args)
159
+ },
160
+ simplr_phone_intelligence: {
161
+ name: "simplr_phone_intelligence",
162
+ description: "Look up stored risk intelligence for a phone number (carrier, line type, SIM-swap and prior-outcome signals). Read-only with no side effects \u2014 safe to call whenever you need context about a phone number before deciding.",
163
+ inputSchema: phoneIntelligenceSchema,
164
+ execute: (args) => client.phoneIntelligence(args.phone)
165
+ },
166
+ simplr_report_phone_outcome: {
167
+ name: "simplr_report_phone_outcome",
168
+ description: "Report a confirmed real-world outcome for a phone number (e.g. 'fraud', 'sim_swap_fraud', 'legitimate') back to Simplr. This is a feedback/training signal that improves future scoring. Only call it once you actually KNOW the outcome \u2014 do not guess.",
169
+ inputSchema: reportPhoneOutcomeSchema,
170
+ execute: (args) => client.reportPhone(args)
171
+ }
172
+ };
173
+ }
174
+
175
+ // src/json-schema.ts
176
+ function def(schema) {
177
+ return schema._def;
178
+ }
179
+ function zodToJsonSchema(schema) {
180
+ const d = def(schema);
181
+ const typeName = d.typeName;
182
+ const description = d.description;
183
+ const withDesc = (js) => description ? { description, ...js } : js;
184
+ switch (typeName) {
185
+ case "ZodObject": {
186
+ const shape = typeof d.shape === "function" ? d.shape() : d.shape;
187
+ const properties = {};
188
+ const required = [];
189
+ for (const [key, value] of Object.entries(shape)) {
190
+ const vDef = def(value);
191
+ properties[key] = zodToJsonSchema(value);
192
+ if (vDef.typeName !== "ZodOptional" && vDef.typeName !== "ZodDefault") {
193
+ required.push(key);
194
+ }
195
+ }
196
+ const out = { type: "object", properties };
197
+ if (required.length) out.required = required;
198
+ return withDesc(out);
199
+ }
200
+ case "ZodString": {
201
+ const out = { type: "string" };
202
+ const checks = d.checks ?? [];
203
+ if (checks.some((c) => c.kind === "email")) out.format = "email";
204
+ return withDesc(out);
205
+ }
206
+ case "ZodNumber":
207
+ return withDesc({ type: "number" });
208
+ case "ZodBoolean":
209
+ return withDesc({ type: "boolean" });
210
+ case "ZodEnum":
211
+ return withDesc({ type: "string", enum: [...d.values] });
212
+ case "ZodNativeEnum":
213
+ return withDesc({
214
+ type: "string",
215
+ enum: Object.values(d.values).filter((v) => typeof v === "string")
216
+ });
217
+ case "ZodArray":
218
+ return withDesc({ type: "array", items: zodToJsonSchema(d.type) });
219
+ case "ZodRecord":
220
+ return withDesc({ type: "object", additionalProperties: true });
221
+ case "ZodOptional":
222
+ case "ZodNullable":
223
+ case "ZodDefault": {
224
+ const inner = zodToJsonSchema(d.innerType);
225
+ return description ? { ...inner, description } : inner;
226
+ }
227
+ case "ZodEffects":
228
+ return withDesc(zodToJsonSchema(d.schema));
229
+ default:
230
+ return withDesc({ type: "object" });
231
+ }
232
+ }
233
+
234
+ // src/openai.ts
235
+ function simplrOpenAITools(config) {
236
+ const descriptors = createSimplrToolDescriptors(config);
237
+ return Object.keys(descriptors).map((key) => {
238
+ const d = descriptors[key];
239
+ return {
240
+ type: "function",
241
+ function: {
242
+ name: d.name,
243
+ description: d.description,
244
+ parameters: zodToJsonSchema(d.inputSchema)
245
+ }
246
+ };
247
+ });
248
+ }
249
+ async function executeSimplrTool(name, args, config) {
250
+ const descriptors = createSimplrToolDescriptors(config);
251
+ const descriptor = descriptors[name];
252
+ if (!descriptor) {
253
+ throw new SimplrError(
254
+ `Unknown Simplr tool "${name}". Valid tools: ${Object.keys(descriptors).join(", ")}.`,
255
+ 0,
256
+ null
257
+ );
258
+ }
259
+ let parsedArgs;
260
+ if (typeof args === "string") {
261
+ try {
262
+ parsedArgs = args.trim() ? JSON.parse(args) : {};
263
+ } catch {
264
+ throw new SimplrError(
265
+ `Invalid JSON arguments for tool "${name}": ${args}`,
266
+ 0,
267
+ null
268
+ );
269
+ }
270
+ } else {
271
+ parsedArgs = args ?? {};
272
+ }
273
+ let validated;
274
+ try {
275
+ validated = descriptor.inputSchema.parse(parsedArgs);
276
+ } catch (err) {
277
+ throw new SimplrError(
278
+ `Arguments for tool "${name}" failed validation: ${err instanceof Error ? err.message : String(err)}`,
279
+ 0,
280
+ null
281
+ );
282
+ }
283
+ return descriptor.execute(validated);
284
+ }
285
+ export {
286
+ executeSimplrTool,
287
+ simplrOpenAITools,
288
+ zodToJsonSchema
289
+ };
290
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/schemas.ts","../src/tools.ts","../src/json-schema.ts","../src/openai.ts"],"sourcesContent":["/**\n * Thrown when the Simplr API returns a non-2xx response, or a request fails\n * (network error / timeout — in which case `status` is 0 and `body` is null).\n *\n * Mirrors `SimplrError` from `@simplr-ai/node`.\n */\nexport class SimplrError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"SimplrError\";\n this.status = status;\n this.body = body;\n }\n}\n","/**\n * Thin internal HTTP client.\n *\n * This mirrors the minimal request layer of `@simplr-ai/node` (`apiRequest` +\n * the check / orders / phone endpoints) so this package has **no unbuilt\n * workspace dependency** and tests can run fully offline. If you need the full\n * SDK (bulk, edge, flags, webhooks) use `@simplr-ai/node` directly.\n */\nimport { SimplrError } from \"./errors.js\";\nimport type {\n CheckInput,\n CheckResult,\n OrderInput,\n OrderResult,\n PhoneIntelligenceResult,\n PhoneReportInput,\n PhoneReportResult,\n SimplrAIConfig,\n} from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.simplr.sh\";\nconst DEFAULT_TIMEOUT_MS = 15000;\n\ninterface ResolvedConfig {\n apiKey: string;\n baseUrl: string;\n timeoutMs: number;\n fetchImpl: typeof fetch;\n}\n\nfunction resolve(config: SimplrAIConfig): ResolvedConfig {\n if (!config?.apiKey) throw new Error(\"@simplr-ai/ai: `apiKey` is required\");\n const fetchImpl = config.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== \"function\") {\n throw new Error(\n \"@simplr-ai/ai: no global fetch available — use Node 18+ or pass `fetch` in config\",\n );\n }\n return {\n apiKey: config.apiKey,\n baseUrl: (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, \"\"),\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n fetchImpl,\n };\n}\n\n/**\n * Internal request helper. Sends `X-API-Key`, applies a timeout, and unwraps the\n * API's `{ success, message, content }` envelope (returning `content`).\n */\nasync function apiRequest<T>(\n cfg: ResolvedConfig,\n method: \"GET\" | \"POST\",\n path: string,\n body?: unknown,\n): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), cfg.timeoutMs);\n try {\n const res = await cfg.fetchImpl(`${cfg.baseUrl}${path}`, {\n method,\n headers: { \"Content-Type\": \"application/json\", \"X-API-Key\": cfg.apiKey },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n const text = await res.text();\n let parsed: any;\n try {\n parsed = text ? JSON.parse(text) : undefined;\n } catch {\n parsed = text;\n }\n\n if (!res.ok) {\n const message =\n (parsed && (parsed.message || parsed.error)) || `Simplr API error ${res.status}`;\n throw new SimplrError(message, res.status, parsed);\n }\n\n return (parsed && typeof parsed === \"object\" && \"content\" in parsed\n ? parsed.content\n : parsed) as T;\n } catch (err) {\n if (err instanceof SimplrError) throw err;\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SimplrError(`Request to ${path} timed out after ${cfg.timeoutMs}ms`, 0, null);\n }\n throw new SimplrError(err instanceof Error ? err.message : \"Network error\", 0, null);\n } finally {\n clearTimeout(timer);\n }\n}\n\n/** A minimal Simplr API client exposing only the endpoints these tools need. */\nexport class SimplrClient {\n private readonly cfg: ResolvedConfig;\n\n constructor(config: SimplrAIConfig) {\n this.cfg = resolve(config);\n }\n\n /** POST /v1/check — identity/fraud check. */\n check(input: CheckInput): Promise<CheckResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check\", input);\n }\n\n /** POST /v1/orders — order fraud scoring. */\n scoreOrder(input: OrderInput): Promise<OrderResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/orders\", input);\n }\n\n /** GET /v1/check/phone/intelligence/{phone} — stored phone intelligence. */\n phoneIntelligence(phone: string): Promise<PhoneIntelligenceResult> {\n return apiRequest(\n this.cfg,\n \"GET\",\n `/v1/check/phone/intelligence/${encodeURIComponent(phone)}`,\n );\n }\n\n /** POST /v1/check/phone/report — report a real-world phone outcome. */\n reportPhone(input: PhoneReportInput): Promise<PhoneReportResult> {\n return apiRequest(this.cfg, \"POST\", \"/v1/check/phone/report\", input);\n }\n}\n","/**\n * Zod input schemas for each Simplr tool, with rich `.describe()` text so that\n * LLMs call the tools with the right arguments. Each schema corresponds 1:1 to\n * the API request body documented in the Simplr contract.\n */\nimport { z } from \"zod\";\n\n/** Input for `simplr_check_identity` → POST /v1/check. */\nexport const checkIdentitySchema = z\n .object({\n email: z\n .string()\n .email()\n .optional()\n .describe(\"The user's email address to evaluate (e.g. for signup/login risk).\"),\n phone: z\n .string()\n .optional()\n .describe(\"The user's phone number in E.164 format (e.g. +14155552671).\"),\n event_type: z\n .string()\n .optional()\n .describe(\n \"The lifecycle event being scored, e.g. 'signup', 'login', 'checkout', 'password_reset'. Helps tune the risk model.\",\n ),\n event_id: z\n .string()\n .optional()\n .describe(\"Your own idempotency / correlation id for this event, if any.\"),\n metadata: z\n .record(z.unknown())\n .optional()\n .describe(\n \"Arbitrary extra context about the event (e.g. { ip: '1.2.3.4', user_id: 'u_123' }). Free-form key/value object.\",\n ),\n })\n .describe(\n \"Provide at least one of `email` or `phone`. Returns a fraud/identity risk assessment for the given user or event.\",\n );\n\n/** Input for `simplr_score_order` → POST /v1/orders. */\nexport const scoreOrderSchema = z\n .object({\n order_id: z\n .string()\n .describe(\"Your unique identifier for this order.\"),\n external_id: z\n .string()\n .optional()\n .describe(\"An optional secondary id (e.g. your payment-processor reference).\"),\n amount: z\n .number()\n .describe(\"The order total as a number in the order's currency (e.g. 129.99).\"),\n currency: z\n .string()\n .describe(\"ISO 4217 currency code, e.g. 'USD', 'EUR', 'GBP'.\"),\n fingerprint_hash: z\n .string()\n .optional()\n .describe(\n \"Device fingerprint hash from a prior identity check, if available, to link the order to a device.\",\n ),\n metadata: z\n .record(z.unknown())\n .optional()\n .describe(\"Arbitrary extra order context (items, shipping, customer id, etc.).\"),\n })\n .describe(\n \"Score a placed order for payment/transaction fraud risk. Returns a risk_score and risk_level for the order.\",\n );\n\n/** Input for `simplr_phone_intelligence` → GET /v1/check/phone/intelligence/{phone}. */\nexport const phoneIntelligenceSchema = z\n .object({\n phone: z\n .string()\n .describe(\n \"The phone number to look up, in E.164 format (e.g. +14155552671). It will be URL-encoded.\",\n ),\n })\n .describe(\n \"Fetch stored risk intelligence for a phone number (carrier, line type, SIM-swap signals, prior outcomes). Read-only, no side effects.\",\n );\n\n/** Input for `simplr_report_phone_outcome` → POST /v1/check/phone/report. */\nexport const reportPhoneOutcomeSchema = z\n .object({\n phone: z\n .string()\n .describe(\"The phone number the outcome applies to, in E.164 format.\"),\n outcome: z\n .enum([\n \"fraud\",\n \"sim_swap_fraud\",\n \"account_takeover\",\n \"spam\",\n \"bot\",\n \"legitimate\",\n ])\n .describe(\n \"The confirmed real-world outcome for this phone: 'legitimate' (good actor), 'fraud', 'sim_swap_fraud', 'account_takeover', 'spam', or 'bot'.\",\n ),\n check_id: z\n .string()\n .optional()\n .describe(\"The id of the original check this outcome relates to, if known.\"),\n confidence: z\n .number()\n .min(0)\n .max(1)\n .optional()\n .describe(\"Your confidence in the reported outcome, 0.0–1.0.\"),\n metadata: z\n .record(z.unknown())\n .optional()\n .describe(\"Arbitrary extra context about how the outcome was determined.\"),\n })\n .describe(\n \"Report a confirmed real-world outcome for a phone number back to Simplr. This is a feedback/training signal that improves future scoring — only call it once you actually know the outcome.\",\n );\n\nexport type CheckIdentityArgs = z.infer<typeof checkIdentitySchema>;\nexport type ScoreOrderArgs = z.infer<typeof scoreOrderSchema>;\nexport type PhoneIntelligenceArgs = z.infer<typeof phoneIntelligenceSchema>;\nexport type ReportPhoneOutcomeArgs = z.infer<typeof reportPhoneOutcomeSchema>;\n","/**\n * Framework-agnostic tool descriptors.\n *\n * Each descriptor is a plain object `{ name, description, inputSchema, execute }`.\n * The same descriptors are wrapped for Vercel AI SDK (`./index`), raw OpenAI\n * function-calling (`./openai`), and LangChain (`./langchain`).\n */\nimport type { z } from \"zod\";\nimport { SimplrClient } from \"./client.js\";\nimport {\n checkIdentitySchema,\n phoneIntelligenceSchema,\n reportPhoneOutcomeSchema,\n scoreOrderSchema,\n type CheckIdentityArgs,\n type PhoneIntelligenceArgs,\n type ReportPhoneOutcomeArgs,\n type ScoreOrderArgs,\n} from \"./schemas.js\";\nimport type {\n CheckResult,\n OrderResult,\n PhoneIntelligenceResult,\n PhoneReportResult,\n SimplrAIConfig,\n} from \"./types.js\";\n\n/** A single framework-agnostic Simplr tool descriptor. */\nexport interface SimplrToolDescriptor<Args = any, Result = any> {\n /** Stable tool name, e.g. `simplr_check_identity`. */\n name: string;\n /** Agent-facing description (when to use it, what it returns). */\n description: string;\n /** Zod schema for the tool's input arguments. */\n inputSchema: z.ZodType<Args>;\n /** Run the tool against the Simplr API and return the unwrapped result. */\n execute: (args: Args) => Promise<Result>;\n}\n\nconst RISK_LEVEL_DOC =\n \"The result includes `risk_score` (0–100, higher = riskier) and `risk_level` (one of 'low', 'medium', 'high', 'critical').\";\n\n/**\n * Build the four Simplr tool descriptors bound to a client. These are pure data\n * + closures — no AI framework is required to use them.\n */\nexport function createSimplrToolDescriptors(\n config: SimplrAIConfig,\n): {\n simplr_check_identity: SimplrToolDescriptor<CheckIdentityArgs, CheckResult>;\n simplr_score_order: SimplrToolDescriptor<ScoreOrderArgs, OrderResult>;\n simplr_phone_intelligence: SimplrToolDescriptor<\n PhoneIntelligenceArgs,\n PhoneIntelligenceResult\n >;\n simplr_report_phone_outcome: SimplrToolDescriptor<\n ReportPhoneOutcomeArgs,\n PhoneReportResult\n >;\n} {\n const client = new SimplrClient(config);\n\n return {\n simplr_check_identity: {\n name: \"simplr_check_identity\",\n description:\n \"Assess the fraud/identity risk of a user or event using their email and/or phone. \" +\n \"Use this for signups, logins, password resets, or any moment you need to decide whether to \" +\n \"trust, challenge (e.g. step-up auth), or block a user. \" +\n RISK_LEVEL_DOC,\n inputSchema: checkIdentitySchema,\n execute: (args) => client.check(args),\n },\n\n simplr_score_order: {\n name: \"simplr_score_order\",\n description:\n \"Score a placed order/transaction for payment fraud risk given its amount, currency, and ids. \" +\n \"Use this at checkout or post-purchase review to decide whether to approve, hold for manual review, or reject an order. \" +\n RISK_LEVEL_DOC,\n inputSchema: scoreOrderSchema,\n execute: (args) => client.scoreOrder(args),\n },\n\n simplr_phone_intelligence: {\n name: \"simplr_phone_intelligence\",\n description:\n \"Look up stored risk intelligence for a phone number (carrier, line type, SIM-swap and prior-outcome signals). \" +\n \"Read-only with no side effects — safe to call whenever you need context about a phone number before deciding.\",\n inputSchema: phoneIntelligenceSchema,\n execute: (args) => client.phoneIntelligence(args.phone),\n },\n\n simplr_report_phone_outcome: {\n name: \"simplr_report_phone_outcome\",\n description:\n \"Report a confirmed real-world outcome for a phone number (e.g. 'fraud', 'sim_swap_fraud', 'legitimate') back to Simplr. \" +\n \"This is a feedback/training signal that improves future scoring. Only call it once you actually KNOW the outcome — \" +\n \"do not guess.\",\n inputSchema: reportPhoneOutcomeSchema,\n execute: (args) => client.reportPhone(args),\n },\n };\n}\n\n/** The set of tool names exposed by this package. */\nexport type SimplrToolName =\n | \"simplr_check_identity\"\n | \"simplr_score_order\"\n | \"simplr_phone_intelligence\"\n | \"simplr_report_phone_outcome\";\n","/**\n * A minimal zod → JSON Schema converter.\n *\n * Intentionally tiny: it only covers the zod node types actually used by this\n * package's schemas (object, string, number, boolean, enum, record, optional,\n * and the `.describe()` metadata). This avoids pulling in a heavy dependency\n * just to emit OpenAI function-calling `parameters`.\n */\nimport type { z } from \"zod\";\n\nexport interface JsonSchema {\n type?: string;\n description?: string;\n properties?: Record<string, JsonSchema>;\n required?: string[];\n items?: JsonSchema;\n enum?: string[];\n format?: string;\n additionalProperties?: boolean | JsonSchema;\n}\n\nfunction def(schema: z.ZodTypeAny): any {\n return (schema as any)._def;\n}\n\nexport function zodToJsonSchema(schema: z.ZodTypeAny): JsonSchema {\n const d = def(schema);\n const typeName: string = d.typeName;\n const description: string | undefined = d.description;\n\n const withDesc = (js: JsonSchema): JsonSchema =>\n description ? { description, ...js } : js;\n\n switch (typeName) {\n case \"ZodObject\": {\n const shape: Record<string, z.ZodTypeAny> =\n typeof d.shape === \"function\" ? d.shape() : d.shape;\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n for (const [key, value] of Object.entries(shape)) {\n const vDef = def(value);\n properties[key] = zodToJsonSchema(value);\n if (vDef.typeName !== \"ZodOptional\" && vDef.typeName !== \"ZodDefault\") {\n required.push(key);\n }\n }\n const out: JsonSchema = { type: \"object\", properties };\n if (required.length) out.required = required;\n return withDesc(out);\n }\n\n case \"ZodString\": {\n const out: JsonSchema = { type: \"string\" };\n // Detect an email check so we can emit format: \"email\".\n const checks: any[] = d.checks ?? [];\n if (checks.some((c) => c.kind === \"email\")) out.format = \"email\";\n return withDesc(out);\n }\n\n case \"ZodNumber\":\n return withDesc({ type: \"number\" });\n\n case \"ZodBoolean\":\n return withDesc({ type: \"boolean\" });\n\n case \"ZodEnum\":\n return withDesc({ type: \"string\", enum: [...d.values] });\n\n case \"ZodNativeEnum\":\n return withDesc({\n type: \"string\",\n enum: Object.values(d.values).filter((v) => typeof v === \"string\") as string[],\n });\n\n case \"ZodArray\":\n return withDesc({ type: \"array\", items: zodToJsonSchema(d.type) });\n\n case \"ZodRecord\":\n return withDesc({ type: \"object\", additionalProperties: true });\n\n case \"ZodOptional\":\n case \"ZodNullable\":\n case \"ZodDefault\": {\n const inner = zodToJsonSchema(d.innerType);\n return description ? { ...inner, description } : inner;\n }\n\n case \"ZodEffects\":\n return withDesc(zodToJsonSchema(d.schema));\n\n default:\n // Fallback: permissive object.\n return withDesc({ type: \"object\" });\n }\n}\n","/**\n * `@simplr-ai/ai/openai` — raw OpenAI function-calling integration.\n *\n * `simplrOpenAITools(config)` returns the array of `tools` you pass to the\n * OpenAI Chat Completions / Responses API. When the model emits a tool call,\n * pass its `name` and JSON-string `arguments` to `executeSimplrTool` to run it.\n *\n * No OpenAI SDK is required — these are plain JSON descriptors.\n */\nimport { createSimplrToolDescriptors, type SimplrToolName } from \"./tools.js\";\nimport { zodToJsonSchema, type JsonSchema } from \"./json-schema.js\";\nimport { SimplrError } from \"./errors.js\";\nimport type { SimplrAIConfig } from \"./types.js\";\n\n/** An OpenAI function-calling tool descriptor. */\nexport interface OpenAIFunctionTool {\n type: \"function\";\n function: {\n name: string;\n description: string;\n parameters: JsonSchema;\n };\n}\n\n/**\n * Build the OpenAI `tools` array for every Simplr capability.\n *\n * ```ts\n * import OpenAI from \"openai\";\n * import { simplrOpenAITools, executeSimplrTool } from \"@simplr-ai/ai/openai\";\n *\n * const config = { apiKey: process.env.SIMPLR_API_KEY! };\n * const client = new OpenAI();\n * const res = await client.chat.completions.create({\n * model: \"gpt-4o\",\n * messages,\n * tools: simplrOpenAITools(config),\n * });\n * const call = res.choices[0].message.tool_calls?.[0];\n * if (call) {\n * const result = await executeSimplrTool(call.function.name, call.function.arguments, config);\n * }\n * ```\n */\nexport function simplrOpenAITools(config: SimplrAIConfig): OpenAIFunctionTool[] {\n const descriptors = createSimplrToolDescriptors(config);\n return (Object.keys(descriptors) as SimplrToolName[]).map((key) => {\n const d = descriptors[key];\n return {\n type: \"function\",\n function: {\n name: d.name,\n description: d.description,\n parameters: zodToJsonSchema(d.inputSchema as any),\n },\n };\n });\n}\n\n/**\n * Execute a single tool call emitted by the model.\n *\n * @param name The tool name from `tool_call.function.name`.\n * @param args The raw JSON-string arguments (`tool_call.function.arguments`),\n * or an already-parsed object.\n * @param config Simplr config (apiKey, etc.).\n * @returns The unwrapped Simplr API result. Validates input against the tool's\n * zod schema first and throws `SimplrError` on bad input / unknown tool.\n */\nexport async function executeSimplrTool(\n name: string,\n args: string | Record<string, unknown>,\n config: SimplrAIConfig,\n): Promise<unknown> {\n const descriptors = createSimplrToolDescriptors(config) as Record<\n string,\n {\n name: string;\n inputSchema: { parse: (v: unknown) => unknown };\n execute: (v: unknown) => Promise<unknown>;\n }\n >;\n const descriptor = descriptors[name];\n if (!descriptor) {\n throw new SimplrError(\n `Unknown Simplr tool \"${name}\". Valid tools: ${Object.keys(descriptors).join(\", \")}.`,\n 0,\n null,\n );\n }\n\n let parsedArgs: unknown;\n if (typeof args === \"string\") {\n try {\n parsedArgs = args.trim() ? JSON.parse(args) : {};\n } catch {\n throw new SimplrError(\n `Invalid JSON arguments for tool \"${name}\": ${args}`,\n 0,\n null,\n );\n }\n } else {\n parsedArgs = args ?? {};\n }\n\n let validated: unknown;\n try {\n validated = descriptor.inputSchema.parse(parsedArgs);\n } catch (err) {\n throw new SimplrError(\n `Arguments for tool \"${name}\" failed validation: ${\n err instanceof Error ? err.message : String(err)\n }`,\n 0,\n null,\n );\n }\n\n return descriptor.execute(validated);\n}\n\nexport { zodToJsonSchema } from \"./json-schema.js\";\nexport type { JsonSchema } from \"./json-schema.js\";\n"],"mappings":"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","names":[]}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Type definitions mirroring the Simplr API contract.
3
+ *
4
+ * These match the request/response shapes of `@simplr-ai/node` exactly — see
5
+ * the contract at https://docs.simplr.so/docs/sdks/.
6
+ */
7
+ type RiskLevel = "low" | "medium" | "high" | "critical";
8
+ /** Configuration shared by every tool factory in this package. */
9
+ interface SimplrAIConfig {
10
+ /**
11
+ * Secret API key (`sk_live_…` / `sk_test_…`). Sent as `X-API-Key`.
12
+ * Keep this server-side only — never ship it to a browser or agent client.
13
+ */
14
+ apiKey: string;
15
+ /** API base URL. Defaults to `https://api.simplr.sh`. */
16
+ baseUrl?: string;
17
+ /** Per-request timeout in ms (default 15000). */
18
+ timeoutMs?: number;
19
+ /** Override the fetch implementation (defaults to global fetch). */
20
+ fetch?: typeof fetch;
21
+ }
22
+ interface CheckInput {
23
+ email?: string;
24
+ phone?: string;
25
+ device?: Record<string, unknown>;
26
+ behavior?: Record<string, unknown>;
27
+ event_type?: string;
28
+ event_id?: string;
29
+ metadata?: Record<string, unknown>;
30
+ }
31
+ interface CheckResult {
32
+ type?: string;
33
+ risk_score: number;
34
+ risk_level: RiskLevel;
35
+ signals?: Record<string, unknown>;
36
+ email?: string;
37
+ phone_number?: string;
38
+ fingerprint_hash?: string;
39
+ checked_at?: string;
40
+ is_sandbox?: boolean;
41
+ [key: string]: unknown;
42
+ }
43
+ interface OrderInput {
44
+ order_id: string;
45
+ external_id?: string;
46
+ amount: number;
47
+ currency: string;
48
+ fingerprint_hash?: string;
49
+ [key: string]: unknown;
50
+ }
51
+ interface OrderResult {
52
+ order_id: string;
53
+ risk_score: number;
54
+ risk_level: RiskLevel;
55
+ [key: string]: unknown;
56
+ }
57
+ type PhoneOutcome = "fraud" | "sim_swap_fraud" | "account_takeover" | "spam" | "bot" | "legitimate";
58
+ interface PhoneReportInput {
59
+ phone: string;
60
+ outcome: PhoneOutcome;
61
+ check_id?: string;
62
+ confidence?: number;
63
+ metadata?: Record<string, unknown>;
64
+ }
65
+ /** Result of a phone-intelligence lookup — a free-form intelligence object. */
66
+ type PhoneIntelligenceResult = Record<string, unknown>;
67
+ /** Result of reporting a phone outcome. */
68
+ interface PhoneReportResult {
69
+ success: boolean;
70
+ [key: string]: unknown;
71
+ }
72
+
73
+ export type { CheckResult as C, OrderResult as O, PhoneIntelligenceResult as P, RiskLevel as R, SimplrAIConfig as S, PhoneReportResult as a, CheckInput as b, OrderInput as c, PhoneReportInput as d, PhoneOutcome as e };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Type definitions mirroring the Simplr API contract.
3
+ *
4
+ * These match the request/response shapes of `@simplr-ai/node` exactly — see
5
+ * the contract at https://docs.simplr.so/docs/sdks/.
6
+ */
7
+ type RiskLevel = "low" | "medium" | "high" | "critical";
8
+ /** Configuration shared by every tool factory in this package. */
9
+ interface SimplrAIConfig {
10
+ /**
11
+ * Secret API key (`sk_live_…` / `sk_test_…`). Sent as `X-API-Key`.
12
+ * Keep this server-side only — never ship it to a browser or agent client.
13
+ */
14
+ apiKey: string;
15
+ /** API base URL. Defaults to `https://api.simplr.sh`. */
16
+ baseUrl?: string;
17
+ /** Per-request timeout in ms (default 15000). */
18
+ timeoutMs?: number;
19
+ /** Override the fetch implementation (defaults to global fetch). */
20
+ fetch?: typeof fetch;
21
+ }
22
+ interface CheckInput {
23
+ email?: string;
24
+ phone?: string;
25
+ device?: Record<string, unknown>;
26
+ behavior?: Record<string, unknown>;
27
+ event_type?: string;
28
+ event_id?: string;
29
+ metadata?: Record<string, unknown>;
30
+ }
31
+ interface CheckResult {
32
+ type?: string;
33
+ risk_score: number;
34
+ risk_level: RiskLevel;
35
+ signals?: Record<string, unknown>;
36
+ email?: string;
37
+ phone_number?: string;
38
+ fingerprint_hash?: string;
39
+ checked_at?: string;
40
+ is_sandbox?: boolean;
41
+ [key: string]: unknown;
42
+ }
43
+ interface OrderInput {
44
+ order_id: string;
45
+ external_id?: string;
46
+ amount: number;
47
+ currency: string;
48
+ fingerprint_hash?: string;
49
+ [key: string]: unknown;
50
+ }
51
+ interface OrderResult {
52
+ order_id: string;
53
+ risk_score: number;
54
+ risk_level: RiskLevel;
55
+ [key: string]: unknown;
56
+ }
57
+ type PhoneOutcome = "fraud" | "sim_swap_fraud" | "account_takeover" | "spam" | "bot" | "legitimate";
58
+ interface PhoneReportInput {
59
+ phone: string;
60
+ outcome: PhoneOutcome;
61
+ check_id?: string;
62
+ confidence?: number;
63
+ metadata?: Record<string, unknown>;
64
+ }
65
+ /** Result of a phone-intelligence lookup — a free-form intelligence object. */
66
+ type PhoneIntelligenceResult = Record<string, unknown>;
67
+ /** Result of reporting a phone outcome. */
68
+ interface PhoneReportResult {
69
+ success: boolean;
70
+ [key: string]: unknown;
71
+ }
72
+
73
+ export type { CheckResult as C, OrderResult as O, PhoneIntelligenceResult as P, RiskLevel as R, SimplrAIConfig as S, PhoneReportResult as a, CheckInput as b, OrderInput as c, PhoneReportInput as d, PhoneOutcome as e };
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@simplr-ai/ai",
3
+ "version": "1.0.0",
4
+ "description": "Simplr's fraud/identity/phone checks as ready-to-use tools for AI agents — Vercel AI SDK, OpenAI function-calling, and LangChain.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "require": {
17
+ "types": "./dist/index.d.cts",
18
+ "default": "./dist/index.cjs"
19
+ }
20
+ },
21
+ "./openai": {
22
+ "import": {
23
+ "types": "./dist/openai.d.ts",
24
+ "default": "./dist/openai.js"
25
+ },
26
+ "require": {
27
+ "types": "./dist/openai.d.cts",
28
+ "default": "./dist/openai.cjs"
29
+ }
30
+ },
31
+ "./langchain": {
32
+ "import": {
33
+ "types": "./dist/langchain.d.ts",
34
+ "default": "./dist/langchain.js"
35
+ },
36
+ "require": {
37
+ "types": "./dist/langchain.d.cts",
38
+ "default": "./dist/langchain.cjs"
39
+ }
40
+ }
41
+ },
42
+ "files": [
43
+ "dist"
44
+ ],
45
+ "engines": {
46
+ "node": ">=18"
47
+ },
48
+ "scripts": {
49
+ "build": "tsup",
50
+ "dev": "tsup --watch",
51
+ "typecheck": "tsc --noEmit",
52
+ "test": "vitest run"
53
+ },
54
+ "dependencies": {
55
+ "zod": "^3.23.0"
56
+ },
57
+ "peerDependencies": {
58
+ "ai": ">=3",
59
+ "@langchain/core": ">=0.2"
60
+ },
61
+ "peerDependenciesMeta": {
62
+ "ai": {
63
+ "optional": true
64
+ },
65
+ "@langchain/core": {
66
+ "optional": true
67
+ }
68
+ },
69
+ "devDependencies": {
70
+ "@types/node": "^20.0.0",
71
+ "tsup": "^8.0.0",
72
+ "typescript": "^5.3.0",
73
+ "vitest": "^1.6.0"
74
+ },
75
+ "keywords": [
76
+ "simplr",
77
+ "simplr",
78
+ "fraud",
79
+ "identity",
80
+ "phone-intelligence",
81
+ "ai",
82
+ "ai-sdk",
83
+ "vercel-ai",
84
+ "openai",
85
+ "function-calling",
86
+ "tools",
87
+ "langchain",
88
+ "agents"
89
+ ]
90
+ }