@hermespilot/link 0.1.9 → 0.2.1

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.
@@ -15,6 +15,42 @@ interface RuntimePaths {
15
15
  pairingDir: string;
16
16
  }
17
17
 
18
+ interface LinkStatistics {
19
+ conversations: {
20
+ total: number;
21
+ active: number;
22
+ deleted: number;
23
+ };
24
+ tokens: {
25
+ input_tokens: number;
26
+ output_tokens: number;
27
+ total_tokens: number;
28
+ };
29
+ messages: {
30
+ total: number;
31
+ };
32
+ runs: {
33
+ total: number;
34
+ };
35
+ models: {
36
+ total: number;
37
+ };
38
+ profiles: {
39
+ total: number;
40
+ };
41
+ skills: {
42
+ total: number;
43
+ };
44
+ tools: {
45
+ total: number;
46
+ };
47
+ updated_at?: string;
48
+ }
49
+ interface LinkStatisticsFilter {
50
+ profileUid?: string | null;
51
+ profileName?: string | null;
52
+ }
53
+
18
54
  type LogLevel = 'debug' | 'info' | 'warn' | 'error';
19
55
  interface FileLoggerOptions {
20
56
  paths?: RuntimePaths;
@@ -41,9 +77,315 @@ declare class FileLogger {
41
77
  private rotateIfNeeded;
42
78
  }
43
79
 
80
+ interface ConversationProfileSummary {
81
+ uid?: string;
82
+ name: string;
83
+ display_name: string;
84
+ avatar_url?: string | null;
85
+ }
86
+ interface ConversationSummary {
87
+ id: string;
88
+ title: string;
89
+ created_at: string;
90
+ updated_at: string;
91
+ last_event_seq: number;
92
+ usage: {
93
+ input_tokens: number;
94
+ output_tokens: number;
95
+ total_tokens: number;
96
+ updated_at?: string;
97
+ };
98
+ profile: ConversationProfileSummary;
99
+ last_message: {
100
+ id: string;
101
+ role: string;
102
+ content_preview: string;
103
+ } | null;
104
+ }
105
+ interface ConversationRuntimeMetadata {
106
+ profile: ConversationProfileSummary;
107
+ model: {
108
+ id: string;
109
+ provider?: string;
110
+ context_window?: number;
111
+ reasoning_effort?: string;
112
+ };
113
+ context: {
114
+ input_tokens: number;
115
+ output_tokens: number;
116
+ total_tokens: number;
117
+ context_window?: number;
118
+ usage_percent?: number;
119
+ updated_at?: string;
120
+ };
121
+ }
122
+ interface ConversationMessagesPageInfo {
123
+ limit: number;
124
+ has_more_before: boolean;
125
+ has_more_after: boolean;
126
+ oldest_message_id: string | null;
127
+ newest_message_id: string | null;
128
+ }
129
+ interface LinkMessagePart {
130
+ type: 'text' | 'image' | 'file' | 'audio' | 'video' | 'unsupported';
131
+ text?: string;
132
+ blob?: string;
133
+ mime?: string;
134
+ size?: number;
135
+ filename?: string;
136
+ url?: string;
137
+ local_path?: string;
138
+ kind?: 'voice';
139
+ is_voice_note?: boolean;
140
+ duration_ms?: number;
141
+ waveform?: number[];
142
+ }
143
+ interface LinkMessageAgentEvent {
144
+ id: string;
145
+ title: string;
146
+ status: 'running' | 'completed' | 'failed' | 'info';
147
+ created_at: string;
148
+ subtitle?: string;
149
+ detail?: string;
150
+ completed_at?: string;
151
+ raw?: {
152
+ format: string;
153
+ payload: unknown;
154
+ };
155
+ }
156
+ interface LinkMessage {
157
+ id: string;
158
+ schema_version: 1;
159
+ conversation_id: string;
160
+ role: 'user' | 'assistant' | 'tool' | 'system';
161
+ status: 'queued' | 'completed' | 'streaming' | 'failed' | 'cancelled';
162
+ run_id?: string;
163
+ client_message_id?: string;
164
+ created_at: string;
165
+ updated_at: string;
166
+ sender: {
167
+ id: string;
168
+ type: 'human' | 'agent' | 'system' | 'tool';
169
+ display_name: string;
170
+ profile_uid?: string;
171
+ profile?: string;
172
+ };
173
+ parts: LinkMessagePart[];
174
+ attachments: unknown[];
175
+ agent_events?: LinkMessageAgentEvent[];
176
+ hermes?: Record<string, unknown>;
177
+ raw?: {
178
+ format: string;
179
+ payload: unknown;
180
+ };
181
+ }
182
+ interface ConversationEvent {
183
+ seq: number;
184
+ type: string;
185
+ conversation_id: string;
186
+ message_id?: string;
187
+ run_id?: string;
188
+ created_at: string;
189
+ payload?: Record<string, unknown>;
190
+ raw?: {
191
+ format: string;
192
+ payload: unknown;
193
+ };
194
+ }
195
+ interface DeleteConversationResult {
196
+ conversation_id: string;
197
+ hermes_deleted: boolean;
198
+ deleted_at: string;
199
+ }
200
+ interface BulkDeleteConversationResult {
201
+ conversation_id: string;
202
+ status: 'deleted' | 'failed';
203
+ hermes_deleted?: boolean;
204
+ deleted_at?: string;
205
+ error?: {
206
+ code: string;
207
+ message: string;
208
+ };
209
+ }
210
+ interface LinkRun {
211
+ id: string;
212
+ kind?: 'agent' | 'command';
213
+ hermes_run_id?: string;
214
+ conversation_id: string;
215
+ trigger_message_id: string;
216
+ assistant_message_id: string;
217
+ hermes_session_id: string;
218
+ status: 'queued' | 'running' | 'completed' | 'failed' | 'cancelled' | 'unknown';
219
+ started_at: string;
220
+ completed_at?: string;
221
+ error_message?: string;
222
+ error_detail?: string;
223
+ profile_uid?: string;
224
+ profile_name_snapshot?: string;
225
+ profile?: string;
226
+ model?: string;
227
+ provider?: string;
228
+ context_window?: number;
229
+ usage?: {
230
+ input_tokens: number;
231
+ output_tokens: number;
232
+ total_tokens: number;
233
+ context_tokens?: number;
234
+ context_window?: number;
235
+ usage_percent?: number;
236
+ };
237
+ }
238
+ interface SendMessageInput {
239
+ conversationId: string;
240
+ content: string;
241
+ attachments?: MessageAttachmentInput[];
242
+ clientMessageId?: string;
243
+ idempotencyKey?: string;
244
+ profileName?: string;
245
+ }
246
+ interface MessageAttachmentInput {
247
+ blob_id?: string;
248
+ blobId?: string;
249
+ kind?: string;
250
+ type?: string;
251
+ is_voice_note?: boolean;
252
+ isVoiceNote?: boolean;
253
+ duration_ms?: number;
254
+ durationMs?: number;
255
+ waveform?: number[];
256
+ waveform_samples?: number[];
257
+ waveformSamples?: number[];
258
+ }
259
+ interface ConversationMessagesPageOptions {
260
+ limit?: number;
261
+ beforeMessageId?: string;
262
+ }
263
+ interface SendMessageResult {
264
+ conversation_id: string;
265
+ user_message: Pick<LinkMessage, 'id' | 'status'>;
266
+ assistant_message: Pick<LinkMessage, 'id' | 'status'>;
267
+ run: Pick<LinkRun, 'id' | 'status'>;
268
+ last_event_seq: number;
269
+ conversation?: ConversationSummary;
270
+ }
271
+ interface CancelRunResult {
272
+ conversation_id: string;
273
+ run: Pick<LinkRun, 'id' | 'status'>;
274
+ last_event_seq: number;
275
+ }
276
+ type ConversationEventListener = (event: ConversationEvent) => void;
277
+
278
+ declare class ConversationService {
279
+ private readonly paths;
280
+ private readonly logger;
281
+ private readonly emitter;
282
+ private readonly conversationLocks;
283
+ private readonly activeRunControllers;
284
+ private readonly store;
285
+ private readonly commandHandlers;
286
+ private readonly metadata;
287
+ private readonly maintenance;
288
+ private readonly orchestration;
289
+ private readonly queries;
290
+ private readonly runLifecycle;
291
+ constructor(paths: RuntimePaths, logger: FileLogger);
292
+ private withConversationLock;
293
+ listConversations(): Promise<ConversationSummary[]>;
294
+ getStatistics(filter?: LinkStatisticsFilter): Promise<LinkStatistics>;
295
+ rebuildStatisticsIndex(): Promise<void>;
296
+ createConversation(input?: {
297
+ title?: string;
298
+ profileName?: string;
299
+ }): Promise<ConversationSummary>;
300
+ ensureCronInboxConversation(input?: {
301
+ profileName?: string;
302
+ }): Promise<string>;
303
+ appendCronDelivery(input: {
304
+ conversationId: string;
305
+ profileName: string;
306
+ jobId: string;
307
+ jobName?: string;
308
+ outputPath: string;
309
+ content: string;
310
+ runAt?: string;
311
+ }): Promise<void>;
312
+ syncCronDeliveries(): Promise<void>;
313
+ getMessages(conversationId: string, options?: ConversationMessagesPageOptions): Promise<{
314
+ messages: LinkMessage[];
315
+ last_event_seq: number;
316
+ runtime: ConversationRuntimeMetadata;
317
+ page: ConversationMessagesPageInfo;
318
+ }>;
319
+ setConversationModel(conversationId: string, modelId: string): Promise<{
320
+ conversation_id: string;
321
+ model_override: string;
322
+ runtime: ConversationRuntimeMetadata;
323
+ last_event_seq: number;
324
+ }>;
325
+ setConversationProfile(conversationId: string, profileName: string): Promise<{
326
+ conversation_id: string;
327
+ profile: {
328
+ uid: string;
329
+ name: string;
330
+ display_name: string;
331
+ avatar_url: string | null;
332
+ };
333
+ runtime: ConversationRuntimeMetadata;
334
+ conversation: ConversationSummary;
335
+ last_event_seq: number;
336
+ }>;
337
+ listEvents(conversationId: string, after?: number): Promise<ConversationEvent[]>;
338
+ subscribe(conversationId: string, listener: ConversationEventListener): () => void;
339
+ subscribeAll(listener: ConversationEventListener): () => void;
340
+ sendMessage(input: SendMessageInput): Promise<SendMessageResult>;
341
+ cancelRun(conversationId: string, runId: string): Promise<CancelRunResult>;
342
+ cancelRunById(runId: string): Promise<CancelRunResult>;
343
+ deleteConversation(conversationId: string): Promise<DeleteConversationResult>;
344
+ deleteConversations(conversationIds: string[]): Promise<{
345
+ deleted_count: number;
346
+ failed_count: number;
347
+ conversations: BulkDeleteConversationResult[];
348
+ }>;
349
+ deleteLocalConversationsForProfile(input: {
350
+ profileName: string;
351
+ profileUid?: string | null;
352
+ }): Promise<{
353
+ deleted_count: number;
354
+ conversation_ids: string[];
355
+ }>;
356
+ writeBlob(conversationId: string, input: {
357
+ bytes: Uint8Array;
358
+ filename?: string;
359
+ mime?: string;
360
+ }): Promise<{
361
+ id: string;
362
+ size: number;
363
+ mime: string;
364
+ filename: string;
365
+ }>;
366
+ readBlob(conversationId: string, blobId: string): Promise<{
367
+ bytes: Buffer;
368
+ mime: string;
369
+ filename: string;
370
+ size: number;
371
+ }>;
372
+ deleteUnreferencedBlob(conversationId: string, blobId: string): Promise<{
373
+ deleted: boolean;
374
+ blob_id: string;
375
+ }>;
376
+ private refreshTitleFromHermesWithRetries;
377
+ private refreshTitleFromHermes;
378
+ private persistConversationStats;
379
+ private appendEvent;
380
+ private abortActiveRunsForConversation;
381
+ private hasActiveRunControllerForConversation;
382
+ private liveEventName;
383
+ }
384
+
44
385
  interface CreateAppOptions {
45
386
  paths?: RuntimePaths;
46
387
  logger?: FileLogger;
388
+ conversations?: ConversationService;
47
389
  onPairingClaimed?: () => void | Promise<void>;
48
390
  }
49
391
  declare function createApp(options?: CreateAppOptions): Promise<Koa>;
package/dist/http/app.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApp
3
- } from "../chunk-QAPDGN52.js";
3
+ } from "../chunk-YQX7OQFH.js";
4
4
  export {
5
5
  createApp
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hermespilot/link",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
4
4
  "private": false,
5
5
  "description": "Hermes Link companion service and CLI for connecting hermes-agent through HermesPilot",
6
6
  "license": "MIT",