ttc-ai-chat-sdk 1.2.1 → 1.3.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 +138 -0
- package/dist/index.d.ts +14 -11
- package/dist/utils/authClient.js +9 -0
- package/dist/utils/authClient.js.map +1 -1
- package/dist/utils/storage.js +120 -0
- package/dist/utils/storage.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -173,6 +173,144 @@ const models = await assistant.getModels();
|
|
|
173
173
|
await assistant.selectModel("model-id", "llm"); // type: 'llm' | 'stt' | 'tts'
|
|
174
174
|
```
|
|
175
175
|
|
|
176
|
+
## Assistant API (Server-Side)
|
|
177
|
+
|
|
178
|
+
The `AssistantAPI` allows you to manage assistants from your backend. Use it to create assistants, generate tokens, and manage assistant metadata.
|
|
179
|
+
|
|
180
|
+
### Initialize the Assistant API
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { ttc } from "ttc-ai-chat-sdk";
|
|
184
|
+
|
|
185
|
+
const apiKey = "your-api-key";
|
|
186
|
+
const assistantAPI = ttc.assistantAPI(apiKey);
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Create an Assistant
|
|
190
|
+
|
|
191
|
+
Create a new assistant for a user and get a chat token for the frontend:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
const result = await assistantAPI.create(
|
|
195
|
+
"My Assistant", // name
|
|
196
|
+
"user-unique-id-123", // cuid (custom user ID)
|
|
197
|
+
{
|
|
198
|
+
backstory: "You are a helpful shopping assistant",
|
|
199
|
+
emote: "friendly",
|
|
200
|
+
traits: "helpful, knowledgeable",
|
|
201
|
+
metadata: { theme: "dark" }
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
if (result.status === "success") {
|
|
206
|
+
const { chatId, token } = result.data;
|
|
207
|
+
// Send token to frontend
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Generate a New Token
|
|
212
|
+
|
|
213
|
+
Generate a fresh token for an existing assistant:
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
const result = await assistantAPI.generateToken(
|
|
217
|
+
"user-unique-id-123", // cuid
|
|
218
|
+
"30d" // expiry duration
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
if (result.status === "success") {
|
|
222
|
+
const { token } = result.data;
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Validate a Token
|
|
227
|
+
|
|
228
|
+
Check if a token is still valid:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
const result = await assistantAPI.validateToken(token);
|
|
232
|
+
|
|
233
|
+
if (result.status === "success") {
|
|
234
|
+
// result.data.status: 'valid' | 'expired' | 'error' | 'notFound'
|
|
235
|
+
console.log("Token status:", result.data.status);
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Fetch Assistants
|
|
240
|
+
|
|
241
|
+
Get a list of all assistants or fetch a specific one:
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
// Fetch all assistants (paginated)
|
|
245
|
+
const list = await assistantAPI.fetchMany(1, 10, {});
|
|
246
|
+
|
|
247
|
+
// Fetch a specific assistant by ID or cuid
|
|
248
|
+
const assistant = await assistantAPI.fetch({ cuid: "user-unique-id-123" });
|
|
249
|
+
// or
|
|
250
|
+
const assistant = await assistantAPI.fetch({ id: "assistant-id" });
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Update an Assistant
|
|
254
|
+
|
|
255
|
+
Update assistant metadata or persona:
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
await assistantAPI.update("assistant-id", {
|
|
259
|
+
name: "Updated Name",
|
|
260
|
+
backstory: "New backstory",
|
|
261
|
+
metadata: { theme: "light" }
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Delete an Assistant
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
await assistantAPI.delete("assistant-id");
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Express Integration (Auth Server)
|
|
272
|
+
|
|
273
|
+
For seamless token management, you can integrate with Express to automatically handle token creation and validation:
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
import express from "express";
|
|
277
|
+
import { ttc } from "ttc-ai-chat-sdk";
|
|
278
|
+
|
|
279
|
+
const app = express();
|
|
280
|
+
|
|
281
|
+
ttc.assistantAPI("your-api-key", {
|
|
282
|
+
express: app,
|
|
283
|
+
endpoint: "/ttc-auth",
|
|
284
|
+
userData: async (req) => {
|
|
285
|
+
// Extract user info from your auth system
|
|
286
|
+
const user = await getUserFromRequest(req);
|
|
287
|
+
return {
|
|
288
|
+
cuid: user.id,
|
|
289
|
+
name: user.name,
|
|
290
|
+
option: {
|
|
291
|
+
backstory: "Helpful assistant for " + user.name,
|
|
292
|
+
metadata: { userId: user.id }
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
app.listen(3000);
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Then on the frontend, initialize the assistant with the auth URL:
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
const assistant = await ttc.assistant({
|
|
305
|
+
modules: [MyAppModule],
|
|
306
|
+
url: "http://localhost:3000/ttc-auth",
|
|
307
|
+
tokenCb: async () => {
|
|
308
|
+
// Return your platform's auth token
|
|
309
|
+
return localStorage.getItem("authToken");
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
176
314
|
## Full Documentation
|
|
177
315
|
|
|
178
316
|
For complete API reference, all available methods, and advanced configuration, check out the full SDK documentation.
|
package/dist/index.d.ts
CHANGED
|
@@ -226,16 +226,6 @@ export interface AssistantAPI {
|
|
|
226
226
|
*/
|
|
227
227
|
delete(assistantId: string): Promise<rpcResponseType<any>>;
|
|
228
228
|
}
|
|
229
|
-
export interface AssistantConfig {
|
|
230
|
-
/** Array of module classes to register */
|
|
231
|
-
modules: any[];
|
|
232
|
-
/** The authentication token for the chat session */
|
|
233
|
-
chatToken?: string;
|
|
234
|
-
/** Custom server URL */
|
|
235
|
-
url?: string;
|
|
236
|
-
/** Callback to retrieve token dynamically */
|
|
237
|
-
tokenCb?: () => Promise<string>;
|
|
238
|
-
}
|
|
239
229
|
export interface AuthServerOptions {
|
|
240
230
|
/** Express app instance */
|
|
241
231
|
express: any;
|
|
@@ -257,9 +247,22 @@ export interface TTC {
|
|
|
257
247
|
/**
|
|
258
248
|
* Initialize the assistant with configuration options
|
|
259
249
|
* @param config - Configuration object containing chatToken, modules, url, and tokenCb
|
|
250
|
+
* chatToken: The authentication token for the chat session, this is optional when you're using server-side managed tokens on your platform via tokenCb
|
|
251
|
+
* modules: An array of module classes to register with the assistant
|
|
252
|
+
* url: Your backend server url running the assistant management service
|
|
253
|
+
* tokenCb: A callback function to retrieve your platform token, you must implement this to return you token as this token would be provided in the userData callback on server
|
|
260
254
|
* @returns Promise resolving to the Assistant instance for interacting with the AI
|
|
261
255
|
*/
|
|
262
|
-
assistant(config?:
|
|
256
|
+
assistant(config?: {
|
|
257
|
+
/** Array of module classes to register */
|
|
258
|
+
modules: any[];
|
|
259
|
+
/** The authentication token for the chat session */
|
|
260
|
+
chatToken?: string;
|
|
261
|
+
/** Custom server URL */
|
|
262
|
+
url?: string;
|
|
263
|
+
/** Callback to retrieve token dynamically */
|
|
264
|
+
tokenCb?: () => Promise<string>;
|
|
265
|
+
}): Promise<Assistant>;
|
|
263
266
|
/**
|
|
264
267
|
* Decorator to describe a function that the AI can call
|
|
265
268
|
* @param config - Configuration for the function description
|
package/dist/utils/authClient.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AuthClient = void 0;
|
|
4
|
+
const storage_1 = require("./storage");
|
|
4
5
|
const AuthClient = async (chatToken, backendUrl, authCb) => {
|
|
5
6
|
try {
|
|
7
|
+
if (!chatToken) {
|
|
8
|
+
const token = await storage_1.storageUtil.getItem('ttc_chat_token');
|
|
9
|
+
if (token !== chatToken) {
|
|
10
|
+
await storage_1.storageUtil.setItem('ttc_chat_token', chatToken);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
6
13
|
if (chatToken) {
|
|
7
14
|
const validate = await ttcRequest(backendUrl, chatToken, 'validation');
|
|
8
15
|
if (!validate.ok) {
|
|
@@ -11,6 +18,7 @@ const AuthClient = async (chatToken, backendUrl, authCb) => {
|
|
|
11
18
|
const response = await validate.json();
|
|
12
19
|
if (response.status === 'success') {
|
|
13
20
|
if (response.data.status === 'valid') {
|
|
21
|
+
await storage_1.storageUtil.setItem('ttc_chat_token', response.data.token);
|
|
14
22
|
return response.data.token;
|
|
15
23
|
}
|
|
16
24
|
else {
|
|
@@ -27,6 +35,7 @@ const AuthClient = async (chatToken, backendUrl, authCb) => {
|
|
|
27
35
|
const responseData = await response.json();
|
|
28
36
|
console.log('AuthClient obtained new token', responseData);
|
|
29
37
|
if (responseData.status === 'success') {
|
|
38
|
+
await storage_1.storageUtil.setItem('ttc_chat_token', responseData.data.token);
|
|
30
39
|
return responseData.data.token;
|
|
31
40
|
}
|
|
32
41
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authClient.js","sourceRoot":"","sources":["../../src/utils/authClient.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"authClient.js","sourceRoot":"","sources":["../../src/utils/authClient.ts"],"names":[],"mappings":";;;AAAA,uCAAwC;AAMjC,MAAM,UAAU,GAAG,KAAK,EAAE,SAAiB,EAAE,UAAkB,EAAE,MAA8B,EAAmB,EAAE;IAEvH,IAAI;QAEA,IAAG,CAAC,SAAS,EAAC;YACV,MAAM,KAAK,GAAG,MAAM,qBAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YAE1D,IAAG,KAAK,KAAK,SAAS,EAAC;gBACnB,MAAM,qBAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;aAC1D;SACJ;QAED,IAAI,SAAS,EAAE;YACX,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,UAAU,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;YACvE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;gBACd,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;aAClF;YACD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACvC,IAAG,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE;gBAC9B,IAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE;oBACjC,MAAM,qBAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACjE,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;iBAC9B;qBAAM;oBACH,OAAO,CAAC,IAAI,CAAC,6CAA6C,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;iBAC9H;aACJ;SACJ;QAED,IAAI,MAAM,IAAI,UAAU,EAAE;YACtB,MAAM,KAAK,GAAG,MAAM,MAAM,EAAE,CAAC;YAE7B,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC/D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;gBACd,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;aAClF;YACD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,YAAY,CAAC,CAAC;YAC3D,IAAI,YAAY,CAAC,MAAM,KAAK,SAAS,EAAE;gBACnC,MAAM,qBAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrE,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;aAClC;iBAAM;gBACH,OAAO,IAAI,CAAC;aACf;SACJ;QAAA,CAAC;KAEL;IAAC,OAAO,KAAK,EAAE;QACZ,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;KACf;AACL,CAAC,CAAA;AAjDY,QAAA,UAAU,cAiDtB;AAED,MAAM,UAAU,GAAG,KAAK,EAAE,GAAW,EAAE,KAAa,EAAE,IAA6B,EAAE,EAAE;IACnF,MAAM,WAAW,GAAG,SAAS,IAAI,EAAE,CAAC;IACpC,OAAO,MAAM,KAAK,CAAC,GAAG,GAAG,GAAG,WAAW,EAAE,EAAE;QACvC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACL,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,EAAE;SACzE;KACJ,CAAC,CAAC;AACP,CAAC,CAAA"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.storageUtil = exports.StorageUtil = void 0;
|
|
4
|
+
class StorageUtil {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.store = {};
|
|
7
|
+
this.initialized = false;
|
|
8
|
+
this.loadStore();
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Simple encode function using character shifting and base64
|
|
12
|
+
*/
|
|
13
|
+
encode(data) {
|
|
14
|
+
// Shift characters
|
|
15
|
+
const shifted = data
|
|
16
|
+
.split('')
|
|
17
|
+
.map(char => String.fromCharCode(char.charCodeAt(0) + StorageUtil.CIPHER_OFFSET))
|
|
18
|
+
.join('');
|
|
19
|
+
// Base64 encode
|
|
20
|
+
if (typeof btoa !== 'undefined') {
|
|
21
|
+
return btoa(encodeURIComponent(shifted));
|
|
22
|
+
}
|
|
23
|
+
// Node.js fallback
|
|
24
|
+
return Buffer.from(encodeURIComponent(shifted)).toString('base64');
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Decode function to reverse the encoding
|
|
28
|
+
*/
|
|
29
|
+
decode(encoded) {
|
|
30
|
+
let decoded;
|
|
31
|
+
// Base64 decode
|
|
32
|
+
if (typeof atob !== 'undefined') {
|
|
33
|
+
decoded = decodeURIComponent(atob(encoded));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Node.js fallback
|
|
37
|
+
decoded = decodeURIComponent(Buffer.from(encoded, 'base64').toString('utf-8'));
|
|
38
|
+
}
|
|
39
|
+
// Reverse character shift
|
|
40
|
+
return decoded
|
|
41
|
+
.split('')
|
|
42
|
+
.map(char => String.fromCharCode(char.charCodeAt(0) - StorageUtil.CIPHER_OFFSET))
|
|
43
|
+
.join('');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Save the entire store to localStorage as an encoded blob
|
|
47
|
+
*/
|
|
48
|
+
async saveStore() {
|
|
49
|
+
if (typeof localStorage === 'undefined') {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const serialized = JSON.stringify(this.store);
|
|
54
|
+
const encoded = this.encode(serialized);
|
|
55
|
+
localStorage.setItem(StorageUtil.STORAGE_KEY, encoded);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.warn('Failed to save store:', error);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Load and decode the store from localStorage
|
|
63
|
+
*/
|
|
64
|
+
async loadStore() {
|
|
65
|
+
if (this.initialized)
|
|
66
|
+
return;
|
|
67
|
+
this.initialized = true;
|
|
68
|
+
if (typeof localStorage === 'undefined') {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const encoded = localStorage.getItem(StorageUtil.STORAGE_KEY);
|
|
73
|
+
if (encoded) {
|
|
74
|
+
const decoded = this.decode(encoded);
|
|
75
|
+
this.store = JSON.parse(decoded);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.warn('Failed to load store, starting fresh:', error);
|
|
80
|
+
this.store = {};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Set an item in the store
|
|
85
|
+
*/
|
|
86
|
+
async setItem(key, value) {
|
|
87
|
+
await this.loadStore();
|
|
88
|
+
this.store[key] = value;
|
|
89
|
+
await this.saveStore();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get an item from the store
|
|
93
|
+
*/
|
|
94
|
+
async getItem(key) {
|
|
95
|
+
await this.loadStore();
|
|
96
|
+
return this.store[key] ?? null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Remove an item from the store
|
|
100
|
+
*/
|
|
101
|
+
async removeItem(key) {
|
|
102
|
+
await this.loadStore();
|
|
103
|
+
delete this.store[key];
|
|
104
|
+
await this.saveStore();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Clear all items from the store
|
|
108
|
+
*/
|
|
109
|
+
async clear() {
|
|
110
|
+
this.store = {};
|
|
111
|
+
if (typeof localStorage !== 'undefined') {
|
|
112
|
+
localStorage.removeItem(StorageUtil.STORAGE_KEY);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.StorageUtil = StorageUtil;
|
|
117
|
+
StorageUtil.STORAGE_KEY = '_x9k2m_c7v3q_';
|
|
118
|
+
StorageUtil.CIPHER_OFFSET = 7;
|
|
119
|
+
exports.storageUtil = new StorageUtil();
|
|
120
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/utils/storage.ts"],"names":[],"mappings":"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"}
|