torque-assistant 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 +21 -0
- package/README.md +103 -0
- package/dist/errors.d.ts +25 -0
- package/dist/http.d.ts +8 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.esm.js +307 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +316 -0
- package/dist/index.js.map +1 -0
- package/dist/stream.d.ts +3 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Torque
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# torque-assistant
|
|
2
|
+
|
|
3
|
+
Official **server-side** client for Torque Assistant (Platform API v1).
|
|
4
|
+
|
|
5
|
+
Uses the same business API key as Checkout (`sk_live_…`). Targets BFF / backend integrators — not in-app browser sessions.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
yarn add torque-assistant @torquefi/types
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { createTorqueAssistantFromEnv } from 'torque-assistant'
|
|
17
|
+
|
|
18
|
+
const assistant = createTorqueAssistantFromEnv()
|
|
19
|
+
|
|
20
|
+
const reply = await assistant.chat({
|
|
21
|
+
messages: [{ role: 'user', content: 'Summarize my BTC exposure' }],
|
|
22
|
+
context: { walletAddress: '0x…', chainId: 8453 },
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
console.log(reply.content, reply.functionResults)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Streaming (SSE)
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
for await (const event of assistant.chatStream({
|
|
32
|
+
messages: [{ role: 'user', content: 'What moved today?' }],
|
|
33
|
+
context: { walletAddress: '0x…', chainId: 8453 },
|
|
34
|
+
})) {
|
|
35
|
+
if (event.type === 'delta') process.stdout.write(event.text)
|
|
36
|
+
if (event.type === 'done') console.log(event.functionResults)
|
|
37
|
+
if (event.type === 'error') throw new Error(event.message)
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Pass `signal` via the second argument to cancel:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
const controller = new AbortController()
|
|
45
|
+
const stream = assistant.chatStream(request, { signal: controller.signal })
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Configuration
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { createTorqueAssistant } from 'torque-assistant'
|
|
52
|
+
|
|
53
|
+
const assistant = createTorqueAssistant({
|
|
54
|
+
apiKey: process.env.TORQUE_API_KEY!,
|
|
55
|
+
baseUrl: 'https://app.torque.fi', // optional
|
|
56
|
+
timeout: 180_000, // optional — Gemini tool rounds can be slow
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Environment variables:** `TORQUE_API_KEY`, optional `TORQUE_BASE_URL`.
|
|
61
|
+
|
|
62
|
+
## Endpoint
|
|
63
|
+
|
|
64
|
+
| Method | SDK | HTTP |
|
|
65
|
+
|--------|-----|------|
|
|
66
|
+
| `chat` | JSON response | `POST /api/v1/assistant/chat` |
|
|
67
|
+
| `chatStream` | Async iterator over SSE | `POST /api/v1/assistant/chat?stream=true` |
|
|
68
|
+
|
|
69
|
+
## Errors
|
|
70
|
+
|
|
71
|
+
| Status | Code | Class |
|
|
72
|
+
|--------|------|-------|
|
|
73
|
+
| `402` | `assistant_credits_exhausted` | `TorqueAssistantCreditsError` |
|
|
74
|
+
| v1 JSON | `{ error: { code, message } }` | `TorqueAssistantError` |
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import {
|
|
78
|
+
TorqueAssistantCreditsError,
|
|
79
|
+
TorqueAssistantError,
|
|
80
|
+
ASSISTANT_CREDITS_ERROR_CODE,
|
|
81
|
+
} from 'torque-assistant'
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
await assistant.chat({ messages, context })
|
|
85
|
+
} catch (e) {
|
|
86
|
+
if (e instanceof TorqueAssistantCreditsError) {
|
|
87
|
+
console.log(e.remaining, '/', e.limit, 'messages left')
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Actions / signing
|
|
93
|
+
|
|
94
|
+
`functionResults` may include confirmable swap, transfer, lend, or borrow payloads. This SDK does **not** sign or submit transactions — implement confirmation in your client (same contract as in-app `AssistantTransactionHandler`).
|
|
95
|
+
|
|
96
|
+
## Docs
|
|
97
|
+
|
|
98
|
+
- [SDK roadmap](../../public/docs/developer/SDK_ROADMAP.md)
|
|
99
|
+
- [Torque API v1 — Assistant](../../public/docs/developer/TORQUE_API_V1.md)
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
MIT
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface TorqueAssistantErrorDetails {
|
|
2
|
+
code: string;
|
|
3
|
+
statusCode: number;
|
|
4
|
+
details?: Record<string, unknown>;
|
|
5
|
+
}
|
|
6
|
+
export declare class TorqueAssistantError extends Error {
|
|
7
|
+
code: string;
|
|
8
|
+
statusCode: number;
|
|
9
|
+
details?: Record<string, unknown>;
|
|
10
|
+
constructor(message: string, options: TorqueAssistantErrorDetails);
|
|
11
|
+
}
|
|
12
|
+
export declare class TorqueAssistantCreditsError extends TorqueAssistantError {
|
|
13
|
+
upgrade?: boolean;
|
|
14
|
+
remaining?: number;
|
|
15
|
+
limit?: number;
|
|
16
|
+
resetAt?: number | null;
|
|
17
|
+
constructor(message: string, options: {
|
|
18
|
+
statusCode: number;
|
|
19
|
+
upgrade?: boolean;
|
|
20
|
+
remaining?: number;
|
|
21
|
+
limit?: number;
|
|
22
|
+
resetAt?: number | null;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export declare function parseAssistantError(body: unknown, statusCode: number, fallbackMessage: string): TorqueAssistantError;
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AssistantChatPostBody, AssistantChatResponse } from '@torquefi/types/assistant';
|
|
2
|
+
export interface TorqueAssistantHttpConfig {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
timeout: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function torqueAssistantPost<T>(config: TorqueAssistantHttpConfig, path: string, body: AssistantChatPostBody, signal?: AbortSignal): Promise<T>;
|
|
8
|
+
export declare function torqueAssistantChat(config: TorqueAssistantHttpConfig, body: AssistantChatPostBody, signal?: AbortSignal): Promise<AssistantChatResponse>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AssistantChatPostBody, AssistantChatResponse, AssistantChatStreamEvent } from '@torquefi/types/assistant';
|
|
2
|
+
import type { TorquePlatformClientConfig } from '@torquefi/types/platform';
|
|
3
|
+
export type { TorquePlatformClientConfig as TorqueAssistantConfig } from '@torquefi/types/platform';
|
|
4
|
+
export interface TorqueAssistantOptions extends TorquePlatformClientConfig {
|
|
5
|
+
}
|
|
6
|
+
export type AssistantChatRequest = AssistantChatPostBody;
|
|
7
|
+
export interface AssistantChatStreamOptions {
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
export { TorqueAssistantError, TorqueAssistantCreditsError, } from './errors';
|
|
11
|
+
export { ASSISTANT_CREDITS_ERROR_CODE } from '@torquefi/types/assistant';
|
|
12
|
+
export type { AssistantChatContext, AssistantChatFunctionResult, AssistantChatMessage, AssistantChatPostBody, AssistantChatResponse, AssistantChatStreamEvent, } from '@torquefi/types/assistant';
|
|
13
|
+
export declare class TorqueAssistant {
|
|
14
|
+
private readonly http;
|
|
15
|
+
constructor(config: TorqueAssistantOptions);
|
|
16
|
+
/**
|
|
17
|
+
* Non-streaming chat. POST /api/v1/assistant/chat
|
|
18
|
+
*/
|
|
19
|
+
chat(request: AssistantChatRequest, options?: AssistantChatStreamOptions): Promise<AssistantChatResponse>;
|
|
20
|
+
/**
|
|
21
|
+
* Streaming chat over SSE. POST /api/v1/assistant/chat?stream=true
|
|
22
|
+
*/
|
|
23
|
+
chatStream(request: AssistantChatRequest, options?: AssistantChatStreamOptions): AsyncGenerator<AssistantChatStreamEvent>;
|
|
24
|
+
}
|
|
25
|
+
export declare function createTorqueAssistant(config: TorqueAssistantOptions): TorqueAssistant;
|
|
26
|
+
/**
|
|
27
|
+
* Reads TORQUE_API_KEY and optional TORQUE_BASE_URL from the environment.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createTorqueAssistantFromEnv(overrides?: Partial<TorqueAssistantOptions>): TorqueAssistant;
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { ASSISTANT_CREDITS_ERROR_CODE } from '@torquefi/types/assistant';
|
|
2
|
+
export { ASSISTANT_CREDITS_ERROR_CODE } from '@torquefi/types/assistant';
|
|
3
|
+
|
|
4
|
+
class TorqueAssistantError extends Error {
|
|
5
|
+
constructor(message, options) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'TorqueAssistantError';
|
|
8
|
+
this.code = options.code;
|
|
9
|
+
this.statusCode = options.statusCode;
|
|
10
|
+
this.details = options.details;
|
|
11
|
+
Object.setPrototypeOf(this, TorqueAssistantError.prototype);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
class TorqueAssistantCreditsError extends TorqueAssistantError {
|
|
15
|
+
constructor(message, options) {
|
|
16
|
+
super(message, {
|
|
17
|
+
code: ASSISTANT_CREDITS_ERROR_CODE,
|
|
18
|
+
statusCode: options.statusCode,
|
|
19
|
+
details: {
|
|
20
|
+
upgrade: options.upgrade,
|
|
21
|
+
remaining: options.remaining,
|
|
22
|
+
limit: options.limit,
|
|
23
|
+
resetAt: options.resetAt,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
this.name = 'TorqueAssistantCreditsError';
|
|
27
|
+
this.upgrade = options.upgrade;
|
|
28
|
+
this.remaining = options.remaining;
|
|
29
|
+
this.limit = options.limit;
|
|
30
|
+
this.resetAt = options.resetAt;
|
|
31
|
+
Object.setPrototypeOf(this, TorqueAssistantCreditsError.prototype);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function parseAssistantError(body, statusCode, fallbackMessage) {
|
|
35
|
+
const payload = body;
|
|
36
|
+
if (statusCode === 402 &&
|
|
37
|
+
typeof payload?.error === 'string' &&
|
|
38
|
+
payload.error === ASSISTANT_CREDITS_ERROR_CODE) {
|
|
39
|
+
return new TorqueAssistantCreditsError(typeof payload.message === 'string' ? payload.message : fallbackMessage, {
|
|
40
|
+
statusCode,
|
|
41
|
+
upgrade: payload.upgrade,
|
|
42
|
+
remaining: payload.remaining,
|
|
43
|
+
limit: payload.limit,
|
|
44
|
+
resetAt: payload.resetAt,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (payload?.error && typeof payload.error === 'object') {
|
|
48
|
+
const err = payload.error;
|
|
49
|
+
return new TorqueAssistantError(typeof err.message === 'string' ? err.message : fallbackMessage, {
|
|
50
|
+
code: typeof err.code === 'string' ? err.code : 'API_ERROR',
|
|
51
|
+
statusCode,
|
|
52
|
+
details: err.details,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (typeof payload?.error === 'string') {
|
|
56
|
+
return new TorqueAssistantError(typeof payload.message === 'string' ? payload.message : fallbackMessage, {
|
|
57
|
+
code: payload.error,
|
|
58
|
+
statusCode,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return new TorqueAssistantError(fallbackMessage, {
|
|
62
|
+
code: 'API_ERROR',
|
|
63
|
+
statusCode,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function torqueAssistantPost(config, path, body, signal) {
|
|
68
|
+
const url = `${config.baseUrl}${path}`;
|
|
69
|
+
const controller = new AbortController();
|
|
70
|
+
const timeoutId = setTimeout(() => controller.abort(), config.timeout);
|
|
71
|
+
const onAbort = () => controller.abort();
|
|
72
|
+
if (signal) {
|
|
73
|
+
if (signal.aborted)
|
|
74
|
+
controller.abort();
|
|
75
|
+
else
|
|
76
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const response = await fetch(url, {
|
|
80
|
+
method: 'POST',
|
|
81
|
+
headers: {
|
|
82
|
+
Accept: 'application/json',
|
|
83
|
+
'Content-Type': 'application/json',
|
|
84
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
85
|
+
},
|
|
86
|
+
body: JSON.stringify(body),
|
|
87
|
+
signal: controller.signal,
|
|
88
|
+
});
|
|
89
|
+
clearTimeout(timeoutId);
|
|
90
|
+
signal?.removeEventListener('abort', onAbort);
|
|
91
|
+
const payload = await response.json().catch(() => ({}));
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
throw parseAssistantError(payload, response.status, `HTTP ${response.status}: ${response.statusText}`);
|
|
94
|
+
}
|
|
95
|
+
return payload;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
clearTimeout(timeoutId);
|
|
99
|
+
signal?.removeEventListener('abort', onAbort);
|
|
100
|
+
if (error instanceof TorqueAssistantError) {
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
if (error instanceof Error) {
|
|
104
|
+
if (error.name === 'AbortError') {
|
|
105
|
+
throw new TorqueAssistantError('Request timeout', {
|
|
106
|
+
code: 'TIMEOUT',
|
|
107
|
+
statusCode: 408,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
throw new TorqueAssistantError(error.message, {
|
|
111
|
+
code: 'NETWORK_ERROR',
|
|
112
|
+
statusCode: 500,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
throw new TorqueAssistantError('Request failed', {
|
|
116
|
+
code: 'UNKNOWN_ERROR',
|
|
117
|
+
statusCode: 500,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async function torqueAssistantChat(config, body, signal) {
|
|
122
|
+
return torqueAssistantPost(config, '/api/v1/assistant/chat', body, signal);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function parseJsonContent(content) {
|
|
126
|
+
if (typeof content === 'string')
|
|
127
|
+
return content;
|
|
128
|
+
if (Array.isArray(content)) {
|
|
129
|
+
return content
|
|
130
|
+
.map((part) => part?.text ?? '')
|
|
131
|
+
.join('');
|
|
132
|
+
}
|
|
133
|
+
return '';
|
|
134
|
+
}
|
|
135
|
+
function* eventsFromJsonPayload(payload) {
|
|
136
|
+
const text = parseJsonContent(payload.content);
|
|
137
|
+
if (text) {
|
|
138
|
+
yield { type: 'delta', text };
|
|
139
|
+
}
|
|
140
|
+
yield { type: 'done', functionResults: payload.functionResults };
|
|
141
|
+
}
|
|
142
|
+
async function* torqueAssistantChatStream(config, body, signal) {
|
|
143
|
+
const url = `${config.baseUrl}/api/v1/assistant/chat?stream=true`;
|
|
144
|
+
const controller = new AbortController();
|
|
145
|
+
const timeoutId = setTimeout(() => controller.abort(), config.timeout);
|
|
146
|
+
const onAbort = () => controller.abort();
|
|
147
|
+
if (signal) {
|
|
148
|
+
if (signal.aborted)
|
|
149
|
+
controller.abort();
|
|
150
|
+
else
|
|
151
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
const response = await fetch(url, {
|
|
155
|
+
method: 'POST',
|
|
156
|
+
headers: {
|
|
157
|
+
Accept: 'text/event-stream, application/json',
|
|
158
|
+
'Content-Type': 'application/json',
|
|
159
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
160
|
+
},
|
|
161
|
+
body: JSON.stringify(body),
|
|
162
|
+
signal: controller.signal,
|
|
163
|
+
});
|
|
164
|
+
clearTimeout(timeoutId);
|
|
165
|
+
signal?.removeEventListener('abort', onAbort);
|
|
166
|
+
if (!response.ok) {
|
|
167
|
+
const payload = await response.json().catch(() => ({}));
|
|
168
|
+
throw parseAssistantError(payload, response.status, `HTTP ${response.status}: ${response.statusText}`);
|
|
169
|
+
}
|
|
170
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
171
|
+
if (contentType.includes('application/json')) {
|
|
172
|
+
const payload = (await response.json().catch(() => ({})));
|
|
173
|
+
yield* eventsFromJsonPayload(payload);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (!response.body) {
|
|
177
|
+
yield { type: 'error', message: 'No response body.' };
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const reader = response.body.getReader();
|
|
181
|
+
const decoder = new TextDecoder();
|
|
182
|
+
let buf = '';
|
|
183
|
+
while (true) {
|
|
184
|
+
const { done, value } = await reader.read();
|
|
185
|
+
if (done)
|
|
186
|
+
break;
|
|
187
|
+
buf += decoder.decode(value, { stream: true });
|
|
188
|
+
const lines = buf.split('\n');
|
|
189
|
+
buf = lines.pop() ?? '';
|
|
190
|
+
for (const line of lines) {
|
|
191
|
+
if (!line.startsWith('data: '))
|
|
192
|
+
continue;
|
|
193
|
+
const raw = line.slice(6).trim();
|
|
194
|
+
if (raw === '[DONE]') {
|
|
195
|
+
yield { type: 'done' };
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
let event;
|
|
199
|
+
try {
|
|
200
|
+
event = JSON.parse(raw);
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (event.type === 'delta' && event.text) {
|
|
206
|
+
yield { type: 'delta', text: event.text };
|
|
207
|
+
}
|
|
208
|
+
else if (event.type === 'correction' && event.text) {
|
|
209
|
+
yield { type: 'correction', text: event.text };
|
|
210
|
+
}
|
|
211
|
+
else if (event.type === 'done') {
|
|
212
|
+
yield { type: 'done', functionResults: event.functionResults };
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
else if (event.type === 'error') {
|
|
216
|
+
yield { type: 'error', message: event.message };
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
yield { type: 'done' };
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
clearTimeout(timeoutId);
|
|
225
|
+
signal?.removeEventListener('abort', onAbort);
|
|
226
|
+
if (error instanceof TorqueAssistantError) {
|
|
227
|
+
throw error;
|
|
228
|
+
}
|
|
229
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
230
|
+
yield { type: 'done' };
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (error instanceof Error) {
|
|
234
|
+
throw new TorqueAssistantError(error.message, {
|
|
235
|
+
code: 'NETWORK_ERROR',
|
|
236
|
+
statusCode: 500,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
throw new TorqueAssistantError('Stream failed', {
|
|
240
|
+
code: 'UNKNOWN_ERROR',
|
|
241
|
+
statusCode: 500,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function validateConfig(config) {
|
|
247
|
+
if (!config.apiKey?.trim()) {
|
|
248
|
+
throw new TorqueAssistantError('API key is required', {
|
|
249
|
+
code: 'INVALID_CONFIG',
|
|
250
|
+
statusCode: 400,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
if (config.timeout != null && (typeof config.timeout !== 'number' || config.timeout <= 0)) {
|
|
254
|
+
throw new TorqueAssistantError('Timeout must be a positive number', {
|
|
255
|
+
code: 'INVALID_CONFIG',
|
|
256
|
+
statusCode: 400,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function toHttpConfig(config) {
|
|
261
|
+
return {
|
|
262
|
+
apiKey: config.apiKey.trim(),
|
|
263
|
+
baseUrl: (config.baseUrl || 'https://app.torque.fi').replace(/\/$/, ''),
|
|
264
|
+
timeout: config.timeout ?? 180000,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
class TorqueAssistant {
|
|
268
|
+
constructor(config) {
|
|
269
|
+
validateConfig(config);
|
|
270
|
+
this.http = toHttpConfig(config);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Non-streaming chat. POST /api/v1/assistant/chat
|
|
274
|
+
*/
|
|
275
|
+
async chat(request, options) {
|
|
276
|
+
return torqueAssistantChat(this.http, request, options?.signal);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Streaming chat over SSE. POST /api/v1/assistant/chat?stream=true
|
|
280
|
+
*/
|
|
281
|
+
chatStream(request, options) {
|
|
282
|
+
return torqueAssistantChatStream(this.http, request, options?.signal);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function createTorqueAssistant(config) {
|
|
286
|
+
return new TorqueAssistant(config);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Reads TORQUE_API_KEY and optional TORQUE_BASE_URL from the environment.
|
|
290
|
+
*/
|
|
291
|
+
function createTorqueAssistantFromEnv(overrides) {
|
|
292
|
+
const apiKey = process.env.TORQUE_API_KEY || overrides?.apiKey;
|
|
293
|
+
if (!apiKey) {
|
|
294
|
+
throw new TorqueAssistantError('TORQUE_API_KEY environment variable is required', {
|
|
295
|
+
code: 'MISSING_ENV_VARS',
|
|
296
|
+
statusCode: 400,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
return new TorqueAssistant({
|
|
300
|
+
apiKey,
|
|
301
|
+
baseUrl: process.env.TORQUE_BASE_URL || overrides?.baseUrl,
|
|
302
|
+
timeout: overrides?.timeout,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export { TorqueAssistant, TorqueAssistantCreditsError, TorqueAssistantError, createTorqueAssistant, createTorqueAssistantFromEnv };
|
|
307
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/errors.ts","../src/http.ts","../src/stream.ts","../src/index.ts"],"sourcesContent":["import { ASSISTANT_CREDITS_ERROR_CODE } from '@torquefi/types/assistant'\n\nexport interface TorqueAssistantErrorDetails {\n code: string\n statusCode: number\n details?: Record<string, unknown>\n}\n\nexport class TorqueAssistantError extends Error {\n code: string\n statusCode: number\n details?: Record<string, unknown>\n\n constructor(message: string, options: TorqueAssistantErrorDetails) {\n super(message)\n this.name = 'TorqueAssistantError'\n this.code = options.code\n this.statusCode = options.statusCode\n this.details = options.details\n Object.setPrototypeOf(this, TorqueAssistantError.prototype)\n }\n}\n\nexport class TorqueAssistantCreditsError extends TorqueAssistantError {\n upgrade?: boolean\n remaining?: number\n limit?: number\n resetAt?: number | null\n\n constructor(\n message: string,\n options: {\n statusCode: number\n upgrade?: boolean\n remaining?: number\n limit?: number\n resetAt?: number | null\n },\n ) {\n super(message, {\n code: ASSISTANT_CREDITS_ERROR_CODE,\n statusCode: options.statusCode,\n details: {\n upgrade: options.upgrade,\n remaining: options.remaining,\n limit: options.limit,\n resetAt: options.resetAt,\n },\n })\n this.name = 'TorqueAssistantCreditsError'\n this.upgrade = options.upgrade\n this.remaining = options.remaining\n this.limit = options.limit\n this.resetAt = options.resetAt\n Object.setPrototypeOf(this, TorqueAssistantCreditsError.prototype)\n }\n}\n\nexport function parseAssistantError(\n body: unknown,\n statusCode: number,\n fallbackMessage: string,\n): TorqueAssistantError {\n const payload = body as {\n error?: string | { code?: string; message?: string; details?: Record<string, unknown> }\n message?: string\n upgrade?: boolean\n remaining?: number\n limit?: number\n resetAt?: number | null\n } | null\n\n if (\n statusCode === 402 &&\n typeof payload?.error === 'string' &&\n payload.error === ASSISTANT_CREDITS_ERROR_CODE\n ) {\n return new TorqueAssistantCreditsError(\n typeof payload.message === 'string' ? payload.message : fallbackMessage,\n {\n statusCode,\n upgrade: payload.upgrade,\n remaining: payload.remaining,\n limit: payload.limit,\n resetAt: payload.resetAt,\n },\n )\n }\n\n if (payload?.error && typeof payload.error === 'object') {\n const err = payload.error\n return new TorqueAssistantError(\n typeof err.message === 'string' ? err.message : fallbackMessage,\n {\n code: typeof err.code === 'string' ? err.code : 'API_ERROR',\n statusCode,\n details: err.details,\n },\n )\n }\n\n if (typeof payload?.error === 'string') {\n return new TorqueAssistantError(\n typeof payload.message === 'string' ? payload.message : fallbackMessage,\n {\n code: payload.error,\n statusCode,\n },\n )\n }\n\n return new TorqueAssistantError(fallbackMessage, {\n code: 'API_ERROR',\n statusCode,\n })\n}\n","import type { AssistantChatPostBody, AssistantChatResponse } from '@torquefi/types/assistant'\n\nimport { parseAssistantError, TorqueAssistantError } from './errors'\n\nexport interface TorqueAssistantHttpConfig {\n apiKey: string\n baseUrl: string\n timeout: number\n}\n\nexport async function torqueAssistantPost<T>(\n config: TorqueAssistantHttpConfig,\n path: string,\n body: AssistantChatPostBody,\n signal?: AbortSignal,\n): Promise<T> {\n const url = `${config.baseUrl}${path}`\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), config.timeout)\n\n const onAbort = () => controller.abort()\n if (signal) {\n if (signal.aborted) controller.abort()\n else signal.addEventListener('abort', onAbort, { once: true })\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n signal?.removeEventListener('abort', onAbort)\n\n const payload: unknown = await response.json().catch(() => ({}))\n\n if (!response.ok) {\n throw parseAssistantError(\n payload,\n response.status,\n `HTTP ${response.status}: ${response.statusText}`,\n )\n }\n\n return payload as T\n } catch (error) {\n clearTimeout(timeoutId)\n signal?.removeEventListener('abort', onAbort)\n\n if (error instanceof TorqueAssistantError) {\n throw error\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new TorqueAssistantError('Request timeout', {\n code: 'TIMEOUT',\n statusCode: 408,\n })\n }\n throw new TorqueAssistantError(error.message, {\n code: 'NETWORK_ERROR',\n statusCode: 500,\n })\n }\n\n throw new TorqueAssistantError('Request failed', {\n code: 'UNKNOWN_ERROR',\n statusCode: 500,\n })\n }\n}\n\nexport async function torqueAssistantChat(\n config: TorqueAssistantHttpConfig,\n body: AssistantChatPostBody,\n signal?: AbortSignal,\n): Promise<AssistantChatResponse> {\n return torqueAssistantPost<AssistantChatResponse>(\n config,\n '/api/v1/assistant/chat',\n body,\n signal,\n )\n}\n","import type {\n AssistantChatFunctionResult,\n AssistantChatPostBody,\n AssistantChatStreamEvent,\n} from '@torquefi/types/assistant'\n\nimport { parseAssistantError, TorqueAssistantError } from './errors'\nimport type { TorqueAssistantHttpConfig } from './http'\n\ntype AssistantChatSsePayload = {\n type: string\n text?: string\n message?: string\n functionResults?: AssistantChatFunctionResult[]\n}\n\nfunction parseJsonContent(content: unknown): string {\n if (typeof content === 'string') return content\n if (Array.isArray(content)) {\n return (content as Array<{ text?: string }>)\n .map((part) => part?.text ?? '')\n .join('')\n }\n return ''\n}\n\nfunction* eventsFromJsonPayload(payload: {\n content?: unknown\n functionResults?: AssistantChatFunctionResult[]\n}): Generator<AssistantChatStreamEvent> {\n const text = parseJsonContent(payload.content)\n if (text) {\n yield { type: 'delta', text }\n }\n yield { type: 'done', functionResults: payload.functionResults }\n}\n\nexport async function* torqueAssistantChatStream(\n config: TorqueAssistantHttpConfig,\n body: AssistantChatPostBody,\n signal?: AbortSignal,\n): AsyncGenerator<AssistantChatStreamEvent> {\n const url = `${config.baseUrl}/api/v1/assistant/chat?stream=true`\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), config.timeout)\n\n const onAbort = () => controller.abort()\n if (signal) {\n if (signal.aborted) controller.abort()\n else signal.addEventListener('abort', onAbort, { once: true })\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n Accept: 'text/event-stream, application/json',\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n signal?.removeEventListener('abort', onAbort)\n\n if (!response.ok) {\n const payload: unknown = await response.json().catch(() => ({}))\n throw parseAssistantError(\n payload,\n response.status,\n `HTTP ${response.status}: ${response.statusText}`,\n )\n }\n\n const contentType = response.headers.get('content-type') ?? ''\n\n if (contentType.includes('application/json')) {\n const payload = (await response.json().catch(() => ({}))) as {\n content?: unknown\n functionResults?: AssistantChatFunctionResult[]\n }\n yield* eventsFromJsonPayload(payload)\n return\n }\n\n if (!response.body) {\n yield { type: 'error', message: 'No response body.' }\n return\n }\n\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n buf += decoder.decode(value, { stream: true })\n const lines = buf.split('\\n')\n buf = lines.pop() ?? ''\n\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue\n\n const raw = line.slice(6).trim()\n if (raw === '[DONE]') {\n yield { type: 'done' }\n return\n }\n\n let event: AssistantChatSsePayload\n try {\n event = JSON.parse(raw) as AssistantChatSsePayload\n } catch {\n continue\n }\n\n if (event.type === 'delta' && event.text) {\n yield { type: 'delta', text: event.text }\n } else if (event.type === 'correction' && event.text) {\n yield { type: 'correction', text: event.text }\n } else if (event.type === 'done') {\n yield { type: 'done', functionResults: event.functionResults }\n return\n } else if (event.type === 'error') {\n yield { type: 'error', message: event.message }\n return\n }\n }\n }\n\n yield { type: 'done' }\n } catch (error) {\n clearTimeout(timeoutId)\n signal?.removeEventListener('abort', onAbort)\n\n if (error instanceof TorqueAssistantError) {\n throw error\n }\n\n if (error instanceof Error && error.name === 'AbortError') {\n yield { type: 'done' }\n return\n }\n\n if (error instanceof Error) {\n throw new TorqueAssistantError(error.message, {\n code: 'NETWORK_ERROR',\n statusCode: 500,\n })\n }\n\n throw new TorqueAssistantError('Stream failed', {\n code: 'UNKNOWN_ERROR',\n statusCode: 500,\n })\n }\n}\n","import type { AssistantChatPostBody, AssistantChatResponse, AssistantChatStreamEvent } from '@torquefi/types/assistant'\nimport type { TorquePlatformClientConfig } from '@torquefi/types/platform'\n\nimport { TorqueAssistantCreditsError, TorqueAssistantError } from './errors'\nimport { torqueAssistantChat, type TorqueAssistantHttpConfig } from './http'\nimport { torqueAssistantChatStream } from './stream'\n\nexport type { TorquePlatformClientConfig as TorqueAssistantConfig } from '@torquefi/types/platform'\n\nexport interface TorqueAssistantOptions extends TorquePlatformClientConfig {}\n\nexport type AssistantChatRequest = AssistantChatPostBody\n\nexport interface AssistantChatStreamOptions {\n signal?: AbortSignal\n}\n\nexport {\n TorqueAssistantError,\n TorqueAssistantCreditsError,\n} from './errors'\nexport { ASSISTANT_CREDITS_ERROR_CODE } from '@torquefi/types/assistant'\nexport type {\n AssistantChatContext,\n AssistantChatFunctionResult,\n AssistantChatMessage,\n AssistantChatPostBody,\n AssistantChatResponse,\n AssistantChatStreamEvent,\n} from '@torquefi/types/assistant'\n\nfunction validateConfig(config: TorqueAssistantOptions): void {\n if (!config.apiKey?.trim()) {\n throw new TorqueAssistantError('API key is required', {\n code: 'INVALID_CONFIG',\n statusCode: 400,\n })\n }\n if (config.timeout != null && (typeof config.timeout !== 'number' || config.timeout <= 0)) {\n throw new TorqueAssistantError('Timeout must be a positive number', {\n code: 'INVALID_CONFIG',\n statusCode: 400,\n })\n }\n}\n\nfunction toHttpConfig(config: TorqueAssistantOptions): TorqueAssistantHttpConfig {\n return {\n apiKey: config.apiKey.trim(),\n baseUrl: (config.baseUrl || 'https://app.torque.fi').replace(/\\/$/, ''),\n timeout: config.timeout ?? 180_000,\n }\n}\n\nexport class TorqueAssistant {\n private readonly http: TorqueAssistantHttpConfig\n\n constructor(config: TorqueAssistantOptions) {\n validateConfig(config)\n this.http = toHttpConfig(config)\n }\n\n /**\n * Non-streaming chat. POST /api/v1/assistant/chat\n */\n async chat(\n request: AssistantChatRequest,\n options?: AssistantChatStreamOptions,\n ): Promise<AssistantChatResponse> {\n return torqueAssistantChat(this.http, request, options?.signal)\n }\n\n /**\n * Streaming chat over SSE. POST /api/v1/assistant/chat?stream=true\n */\n chatStream(\n request: AssistantChatRequest,\n options?: AssistantChatStreamOptions,\n ): AsyncGenerator<AssistantChatStreamEvent> {\n return torqueAssistantChatStream(this.http, request, options?.signal)\n }\n}\n\nexport function createTorqueAssistant(config: TorqueAssistantOptions): TorqueAssistant {\n return new TorqueAssistant(config)\n}\n\n/**\n * Reads TORQUE_API_KEY and optional TORQUE_BASE_URL from the environment.\n */\nexport function createTorqueAssistantFromEnv(\n overrides?: Partial<TorqueAssistantOptions>,\n): TorqueAssistant {\n const apiKey = process.env.TORQUE_API_KEY || overrides?.apiKey\n if (!apiKey) {\n throw new TorqueAssistantError('TORQUE_API_KEY environment variable is required', {\n code: 'MISSING_ENV_VARS',\n statusCode: 400,\n })\n }\n\n return new TorqueAssistant({\n apiKey,\n baseUrl: process.env.TORQUE_BASE_URL || overrides?.baseUrl,\n timeout: overrides?.timeout,\n })\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var assistant = require('@torquefi/types/assistant');
|
|
4
|
+
|
|
5
|
+
class TorqueAssistantError extends Error {
|
|
6
|
+
constructor(message, options) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'TorqueAssistantError';
|
|
9
|
+
this.code = options.code;
|
|
10
|
+
this.statusCode = options.statusCode;
|
|
11
|
+
this.details = options.details;
|
|
12
|
+
Object.setPrototypeOf(this, TorqueAssistantError.prototype);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
class TorqueAssistantCreditsError extends TorqueAssistantError {
|
|
16
|
+
constructor(message, options) {
|
|
17
|
+
super(message, {
|
|
18
|
+
code: assistant.ASSISTANT_CREDITS_ERROR_CODE,
|
|
19
|
+
statusCode: options.statusCode,
|
|
20
|
+
details: {
|
|
21
|
+
upgrade: options.upgrade,
|
|
22
|
+
remaining: options.remaining,
|
|
23
|
+
limit: options.limit,
|
|
24
|
+
resetAt: options.resetAt,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
this.name = 'TorqueAssistantCreditsError';
|
|
28
|
+
this.upgrade = options.upgrade;
|
|
29
|
+
this.remaining = options.remaining;
|
|
30
|
+
this.limit = options.limit;
|
|
31
|
+
this.resetAt = options.resetAt;
|
|
32
|
+
Object.setPrototypeOf(this, TorqueAssistantCreditsError.prototype);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function parseAssistantError(body, statusCode, fallbackMessage) {
|
|
36
|
+
const payload = body;
|
|
37
|
+
if (statusCode === 402 &&
|
|
38
|
+
typeof payload?.error === 'string' &&
|
|
39
|
+
payload.error === assistant.ASSISTANT_CREDITS_ERROR_CODE) {
|
|
40
|
+
return new TorqueAssistantCreditsError(typeof payload.message === 'string' ? payload.message : fallbackMessage, {
|
|
41
|
+
statusCode,
|
|
42
|
+
upgrade: payload.upgrade,
|
|
43
|
+
remaining: payload.remaining,
|
|
44
|
+
limit: payload.limit,
|
|
45
|
+
resetAt: payload.resetAt,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (payload?.error && typeof payload.error === 'object') {
|
|
49
|
+
const err = payload.error;
|
|
50
|
+
return new TorqueAssistantError(typeof err.message === 'string' ? err.message : fallbackMessage, {
|
|
51
|
+
code: typeof err.code === 'string' ? err.code : 'API_ERROR',
|
|
52
|
+
statusCode,
|
|
53
|
+
details: err.details,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (typeof payload?.error === 'string') {
|
|
57
|
+
return new TorqueAssistantError(typeof payload.message === 'string' ? payload.message : fallbackMessage, {
|
|
58
|
+
code: payload.error,
|
|
59
|
+
statusCode,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return new TorqueAssistantError(fallbackMessage, {
|
|
63
|
+
code: 'API_ERROR',
|
|
64
|
+
statusCode,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function torqueAssistantPost(config, path, body, signal) {
|
|
69
|
+
const url = `${config.baseUrl}${path}`;
|
|
70
|
+
const controller = new AbortController();
|
|
71
|
+
const timeoutId = setTimeout(() => controller.abort(), config.timeout);
|
|
72
|
+
const onAbort = () => controller.abort();
|
|
73
|
+
if (signal) {
|
|
74
|
+
if (signal.aborted)
|
|
75
|
+
controller.abort();
|
|
76
|
+
else
|
|
77
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const response = await fetch(url, {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: {
|
|
83
|
+
Accept: 'application/json',
|
|
84
|
+
'Content-Type': 'application/json',
|
|
85
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
86
|
+
},
|
|
87
|
+
body: JSON.stringify(body),
|
|
88
|
+
signal: controller.signal,
|
|
89
|
+
});
|
|
90
|
+
clearTimeout(timeoutId);
|
|
91
|
+
signal?.removeEventListener('abort', onAbort);
|
|
92
|
+
const payload = await response.json().catch(() => ({}));
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
throw parseAssistantError(payload, response.status, `HTTP ${response.status}: ${response.statusText}`);
|
|
95
|
+
}
|
|
96
|
+
return payload;
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
clearTimeout(timeoutId);
|
|
100
|
+
signal?.removeEventListener('abort', onAbort);
|
|
101
|
+
if (error instanceof TorqueAssistantError) {
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
if (error instanceof Error) {
|
|
105
|
+
if (error.name === 'AbortError') {
|
|
106
|
+
throw new TorqueAssistantError('Request timeout', {
|
|
107
|
+
code: 'TIMEOUT',
|
|
108
|
+
statusCode: 408,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
throw new TorqueAssistantError(error.message, {
|
|
112
|
+
code: 'NETWORK_ERROR',
|
|
113
|
+
statusCode: 500,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
throw new TorqueAssistantError('Request failed', {
|
|
117
|
+
code: 'UNKNOWN_ERROR',
|
|
118
|
+
statusCode: 500,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function torqueAssistantChat(config, body, signal) {
|
|
123
|
+
return torqueAssistantPost(config, '/api/v1/assistant/chat', body, signal);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function parseJsonContent(content) {
|
|
127
|
+
if (typeof content === 'string')
|
|
128
|
+
return content;
|
|
129
|
+
if (Array.isArray(content)) {
|
|
130
|
+
return content
|
|
131
|
+
.map((part) => part?.text ?? '')
|
|
132
|
+
.join('');
|
|
133
|
+
}
|
|
134
|
+
return '';
|
|
135
|
+
}
|
|
136
|
+
function* eventsFromJsonPayload(payload) {
|
|
137
|
+
const text = parseJsonContent(payload.content);
|
|
138
|
+
if (text) {
|
|
139
|
+
yield { type: 'delta', text };
|
|
140
|
+
}
|
|
141
|
+
yield { type: 'done', functionResults: payload.functionResults };
|
|
142
|
+
}
|
|
143
|
+
async function* torqueAssistantChatStream(config, body, signal) {
|
|
144
|
+
const url = `${config.baseUrl}/api/v1/assistant/chat?stream=true`;
|
|
145
|
+
const controller = new AbortController();
|
|
146
|
+
const timeoutId = setTimeout(() => controller.abort(), config.timeout);
|
|
147
|
+
const onAbort = () => controller.abort();
|
|
148
|
+
if (signal) {
|
|
149
|
+
if (signal.aborted)
|
|
150
|
+
controller.abort();
|
|
151
|
+
else
|
|
152
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const response = await fetch(url, {
|
|
156
|
+
method: 'POST',
|
|
157
|
+
headers: {
|
|
158
|
+
Accept: 'text/event-stream, application/json',
|
|
159
|
+
'Content-Type': 'application/json',
|
|
160
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
161
|
+
},
|
|
162
|
+
body: JSON.stringify(body),
|
|
163
|
+
signal: controller.signal,
|
|
164
|
+
});
|
|
165
|
+
clearTimeout(timeoutId);
|
|
166
|
+
signal?.removeEventListener('abort', onAbort);
|
|
167
|
+
if (!response.ok) {
|
|
168
|
+
const payload = await response.json().catch(() => ({}));
|
|
169
|
+
throw parseAssistantError(payload, response.status, `HTTP ${response.status}: ${response.statusText}`);
|
|
170
|
+
}
|
|
171
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
172
|
+
if (contentType.includes('application/json')) {
|
|
173
|
+
const payload = (await response.json().catch(() => ({})));
|
|
174
|
+
yield* eventsFromJsonPayload(payload);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (!response.body) {
|
|
178
|
+
yield { type: 'error', message: 'No response body.' };
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const reader = response.body.getReader();
|
|
182
|
+
const decoder = new TextDecoder();
|
|
183
|
+
let buf = '';
|
|
184
|
+
while (true) {
|
|
185
|
+
const { done, value } = await reader.read();
|
|
186
|
+
if (done)
|
|
187
|
+
break;
|
|
188
|
+
buf += decoder.decode(value, { stream: true });
|
|
189
|
+
const lines = buf.split('\n');
|
|
190
|
+
buf = lines.pop() ?? '';
|
|
191
|
+
for (const line of lines) {
|
|
192
|
+
if (!line.startsWith('data: '))
|
|
193
|
+
continue;
|
|
194
|
+
const raw = line.slice(6).trim();
|
|
195
|
+
if (raw === '[DONE]') {
|
|
196
|
+
yield { type: 'done' };
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
let event;
|
|
200
|
+
try {
|
|
201
|
+
event = JSON.parse(raw);
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (event.type === 'delta' && event.text) {
|
|
207
|
+
yield { type: 'delta', text: event.text };
|
|
208
|
+
}
|
|
209
|
+
else if (event.type === 'correction' && event.text) {
|
|
210
|
+
yield { type: 'correction', text: event.text };
|
|
211
|
+
}
|
|
212
|
+
else if (event.type === 'done') {
|
|
213
|
+
yield { type: 'done', functionResults: event.functionResults };
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
else if (event.type === 'error') {
|
|
217
|
+
yield { type: 'error', message: event.message };
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
yield { type: 'done' };
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
clearTimeout(timeoutId);
|
|
226
|
+
signal?.removeEventListener('abort', onAbort);
|
|
227
|
+
if (error instanceof TorqueAssistantError) {
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
231
|
+
yield { type: 'done' };
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
if (error instanceof Error) {
|
|
235
|
+
throw new TorqueAssistantError(error.message, {
|
|
236
|
+
code: 'NETWORK_ERROR',
|
|
237
|
+
statusCode: 500,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
throw new TorqueAssistantError('Stream failed', {
|
|
241
|
+
code: 'UNKNOWN_ERROR',
|
|
242
|
+
statusCode: 500,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function validateConfig(config) {
|
|
248
|
+
if (!config.apiKey?.trim()) {
|
|
249
|
+
throw new TorqueAssistantError('API key is required', {
|
|
250
|
+
code: 'INVALID_CONFIG',
|
|
251
|
+
statusCode: 400,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
if (config.timeout != null && (typeof config.timeout !== 'number' || config.timeout <= 0)) {
|
|
255
|
+
throw new TorqueAssistantError('Timeout must be a positive number', {
|
|
256
|
+
code: 'INVALID_CONFIG',
|
|
257
|
+
statusCode: 400,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function toHttpConfig(config) {
|
|
262
|
+
return {
|
|
263
|
+
apiKey: config.apiKey.trim(),
|
|
264
|
+
baseUrl: (config.baseUrl || 'https://app.torque.fi').replace(/\/$/, ''),
|
|
265
|
+
timeout: config.timeout ?? 180000,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
class TorqueAssistant {
|
|
269
|
+
constructor(config) {
|
|
270
|
+
validateConfig(config);
|
|
271
|
+
this.http = toHttpConfig(config);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Non-streaming chat. POST /api/v1/assistant/chat
|
|
275
|
+
*/
|
|
276
|
+
async chat(request, options) {
|
|
277
|
+
return torqueAssistantChat(this.http, request, options?.signal);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Streaming chat over SSE. POST /api/v1/assistant/chat?stream=true
|
|
281
|
+
*/
|
|
282
|
+
chatStream(request, options) {
|
|
283
|
+
return torqueAssistantChatStream(this.http, request, options?.signal);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function createTorqueAssistant(config) {
|
|
287
|
+
return new TorqueAssistant(config);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Reads TORQUE_API_KEY and optional TORQUE_BASE_URL from the environment.
|
|
291
|
+
*/
|
|
292
|
+
function createTorqueAssistantFromEnv(overrides) {
|
|
293
|
+
const apiKey = process.env.TORQUE_API_KEY || overrides?.apiKey;
|
|
294
|
+
if (!apiKey) {
|
|
295
|
+
throw new TorqueAssistantError('TORQUE_API_KEY environment variable is required', {
|
|
296
|
+
code: 'MISSING_ENV_VARS',
|
|
297
|
+
statusCode: 400,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
return new TorqueAssistant({
|
|
301
|
+
apiKey,
|
|
302
|
+
baseUrl: process.env.TORQUE_BASE_URL || overrides?.baseUrl,
|
|
303
|
+
timeout: overrides?.timeout,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
Object.defineProperty(exports, "ASSISTANT_CREDITS_ERROR_CODE", {
|
|
308
|
+
enumerable: true,
|
|
309
|
+
get: function () { return assistant.ASSISTANT_CREDITS_ERROR_CODE; }
|
|
310
|
+
});
|
|
311
|
+
exports.TorqueAssistant = TorqueAssistant;
|
|
312
|
+
exports.TorqueAssistantCreditsError = TorqueAssistantCreditsError;
|
|
313
|
+
exports.TorqueAssistantError = TorqueAssistantError;
|
|
314
|
+
exports.createTorqueAssistant = createTorqueAssistant;
|
|
315
|
+
exports.createTorqueAssistantFromEnv = createTorqueAssistantFromEnv;
|
|
316
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/errors.ts","../src/http.ts","../src/stream.ts","../src/index.ts"],"sourcesContent":["import { ASSISTANT_CREDITS_ERROR_CODE } from '@torquefi/types/assistant'\n\nexport interface TorqueAssistantErrorDetails {\n code: string\n statusCode: number\n details?: Record<string, unknown>\n}\n\nexport class TorqueAssistantError extends Error {\n code: string\n statusCode: number\n details?: Record<string, unknown>\n\n constructor(message: string, options: TorqueAssistantErrorDetails) {\n super(message)\n this.name = 'TorqueAssistantError'\n this.code = options.code\n this.statusCode = options.statusCode\n this.details = options.details\n Object.setPrototypeOf(this, TorqueAssistantError.prototype)\n }\n}\n\nexport class TorqueAssistantCreditsError extends TorqueAssistantError {\n upgrade?: boolean\n remaining?: number\n limit?: number\n resetAt?: number | null\n\n constructor(\n message: string,\n options: {\n statusCode: number\n upgrade?: boolean\n remaining?: number\n limit?: number\n resetAt?: number | null\n },\n ) {\n super(message, {\n code: ASSISTANT_CREDITS_ERROR_CODE,\n statusCode: options.statusCode,\n details: {\n upgrade: options.upgrade,\n remaining: options.remaining,\n limit: options.limit,\n resetAt: options.resetAt,\n },\n })\n this.name = 'TorqueAssistantCreditsError'\n this.upgrade = options.upgrade\n this.remaining = options.remaining\n this.limit = options.limit\n this.resetAt = options.resetAt\n Object.setPrototypeOf(this, TorqueAssistantCreditsError.prototype)\n }\n}\n\nexport function parseAssistantError(\n body: unknown,\n statusCode: number,\n fallbackMessage: string,\n): TorqueAssistantError {\n const payload = body as {\n error?: string | { code?: string; message?: string; details?: Record<string, unknown> }\n message?: string\n upgrade?: boolean\n remaining?: number\n limit?: number\n resetAt?: number | null\n } | null\n\n if (\n statusCode === 402 &&\n typeof payload?.error === 'string' &&\n payload.error === ASSISTANT_CREDITS_ERROR_CODE\n ) {\n return new TorqueAssistantCreditsError(\n typeof payload.message === 'string' ? payload.message : fallbackMessage,\n {\n statusCode,\n upgrade: payload.upgrade,\n remaining: payload.remaining,\n limit: payload.limit,\n resetAt: payload.resetAt,\n },\n )\n }\n\n if (payload?.error && typeof payload.error === 'object') {\n const err = payload.error\n return new TorqueAssistantError(\n typeof err.message === 'string' ? err.message : fallbackMessage,\n {\n code: typeof err.code === 'string' ? err.code : 'API_ERROR',\n statusCode,\n details: err.details,\n },\n )\n }\n\n if (typeof payload?.error === 'string') {\n return new TorqueAssistantError(\n typeof payload.message === 'string' ? payload.message : fallbackMessage,\n {\n code: payload.error,\n statusCode,\n },\n )\n }\n\n return new TorqueAssistantError(fallbackMessage, {\n code: 'API_ERROR',\n statusCode,\n })\n}\n","import type { AssistantChatPostBody, AssistantChatResponse } from '@torquefi/types/assistant'\n\nimport { parseAssistantError, TorqueAssistantError } from './errors'\n\nexport interface TorqueAssistantHttpConfig {\n apiKey: string\n baseUrl: string\n timeout: number\n}\n\nexport async function torqueAssistantPost<T>(\n config: TorqueAssistantHttpConfig,\n path: string,\n body: AssistantChatPostBody,\n signal?: AbortSignal,\n): Promise<T> {\n const url = `${config.baseUrl}${path}`\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), config.timeout)\n\n const onAbort = () => controller.abort()\n if (signal) {\n if (signal.aborted) controller.abort()\n else signal.addEventListener('abort', onAbort, { once: true })\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n signal?.removeEventListener('abort', onAbort)\n\n const payload: unknown = await response.json().catch(() => ({}))\n\n if (!response.ok) {\n throw parseAssistantError(\n payload,\n response.status,\n `HTTP ${response.status}: ${response.statusText}`,\n )\n }\n\n return payload as T\n } catch (error) {\n clearTimeout(timeoutId)\n signal?.removeEventListener('abort', onAbort)\n\n if (error instanceof TorqueAssistantError) {\n throw error\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new TorqueAssistantError('Request timeout', {\n code: 'TIMEOUT',\n statusCode: 408,\n })\n }\n throw new TorqueAssistantError(error.message, {\n code: 'NETWORK_ERROR',\n statusCode: 500,\n })\n }\n\n throw new TorqueAssistantError('Request failed', {\n code: 'UNKNOWN_ERROR',\n statusCode: 500,\n })\n }\n}\n\nexport async function torqueAssistantChat(\n config: TorqueAssistantHttpConfig,\n body: AssistantChatPostBody,\n signal?: AbortSignal,\n): Promise<AssistantChatResponse> {\n return torqueAssistantPost<AssistantChatResponse>(\n config,\n '/api/v1/assistant/chat',\n body,\n signal,\n )\n}\n","import type {\n AssistantChatFunctionResult,\n AssistantChatPostBody,\n AssistantChatStreamEvent,\n} from '@torquefi/types/assistant'\n\nimport { parseAssistantError, TorqueAssistantError } from './errors'\nimport type { TorqueAssistantHttpConfig } from './http'\n\ntype AssistantChatSsePayload = {\n type: string\n text?: string\n message?: string\n functionResults?: AssistantChatFunctionResult[]\n}\n\nfunction parseJsonContent(content: unknown): string {\n if (typeof content === 'string') return content\n if (Array.isArray(content)) {\n return (content as Array<{ text?: string }>)\n .map((part) => part?.text ?? '')\n .join('')\n }\n return ''\n}\n\nfunction* eventsFromJsonPayload(payload: {\n content?: unknown\n functionResults?: AssistantChatFunctionResult[]\n}): Generator<AssistantChatStreamEvent> {\n const text = parseJsonContent(payload.content)\n if (text) {\n yield { type: 'delta', text }\n }\n yield { type: 'done', functionResults: payload.functionResults }\n}\n\nexport async function* torqueAssistantChatStream(\n config: TorqueAssistantHttpConfig,\n body: AssistantChatPostBody,\n signal?: AbortSignal,\n): AsyncGenerator<AssistantChatStreamEvent> {\n const url = `${config.baseUrl}/api/v1/assistant/chat?stream=true`\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), config.timeout)\n\n const onAbort = () => controller.abort()\n if (signal) {\n if (signal.aborted) controller.abort()\n else signal.addEventListener('abort', onAbort, { once: true })\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n Accept: 'text/event-stream, application/json',\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n signal?.removeEventListener('abort', onAbort)\n\n if (!response.ok) {\n const payload: unknown = await response.json().catch(() => ({}))\n throw parseAssistantError(\n payload,\n response.status,\n `HTTP ${response.status}: ${response.statusText}`,\n )\n }\n\n const contentType = response.headers.get('content-type') ?? ''\n\n if (contentType.includes('application/json')) {\n const payload = (await response.json().catch(() => ({}))) as {\n content?: unknown\n functionResults?: AssistantChatFunctionResult[]\n }\n yield* eventsFromJsonPayload(payload)\n return\n }\n\n if (!response.body) {\n yield { type: 'error', message: 'No response body.' }\n return\n }\n\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n buf += decoder.decode(value, { stream: true })\n const lines = buf.split('\\n')\n buf = lines.pop() ?? ''\n\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue\n\n const raw = line.slice(6).trim()\n if (raw === '[DONE]') {\n yield { type: 'done' }\n return\n }\n\n let event: AssistantChatSsePayload\n try {\n event = JSON.parse(raw) as AssistantChatSsePayload\n } catch {\n continue\n }\n\n if (event.type === 'delta' && event.text) {\n yield { type: 'delta', text: event.text }\n } else if (event.type === 'correction' && event.text) {\n yield { type: 'correction', text: event.text }\n } else if (event.type === 'done') {\n yield { type: 'done', functionResults: event.functionResults }\n return\n } else if (event.type === 'error') {\n yield { type: 'error', message: event.message }\n return\n }\n }\n }\n\n yield { type: 'done' }\n } catch (error) {\n clearTimeout(timeoutId)\n signal?.removeEventListener('abort', onAbort)\n\n if (error instanceof TorqueAssistantError) {\n throw error\n }\n\n if (error instanceof Error && error.name === 'AbortError') {\n yield { type: 'done' }\n return\n }\n\n if (error instanceof Error) {\n throw new TorqueAssistantError(error.message, {\n code: 'NETWORK_ERROR',\n statusCode: 500,\n })\n }\n\n throw new TorqueAssistantError('Stream failed', {\n code: 'UNKNOWN_ERROR',\n statusCode: 500,\n })\n }\n}\n","import type { AssistantChatPostBody, AssistantChatResponse, AssistantChatStreamEvent } from '@torquefi/types/assistant'\nimport type { TorquePlatformClientConfig } from '@torquefi/types/platform'\n\nimport { TorqueAssistantCreditsError, TorqueAssistantError } from './errors'\nimport { torqueAssistantChat, type TorqueAssistantHttpConfig } from './http'\nimport { torqueAssistantChatStream } from './stream'\n\nexport type { TorquePlatformClientConfig as TorqueAssistantConfig } from '@torquefi/types/platform'\n\nexport interface TorqueAssistantOptions extends TorquePlatformClientConfig {}\n\nexport type AssistantChatRequest = AssistantChatPostBody\n\nexport interface AssistantChatStreamOptions {\n signal?: AbortSignal\n}\n\nexport {\n TorqueAssistantError,\n TorqueAssistantCreditsError,\n} from './errors'\nexport { ASSISTANT_CREDITS_ERROR_CODE } from '@torquefi/types/assistant'\nexport type {\n AssistantChatContext,\n AssistantChatFunctionResult,\n AssistantChatMessage,\n AssistantChatPostBody,\n AssistantChatResponse,\n AssistantChatStreamEvent,\n} from '@torquefi/types/assistant'\n\nfunction validateConfig(config: TorqueAssistantOptions): void {\n if (!config.apiKey?.trim()) {\n throw new TorqueAssistantError('API key is required', {\n code: 'INVALID_CONFIG',\n statusCode: 400,\n })\n }\n if (config.timeout != null && (typeof config.timeout !== 'number' || config.timeout <= 0)) {\n throw new TorqueAssistantError('Timeout must be a positive number', {\n code: 'INVALID_CONFIG',\n statusCode: 400,\n })\n }\n}\n\nfunction toHttpConfig(config: TorqueAssistantOptions): TorqueAssistantHttpConfig {\n return {\n apiKey: config.apiKey.trim(),\n baseUrl: (config.baseUrl || 'https://app.torque.fi').replace(/\\/$/, ''),\n timeout: config.timeout ?? 180_000,\n }\n}\n\nexport class TorqueAssistant {\n private readonly http: TorqueAssistantHttpConfig\n\n constructor(config: TorqueAssistantOptions) {\n validateConfig(config)\n this.http = toHttpConfig(config)\n }\n\n /**\n * Non-streaming chat. POST /api/v1/assistant/chat\n */\n async chat(\n request: AssistantChatRequest,\n options?: AssistantChatStreamOptions,\n ): Promise<AssistantChatResponse> {\n return torqueAssistantChat(this.http, request, options?.signal)\n }\n\n /**\n * Streaming chat over SSE. POST /api/v1/assistant/chat?stream=true\n */\n chatStream(\n request: AssistantChatRequest,\n options?: AssistantChatStreamOptions,\n ): AsyncGenerator<AssistantChatStreamEvent> {\n return torqueAssistantChatStream(this.http, request, options?.signal)\n }\n}\n\nexport function createTorqueAssistant(config: TorqueAssistantOptions): TorqueAssistant {\n return new TorqueAssistant(config)\n}\n\n/**\n * Reads TORQUE_API_KEY and optional TORQUE_BASE_URL from the environment.\n */\nexport function createTorqueAssistantFromEnv(\n overrides?: Partial<TorqueAssistantOptions>,\n): TorqueAssistant {\n const apiKey = process.env.TORQUE_API_KEY || overrides?.apiKey\n if (!apiKey) {\n throw new TorqueAssistantError('TORQUE_API_KEY environment variable is required', {\n code: 'MISSING_ENV_VARS',\n statusCode: 400,\n })\n }\n\n return new TorqueAssistant({\n apiKey,\n baseUrl: process.env.TORQUE_BASE_URL || overrides?.baseUrl,\n timeout: overrides?.timeout,\n })\n}\n"],"names":["ASSISTANT_CREDITS_ERROR_CODE"],"mappings":"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"}
|
package/dist/stream.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { AssistantChatPostBody, AssistantChatStreamEvent } from '@torquefi/types/assistant';
|
|
2
|
+
import type { TorqueAssistantHttpConfig } from './http';
|
|
3
|
+
export declare function torqueAssistantChatStream(config: TorqueAssistantHttpConfig, body: AssistantChatPostBody, signal?: AbortSignal): AsyncGenerator<AssistantChatStreamEvent>;
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "torque-assistant",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official Torque Assistant SDK — server-side chat and SSE streaming for Platform API v1",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.esm.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "rollup -c",
|
|
23
|
+
"dev": "rollup -c -w",
|
|
24
|
+
"clean": "rimraf dist",
|
|
25
|
+
"prepublishOnly": "yarn clean && yarn build"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"torque",
|
|
29
|
+
"assistant",
|
|
30
|
+
"chat",
|
|
31
|
+
"sse",
|
|
32
|
+
"fintech",
|
|
33
|
+
"api",
|
|
34
|
+
"typescript",
|
|
35
|
+
"sdk"
|
|
36
|
+
],
|
|
37
|
+
"author": "Torque <hello@torque.fi>",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"homepage": "https://torque.fi",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/torque-fi/torque_webapp.git",
|
|
43
|
+
"directory": "packages/torque-assistant"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@torquefi/types": "^0.1.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@rollup/plugin-typescript": "^12.1.4",
|
|
50
|
+
"@types/node": "^20.0.0",
|
|
51
|
+
"rimraf": "^5.0.0",
|
|
52
|
+
"rollup": "^4.0.0",
|
|
53
|
+
"typescript": "^5.0.0"
|
|
54
|
+
},
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=16.0.0"
|
|
57
|
+
}
|
|
58
|
+
}
|