@chaoslabs/ai-sdk 0.0.1 → 0.0.3

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/dist/schemas.js CHANGED
@@ -1,143 +1,283 @@
1
- // Chaos AI SDK V1 - Zod Schemas
2
- import { z } from "zod";
1
+ // Zod schemas for block validation (match Python backend)
2
+ // Updated to match actual server response structure
3
+ import { z } from 'zod';
3
4
  // ============================================================================
4
- // Client Configuration
5
+ // Block Schemas - Matching Actual Server Response Structure
5
6
  // ============================================================================
6
- export const ChaosConfigSchema = z.object({
7
- apiKey: z.string(),
8
- baseUrl: z.string().optional(),
9
- timeout: z.number().optional(),
10
- });
11
- // ============================================================================
12
- // Request Types
13
- // ============================================================================
14
- export const InputItemSchema = z.object({
15
- type: z.literal("message"),
16
- role: z.enum(["user", "system"]),
7
+ // --- Markdown Block ---
8
+ // Server sends: { content: string } (no type field)
9
+ export const MarkdownBlockSchema = z.object({
17
10
  content: z.string(),
18
11
  });
19
- export const RequestMetadataSchema = z.object({
20
- user_id: z.string(),
21
- session_id: z.string(),
22
- wallet_id: z.string().optional(),
23
- });
24
- export const CreateResponseParamsSchema = z.object({
25
- model: z.string(),
26
- input: z.array(InputItemSchema),
27
- stream: z.boolean().optional(),
28
- metadata: RequestMetadataSchema,
12
+ // --- Table Block ---
13
+ // Server sends: { blockType: "table", ... }
14
+ export const TableColumnTypeSchema = z.enum([
15
+ 'text',
16
+ 'number',
17
+ 'currency',
18
+ 'percentage',
19
+ 'token',
20
+ 'date',
21
+ 'link',
22
+ 'boolean',
23
+ ]);
24
+ export const TableSortDirectionSchema = z.enum(['asc', 'desc']);
25
+ export const TableColumnConfigSchema = z.object({
26
+ type: TableColumnTypeSchema.optional(),
27
+ sortable: z.boolean().optional(),
28
+ align: z.enum(['left', 'center', 'right']).optional(),
29
+ width: z.string().optional(),
29
30
  });
30
- // ============================================================================
31
- // Block Types
32
- // ============================================================================
33
- export const TableCellValueSchema = z.union([z.string(), z.number()]);
34
31
  export const TableBlockSchema = z.object({
35
- type: z.literal("table"),
32
+ blockType: z.literal('table'),
36
33
  title: z.string(),
37
34
  tableHeaders: z.array(z.string()),
38
- rows: z.array(z.array(TableCellValueSchema)),
35
+ tableRows: z.array(z.array(z.union([z.string(), z.number(), z.boolean(), z.null()]))),
36
+ tableHeadersTypes: z.record(z.string(), z.union([TableColumnTypeSchema, z.literal('currency'), z.literal('percentage')])).optional().nullable(),
37
+ tableColumnConfigs: z.record(z.string(), TableColumnConfigSchema).optional().nullable(),
38
+ tableHeadersMetadata: z.record(z.string(), z.object({ type: z.string().optional() }).passthrough()).optional().nullable(),
39
+ sourceName: z.string().optional().nullable(),
40
+ defaultSortColumn: z.string().optional().nullable(),
41
+ defaultSortDirection: TableSortDirectionSchema.optional().nullable(),
42
+ maxRows: z.number().optional().nullable(),
43
+ searchable: z.boolean().optional().nullable(),
44
+ exportable: z.boolean().optional().nullable(),
45
+ tool_params: z.unknown().optional().nullable(),
46
+ tool_name: z.string().optional().nullable(),
39
47
  });
40
- export const MarkdownBlockSchema = z.object({
41
- type: z.literal("markdown"),
42
- content: z.string(),
48
+ // --- Chart Block ---
49
+ // Server sends: { blockType: "chart", data: [[label, value], ...], ... }
50
+ export const ChartDataPointSchema = z.union([
51
+ z.tuple([z.number(), z.number()]),
52
+ z.object({ x: z.union([z.number(), z.string()]), y: z.number() }),
53
+ z.array(z.unknown()),
54
+ ]);
55
+ // Array format series item (legacy)
56
+ export const ChartSeriesSchema = z.object({
57
+ name: z.string(),
58
+ data: z.array(ChartDataPointSchema),
59
+ color: z.string().optional(),
60
+ });
61
+ // Timeseries format: server sends series as { "24H": [{ label, data }, ...] }
62
+ export const TimeseriesSeriesItemSchema = z.object({
63
+ label: z.string(),
64
+ data: z.array(z.array(z.union([z.number(), z.string()]))), // [[timestamp, value], ...]
43
65
  });
44
- // Primitive params - accepts any JSON-compatible value
45
- export const PrimitiveParamsSchema = z.record(z.string(), z.unknown());
66
+ // Series can be either:
67
+ // - Array format: [{ name, data, color }, ...]
68
+ // - Object format (timeseries): { "24H": [{ label, data }, ...], "7D": [...] }
69
+ export const ChartSeriesFieldSchema = z.union([
70
+ z.array(ChartSeriesSchema),
71
+ z.record(z.string(), z.array(TimeseriesSeriesItemSchema)),
72
+ ]);
73
+ export const ChartSegmentSchema = z.object({
74
+ label: z.string(),
75
+ value: z.number(),
76
+ color: z.string().optional(),
77
+ });
78
+ export const ChartAxisSchema = z.object({
79
+ title: z.string().optional(),
80
+ min: z.number().optional(),
81
+ max: z.number().optional(),
82
+ type: z.string().optional(),
83
+ });
84
+ // Legacy data format for pie/donut charts: [[label, value], ...]
85
+ export const ChartLegacyDataSchema = z.array(z.tuple([z.string(), z.number()]));
86
+ export const ChartBlockSchema = z.object({
87
+ blockType: z.literal('chart'),
88
+ title: z.string(),
89
+ chartType: z.enum(['pie', 'donut', 'line', 'area', 'bar', 'timeseries']).optional().nullable(),
90
+ series: ChartSeriesFieldSchema.nullish(),
91
+ segments: z.array(ChartSegmentSchema).optional().nullable(),
92
+ // Legacy data format from server: [[label, value], ...]
93
+ data: ChartLegacyDataSchema.optional().nullable(),
94
+ categories: z.array(z.string()).optional().nullable(),
95
+ xAxis: ChartAxisSchema.optional().nullable(),
96
+ yAxis: ChartAxisSchema.optional().nullable(),
97
+ isCurrency: z.boolean().optional().nullable(),
98
+ sourceName: z.string().optional().nullable(),
99
+ timeframe: z.string().optional().nullable(),
100
+ captions: z.array(z.object({ label: z.string(), value: z.string() })).nullish(),
101
+ titleCryptIcons: z.array(z.object({ name: z.string(), entity: z.string().optional() })).nullish(),
102
+ tool_params: z.unknown().optional().nullable(),
103
+ tool_name: z.string().optional().nullable(),
104
+ });
105
+ // --- Transaction Action Block ---
106
+ // Server sends: { blockType: "transaction_action", primitives: [...], transactions: [...], risks: {...}, ... }
107
+ // Primitive display icon
108
+ export const PrimitiveIconSchema = z.object({
109
+ type: z.string(),
110
+ value: z.string(),
111
+ });
112
+ // Primitive display line item
113
+ export const PrimitiveLineItemSchema = z.object({
114
+ label: z.string(),
115
+ value: z.string(),
116
+ icon: PrimitiveIconSchema.optional(),
117
+ });
118
+ // Primitive display info
46
119
  export const PrimitiveDisplaySchema = z.object({
47
- headline: z.string(),
48
- amount: z.string().optional(),
120
+ headline: z.string().optional(),
49
121
  action_verb: z.string().optional(),
50
- from_asset: z.string().optional(),
51
- to_asset: z.string().optional(),
52
- from_chain: z.string().optional(),
53
- to_chain: z.string().optional(),
54
- protocol: z.string().optional(),
55
- leverage: z.string().optional(),
56
- direction: z.string().optional(),
57
- recipient: z.string().optional(),
122
+ primary_icon: PrimitiveIconSchema.optional(),
123
+ secondary_icon: PrimitiveIconSchema.optional(),
124
+ line_items: z.array(PrimitiveLineItemSchema).optional(),
58
125
  });
126
+ // Primitive (the actual action like swap, supply, etc.)
59
127
  export const PrimitiveSchema = z.object({
60
128
  primitive: z.string(),
61
- params: PrimitiveParamsSchema,
129
+ params: z.record(z.string(), z.unknown()).optional(),
62
130
  display: PrimitiveDisplaySchema.optional(),
63
131
  });
132
+ // Raw transaction data from server
133
+ export const RawTransactionSchema = z.object({
134
+ to: z.string().optional(),
135
+ data: z.string().optional(),
136
+ value: z.string().optional(),
137
+ chainId: z.number().optional(),
138
+ description: z.string().optional(),
139
+ contractName: z.string().optional(),
140
+ contractVerified: z.boolean().optional(),
141
+ protocolName: z.string().optional(),
142
+ contractIcon: z.string().optional(),
143
+ });
144
+ // Transaction group (contains multiple raw transactions)
145
+ export const TransactionGroupSchema = z.object({
146
+ transactions: z.array(RawTransactionSchema).optional(),
147
+ requiresApproval: z.boolean().optional(),
148
+ verificationUnavailable: z.boolean().optional(),
149
+ });
150
+ // Risk impact (quantified risk details)
151
+ export const RiskImpactSchema = z.object({
152
+ metric: z.string(),
153
+ current: z.number().nullish(),
154
+ projected: z.number().nullish(),
155
+ threshold: z.number().nullish(),
156
+ at_risk_usd: z.number().nullish(),
157
+ liquidation_price: z.string().nullish(),
158
+ });
159
+ // Risk check item (used in blockers, warnings, info arrays)
160
+ export const RiskCheckSchema = z.object({
161
+ id: z.string(),
162
+ severity: z.enum(['block', 'warn', 'info']),
163
+ title: z.string(),
164
+ message: z.string(),
165
+ impact: RiskImpactSchema.nullish(),
166
+ });
167
+ // Legacy alias for backwards compatibility
168
+ export const RiskInfoItemSchema = RiskCheckSchema;
169
+ // Risks object
64
170
  export const RisksSchema = z.object({
65
- level: z.enum(["low", "medium", "high", "critical"]),
66
- warnings: z.array(z.string()),
67
- blockers: z.array(z.string()).optional(),
171
+ level: z.enum(['low', 'medium', 'high', 'critical']).nullish(),
172
+ blockers: z.array(RiskCheckSchema).nullish(),
173
+ warnings: z.array(RiskCheckSchema).nullish(),
174
+ info: z.array(RiskCheckSchema).nullish(),
68
175
  });
69
176
  export const TransactionActionBlockSchema = z.object({
70
- type: z.literal("transaction_action"),
71
- title: z.string(),
72
- primitives: z.array(PrimitiveSchema),
177
+ blockType: z.literal('transaction_action'),
178
+ value: z.record(z.string(), z.unknown()).optional(),
179
+ sequence: z.boolean().optional(),
180
+ primitives: z.array(PrimitiveSchema).optional(),
181
+ transactions: z.array(TransactionGroupSchema).optional(),
182
+ needs_confirmation: z.boolean().optional(),
183
+ notes: z.string().optional(),
73
184
  risks: RisksSchema.optional(),
185
+ metadata: z.record(z.string(), z.unknown()).optional(),
186
+ tool_params: z.unknown().optional().nullable(),
187
+ tool_name: z.string().optional().nullable(),
74
188
  });
189
+ // --- Interactive Block ---
190
+ // Server sends: { blockType: "interactive", title, body?, context?, style?, options? }
191
+ // Note: Using .nullish() to accept both null and undefined (Python sends null for None)
75
192
  export const InteractiveOptionSchema = z.object({
76
193
  id: z.string(),
77
194
  label: z.string(),
78
- description: z.string().optional(),
79
- });
80
- export const InteractiveCardBlockSchema = z.object({
81
- type: z.literal("interactive_card"),
82
- title: z.string(),
83
- body: z.string().optional(),
84
- style: z.enum(["options", "confirm_cancel"]),
85
- options: z.array(InteractiveOptionSchema).optional(),
195
+ description: z.string().nullish(), // Accept null OR undefined
196
+ metadata: z.record(z.string(), z.unknown()).nullish(),
86
197
  });
87
- export const TimeseriesDataPointSchema = z.tuple([z.number(), z.number()]);
88
- export const TimeseriesSeriesSchema = z.object({
89
- label: z.string(),
90
- data: z.array(TimeseriesDataPointSchema),
91
- });
92
- export const TimeseriesDataSchema = z.record(z.string(), z.array(TimeseriesSeriesSchema));
93
- export const TimeseriesBlockSchema = z.object({
94
- type: z.literal("timeseries"),
95
- title: z.string(),
96
- data: TimeseriesDataSchema,
198
+ export const InteractiveBlockSchema = z.object({
199
+ blockType: z.literal('interactive'),
200
+ title: z.string(), // Required, matches Python
201
+ body: z.string().nullish(), // Optional, matches Python
202
+ context: z.string().nullish(), // Optional, matches Python
203
+ style: z.enum(['options', 'confirm_cancel']).nullish(),
204
+ options: z.array(InteractiveOptionSchema).nullish(),
97
205
  });
98
- export const PieChartBlockSchema = z.object({
99
- type: z.literal("pie_chart"),
100
- title: z.string(),
101
- data: z.array(z.tuple([z.string(), z.number()])),
102
- });
103
- export const BlockSchema = z.discriminatedUnion("type", [
104
- TableBlockSchema,
105
- MarkdownBlockSchema,
106
- TransactionActionBlockSchema,
107
- InteractiveCardBlockSchema,
108
- TimeseriesBlockSchema,
109
- PieChartBlockSchema,
110
- ]);
111
206
  // ============================================================================
112
- // Response Types
207
+ // Block Detection and Parsing
113
208
  // ============================================================================
114
- export const OutputTextSchema = z.object({
115
- type: z.literal("output_text"),
116
- text: z.string(),
117
- });
118
- export const ChaosBlockSchema = z.object({
119
- type: z.literal("chaos.block"),
120
- block: BlockSchema,
121
- });
122
- export const ContentPartSchema = z.discriminatedUnion("type", [
123
- OutputTextSchema,
124
- ChaosBlockSchema,
209
+ // Detect block type from raw server data
210
+ export function detectBlockType(raw) {
211
+ if (!raw || typeof raw !== 'object')
212
+ return 'unknown';
213
+ const obj = raw;
214
+ // Check blockType field first
215
+ if (obj.blockType === 'table')
216
+ return 'table';
217
+ if (obj.blockType === 'chart')
218
+ return 'chart';
219
+ if (obj.blockType === 'transaction_action')
220
+ return 'transaction_action';
221
+ if (obj.blockType === 'interactive')
222
+ return 'interactive';
223
+ // Markdown blocks have no blockType, just content
224
+ if ('content' in obj && typeof obj.content === 'string' && !('blockType' in obj)) {
225
+ return 'markdown';
226
+ }
227
+ return 'unknown';
228
+ }
229
+ // Parse a raw block based on detected type
230
+ export function parseRawBlock(raw) {
231
+ const blockType = detectBlockType(raw);
232
+ switch (blockType) {
233
+ case 'markdown': {
234
+ const result = MarkdownBlockSchema.safeParse(raw);
235
+ if (result.success) {
236
+ return { success: true, data: { type: 'markdown', ...result.data }, type: 'markdown' };
237
+ }
238
+ return { success: false, error: `Markdown parse error: ${result.error.message}` };
239
+ }
240
+ case 'table': {
241
+ const result = TableBlockSchema.safeParse(raw);
242
+ if (result.success) {
243
+ return { success: true, data: { type: 'table', ...result.data }, type: 'table' };
244
+ }
245
+ return { success: false, error: `Table parse error: ${result.error.message}` };
246
+ }
247
+ case 'chart': {
248
+ const result = ChartBlockSchema.safeParse(raw);
249
+ if (result.success) {
250
+ return { success: true, data: { type: 'chart', ...result.data }, type: 'chart' };
251
+ }
252
+ return { success: false, error: `Chart parse error: ${result.error.message}` };
253
+ }
254
+ case 'transaction_action': {
255
+ const result = TransactionActionBlockSchema.safeParse(raw);
256
+ if (result.success) {
257
+ return { success: true, data: { type: 'transaction_action', ...result.data }, type: 'transaction_action' };
258
+ }
259
+ return { success: false, error: `TransactionAction parse error: ${result.error.message}` };
260
+ }
261
+ case 'interactive': {
262
+ const result = InteractiveBlockSchema.safeParse(raw);
263
+ if (result.success) {
264
+ return { success: true, data: { type: 'interactive', ...result.data }, type: 'interactive' };
265
+ }
266
+ return { success: false, error: `Interactive parse error: ${result.error.message}` };
267
+ }
268
+ default:
269
+ return { success: false, error: `Unknown block type` };
270
+ }
271
+ }
272
+ // ============================================================================
273
+ // Legacy exports for backwards compatibility
274
+ // ============================================================================
275
+ // Create a discriminated union schema that adds 'type' field
276
+ // This is for SDK consumers who expect 'type' field
277
+ export const BlockSchema = z.union([
278
+ MarkdownBlockSchema.transform(data => ({ type: 'markdown', ...data })),
279
+ TableBlockSchema.transform(data => ({ type: 'table', ...data })),
280
+ ChartBlockSchema.transform(data => ({ type: 'chart', ...data })),
281
+ TransactionActionBlockSchema.transform(data => ({ type: 'transaction_action', ...data })),
282
+ InteractiveBlockSchema.transform(data => ({ type: 'interactive', ...data })),
125
283
  ]);
126
- export const OutputItemSchema = z.object({
127
- type: z.literal("message"),
128
- role: z.literal("assistant"),
129
- content: z.array(ContentPartSchema),
130
- });
131
- export const ResponseErrorSchema = z.object({
132
- message: z.string(),
133
- type: z.string(),
134
- code: z.string(),
135
- });
136
- export const ResponseSchema = z.object({
137
- id: z.string(),
138
- object: z.literal("response"),
139
- model: z.string(),
140
- status: z.enum(["completed", "failed"]),
141
- output: z.array(OutputItemSchema),
142
- error: ResponseErrorSchema.optional(),
143
- });