@haiai/haiai 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/README.md +127 -0
  2. package/bin/haiai.cjs +70 -0
  3. package/dist/cjs/a2a.js +352 -0
  4. package/dist/cjs/a2a.js.map +1 -0
  5. package/dist/cjs/agent.js +236 -0
  6. package/dist/cjs/agent.js.map +1 -0
  7. package/dist/cjs/client.js +2168 -0
  8. package/dist/cjs/client.js.map +1 -0
  9. package/dist/cjs/config.js +176 -0
  10. package/dist/cjs/config.js.map +1 -0
  11. package/dist/cjs/errors.js +102 -0
  12. package/dist/cjs/errors.js.map +1 -0
  13. package/dist/cjs/hash.js +52 -0
  14. package/dist/cjs/hash.js.map +1 -0
  15. package/dist/cjs/index.js +84 -0
  16. package/dist/cjs/index.js.map +1 -0
  17. package/dist/cjs/integrations.js +193 -0
  18. package/dist/cjs/integrations.js.map +1 -0
  19. package/dist/cjs/jacs.js +66 -0
  20. package/dist/cjs/jacs.js.map +1 -0
  21. package/dist/cjs/mime.js +100 -0
  22. package/dist/cjs/mime.js.map +1 -0
  23. package/dist/cjs/package.json +3 -0
  24. package/dist/cjs/signing.js +190 -0
  25. package/dist/cjs/signing.js.map +1 -0
  26. package/dist/cjs/sse.js +76 -0
  27. package/dist/cjs/sse.js.map +1 -0
  28. package/dist/cjs/types.js +6 -0
  29. package/dist/cjs/types.js.map +1 -0
  30. package/dist/cjs/verify.js +76 -0
  31. package/dist/cjs/verify.js.map +1 -0
  32. package/dist/cjs/ws.js +206 -0
  33. package/dist/cjs/ws.js.map +1 -0
  34. package/dist/esm/a2a.js +305 -0
  35. package/dist/esm/a2a.js.map +1 -0
  36. package/dist/esm/agent.js +231 -0
  37. package/dist/esm/agent.js.map +1 -0
  38. package/dist/esm/client.js +2131 -0
  39. package/dist/esm/client.js.map +1 -0
  40. package/dist/esm/config.js +171 -0
  41. package/dist/esm/config.js.map +1 -0
  42. package/dist/esm/errors.js +88 -0
  43. package/dist/esm/errors.js.map +1 -0
  44. package/dist/esm/hash.js +49 -0
  45. package/dist/esm/hash.js.map +1 -0
  46. package/dist/esm/index.js +27 -0
  47. package/dist/esm/index.js.map +1 -0
  48. package/dist/esm/integrations.js +147 -0
  49. package/dist/esm/integrations.js.map +1 -0
  50. package/dist/esm/jacs.js +61 -0
  51. package/dist/esm/jacs.js.map +1 -0
  52. package/dist/esm/mime.js +97 -0
  53. package/dist/esm/mime.js.map +1 -0
  54. package/dist/esm/signing.js +183 -0
  55. package/dist/esm/signing.js.map +1 -0
  56. package/dist/esm/sse.js +73 -0
  57. package/dist/esm/sse.js.map +1 -0
  58. package/dist/esm/types.js +5 -0
  59. package/dist/esm/types.js.map +1 -0
  60. package/dist/esm/verify.js +72 -0
  61. package/dist/esm/verify.js.map +1 -0
  62. package/dist/esm/ws.js +168 -0
  63. package/dist/esm/ws.js.map +1 -0
  64. package/dist/types/a2a.d.ts +52 -0
  65. package/dist/types/a2a.d.ts.map +1 -0
  66. package/dist/types/agent.d.ts +202 -0
  67. package/dist/types/agent.d.ts.map +1 -0
  68. package/dist/types/client.d.ts +486 -0
  69. package/dist/types/client.d.ts.map +1 -0
  70. package/dist/types/config.d.ts +31 -0
  71. package/dist/types/config.d.ts.map +1 -0
  72. package/dist/types/errors.d.ts +50 -0
  73. package/dist/types/errors.d.ts.map +1 -0
  74. package/dist/types/hash.d.ts +32 -0
  75. package/dist/types/hash.d.ts.map +1 -0
  76. package/dist/types/index.d.ts +22 -0
  77. package/dist/types/index.d.ts.map +1 -0
  78. package/dist/types/integrations.d.ts +25 -0
  79. package/dist/types/integrations.d.ts.map +1 -0
  80. package/dist/types/jacs.d.ts +26 -0
  81. package/dist/types/jacs.d.ts.map +1 -0
  82. package/dist/types/mime.d.ts +39 -0
  83. package/dist/types/mime.d.ts.map +1 -0
  84. package/dist/types/signing.d.ts +58 -0
  85. package/dist/types/signing.d.ts.map +1 -0
  86. package/dist/types/sse.d.ts +8 -0
  87. package/dist/types/sse.d.ts.map +1 -0
  88. package/dist/types/types.d.ts +652 -0
  89. package/dist/types/types.d.ts.map +1 -0
  90. package/dist/types/verify.d.ts +20 -0
  91. package/dist/types/verify.d.ts.map +1 -0
  92. package/dist/types/ws.d.ts +30 -0
  93. package/dist/types/ws.d.ts.map +1 -0
  94. package/examples/a2a_quickstart.ts +138 -0
  95. package/examples/hai_quickstart.ts +111 -0
  96. package/examples/mcp_quickstart.ts +53 -0
  97. package/npm/@haiai/cli-darwin-arm64/package.json +16 -0
  98. package/npm/@haiai/cli-darwin-x64/package.json +16 -0
  99. package/npm/@haiai/cli-linux-arm64/package.json +16 -0
  100. package/npm/@haiai/cli-linux-x64/package.json +16 -0
  101. package/npm/@haiai/cli-win32-x64/package.json +16 -0
  102. package/package.json +68 -0
  103. package/scripts/build-platform-packages.js +132 -0
  104. package/scripts/smoke-package.cjs +114 -0
  105. package/scripts/write-cjs-package.cjs +9 -0
  106. package/src/a2a.ts +463 -0
  107. package/src/agent.ts +302 -0
  108. package/src/client.ts +2504 -0
  109. package/src/config.ts +204 -0
  110. package/src/errors.ts +99 -0
  111. package/src/hash.ts +66 -0
  112. package/src/index.ts +163 -0
  113. package/src/integrations.ts +210 -0
  114. package/src/jacs.ts +86 -0
  115. package/src/mime.ts +131 -0
  116. package/src/signing.ts +233 -0
  117. package/src/sse.ts +86 -0
  118. package/src/types.ts +773 -0
  119. package/src/verify.ts +89 -0
  120. package/src/ws.ts +198 -0
  121. package/tests/_debug_jacs.cjs +29 -0
  122. package/tests/a2a-contract.test.ts +271 -0
  123. package/tests/a2a-fixtures.test.ts +73 -0
  124. package/tests/a2a.test.ts +379 -0
  125. package/tests/binary.test.ts +90 -0
  126. package/tests/client-api-methods.test.ts +176 -0
  127. package/tests/client-path-escaping.test.ts +80 -0
  128. package/tests/client-register.test.ts +61 -0
  129. package/tests/config.test.ts +281 -0
  130. package/tests/contract.test.ts +360 -0
  131. package/tests/cross-lang-contract.test.ts +67 -0
  132. package/tests/email-conformance.test.ts +289 -0
  133. package/tests/email-integration.test.ts +217 -0
  134. package/tests/email.test.ts +767 -0
  135. package/tests/errors.test.ts +167 -0
  136. package/tests/init-contract.test.ts +129 -0
  137. package/tests/integrations.test.ts +132 -0
  138. package/tests/jacs-passthrough.test.ts +125 -0
  139. package/tests/key-cache.test.ts +201 -0
  140. package/tests/key-integration.test.ts +119 -0
  141. package/tests/key-lookups.test.ts +187 -0
  142. package/tests/key-rotation.test.ts +362 -0
  143. package/tests/mime.test.ts +127 -0
  144. package/tests/security.test.ts +109 -0
  145. package/tests/setup.ts +60 -0
  146. package/tests/signing.test.ts +142 -0
  147. package/tests/sse.test.ts +125 -0
  148. package/tests/types.test.ts +294 -0
  149. package/tests/verify-link.test.ts +81 -0
  150. package/tests/ws.test.ts +213 -0
  151. package/tsconfig.cjs.json +11 -0
  152. package/tsconfig.json +22 -0
  153. package/vitest.config.ts +11 -0
package/src/types.ts ADDED
@@ -0,0 +1,773 @@
1
+ // =============================================================================
2
+ // Core types
3
+ // =============================================================================
4
+
5
+ /** Options for HaiClient constructor. */
6
+ export interface HaiClientOptions {
7
+ /** Path to jacs.config.json. Defaults to JACS_CONFIG_PATH env or ./jacs.config.json. */
8
+ configPath?: string;
9
+ /** HAI server URL. Default: https://hai.ai */
10
+ url?: string;
11
+ /** Request timeout in milliseconds. Default: 30000. */
12
+ timeout?: number;
13
+ /** Maximum retry attempts for retryable requests. Default: 3. */
14
+ maxRetries?: number;
15
+ }
16
+
17
+ /** JACS agent configuration loaded from jacs.config.json. */
18
+ export interface AgentConfig {
19
+ jacsAgentName: string;
20
+ jacsAgentVersion: string;
21
+ jacsKeyDir: string;
22
+ jacsId?: string;
23
+ jacsPrivateKeyPath?: string;
24
+ }
25
+
26
+ // =============================================================================
27
+ // Event types
28
+ // =============================================================================
29
+
30
+ /** Event types emitted by the HAI event stream. */
31
+ export type EventType =
32
+ | 'connected'
33
+ | 'benchmark_job'
34
+ | 'heartbeat'
35
+ | 'error'
36
+ | 'disconnected'
37
+ | 'job_complete'
38
+ | 'score'
39
+ | string;
40
+
41
+ /** An event received from HAI via SSE or WebSocket. */
42
+ export interface HaiEvent {
43
+ /** Type of event (e.g., "benchmark_job", "heartbeat", "connected"). */
44
+ eventType: EventType;
45
+ /** Event payload as parsed JSON. */
46
+ data: unknown;
47
+ /** Event ID if provided by the server. */
48
+ id?: string;
49
+ /** Raw event data string. */
50
+ raw: string;
51
+ }
52
+
53
+ /** Connection transport mode. */
54
+ export type ConnectionMode = 'sse' | 'ws';
55
+
56
+ // =============================================================================
57
+ // Benchmark types
58
+ // =============================================================================
59
+
60
+ /** Benchmark tier identifiers. */
61
+ export type BenchmarkTier = 'free' | 'pro' | 'enterprise';
62
+
63
+ /** A benchmark job received from HAI via SSE or WebSocket. */
64
+ export interface BenchmarkJob {
65
+ /** Unique run/job ID. */
66
+ runId: string;
67
+ /** Scenario description or prompt for the mediator. */
68
+ scenario: unknown;
69
+ /** Full event data. */
70
+ data: Record<string, unknown>;
71
+ }
72
+
73
+ /** Configuration for a benchmark job. */
74
+ export interface BenchmarkJobConfig {
75
+ /** Benchmark tier. */
76
+ tier: BenchmarkTier;
77
+ /** Run name. */
78
+ name?: string;
79
+ /** Transport protocol for the benchmark. */
80
+ transport?: ConnectionMode;
81
+ /** Stripe payment ID (required for pro tier). */
82
+ paymentId?: string;
83
+ }
84
+
85
+ /** A single message in a benchmark transcript. */
86
+ export interface TranscriptMessage {
87
+ /** Speaker role ("party_a", "party_b", "mediator", "system"). */
88
+ role: string;
89
+ /** Message text content. */
90
+ content: string;
91
+ /** ISO 8601 timestamp of the message. */
92
+ timestamp: string;
93
+ /** Structural annotations (e.g., "Dispute escalated"). */
94
+ annotations: string[];
95
+ }
96
+
97
+ /** A turn in a conversation (alias for TranscriptMessage). */
98
+ export type ConversationTurn = TranscriptMessage;
99
+
100
+ // =============================================================================
101
+ // Result types
102
+ // =============================================================================
103
+
104
+ /** Result of a hello world exchange with HAI. */
105
+ export interface HelloWorldResult {
106
+ /** Whether the exchange succeeded. */
107
+ success: boolean;
108
+ /** ISO 8601 timestamp from HAI's response. */
109
+ timestamp: string;
110
+ /** The caller's IP address as seen by HAI. */
111
+ clientIp: string;
112
+ /** HAI's public key fingerprint. */
113
+ haiPublicKeyFingerprint: string;
114
+ /** Human-readable acknowledgment message from HAI. */
115
+ message: string;
116
+ /** HAI's signed acknowledgment. */
117
+ haiSignedAck: string;
118
+ /** Unique hello exchange ID. */
119
+ helloId: string;
120
+ /** Test scenario preview (if requested). */
121
+ testScenario?: unknown;
122
+ /** Whether HAI's signature on the ACK was verified. */
123
+ haiSignatureValid: boolean;
124
+ /** Full response from the API. */
125
+ rawResponse: Record<string, unknown>;
126
+ }
127
+
128
+ /** Result of registering an agent with HAI. */
129
+ export interface RegistrationResult {
130
+ success: boolean;
131
+ agentId: string;
132
+ jacsId: string;
133
+ haiSignature: string;
134
+ registrationId: string;
135
+ registeredAt: string;
136
+ rawResponse: Record<string, unknown>;
137
+ }
138
+
139
+ /** Options for key rotation. */
140
+ export interface RotateKeysOptions {
141
+ /** Whether to re-register with HAI after local rotation. Default: true. */
142
+ registerWithHai?: boolean;
143
+ /** HAI server URL (required if registerWithHai is true). */
144
+ haiUrl?: string;
145
+ }
146
+
147
+ /** Result of a key rotation operation. */
148
+ export interface RotationResult {
149
+ /** Agent's stable JACS ID (unchanged). */
150
+ jacsId: string;
151
+ /** Version before rotation. */
152
+ oldVersion: string;
153
+ /** New version assigned during rotation. */
154
+ newVersion: string;
155
+ /** SHA-256 hash of the new public key (hex). */
156
+ newPublicKeyHash: string;
157
+ /** Whether re-registration with HAI succeeded. */
158
+ registeredWithHai: boolean;
159
+ /** Complete self-signed agent JSON string. */
160
+ signedAgentJson: string;
161
+ }
162
+
163
+ /** Result of a free chaotic benchmark run. No score, transcript only. */
164
+ export interface FreeChaoticResult {
165
+ /** Whether the run completed. */
166
+ success: boolean;
167
+ /** Unique ID for this benchmark run. */
168
+ runId: string;
169
+ /** List of transcript messages. */
170
+ transcript: TranscriptMessage[];
171
+ /** CTA message for paid tiers. */
172
+ upsellMessage: string;
173
+ /** Full response from the API. */
174
+ rawResponse: Record<string, unknown>;
175
+ }
176
+
177
+ /** Result of a pro tier benchmark run. Single score, no breakdown. */
178
+ export interface ProRunResult {
179
+ /** Whether the run completed. */
180
+ success: boolean;
181
+ /** Unique ID for this benchmark run. */
182
+ runId: string;
183
+ /** Single aggregate score (0-100). */
184
+ score: number;
185
+ /** List of transcript messages. */
186
+ transcript: TranscriptMessage[];
187
+ /** ID of the Stripe payment used. */
188
+ paymentId: string;
189
+ /** Full response from the API. */
190
+ rawResponse: Record<string, unknown>;
191
+ }
192
+
193
+ /** Result of an enterprise tier benchmark run. */
194
+ export interface EnterpriseRunResult {
195
+ /** Whether the run completed. */
196
+ success: boolean;
197
+ /** Unique ID for this benchmark run. */
198
+ runId: string;
199
+ /** Aggregate score (0-100). */
200
+ score: number;
201
+ /** Category-level breakdowns. */
202
+ categories: Record<string, number>;
203
+ /** List of transcript messages. */
204
+ transcript: TranscriptMessage[];
205
+ /** ID of the Stripe payment used. */
206
+ paymentId: string;
207
+ /** Full response from the API. */
208
+ rawResponse: Record<string, unknown>;
209
+ }
210
+
211
+ /** Generic benchmark result (union of all tiers). */
212
+ export type BenchmarkResult = FreeChaoticResult | ProRunResult | EnterpriseRunResult;
213
+
214
+ /** @deprecated Use ProRunResult instead. */
215
+ export type DnsCertifiedResult = ProRunResult;
216
+ /** @deprecated Use EnterpriseRunResult instead. */
217
+ export type FullyCertifiedResult = EnterpriseRunResult;
218
+
219
+ /** Result of submitting a benchmark job response. */
220
+ export interface JobResponseResult {
221
+ /** Whether the response was accepted. */
222
+ success: boolean;
223
+ /** The job ID that was responded to. */
224
+ jobId: string;
225
+ /** Acknowledgment message from HAI. */
226
+ message: string;
227
+ /** Full response from the API. */
228
+ rawResponse: Record<string, unknown>;
229
+ }
230
+
231
+ /** A single registration entry from the verify endpoint. */
232
+ export interface RegistrationEntry {
233
+ /** Key ID used for this registration. */
234
+ keyId: string;
235
+ /** Signature algorithm (e.g., "Ed25519"). */
236
+ algorithm: string;
237
+ /** Signature JSON payload. */
238
+ signatureJson: string;
239
+ /** Timestamp when the registration was signed. */
240
+ signedAt: string;
241
+ }
242
+
243
+ /** Result of verifying an agent's registration (GET /api/v1/agents/{jacs_id}/verify). */
244
+ export interface VerifyAgentResult {
245
+ /** The agent's JACS ID. */
246
+ jacsId: string;
247
+ /** Whether the agent is registered with HAI. */
248
+ registered: boolean;
249
+ /** List of registration entries. */
250
+ registrations: RegistrationEntry[];
251
+ /** Whether DNS has been verified for the agent's domain. */
252
+ dnsVerified: boolean;
253
+ /** Agent registration timestamp. */
254
+ registeredAt: string;
255
+ /** Full response from the API. */
256
+ rawResponse: Record<string, unknown>;
257
+ }
258
+
259
+ /** Result of checking username availability. */
260
+ export interface CheckUsernameResult {
261
+ /** Whether the username is available. */
262
+ available: boolean;
263
+ /** The username that was checked. */
264
+ username: string;
265
+ /** Reason if unavailable. */
266
+ reason?: string;
267
+ }
268
+
269
+ /** Result of claiming a username. */
270
+ export interface ClaimUsernameResult {
271
+ /** The claimed username. */
272
+ username: string;
273
+ /** The resulting hai.ai email address. */
274
+ email: string;
275
+ /** The agent ID the username was claimed for. */
276
+ agentId: string;
277
+ }
278
+
279
+ /** Result of updating (renaming) a username. */
280
+ export interface UpdateUsernameResult {
281
+ /** The new username. */
282
+ username: string;
283
+ /** The resulting hai.ai email address. */
284
+ email: string;
285
+ /** Previous username before rename. */
286
+ previousUsername: string;
287
+ }
288
+
289
+ /** Result of deleting a username claim. */
290
+ export interface DeleteUsernameResult {
291
+ /** Released username placed into cooldown. */
292
+ releasedUsername: string;
293
+ /** ISO 8601 timestamp when cooldown expires. */
294
+ cooldownUntil: string;
295
+ /** Human-readable server message. */
296
+ message: string;
297
+ }
298
+
299
+ /** Payload submitted to HAI for a benchmark job response. */
300
+ export interface JobResponse {
301
+ response: {
302
+ message: string;
303
+ metadata: Record<string, unknown> | null;
304
+ processing_time_ms: number;
305
+ };
306
+ }
307
+
308
+ // =============================================================================
309
+ // Agent types
310
+ // =============================================================================
311
+
312
+ /** Capabilities an agent can declare. */
313
+ export type AgentCapability =
314
+ | 'mediation'
315
+ | 'arbitration'
316
+ | 'negotiation'
317
+ | 'translation'
318
+ | 'summarization'
319
+ | string;
320
+
321
+ // =============================================================================
322
+ // Connection options
323
+ // =============================================================================
324
+
325
+ /** Options for HaiClient.connect(). */
326
+ export interface ConnectOptions {
327
+ /** Transport protocol: "sse" (default) or "ws" (WebSocket). */
328
+ transport?: ConnectionMode;
329
+ /** Callback function called for each event. */
330
+ onEvent?: (event: HaiEvent) => void;
331
+ }
332
+
333
+ /** Options for HaiClient.onBenchmarkJob(). */
334
+ export interface OnBenchmarkJobOptions {
335
+ /** Transport protocol: "sse" (default) or "ws". */
336
+ transport?: ConnectionMode;
337
+ }
338
+
339
+ /** Options for pro tier benchmark run. */
340
+ export interface ProRunOptions {
341
+ /** Transport protocol. */
342
+ transport?: ConnectionMode;
343
+ /** Milliseconds between payment status checks. Default: 2000. */
344
+ pollIntervalMs?: number;
345
+ /** Max milliseconds to wait for payment. Default: 300000 (5 min). */
346
+ pollTimeoutMs?: number;
347
+ /** Callback with checkout URL (e.g., to open in browser). */
348
+ onCheckoutUrl?: (url: string) => void;
349
+ }
350
+
351
+ /** @deprecated Use ProRunOptions instead. */
352
+ export type DnsCertifiedRunOptions = ProRunOptions;
353
+
354
+ /** Options for free chaotic run. */
355
+ export interface FreeChaoticRunOptions {
356
+ /** Transport protocol. */
357
+ transport?: ConnectionMode;
358
+ }
359
+
360
+ // =============================================================================
361
+ // Email types
362
+ // =============================================================================
363
+
364
+ /** An email attachment. */
365
+ export interface EmailAttachment {
366
+ /** Attachment file name. */
367
+ filename: string;
368
+ /** MIME content type. */
369
+ contentType: string;
370
+ /** Raw attachment data. */
371
+ data: Buffer;
372
+ /** Base64-encoded attachment data (used when `data` is empty). */
373
+ dataBase64?: string;
374
+ }
375
+
376
+ /** Options for sending an email. */
377
+ export interface SendEmailOptions {
378
+ /** Recipient email address. */
379
+ to: string;
380
+ /** Email subject line. */
381
+ subject: string;
382
+ /** Email body text. */
383
+ body: string;
384
+ /** Message ID to reply to (for threading). */
385
+ inReplyTo?: string;
386
+ /** File attachments to include with the email. */
387
+ attachments?: EmailAttachment[];
388
+ /** CC recipient addresses. */
389
+ cc?: string[];
390
+ /** BCC recipient addresses. */
391
+ bcc?: string[];
392
+ /** Labels/tags for the message. */
393
+ labels?: string[];
394
+ }
395
+
396
+ /** Result of sending an email. */
397
+ export interface SendEmailResult {
398
+ /** Unique message ID assigned by HAI. */
399
+ messageId: string;
400
+ /** Delivery status. */
401
+ status: string;
402
+ }
403
+
404
+ /** An email message. */
405
+ export interface EmailMessage {
406
+ /** Unique message ID. */
407
+ id: string;
408
+ /** Direction: "inbound" or "outbound". */
409
+ direction: string;
410
+ /** Sender email address. */
411
+ fromAddress: string;
412
+ /** Recipient email address. */
413
+ toAddress: string;
414
+ /** Email subject. */
415
+ subject: string;
416
+ /** Email body text. */
417
+ bodyText: string;
418
+ /** RFC 2822 Message-ID. */
419
+ messageId: string;
420
+ /** Message-ID of the parent message (for threading), or null. */
421
+ inReplyTo: string | null;
422
+ /** Whether the message has been read. */
423
+ isRead: boolean;
424
+ /** Delivery status (e.g., "queued", "delivered", "failed"). */
425
+ deliveryStatus: string;
426
+ /** ISO 8601 timestamp when the message was created. */
427
+ createdAt: string;
428
+ /** ISO 8601 timestamp when the message was read, or null. */
429
+ readAt: string | null;
430
+ /** Whether the JACS signature on this message was verified. */
431
+ jacsVerified: boolean;
432
+ /** CC recipient addresses. */
433
+ ccAddresses: string[];
434
+ /** Labels/tags on the message. */
435
+ labels: string[];
436
+ /** Folder the message is in (e.g., "inbox", "archive"). */
437
+ folder: string;
438
+ }
439
+
440
+ /** Options for listing email messages. */
441
+ export interface ListMessagesOptions {
442
+ /** Max number of messages to return. */
443
+ limit?: number;
444
+ /** Offset for pagination. */
445
+ offset?: number;
446
+ /** Filter by direction: "inbound" or "outbound". */
447
+ direction?: 'inbound' | 'outbound';
448
+ /** Filter by read status (true/false/undefined for all). */
449
+ isRead?: boolean;
450
+ /** Filter by folder (e.g., "inbox", "archive"). */
451
+ folder?: string;
452
+ /** Filter by label/tag. */
453
+ label?: string;
454
+ }
455
+
456
+ /** Options for searching email messages. */
457
+ export interface SearchOptions {
458
+ /** Search query string. */
459
+ query: string;
460
+ /** Max number of results. */
461
+ limit?: number;
462
+ /** Offset for pagination. */
463
+ offset?: number;
464
+ /** Filter by direction: "inbound" or "outbound". */
465
+ direction?: 'inbound' | 'outbound';
466
+ /** Filter by sender address. */
467
+ fromAddress?: string;
468
+ /** Filter by recipient address. */
469
+ toAddress?: string;
470
+ /** Filter by read status. */
471
+ isRead?: boolean;
472
+ /** Filter by JACS verification status. */
473
+ jacsVerified?: boolean;
474
+ /** Filter by folder (e.g., "inbox", "archive"). */
475
+ folder?: string;
476
+ /** Filter by label/tag. */
477
+ label?: string;
478
+ }
479
+
480
+ /** A contact derived from email message history. */
481
+ export interface Contact {
482
+ /** Contact email address. */
483
+ email: string;
484
+ /** Display name, if known. */
485
+ displayName?: string;
486
+ /** ISO 8601 timestamp of last contact. */
487
+ lastContact: string;
488
+ /** Whether this contact's agent is JACS-verified. */
489
+ jacsVerified: boolean;
490
+ /** Reputation tier of this contact. */
491
+ reputationTier?: string;
492
+ }
493
+
494
+ /** Options for forwarding an email. */
495
+ export interface ForwardOptions {
496
+ /** ID of the message to forward. */
497
+ messageId: string;
498
+ /** Recipient to forward to. */
499
+ to: string;
500
+ /** Optional comment prepended to the forwarded body. */
501
+ comment?: string;
502
+ }
503
+
504
+ /** Volume statistics from the email status response. */
505
+ export interface EmailVolumeInfo {
506
+ /** Total messages sent all time. */
507
+ sentTotal: number;
508
+ /** Total messages received all time. */
509
+ receivedTotal: number;
510
+ /** Messages sent in the last 24 hours. */
511
+ sent24h: number;
512
+ }
513
+
514
+ /** Delivery metrics from the email status response. */
515
+ export interface EmailDeliveryInfo {
516
+ /** Number of bounced messages. */
517
+ bounceCount: number;
518
+ /** Number of spam reports received. */
519
+ spamReportCount: number;
520
+ /** Delivery success rate (0.0 to 1.0). */
521
+ deliveryRate: number;
522
+ }
523
+
524
+ /** Reputation scoring from the email status response. */
525
+ export interface EmailReputationInfo {
526
+ /** Overall reputation score. */
527
+ score: number;
528
+ /** Reputation tier string. */
529
+ tier: string;
530
+ /** Email-specific reputation score. */
531
+ emailScore: number;
532
+ /** HAI platform reputation score, or null if not yet computed. */
533
+ haiScore: number | null;
534
+ }
535
+
536
+ /** Email rate limit and status info. */
537
+ export interface EmailStatus {
538
+ /** The agent's email address. */
539
+ email: string;
540
+ /** Email provisioning status. */
541
+ status: string;
542
+ /** Agent's reputation tier. */
543
+ tier: string;
544
+ /** Current billing tier. */
545
+ billingTier: string;
546
+ /** Messages sent in the last 24 hours. */
547
+ messagesSent24h: number;
548
+ /** Maximum emails per day for current tier. */
549
+ dailyLimit: number;
550
+ /** Emails sent today. */
551
+ dailyUsed: number;
552
+ /** ISO 8601 timestamp when the daily counter resets. */
553
+ resetsAt: string;
554
+ /** Total messages sent all time. */
555
+ messagesSentTotal: number;
556
+ /** Whether external (non-hai.ai) email sending is enabled. */
557
+ externalEnabled: boolean;
558
+ /** Number of external emails sent today. */
559
+ externalSendsToday: number;
560
+ /** ISO 8601 timestamp of last tier change, or null. */
561
+ lastTierChange: string | null;
562
+ /** Volume statistics (from consolidated status). */
563
+ volume?: EmailVolumeInfo | null;
564
+ /** Delivery metrics (from consolidated status). */
565
+ delivery?: EmailDeliveryInfo | null;
566
+ /** Reputation scoring (from consolidated status). */
567
+ reputation?: EmailReputationInfo | null;
568
+ }
569
+
570
+ /** Response from the public key registry endpoint. */
571
+ export interface KeyRegistryResponse {
572
+ /** The agent's email address. */
573
+ email: string;
574
+ /** The agent's JACS ID. */
575
+ jacsId: string;
576
+ /** Base64-encoded public key. */
577
+ publicKey: string;
578
+ /** Signature algorithm (e.g., "ed25519"). */
579
+ algorithm: string;
580
+ /** Agent's reputation tier. */
581
+ reputationTier: string;
582
+ /** ISO 8601 registration timestamp. */
583
+ registeredAt: string;
584
+ }
585
+
586
+ /** Status of a single field in JACS email content verification. */
587
+ export type FieldStatus = 'pass' | 'modified' | 'fail' | 'unverifiable';
588
+
589
+ /** Result for a single field in content verification. */
590
+ export interface FieldResult {
591
+ /** Field name (e.g., "subject", "body", "from"). */
592
+ field: string;
593
+ /** Verification status for this field. */
594
+ status: FieldStatus;
595
+ /** Original hash from the JACS signature, if available. */
596
+ originalHash?: string;
597
+ /** Current hash computed from the email, if available. */
598
+ currentHash?: string;
599
+ /** Original value (for short fields), if available. */
600
+ originalValue?: string;
601
+ /** Current value (for short fields), if available. */
602
+ currentValue?: string;
603
+ }
604
+
605
+ /** Entry in a JACS email forwarding chain. */
606
+ export interface ChainEntry {
607
+ /** Signer identifier (e.g., email address). */
608
+ signer: string;
609
+ /** JACS ID of the signer. */
610
+ jacsId: string;
611
+ /** Whether this chain entry's signature is valid. */
612
+ valid: boolean;
613
+ /** Whether this entry represents a forward (vs. original). */
614
+ forwarded: boolean;
615
+ }
616
+
617
+ /** Result of verifying a JACS attachment-signed email. */
618
+ export interface EmailVerificationResultV2 {
619
+ /** Whether overall verification passed. */
620
+ valid: boolean;
621
+ /** JACS ID of the signer. */
622
+ jacsId: string;
623
+ /** Signature algorithm (e.g., "Ed25519"). */
624
+ algorithm: string;
625
+ /** Signer's reputation tier. */
626
+ reputationTier: string;
627
+ /** Whether DNS verification passed, or null if not checked. */
628
+ dnsVerified?: boolean | null;
629
+ /** Per-field verification results. */
630
+ fieldResults: FieldResult[];
631
+ /** Forwarding chain entries. */
632
+ chain: ChainEntry[];
633
+ /** Error message if verification failed, or null. */
634
+ error?: string | null;
635
+ /** Agent status from registry: "active", "suspended", or "revoked". */
636
+ agentStatus?: string | null;
637
+ /** Benchmark tiers the agent has completed. */
638
+ benchmarksCompleted?: string[];
639
+ }
640
+
641
+ // =============================================================================
642
+ // Key lookup types
643
+ // =============================================================================
644
+
645
+ /** Public key information returned by the key lookup endpoint. */
646
+ export interface PublicKeyInfo {
647
+ /** Agent's JACS ID. */
648
+ jacsId: string;
649
+ /** Key version. */
650
+ version: string;
651
+ /** Public key in PEM format. */
652
+ publicKey: string;
653
+ /** Base64-encoded raw public key bytes. */
654
+ publicKeyRawB64: string;
655
+ /** Signature algorithm (e.g., "Ed25519"). */
656
+ algorithm: string;
657
+ /** Hash of the public key. */
658
+ publicKeyHash: string;
659
+ /** Key status (e.g., "active"). */
660
+ status: string;
661
+ /** Whether DNS has been verified for this agent. */
662
+ dnsVerified: boolean;
663
+ /** ISO 8601 timestamp when the key was created. */
664
+ createdAt: string;
665
+ }
666
+
667
+ // =============================================================================
668
+ // Verification types
669
+ // =============================================================================
670
+
671
+ /** Badge levels for agent verification. */
672
+ export type BadgeLevel = 'none' | 'basic' | 'domain' | 'attested';
673
+
674
+ /** Result of verifying an agent document. */
675
+ export interface VerificationResult {
676
+ /** Whether the Ed25519 signature is valid. */
677
+ signatureValid: boolean;
678
+ /** Whether DNS has been verified. */
679
+ dnsVerified: boolean;
680
+ /** Whether the agent is registered with HAI. */
681
+ haiRegistered: boolean;
682
+ /** Agent's badge/trust level. */
683
+ badgeLevel: BadgeLevel;
684
+ /** Agent's JACS ID from the document. */
685
+ jacsId: string;
686
+ /** JACS version from the document. */
687
+ version: string;
688
+ /** Any errors encountered during verification. */
689
+ errors: string[];
690
+ }
691
+
692
+ /** Result of verifying a signed JACS document via HAI verify endpoint. */
693
+ export interface DocumentVerificationResult {
694
+ /** Whether verification succeeded. */
695
+ valid: boolean;
696
+ /** ISO 8601 verification timestamp from HAI. */
697
+ verifiedAt: string;
698
+ /** Document type string from verifier. */
699
+ documentType: string;
700
+ /** Whether issuer trust checks passed. */
701
+ issuerVerified: boolean;
702
+ /** Whether signature checks passed. */
703
+ signatureVerified: boolean;
704
+ /** Signer identifier from verifier. */
705
+ signerId: string;
706
+ /** ISO 8601 signed-at timestamp from verifier. */
707
+ signedAt: string;
708
+ /** Optional error message. */
709
+ error?: string;
710
+ }
711
+
712
+ /** Advanced verification badge levels from /api/v1/agents/{agent_id}/verification. */
713
+ export type AdvancedBadgeLevel = 'none' | 'basic' | 'domain' | 'attested';
714
+
715
+ /** Three-level verification status from advanced verification endpoints. */
716
+ export interface AdvancedVerificationStatus {
717
+ /** Level 1 cryptographic JACS signature verification. */
718
+ jacsValid: boolean;
719
+ /** Level 2 DNS/domain verification. */
720
+ dnsValid: boolean;
721
+ /** Level 3 HAI registration/attestation. */
722
+ haiRegistered: boolean;
723
+ /** Computed trust badge level. */
724
+ badge: AdvancedBadgeLevel;
725
+ }
726
+
727
+ /** Result from GET /api/v1/agents/{agent_id}/verification and POST /api/v1/agents/verify. */
728
+ export interface AdvancedVerificationResult {
729
+ /** Agent identifier that was verified. */
730
+ agentId: string;
731
+ /** Multi-level verification status. */
732
+ verification: AdvancedVerificationStatus;
733
+ /** Optional HAI signature summaries. */
734
+ haiSignatures: string[];
735
+ /** ISO 8601 verification timestamp. */
736
+ verifiedAt: string;
737
+ /** Errors/warnings produced during verification. */
738
+ errors: string[];
739
+ /** Full raw response payload. */
740
+ rawResponse: Record<string, unknown>;
741
+ }
742
+
743
+ // =============================================================================
744
+ // API error types
745
+ // =============================================================================
746
+
747
+ /** Structured error codes returned by the HAI API. */
748
+ export type HaiErrorCode =
749
+ | 'EMAIL_NOT_ACTIVE'
750
+ | 'RECIPIENT_NOT_FOUND'
751
+ | 'SUBJECT_TOO_LONG'
752
+ | 'BODY_TOO_LARGE'
753
+ | 'EXTERNAL_RECIPIENT'
754
+ | 'RATE_LIMITED'
755
+ | 'MESSAGE_NOT_FOUND'
756
+ | 'SIGNATURE_INVALID';
757
+
758
+ /** API error response shape. */
759
+ export interface ApiErrorResponse {
760
+ error: string;
761
+ message: string;
762
+ status: number;
763
+ request_id?: string;
764
+ error_code?: HaiErrorCode;
765
+ }
766
+
767
+ /** Request payload options for POST /api/v1/agents/verify. */
768
+ export interface VerifyAgentDocumentOnHaiOptions {
769
+ /** Optional public key PEM if not embedded in agent_json. */
770
+ publicKey?: string;
771
+ /** Optional domain override for DNS verification. */
772
+ domain?: string;
773
+ }