@stacknet/stacks 0.2.0 → 0.2.2

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 +136 -0
  2. package/dist/{billing-eQZIWeNW.d.cts → billing-cj0eSVrp.d.cts} +59 -1
  3. package/dist/{billing-eQZIWeNW.d.ts → billing-cj0eSVrp.d.ts} +59 -1
  4. package/dist/clients/index.cjs +4 -4
  5. package/dist/clients/index.d.cts +24 -1
  6. package/dist/clients/index.d.ts +24 -1
  7. package/dist/clients/index.js +4 -4
  8. package/dist/index.cjs +7 -7
  9. package/dist/index.d.cts +3 -3
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.js +7 -7
  12. package/dist/proxy/index.cjs +2 -2
  13. package/dist/proxy/index.js +2 -2
  14. package/dist/streaming/index.cjs +5 -5
  15. package/dist/streaming/index.js +5 -5
  16. package/dist/types/index.d.cts +1 -1
  17. package/dist/types/index.d.ts +1 -1
  18. package/package.json +15 -13
  19. package/src/clients/agents.ts +0 -250
  20. package/src/clients/billing.ts +0 -197
  21. package/src/clients/coder.ts +0 -655
  22. package/src/clients/files.ts +0 -86
  23. package/src/clients/index.ts +0 -93
  24. package/src/clients/magma.ts +0 -299
  25. package/src/clients/mcp.ts +0 -208
  26. package/src/clients/network.ts +0 -118
  27. package/src/clients/points.ts +0 -403
  28. package/src/clients/skills.ts +0 -236
  29. package/src/clients/social.ts +0 -286
  30. package/src/clients/stack-management.ts +0 -279
  31. package/src/clients/task-network.ts +0 -303
  32. package/src/clients/user.ts +0 -84
  33. package/src/clients/widgets.ts +0 -171
  34. package/src/index.ts +0 -387
  35. package/src/managers/index.ts +0 -10
  36. package/src/managers/task-manager.ts +0 -332
  37. package/src/proxy/forwarder.ts +0 -235
  38. package/src/proxy/index.ts +0 -32
  39. package/src/proxy/route-handlers.ts +0 -1107
  40. package/src/streaming/component-stream.ts +0 -319
  41. package/src/streaming/index.ts +0 -21
  42. package/src/streaming/sse.ts +0 -266
  43. package/src/types/agent.ts +0 -108
  44. package/src/types/billing.ts +0 -121
  45. package/src/types/chat.ts +0 -58
  46. package/src/types/coder.ts +0 -345
  47. package/src/types/credential.ts +0 -111
  48. package/src/types/file.ts +0 -15
  49. package/src/types/imagination.ts +0 -50
  50. package/src/types/index.ts +0 -20
  51. package/src/types/mcp.ts +0 -35
  52. package/src/types/network.ts +0 -97
  53. package/src/types/points.ts +0 -250
  54. package/src/types/skill.ts +0 -107
  55. package/src/types/social.ts +0 -109
  56. package/src/types/stack.ts +0 -269
  57. package/src/types/task.ts +0 -41
  58. package/src/types/user.ts +0 -29
  59. package/src/types/widget.ts +0 -57
  60. package/src/utils/constants.ts +0 -26
  61. package/src/utils/errors.ts +0 -169
  62. package/src/utils/helpers.ts +0 -85
  63. package/src/utils/index.ts +0 -7
@@ -1,319 +0,0 @@
1
- /**
2
- * Component Streaming - Artifact streaming adapter
3
- *
4
- * Converts tool call responses to artifact data stream format
5
- */
6
-
7
- export interface DataStreamWriter {
8
- write(data: { type: string; data: unknown; transient?: boolean }): void;
9
- }
10
-
11
- export interface ArtifactToolCall {
12
- id: string;
13
- type: 'function';
14
- function: {
15
- name: string;
16
- arguments: string;
17
- };
18
- }
19
-
20
- export interface ArtifactToolResult {
21
- type: string;
22
- id?: string;
23
- title?: string;
24
- kind?: string;
25
- content?: string;
26
- message?: string;
27
- [key: string]: unknown;
28
- }
29
-
30
- /**
31
- * Artifact streaming adapter for AI SDK integration
32
- */
33
- export class ComponentStreamAdapter {
34
- constructor(private dataStream: DataStreamWriter) {}
35
-
36
- /**
37
- * Process tool calls and convert to artifact stream events
38
- */
39
- processToolCalls(toolCalls: ArtifactToolCall[]): void {
40
- if (!toolCalls || toolCalls.length === 0) return;
41
-
42
- for (const toolCall of toolCalls) {
43
- try {
44
- const args = JSON.parse(toolCall.function.arguments);
45
- const toolName = toolCall.function.name;
46
-
47
- switch (toolName) {
48
- case 'create_document':
49
- this.handleCreateDocument(args, toolCall.id);
50
- break;
51
- case 'update_document':
52
- this.handleUpdateDocument(args, toolCall.id);
53
- break;
54
- default:
55
- console.log(`[ComponentStream] Unknown tool: ${toolName}`);
56
- }
57
- } catch (error) {
58
- console.error('[ComponentStream] Error processing tool call:', error);
59
- }
60
- }
61
- }
62
-
63
- /**
64
- * Process tool results
65
- */
66
- processToolResult(result: ArtifactToolResult): void {
67
- try {
68
- if (result.type === 'artifact') {
69
- this.handleArtifactResult(result);
70
- } else if (result.type === 'artifact_update') {
71
- this.handleArtifactUpdate(result);
72
- }
73
- } catch (error) {
74
- console.error('[ComponentStream] Error processing tool result:', error);
75
- }
76
- }
77
-
78
- /**
79
- * Stream an artifact with metadata
80
- */
81
- streamArtifact(artifact: {
82
- id: string;
83
- kind: string;
84
- title: string;
85
- content: string;
86
- }): void {
87
- this.dataStream.write({
88
- type: 'data-kind',
89
- data: artifact.kind,
90
- transient: true,
91
- });
92
-
93
- this.dataStream.write({
94
- type: 'data-id',
95
- data: artifact.id,
96
- transient: true,
97
- });
98
-
99
- this.dataStream.write({
100
- type: 'data-title',
101
- data: artifact.title,
102
- transient: true,
103
- });
104
-
105
- this.dataStream.write({
106
- type: 'data-clear',
107
- data: null,
108
- transient: true,
109
- });
110
-
111
- this.streamContent(artifact.content);
112
-
113
- this.dataStream.write({
114
- type: 'data-finish',
115
- data: null,
116
- transient: true,
117
- });
118
- }
119
-
120
- /**
121
- * Stream a text delta
122
- */
123
- streamTextDelta(delta: string): void {
124
- this.dataStream.write({
125
- type: 'data-textDelta',
126
- data: delta,
127
- transient: true,
128
- });
129
- }
130
-
131
- /**
132
- * Stream content in chunks
133
- */
134
- streamContent(content: string, chunkSize: number = 50): void {
135
- const chunks = this.splitIntoChunks(content, chunkSize);
136
-
137
- for (const chunk of chunks) {
138
- this.dataStream.write({
139
- type: 'data-textDelta',
140
- data: chunk,
141
- transient: true,
142
- });
143
- }
144
- }
145
-
146
- /**
147
- * Signal finish
148
- */
149
- finish(): void {
150
- this.dataStream.write({
151
- type: 'data-finish',
152
- data: null,
153
- transient: true,
154
- });
155
- }
156
-
157
- private handleCreateDocument(
158
- args: { title: string; kind: string; content: string },
159
- toolCallId: string
160
- ): void {
161
- const { title, kind, content } = args;
162
- const documentId = `doc_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
163
-
164
- console.log(`[ComponentStream] Creating document: ${title} (${kind})`);
165
-
166
- this.streamArtifact({
167
- id: documentId,
168
- kind,
169
- title,
170
- content,
171
- });
172
-
173
- this.dataStream.write({
174
- type: 'tool-result',
175
- data: {
176
- toolCallId,
177
- toolName: 'create_document',
178
- result: {
179
- id: documentId,
180
- title,
181
- kind,
182
- message: 'Document created successfully',
183
- },
184
- },
185
- });
186
- }
187
-
188
- private handleUpdateDocument(
189
- args: { id: string; description: string; content: string },
190
- toolCallId: string
191
- ): void {
192
- const { id, description, content } = args;
193
-
194
- console.log(`[ComponentStream] Updating document: ${id}`);
195
-
196
- this.dataStream.write({
197
- type: 'data-clear',
198
- data: null,
199
- transient: true,
200
- });
201
-
202
- this.streamContent(content);
203
-
204
- this.dataStream.write({
205
- type: 'data-finish',
206
- data: null,
207
- transient: true,
208
- });
209
-
210
- this.dataStream.write({
211
- type: 'tool-result',
212
- data: {
213
- toolCallId,
214
- toolName: 'update_document',
215
- result: {
216
- id,
217
- message: `Document updated: ${description}`,
218
- },
219
- },
220
- });
221
- }
222
-
223
- private handleArtifactResult(result: ArtifactToolResult): void {
224
- const { id, title, kind, content } = result;
225
-
226
- if (!id || !title || !kind || !content) {
227
- console.error('[ComponentStream] Invalid artifact result:', result);
228
- return;
229
- }
230
-
231
- this.streamArtifact({ id, kind, title, content });
232
- }
233
-
234
- private handleArtifactUpdate(result: ArtifactToolResult): void {
235
- const { content } = result;
236
-
237
- if (!content) {
238
- console.error('[ComponentStream] Invalid artifact update:', result);
239
- return;
240
- }
241
-
242
- this.dataStream.write({
243
- type: 'data-clear',
244
- data: null,
245
- transient: true,
246
- });
247
-
248
- this.streamContent(content);
249
-
250
- this.dataStream.write({
251
- type: 'data-finish',
252
- data: null,
253
- transient: true,
254
- });
255
- }
256
-
257
- private splitIntoChunks(content: string, chunkSize: number): string[] {
258
- const chunks: string[] = [];
259
- const words = content.split(' ');
260
- let currentChunk = '';
261
-
262
- for (let i = 0; i < words.length; i++) {
263
- const word = i === 0 ? words[i] : ' ' + words[i];
264
-
265
- if (currentChunk.length + word.length > chunkSize && currentChunk.length > 0) {
266
- chunks.push(currentChunk);
267
- currentChunk = word.trim();
268
- } else {
269
- currentChunk += word;
270
- }
271
- }
272
-
273
- if (currentChunk.length > 0) {
274
- chunks.push(currentChunk);
275
- }
276
-
277
- return chunks;
278
- }
279
- }
280
-
281
- /**
282
- * Helper to detect tool calls in a message
283
- */
284
- export function hasToolCalls(message: {
285
- tool_calls?: unknown[];
286
- }): boolean {
287
- return !!(
288
- message?.tool_calls &&
289
- Array.isArray(message.tool_calls) &&
290
- message.tool_calls.length > 0
291
- );
292
- }
293
-
294
- /**
295
- * Helper to extract tool results from content
296
- */
297
- export function extractToolResults(content: string): ArtifactToolResult[] {
298
- try {
299
- const parsed = JSON.parse(content);
300
- if (
301
- parsed.type &&
302
- (parsed.type === 'artifact' || parsed.type === 'artifact_update')
303
- ) {
304
- return [parsed];
305
- }
306
- } catch {
307
- // Not JSON
308
- }
309
- return [];
310
- }
311
-
312
- /**
313
- * Factory function
314
- */
315
- export function createComponentStreamAdapter(
316
- dataStream: DataStreamWriter
317
- ): ComponentStreamAdapter {
318
- return new ComponentStreamAdapter(dataStream);
319
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * @stacknet/stacks - Streaming utilities
3
- */
4
-
5
- export {
6
- parseSSEStream,
7
- createSSEResponse,
8
- SSEWriter,
9
- createSSEWriter,
10
- type SSEEvent,
11
- } from './sse';
12
-
13
- export {
14
- ComponentStreamAdapter,
15
- createComponentStreamAdapter,
16
- hasToolCalls,
17
- extractToolResults,
18
- type DataStreamWriter,
19
- type ArtifactToolCall,
20
- type ArtifactToolResult,
21
- } from './component-stream';
@@ -1,266 +0,0 @@
1
- /**
2
- * SSE (Server-Sent Events) streaming utilities
3
- */
4
-
5
- import { SSE_HEADERS } from '../utils/constants';
6
-
7
- export interface SSEEvent {
8
- event?: string;
9
- data: unknown;
10
- id?: string;
11
- retry?: number;
12
- }
13
-
14
- /** Hard cap on the in-memory buffer used by `parseSSEStream`. A malicious
15
- * or malfunctioning upstream that never emits a newline would otherwise
16
- * grow the buffer until the process OOMs. 1 MiB is far beyond any real
17
- * SSE event. */
18
- const MAX_SSE_BUFFER_BYTES = 1024 * 1024;
19
-
20
- /** SSE framing uses newlines as field separators; any `\r` or `\n` in
21
- * `event`, `id`, or a string `data` value would let an untrusted caller
22
- * inject additional SSE frames that the receiver would process as if
23
- * they came from the server. Strip them. */
24
- function stripCRLF(value: string): string {
25
- // Replace CR/LF/LS/PS with a single space so the field remains
26
- // structurally valid without carrying a frame separator.
27
- return value.replace(/[\r\n\u2028\u2029]/g, ' ');
28
- }
29
-
30
- /**
31
- * Parse SSE stream from a Response
32
- */
33
- export async function* parseSSEStream(
34
- response: Response
35
- ): AsyncIterable<SSEEvent> {
36
- if (!response.body) {
37
- throw new Error('Response body is null');
38
- }
39
-
40
- const reader = response.body.getReader();
41
- const decoder = new TextDecoder();
42
- let buffer = '';
43
- let currentEvent: Partial<SSEEvent> = {};
44
-
45
- try {
46
- while (true) {
47
- const { done, value } = await reader.read();
48
- if (done) break;
49
-
50
- buffer += decoder.decode(value, { stream: true });
51
- if (buffer.length > MAX_SSE_BUFFER_BYTES) {
52
- throw new Error(
53
- `SSE buffer exceeded ${MAX_SSE_BUFFER_BYTES} bytes without an event delimiter`,
54
- );
55
- }
56
- const lines = buffer.split('\n');
57
- buffer = lines.pop() || '';
58
-
59
- for (const line of lines) {
60
- if (line === '') {
61
- // Empty line means end of event
62
- if (currentEvent.data !== undefined) {
63
- yield currentEvent as SSEEvent;
64
- }
65
- currentEvent = {};
66
- continue;
67
- }
68
-
69
- if (line.startsWith(':')) {
70
- // Comment, skip
71
- continue;
72
- }
73
-
74
- const colonIndex = line.indexOf(':');
75
- if (colonIndex === -1) continue;
76
-
77
- const field = line.slice(0, colonIndex);
78
- const value = line.slice(colonIndex + 1).trimStart();
79
-
80
- switch (field) {
81
- case 'event':
82
- currentEvent.event = value;
83
- break;
84
- case 'data':
85
- try {
86
- currentEvent.data = JSON.parse(value);
87
- } catch {
88
- currentEvent.data = value;
89
- }
90
- break;
91
- case 'id':
92
- currentEvent.id = value;
93
- break;
94
- case 'retry':
95
- currentEvent.retry = parseInt(value, 10);
96
- break;
97
- }
98
- }
99
- }
100
-
101
- // Emit any remaining event
102
- if (currentEvent.data !== undefined) {
103
- yield currentEvent as SSEEvent;
104
- }
105
- } finally {
106
- reader.releaseLock();
107
- }
108
- }
109
-
110
- /** Encode an SSE message safely — every field with CRLF stripped, data
111
- * multi-line payloads split into repeated `data:` lines per the spec.
112
- * Keeping this in one place lets both `createSSEResponse` and
113
- * `SSEWriter.write` share exactly the same sanitization rules. */
114
- function encodeEvent(event: SSEEvent): string {
115
- let message = '';
116
-
117
- if (event.event) {
118
- message += `event: ${stripCRLF(event.event)}\n`;
119
- }
120
-
121
- if (event.id) {
122
- message += `id: ${stripCRLF(event.id)}\n`;
123
- }
124
-
125
- if (event.retry !== undefined && Number.isFinite(event.retry)) {
126
- // retry is numeric per the SSE spec — coerce defensively.
127
- message += `retry: ${Math.floor(event.retry)}\n`;
128
- }
129
-
130
- const dataString =
131
- typeof event.data === 'string'
132
- ? event.data
133
- : JSON.stringify(event.data);
134
-
135
- // Per the SSE spec, data may span multiple lines — each line is a
136
- // separate `data:` field. This also means an embedded newline in a
137
- // string payload can't be used to smuggle a new frame: the blank
138
- // line at the end of the event is produced by us, not the caller.
139
- for (const dataLine of dataString.split(/\r?\n/)) {
140
- message += `data: ${dataLine}\n`;
141
- }
142
-
143
- message += '\n';
144
- return message;
145
- }
146
-
147
- /**
148
- * Create an SSE Response from an async iterable
149
- */
150
- export function createSSEResponse(
151
- stream: AsyncIterable<SSEEvent>,
152
- headers?: Record<string, string>
153
- ): Response {
154
- const encoder = new TextEncoder();
155
-
156
- const readableStream = new ReadableStream({
157
- async start(controller) {
158
- try {
159
- for await (const event of stream) {
160
- controller.enqueue(encoder.encode(encodeEvent(event)));
161
- }
162
- } catch (error) {
163
- console.error('SSE stream error:', error);
164
- } finally {
165
- controller.close();
166
- }
167
- },
168
- });
169
-
170
- return new Response(readableStream, {
171
- headers: {
172
- ...SSE_HEADERS,
173
- ...headers,
174
- },
175
- });
176
- }
177
-
178
- /**
179
- * Create an SSE writer for streaming events
180
- */
181
- export class SSEWriter {
182
- private encoder = new TextEncoder();
183
- private controller: ReadableStreamDefaultController<Uint8Array> | null = null;
184
- private stream: ReadableStream<Uint8Array>;
185
-
186
- constructor() {
187
- this.stream = new ReadableStream({
188
- start: (controller) => {
189
- this.controller = controller;
190
- },
191
- });
192
- }
193
-
194
- /**
195
- * Get the underlying ReadableStream
196
- */
197
- getStream(): ReadableStream<Uint8Array> {
198
- return this.stream;
199
- }
200
-
201
- /**
202
- * Get a Response object for this stream
203
- */
204
- getResponse(headers?: Record<string, string>): Response {
205
- return new Response(this.stream, {
206
- headers: {
207
- ...SSE_HEADERS,
208
- ...headers,
209
- },
210
- });
211
- }
212
-
213
- /**
214
- * Write an SSE event
215
- */
216
- write(event: SSEEvent): void {
217
- if (!this.controller) return;
218
- this.controller.enqueue(this.encoder.encode(encodeEvent(event)));
219
- }
220
-
221
- /**
222
- * Write a data-only event
223
- */
224
- writeData(data: unknown): void {
225
- this.write({ data });
226
- }
227
-
228
- /**
229
- * Write a comment (for keep-alive)
230
- */
231
- writeComment(comment: string): void {
232
- if (!this.controller) return;
233
- // Comments are a single `:` line followed by a blank line. Strip any
234
- // CRLF so a caller can't close out the comment and smuggle a real
235
- // event after it.
236
- const safe = stripCRLF(comment);
237
- this.controller.enqueue(this.encoder.encode(`: ${safe}\n\n`));
238
- }
239
-
240
- /**
241
- * Close the stream
242
- */
243
- close(): void {
244
- if (this.controller) {
245
- this.controller.close();
246
- this.controller = null;
247
- }
248
- }
249
-
250
- /**
251
- * Signal an error
252
- */
253
- error(err: Error): void {
254
- if (this.controller) {
255
- this.controller.error(err);
256
- this.controller = null;
257
- }
258
- }
259
- }
260
-
261
- /**
262
- * Create an SSE writer
263
- */
264
- export function createSSEWriter(): SSEWriter {
265
- return new SSEWriter();
266
- }
@@ -1,108 +0,0 @@
1
- /**
2
- * Agent type definitions
3
- */
4
-
5
- export interface Agent {
6
- id: string;
7
- name: string;
8
- description?: string;
9
- system_prompt?: string;
10
- model?: string;
11
- tools?: string[];
12
- triggers?: AgentTrigger[];
13
- workflow?: AgentWorkflow;
14
- visibility?: 'public' | 'private' | 'template';
15
- creator_mid?: string;
16
- created_at?: string;
17
- updated_at?: string;
18
- enabled?: boolean;
19
- }
20
-
21
- export interface AgentTrigger {
22
- type: 'webhook' | 'cron' | 'event';
23
- config: Record<string, unknown>;
24
- }
25
-
26
- export interface AgentWorkflow {
27
- nodes: AgentWorkflowNode[];
28
- edges: AgentWorkflowEdge[];
29
- }
30
-
31
- export interface AgentWorkflowNode {
32
- id: string;
33
- type: string;
34
- position: { x: number; y: number };
35
- data: Record<string, unknown>;
36
- }
37
-
38
- export interface AgentWorkflowEdge {
39
- id: string;
40
- source: string;
41
- target: string;
42
- sourceHandle?: string;
43
- targetHandle?: string;
44
- }
45
-
46
- export interface AgentExecuteRequest {
47
- input?: string;
48
- context?: Record<string, unknown>;
49
- stream?: boolean;
50
- }
51
-
52
- export interface AgentExecuteResponse {
53
- id: string;
54
- output: string;
55
- status: 'success' | 'error';
56
- metadata?: Record<string, unknown>;
57
- }
58
-
59
- export interface AgentsListResponse {
60
- agents: Agent[];
61
- }
62
-
63
- export interface AgentResponse {
64
- agent?: Agent;
65
- id?: string;
66
- name?: string;
67
- error?: string;
68
- }
69
-
70
- export interface AgentCreateInput {
71
- name: string;
72
- description?: string;
73
- system_prompt?: string;
74
- model?: string;
75
- tools?: string[];
76
- triggers?: AgentTrigger[];
77
- workflow?: AgentWorkflow;
78
- visibility?: 'public' | 'private' | 'template';
79
- created_by?: string;
80
- }
81
-
82
- export interface AgentUpdateInput {
83
- name?: string;
84
- description?: string;
85
- system_prompt?: string;
86
- model?: string;
87
- tools?: string[];
88
- triggers?: AgentTrigger[];
89
- workflow?: AgentWorkflow;
90
- visibility?: 'public' | 'private' | 'template';
91
- enabled?: boolean;
92
- }
93
-
94
- export interface AgentFromPromptInput {
95
- prompt: string;
96
- created_by?: string;
97
- }
98
-
99
- export interface AgentsClientConfig {
100
- baseUrl?: string;
101
- /** JWT auth token for authenticated requests */
102
- authToken?: string;
103
- /**
104
- * Use the coprocessor API (/cpx/agent/agents) instead of legacy (/agents).
105
- * Defaults to true. Set to false for backwards compatibility.
106
- */
107
- useCpxApi?: boolean;
108
- }