twelveai 0.1.0 → 0.2.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/README.md CHANGED
@@ -36,6 +36,18 @@ console.log(res.message) // "Your current balance is NGN 307.05."
36
36
 
37
37
  Behind that one call the SDK also completed any **client-fetch hand-offs**: when a tool is configured as *"my app calls it"*, the engine returns the resolved request (method, URL, body - no credentials attached) instead of calling your API. The SDK performs it with your `clientAuth`, resumes the turn, and hands you the final grounded answer. Inspect what ran via `res.executedHandoffs`.
38
38
 
39
+ ## Level 0: classify only (zero commitment)
40
+
41
+ Not ready to hand over the conversation? Keep every flow you have and use
42
+ TwelveAI purely as the router - free, nothing stored:
43
+
44
+ ```ts
45
+ const r = await twelve.classify({ message: 'send 5k to 0123456789' })
46
+ // { intent: 'transfer', confidence: 0.8,
47
+ // entities: { amount: 5000, account_number: '0123456789' } }
48
+ if (r.confidence > 0.6) routeToMyTransferFlow(r.entities)
49
+ ```
50
+
39
51
  ## Multi-turn conversations
40
52
 
41
53
  Pass the previous turn's `continuation` to keep context:
package/dist/index.cjs CHANGED
@@ -67,6 +67,34 @@ var TwelveAI = class {
67
67
  async confirm(continuation, input = {}) {
68
68
  return this.chat({ message: "yes", ...input, continuation, confirmed: true });
69
69
  }
70
+ /**
71
+ * Level-0 integration: classify a message WITHOUT running the conversation.
72
+ * Returns the intent, a deterministic confidence score, and cheap extracted
73
+ * entities (amount / account number / phone) - you keep your existing flows
74
+ * and make the call yourself. Free: no tools run, nothing is stored.
75
+ */
76
+ async classify(input) {
77
+ try {
78
+ const res = await this.fetchImpl(`${this.baseUrl}/v1/classify`, {
79
+ method: "POST",
80
+ headers: { "content-type": "application/json", "x-api-key": this.apiKey },
81
+ body: JSON.stringify({ message: input.message })
82
+ });
83
+ const data = await res.json().catch(() => ({}));
84
+ return {
85
+ ok: res.ok && data.ok !== false,
86
+ intent: data.intent ?? null,
87
+ label: data.label ?? null,
88
+ confidence: data.confidence ?? 0,
89
+ alternatives: data.alternatives ?? [],
90
+ entities: data.entities ?? {},
91
+ status: res.status,
92
+ ...res.ok ? {} : { error: data.error ?? `Engine returned ${res.status}` }
93
+ };
94
+ } catch (error) {
95
+ return { ok: false, intent: null, label: null, confidence: 0, alternatives: [], entities: {}, status: 0, error: error?.message || "Could not reach the engine." };
96
+ }
97
+ }
70
98
  /* ------------------------------ internals ------------------------------ */
71
99
  chatBody(input) {
72
100
  const body = {};
package/dist/index.d.cts CHANGED
@@ -123,6 +123,22 @@ interface ChatResponse {
123
123
  * `clientAuth` headers and returns `{ ok, data }`.
124
124
  */
125
125
  type HandoffExecutor = (call: PendingToolCall) => Promise<unknown>;
126
+ interface ClassifyResponse {
127
+ ok: boolean;
128
+ /** The winning agent intent, or null when nothing matched. */
129
+ intent: string | null;
130
+ label: string | null;
131
+ /** Deterministic confidence in [0, 0.95]; 0 = no match. */
132
+ confidence: number;
133
+ alternatives: Array<{
134
+ intent: string;
135
+ label: string;
136
+ }>;
137
+ /** Cheap extracted entities: amount, account_number, phone (when present). */
138
+ entities: Record<string, unknown>;
139
+ status: number;
140
+ error?: string;
141
+ }
126
142
 
127
143
  /**
128
144
  * The TwelveAI client. One call does the whole conversation protocol:
@@ -161,6 +177,15 @@ declare class TwelveAI {
161
177
  * `confirmed: true` so the engine proceeds.
162
178
  */
163
179
  confirm(continuation: string, input?: Omit<ChatInput, 'continuation' | 'confirmed'>): Promise<ChatResponse>;
180
+ /**
181
+ * Level-0 integration: classify a message WITHOUT running the conversation.
182
+ * Returns the intent, a deterministic confidence score, and cheap extracted
183
+ * entities (amount / account number / phone) - you keep your existing flows
184
+ * and make the call yourself. Free: no tools run, nothing is stored.
185
+ */
186
+ classify(input: {
187
+ message: string;
188
+ }): Promise<ClassifyResponse>;
164
189
  private chatBody;
165
190
  private post;
166
191
  /**
@@ -227,4 +252,4 @@ declare function createJwksVerifier(options?: JwksVerifierOptions): (input: JwtR
227
252
  claims?: Record<string, unknown>;
228
253
  }>;
229
254
 
230
- export { type Attachment, type ChatInput, type ChatResponse, type HandoffExecutor, type HandoffRequest, type JwksVerifierOptions, type JwtRequestInput, type PendingToolCall, type SignedRequestInput, type ToolCall, type ToolResult, TwelveAI, type TwelveAIOptions, createJwksVerifier, verifySignedRequest, verifyWebhook };
255
+ export { type Attachment, type ChatInput, type ChatResponse, type ClassifyResponse, type HandoffExecutor, type HandoffRequest, type JwksVerifierOptions, type JwtRequestInput, type PendingToolCall, type SignedRequestInput, type ToolCall, type ToolResult, TwelveAI, type TwelveAIOptions, createJwksVerifier, verifySignedRequest, verifyWebhook };
package/dist/index.d.ts CHANGED
@@ -123,6 +123,22 @@ interface ChatResponse {
123
123
  * `clientAuth` headers and returns `{ ok, data }`.
124
124
  */
125
125
  type HandoffExecutor = (call: PendingToolCall) => Promise<unknown>;
126
+ interface ClassifyResponse {
127
+ ok: boolean;
128
+ /** The winning agent intent, or null when nothing matched. */
129
+ intent: string | null;
130
+ label: string | null;
131
+ /** Deterministic confidence in [0, 0.95]; 0 = no match. */
132
+ confidence: number;
133
+ alternatives: Array<{
134
+ intent: string;
135
+ label: string;
136
+ }>;
137
+ /** Cheap extracted entities: amount, account_number, phone (when present). */
138
+ entities: Record<string, unknown>;
139
+ status: number;
140
+ error?: string;
141
+ }
126
142
 
127
143
  /**
128
144
  * The TwelveAI client. One call does the whole conversation protocol:
@@ -161,6 +177,15 @@ declare class TwelveAI {
161
177
  * `confirmed: true` so the engine proceeds.
162
178
  */
163
179
  confirm(continuation: string, input?: Omit<ChatInput, 'continuation' | 'confirmed'>): Promise<ChatResponse>;
180
+ /**
181
+ * Level-0 integration: classify a message WITHOUT running the conversation.
182
+ * Returns the intent, a deterministic confidence score, and cheap extracted
183
+ * entities (amount / account number / phone) - you keep your existing flows
184
+ * and make the call yourself. Free: no tools run, nothing is stored.
185
+ */
186
+ classify(input: {
187
+ message: string;
188
+ }): Promise<ClassifyResponse>;
164
189
  private chatBody;
165
190
  private post;
166
191
  /**
@@ -227,4 +252,4 @@ declare function createJwksVerifier(options?: JwksVerifierOptions): (input: JwtR
227
252
  claims?: Record<string, unknown>;
228
253
  }>;
229
254
 
230
- export { type Attachment, type ChatInput, type ChatResponse, type HandoffExecutor, type HandoffRequest, type JwksVerifierOptions, type JwtRequestInput, type PendingToolCall, type SignedRequestInput, type ToolCall, type ToolResult, TwelveAI, type TwelveAIOptions, createJwksVerifier, verifySignedRequest, verifyWebhook };
255
+ export { type Attachment, type ChatInput, type ChatResponse, type ClassifyResponse, type HandoffExecutor, type HandoffRequest, type JwksVerifierOptions, type JwtRequestInput, type PendingToolCall, type SignedRequestInput, type ToolCall, type ToolResult, TwelveAI, type TwelveAIOptions, createJwksVerifier, verifySignedRequest, verifyWebhook };
package/dist/index.js CHANGED
@@ -38,6 +38,34 @@ var TwelveAI = class {
38
38
  async confirm(continuation, input = {}) {
39
39
  return this.chat({ message: "yes", ...input, continuation, confirmed: true });
40
40
  }
41
+ /**
42
+ * Level-0 integration: classify a message WITHOUT running the conversation.
43
+ * Returns the intent, a deterministic confidence score, and cheap extracted
44
+ * entities (amount / account number / phone) - you keep your existing flows
45
+ * and make the call yourself. Free: no tools run, nothing is stored.
46
+ */
47
+ async classify(input) {
48
+ try {
49
+ const res = await this.fetchImpl(`${this.baseUrl}/v1/classify`, {
50
+ method: "POST",
51
+ headers: { "content-type": "application/json", "x-api-key": this.apiKey },
52
+ body: JSON.stringify({ message: input.message })
53
+ });
54
+ const data = await res.json().catch(() => ({}));
55
+ return {
56
+ ok: res.ok && data.ok !== false,
57
+ intent: data.intent ?? null,
58
+ label: data.label ?? null,
59
+ confidence: data.confidence ?? 0,
60
+ alternatives: data.alternatives ?? [],
61
+ entities: data.entities ?? {},
62
+ status: res.status,
63
+ ...res.ok ? {} : { error: data.error ?? `Engine returned ${res.status}` }
64
+ };
65
+ } catch (error) {
66
+ return { ok: false, intent: null, label: null, confidence: 0, alternatives: [], entities: {}, status: 0, error: error?.message || "Could not reach the engine." };
67
+ }
68
+ }
41
69
  /* ------------------------------ internals ------------------------------ */
42
70
  chatBody(input) {
43
71
  const body = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "twelveai",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Official SDK for TwelveAI - AI infrastructure for conversational banking. One call runs the whole chat protocol: routing, grounded tool calls, client-fetch hand-offs, confirmations, and request verification.",
5
5
  "license": "MIT",
6
6
  "author": "TwelveAI",