convoai 1.5.3 → 1.6.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.
Files changed (63) hide show
  1. package/README.md +36 -9
  2. package/dist/src/commands/agent/chat.js +2 -4
  3. package/dist/src/commands/agent/chat.js.map +1 -1
  4. package/dist/src/commands/agent/join.js +2 -4
  5. package/dist/src/commands/agent/join.js.map +1 -1
  6. package/dist/src/commands/dev.d.ts +2 -0
  7. package/dist/src/commands/dev.js +73 -0
  8. package/dist/src/commands/dev.js.map +1 -0
  9. package/dist/src/commands/go.js +3 -8
  10. package/dist/src/commands/go.js.map +1 -1
  11. package/dist/src/commands/init.d.ts +2 -0
  12. package/dist/src/commands/init.js +326 -0
  13. package/dist/src/commands/init.js.map +1 -0
  14. package/dist/src/commands/openclaw.js +2 -4
  15. package/dist/src/commands/openclaw.js.map +1 -1
  16. package/dist/src/commands/quickstart.js +137 -56
  17. package/dist/src/commands/quickstart.js.map +1 -1
  18. package/dist/src/index.js +11 -0
  19. package/dist/src/index.js.map +1 -1
  20. package/dist/src/starters/web/server/convoai-api.d.ts +42 -0
  21. package/dist/src/starters/web/server/convoai-api.js +116 -0
  22. package/dist/src/starters/web/server/convoai-api.js.map +1 -0
  23. package/dist/src/starters/web/server/index.d.ts +1 -0
  24. package/dist/src/starters/web/server/index.js +85 -0
  25. package/dist/src/starters/web/server/index.js.map +1 -0
  26. package/dist/src/starters/web/server/routes/callback.d.ts +2 -0
  27. package/dist/src/starters/web/server/routes/callback.js +10 -0
  28. package/dist/src/starters/web/server/routes/callback.js.map +1 -0
  29. package/dist/src/starters/web/server/routes/knowledge.d.ts +2 -0
  30. package/dist/src/starters/web/server/routes/knowledge.js +15 -0
  31. package/dist/src/starters/web/server/routes/knowledge.js.map +1 -0
  32. package/dist/src/starters/web/server/routes/session.d.ts +2 -0
  33. package/dist/src/starters/web/server/routes/session.js +82 -0
  34. package/dist/src/starters/web/server/routes/session.js.map +1 -0
  35. package/dist/src/starters/web/server/routes/token.d.ts +2 -0
  36. package/dist/src/starters/web/server/routes/token.js +19 -0
  37. package/dist/src/starters/web/server/routes/token.js.map +1 -0
  38. package/dist/src/web/serve.d.ts +7 -0
  39. package/dist/src/web/serve.js +42 -0
  40. package/dist/src/web/serve.js.map +1 -0
  41. package/package.json +3 -1
  42. package/src/starters/web/.env.example +28 -0
  43. package/src/starters/web/README.md +81 -0
  44. package/src/starters/web/connectors/README.md +35 -0
  45. package/src/starters/web/frontend/app.js +352 -0
  46. package/src/starters/web/frontend/index.html +54 -0
  47. package/src/starters/web/frontend/style.css +241 -0
  48. package/src/starters/web/package.json +23 -0
  49. package/src/starters/web/python-server/.env.example +23 -0
  50. package/src/starters/web/python-server/README.md +37 -0
  51. package/src/starters/web/python-server/app.py +202 -0
  52. package/src/starters/web/python-server/requirements.txt +4 -0
  53. package/src/starters/web/python-server/token_builder.py +99 -0
  54. package/src/starters/web/server/convoai-api.ts +243 -0
  55. package/src/starters/web/server/index.ts +109 -0
  56. package/src/starters/web/server/routes/callback.ts +13 -0
  57. package/src/starters/web/server/routes/knowledge.ts +19 -0
  58. package/src/starters/web/server/routes/session.ts +122 -0
  59. package/src/starters/web/server/routes/token.ts +22 -0
  60. package/src/starters/web/server/tsconfig.json +14 -0
  61. package/src/web/chat-client.html +1 -1
  62. package/src/web/client.html +1 -1
  63. package/src/web/serve.ts +45 -0
@@ -0,0 +1,13 @@
1
+ // Webhook endpoint for ConvoAI Engine callbacks.
2
+ // Customize: add your webhook handling logic here.
3
+
4
+ import { Router } from 'express';
5
+
6
+ const router = Router();
7
+
8
+ router.post('/callback', (req, res) => {
9
+ console.log('[callback] Received webhook:', JSON.stringify(req.body, null, 2));
10
+ res.json({ received: true });
11
+ });
12
+
13
+ export default router;
@@ -0,0 +1,19 @@
1
+ // Knowledge base query endpoint.
2
+ // Customize: connect your knowledge base, RAG pipeline, or vector DB here.
3
+
4
+ import { Router } from 'express';
5
+
6
+ const router = Router();
7
+
8
+ router.post('/knowledge', (req, res) => {
9
+ const { query } = req.body || {};
10
+ console.log('[knowledge] Query:', query);
11
+
12
+ // Customize: replace with your knowledge base integration
13
+ res.json({
14
+ results: [],
15
+ message: 'Knowledge base not configured. Edit server/routes/knowledge.ts to connect yours.',
16
+ });
17
+ });
18
+
19
+ export default router;
@@ -0,0 +1,122 @@
1
+ import { Router } from 'express';
2
+ import { startAgent, stopAgent, interruptAgent, type StartAgentConfig } from '../convoai-api.js';
3
+
4
+ const router = Router();
5
+
6
+ // In-memory session store (single session for simplicity)
7
+ // Customize: replace with database or Redis for production
8
+ let currentSession: { agentId: string; channel: string } | null = null;
9
+
10
+ router.post('/session/start', async (req, res) => {
11
+ try {
12
+ if (currentSession) {
13
+ res.status(409).json({ error: 'Session already active. Stop it first.' });
14
+ return;
15
+ }
16
+
17
+ // Validate required credentials before attempting API calls
18
+ const required = ['AGORA_APP_ID', 'AGORA_APP_CERTIFICATE', 'AGORA_CUSTOMER_ID', 'AGORA_CUSTOMER_SECRET'];
19
+ const missing = required.filter(k => !process.env[k]);
20
+ if (missing.length > 0) {
21
+ res.status(503).json({
22
+ error: `Missing credentials: ${missing.join(', ')}. Edit .env and restart the server.`,
23
+ });
24
+ return;
25
+ }
26
+
27
+ const appId = process.env.AGORA_APP_ID!;
28
+ const appCertificate = process.env.AGORA_APP_CERTIFICATE!;
29
+ const customerId = process.env.AGORA_CUSTOMER_ID!;
30
+ const customerSecret = process.env.AGORA_CUSTOMER_SECRET!;
31
+ const region = process.env.AGORA_REGION || 'global';
32
+
33
+ const channel = `session-${Date.now().toString(36)}`;
34
+ const clientUid = Math.floor(Math.random() * 90000) + 10000;
35
+
36
+ const config: StartAgentConfig = {
37
+ appId,
38
+ appCertificate,
39
+ customerId,
40
+ customerSecret,
41
+ region,
42
+ channel,
43
+ clientUid,
44
+ llm: {
45
+ vendor: process.env.LLM_VENDOR,
46
+ model: process.env.LLM_MODEL,
47
+ apiKey: process.env.LLM_API_KEY,
48
+ url: process.env.LLM_URL,
49
+ style: process.env.LLM_STYLE,
50
+ },
51
+ tts: {
52
+ vendor: process.env.TTS_VENDOR,
53
+ params: process.env.TTS_PARAMS ? JSON.parse(process.env.TTS_PARAMS) : {},
54
+ },
55
+ asr: {
56
+ vendor: process.env.ASR_VENDOR,
57
+ language: process.env.ASR_LANGUAGE,
58
+ },
59
+ };
60
+
61
+ const result = await startAgent(config);
62
+ currentSession = { agentId: result.agentId, channel: result.channel };
63
+
64
+ res.json({
65
+ appId: result.appId,
66
+ channel: result.channel,
67
+ token: result.token,
68
+ uid: result.uid,
69
+ agentId: result.agentId,
70
+ });
71
+ } catch (err: unknown) {
72
+ const message = err instanceof Error ? err.message : 'Unknown error';
73
+ console.error('[session/start]', message);
74
+ res.status(500).json({ error: message });
75
+ }
76
+ });
77
+
78
+ router.post('/session/stop', async (req, res) => {
79
+ try {
80
+ if (!currentSession) {
81
+ res.status(404).json({ error: 'No active session' });
82
+ return;
83
+ }
84
+
85
+ const appId = process.env.AGORA_APP_ID!;
86
+ const customerId = process.env.AGORA_CUSTOMER_ID!;
87
+ const customerSecret = process.env.AGORA_CUSTOMER_SECRET!;
88
+ const region = process.env.AGORA_REGION || 'global';
89
+
90
+ await stopAgent(appId, currentSession.agentId, customerId, customerSecret, region);
91
+ currentSession = null;
92
+
93
+ res.json({ status: 'stopped' });
94
+ } catch (err: unknown) {
95
+ const message = err instanceof Error ? err.message : 'Unknown error';
96
+ console.error('[session/stop]', message);
97
+ currentSession = null;
98
+ res.status(500).json({ error: message });
99
+ }
100
+ });
101
+
102
+ router.post('/session/interrupt', async (req, res) => {
103
+ try {
104
+ if (!currentSession) {
105
+ res.status(404).json({ error: 'No active session' });
106
+ return;
107
+ }
108
+
109
+ const appId = process.env.AGORA_APP_ID!;
110
+ const customerId = process.env.AGORA_CUSTOMER_ID!;
111
+ const customerSecret = process.env.AGORA_CUSTOMER_SECRET!;
112
+ const region = process.env.AGORA_REGION || 'global';
113
+
114
+ await interruptAgent(appId, currentSession.agentId, customerId, customerSecret, region);
115
+ res.json({ status: 'interrupted' });
116
+ } catch (err: unknown) {
117
+ const message = err instanceof Error ? err.message : 'Unknown error';
118
+ res.status(500).json({ error: message });
119
+ }
120
+ });
121
+
122
+ export default router;
@@ -0,0 +1,22 @@
1
+ import { Router } from 'express';
2
+ import { generateToken } from '../convoai-api.js';
3
+
4
+ const router = Router();
5
+
6
+ router.get('/token', (req, res) => {
7
+ try {
8
+ const appId = process.env.AGORA_APP_ID!;
9
+ const appCertificate = process.env.AGORA_APP_CERTIFICATE!;
10
+ const channel = (req.query.channel as string) || `ch-${Date.now().toString(36)}`;
11
+ const uid = parseInt(req.query.uid as string, 10) || 0;
12
+
13
+ const token = generateToken(appId, appCertificate, channel, uid);
14
+
15
+ res.json({ token, channel, uid });
16
+ } catch (err: unknown) {
17
+ const message = err instanceof Error ? err.message : 'Unknown error';
18
+ res.status(500).json({ error: message });
19
+ }
20
+ });
21
+
22
+ export default router;
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "outDir": "../dist/server",
7
+ "rootDir": ".",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "declaration": true
12
+ },
13
+ "include": ["./**/*.ts"]
14
+ }
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html><head><title>ConvoAI Headless</title></head>
3
3
  <body>
4
- <script src="https://download.agora.io/sdk/release/AgoraRTC_N-4.22.0.js"></script>
4
+ <script src="/agora-sdk.js"></script>
5
5
  <script>
6
6
  const P = new URLSearchParams(location.search);
7
7
  const appId = P.get('appId');
@@ -42,7 +42,7 @@
42
42
  <p class="hint">Press Ctrl+C in the terminal to stop</p>
43
43
  </div>
44
44
 
45
- <script src="https://download.agora.io/sdk/release/AgoraRTC_N-4.22.0.js"></script>
45
+ <script src="/agora-sdk.js"></script>
46
46
  <script>
47
47
  const P = new URLSearchParams(location.search);
48
48
  const appId = P.get('appId');
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Shared HTTP handler that serves HTML pages + the Agora RTC SDK from npm.
3
+ * Using the npm package (agora-rtc-sdk-ng) instead of CDN ensures each
4
+ * `npm install convoai` counts as an npm download for the SDK.
5
+ */
6
+ import { readFileSync } from 'node:fs';
7
+ import { createRequire } from 'node:module';
8
+ import type { IncomingMessage, ServerResponse } from 'node:http';
9
+
10
+ const require = createRequire(import.meta.url);
11
+
12
+ let _sdkCache: Buffer | null = null;
13
+
14
+ function getSdkContent(): Buffer {
15
+ if (!_sdkCache) {
16
+ // Resolve the package main entry (exports "." → AgoraRTC_N-production.js)
17
+ // Using the subpath directly would throw ERR_PACKAGE_PATH_NOT_EXPORTED
18
+ const sdkPath = require.resolve('agora-rtc-sdk-ng');
19
+ _sdkCache = readFileSync(sdkPath);
20
+ }
21
+ return _sdkCache;
22
+ }
23
+
24
+ /**
25
+ * Returns an HTTP request handler that serves:
26
+ * - `/agora-sdk.js` → Agora RTC SDK from node_modules
27
+ * - Everything else → the provided HTML string
28
+ */
29
+ export function createWebHandler(html: string): (req: IncomingMessage, res: ServerResponse) => void {
30
+ return (req, res) => {
31
+ const pathname = (req.url || '/').split('?')[0];
32
+ if (pathname === '/agora-sdk.js') {
33
+ const sdk = getSdkContent();
34
+ res.writeHead(200, {
35
+ 'Content-Type': 'application/javascript; charset=utf-8',
36
+ 'Content-Length': sdk.length,
37
+ 'Cache-Control': 'public, max-age=86400',
38
+ });
39
+ res.end(sdk);
40
+ } else {
41
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
42
+ res.end(html);
43
+ }
44
+ };
45
+ }