@redplanethq/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/LICENSE ADDED
@@ -0,0 +1,44 @@
1
+ Sol License
2
+
3
+ GNU AFFERO GENERAL PUBLIC LICENSE
4
+ Version 3, 19 November 2007
5
+
6
+ Copyright (c) 2025 — Poozle Inc.
7
+
8
+ This program is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU Affero General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU Affero General Public License for more details.
17
+
18
+ You should have received a copy of the GNU Affero General Public License
19
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
20
+
21
+ Additional Terms:
22
+
23
+ As additional permission under GNU AGPL version 3 section 7, you
24
+ may combine or link a "work that uses the Library" with a publicly
25
+ distributed version of this library to produce a combined library or
26
+ application, then distribute that combined work under the terms of
27
+ your choice, with no requirement to comply with the obligations
28
+ normally placed on you by section 4 of the GNU AGPL version 3
29
+ (or the corresponding section of a later version of the GNU AGPL
30
+ version 3 license).
31
+
32
+ "Commons Clause" License Condition v1.0
33
+
34
+ The Software is provided to you by the Licensor under the License (defined below), subject to the following condition:
35
+
36
+ Without limiting other conditions in the License, the grant of rights under the License will not include, and the License does not grant to you, the right to Sell the Software.
37
+
38
+ For purposes of the foregoing, "Sell" means practicing any or all of the rights granted to you under the License to provide the Software to third parties, for a fee or other consideration (including without limitation fees for hosting or consulting/support services related to the Software), as part of a product or service whose value derives, entirely or substantially, from the functionality of the Software. Any license notice or attribution required by the License must also include this Commons Clause License Condition notice.
39
+
40
+ Software: All files in this repository.
41
+
42
+ License: GNU Affero General Public License v3.0
43
+
44
+ Licensor: Poozle Inc.
package/README.md ADDED
@@ -0,0 +1,203 @@
1
+ # Echo SDK
2
+
3
+ The Echo SDK provides tools and utilities for building integrations with the Echo platform.
4
+
5
+ ## Integration System
6
+
7
+ The Echo integration system uses a CLI-based approach where each integration is a command-line tool that responds to specific events. This makes integrations portable, testable, and easy to debug.
8
+
9
+ ### Integration Event Types
10
+
11
+ Each integration CLI handles 5 core event types:
12
+
13
+ #### 1. `spec`
14
+ Returns the integration's metadata and configuration.
15
+
16
+ **Usage:**
17
+ ```bash
18
+ my-integration spec
19
+ ```
20
+
21
+ **Returns:** Integration specification including name, description, auth config, etc.
22
+
23
+ #### 2. `setup`
24
+ Processes authentication data and returns tokens/credentials to be saved.
25
+
26
+ **Usage:**
27
+ ```bash
28
+ my-integration setup --event-body '{"code":"oauth_code","state":"state"}' --integration-definition '{}'
29
+ ```
30
+
31
+ **Returns:** Configuration data (tokens, credentials) to be stored for the account.
32
+
33
+ #### 3. `identify`
34
+ Extracts accountId from webhook data to route webhooks to the correct account.
35
+
36
+ **Usage:**
37
+ ```bash
38
+ my-integration identify --webhook-data '{"team_id":"T123","event":{}}'
39
+ ```
40
+
41
+ **Returns:** Account identifier for webhook routing.
42
+
43
+ #### 4. `process`
44
+ Handles webhook events and returns activity data.
45
+
46
+ **Usage:**
47
+ ```bash
48
+ my-integration process --event-data '{"type":"reaction_added","reaction":"=M"}' --config '{"access_token":"token"}'
49
+ ```
50
+
51
+ **Returns:** Activity messages representing user actions.
52
+
53
+ #### 5. `sync`
54
+ Performs scheduled data synchronization for integrations that don't support webhooks.
55
+
56
+ **Usage:**
57
+ ```bash
58
+ my-integration sync --config '{"access_token":"token","last_sync":"2023-01-01T00:00:00Z"}'
59
+ ```
60
+
61
+ **Returns:** Activity messages and updated state for next sync.
62
+
63
+ ### Message Types
64
+
65
+ All integration responses are wrapped in a `Message` object with a `type` field:
66
+
67
+ - **`spec`** - Integration metadata and configuration
68
+ - **`activity`** - User actions/events from the integration
69
+ - **`state`** - Sync state for polling integrations
70
+ - **`identifier`** - Account identification for webhook routing
71
+
72
+ ### Building an Integration
73
+
74
+ 1. **Install the SDK:**
75
+ ```bash
76
+ npm install @echo/core-sdk
77
+ ```
78
+
79
+ 2. **Create your integration class:**
80
+ ```typescript
81
+ import { IntegrationCLI } from '@echo/core-sdk';
82
+
83
+ class MyIntegration extends IntegrationCLI {
84
+ constructor() {
85
+ super('my-integration', '1.0.0');
86
+ }
87
+
88
+ protected async handleEvent(eventPayload: IntegrationEventPayload): Promise<any> {
89
+ switch (eventPayload.event) {
90
+ case 'SETUP':
91
+ return this.handleSetup(eventPayload);
92
+ case 'PROCESS':
93
+ return this.handleProcess(eventPayload);
94
+ case 'IDENTIFY':
95
+ return this.handleIdentify(eventPayload);
96
+ case 'SYNC':
97
+ return this.handleSync(eventPayload);
98
+ default:
99
+ throw new Error(`Unknown event type: ${eventPayload.event}`);
100
+ }
101
+ }
102
+
103
+ protected async getSpec(): Promise<Spec> {
104
+ return {
105
+ name: 'My Integration',
106
+ key: 'my-integration',
107
+ description: 'Integration with My Service',
108
+ icon: 'https://example.com/icon.png',
109
+ auth: {
110
+ OAuth2: {
111
+ token_url: 'https://api.example.com/oauth/token',
112
+ authorization_url: 'https://api.example.com/oauth/authorize',
113
+ scopes: ['read', 'write']
114
+ }
115
+ }
116
+ };
117
+ }
118
+
119
+ private async handleSetup(eventPayload: IntegrationEventPayload): Promise<any> {
120
+ // Process OAuth response and return tokens to save
121
+ const { code } = eventPayload.eventBody;
122
+ // Exchange code for tokens...
123
+ return {
124
+ access_token: 'token',
125
+ refresh_token: 'refresh_token',
126
+ expires_at: Date.now() + 3600000
127
+ };
128
+ }
129
+
130
+ private async handleProcess(eventPayload: IntegrationEventPayload): Promise<any> {
131
+ // Handle webhook events
132
+ const { eventData } = eventPayload.eventBody;
133
+ // Process event and return activity...
134
+ return {
135
+ type: 'message',
136
+ user: 'user123',
137
+ content: 'Hello world',
138
+ timestamp: new Date()
139
+ };
140
+ }
141
+
142
+ private async handleIdentify(eventPayload: IntegrationEventPayload): Promise<any> {
143
+ // Extract account ID from webhook
144
+ const { team_id } = eventPayload.eventBody;
145
+ return { id: team_id };
146
+ }
147
+
148
+ private async handleSync(eventPayload: IntegrationEventPayload): Promise<any> {
149
+ // Perform scheduled sync
150
+ const { config } = eventPayload;
151
+ // Fetch data since last sync...
152
+ return {
153
+ activities: [/* activity data */],
154
+ state: { last_sync: new Date().toISOString() }
155
+ };
156
+ }
157
+ }
158
+
159
+ // CLI entry point
160
+ const integration = new MyIntegration();
161
+ integration.parse();
162
+ ```
163
+
164
+ 3. **Build and package your integration:**
165
+ ```bash
166
+ npm run build
167
+ npm pack
168
+ ```
169
+
170
+ ### Integration Development
171
+
172
+ The `IntegrationCLI` base class provides:
173
+
174
+ - **Automatic CLI setup** with all required commands
175
+ - **JSON input/output handling** for all event types
176
+ - **Error handling** with proper exit codes
177
+ - **Consistent message formatting** for all responses
178
+
179
+ ### Testing
180
+
181
+ Test your integration by running commands directly:
182
+
183
+ ```bash
184
+ # Test spec
185
+ node dist/index.js spec
186
+
187
+ # Test setup
188
+ node dist/index.js setup --event-body '{"code":"test"}' --integration-definition '{}'
189
+
190
+ # Test webhook processing
191
+ node dist/index.js process --event-data '{"type":"test"}' --config '{"token":"test"}'
192
+ ```
193
+
194
+ ### Best Practices
195
+
196
+ 1. **Always validate input data** before processing
197
+ 2. **Handle errors gracefully** with meaningful error messages
198
+ 3. **Use consistent data structures** for activities
199
+ 4. **Include proper timestamps** in all activity data
200
+ 5. **Store minimal state** for sync operations
201
+ 6. **Test all event types** thoroughly
202
+
203
+ For more examples, see the integrations in the `integrations/` directory.
@@ -0,0 +1,246 @@
1
+ import { Command } from 'commander';
2
+
3
+ declare enum LLMModelEnum {
4
+ GPT35TURBO = "GPT35TURBO",
5
+ GPT4TURBO = "GPT4TURBO",
6
+ GPT4O = "GPT4O",
7
+ GPT41 = "GPT41",
8
+ GPT41MINI = "GPT41MINI",
9
+ GPT41NANO = "GPT41NANO",
10
+ LLAMA3 = "LLAMA3",
11
+ CLAUDEOPUS = "CLAUDEOPUS",
12
+ CLAUDESONNET = "CLAUDESONNET",
13
+ CLAUDEHAIKU = "CLAUDEHAIKU",
14
+ GEMINI25FLASH = "GEMINI25FLASH",
15
+ GEMINI25PRO = "GEMINI25PRO",
16
+ GEMINI20FLASH = "GEMINI20FLASH",
17
+ GEMINI20FLASHLITE = "GEMINI20FLASHLITE"
18
+ }
19
+ declare enum LLMMappings {
20
+ GPT35TURBO = "gpt-3.5-turbo",
21
+ GPT4TURBO = "gpt-4-turbo",
22
+ GPT4O = "gpt-4o",
23
+ GPT41 = "gpt-4.1-2025-04-14",
24
+ GPT41MINI = "gpt-4.1-mini-2025-04-14",
25
+ GPT41NANO = "gpt-4.1-nano-2025-04-14",
26
+ LLAMA3 = "llama3",
27
+ CLAUDEOPUS = "claude-3-opus-20240229",
28
+ CLAUDESONNET = "claude-3-7-sonnet-20250219",
29
+ CLAUDEHAIKU = "claude-3-5-haiku-20241022",
30
+ GEMINI25FLASH = "gemini-2.5-flash-preview-04-17",
31
+ GEMINI25PRO = "gemini-2.5-pro-preview-03-25",
32
+ GEMINI20FLASH = "gemini-2.0-flash",
33
+ GEMINI20FLASHLITE = "gemini-2.0-flash-lite"
34
+ }
35
+ declare const OpenAIModels: LLMModelEnum[];
36
+ declare const ClaudeModels: LLMModelEnum[];
37
+ declare const GeminiModels: LLMModelEnum[];
38
+ declare const LLMModelType: {
39
+ GPT35TURBO: string;
40
+ GPT4TURBO: string;
41
+ GPT4O: string;
42
+ GPT41: string;
43
+ GPT41MINI: string;
44
+ GPT41NANO: string;
45
+ LLAMA3: string;
46
+ CLAUDEOPUS: string;
47
+ CLAUDESONNET: string;
48
+ CLAUDEHAIKU: string;
49
+ GEMINI25FLASH: string;
50
+ GEMINI25PRO: string;
51
+ GEMINI20FLASH: string;
52
+ GEMINI20FLASHLITE: string;
53
+ };
54
+ type LLMModelType = (typeof LLMModelType)[keyof typeof LLMModelType];
55
+
56
+ declare enum EpisodeType {
57
+ Conversation = "CONVERSATION",
58
+ Text = "TEXT"
59
+ }
60
+ /**
61
+ * Interface for episodic node in the reified knowledge graph
62
+ * Episodes are containers for statements and represent source information
63
+ */
64
+ interface EpisodicNode {
65
+ uuid: string;
66
+ content: string;
67
+ originalContent: string;
68
+ contentEmbedding?: number[];
69
+ metadata: Record<string, any>;
70
+ source: string;
71
+ createdAt: Date;
72
+ validAt: Date;
73
+ labels: string[];
74
+ userId: string;
75
+ space?: string;
76
+ sessionId?: string;
77
+ }
78
+ /**
79
+ * Interface for entity node in the reified knowledge graph
80
+ * Entities represent subjects, objects, or predicates in statements
81
+ */
82
+ interface EntityNode {
83
+ uuid: string;
84
+ name: string;
85
+ type: string;
86
+ attributes: Record<string, any>;
87
+ nameEmbedding: number[];
88
+ createdAt: Date;
89
+ userId: string;
90
+ space?: string;
91
+ }
92
+ /**
93
+ * Interface for statement node in the reified knowledge graph
94
+ * Statements are first-class objects representing facts with temporal properties
95
+ */
96
+ interface StatementNode {
97
+ uuid: string;
98
+ fact: string;
99
+ factEmbedding: number[];
100
+ createdAt: Date;
101
+ validAt: Date;
102
+ invalidAt: Date | null;
103
+ attributes: Record<string, any>;
104
+ userId: string;
105
+ space?: string;
106
+ }
107
+ /**
108
+ * Interface for a triple in the reified knowledge graph
109
+ * A triple connects a subject, predicate, object via a statement node
110
+ * and maintains provenance information
111
+ */
112
+ interface Triple {
113
+ statement: StatementNode;
114
+ subject: EntityNode;
115
+ predicate: EntityNode;
116
+ object: EntityNode;
117
+ provenance: EpisodicNode;
118
+ }
119
+ type AddEpisodeParams = {
120
+ episodeBody: string;
121
+ referenceTime: Date;
122
+ metadata: Record<string, any>;
123
+ source: string;
124
+ userId: string;
125
+ spaceId?: string;
126
+ sessionId?: string;
127
+ };
128
+ type AddEpisodeResult = {
129
+ episodeUuid: string;
130
+ nodesCreated: number;
131
+ statementsCreated: number;
132
+ processingTimeMs: number;
133
+ };
134
+
135
+ declare enum ActionStatusEnum {
136
+ ACCEPT = "ACCEPT",
137
+ DECLINE = "DECLINE",
138
+ QUESTION = "QUESTION",
139
+ TOOL_REQUEST = "TOOL_REQUEST",
140
+ SUCCESS = "SUCCESS",
141
+ FAILED = "FAILED"
142
+ }
143
+ declare const ActionStatus: {
144
+ ACCEPT: string;
145
+ DECLINE: string;
146
+ QUESTION: string;
147
+ TOOL_REQUEST: string;
148
+ SUCCESS: string;
149
+ FAILED: string;
150
+ };
151
+ type ActionStatus = (typeof ActionStatus)[keyof typeof ActionStatus];
152
+
153
+ declare class OAuth2Params {
154
+ authorization_url: string;
155
+ authorization_params?: Record<string, string>;
156
+ default_scopes?: string[];
157
+ scope_separator?: string;
158
+ scope_identifier?: string;
159
+ token_url: string;
160
+ token_params?: Record<string, string>;
161
+ redirect_uri_metadata?: string[];
162
+ token_response_metadata?: string[];
163
+ token_expiration_buffer?: number;
164
+ scopes?: string[];
165
+ }
166
+ type AuthType = "OAuth2" | "APIKey";
167
+ declare class APIKeyParams {
168
+ "header_name": string;
169
+ "format": string;
170
+ }
171
+
172
+ declare enum IntegrationEventType {
173
+ /**
174
+ * Processes authentication data and returns tokens/credentials to be saved
175
+ */
176
+ SETUP = "setup",
177
+ /**
178
+ * Processing incoming data from the integration
179
+ */
180
+ PROCESS = "process",
181
+ /**
182
+ * Identifying which account a webhook belongs to
183
+ */
184
+ IDENTIFY = "identify",
185
+ /**
186
+ * Scheduled synchronization of data
187
+ */
188
+ SYNC = "sync",
189
+ /**
190
+ * For returning integration metadata/config
191
+ */
192
+ SPEC = "spec"
193
+ }
194
+ interface IntegrationEventPayload {
195
+ event: IntegrationEventType;
196
+ [x: string]: any;
197
+ }
198
+ declare class Spec {
199
+ name: string;
200
+ key: string;
201
+ description: string;
202
+ icon: string;
203
+ mcp?: {
204
+ command: string;
205
+ args: string[];
206
+ env: Record<string, string>;
207
+ };
208
+ auth?: Record<string, OAuth2Params | APIKeyParams>;
209
+ }
210
+ interface Config {
211
+ access_token: string;
212
+ [key: string]: any;
213
+ }
214
+ interface Identifier {
215
+ id: string;
216
+ type?: string;
217
+ }
218
+ type MessageType = "spec" | "activity" | "state" | "identifier";
219
+ interface Message {
220
+ type: MessageType;
221
+ data: any;
222
+ }
223
+
224
+ declare enum UserTypeEnum {
225
+ Agent = "Agent",
226
+ User = "User",
227
+ System = "System"
228
+ }
229
+
230
+ declare abstract class IntegrationCLI {
231
+ protected program: Command;
232
+ protected integrationName: string;
233
+ protected version: string;
234
+ constructor(integrationName: string, version?: string);
235
+ private setupProgram;
236
+ private setupAccountCommands;
237
+ private setupDataCommands;
238
+ private setupSpecCommand;
239
+ private setupSyncCommand;
240
+ protected abstract handleEvent(eventPayload: IntegrationEventPayload): Promise<Message[]>;
241
+ protected abstract getSpec(): Promise<Spec>;
242
+ parse(): void;
243
+ getProgram(): Command;
244
+ }
245
+
246
+ export { APIKeyParams, ActionStatus, ActionStatusEnum, type AddEpisodeParams, type AddEpisodeResult, type AuthType, ClaudeModels, type Config, type EntityNode, EpisodeType, type EpisodicNode, GeminiModels, type Identifier, IntegrationCLI, type IntegrationEventPayload, IntegrationEventType, LLMMappings, LLMModelEnum, LLMModelType, type Message, type MessageType, OAuth2Params, OpenAIModels, Spec, type StatementNode, type Triple, UserTypeEnum };