@chaoslabs/ai-sdk 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -1
- package/dist/__tests__/http-streaming.test.d.ts +15 -0
- package/dist/__tests__/http-streaming.test.js +1401 -0
- package/dist/__tests__/stream.test.d.ts +1 -0
- package/dist/__tests__/stream.test.js +345 -0
- package/dist/__tests__/trivial.test.d.ts +1 -0
- package/dist/__tests__/trivial.test.js +6 -0
- package/dist/blocks.d.ts +108 -0
- package/dist/blocks.js +246 -0
- package/dist/client.d.ts +21 -5
- package/dist/client.js +75 -29
- package/dist/conversation.d.ts +136 -0
- package/dist/conversation.js +230 -0
- package/dist/http-streaming.d.ts +55 -0
- package/dist/http-streaming.js +359 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/primitives.d.ts +157 -0
- package/dist/primitives.js +220 -0
- package/dist/schemas.d.ts +6 -6
- package/dist/stream.d.ts +32 -0
- package/dist/stream.js +127 -0
- package/dist/types.d.ts +11 -0
- package/package.json +2 -1
package/dist/blocks.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// Chaos AI SDK - Block Utilities
|
|
2
|
+
//
|
|
3
|
+
// Helper functions for working with blocks extracted from responses.
|
|
4
|
+
import { extractBlocks, isTableBlock, isChartBlock, isTransactionActionBlock, isMarkdownBlock, isInteractiveBlock, } from './types.js';
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// Block Extraction Utilities
|
|
7
|
+
// ============================================================================
|
|
8
|
+
/**
|
|
9
|
+
* Extract all table blocks from a response.
|
|
10
|
+
*/
|
|
11
|
+
export function extractTableBlocks(response) {
|
|
12
|
+
return extractBlocks(response).filter(isTableBlock);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Extract all chart blocks from a response.
|
|
16
|
+
*/
|
|
17
|
+
export function extractChartBlocks(response) {
|
|
18
|
+
return extractBlocks(response).filter(isChartBlock);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Extract all transaction action blocks from a response.
|
|
22
|
+
*/
|
|
23
|
+
export function extractTransactionBlocks(response) {
|
|
24
|
+
return extractBlocks(response).filter(isTransactionActionBlock);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Extract all markdown blocks from a response.
|
|
28
|
+
*/
|
|
29
|
+
export function extractMarkdownBlocks(response) {
|
|
30
|
+
return extractBlocks(response).filter(isMarkdownBlock);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Extract all interactive blocks from a response.
|
|
34
|
+
*/
|
|
35
|
+
export function extractInteractiveBlocks(response) {
|
|
36
|
+
return extractBlocks(response).filter(isInteractiveBlock);
|
|
37
|
+
}
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// Block Search Utilities
|
|
40
|
+
// ============================================================================
|
|
41
|
+
/**
|
|
42
|
+
* Find the first table block with a matching title.
|
|
43
|
+
*/
|
|
44
|
+
export function findTableByTitle(response, title) {
|
|
45
|
+
return extractTableBlocks(response).find((block) => block.title.toLowerCase().includes(title.toLowerCase()));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Find the first chart block with a matching title.
|
|
49
|
+
*/
|
|
50
|
+
export function findChartByTitle(response, title) {
|
|
51
|
+
return extractChartBlocks(response).find((block) => block.title.toLowerCase().includes(title.toLowerCase()));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Find transaction blocks containing a specific primitive type.
|
|
55
|
+
*/
|
|
56
|
+
export function findTransactionsByPrimitive(response, primitiveType) {
|
|
57
|
+
return extractTransactionBlocks(response).filter((block) => block.primitives?.some((p) => p.primitive === primitiveType));
|
|
58
|
+
}
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Primitive Extraction
|
|
61
|
+
// ============================================================================
|
|
62
|
+
/**
|
|
63
|
+
* Extract all primitives from all transaction blocks.
|
|
64
|
+
*/
|
|
65
|
+
export function extractPrimitives(response) {
|
|
66
|
+
const primitives = [];
|
|
67
|
+
for (const block of extractTransactionBlocks(response)) {
|
|
68
|
+
if (block.primitives) {
|
|
69
|
+
primitives.push(...block.primitives);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return primitives;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Extract primitives of a specific type.
|
|
76
|
+
*/
|
|
77
|
+
export function extractPrimitivesByType(response, primitiveType) {
|
|
78
|
+
return extractPrimitives(response).filter((p) => p.primitive === primitiveType);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get unique primitive types from a response.
|
|
82
|
+
*/
|
|
83
|
+
export function getPrimitiveTypes(response) {
|
|
84
|
+
const types = new Set();
|
|
85
|
+
for (const primitive of extractPrimitives(response)) {
|
|
86
|
+
types.add(primitive.primitive);
|
|
87
|
+
}
|
|
88
|
+
return Array.from(types);
|
|
89
|
+
}
|
|
90
|
+
// ============================================================================
|
|
91
|
+
// Table Utilities
|
|
92
|
+
// ============================================================================
|
|
93
|
+
/**
|
|
94
|
+
* Convert a table block to an array of objects.
|
|
95
|
+
* Each object has keys from the table headers.
|
|
96
|
+
*/
|
|
97
|
+
export function tableToObjects(table) {
|
|
98
|
+
const { tableHeaders, tableRows } = table;
|
|
99
|
+
return tableRows.map((row) => {
|
|
100
|
+
const obj = {};
|
|
101
|
+
for (let i = 0; i < tableHeaders.length; i++) {
|
|
102
|
+
obj[tableHeaders[i]] = row[i];
|
|
103
|
+
}
|
|
104
|
+
return obj;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get a specific column from a table block.
|
|
109
|
+
*/
|
|
110
|
+
export function getTableColumn(table, columnName) {
|
|
111
|
+
const columnIndex = table.tableHeaders.indexOf(columnName);
|
|
112
|
+
if (columnIndex === -1)
|
|
113
|
+
return [];
|
|
114
|
+
return table.tableRows.map((row) => row[columnIndex]);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Find a row in a table by matching a column value.
|
|
118
|
+
*/
|
|
119
|
+
export function findTableRow(table, columnName, value) {
|
|
120
|
+
const columnIndex = table.tableHeaders.indexOf(columnName);
|
|
121
|
+
if (columnIndex === -1)
|
|
122
|
+
return undefined;
|
|
123
|
+
return table.tableRows.find((row) => row[columnIndex] === value);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get table dimensions.
|
|
127
|
+
*/
|
|
128
|
+
export function getTableDimensions(table) {
|
|
129
|
+
return {
|
|
130
|
+
columns: table.tableHeaders.length,
|
|
131
|
+
rows: table.tableRows.length,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// ============================================================================
|
|
135
|
+
// Chart Utilities
|
|
136
|
+
// ============================================================================
|
|
137
|
+
/**
|
|
138
|
+
* Get chart data as label-value pairs.
|
|
139
|
+
* Works with both segments and legacy data formats.
|
|
140
|
+
*/
|
|
141
|
+
export function getChartData(chart) {
|
|
142
|
+
if (chart.segments) {
|
|
143
|
+
return chart.segments.map((s) => ({ label: s.label, value: s.value }));
|
|
144
|
+
}
|
|
145
|
+
if (chart.data) {
|
|
146
|
+
return chart.data.map(([label, value]) => ({ label, value }));
|
|
147
|
+
}
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get the total value of all chart segments.
|
|
152
|
+
*/
|
|
153
|
+
export function getChartTotal(chart) {
|
|
154
|
+
return getChartData(chart).reduce((sum, item) => sum + item.value, 0);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get chart segment percentages.
|
|
158
|
+
*/
|
|
159
|
+
export function getChartPercentages(chart) {
|
|
160
|
+
const data = getChartData(chart);
|
|
161
|
+
const total = data.reduce((sum, item) => sum + item.value, 0);
|
|
162
|
+
if (total === 0)
|
|
163
|
+
return data.map((d) => ({ label: d.label, percentage: 0 }));
|
|
164
|
+
return data.map((d) => ({
|
|
165
|
+
label: d.label,
|
|
166
|
+
percentage: (d.value / total) * 100,
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
// ============================================================================
|
|
170
|
+
// Risk Utilities
|
|
171
|
+
// ============================================================================
|
|
172
|
+
/**
|
|
173
|
+
* Get all warnings from transaction blocks.
|
|
174
|
+
*/
|
|
175
|
+
export function getAllWarnings(response) {
|
|
176
|
+
const warnings = [];
|
|
177
|
+
for (const block of extractTransactionBlocks(response)) {
|
|
178
|
+
if (block.risks?.warnings) {
|
|
179
|
+
warnings.push(...block.risks.warnings);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return warnings;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get all blockers from transaction blocks.
|
|
186
|
+
*/
|
|
187
|
+
export function getAllBlockers(response) {
|
|
188
|
+
const blockers = [];
|
|
189
|
+
for (const block of extractTransactionBlocks(response)) {
|
|
190
|
+
if (block.risks?.blockers) {
|
|
191
|
+
blockers.push(...block.risks.blockers);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return blockers;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get the highest risk level from all transaction blocks.
|
|
198
|
+
*/
|
|
199
|
+
export function getHighestRiskLevel(response) {
|
|
200
|
+
const riskLevels = ['low', 'medium', 'high', 'critical'];
|
|
201
|
+
let highestIndex = -1;
|
|
202
|
+
let highestLevel;
|
|
203
|
+
for (const block of extractTransactionBlocks(response)) {
|
|
204
|
+
if (block.risks?.level) {
|
|
205
|
+
const index = riskLevels.indexOf(block.risks.level.toLowerCase());
|
|
206
|
+
if (index > highestIndex) {
|
|
207
|
+
highestIndex = index;
|
|
208
|
+
highestLevel = block.risks.level;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return highestLevel;
|
|
213
|
+
}
|
|
214
|
+
// ============================================================================
|
|
215
|
+
// Block Statistics
|
|
216
|
+
// ============================================================================
|
|
217
|
+
/**
|
|
218
|
+
* Count blocks by type in a response.
|
|
219
|
+
*/
|
|
220
|
+
export function countBlocksByType(response) {
|
|
221
|
+
const counts = {
|
|
222
|
+
table: 0,
|
|
223
|
+
chart: 0,
|
|
224
|
+
transaction_action: 0,
|
|
225
|
+
markdown: 0,
|
|
226
|
+
interactive: 0,
|
|
227
|
+
};
|
|
228
|
+
for (const block of extractBlocks(response)) {
|
|
229
|
+
if (block.type in counts) {
|
|
230
|
+
counts[block.type]++;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return counts;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Check if a response contains any blocks.
|
|
237
|
+
*/
|
|
238
|
+
export function hasBlocks(response) {
|
|
239
|
+
return extractBlocks(response).length > 0;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Check if a response contains a specific block type.
|
|
243
|
+
*/
|
|
244
|
+
export function hasBlockType(response, type) {
|
|
245
|
+
return extractBlocks(response).some((block) => block.type === type);
|
|
246
|
+
}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
import type { ChaosConfig, CreateResponseParams, Response } from './types.js';
|
|
2
2
|
import { WALLET_MODEL, ASK_MODEL } from './request.js';
|
|
3
|
+
import { StreamingHttpClient } from './http-streaming.js';
|
|
3
4
|
export { WALLET_MODEL, ASK_MODEL };
|
|
5
|
+
/**
|
|
6
|
+
* Extended config with useNativeHttp option
|
|
7
|
+
*/
|
|
8
|
+
interface ExtendedChaosConfig extends ChaosConfig {
|
|
9
|
+
apiKey: string;
|
|
10
|
+
baseUrl: string;
|
|
11
|
+
timeout: number;
|
|
12
|
+
useNativeHttp: boolean;
|
|
13
|
+
}
|
|
4
14
|
/**
|
|
5
15
|
* The v1 responses API namespace.
|
|
6
16
|
*/
|
|
7
17
|
declare class V1Responses {
|
|
8
18
|
private config;
|
|
9
19
|
private sessionId;
|
|
10
|
-
private
|
|
11
|
-
constructor(config:
|
|
20
|
+
private streamingClient;
|
|
21
|
+
constructor(config: ExtendedChaosConfig);
|
|
12
22
|
private generateId;
|
|
13
23
|
/**
|
|
14
24
|
* Create a response using v1 API.
|
|
15
25
|
*/
|
|
16
26
|
create(params: CreateResponseParams): Promise<Response>;
|
|
17
27
|
/**
|
|
18
|
-
* Create a
|
|
28
|
+
* Create a response using native HTTP streaming.
|
|
19
29
|
*/
|
|
20
|
-
private
|
|
30
|
+
private createWithNativeHttp;
|
|
21
31
|
/**
|
|
22
32
|
* Cancel the current request.
|
|
23
33
|
*/
|
|
@@ -32,7 +42,7 @@ declare class V1Responses {
|
|
|
32
42
|
*/
|
|
33
43
|
declare class V1Chat {
|
|
34
44
|
readonly responses: V1Responses;
|
|
35
|
-
constructor(config:
|
|
45
|
+
constructor(config: ExtendedChaosConfig);
|
|
36
46
|
}
|
|
37
47
|
/**
|
|
38
48
|
* Chaos AI SDK Client - V1 API.
|
|
@@ -64,6 +74,8 @@ declare class V1Chat {
|
|
|
64
74
|
export declare class Chaos {
|
|
65
75
|
readonly chat: V1Chat;
|
|
66
76
|
private config;
|
|
77
|
+
/** Whether to use native http module for streaming */
|
|
78
|
+
readonly useNativeHttp: boolean;
|
|
67
79
|
constructor(config: ChaosConfig);
|
|
68
80
|
/**
|
|
69
81
|
* Get the API key.
|
|
@@ -73,5 +85,9 @@ export declare class Chaos {
|
|
|
73
85
|
* Get the base URL.
|
|
74
86
|
*/
|
|
75
87
|
get baseUrl(): string;
|
|
88
|
+
/**
|
|
89
|
+
* Get a StreamingHttpClient instance for direct streaming access.
|
|
90
|
+
*/
|
|
91
|
+
getStreamingClient(): StreamingHttpClient;
|
|
76
92
|
}
|
|
77
93
|
export default Chaos;
|
package/dist/client.js
CHANGED
|
@@ -3,23 +3,37 @@
|
|
|
3
3
|
// This client talks to the new v1 API endpoint with Bearer auth.
|
|
4
4
|
import { ChaosError, ChaosTimeoutError } from './types.js';
|
|
5
5
|
import { toV1WalletRequest, toV1AskRequest, buildV1Headers, buildV1Endpoint, WALLET_MODEL, ASK_MODEL, } from './request.js';
|
|
6
|
-
import {
|
|
6
|
+
import { toV1Response } from './response.js';
|
|
7
|
+
import { parseStreamLine } from './stream.js';
|
|
8
|
+
import { StreamingHttpClient } from './http-streaming.js';
|
|
9
|
+
/**
|
|
10
|
+
* Build final state from a list of stream events.
|
|
11
|
+
*/
|
|
12
|
+
function buildFinalStateFromEvents(events) {
|
|
13
|
+
const blocks = [];
|
|
14
|
+
for (const event of events) {
|
|
15
|
+
if (event.type === 'report' && event.content) {
|
|
16
|
+
const content = event.content;
|
|
17
|
+
if (content.data) {
|
|
18
|
+
blocks.push(content.data);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return { blocks };
|
|
23
|
+
}
|
|
7
24
|
// Export model constants
|
|
8
25
|
export { WALLET_MODEL, ASK_MODEL };
|
|
9
26
|
// ============================================================================
|
|
10
27
|
// Constants
|
|
11
28
|
// ============================================================================
|
|
12
29
|
const DEFAULT_TIMEOUT = 120000; // 2 minutes
|
|
13
|
-
// ============================================================================
|
|
14
|
-
// V1 Responses Class
|
|
15
|
-
// ============================================================================
|
|
16
30
|
/**
|
|
17
31
|
* The v1 responses API namespace.
|
|
18
32
|
*/
|
|
19
33
|
class V1Responses {
|
|
20
34
|
config;
|
|
21
35
|
sessionId;
|
|
22
|
-
|
|
36
|
+
streamingClient = null;
|
|
23
37
|
constructor(config) {
|
|
24
38
|
this.config = config;
|
|
25
39
|
this.sessionId = this.generateId();
|
|
@@ -31,48 +45,63 @@ class V1Responses {
|
|
|
31
45
|
* Create a response using v1 API.
|
|
32
46
|
*/
|
|
33
47
|
async create(params) {
|
|
34
|
-
|
|
48
|
+
// Always use native HTTP for true streaming behavior
|
|
49
|
+
return this.createWithNativeHttp(params);
|
|
35
50
|
}
|
|
36
51
|
/**
|
|
37
|
-
* Create a
|
|
52
|
+
* Create a response using native HTTP streaming.
|
|
38
53
|
*/
|
|
39
|
-
async
|
|
54
|
+
async createWithNativeHttp(params) {
|
|
40
55
|
const responseId = this.generateId();
|
|
41
56
|
const sessionId = params.metadata.session_id || this.sessionId;
|
|
42
|
-
// Create
|
|
43
|
-
this.
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
// Create streaming client
|
|
58
|
+
this.streamingClient = new StreamingHttpClient({
|
|
59
|
+
baseUrl: this.config.baseUrl,
|
|
60
|
+
timeout: this.config.timeout,
|
|
61
|
+
});
|
|
46
62
|
// Build request
|
|
47
|
-
const endpoint = buildV1Endpoint(this.config.baseUrl);
|
|
48
63
|
const headers = buildV1Headers(this.config.apiKey);
|
|
49
64
|
// Check if wallet or ask mode
|
|
50
65
|
const isWallet = params.model === WALLET_MODEL || params.model.includes('WALLET');
|
|
51
66
|
const requestBody = isWallet
|
|
52
67
|
? toV1WalletRequest(params, sessionId)
|
|
53
68
|
: toV1AskRequest(params, sessionId);
|
|
69
|
+
// Build endpoint path
|
|
70
|
+
const endpoint = buildV1Endpoint(this.config.baseUrl);
|
|
71
|
+
const url = new URL(endpoint);
|
|
72
|
+
const path = url.pathname + url.search;
|
|
54
73
|
try {
|
|
55
|
-
//
|
|
56
|
-
const
|
|
74
|
+
// Collect events for final response
|
|
75
|
+
const events = [];
|
|
76
|
+
// Stream lines using native http
|
|
77
|
+
for await (const line of this.streamingClient.streamLines(path, {
|
|
57
78
|
method: 'POST',
|
|
58
79
|
headers,
|
|
59
80
|
body: JSON.stringify(requestBody),
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
81
|
+
})) {
|
|
82
|
+
try {
|
|
83
|
+
const event = JSON.parse(line);
|
|
84
|
+
events.push(event);
|
|
85
|
+
// Call stream event callback if provided
|
|
86
|
+
if (params.onStreamEvent) {
|
|
87
|
+
const msg = parseStreamLine(line);
|
|
88
|
+
if (msg) {
|
|
89
|
+
params.onStreamEvent(msg);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Skip invalid JSON lines
|
|
95
|
+
}
|
|
64
96
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
// Parse NDJSON stream
|
|
69
|
-
const finalState = await parseV1Stream(response.body);
|
|
97
|
+
// Build final state from events
|
|
98
|
+
const finalState = buildFinalStateFromEvents(events);
|
|
70
99
|
// Convert to Response
|
|
71
100
|
return toV1Response(responseId, params.model, finalState);
|
|
72
101
|
}
|
|
73
102
|
catch (error) {
|
|
74
|
-
if (error instanceof
|
|
75
|
-
throw
|
|
103
|
+
if (error instanceof ChaosTimeoutError) {
|
|
104
|
+
throw error;
|
|
76
105
|
}
|
|
77
106
|
if (error instanceof ChaosError) {
|
|
78
107
|
throw error;
|
|
@@ -80,15 +109,17 @@ class V1Responses {
|
|
|
80
109
|
throw new ChaosError(error instanceof Error ? error.message : String(error));
|
|
81
110
|
}
|
|
82
111
|
finally {
|
|
83
|
-
this.
|
|
112
|
+
this.streamingClient = null;
|
|
84
113
|
}
|
|
85
114
|
}
|
|
86
115
|
/**
|
|
87
116
|
* Cancel the current request.
|
|
88
117
|
*/
|
|
89
118
|
cancel() {
|
|
90
|
-
|
|
91
|
-
this.
|
|
119
|
+
// Cancel native HTTP streaming client
|
|
120
|
+
if (this.streamingClient) {
|
|
121
|
+
this.streamingClient.abort();
|
|
122
|
+
}
|
|
92
123
|
}
|
|
93
124
|
/**
|
|
94
125
|
* Reset the session for a new conversation.
|
|
@@ -143,12 +174,18 @@ class V1Chat {
|
|
|
143
174
|
export class Chaos {
|
|
144
175
|
chat;
|
|
145
176
|
config;
|
|
177
|
+
/** Whether to use native http module for streaming */
|
|
178
|
+
useNativeHttp;
|
|
146
179
|
constructor(config) {
|
|
180
|
+
// Default useNativeHttp to true for proper streaming
|
|
181
|
+
const useNativeHttp = config.useNativeHttp !== false;
|
|
147
182
|
this.config = {
|
|
148
183
|
apiKey: config.apiKey,
|
|
149
184
|
baseUrl: config.baseUrl || 'https://ai-staging.chaoslabs.co',
|
|
150
185
|
timeout: config.timeout || DEFAULT_TIMEOUT,
|
|
186
|
+
useNativeHttp,
|
|
151
187
|
};
|
|
188
|
+
this.useNativeHttp = useNativeHttp;
|
|
152
189
|
this.chat = new V1Chat(this.config);
|
|
153
190
|
}
|
|
154
191
|
/**
|
|
@@ -163,5 +200,14 @@ export class Chaos {
|
|
|
163
200
|
get baseUrl() {
|
|
164
201
|
return this.config.baseUrl;
|
|
165
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Get a StreamingHttpClient instance for direct streaming access.
|
|
205
|
+
*/
|
|
206
|
+
getStreamingClient() {
|
|
207
|
+
return new StreamingHttpClient({
|
|
208
|
+
baseUrl: this.config.baseUrl,
|
|
209
|
+
timeout: this.config.timeout,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
166
212
|
}
|
|
167
213
|
export default Chaos;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { Chaos } from './client.js';
|
|
2
|
+
import type { InputItem, Response, RequestMetadata } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Options for creating a new conversation.
|
|
5
|
+
*/
|
|
6
|
+
export interface ConversationOptions {
|
|
7
|
+
/** Model to use (defaults to WALLET_MODEL) */
|
|
8
|
+
model?: string;
|
|
9
|
+
/** Maximum number of messages to keep in history */
|
|
10
|
+
maxHistoryLength?: number;
|
|
11
|
+
/** User identifier */
|
|
12
|
+
userId: string;
|
|
13
|
+
/** Wallet identifier */
|
|
14
|
+
walletId: string;
|
|
15
|
+
/** Optional initial session ID (auto-generated if not provided) */
|
|
16
|
+
sessionId?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Statistics about the conversation.
|
|
20
|
+
*/
|
|
21
|
+
export interface ConversationStats {
|
|
22
|
+
/** Number of user turns */
|
|
23
|
+
userTurns: number;
|
|
24
|
+
/** Number of assistant turns */
|
|
25
|
+
assistantTurns: number;
|
|
26
|
+
/** Total messages in history */
|
|
27
|
+
totalMessages: number;
|
|
28
|
+
/** Session ID */
|
|
29
|
+
sessionId: string;
|
|
30
|
+
/** When the conversation started */
|
|
31
|
+
startedAt: Date;
|
|
32
|
+
/** When the last message was sent */
|
|
33
|
+
lastMessageAt: Date | null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Manages a multi-turn conversation with history tracking.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { Chaos, Conversation } from '@chaoslabs/ai-sdk';
|
|
41
|
+
*
|
|
42
|
+
* const chaos = new Chaos({ apiKey: 'ck-...' });
|
|
43
|
+
* const conversation = new Conversation(chaos, {
|
|
44
|
+
* userId: 'user-123',
|
|
45
|
+
* walletId: '0x...',
|
|
46
|
+
* });
|
|
47
|
+
*
|
|
48
|
+
* // Send messages - history is tracked automatically
|
|
49
|
+
* const response1 = await conversation.send("What's my portfolio value?");
|
|
50
|
+
* const response2 = await conversation.send("Which asset has the highest allocation?");
|
|
51
|
+
*
|
|
52
|
+
* // Get conversation stats
|
|
53
|
+
* console.log(conversation.stats);
|
|
54
|
+
*
|
|
55
|
+
* // Reset for a new conversation
|
|
56
|
+
* conversation.reset();
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare class Conversation {
|
|
60
|
+
private client;
|
|
61
|
+
private model;
|
|
62
|
+
private maxHistoryLength;
|
|
63
|
+
private history;
|
|
64
|
+
private metadata;
|
|
65
|
+
private userTurns;
|
|
66
|
+
private assistantTurns;
|
|
67
|
+
private startedAt;
|
|
68
|
+
private lastMessageAt;
|
|
69
|
+
constructor(client: Chaos, options: ConversationOptions);
|
|
70
|
+
/**
|
|
71
|
+
* Get the current session ID.
|
|
72
|
+
*/
|
|
73
|
+
get sessionId(): string;
|
|
74
|
+
/**
|
|
75
|
+
* Get the conversation history.
|
|
76
|
+
*/
|
|
77
|
+
get messages(): readonly InputItem[];
|
|
78
|
+
/**
|
|
79
|
+
* Get conversation statistics.
|
|
80
|
+
*/
|
|
81
|
+
get stats(): ConversationStats;
|
|
82
|
+
/**
|
|
83
|
+
* Send a message and get a response.
|
|
84
|
+
* Automatically manages conversation history.
|
|
85
|
+
*/
|
|
86
|
+
send(message: string): Promise<Response>;
|
|
87
|
+
/**
|
|
88
|
+
* Add a user message to the history without sending.
|
|
89
|
+
* Useful for restoring conversation state.
|
|
90
|
+
*/
|
|
91
|
+
addUserMessage(content: string): void;
|
|
92
|
+
/**
|
|
93
|
+
* Add an assistant message to the history.
|
|
94
|
+
* Useful for restoring conversation state.
|
|
95
|
+
*/
|
|
96
|
+
addAssistantMessage(content: string): void;
|
|
97
|
+
/**
|
|
98
|
+
* Add a system message to the history.
|
|
99
|
+
*/
|
|
100
|
+
addSystemMessage(content: string): void;
|
|
101
|
+
/**
|
|
102
|
+
* Reset the conversation to start fresh.
|
|
103
|
+
* Generates a new session ID and clears history.
|
|
104
|
+
*/
|
|
105
|
+
reset(): void;
|
|
106
|
+
/**
|
|
107
|
+
* Clear the history but keep the same session ID.
|
|
108
|
+
*/
|
|
109
|
+
clearHistory(): void;
|
|
110
|
+
/**
|
|
111
|
+
* Fork this conversation to create a branch.
|
|
112
|
+
* The new conversation has the same history but a new session ID.
|
|
113
|
+
*/
|
|
114
|
+
fork(): Conversation;
|
|
115
|
+
/**
|
|
116
|
+
* Serialize the conversation to JSON for persistence.
|
|
117
|
+
*/
|
|
118
|
+
toJSON(): {
|
|
119
|
+
sessionId: string;
|
|
120
|
+
history: InputItem[];
|
|
121
|
+
metadata: RequestMetadata;
|
|
122
|
+
stats: ConversationStats;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Restore conversation state from JSON.
|
|
126
|
+
*/
|
|
127
|
+
static fromJSON(client: Chaos, data: {
|
|
128
|
+
sessionId: string;
|
|
129
|
+
history: InputItem[];
|
|
130
|
+
metadata: RequestMetadata;
|
|
131
|
+
}): Conversation;
|
|
132
|
+
/**
|
|
133
|
+
* Trim history to stay within maxHistoryLength.
|
|
134
|
+
*/
|
|
135
|
+
private trimHistory;
|
|
136
|
+
}
|