@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.
- package/README.md +136 -0
- package/dist/{billing-eQZIWeNW.d.cts → billing-cj0eSVrp.d.cts} +59 -1
- package/dist/{billing-eQZIWeNW.d.ts → billing-cj0eSVrp.d.ts} +59 -1
- package/dist/clients/index.cjs +4 -4
- package/dist/clients/index.d.cts +24 -1
- package/dist/clients/index.d.ts +24 -1
- package/dist/clients/index.js +4 -4
- package/dist/index.cjs +7 -7
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +7 -7
- package/dist/proxy/index.cjs +2 -2
- package/dist/proxy/index.js +2 -2
- package/dist/streaming/index.cjs +5 -5
- package/dist/streaming/index.js +5 -5
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +15 -13
- package/src/clients/agents.ts +0 -250
- package/src/clients/billing.ts +0 -197
- package/src/clients/coder.ts +0 -655
- package/src/clients/files.ts +0 -86
- package/src/clients/index.ts +0 -93
- package/src/clients/magma.ts +0 -299
- package/src/clients/mcp.ts +0 -208
- package/src/clients/network.ts +0 -118
- package/src/clients/points.ts +0 -403
- package/src/clients/skills.ts +0 -236
- package/src/clients/social.ts +0 -286
- package/src/clients/stack-management.ts +0 -279
- package/src/clients/task-network.ts +0 -303
- package/src/clients/user.ts +0 -84
- package/src/clients/widgets.ts +0 -171
- package/src/index.ts +0 -387
- package/src/managers/index.ts +0 -10
- package/src/managers/task-manager.ts +0 -332
- package/src/proxy/forwarder.ts +0 -235
- package/src/proxy/index.ts +0 -32
- package/src/proxy/route-handlers.ts +0 -1107
- package/src/streaming/component-stream.ts +0 -319
- package/src/streaming/index.ts +0 -21
- package/src/streaming/sse.ts +0 -266
- package/src/types/agent.ts +0 -108
- package/src/types/billing.ts +0 -121
- package/src/types/chat.ts +0 -58
- package/src/types/coder.ts +0 -345
- package/src/types/credential.ts +0 -111
- package/src/types/file.ts +0 -15
- package/src/types/imagination.ts +0 -50
- package/src/types/index.ts +0 -20
- package/src/types/mcp.ts +0 -35
- package/src/types/network.ts +0 -97
- package/src/types/points.ts +0 -250
- package/src/types/skill.ts +0 -107
- package/src/types/social.ts +0 -109
- package/src/types/stack.ts +0 -269
- package/src/types/task.ts +0 -41
- package/src/types/user.ts +0 -29
- package/src/types/widget.ts +0 -57
- package/src/utils/constants.ts +0 -26
- package/src/utils/errors.ts +0 -169
- package/src/utils/helpers.ts +0 -85
- package/src/utils/index.ts +0 -7
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stack Management Client
|
|
3
|
-
* CRUD operations for stacks, providers, keys, allowlists, capabilities, members, and model layers
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { DEFAULT_GLAYER_NETWORK_URL, JSON_HEADERS } from '../utils/constants';
|
|
7
|
-
import { StacksSDKError } from '../utils/errors';
|
|
8
|
-
import type {
|
|
9
|
-
StackConfig,
|
|
10
|
-
CreateStackRequest,
|
|
11
|
-
StackResponse,
|
|
12
|
-
StackListResponse,
|
|
13
|
-
StackOAuthProvider,
|
|
14
|
-
StackWeb3Provider,
|
|
15
|
-
StackStripeProvider,
|
|
16
|
-
ConfigureOAuthInput,
|
|
17
|
-
ConfigureWeb3Input,
|
|
18
|
-
ConfigureStripeInput,
|
|
19
|
-
StackKeyInfo,
|
|
20
|
-
CreateKeyResponse,
|
|
21
|
-
StackKeysListResponse,
|
|
22
|
-
AllowlistConfig,
|
|
23
|
-
AllowlistUpdateInput,
|
|
24
|
-
ModelLayersResponse,
|
|
25
|
-
StackMember,
|
|
26
|
-
StackMemberStats,
|
|
27
|
-
StackManagementClientConfig,
|
|
28
|
-
} from '../types/stack';
|
|
29
|
-
|
|
30
|
-
export type { StackManagementClientConfig } from '../types/stack';
|
|
31
|
-
|
|
32
|
-
const API_PATH = '/api/v2';
|
|
33
|
-
|
|
34
|
-
export class StackManagementClient {
|
|
35
|
-
private baseUrl: string;
|
|
36
|
-
private authToken: string | null;
|
|
37
|
-
|
|
38
|
-
constructor(config: StackManagementClientConfig = {}) {
|
|
39
|
-
this.baseUrl = config.baseUrl || DEFAULT_GLAYER_NETWORK_URL;
|
|
40
|
-
this.authToken = config.authToken || null;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** Update the auth token (e.g. after login via userutils) */
|
|
44
|
-
setAuthToken(token: string | null) {
|
|
45
|
-
this.authToken = token;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private get headers(): Record<string, string> {
|
|
49
|
-
const h: Record<string, string> = { ...JSON_HEADERS };
|
|
50
|
-
if (this.authToken) {
|
|
51
|
-
h['Authorization'] = `Bearer ${this.authToken}`;
|
|
52
|
-
}
|
|
53
|
-
return h;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private url(path: string): string {
|
|
57
|
-
return `${this.baseUrl}${API_PATH}${path}`;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private async request<T>(method: string, path: string, body?: unknown): Promise<T> {
|
|
61
|
-
const opts: RequestInit = { method, headers: this.headers };
|
|
62
|
-
if (body && method !== 'GET') {
|
|
63
|
-
opts.body = JSON.stringify(body);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const response = await fetch(this.url(path), opts);
|
|
67
|
-
|
|
68
|
-
if (!response.ok) {
|
|
69
|
-
const data = await response.json().catch(() => ({}));
|
|
70
|
-
const code = response.status === 404 ? 'not_found' : response.status === 401 ? 'unauthorized' : 'bad_request';
|
|
71
|
-
throw new StacksSDKError(
|
|
72
|
-
`${code}:api`,
|
|
73
|
-
data.error?.message || data.error || `Request failed: ${response.statusText}`
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const data = await response.json();
|
|
78
|
-
// Unwrap server envelope { success, data }
|
|
79
|
-
return (data && typeof data === 'object' && 'data' in data) ? data.data : data;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// =========================================================================
|
|
83
|
-
// Stack CRUD
|
|
84
|
-
// =========================================================================
|
|
85
|
-
|
|
86
|
-
async createStack(input: CreateStackRequest): Promise<StackResponse> {
|
|
87
|
-
return this.request<StackResponse>('POST', '/stacks', input);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
async listStacks(): Promise<StackListResponse> {
|
|
91
|
-
return this.request<StackListResponse>('GET', '/stacks');
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async getStack(stackId: string): Promise<StackResponse> {
|
|
95
|
-
return this.request<StackResponse>('GET', `/stacks/${stackId}`);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
async updateStack(stackId: string, updates: Partial<StackConfig>): Promise<StackResponse> {
|
|
99
|
-
return this.request<StackResponse>('PATCH', `/stacks/${stackId}`, updates);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async deleteStack(stackId: string): Promise<{ deleted: boolean }> {
|
|
103
|
-
return this.request<{ deleted: boolean }>('DELETE', `/stacks/${stackId}`);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// =========================================================================
|
|
107
|
-
// OAuth Providers
|
|
108
|
-
// =========================================================================
|
|
109
|
-
|
|
110
|
-
/** @server-only — Sends OAuth clientSecret. Only call from server-side code. */
|
|
111
|
-
async configureOAuthProvider(stackId: string, provider: string, config: ConfigureOAuthInput): Promise<StackOAuthProvider> {
|
|
112
|
-
return this.request<StackOAuthProvider>('POST', `/stacks/${stackId}/oauth/${provider}`, config);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async removeOAuthProvider(stackId: string, provider: string): Promise<{ removed: boolean }> {
|
|
116
|
-
return this.request<{ removed: boolean }>('DELETE', `/stacks/${stackId}/oauth/${provider}`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// =========================================================================
|
|
120
|
-
// Web3 Providers
|
|
121
|
-
// =========================================================================
|
|
122
|
-
|
|
123
|
-
async configureWeb3Provider(stackId: string, provider: string, config: ConfigureWeb3Input): Promise<StackWeb3Provider> {
|
|
124
|
-
return this.request<StackWeb3Provider>('POST', `/stacks/${stackId}/web3/${provider}`, config);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async removeWeb3Provider(stackId: string, provider: string): Promise<{ removed: boolean }> {
|
|
128
|
-
return this.request<{ removed: boolean }>('DELETE', `/stacks/${stackId}/web3/${provider}`);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// =========================================================================
|
|
132
|
-
// Stripe Provider
|
|
133
|
-
// =========================================================================
|
|
134
|
-
|
|
135
|
-
/** @server-only — Sends Stripe secretKey. Only call from server-side code. */
|
|
136
|
-
async configureStripeProvider(stackId: string, config: ConfigureStripeInput): Promise<StackStripeProvider> {
|
|
137
|
-
return this.request<StackStripeProvider>('POST', `/stacks/${stackId}/stripe`, config);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async getStripeProvider(stackId: string): Promise<StackStripeProvider> {
|
|
141
|
-
return this.request<StackStripeProvider>('GET', `/stacks/${stackId}/stripe`);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
async removeStripeProvider(stackId: string): Promise<{ removed: boolean }> {
|
|
145
|
-
return this.request<{ removed: boolean }>('DELETE', `/stacks/${stackId}/stripe`);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async createPaymentIntent(stackId: string, amountCents: number, metadata?: Record<string, string>): Promise<{ clientSecret: string; paymentIntentId: string }> {
|
|
149
|
-
return this.request('POST', `/stacks/${stackId}/stripe/payment-intent`, { amountCents, metadata });
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// =========================================================================
|
|
153
|
-
// Stack Keys
|
|
154
|
-
// =========================================================================
|
|
155
|
-
|
|
156
|
-
async createKey(stackId: string, name: string, permission: 'read' | 'write'): Promise<CreateKeyResponse> {
|
|
157
|
-
return this.request<CreateKeyResponse>('POST', `/stacks/${stackId}/keys`, { name, permission });
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
async listKeys(stackId: string): Promise<StackKeysListResponse> {
|
|
161
|
-
return this.request<StackKeysListResponse>('GET', `/stacks/${stackId}/keys`);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
async revokeKey(stackId: string, keyId: string): Promise<{ success: boolean }> {
|
|
165
|
-
return this.request<{ success: boolean }>('DELETE', `/stacks/${stackId}/keys/${keyId}`);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// =========================================================================
|
|
169
|
-
// Allowlist
|
|
170
|
-
// =========================================================================
|
|
171
|
-
|
|
172
|
-
async getAllowlist(stackId: string): Promise<AllowlistConfig> {
|
|
173
|
-
return this.request<AllowlistConfig>('GET', `/stacks/${stackId}/auth/allowlist`);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async updateAllowlist(stackId: string, config: AllowlistUpdateInput): Promise<AllowlistConfig> {
|
|
177
|
-
return this.request<AllowlistConfig>('PUT', `/stacks/${stackId}/auth/allowlist`, config);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// =========================================================================
|
|
181
|
-
// Capabilities
|
|
182
|
-
// =========================================================================
|
|
183
|
-
|
|
184
|
-
async updateCapabilities(stackId: string, capabilityBitmask: number): Promise<StackResponse> {
|
|
185
|
-
return this.request<StackResponse>('PATCH', `/stacks/${stackId}`, { capabilityBitmask });
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// =========================================================================
|
|
189
|
-
// Model Layers
|
|
190
|
-
// =========================================================================
|
|
191
|
-
|
|
192
|
-
async getModelLayers(stackId: string): Promise<ModelLayersResponse> {
|
|
193
|
-
return this.request<ModelLayersResponse>('GET', `/stacks/${stackId}/model-layers`);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
async updateModelAlias(stackId: string, layer: string, capability: string, alias: string): Promise<{ updated: boolean }> {
|
|
197
|
-
return this.request('PATCH', `/stacks/${stackId}/model-layers`, { layer, capability, alias });
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
async resetModelAlias(stackId: string, layer: string, capability: string): Promise<{ updated: boolean }> {
|
|
201
|
-
return this.request('DELETE', `/stacks/${stackId}/model-layers/${layer}/${capability}`);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// =========================================================================
|
|
205
|
-
// Logo
|
|
206
|
-
// =========================================================================
|
|
207
|
-
|
|
208
|
-
async uploadLogo(stackId: string, file: File): Promise<StackResponse> {
|
|
209
|
-
const url = `${this.baseUrl}${API_PATH}/stacks/${stackId}/logo`;
|
|
210
|
-
const formData = new FormData();
|
|
211
|
-
formData.append('logo', file);
|
|
212
|
-
|
|
213
|
-
const headers: Record<string, string> = {};
|
|
214
|
-
if (this.authToken) {
|
|
215
|
-
headers['Authorization'] = `Bearer ${this.authToken}`;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const response = await fetch(url, { method: 'POST', headers, body: formData });
|
|
219
|
-
|
|
220
|
-
if (!response.ok) {
|
|
221
|
-
const data = await response.json().catch(() => ({}));
|
|
222
|
-
throw new StacksSDKError('bad_request:api', data.error?.message || `Failed to upload logo: ${response.statusText}`);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const data = await response.json();
|
|
226
|
-
return (data && typeof data === 'object' && 'data' in data) ? data.data : data;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
async deleteLogo(stackId: string): Promise<StackResponse> {
|
|
230
|
-
return this.request<StackResponse>('DELETE', `/stacks/${stackId}/logo`);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// =========================================================================
|
|
234
|
-
// Members
|
|
235
|
-
// =========================================================================
|
|
236
|
-
|
|
237
|
-
async getMemberStats(stackId: string): Promise<StackMemberStats> {
|
|
238
|
-
return this.request<StackMemberStats>('GET', `/stacks/${stackId}/members/stats`);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async getMembers(stackId: string, opts?: { limit?: number; offset?: number; role?: string }): Promise<StackMember[]> {
|
|
242
|
-
const params = new URLSearchParams();
|
|
243
|
-
if (opts?.limit) params.set('limit', String(opts.limit));
|
|
244
|
-
if (opts?.offset) params.set('offset', String(opts.offset));
|
|
245
|
-
if (opts?.role) params.set('role', opts.role);
|
|
246
|
-
const qs = params.toString() ? `?${params}` : '';
|
|
247
|
-
return this.request<StackMember[]>('GET', `/stacks/${stackId}/members${qs}`);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
async updateMemberRole(stackId: string, userId: string, role: 'admin' | 'user'): Promise<{ success: boolean }> {
|
|
251
|
-
return this.request<{ success: boolean }>('PATCH', `/stacks/${stackId}/members/${encodeURIComponent(userId)}/role`, { role });
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// =========================================================================
|
|
255
|
-
// Usage Records
|
|
256
|
-
// =========================================================================
|
|
257
|
-
|
|
258
|
-
async getUsageRecords(stackId: string, opts?: { page?: number; limit?: number; days?: number; model?: string }): Promise<{ data: any[]; pagination: any }> {
|
|
259
|
-
const params = new URLSearchParams();
|
|
260
|
-
if (opts?.page) params.set('page', String(opts.page));
|
|
261
|
-
if (opts?.limit) params.set('limit', String(opts.limit));
|
|
262
|
-
if (opts?.days) params.set('days', String(opts.days));
|
|
263
|
-
if (opts?.model) params.set('model', opts.model);
|
|
264
|
-
const qs = params.toString() ? `?${params}` : '';
|
|
265
|
-
return this.request('GET', `/stacks/${stackId}/usage/records${qs}`);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Create a StackManagementClient instance
|
|
271
|
-
*/
|
|
272
|
-
export function createStackManagementClient(config: StackManagementClientConfig = {}): StackManagementClient {
|
|
273
|
-
return new StackManagementClient(config);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Default stack management client instance
|
|
278
|
-
*/
|
|
279
|
-
export const stackManagementClient = createStackManagementClient();
|
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TaskNetworkClient - OpenAI-compatible SDK for StackNet
|
|
3
|
-
*
|
|
4
|
-
* Provides streaming chat completions via the local StackNet
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type {
|
|
8
|
-
Message,
|
|
9
|
-
ChatCompletionRequest,
|
|
10
|
-
ChatCompletionChunk,
|
|
11
|
-
TaskPayload,
|
|
12
|
-
} from '../types';
|
|
13
|
-
import { DEFAULT_TASK_NETWORK_URL } from '../utils/constants';
|
|
14
|
-
|
|
15
|
-
export interface TaskNetworkConfig {
|
|
16
|
-
baseUrl?: string;
|
|
17
|
-
apiKey?: string;
|
|
18
|
-
timeout?: number;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export class TaskNetworkClient {
|
|
22
|
-
private baseUrl: string;
|
|
23
|
-
private apiKey?: string;
|
|
24
|
-
private timeout: number;
|
|
25
|
-
|
|
26
|
-
constructor(config: TaskNetworkConfig = {}) {
|
|
27
|
-
this.baseUrl = (config.baseUrl || DEFAULT_TASK_NETWORK_URL).replace(/\/$/, '');
|
|
28
|
-
this.apiKey = config.apiKey;
|
|
29
|
-
this.timeout = config.timeout || 60000;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* OpenAI-compatible streaming chat completions
|
|
34
|
-
*/
|
|
35
|
-
async *chatCompletions(
|
|
36
|
-
request: ChatCompletionRequest
|
|
37
|
-
): AsyncIterable<ChatCompletionChunk> {
|
|
38
|
-
const userMessages = request.messages.filter((m) => m.role === 'user');
|
|
39
|
-
const prompt = userMessages[userMessages.length - 1]?.content || '';
|
|
40
|
-
|
|
41
|
-
const taskId = await this.submitTask({
|
|
42
|
-
type: 'ai-prompt',
|
|
43
|
-
model: request.model,
|
|
44
|
-
prompt: prompt,
|
|
45
|
-
sessionId: request.sessionId,
|
|
46
|
-
temperature: request.temperature,
|
|
47
|
-
maxTokens: request.max_tokens,
|
|
48
|
-
stream: true,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
yield* this.streamTaskResults(taskId, request.model);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Submit a task to the network
|
|
56
|
-
* Returns taskId. If result is immediately available, also includes output.
|
|
57
|
-
*/
|
|
58
|
-
async submitTask(payload: TaskPayload): Promise<string> {
|
|
59
|
-
const response = await fetch(`${this.baseUrl}/tasks`, {
|
|
60
|
-
method: 'POST',
|
|
61
|
-
headers: {
|
|
62
|
-
'Content-Type': 'application/json',
|
|
63
|
-
...(this.apiKey && { Authorization: `Bearer ${this.apiKey}` }),
|
|
64
|
-
},
|
|
65
|
-
body: JSON.stringify(payload),
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
if (!response.ok) {
|
|
69
|
-
const error = await response.text();
|
|
70
|
-
throw new Error(`Task submission failed: ${error}`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const data = await response.json();
|
|
74
|
-
// Handle both taskId and id (StackNet uses different field names)
|
|
75
|
-
const taskId = data.taskId || data.id;
|
|
76
|
-
if (!taskId) {
|
|
77
|
-
throw new Error('Task submission did not return a taskId');
|
|
78
|
-
}
|
|
79
|
-
return taskId;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Submit a task and get full response (for immediate results)
|
|
84
|
-
*/
|
|
85
|
-
async submitTaskFull(payload: TaskPayload): Promise<{ taskId: string; output?: unknown; status?: string }> {
|
|
86
|
-
const response = await fetch(`${this.baseUrl}/tasks`, {
|
|
87
|
-
method: 'POST',
|
|
88
|
-
headers: {
|
|
89
|
-
'Content-Type': 'application/json',
|
|
90
|
-
...(this.apiKey && { Authorization: `Bearer ${this.apiKey}` }),
|
|
91
|
-
},
|
|
92
|
-
body: JSON.stringify(payload),
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
if (!response.ok) {
|
|
96
|
-
const error = await response.text();
|
|
97
|
-
throw new Error(`Task submission failed: ${error}`);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const data = await response.json();
|
|
101
|
-
return {
|
|
102
|
-
taskId: data.taskId || data.id,
|
|
103
|
-
output: data.output,
|
|
104
|
-
status: data.status,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Get task status
|
|
110
|
-
*/
|
|
111
|
-
async getTask(taskId: string): Promise<{ status: string; result?: unknown }> {
|
|
112
|
-
const response = await fetch(`${this.baseUrl}/tasks/${taskId}`, {
|
|
113
|
-
headers: {
|
|
114
|
-
...(this.apiKey && { Authorization: `Bearer ${this.apiKey}` }),
|
|
115
|
-
},
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
if (!response.ok) {
|
|
119
|
-
throw new Error(`Failed to get task: ${response.statusText}`);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return response.json();
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Stream task results as OpenAI-compatible chunks
|
|
127
|
-
*/
|
|
128
|
-
async *streamTaskResults(
|
|
129
|
-
taskId: string,
|
|
130
|
-
model: string
|
|
131
|
-
): AsyncIterable<ChatCompletionChunk> {
|
|
132
|
-
const response = await fetch(`${this.baseUrl}/tasks/${taskId}/stream`, {
|
|
133
|
-
headers: {
|
|
134
|
-
...(this.apiKey && { Authorization: `Bearer ${this.apiKey}` }),
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
if (!response.ok) {
|
|
139
|
-
throw new Error(`Stream failed: ${response.statusText}`);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (!response.body) {
|
|
143
|
-
throw new Error('Response body is null');
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const reader = response.body.getReader();
|
|
147
|
-
const decoder = new TextDecoder();
|
|
148
|
-
let buffer = '';
|
|
149
|
-
let lastContent = '';
|
|
150
|
-
const created = Math.floor(Date.now() / 1000);
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
while (true) {
|
|
154
|
-
const { done, value } = await reader.read();
|
|
155
|
-
|
|
156
|
-
if (done) {
|
|
157
|
-
yield {
|
|
158
|
-
id: taskId,
|
|
159
|
-
object: 'chat.completion.chunk',
|
|
160
|
-
created,
|
|
161
|
-
model,
|
|
162
|
-
choices: [
|
|
163
|
-
{
|
|
164
|
-
index: 0,
|
|
165
|
-
delta: {},
|
|
166
|
-
finish_reason: 'stop',
|
|
167
|
-
},
|
|
168
|
-
],
|
|
169
|
-
};
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
buffer += decoder.decode(value, { stream: true });
|
|
174
|
-
const lines = buffer.split('\n');
|
|
175
|
-
buffer = lines.pop() || '';
|
|
176
|
-
|
|
177
|
-
for (const line of lines) {
|
|
178
|
-
if (line.startsWith('data: ')) {
|
|
179
|
-
try {
|
|
180
|
-
const data = JSON.parse(line.slice(6));
|
|
181
|
-
|
|
182
|
-
if (Array.isArray(data) && data.length > 0) {
|
|
183
|
-
const latestCommit = data[0];
|
|
184
|
-
const newContent = latestCommit.result || '';
|
|
185
|
-
|
|
186
|
-
if (newContent && newContent !== lastContent) {
|
|
187
|
-
const delta = newContent.substring(lastContent.length);
|
|
188
|
-
lastContent = newContent;
|
|
189
|
-
|
|
190
|
-
if (delta) {
|
|
191
|
-
yield {
|
|
192
|
-
id: taskId,
|
|
193
|
-
object: 'chat.completion.chunk',
|
|
194
|
-
created,
|
|
195
|
-
model,
|
|
196
|
-
choices: [
|
|
197
|
-
{
|
|
198
|
-
index: 0,
|
|
199
|
-
delta: {
|
|
200
|
-
role: 'assistant',
|
|
201
|
-
content: delta,
|
|
202
|
-
},
|
|
203
|
-
finish_reason: null,
|
|
204
|
-
},
|
|
205
|
-
],
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
} catch {
|
|
211
|
-
// Skip invalid JSON
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
} finally {
|
|
217
|
-
reader.releaseLock();
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Stream raw task results (not OpenAI format)
|
|
223
|
-
*/
|
|
224
|
-
async *streamTaskRaw(taskId: string): AsyncIterable<unknown> {
|
|
225
|
-
const response = await fetch(`${this.baseUrl}/tasks/${taskId}/stream`, {
|
|
226
|
-
headers: {
|
|
227
|
-
...(this.apiKey && { Authorization: `Bearer ${this.apiKey}` }),
|
|
228
|
-
},
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
if (!response.ok) {
|
|
232
|
-
throw new Error(`Stream failed: ${response.statusText}`);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (!response.body) {
|
|
236
|
-
throw new Error('Response body is null');
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const reader = response.body.getReader();
|
|
240
|
-
const decoder = new TextDecoder();
|
|
241
|
-
let buffer = '';
|
|
242
|
-
|
|
243
|
-
try {
|
|
244
|
-
while (true) {
|
|
245
|
-
const { done, value } = await reader.read();
|
|
246
|
-
if (done) break;
|
|
247
|
-
|
|
248
|
-
buffer += decoder.decode(value, { stream: true });
|
|
249
|
-
const lines = buffer.split('\n');
|
|
250
|
-
buffer = lines.pop() || '';
|
|
251
|
-
|
|
252
|
-
for (const line of lines) {
|
|
253
|
-
if (line.startsWith('data: ')) {
|
|
254
|
-
try {
|
|
255
|
-
yield JSON.parse(line.slice(6));
|
|
256
|
-
} catch {
|
|
257
|
-
// Skip invalid JSON
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
} finally {
|
|
263
|
-
reader.releaseLock();
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Health check
|
|
269
|
-
*/
|
|
270
|
-
async healthCheck(): Promise<boolean> {
|
|
271
|
-
try {
|
|
272
|
-
const response = await fetch(`${this.baseUrl}/health`);
|
|
273
|
-
return response.ok;
|
|
274
|
-
} catch {
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Get node information
|
|
281
|
-
*/
|
|
282
|
-
async getNode(): Promise<unknown> {
|
|
283
|
-
const response = await fetch(`${this.baseUrl}/node`);
|
|
284
|
-
if (!response.ok) {
|
|
285
|
-
throw new Error(`Failed to get node info: ${response.statusText}`);
|
|
286
|
-
}
|
|
287
|
-
return response.json();
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Factory function to create a client
|
|
293
|
-
*/
|
|
294
|
-
export function createTaskNetworkClient(
|
|
295
|
-
config?: TaskNetworkConfig
|
|
296
|
-
): TaskNetworkClient {
|
|
297
|
-
return new TaskNetworkClient(config);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Default singleton instance
|
|
302
|
-
*/
|
|
303
|
-
export const taskNetworkClient = createTaskNetworkClient();
|
package/src/clients/user.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* User Client
|
|
3
|
-
* Client for interacting with user profile API
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { DEFAULT_TASK_NETWORK_URL, JSON_HEADERS } from '../utils/constants';
|
|
7
|
-
import { StacksSDKError } from '../utils/errors';
|
|
8
|
-
import type {
|
|
9
|
-
UserProfile,
|
|
10
|
-
UserProfileUpdateInput,
|
|
11
|
-
UserProfileResponse,
|
|
12
|
-
UserClientConfig,
|
|
13
|
-
} from '../types/user';
|
|
14
|
-
|
|
15
|
-
export type { UserClientConfig } from '../types/user';
|
|
16
|
-
|
|
17
|
-
export class UserClient {
|
|
18
|
-
private baseUrl: string;
|
|
19
|
-
|
|
20
|
-
constructor(config: UserClientConfig = {}) {
|
|
21
|
-
this.baseUrl = config.baseUrl || DEFAULT_TASK_NETWORK_URL;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
private get userUrl(): string {
|
|
25
|
-
return `${this.baseUrl}/user`;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Get user profile by MID
|
|
30
|
-
*/
|
|
31
|
-
async getProfile(mid: string): Promise<UserProfile | null> {
|
|
32
|
-
try {
|
|
33
|
-
const response = await fetch(`${this.userUrl}/profile/${mid}`);
|
|
34
|
-
|
|
35
|
-
if (!response.ok) {
|
|
36
|
-
if (response.status === 404) {
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
throw new StacksSDKError(
|
|
40
|
-
'bad_request:api',
|
|
41
|
-
`Failed to get user profile: ${response.statusText}`
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return response.json();
|
|
46
|
-
} catch (error) {
|
|
47
|
-
if (error instanceof StacksSDKError) throw error;
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Update user profile
|
|
54
|
-
*/
|
|
55
|
-
async updateProfile(mid: string, input: UserProfileUpdateInput): Promise<UserProfileResponse> {
|
|
56
|
-
const response = await fetch(`${this.userUrl}/profile/${mid}`, {
|
|
57
|
-
method: 'PUT',
|
|
58
|
-
headers: JSON_HEADERS,
|
|
59
|
-
body: JSON.stringify(input),
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
if (!response.ok) {
|
|
63
|
-
const data = await response.json().catch(() => ({}));
|
|
64
|
-
throw new StacksSDKError(
|
|
65
|
-
'bad_request:api',
|
|
66
|
-
data.error || `Failed to update user profile: ${response.statusText}`
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return response.json();
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Create a UserClient instance
|
|
76
|
-
*/
|
|
77
|
-
export function createUserClient(config: UserClientConfig = {}): UserClient {
|
|
78
|
-
return new UserClient(config);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Default user client instance
|
|
83
|
-
*/
|
|
84
|
-
export const userClient = createUserClient();
|