@recursiv/sdk 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/LICENSE +105 -0
- package/README.md +331 -0
- package/dist/client.d.ts +22 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +192 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +29 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +60 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +148 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +184 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/sse.d.ts +6 -0
- package/dist/lib/sse.d.ts.map +1 -0
- package/dist/lib/sse.js +52 -0
- package/dist/lib/sse.js.map +1 -0
- package/dist/lib/webhooks.d.ts +41 -0
- package/dist/lib/webhooks.d.ts.map +1 -0
- package/dist/lib/webhooks.js +91 -0
- package/dist/lib/webhooks.js.map +1 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +2 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/useChat.d.ts +26 -0
- package/dist/react/useChat.d.ts.map +1 -0
- package/dist/react/useChat.js +111 -0
- package/dist/react/useChat.js.map +1 -0
- package/dist/realtime.d.ts +67 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +104 -0
- package/dist/realtime.js.map +1 -0
- package/dist/resources/admin.d.ts +287 -0
- package/dist/resources/admin.d.ts.map +1 -0
- package/dist/resources/admin.js +110 -0
- package/dist/resources/admin.js.map +1 -0
- package/dist/resources/agents.d.ts +136 -0
- package/dist/resources/agents.d.ts.map +1 -0
- package/dist/resources/agents.js +113 -0
- package/dist/resources/agents.js.map +1 -0
- package/dist/resources/auth.d.ts +68 -0
- package/dist/resources/auth.d.ts.map +1 -0
- package/dist/resources/auth.js +231 -0
- package/dist/resources/auth.js.map +1 -0
- package/dist/resources/billing.d.ts +143 -0
- package/dist/resources/billing.d.ts.map +1 -0
- package/dist/resources/billing.js +55 -0
- package/dist/resources/billing.js.map +1 -0
- package/dist/resources/brain.d.ts +26 -0
- package/dist/resources/brain.d.ts.map +1 -0
- package/dist/resources/brain.js +11 -0
- package/dist/resources/brain.js.map +1 -0
- package/dist/resources/chat.d.ts +52 -0
- package/dist/resources/chat.d.ts.map +1 -0
- package/dist/resources/chat.js +59 -0
- package/dist/resources/chat.js.map +1 -0
- package/dist/resources/commands.d.ts +41 -0
- package/dist/resources/commands.d.ts.map +1 -0
- package/dist/resources/commands.js +15 -0
- package/dist/resources/commands.js.map +1 -0
- package/dist/resources/communities.d.ts +19 -0
- package/dist/resources/communities.d.ts.map +1 -0
- package/dist/resources/communities.js +31 -0
- package/dist/resources/communities.js.map +1 -0
- package/dist/resources/databases.d.ts +58 -0
- package/dist/resources/databases.d.ts.map +1 -0
- package/dist/resources/databases.js +27 -0
- package/dist/resources/databases.js.map +1 -0
- package/dist/resources/deployments.d.ts +57 -0
- package/dist/resources/deployments.d.ts.map +1 -0
- package/dist/resources/deployments.js +31 -0
- package/dist/resources/deployments.js.map +1 -0
- package/dist/resources/dispatcher.d.ts +330 -0
- package/dist/resources/dispatcher.d.ts.map +1 -0
- package/dist/resources/dispatcher.js +155 -0
- package/dist/resources/dispatcher.js.map +1 -0
- package/dist/resources/email.d.ts +136 -0
- package/dist/resources/email.d.ts.map +1 -0
- package/dist/resources/email.js +51 -0
- package/dist/resources/email.js.map +1 -0
- package/dist/resources/free-tier.d.ts +59 -0
- package/dist/resources/free-tier.d.ts.map +1 -0
- package/dist/resources/free-tier.js +27 -0
- package/dist/resources/free-tier.js.map +1 -0
- package/dist/resources/github.d.ts +55 -0
- package/dist/resources/github.d.ts.map +1 -0
- package/dist/resources/github.js +23 -0
- package/dist/resources/github.js.map +1 -0
- package/dist/resources/inbox.d.ts +13 -0
- package/dist/resources/inbox.d.ts.map +1 -0
- package/dist/resources/inbox.js +11 -0
- package/dist/resources/inbox.js.map +1 -0
- package/dist/resources/integrations.d.ts +158 -0
- package/dist/resources/integrations.d.ts.map +1 -0
- package/dist/resources/integrations.js +78 -0
- package/dist/resources/integrations.js.map +1 -0
- package/dist/resources/invite-codes-admin.d.ts +69 -0
- package/dist/resources/invite-codes-admin.d.ts.map +1 -0
- package/dist/resources/invite-codes-admin.js +31 -0
- package/dist/resources/invite-codes-admin.js.map +1 -0
- package/dist/resources/invite-codes.d.ts +166 -0
- package/dist/resources/invite-codes.d.ts.map +1 -0
- package/dist/resources/invite-codes.js +69 -0
- package/dist/resources/invite-codes.js.map +1 -0
- package/dist/resources/jobs.d.ts +40 -0
- package/dist/resources/jobs.d.ts.map +1 -0
- package/dist/resources/jobs.js +23 -0
- package/dist/resources/jobs.js.map +1 -0
- package/dist/resources/media.d.ts +21 -0
- package/dist/resources/media.d.ts.map +1 -0
- package/dist/resources/media.js +11 -0
- package/dist/resources/media.js.map +1 -0
- package/dist/resources/memory.d.ts +116 -0
- package/dist/resources/memory.d.ts.map +1 -0
- package/dist/resources/memory.js +57 -0
- package/dist/resources/memory.js.map +1 -0
- package/dist/resources/network.d.ts +24 -0
- package/dist/resources/network.d.ts.map +1 -0
- package/dist/resources/network.js +11 -0
- package/dist/resources/network.js.map +1 -0
- package/dist/resources/notifications.d.ts +11 -0
- package/dist/resources/notifications.d.ts.map +1 -0
- package/dist/resources/notifications.js +36 -0
- package/dist/resources/notifications.js.map +1 -0
- package/dist/resources/organization-security.d.ts +29 -0
- package/dist/resources/organization-security.d.ts.map +1 -0
- package/dist/resources/organization-security.js +15 -0
- package/dist/resources/organization-security.js.map +1 -0
- package/dist/resources/organization-settings.d.ts +80 -0
- package/dist/resources/organization-settings.d.ts.map +1 -0
- package/dist/resources/organization-settings.js +35 -0
- package/dist/resources/organization-settings.js.map +1 -0
- package/dist/resources/organizations.d.ts +73 -0
- package/dist/resources/organizations.d.ts.map +1 -0
- package/dist/resources/organizations.js +63 -0
- package/dist/resources/organizations.js.map +1 -0
- package/dist/resources/posts.d.ts +28 -0
- package/dist/resources/posts.d.ts.map +1 -0
- package/dist/resources/posts.js +39 -0
- package/dist/resources/posts.js.map +1 -0
- package/dist/resources/profiles.d.ts +45 -0
- package/dist/resources/profiles.d.ts.map +1 -0
- package/dist/resources/profiles.js +55 -0
- package/dist/resources/profiles.js.map +1 -0
- package/dist/resources/project-brain.d.ts +239 -0
- package/dist/resources/project-brain.d.ts.map +1 -0
- package/dist/resources/project-brain.js +83 -0
- package/dist/resources/project-brain.js.map +1 -0
- package/dist/resources/projects.d.ts +37 -0
- package/dist/resources/projects.d.ts.map +1 -0
- package/dist/resources/projects.js +55 -0
- package/dist/resources/projects.js.map +1 -0
- package/dist/resources/protocols.d.ts +66 -0
- package/dist/resources/protocols.d.ts.map +1 -0
- package/dist/resources/protocols.js +31 -0
- package/dist/resources/protocols.js.map +1 -0
- package/dist/resources/sandbox.d.ts +12 -0
- package/dist/resources/sandbox.d.ts.map +1 -0
- package/dist/resources/sandbox.js +14 -0
- package/dist/resources/sandbox.js.map +1 -0
- package/dist/resources/settings.d.ts +52 -0
- package/dist/resources/settings.d.ts.map +1 -0
- package/dist/resources/settings.js +66 -0
- package/dist/resources/settings.js.map +1 -0
- package/dist/resources/simulator.d.ts +20 -0
- package/dist/resources/simulator.d.ts.map +1 -0
- package/dist/resources/simulator.js +23 -0
- package/dist/resources/simulator.js.map +1 -0
- package/dist/resources/storage.d.ts +82 -0
- package/dist/resources/storage.d.ts.map +1 -0
- package/dist/resources/storage.js +43 -0
- package/dist/resources/storage.js.map +1 -0
- package/dist/resources/swarms.d.ts +98 -0
- package/dist/resources/swarms.d.ts.map +1 -0
- package/dist/resources/swarms.js +53 -0
- package/dist/resources/swarms.js.map +1 -0
- package/dist/resources/tags.d.ts +19 -0
- package/dist/resources/tags.d.ts.map +1 -0
- package/dist/resources/tags.js +23 -0
- package/dist/resources/tags.js.map +1 -0
- package/dist/resources/templates.d.ts +62 -0
- package/dist/resources/templates.d.ts.map +1 -0
- package/dist/resources/templates.js +36 -0
- package/dist/resources/templates.js.map +1 -0
- package/dist/resources/uploads.d.ts +43 -0
- package/dist/resources/uploads.d.ts.map +1 -0
- package/dist/resources/uploads.js +39 -0
- package/dist/resources/uploads.js.map +1 -0
- package/dist/resources/users.d.ts +15 -0
- package/dist/resources/users.d.ts.map +1 -0
- package/dist/resources/users.js +23 -0
- package/dist/resources/users.js.map +1 -0
- package/dist/resources/wallet.d.ts +57 -0
- package/dist/resources/wallet.d.ts.map +1 -0
- package/dist/resources/wallet.js +43 -0
- package/dist/resources/wallet.js.map +1 -0
- package/dist/resources/webhooks.d.ts +29 -0
- package/dist/resources/webhooks.d.ts.map +1 -0
- package/dist/resources/webhooks.js +19 -0
- package/dist/resources/webhooks.js.map +1 -0
- package/dist/types.d.ts +703 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/llm.md +532 -0
- package/package.json +62 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export class WebhookVerificationError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = 'WebhookVerificationError';
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Validates a webhook signature, protecting against tampering and replay attacks.
|
|
9
|
+
* Designed to work in Node.js, Edge runtimes, and Cloudflare Workers.
|
|
10
|
+
*/
|
|
11
|
+
export async function verifyWebhookSignature({ payload, signatureHeader, secret, toleranceMs = 5 * 60 * 1000, }) {
|
|
12
|
+
if (!signatureHeader) {
|
|
13
|
+
throw new WebhookVerificationError('Missing signature header');
|
|
14
|
+
}
|
|
15
|
+
// Header format: t=1614264667,v1=a2b...
|
|
16
|
+
const parts = signatureHeader.split(',');
|
|
17
|
+
let timestamp;
|
|
18
|
+
let signature;
|
|
19
|
+
for (const part of parts) {
|
|
20
|
+
const [key, value] = part.split('=');
|
|
21
|
+
if (key === 't') {
|
|
22
|
+
timestamp = value;
|
|
23
|
+
}
|
|
24
|
+
else if (key === 'v1') {
|
|
25
|
+
signature = value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (!timestamp || !signature) {
|
|
29
|
+
throw new WebhookVerificationError('Invalid signature header format');
|
|
30
|
+
}
|
|
31
|
+
const timestampNum = parseInt(timestamp, 10);
|
|
32
|
+
if (isNaN(timestampNum)) {
|
|
33
|
+
throw new WebhookVerificationError('Invalid timestamp in signature header');
|
|
34
|
+
}
|
|
35
|
+
const now = Date.now();
|
|
36
|
+
// Check if timestamp is too old or too far in the future
|
|
37
|
+
if (Math.abs(now - timestampNum) > toleranceMs) {
|
|
38
|
+
throw new WebhookVerificationError('Webhook timestamp is outside of the tolerance zone (potential replay attack)');
|
|
39
|
+
}
|
|
40
|
+
const payloadStr = typeof payload === 'string' ? payload : new TextDecoder().decode(payload);
|
|
41
|
+
const payloadToSign = `${timestamp}.${payloadStr}`;
|
|
42
|
+
const encoder = new TextEncoder();
|
|
43
|
+
// Use Web Crypto API for edge compatibility
|
|
44
|
+
const crypto = globalThis.crypto;
|
|
45
|
+
if (!crypto || !crypto.subtle) {
|
|
46
|
+
throw new WebhookVerificationError('Web Crypto API is not available in this environment');
|
|
47
|
+
}
|
|
48
|
+
const key = await crypto.subtle.importKey('raw', encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);
|
|
49
|
+
const signatureBytes = hexToBytes(signature);
|
|
50
|
+
if (!signatureBytes) {
|
|
51
|
+
throw new WebhookVerificationError('Invalid signature encoding');
|
|
52
|
+
}
|
|
53
|
+
const isValid = await crypto.subtle.verify('HMAC', key, signatureBytes.buffer, encoder.encode(payloadToSign));
|
|
54
|
+
if (!isValid) {
|
|
55
|
+
throw new WebhookVerificationError('Invalid webhook signature');
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Parses and validates a webhook payload.
|
|
61
|
+
* Returns the typed event object. Checks idempotency using the event ID.
|
|
62
|
+
*/
|
|
63
|
+
export async function constructWebhookEvent(payload, signatureHeader, secret, toleranceMs) {
|
|
64
|
+
await verifyWebhookSignature({ payload, signatureHeader, secret, toleranceMs });
|
|
65
|
+
const payloadStr = typeof payload === 'string' ? payload : new TextDecoder().decode(payload);
|
|
66
|
+
let event;
|
|
67
|
+
try {
|
|
68
|
+
event = JSON.parse(payloadStr);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
throw new WebhookVerificationError('Invalid JSON payload');
|
|
72
|
+
}
|
|
73
|
+
if (!event || !event.id || !event.type) {
|
|
74
|
+
throw new WebhookVerificationError('Invalid event payload structure');
|
|
75
|
+
}
|
|
76
|
+
// The event ID itself acts as the idempotency key for webhooks
|
|
77
|
+
return { event, idempotencyKey: event.id };
|
|
78
|
+
}
|
|
79
|
+
function hexToBytes(hex) {
|
|
80
|
+
if (hex.length % 2 !== 0)
|
|
81
|
+
return null;
|
|
82
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
83
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
84
|
+
const val = parseInt(hex.substring(i * 2, i * 2 + 2), 16);
|
|
85
|
+
if (isNaN(val))
|
|
86
|
+
return null;
|
|
87
|
+
bytes[i] = val;
|
|
88
|
+
}
|
|
89
|
+
return bytes;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/lib/webhooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Recursiv } from '../index.js';
|
|
2
|
+
import type { ChatMessageEvent, ChatMessageEditEvent, ChatMessageDeleteEvent, TypingEvent, AgentThinkingEvent } from '../realtime.js';
|
|
3
|
+
export interface UseChatOptions {
|
|
4
|
+
conversationId?: string;
|
|
5
|
+
onMessage?: (msg: ChatMessageEvent) => void;
|
|
6
|
+
onEdit?: (msg: ChatMessageEditEvent) => void;
|
|
7
|
+
onDelete?: (msg: ChatMessageDeleteEvent) => void;
|
|
8
|
+
onTyping?: (event: TypingEvent) => void;
|
|
9
|
+
onAgentThinking?: (event: AgentThinkingEvent) => void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A React hook that manages WebSocket connections for a specific conversation.
|
|
13
|
+
* It will automatically connect, join the conversation room, and listen for events.
|
|
14
|
+
*
|
|
15
|
+
* @param recursiv The initialized Recursiv SDK client
|
|
16
|
+
* @param options Configuration for the chat connection
|
|
17
|
+
* @returns Functions to interact with the chat via WebSocket
|
|
18
|
+
*/
|
|
19
|
+
export declare function useChat(recursiv: Recursiv, options?: UseChatOptions): {
|
|
20
|
+
isConnected: boolean;
|
|
21
|
+
error: Error | null;
|
|
22
|
+
sendTyping: () => void;
|
|
23
|
+
fetchHistory: (limit?: number, cursor?: string) => Promise<import("../types.js").PaginatedResponse<import("../types.js").Message>>;
|
|
24
|
+
sendMessage: (content: string, replyToId?: string) => Promise<import("../types.js").SingleResponse<import("../types.js").SentMessage>>;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=useChat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/react/useChat.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEtI,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5C,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACvD;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE,cAAmB;;;;2BA+FxC,MAAM,WAAgB,MAAM;2BAK3B,MAAM,cAAc,MAAM;EAS1D"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A React hook that manages WebSocket connections for a specific conversation.
|
|
4
|
+
* It will automatically connect, join the conversation room, and listen for events.
|
|
5
|
+
*
|
|
6
|
+
* @param recursiv The initialized Recursiv SDK client
|
|
7
|
+
* @param options Configuration for the chat connection
|
|
8
|
+
* @returns Functions to interact with the chat via WebSocket
|
|
9
|
+
*/
|
|
10
|
+
export function useChat(recursiv, options = {}) {
|
|
11
|
+
const { conversationId, onMessage, onEdit, onDelete, onTyping, onAgentThinking } = options;
|
|
12
|
+
const [isConnected, setIsConnected] = React.useState(false);
|
|
13
|
+
const [error, setError] = React.useState(null);
|
|
14
|
+
// Store callbacks in refs to avoid constant re-subscriptions
|
|
15
|
+
const callbacksRef = React.useRef({
|
|
16
|
+
onMessage,
|
|
17
|
+
onEdit,
|
|
18
|
+
onDelete,
|
|
19
|
+
onTyping,
|
|
20
|
+
onAgentThinking
|
|
21
|
+
});
|
|
22
|
+
React.useEffect(() => {
|
|
23
|
+
callbacksRef.current = { onMessage, onEdit, onDelete, onTyping, onAgentThinking };
|
|
24
|
+
});
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
let mounted = true;
|
|
27
|
+
let cleanupFuncs = [];
|
|
28
|
+
const setupRealtime = async () => {
|
|
29
|
+
try {
|
|
30
|
+
await recursiv.realtime.connect();
|
|
31
|
+
if (!mounted)
|
|
32
|
+
return;
|
|
33
|
+
setIsConnected(true);
|
|
34
|
+
setError(null);
|
|
35
|
+
if (conversationId) {
|
|
36
|
+
recursiv.realtime.joinConversation(conversationId);
|
|
37
|
+
}
|
|
38
|
+
// Setup generic listeners that delegate to the ref'd callbacks
|
|
39
|
+
const unsubs = [
|
|
40
|
+
recursiv.realtime.onMessage((msg) => {
|
|
41
|
+
if (!conversationId || msg.conversationId === conversationId) {
|
|
42
|
+
callbacksRef.current.onMessage?.(msg);
|
|
43
|
+
}
|
|
44
|
+
}),
|
|
45
|
+
recursiv.realtime.onMessageEdit((msg) => {
|
|
46
|
+
if (!conversationId || msg.conversationId === conversationId) {
|
|
47
|
+
callbacksRef.current.onEdit?.(msg);
|
|
48
|
+
}
|
|
49
|
+
}),
|
|
50
|
+
recursiv.realtime.onMessageDelete((msg) => {
|
|
51
|
+
if (!conversationId || msg.conversationId === conversationId) {
|
|
52
|
+
callbacksRef.current.onDelete?.(msg);
|
|
53
|
+
}
|
|
54
|
+
}),
|
|
55
|
+
recursiv.realtime.onTyping((evt) => {
|
|
56
|
+
if (!conversationId || evt.conversationId === conversationId) {
|
|
57
|
+
callbacksRef.current.onTyping?.(evt);
|
|
58
|
+
}
|
|
59
|
+
}),
|
|
60
|
+
recursiv.realtime.onAgentThinking((evt) => {
|
|
61
|
+
if (!conversationId || evt.conversationId === conversationId) {
|
|
62
|
+
callbacksRef.current.onAgentThinking?.(evt);
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
];
|
|
66
|
+
cleanupFuncs = unsubs.filter(Boolean);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
if (mounted) {
|
|
70
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
71
|
+
setIsConnected(false);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
setupRealtime();
|
|
76
|
+
return () => {
|
|
77
|
+
mounted = false;
|
|
78
|
+
cleanupFuncs.forEach(fn => { fn(); });
|
|
79
|
+
if (conversationId) {
|
|
80
|
+
recursiv.realtime.leaveConversation(conversationId);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}, [recursiv, conversationId]);
|
|
84
|
+
const sendTyping = React.useCallback(() => {
|
|
85
|
+
if (conversationId && isConnected) {
|
|
86
|
+
recursiv.realtime.sendTyping(conversationId);
|
|
87
|
+
}
|
|
88
|
+
}, [conversationId, isConnected, recursiv]);
|
|
89
|
+
return {
|
|
90
|
+
isConnected,
|
|
91
|
+
error,
|
|
92
|
+
sendTyping,
|
|
93
|
+
// Provide a helper to fetch historical messages via REST
|
|
94
|
+
fetchHistory: async (limit = 50, cursor) => {
|
|
95
|
+
if (!conversationId)
|
|
96
|
+
throw new Error('No conversationId provided');
|
|
97
|
+
return recursiv.chat.messages(conversationId, { limit, cursor });
|
|
98
|
+
},
|
|
99
|
+
// Provide a helper to send messages via REST
|
|
100
|
+
sendMessage: async (content, replyToId) => {
|
|
101
|
+
if (!conversationId)
|
|
102
|
+
throw new Error('No conversationId provided');
|
|
103
|
+
return recursiv.chat.send({
|
|
104
|
+
conversation_id: conversationId,
|
|
105
|
+
content,
|
|
106
|
+
reply_to_id: replyToId
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=useChat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChat.js","sourceRoot":"","sources":["../../src/react/useChat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Socket } from 'socket.io-client';
|
|
2
|
+
import { HttpClient } from './client.js';
|
|
3
|
+
export interface ChatMessageEvent {
|
|
4
|
+
id: string;
|
|
5
|
+
conversationId: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
sender: {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
username?: string;
|
|
11
|
+
image?: string;
|
|
12
|
+
isAi?: boolean;
|
|
13
|
+
};
|
|
14
|
+
createdAt: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ChatMessageEditEvent {
|
|
17
|
+
id: string;
|
|
18
|
+
conversationId: string;
|
|
19
|
+
text?: string;
|
|
20
|
+
updatedAt?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface ChatMessageDeleteEvent {
|
|
23
|
+
id: string;
|
|
24
|
+
conversationId: string;
|
|
25
|
+
}
|
|
26
|
+
export interface TypingEvent {
|
|
27
|
+
conversationId: string;
|
|
28
|
+
userId: string;
|
|
29
|
+
userName?: string;
|
|
30
|
+
isTyping: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface AgentThinkingEvent {
|
|
33
|
+
conversationId: string;
|
|
34
|
+
agentId: string;
|
|
35
|
+
agentName: string;
|
|
36
|
+
agentUsername?: string;
|
|
37
|
+
agentImage?: string;
|
|
38
|
+
model?: string;
|
|
39
|
+
status: 'thinking' | 'generating' | 'done' | 'error';
|
|
40
|
+
tokenCount?: number;
|
|
41
|
+
elapsedMs?: number;
|
|
42
|
+
messageId?: string;
|
|
43
|
+
chunk?: string;
|
|
44
|
+
accumulatedContent?: string;
|
|
45
|
+
isContinuing?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare class RealtimeClient {
|
|
48
|
+
private socket;
|
|
49
|
+
private client;
|
|
50
|
+
private connectionPromise;
|
|
51
|
+
constructor(client: HttpClient);
|
|
52
|
+
/**
|
|
53
|
+
* Connects to the WebSocket server using a temporary WebSocket token
|
|
54
|
+
*/
|
|
55
|
+
connect(): Promise<Socket>;
|
|
56
|
+
disconnect(): void;
|
|
57
|
+
getSocket(): Socket | null;
|
|
58
|
+
joinConversation(conversationId: string): void;
|
|
59
|
+
leaveConversation(conversationId: string): void;
|
|
60
|
+
sendTyping(conversationId: string): void;
|
|
61
|
+
onMessage(callback: (msg: ChatMessageEvent) => void): (() => void) | undefined;
|
|
62
|
+
onMessageEdit(callback: (msg: ChatMessageEditEvent) => void): (() => void) | undefined;
|
|
63
|
+
onMessageDelete(callback: (msg: ChatMessageDeleteEvent) => void): (() => void) | undefined;
|
|
64
|
+
onTyping(callback: (event: TypingEvent) => void): (() => void) | undefined;
|
|
65
|
+
onAgentThinking(callback: (event: AgentThinkingEvent) => void): (() => void) | undefined;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=realtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../src/realtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAM,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,iBAAiB,CAAgC;gBAE7C,MAAM,EAAE,UAAU;IAI9B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAqDhC,UAAU;IAQV,SAAS,IAAI,MAAM,GAAG,IAAI;IAI1B,gBAAgB,CAAC,cAAc,EAAE,MAAM;IAMvC,iBAAiB,CAAC,cAAc,EAAE,MAAM;IAMxC,UAAU,CAAC,cAAc,EAAE,MAAM;IAMjC,SAAS,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;IAK9E,aAAa,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,oBAAoB,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;IAKtF,eAAe,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,sBAAsB,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;IAK1F,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;IAK1E,eAAe,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;CAIzF"}
|
package/dist/realtime.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { io } from 'socket.io-client';
|
|
2
|
+
export class RealtimeClient {
|
|
3
|
+
socket = null;
|
|
4
|
+
client;
|
|
5
|
+
connectionPromise = null;
|
|
6
|
+
constructor(client) {
|
|
7
|
+
this.client = client;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Connects to the WebSocket server using a temporary WebSocket token
|
|
11
|
+
*/
|
|
12
|
+
async connect() {
|
|
13
|
+
if (this.socket?.connected) {
|
|
14
|
+
return this.socket;
|
|
15
|
+
}
|
|
16
|
+
if (this.connectionPromise) {
|
|
17
|
+
return this.connectionPromise;
|
|
18
|
+
}
|
|
19
|
+
this.connectionPromise = (async () => {
|
|
20
|
+
try {
|
|
21
|
+
// Fetch a short-lived WS token via REST API
|
|
22
|
+
const response = await this.client.get('/trpc/sessionManagement.getWebSocketToken');
|
|
23
|
+
const token = response.result?.data?.token;
|
|
24
|
+
if (!token) {
|
|
25
|
+
throw new Error('Failed to fetch WebSocket token');
|
|
26
|
+
}
|
|
27
|
+
const socket = io(this.client.baseOrigin, {
|
|
28
|
+
path: '/socket.io',
|
|
29
|
+
transports: ['websocket', 'polling'],
|
|
30
|
+
auth: { token },
|
|
31
|
+
autoConnect: true,
|
|
32
|
+
reconnection: true,
|
|
33
|
+
});
|
|
34
|
+
this.socket = socket;
|
|
35
|
+
return await new Promise((resolve, reject) => {
|
|
36
|
+
socket.on('connect', () => {
|
|
37
|
+
resolve(socket);
|
|
38
|
+
});
|
|
39
|
+
socket.on('connect_error', (err) => {
|
|
40
|
+
socket.disconnect();
|
|
41
|
+
if (this.socket === socket) {
|
|
42
|
+
this.socket = null;
|
|
43
|
+
}
|
|
44
|
+
if (this.connectionPromise !== null) {
|
|
45
|
+
this.connectionPromise = null;
|
|
46
|
+
}
|
|
47
|
+
reject(err);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
this.connectionPromise = null;
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
})();
|
|
56
|
+
return this.connectionPromise;
|
|
57
|
+
}
|
|
58
|
+
disconnect() {
|
|
59
|
+
if (this.socket) {
|
|
60
|
+
this.socket.disconnect();
|
|
61
|
+
this.socket = null;
|
|
62
|
+
}
|
|
63
|
+
this.connectionPromise = null;
|
|
64
|
+
}
|
|
65
|
+
getSocket() {
|
|
66
|
+
return this.socket;
|
|
67
|
+
}
|
|
68
|
+
joinConversation(conversationId) {
|
|
69
|
+
if (this.socket?.connected) {
|
|
70
|
+
this.socket.emit('join_conversation', conversationId);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
leaveConversation(conversationId) {
|
|
74
|
+
if (this.socket?.connected) {
|
|
75
|
+
this.socket.emit('leave_conversation', conversationId);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
sendTyping(conversationId) {
|
|
79
|
+
if (this.socket?.connected) {
|
|
80
|
+
this.socket.emit('chat_typing', { conversationId });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
onMessage(callback) {
|
|
84
|
+
this.socket?.on('chat_message', callback);
|
|
85
|
+
return () => this.socket?.off('chat_message', callback);
|
|
86
|
+
}
|
|
87
|
+
onMessageEdit(callback) {
|
|
88
|
+
this.socket?.on('chat_message_edit', callback);
|
|
89
|
+
return () => this.socket?.off('chat_message_edit', callback);
|
|
90
|
+
}
|
|
91
|
+
onMessageDelete(callback) {
|
|
92
|
+
this.socket?.on('chat_message_delete', callback);
|
|
93
|
+
return () => this.socket?.off('chat_message_delete', callback);
|
|
94
|
+
}
|
|
95
|
+
onTyping(callback) {
|
|
96
|
+
this.socket?.on('chat_typing', callback);
|
|
97
|
+
return () => this.socket?.off('chat_typing', callback);
|
|
98
|
+
}
|
|
99
|
+
onAgentThinking(callback) {
|
|
100
|
+
this.socket?.on('agent_thinking', callback);
|
|
101
|
+
return () => this.socket?.off('agent_thinking', callback);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=realtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime.js","sourceRoot":"","sources":["../src/realtime.ts"],"names":[],"mappings":"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"}
|