orqo-node-sdk 0.1.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/client.js ADDED
@@ -0,0 +1,174 @@
1
+ /**
2
+ * OrqoClient — Admin-level client for the Orqo Gateway.
3
+ *
4
+ * Provides methods for managing instances (create, list, provision)
5
+ * using the Admin Token. Individual instances are represented by
6
+ * the OrqoInstance class.
7
+ */
8
+ import { OrqoError } from './types.js';
9
+ import { OrqoInstance } from './instance.js';
10
+ export class OrqoClient {
11
+ host;
12
+ adminToken;
13
+ _fetch;
14
+ retry;
15
+ constructor(config) {
16
+ this.host = config.host.replace(/\/+$/, '');
17
+ this.adminToken = config.adminToken;
18
+ this._fetch = config.fetch ?? globalThis.fetch;
19
+ this.retry = {
20
+ maxAttempts: 3,
21
+ backoffMs: 1000,
22
+ multiplier: 2,
23
+ retryOn: [429, 500, 502, 503, 504],
24
+ ...config.retry,
25
+ };
26
+ }
27
+ // --------------------------------------------------------------------------
28
+ // Private helpers
29
+ // --------------------------------------------------------------------------
30
+ async request(path, options = {}) {
31
+ const url = `${this.host}${path}`;
32
+ let lastError = null;
33
+ for (let attempt = 0; attempt <= this.retry.maxAttempts; attempt++) {
34
+ if (attempt > 0) {
35
+ const delay = this.retry.backoffMs * Math.pow(this.retry.multiplier, attempt - 1);
36
+ await new Promise(r => setTimeout(r, delay));
37
+ }
38
+ const res = await this._fetch(url, {
39
+ ...options,
40
+ headers: {
41
+ 'Content-Type': 'application/json',
42
+ 'Authorization': `Bearer ${this.adminToken}`,
43
+ ...options.headers,
44
+ },
45
+ });
46
+ if (!res.ok) {
47
+ const body = await res.json().catch(() => null);
48
+ lastError = new OrqoError(body?.error ?? `HTTP ${res.status}`, res.status, body);
49
+ // Only retry on specific status codes
50
+ if (this.retry.retryOn.includes(res.status) && attempt < this.retry.maxAttempts) {
51
+ continue;
52
+ }
53
+ throw lastError;
54
+ }
55
+ return res.json();
56
+ }
57
+ throw lastError ?? new OrqoError('Max retries exceeded', 0);
58
+ }
59
+ // --------------------------------------------------------------------------
60
+ // Instance Management
61
+ // --------------------------------------------------------------------------
62
+ /** List all instances. */
63
+ async listInstances() {
64
+ return this.request('/api/admin/instances');
65
+ }
66
+ /**
67
+ * Quick-Provision: Create an instance, boot WhatsApp, and return QR code
68
+ * in a single call. Returns an OrqoInstance ready for interaction.
69
+ */
70
+ async provision(options) {
71
+ const result = await this.request('/api/admin/quick-provision', {
72
+ method: 'POST',
73
+ body: JSON.stringify(options),
74
+ });
75
+ const instance = new OrqoInstance({
76
+ host: this.host,
77
+ instanceId: result.instanceId,
78
+ apiToken: result.apiToken,
79
+ fetch: this._fetch,
80
+ retry: this.retry,
81
+ });
82
+ return { instance, result };
83
+ }
84
+ /**
85
+ * Get an OrqoInstance handle for an existing instance.
86
+ * Does NOT validate the instance exists — use listInstances() first.
87
+ */
88
+ getInstance(instanceId, apiToken) {
89
+ return new OrqoInstance({
90
+ host: this.host,
91
+ instanceId,
92
+ apiToken,
93
+ fetch: this._fetch,
94
+ retry: this.retry,
95
+ });
96
+ }
97
+ /**
98
+ * Delete an instance.
99
+ */
100
+ async deleteInstance(instanceId) {
101
+ await this.request(`/api/admin/instances/${instanceId}`, {
102
+ method: 'DELETE',
103
+ });
104
+ }
105
+ // --------------------------------------------------------------------------
106
+ // Instance Discovery
107
+ // --------------------------------------------------------------------------
108
+ /** Search instances by query string. */
109
+ async searchInstances(query) {
110
+ return this.request(`/api/admin/instances/search?q=${encodeURIComponent(query)}`);
111
+ }
112
+ /** Get a single instance by ID (admin detail view). */
113
+ async getInstanceById(instanceId) {
114
+ return this.request(`/api/admin/instances/${instanceId}`);
115
+ }
116
+ /** Update instance metadata (name, etc). */
117
+ async updateInstance(instanceId, updates) {
118
+ return this.request(`/api/admin/instances/${instanceId}`, {
119
+ method: 'PATCH',
120
+ body: JSON.stringify(updates),
121
+ });
122
+ }
123
+ // --------------------------------------------------------------------------
124
+ // Instance Settings
125
+ // --------------------------------------------------------------------------
126
+ /** Get full instance settings. */
127
+ async getInstanceSettings(instanceId) {
128
+ return this.request(`/api/admin/instances/${instanceId}/settings`);
129
+ }
130
+ /** Update instance settings. */
131
+ async updateInstanceSettings(instanceId, settings) {
132
+ return this.request(`/api/admin/instances/${instanceId}/settings`, {
133
+ method: 'PUT',
134
+ body: JSON.stringify(settings),
135
+ });
136
+ }
137
+ // --------------------------------------------------------------------------
138
+ // Security
139
+ // --------------------------------------------------------------------------
140
+ /** Rotate API token for an instance. Returns the new token. */
141
+ async rotateToken(instanceId) {
142
+ return this.request(`/api/admin/instances/${instanceId}/rotate-token`, {
143
+ method: 'POST',
144
+ });
145
+ }
146
+ // --------------------------------------------------------------------------
147
+ // LGPD / Data Subject Requests
148
+ // --------------------------------------------------------------------------
149
+ /** Delete a contact's data (LGPD/GDPR DSR). */
150
+ async deleteContact(instanceId, contactId) {
151
+ await this.request(`/api/admin/instances/${instanceId}/dsr/contact/${contactId}`, {
152
+ method: 'DELETE',
153
+ });
154
+ }
155
+ // --------------------------------------------------------------------------
156
+ // AI Instance Config Generation
157
+ // --------------------------------------------------------------------------
158
+ /** Generate a full instance configuration using AI. */
159
+ async generateInstanceConfig(config) {
160
+ return this.request('/api/admin/ai/instance-config', {
161
+ method: 'POST',
162
+ body: JSON.stringify(config),
163
+ });
164
+ }
165
+ // --------------------------------------------------------------------------
166
+ // Secrets Management
167
+ // --------------------------------------------------------------------------
168
+ /** Rotate (re-generate) a secret by key. Returns the new secret value. */
169
+ async rotateSecret(secretKey) {
170
+ return this.request(`/api/admin/super/secrets/${encodeURIComponent(secretKey)}/rotate`, {
171
+ method: 'POST',
172
+ });
173
+ }
174
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @orqo/sdk — Plug-and-Play WhatsApp Integration
3
+ *
4
+ * Zero-dependency TypeScript SDK for the Orqo Gateway.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { OrqoClient } from '@orqo/sdk';
9
+ *
10
+ * const orqo = new OrqoClient({
11
+ * host: 'https://orqo.example.com',
12
+ * adminToken: 'your-admin-token',
13
+ * });
14
+ *
15
+ * // Provision a new instance with WhatsApp
16
+ * const { instance, result } = await orqo.provision({
17
+ * name: 'My Bot',
18
+ * webhookUrl: 'https://your-app.com/webhooks',
19
+ * });
20
+ *
21
+ * // Wait for QR scan (with live QR callback)
22
+ * await instance.waitForConnection({
23
+ * onQr: (qr) => console.log('Scan this QR:', qr),
24
+ * });
25
+ *
26
+ * // Send a message
27
+ * await instance.sendMessage({
28
+ * to: '5511999887766@s.whatsapp.net',
29
+ * text: 'Hello from Orqo! 🚀',
30
+ * });
31
+ * ```
32
+ */
33
+ export { OrqoClient } from './client.js';
34
+ export { OrqoInstance } from './instance.js';
35
+ export { createWebhookHandler } from './webhook-handler.js';
36
+ export { OrqoError, type OrqoClientConfig, type OrqoInstanceConfig, type RetryConfig, type ProvisionOptions, type ProvisionResult, type WhatsAppStatus, type SendMessageOptions, type SendMessageResult, type InstanceStatus, type AgentConfig, type Agent, type WebhookConfig, type Webhook, type GuardrailConfig, type HandoffOptions, type HandoffResult, type WebhookEvent, type ConnectionChangedEvent, type MessageReceivedEvent, type MessageProcessedEvent, type HandoffEvent, type OrqoWebhookEvent, type WebhookHandlerOptions, } from './types.js';
package/dist/index.js ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @orqo/sdk — Plug-and-Play WhatsApp Integration
3
+ *
4
+ * Zero-dependency TypeScript SDK for the Orqo Gateway.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { OrqoClient } from '@orqo/sdk';
9
+ *
10
+ * const orqo = new OrqoClient({
11
+ * host: 'https://orqo.example.com',
12
+ * adminToken: 'your-admin-token',
13
+ * });
14
+ *
15
+ * // Provision a new instance with WhatsApp
16
+ * const { instance, result } = await orqo.provision({
17
+ * name: 'My Bot',
18
+ * webhookUrl: 'https://your-app.com/webhooks',
19
+ * });
20
+ *
21
+ * // Wait for QR scan (with live QR callback)
22
+ * await instance.waitForConnection({
23
+ * onQr: (qr) => console.log('Scan this QR:', qr),
24
+ * });
25
+ *
26
+ * // Send a message
27
+ * await instance.sendMessage({
28
+ * to: '5511999887766@s.whatsapp.net',
29
+ * text: 'Hello from Orqo! 🚀',
30
+ * });
31
+ * ```
32
+ */
33
+ export { OrqoClient } from './client.js';
34
+ export { OrqoInstance } from './instance.js';
35
+ export { createWebhookHandler } from './webhook-handler.js';
36
+ export { OrqoError, } from './types.js';
@@ -0,0 +1,166 @@
1
+ /**
2
+ * OrqoInstance — Represents a single provisioned instance.
3
+ *
4
+ * Provides typed methods for WhatsApp, Agents, Webhooks,
5
+ * Guardrails, Handoff, and API Bridge — scoped to a specific
6
+ * instance + API token.
7
+ */
8
+ import type { OrqoInstanceConfig, WhatsAppStatus, SendMessageOptions, SendMessageResult, InstanceStatus, AgentConfig, Agent, WebhookConfig, Webhook, GuardrailConfig, HandoffOptions, HandoffResult } from './types.js';
9
+ export declare class OrqoInstance {
10
+ readonly instanceId: string;
11
+ private readonly host;
12
+ private readonly apiToken;
13
+ private readonly _fetch;
14
+ private readonly retry;
15
+ constructor(config: OrqoInstanceConfig);
16
+ private request;
17
+ /** Get the current status of this instance. */
18
+ getStatus(): Promise<InstanceStatus>;
19
+ /** Get WhatsApp connection status and QR code (if available). */
20
+ getWhatsAppStatus(): Promise<WhatsAppStatus>;
21
+ /** Start the WhatsApp socket (begins QR code generation). */
22
+ connectWhatsApp(): Promise<InstanceStatus>;
23
+ /** Disconnect WhatsApp. */
24
+ disconnectWhatsApp(): Promise<void>;
25
+ /** Request a pairing code for phone-number-based linking. */
26
+ pairByPhone(phoneNumber: string): Promise<{
27
+ code: string;
28
+ }>;
29
+ /**
30
+ * Poll for WhatsApp connection, resolving when connected.
31
+ *
32
+ * @param intervalMs - Polling interval in milliseconds (default: 3000)
33
+ * @param timeoutMs - Maximum wait time in milliseconds (default: 120000)
34
+ * @param onQr - Optional callback invoked each time a new QR is available
35
+ * @returns The final WhatsApp status (connected)
36
+ */
37
+ waitForConnection(options?: {
38
+ intervalMs?: number;
39
+ timeoutMs?: number;
40
+ onQr?: (qr: string) => void;
41
+ }): Promise<WhatsAppStatus>;
42
+ /** Send a text message via WhatsApp. */
43
+ sendMessage(options: SendMessageOptions): Promise<SendMessageResult>;
44
+ /** Create a new agent for this instance. */
45
+ createAgent(config: AgentConfig): Promise<Agent>;
46
+ /** List all agents. */
47
+ listAgents(): Promise<Agent[]>;
48
+ /** Update an existing agent. */
49
+ updateAgent(agentId: string, updates: Partial<AgentConfig>): Promise<Agent>;
50
+ /** Delete an agent. */
51
+ deleteAgent(agentId: string): Promise<void>;
52
+ /** Register a webhook to receive events. */
53
+ addWebhook(config: WebhookConfig): Promise<Webhook>;
54
+ /** List all registered webhooks. */
55
+ listWebhooks(): Promise<Webhook[]>;
56
+ /** Remove a webhook. */
57
+ removeWebhook(webhookId: string): Promise<void>;
58
+ /** Set guardrail configuration for AI responses. */
59
+ setGuardrails(config: GuardrailConfig): Promise<GuardrailConfig>;
60
+ /** Get current guardrail configuration. */
61
+ getGuardrails(): Promise<GuardrailConfig>;
62
+ /** Hand off a conversation to a human agent. */
63
+ handoffToHuman(options: HandoffOptions): Promise<HandoffResult>;
64
+ /** Resume bot control of a conversation after human handoff. */
65
+ resumeBot(sessionId: string): Promise<HandoffResult>;
66
+ /** Get instance statistics (messages, sessions, uptime). */
67
+ getStats(): Promise<Record<string, unknown>>;
68
+ /** Get conversation sessions with pagination. */
69
+ getSessions(options?: {
70
+ limit?: number;
71
+ offset?: number;
72
+ }): Promise<Array<Record<string, unknown>>>;
73
+ /** Get messages for a session or all messages. */
74
+ getMessages(options?: {
75
+ sessionKey?: string;
76
+ limit?: number;
77
+ }): Promise<Array<Record<string, unknown>>>;
78
+ /** Force reconnect WhatsApp (useful for stale connections). */
79
+ reconnectWhatsApp(): Promise<InstanceStatus>;
80
+ /** Get a specific agent by ID. */
81
+ getAgent(agentId: string): Promise<Agent>;
82
+ /** List cron jobs for this instance. */
83
+ listCronJobs(): Promise<Array<Record<string, unknown>>>;
84
+ /** Create a new cron job. */
85
+ createCronJob(config: {
86
+ schedule: string;
87
+ action: string;
88
+ payload?: Record<string, unknown>;
89
+ }): Promise<Record<string, unknown>>;
90
+ /** Delete a cron job. */
91
+ deleteCronJob(jobId: string): Promise<void>;
92
+ /** Manually trigger a cron job. */
93
+ runCronJob(jobId: string): Promise<Record<string, unknown>>;
94
+ /**
95
+ * Connect an external API via OpenAPI spec.
96
+ * The agent will automatically gain tools from the spec.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * await instance.connectApi({
101
+ * name: 'comanda-api',
102
+ * specUrl: 'https://api.comanda.app/openapi.json',
103
+ * auth: { type: 'bearer', token: 'client-key' },
104
+ * });
105
+ * ```
106
+ */
107
+ connectApi(options: {
108
+ name: string;
109
+ specUrl?: string;
110
+ specInline?: Record<string, unknown>;
111
+ auth?: {
112
+ type: 'bearer' | 'apiKey' | 'basic' | 'custom';
113
+ token?: string;
114
+ headerName?: string;
115
+ username?: string;
116
+ password?: string;
117
+ headers?: Record<string, string>;
118
+ };
119
+ baseUrl?: string;
120
+ timeoutMs?: number;
121
+ refreshIntervalMs?: number;
122
+ description?: string;
123
+ }): Promise<{
124
+ bridge: Record<string, unknown>;
125
+ tools: string[];
126
+ }>;
127
+ /** List all connected API Bridges. */
128
+ listApiBridges(): Promise<Array<Record<string, unknown> & {
129
+ tools: string[];
130
+ }>>;
131
+ /** Remove an API Bridge by ID. */
132
+ removeApiBridge(bridgeId: string): Promise<{
133
+ success: boolean;
134
+ }>;
135
+ /** Refresh an API Bridge (re-fetch OpenAPI spec and update tools). */
136
+ refreshApiBridge(bridgeId: string): Promise<{
137
+ bridge: Record<string, unknown>;
138
+ tools: string[];
139
+ }>;
140
+ /** Update an existing webhook configuration. */
141
+ updateWebhook(webhookId: string, updates: Record<string, unknown>): Promise<Record<string, unknown>>;
142
+ /** Send a test event to a webhook endpoint. */
143
+ testWebhook(webhookId: string): Promise<Record<string, unknown>>;
144
+ /** Update an existing cron job. */
145
+ updateCronJob(jobId: string, updates: Record<string, unknown>): Promise<Record<string, unknown>>;
146
+ /** Get resource limits and current usage. */
147
+ getLimits(): Promise<Record<string, unknown>>;
148
+ /** Create a backup of this instance. */
149
+ backup(): Promise<Record<string, unknown>>;
150
+ /** Generate an agent configuration using AI. */
151
+ generateAgent(config: {
152
+ name: string;
153
+ description: string;
154
+ context: string;
155
+ language?: string;
156
+ }): Promise<Agent>;
157
+ /** List all background jobs for this instance. */
158
+ listBackgroundJobs(): Promise<Record<string, unknown>[]>;
159
+ /** Get a specific background job by ID. */
160
+ getBackgroundJob(jobId: string): Promise<Record<string, unknown>>;
161
+ /** Create a new background job. */
162
+ createBackgroundJob(config: {
163
+ agentId: string;
164
+ input: string;
165
+ }): Promise<Record<string, unknown>>;
166
+ }