gambiarra-sdk 0.1.4

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 ADDED
@@ -0,0 +1,356 @@
1
+ # gambiarra
2
+
3
+ [![npm version](https://img.shields.io/npm/v/gambiarra)](https://www.npmjs.com/package/gambiarra)
4
+ [![npm downloads](https://img.shields.io/npm/dm/gambiarra)](https://www.npmjs.com/package/gambiarra)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ TypeScript SDK for Gambiarra - a distributed LLM coordination system.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install gambiarra
13
+ ```
14
+
15
+ or
16
+
17
+ ```bash
18
+ bun add gambiarra
19
+ ```
20
+
21
+ or
22
+
23
+ ```bash
24
+ pnpm add gambiarra
25
+ ```
26
+
27
+ ## Overview
28
+
29
+ The SDK provides organized namespaces for interacting with Gambiarra hubs:
30
+
31
+ - **`rooms`** - Manage rooms and participants
32
+ - **`participants`** - Create and configure participants
33
+ - **`hub`** - Create and manage hubs
34
+ - **`createClient`** - HTTP client for remote hubs
35
+ - **Types** - Full TypeScript type definitions
36
+
37
+ ## Quick Start
38
+
39
+ ### Creating a Local Hub
40
+
41
+ ```typescript
42
+ import { hub, rooms, participants } from "gambiarra";
43
+
44
+ // Create a hub
45
+ const myHub = hub.create({ port: 3000 });
46
+ console.log(`Hub running at ${myHub.url}`);
47
+
48
+ // Create a room
49
+ const room = rooms.create("My AI Room", "host-id-123");
50
+ console.log(`Room code: ${room.code}`);
51
+
52
+ // Create and add a participant
53
+ const participant = participants.create({
54
+ nickname: "Local Ollama",
55
+ model: "llama3",
56
+ endpoint: "http://localhost:11434",
57
+ specs: {
58
+ gpu: "RTX 4090",
59
+ vram: 24,
60
+ },
61
+ });
62
+
63
+ rooms.addParticipant(room.id, participant);
64
+ ```
65
+
66
+ ### Using the HTTP Client
67
+
68
+ Connect to a remote Gambiarra hub:
69
+
70
+ ```typescript
71
+ import { createClient } from "gambiarra";
72
+
73
+ const client = createClient({ hubUrl: "http://hub.example.com:3000" });
74
+
75
+ // Create a room
76
+ const { room, hostId } = await client.create("Remote Room");
77
+
78
+ // Join the room
79
+ await client.join(room.code, {
80
+ id: "participant-1",
81
+ nickname: "My Bot",
82
+ model: "gpt-4",
83
+ endpoint: "http://localhost:11434",
84
+ });
85
+
86
+ // Get participants
87
+ const participants = await client.getParticipants(room.code);
88
+
89
+ // Health check
90
+ await client.healthCheck(room.code, "participant-1");
91
+
92
+ // Leave the room
93
+ await client.leave(room.code, "participant-1");
94
+ ```
95
+
96
+ ### With Vercel AI SDK
97
+
98
+ Use Gambiarra as an AI provider:
99
+
100
+ ```typescript
101
+ import { createGambiarra } from "gambiarra";
102
+ import { generateText } from "ai";
103
+
104
+ const gambiarra = createGambiarra({ roomCode: "ABC123" });
105
+
106
+ const result = await generateText({
107
+ model: gambiarra.any(), // Random online participant
108
+ prompt: "Hello, world!",
109
+ });
110
+ ```
111
+
112
+ ## API Reference
113
+
114
+ ### `rooms`
115
+
116
+ Manage rooms and participants:
117
+
118
+ ```typescript
119
+ // Create a room
120
+ const room = rooms.create(name, hostId);
121
+
122
+ // Get rooms
123
+ const room = rooms.get(id);
124
+ const room = rooms.getByCode(code);
125
+ const allRooms = rooms.list();
126
+ const roomsWithCount = rooms.listWithParticipantCount();
127
+
128
+ // Remove a room
129
+ rooms.remove(id);
130
+
131
+ // Participant management
132
+ rooms.addParticipant(roomId, participant);
133
+ rooms.removeParticipant(roomId, participantId);
134
+ rooms.getParticipants(roomId);
135
+ rooms.getParticipant(roomId, participantId);
136
+ rooms.updateParticipantStatus(roomId, participantId, status);
137
+ rooms.updateLastSeen(roomId, participantId);
138
+
139
+ // Find participants
140
+ rooms.findParticipantByModel(roomId, modelName);
141
+ rooms.getRandomOnlineParticipant(roomId);
142
+
143
+ // Maintenance
144
+ rooms.checkStaleParticipants();
145
+ rooms.clear(); // Testing only
146
+ ```
147
+
148
+ ### `participants`
149
+
150
+ Create and configure participants:
151
+
152
+ ```typescript
153
+ // Create a participant
154
+ const participant = participants.create({
155
+ nickname: "Bot Name",
156
+ model: "llama3",
157
+ endpoint: "http://localhost:11434",
158
+ specs: {
159
+ gpu: "RTX 4090",
160
+ vram: 24,
161
+ ram: 64,
162
+ cpu: "AMD Ryzen 9",
163
+ },
164
+ config: {
165
+ temperature: 0.7,
166
+ max_tokens: 2048,
167
+ },
168
+ });
169
+
170
+ // Merge configurations
171
+ const merged = participants.mergeConfig(baseConfig, overrides);
172
+ ```
173
+
174
+ ### `hub`
175
+
176
+ Create and manage hubs:
177
+
178
+ ```typescript
179
+ const myHub = hub.create({
180
+ port: 3000,
181
+ hostname: "0.0.0.0",
182
+ mdns: true,
183
+ cors: ["*"],
184
+ });
185
+
186
+ // Hub provides: server, url, mdnsName, close()
187
+ console.log(myHub.url); // http://0.0.0.0:3000
188
+ myHub.close(); // Cleanup
189
+ ```
190
+
191
+ ### `createClient`
192
+
193
+ HTTP client for remote hubs:
194
+
195
+ ```typescript
196
+ const client = createClient({ hubUrl: "http://hub:3000" });
197
+
198
+ // Create room
199
+ const { room, hostId } = await client.create("Room Name");
200
+
201
+ // List rooms
202
+ const rooms = await client.list();
203
+
204
+ // Join room
205
+ const { participant, roomId } = await client.join(code, {
206
+ id: "participant-id",
207
+ nickname: "Bot",
208
+ model: "llama3",
209
+ endpoint: "http://localhost:11434",
210
+ });
211
+
212
+ // Leave room
213
+ await client.leave(code, participantId);
214
+
215
+ // Get participants
216
+ const participants = await client.getParticipants(code);
217
+
218
+ // Health check
219
+ await client.healthCheck(code, participantId);
220
+ ```
221
+
222
+ ## Types
223
+
224
+ All core types are re-exported:
225
+
226
+ ```typescript
227
+ import type {
228
+ RoomInfo,
229
+ ParticipantInfo,
230
+ ParticipantStatus,
231
+ GenerationConfig,
232
+ MachineSpecs,
233
+ HubConfig,
234
+ NetworkConfig,
235
+ } from "gambiarra";
236
+ ```
237
+
238
+ ### Runtime Validation
239
+
240
+ Zod schemas are exported with `Schema` suffix:
241
+
242
+ ```typescript
243
+ import {
244
+ ParticipantInfoSchema,
245
+ RoomInfoSchema,
246
+ GenerationConfigSchema,
247
+ } from "gambiarra";
248
+
249
+ // Validate at runtime
250
+ const result = ParticipantInfoSchema.parse(data);
251
+ ```
252
+
253
+ ## Tree-shaking
254
+
255
+ Import only what you need for optimal bundle size:
256
+
257
+ ```typescript
258
+ // Import specific namespaces
259
+ import { rooms, participants, hub } from "gambiarra";
260
+
261
+ // Or destructure what you need
262
+ import { createClient, createGambiarra } from "gambiarra";
263
+ ```
264
+
265
+ Modern bundlers (webpack, esbuild, rollup) will tree-shake unused exports.
266
+
267
+ ## Architecture
268
+
269
+ The SDK is a **zero-duplication wrapper** around `@gambiarra/core`:
270
+
271
+ - **`types.ts`** - Re-exports all core types
272
+ - **`protocol.ts`** - Re-exports protocol messages
273
+ - **`rooms.ts`** - Re-exports Room namespace
274
+ - **`participants.ts`** - Re-exports Participant namespace
275
+ - **`hub.ts`** - Re-exports Hub creation
276
+ - **`utils.ts`** - Re-exports utilities (logo, etc)
277
+ - **`client.ts`** - NEW: HTTP client implementation
278
+
279
+ **Philosophy:** Core contains implementation, SDK is the user-facing API.
280
+
281
+ ## Examples
282
+
283
+ ### Complete Workflow
284
+
285
+ ```typescript
286
+ import { hub, rooms, participants } from "gambiarra";
287
+
288
+ // 1. Create hub
289
+ const myHub = hub.create({ port: 3000 });
290
+
291
+ // 2. Create room
292
+ const room = rooms.create("AI Collaboration", "host-123");
293
+
294
+ // 3. Add participants
295
+ const bot1 = participants.create({
296
+ nickname: "Llama 3",
297
+ model: "llama3",
298
+ endpoint: "http://localhost:11434",
299
+ });
300
+
301
+ const bot2 = participants.create({
302
+ nickname: "GPT-4",
303
+ model: "gpt-4",
304
+ endpoint: "http://localhost:11435",
305
+ });
306
+
307
+ rooms.addParticipant(room.id, bot1);
308
+ rooms.addParticipant(room.id, bot2);
309
+
310
+ // 4. List participants
311
+ const allParticipants = rooms.getParticipants(room.id);
312
+ console.log(`${allParticipants.length} participants in room`);
313
+
314
+ // 5. Cleanup
315
+ myHub.close();
316
+ ```
317
+
318
+ ### Health Checks
319
+
320
+ ```typescript
321
+ // Send periodic health checks
322
+ setInterval(() => {
323
+ rooms.updateLastSeen(roomId, participantId);
324
+ }, 10_000);
325
+
326
+ // Check for stale participants
327
+ const stale = rooms.checkStaleParticipants();
328
+ for (const { roomId, participantId } of stale) {
329
+ console.log(`Participant ${participantId} is offline`);
330
+ }
331
+ ```
332
+
333
+ ### Error Handling
334
+
335
+ ```typescript
336
+ import { ClientError } from "gambiarra";
337
+
338
+ try {
339
+ await client.join("INVALID", participant);
340
+ } catch (error) {
341
+ if (error instanceof ClientError) {
342
+ console.error(`HTTP ${error.status}: ${error.message}`);
343
+ console.error(error.response); // Original response data
344
+ }
345
+ }
346
+ ```
347
+
348
+ ## Testing
349
+
350
+ ```bash
351
+ bun test
352
+ ```
353
+
354
+ ## License
355
+
356
+ MIT
@@ -0,0 +1,90 @@
1
+ import type { ParticipantInfo, RoomInfo } from "./types.ts";
2
+ /**
3
+ * Options for creating a Gambiarra HTTP client
4
+ */
5
+ export interface ClientOptions {
6
+ /** Base URL of the hub (default: http://localhost:3000) */
7
+ hubUrl?: string;
8
+ }
9
+ /**
10
+ * Options for creating a participant
11
+ */
12
+ export interface CreateParticipantOptions {
13
+ id: string;
14
+ nickname: string;
15
+ model: string;
16
+ endpoint: string;
17
+ specs?: ParticipantInfo["specs"];
18
+ config?: ParticipantInfo["config"];
19
+ }
20
+ /**
21
+ * Response when creating a room
22
+ */
23
+ export interface CreateRoomResponse {
24
+ room: RoomInfo;
25
+ hostId: string;
26
+ }
27
+ /**
28
+ * Response when joining a room
29
+ */
30
+ export interface JoinRoomResponse {
31
+ participant: ParticipantInfo;
32
+ roomId: string;
33
+ }
34
+ /**
35
+ * HTTP client for interacting with a remote Gambiarra hub
36
+ *
37
+ * Provides methods for managing rooms and participants via HTTP.
38
+ */
39
+ export interface GambiarraClient {
40
+ /** Create a new room */
41
+ create(name: string): Promise<CreateRoomResponse>;
42
+ /** List all rooms */
43
+ list(): Promise<RoomInfo[]>;
44
+ /** Join a room as a participant */
45
+ join(code: string, participant: CreateParticipantOptions): Promise<JoinRoomResponse>;
46
+ /** Leave a room */
47
+ leave(code: string, participantId: string): Promise<{
48
+ success: boolean;
49
+ }>;
50
+ /** Get all participants in a room */
51
+ getParticipants(code: string): Promise<ParticipantInfo[]>;
52
+ /** Send health check for a participant */
53
+ healthCheck(code: string, participantId: string): Promise<{
54
+ success: boolean;
55
+ }>;
56
+ }
57
+ /**
58
+ * Error thrown when a client request fails
59
+ */
60
+ export declare class ClientError extends Error {
61
+ readonly status: number;
62
+ readonly response?: unknown;
63
+ constructor(message: string, status: number, response?: unknown);
64
+ }
65
+ /**
66
+ * Create a new Gambiarra HTTP client
67
+ *
68
+ * @param options - Client configuration options
69
+ * @returns A client instance for interacting with the hub
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * import { createClient } from "gambiarra-sdk/client";
74
+ *
75
+ * const client = createClient({ hubUrl: "http://hub.example.com:3000" });
76
+ *
77
+ * // Create a room
78
+ * const { room, hostId } = await client.create("My Room");
79
+ *
80
+ * // Join the room
81
+ * await client.join(room.code, {
82
+ * id: "participant-1",
83
+ * nickname: "Bot",
84
+ * model: "llama3",
85
+ * endpoint: "http://localhost:11434"
86
+ * });
87
+ * ```
88
+ */
89
+ export declare function createClient(options?: ClientOptions): GambiarraClient;
90
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,eAAe,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAElD,qBAAqB;IACrB,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE5B,mCAAmC;IACnC,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,wBAAwB,GACpC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE7B,mBAAmB;IACnB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAE1E,qCAAqC;IACrC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAE1D,0CAA0C;IAC1C,WAAW,CACT,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;gBAEhB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO;CAMhE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,aAAkB,GAAG,eAAe,CAyEzE"}
package/dist/hub.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ export { type ChatCompletionRequest, createHub, type GambiarraModel, type Hub, type HubOptions, type ModelsListResponse, } from "@gambiarra/core/hub";
2
+ /**
3
+ * Hub management namespace
4
+ *
5
+ * Provides functions for creating and managing Gambiarra hubs.
6
+ * A hub is the central server that manages rooms, participants, and proxies LLM requests.
7
+ */
8
+ export declare const hub: {
9
+ /** Create a new Gambiarra hub */
10
+ readonly create: typeof createHub;
11
+ };
12
+ import { createHub } from "@gambiarra/core/hub";
13
+ //# sourceMappingURL=hub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../src/hub.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,qBAAqB,EAC1B,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,GAAG,EACR,KAAK,UAAU,EACf,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAE7B;;;;;GAKG;AACH,eAAO,MAAM,GAAG;IACd,iCAAiC;;CAEzB,CAAC;AAGX,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,11 @@
1
+ export { ClientError, createClient, type GambiarraClient } from "./client.ts";
2
+ export type { ChatCompletionRequest, GambiarraModel, Hub, HubOptions, ModelsListResponse, } from "./hub.ts";
3
+ export { hub } from "./hub.ts";
4
+ export { participants } from "./participants.ts";
5
+ export type * from "./protocol.ts";
6
+ export { createGambiarra, type GambiarraOptions, type GambiarraProvider, } from "./provider.ts";
7
+ export { rooms } from "./rooms.ts";
8
+ export type * from "./types.ts";
9
+ export * from "./types.ts";
10
+ export * from "./utils.ts";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9E,YAAY,EACV,qBAAqB,EACrB,cAAc,EACd,GAAG,EACH,UAAU,EACV,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,mBAAmB,eAAe,CAAC;AAEnC,OAAO,EACL,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,mBAAmB,YAAY,CAAC;AAChC,cAAc,YAAY,CAAC;AAE3B,cAAc,YAAY,CAAC"}