@pellux/goodvibes-sdk 0.33.8 → 0.33.10

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 (33) hide show
  1. package/dist/browser-knowledge.d.ts +27 -0
  2. package/dist/browser-knowledge.d.ts.map +1 -1
  3. package/dist/browser-knowledge.js +12 -0
  4. package/dist/contracts/artifacts/operator-contract.json +441 -6
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/platform/companion/companion-chat-manager.d.ts +38 -2
  8. package/dist/platform/companion/companion-chat-manager.d.ts.map +1 -1
  9. package/dist/platform/companion/companion-chat-manager.js +162 -10
  10. package/dist/platform/companion/companion-chat-routes.d.ts.map +1 -1
  11. package/dist/platform/companion/companion-chat-routes.js +66 -4
  12. package/dist/platform/companion/companion-chat-types.d.ts +25 -0
  13. package/dist/platform/companion/companion-chat-types.d.ts.map +1 -1
  14. package/dist/platform/companion/index.d.ts +2 -2
  15. package/dist/platform/companion/index.d.ts.map +1 -1
  16. package/dist/platform/control-plane/conversation-message.d.ts +6 -0
  17. package/dist/platform/control-plane/conversation-message.d.ts.map +1 -1
  18. package/dist/platform/control-plane/conversation-message.js +0 -8
  19. package/dist/platform/control-plane/method-catalog-control-core.d.ts.map +1 -1
  20. package/dist/platform/control-plane/method-catalog-control-core.js +22 -3
  21. package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts +1 -0
  22. package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts.map +1 -1
  23. package/dist/platform/control-plane/operator-contract-schemas-runtime.js +26 -1
  24. package/dist/platform/daemon/facade-composition.d.ts.map +1 -1
  25. package/dist/platform/daemon/facade-composition.js +1 -0
  26. package/dist/platform/providers/builtin-registry.d.ts.map +1 -1
  27. package/dist/platform/providers/builtin-registry.js +1 -0
  28. package/dist/platform/types/generated/foundation-client-types.d.ts +1 -1
  29. package/dist/platform/types/generated/foundation-client-types.d.ts.map +1 -1
  30. package/dist/platform/types/index.d.ts +1 -1
  31. package/dist/platform/types/index.d.ts.map +1 -1
  32. package/dist/platform/version.js +1 -1
  33. package/package.json +9 -9
@@ -19,8 +19,10 @@
19
19
  * for that specific session — never the global TUI event feed.
20
20
  * - A GC sweep closes sessions that have been idle beyond the TTL.
21
21
  */
22
+ import { Buffer } from 'node:buffer';
22
23
  import type { ProviderMessage } from '../providers/interface.js';
23
- import type { CompanionChatMessage, CompanionChatSession, CreateCompanionChatSessionInput, UpdateCompanionChatSessionInput } from './companion-chat-types.js';
24
+ import type { ArtifactDescriptor } from '../artifacts/index.js';
25
+ import type { CompanionChatMessageAttachmentInput, CompanionChatMessage, CompanionChatSession, CreateCompanionChatSessionInput, UpdateCompanionChatSessionInput } from './companion-chat-types.js';
24
26
  import type { CompanionChatRateLimiterOptions } from './companion-chat-rate-limiter.js';
25
27
  import type { ToolRegistry } from '../tools/registry.js';
26
28
  import type { ToolDefinition } from '../types/tools.js';
@@ -51,6 +53,16 @@ export interface CompanionLLMProvider {
51
53
  type HookDispatcherLike = {
52
54
  fire(event: HookEvent): Promise<HookResult>;
53
55
  };
56
+ export interface CompanionChatArtifactStore {
57
+ get(artifactId: string): ArtifactDescriptor | null;
58
+ readContent(artifactId: string): Promise<{
59
+ readonly record: {
60
+ readonly mimeType: string;
61
+ readonly filename?: string | undefined;
62
+ };
63
+ readonly buffer: ArrayBuffer | Uint8Array | Buffer;
64
+ }>;
65
+ }
54
66
  export interface CompanionChatEventPublisher {
55
67
  publishEvent(event: string, payload: unknown, filter?: {
56
68
  clientId?: string;
@@ -80,6 +92,8 @@ export interface CompanionChatManagerConfig {
80
92
  readonly hookDispatcher?: HookDispatcherLike | null | undefined;
81
93
  /** Optional runtime event bus for typed tool telemetry. */
82
94
  readonly runtimeBus?: RuntimeEventBus | null | undefined;
95
+ /** Optional artifact store used to resolve and inline chat attachments. */
96
+ readonly artifactStore?: CompanionChatArtifactStore | null | undefined;
83
97
  /**
84
98
  * Directory under which session JSON files are persisted.
85
99
  * Default: ~/.goodvibes/companion-chat/sessions/
@@ -107,6 +121,7 @@ export declare class CompanionChatManager {
107
121
  private readonly permissionManager;
108
122
  private readonly hookDispatcher;
109
123
  private readonly runtimeBus;
124
+ private readonly artifactStore;
110
125
  private readonly persistence;
111
126
  private readonly rateLimiter;
112
127
  private readonly idleActiveMs;
@@ -130,7 +145,19 @@ export declare class CompanionChatManager {
130
145
  init(): Promise<void>;
131
146
  createSession(input?: CreateCompanionChatSessionInput): CompanionChatSession;
132
147
  getSession(sessionId: string): CompanionChatSession | null;
148
+ listSessions(input?: {
149
+ readonly includeClosed?: boolean | undefined;
150
+ readonly limit?: number | undefined;
151
+ }): {
152
+ readonly sessions: readonly CompanionChatSession[];
153
+ readonly totals: {
154
+ readonly sessions: number;
155
+ readonly active: number;
156
+ readonly closed: number;
157
+ };
158
+ };
133
159
  getMessages(sessionId: string): CompanionChatMessage[];
160
+ private normalizeMessage;
134
161
  updateSession(sessionId: string, input: UpdateCompanionChatSessionInput): CompanionChatSession;
135
162
  /**
136
163
  * Register the SSE clientId for this session so events are routed only to
@@ -156,11 +183,20 @@ export declare class CompanionChatManager {
156
183
  * @param clientId - The SSE/HTTP client identity for per-client rate limiting.
157
184
  * Pass '' to skip client-level rate limiting.
158
185
  */
159
- postMessage(sessionId: string, content: string, clientId?: string): Promise<string>;
186
+ postMessage(sessionId: string, content: string, clientId?: string, options?: {
187
+ readonly attachments?: readonly CompanionChatMessageAttachmentInput[] | undefined;
188
+ }): Promise<string>;
160
189
  postMessageAndWaitForReply(sessionId: string, content: string, clientId?: string, options?: {
161
190
  readonly timeoutMs?: number | undefined;
191
+ readonly attachments?: readonly CompanionChatMessageAttachmentInput[] | undefined;
162
192
  }): Promise<CompanionChatReplyResult>;
163
193
  private _postMessageInternal;
194
+ private resolveAttachments;
195
+ private formatAttachmentSummary;
196
+ private buildReplayUserContent;
197
+ private isInlineTextAttachment;
198
+ private isInlineImageAttachment;
199
+ private buildProviderUserContent;
164
200
  dispose(): void;
165
201
  private _runTurn;
166
202
  private _executeToolCalls;
@@ -1 +1 @@
1
- {"version":3,"file":"companion-chat-manager.d.ts","sourceRoot":"","sources":["../../../src/platform/companion/companion-chat-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"companion-chat-manager.d.ts","sourceRoot":"","sources":["../../../src/platform/companion/companion-chat-manager.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,7 @@
19
19
  * for that specific session — never the global TUI event feed.
20
20
  * - A GC sweep closes sessions that have been idle beyond the TTL.
21
21
  */
22
+ import { Buffer } from 'node:buffer';
22
23
  import { randomUUID } from 'node:crypto';
23
24
  import { ConversationManager } from '../core/conversation.js';
24
25
  import { CompanionChatPersistence, defaultSessionsDir, } from './companion-chat-persistence.js';
@@ -34,6 +35,16 @@ const DEFAULT_IDLE_ACTIVE_MS = 30 * 60 * 1_000; // 30 minutes with messages
34
35
  const DEFAULT_IDLE_EMPTY_MS = 5 * 60 * 1_000; // 5 minutes empty session
35
36
  const GC_INTERVAL_MS = 60 * 1_000; // sweep every minute
36
37
  const MAX_TOOL_ROUNDS_PER_TURN = 8;
38
+ const MAX_ATTACHMENTS_PER_MESSAGE = 8;
39
+ const MAX_INLINE_IMAGE_ATTACHMENT_BYTES = 20 * 1024 * 1024;
40
+ const MAX_INLINE_TEXT_ATTACHMENT_BYTES = 200 * 1024;
41
+ function toNodeBuffer(buffer) {
42
+ if (Buffer.isBuffer(buffer))
43
+ return buffer;
44
+ if (buffer instanceof ArrayBuffer)
45
+ return Buffer.from(new Uint8Array(buffer));
46
+ return Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength);
47
+ }
37
48
  function assertCompleteProviderModelRoute(input) {
38
49
  if ((input.model !== undefined) === (input.provider !== undefined))
39
50
  return;
@@ -50,6 +61,7 @@ export class CompanionChatManager {
50
61
  permissionManager;
51
62
  hookDispatcher;
52
63
  runtimeBus;
64
+ artifactStore;
53
65
  persistence;
54
66
  rateLimiter;
55
67
  idleActiveMs;
@@ -71,6 +83,7 @@ export class CompanionChatManager {
71
83
  this.permissionManager = config.permissionManager ?? null;
72
84
  this.hookDispatcher = config.hookDispatcher ?? null;
73
85
  this.runtimeBus = config.runtimeBus ?? null;
86
+ this.artifactStore = config.artifactStore ?? null;
74
87
  this.idleActiveMs = config.idleActiveMs ?? DEFAULT_IDLE_ACTIVE_MS;
75
88
  this.idleEmptyMs = config.idleEmptyMs ?? DEFAULT_IDLE_EMPTY_MS;
76
89
  // Persistence
@@ -109,15 +122,16 @@ export class CompanionChatManager {
109
122
  }
110
123
  const stored = await this.persistence.loadAll();
111
124
  for (const { meta, messages } of stored) {
125
+ const normalizedMessages = messages.map((message) => this.normalizeMessage(message));
112
126
  // Skip sessions that were already closed before the restart — they are
113
127
  // in a terminal state and don't need to be in memory.
114
128
  if (meta.status === 'closed')
115
129
  continue;
116
130
  const conversation = new ConversationManager();
117
131
  // Replay messages into the conversation to restore LLM context
118
- for (const msg of messages) {
132
+ for (const msg of normalizedMessages) {
119
133
  if (msg.role === 'user') {
120
- conversation.addUserMessage(msg.content);
134
+ conversation.addUserMessage(this.buildReplayUserContent(msg));
121
135
  }
122
136
  else {
123
137
  conversation.addAssistantMessage(msg.content);
@@ -126,7 +140,7 @@ export class CompanionChatManager {
126
140
  this.sessions.set(meta.id, {
127
141
  meta,
128
142
  conversation,
129
- messages: [...messages],
143
+ messages: normalizedMessages,
130
144
  abortController: new AbortController(),
131
145
  lastActivityAt: meta.updatedAt,
132
146
  subscriberClientId: null,
@@ -169,9 +183,35 @@ export class CompanionChatManager {
169
183
  getSession(sessionId) {
170
184
  return this.sessions.get(sessionId)?.meta ?? null;
171
185
  }
186
+ listSessions(input = {}) {
187
+ const all = [...this.sessions.values()].map((session) => session.meta);
188
+ const active = all.filter((session) => session.status === 'active').length;
189
+ const closed = all.length - active;
190
+ const limit = typeof input.limit === 'number' && Number.isFinite(input.limit)
191
+ ? Math.max(0, Math.floor(input.limit))
192
+ : 100;
193
+ const sessions = all
194
+ .filter((session) => input.includeClosed || session.status !== 'closed')
195
+ .sort((left, right) => right.updatedAt - left.updatedAt)
196
+ .slice(0, limit);
197
+ return {
198
+ sessions,
199
+ totals: {
200
+ sessions: all.length,
201
+ active,
202
+ closed,
203
+ },
204
+ };
205
+ }
172
206
  getMessages(sessionId) {
173
207
  return this.sessions.get(sessionId)?.messages ?? [];
174
208
  }
209
+ normalizeMessage(message) {
210
+ return {
211
+ ...message,
212
+ attachments: message.attachments ?? [],
213
+ };
214
+ }
175
215
  updateSession(sessionId, input) {
176
216
  assertCompleteProviderModelRoute(input);
177
217
  const session = this.sessions.get(sessionId);
@@ -235,8 +275,10 @@ export class CompanionChatManager {
235
275
  * @param clientId - The SSE/HTTP client identity for per-client rate limiting.
236
276
  * Pass '' to skip client-level rate limiting.
237
277
  */
238
- async postMessage(sessionId, content, clientId = '') {
239
- return await this._postMessageInternal(sessionId, content, clientId);
278
+ async postMessage(sessionId, content, clientId = '', options = {}) {
279
+ return await this._postMessageInternal(sessionId, content, clientId, {
280
+ attachments: options.attachments,
281
+ });
240
282
  }
241
283
  async postMessageAndWaitForReply(sessionId, content, clientId = '', options = {}) {
242
284
  let messageId = '';
@@ -247,7 +289,10 @@ export class CompanionChatManager {
247
289
  resolve({ messageId, error: 'Timed out waiting for companion chat reply' });
248
290
  }, options.timeoutMs ?? 120_000);
249
291
  timeout.unref?.();
250
- void this._postMessageInternal(sessionId, content, clientId, { resolve, timeout })
292
+ void this._postMessageInternal(sessionId, content, clientId, {
293
+ pendingReply: { resolve, timeout },
294
+ attachments: options.attachments,
295
+ })
251
296
  .then((id) => { messageId = id; })
252
297
  .catch((error) => {
253
298
  clearTimeout(timeout);
@@ -259,7 +304,7 @@ export class CompanionChatManager {
259
304
  });
260
305
  return result;
261
306
  }
262
- async _postMessageInternal(sessionId, content, clientId, pendingReply) {
307
+ async _postMessageInternal(sessionId, content, clientId, options = {}) {
263
308
  const session = this.sessions.get(sessionId);
264
309
  if (!session) {
265
310
  throw Object.assign(new Error(`Session not found: ${sessionId}`), { code: 'SESSION_NOT_FOUND', status: 404 });
@@ -269,6 +314,10 @@ export class CompanionChatManager {
269
314
  }
270
315
  // Rate-limit check (throws GoodVibesSdkError on violation)
271
316
  this.rateLimiter?.check(sessionId, clientId);
317
+ const attachments = this.resolveAttachments(options.attachments ?? []);
318
+ if (!content.trim() && attachments.length === 0) {
319
+ throw Object.assign(new Error('content or attachments are required'), { code: 'INVALID_INPUT', status: 400 });
320
+ }
272
321
  const messageId = randomUUID();
273
322
  const now = Date.now();
274
323
  const userMsg = {
@@ -276,18 +325,19 @@ export class CompanionChatManager {
276
325
  sessionId,
277
326
  role: 'user',
278
327
  content,
328
+ attachments,
279
329
  createdAt: now,
280
330
  };
281
331
  session.messages.push(userMsg);
282
- session.conversation.addUserMessage(content);
332
+ session.conversation.addUserMessage(await this.buildProviderUserContent(content, attachments));
283
333
  session.lastActivityAt = now;
284
334
  this._updateMeta(session, {
285
335
  messageCount: session.messages.length,
286
336
  updatedAt: now,
287
337
  });
288
338
  this._persist(sessionId);
289
- if (pendingReply) {
290
- this.pendingReplies.set(messageId, pendingReply);
339
+ if (options.pendingReply) {
340
+ this.pendingReplies.set(messageId, options.pendingReply);
291
341
  }
292
342
  void this._runTurn(session, messageId).catch((error) => {
293
343
  logger.warn('[companion-chat] turn execution failed', {
@@ -298,6 +348,106 @@ export class CompanionChatManager {
298
348
  });
299
349
  return messageId;
300
350
  }
351
+ resolveAttachments(inputs) {
352
+ if (inputs.length === 0)
353
+ return [];
354
+ if (inputs.length > MAX_ATTACHMENTS_PER_MESSAGE) {
355
+ throw Object.assign(new Error(`A companion chat message can include at most ${MAX_ATTACHMENTS_PER_MESSAGE} attachments.`), { code: 'TOO_MANY_ATTACHMENTS', status: 400 });
356
+ }
357
+ if (!this.artifactStore) {
358
+ throw Object.assign(new Error('Companion chat attachments require an artifact store.'), { code: 'ATTACHMENTS_UNAVAILABLE', status: 501 });
359
+ }
360
+ return inputs.map((input) => {
361
+ const artifactId = input.artifactId.trim();
362
+ if (!artifactId) {
363
+ throw Object.assign(new Error('Attachment artifactId is required.'), {
364
+ code: 'INVALID_ATTACHMENT',
365
+ status: 400,
366
+ });
367
+ }
368
+ const artifact = this.artifactStore.get(artifactId);
369
+ if (!artifact) {
370
+ throw Object.assign(new Error(`Unknown attachment artifact: ${artifactId}`), {
371
+ code: 'UNKNOWN_ARTIFACT',
372
+ status: 404,
373
+ });
374
+ }
375
+ return {
376
+ ...artifact,
377
+ artifactId: artifact.id,
378
+ ...(input.label?.trim() ? { label: input.label.trim() } : {}),
379
+ metadata: {
380
+ ...artifact.metadata,
381
+ ...(input.metadata ?? {}),
382
+ },
383
+ };
384
+ });
385
+ }
386
+ formatAttachmentSummary(attachments) {
387
+ if (attachments.length === 0)
388
+ return '';
389
+ const lines = attachments.map((attachment, index) => {
390
+ const name = attachment.label ?? attachment.filename ?? attachment.artifactId;
391
+ return `${index + 1}. ${name} (${attachment.mimeType}, ${attachment.sizeBytes} bytes, artifact ${attachment.artifactId})`;
392
+ });
393
+ return `\n\nAttached file${attachments.length === 1 ? '' : 's'}:\n${lines.join('\n')}`;
394
+ }
395
+ buildReplayUserContent(message) {
396
+ return `${message.content}${this.formatAttachmentSummary(message.attachments ?? [])}`;
397
+ }
398
+ isInlineTextAttachment(attachment) {
399
+ const lower = attachment.mimeType.toLowerCase();
400
+ return attachment.sizeBytes <= MAX_INLINE_TEXT_ATTACHMENT_BYTES
401
+ && (lower.startsWith('text/')
402
+ || lower === 'application/json'
403
+ || lower === 'application/xml'
404
+ || lower === 'application/yaml'
405
+ || lower === 'text/csv');
406
+ }
407
+ isInlineImageAttachment(attachment) {
408
+ const lower = attachment.mimeType.toLowerCase();
409
+ return attachment.sizeBytes <= MAX_INLINE_IMAGE_ATTACHMENT_BYTES
410
+ && (lower === 'image/png'
411
+ || lower === 'image/jpeg'
412
+ || lower === 'image/gif'
413
+ || lower === 'image/webp');
414
+ }
415
+ async buildProviderUserContent(content, attachments) {
416
+ if (attachments.length === 0)
417
+ return content;
418
+ const textSections = [content.trim() ? content : 'Please review the attached file(s).'];
419
+ const imageParts = [];
420
+ for (const attachment of attachments) {
421
+ if (!this.artifactStore)
422
+ continue;
423
+ try {
424
+ if (this.isInlineTextAttachment(attachment)) {
425
+ const { buffer } = await this.artifactStore.readContent(attachment.artifactId);
426
+ const text = toNodeBuffer(buffer).toString('utf-8');
427
+ textSections.push(`\n\n--- Attachment: ${attachment.label ?? attachment.filename ?? attachment.artifactId} ---\n${text}`);
428
+ continue;
429
+ }
430
+ if (this.isInlineImageAttachment(attachment)) {
431
+ const { buffer } = await this.artifactStore.readContent(attachment.artifactId);
432
+ imageParts.push({
433
+ type: 'image',
434
+ mediaType: attachment.mimeType,
435
+ data: toNodeBuffer(buffer).toString('base64'),
436
+ });
437
+ }
438
+ }
439
+ catch (error) {
440
+ logger.warn('[companion-chat] failed to inline attachment for provider prompt', {
441
+ artifactId: attachment.artifactId,
442
+ error: summarizeError(error),
443
+ });
444
+ }
445
+ }
446
+ textSections.push(this.formatAttachmentSummary(attachments));
447
+ if (imageParts.length === 0)
448
+ return textSections.join('');
449
+ return [{ type: 'text', text: textSections.join('') }, ...imageParts];
450
+ }
301
451
  dispose() {
302
452
  if (this.gcTimer) {
303
453
  clearInterval(this.gcTimer);
@@ -327,6 +477,7 @@ export class CompanionChatManager {
327
477
  body: userMsg?.content ?? '',
328
478
  source: 'companion-chat-user',
329
479
  timestamp: userMsg?.createdAt ?? Date.now(),
480
+ ...(userMsg?.attachments?.length ? { attachments: userMsg.attachments } : {}),
330
481
  };
331
482
  publish({ type: 'turn.started', sessionId, messageId: userMessageId, turnId, envelope: startEnvelope });
332
483
  let assistantContent = '';
@@ -415,6 +566,7 @@ export class CompanionChatManager {
415
566
  sessionId,
416
567
  role: 'assistant',
417
568
  content: assistantContent,
569
+ attachments: [],
418
570
  createdAt: now,
419
571
  };
420
572
  session.messages.push(assistantMsg);
@@ -1 +1 @@
1
- {"version":3,"file":"companion-chat-routes.d.ts","sourceRoot":"","sources":["../../../src/platform/companion/companion-chat-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAMjF;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CA+C1B;AAkLD;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAMlF"}
1
+ {"version":3,"file":"companion-chat-routes.d.ts","sourceRoot":"","sources":["../../../src/platform/companion/companion-chat-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAMjF;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAoD1B;AA8MD;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAMlF"}
@@ -30,6 +30,10 @@ export async function dispatchCompanionChatRoutes(req, context) {
30
30
  if (pathname === '/api/companion/chat/sessions' && req.method === 'POST') {
31
31
  return handleCreateSession(req, context);
32
32
  }
33
+ // GET /api/companion/chat/sessions
34
+ if (pathname === '/api/companion/chat/sessions' && req.method === 'GET') {
35
+ return handleListSessions(url, context);
36
+ }
33
37
  const sessionMatch = pathname.match(/^\/api\/companion\/chat\/sessions\/([^/]+)(\/(.+))?$/);
34
38
  if (!sessionMatch)
35
39
  return null;
@@ -91,7 +95,30 @@ async function handleCreateSession(req, context) {
91
95
  return Response.json({ error: 'No provider or model configured. Set a current model before creating a companion chat session.', code: 'NO_MODEL_CONFIGURED' }, { status: 400 });
92
96
  }
93
97
  const session = context.chatManager.createSession(input);
94
- return Response.json({ sessionId: session.id, createdAt: session.createdAt }, { status: 201 });
98
+ return Response.json({ sessionId: session.id, createdAt: session.createdAt, session }, { status: 201 });
99
+ }
100
+ // ---------------------------------------------------------------------------
101
+ // GET /api/companion/chat/sessions
102
+ // ---------------------------------------------------------------------------
103
+ function readBooleanQuery(url, key) {
104
+ const value = url.searchParams.get(key);
105
+ if (value === null)
106
+ return undefined;
107
+ return value === '1' || value.toLowerCase() === 'true';
108
+ }
109
+ function readLimitQuery(url) {
110
+ const value = url.searchParams.get('limit');
111
+ if (value === null || value.trim() === '')
112
+ return undefined;
113
+ const parsed = Number(value);
114
+ return Number.isFinite(parsed) ? parsed : undefined;
115
+ }
116
+ function handleListSessions(url, context) {
117
+ const input = {
118
+ includeClosed: readBooleanQuery(url, 'includeClosed'),
119
+ limit: readLimitQuery(url),
120
+ };
121
+ return Response.json(context.chatManager.listSessions(input));
95
122
  }
96
123
  // ---------------------------------------------------------------------------
97
124
  // GET /api/companion/chat/sessions/:sessionId
@@ -198,6 +225,35 @@ export function readCompanionChatMessageBody(body) {
198
225
  ? body['content']
199
226
  : '';
200
227
  }
228
+ function readCompanionChatAttachments(body) {
229
+ const raw = body['attachments'];
230
+ if (raw === undefined)
231
+ return [];
232
+ if (!Array.isArray(raw)) {
233
+ return Response.json({ error: 'attachments must be an array', code: 'INVALID_INPUT' }, { status: 400 });
234
+ }
235
+ const attachments = [];
236
+ for (const [index, item] of raw.entries()) {
237
+ if (typeof item !== 'object' || item === null || Array.isArray(item)) {
238
+ return Response.json({ error: `attachments[${index}] must be an object`, code: 'INVALID_INPUT' }, { status: 400 });
239
+ }
240
+ const record = item;
241
+ if (typeof record['artifactId'] !== 'string' || record['artifactId'].trim().length === 0) {
242
+ return Response.json({ error: `attachments[${index}].artifactId is required`, code: 'INVALID_INPUT' }, { status: 400 });
243
+ }
244
+ const attachment = {
245
+ artifactId: record['artifactId'].trim(),
246
+ };
247
+ if (typeof record['label'] === 'string' && record['label'].trim()) {
248
+ attachment.label = record['label'].trim();
249
+ }
250
+ if (typeof record['metadata'] === 'object' && record['metadata'] !== null && !Array.isArray(record['metadata'])) {
251
+ attachment.metadata = record['metadata'];
252
+ }
253
+ attachments.push(attachment);
254
+ }
255
+ return attachments;
256
+ }
201
257
  // ---------------------------------------------------------------------------
202
258
  // POST /api/companion/chat/sessions/:sessionId/messages
203
259
  // ---------------------------------------------------------------------------
@@ -218,17 +274,23 @@ async function handlePostMessage(req, sessionId, context) {
218
274
  : typeof body['content'] === 'string'
219
275
  ? body['content']
220
276
  : '';
277
+ const attachments = readCompanionChatAttachments(body);
278
+ if (attachments instanceof Response)
279
+ return attachments;
221
280
  const input = {
222
281
  content: rawContent,
282
+ attachments,
223
283
  metadata: typeof body['metadata'] === 'object' && body['metadata'] !== null
224
284
  ? body['metadata']
225
285
  : undefined,
226
286
  };
227
- if (!input.content.trim()) {
228
- return Response.json({ error: 'content or body is required and must be a non-empty string', code: 'INVALID_INPUT' }, { status: 400 });
287
+ if (!input.content.trim() && attachments.length === 0) {
288
+ return Response.json({ error: 'content, body, or attachments are required', code: 'INVALID_INPUT' }, { status: 400 });
229
289
  }
230
290
  try {
231
- const messageId = await context.chatManager.postMessage(sessionId, input.content);
291
+ const messageId = await context.chatManager.postMessage(sessionId, input.content, '', {
292
+ attachments: input.attachments,
293
+ });
232
294
  return Response.json({ messageId }, { status: 202 });
233
295
  }
234
296
  catch (err) {
@@ -7,6 +7,7 @@
7
7
  * via CompanionChatPersistence so they survive daemon restarts.
8
8
  */
9
9
  import type { ConversationMessageEnvelope } from '../control-plane/conversation-message.js';
10
+ import type { ArtifactDescriptor } from '../artifacts/index.js';
10
11
  /**
11
12
  * Re-export the shared envelope so chat-mode code can import from one place.
12
13
  * The envelope shape is the canonical message unit flowing through
@@ -16,11 +17,21 @@ export type { ConversationMessageEnvelope } from '../control-plane/conversation-
16
17
  export type CompanionChatSessionKind = 'companion-chat';
17
18
  export type CompanionChatSessionStatus = 'active' | 'closed';
18
19
  export type CompanionChatMessageRole = 'user' | 'assistant';
20
+ export interface CompanionChatMessageAttachmentInput {
21
+ readonly artifactId: string;
22
+ readonly label?: string | undefined;
23
+ readonly metadata?: Record<string, unknown> | undefined;
24
+ }
25
+ export interface CompanionChatMessageAttachment extends ArtifactDescriptor {
26
+ readonly artifactId: string;
27
+ readonly label?: string | undefined;
28
+ }
19
29
  export interface CompanionChatMessage {
20
30
  readonly id: string;
21
31
  readonly sessionId: string;
22
32
  readonly role: CompanionChatMessageRole;
23
33
  readonly content: string;
34
+ readonly attachments: readonly CompanionChatMessageAttachment[];
24
35
  readonly createdAt: number;
25
36
  }
26
37
  export interface CompanionChatSession {
@@ -42,6 +53,10 @@ export interface CreateCompanionChatSessionInput {
42
53
  readonly provider?: string | undefined;
43
54
  readonly systemPrompt?: string | undefined;
44
55
  }
56
+ export interface ListCompanionChatSessionsInput {
57
+ readonly includeClosed?: boolean | undefined;
58
+ readonly limit?: number | undefined;
59
+ }
45
60
  export interface UpdateCompanionChatSessionInput {
46
61
  readonly title?: string | undefined;
47
62
  readonly model?: string | undefined;
@@ -51,12 +66,22 @@ export interface UpdateCompanionChatSessionInput {
51
66
  export interface CreateCompanionChatSessionOutput {
52
67
  readonly sessionId: string;
53
68
  readonly createdAt: number;
69
+ readonly session: CompanionChatSession;
70
+ }
71
+ export interface ListCompanionChatSessionsOutput {
72
+ readonly sessions: readonly CompanionChatSession[];
73
+ readonly totals: {
74
+ readonly sessions: number;
75
+ readonly active: number;
76
+ readonly closed: number;
77
+ };
54
78
  }
55
79
  export interface UpdateCompanionChatSessionOutput {
56
80
  readonly session: CompanionChatSession;
57
81
  }
58
82
  export interface PostCompanionChatMessageInput {
59
83
  readonly content: string;
84
+ readonly attachments?: readonly CompanionChatMessageAttachmentInput[] | undefined;
60
85
  readonly metadata?: Record<string, unknown> | undefined;
61
86
  }
62
87
  export interface PostCompanionChatMessageOutput {
@@ -1 +1 @@
1
- {"version":3,"file":"companion-chat-types.d.ts","sourceRoot":"","sources":["../../../src/platform/companion/companion-chat-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"companion-chat-types.d.ts","sourceRoot":"","sources":["../../../src/platform/companion/companion-chat-types.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- export type { CompanionChatMessage, CompanionChatSession, CompanionChatSessionKind, CompanionChatSessionStatus, CompanionChatMessageRole, CompanionChatTurnEvent, CompanionChatTurnStartedEvent, CompanionChatTurnDeltaEvent, CompanionChatTurnToolCallEvent, CompanionChatTurnToolResultEvent, CompanionChatTurnCompletedEvent, CompanionChatTurnErrorEvent, CreateCompanionChatSessionInput, CreateCompanionChatSessionOutput, UpdateCompanionChatSessionInput, UpdateCompanionChatSessionOutput, PostCompanionChatMessageInput, PostCompanionChatMessageOutput, GetCompanionChatSessionOutput, ConversationMessageEnvelope, } from './companion-chat-types.js';
2
- export type { CompanionLLMProvider, CompanionChatEventPublisher, CompanionChatManagerConfig, CompanionProviderMessage, CompanionProviderChunk, } from './companion-chat-manager.js';
1
+ export type { CompanionChatMessage, CompanionChatMessageAttachment, CompanionChatMessageAttachmentInput, CompanionChatSession, CompanionChatSessionKind, CompanionChatSessionStatus, CompanionChatMessageRole, CompanionChatTurnEvent, CompanionChatTurnStartedEvent, CompanionChatTurnDeltaEvent, CompanionChatTurnToolCallEvent, CompanionChatTurnToolResultEvent, CompanionChatTurnCompletedEvent, CompanionChatTurnErrorEvent, CreateCompanionChatSessionInput, CreateCompanionChatSessionOutput, ListCompanionChatSessionsInput, ListCompanionChatSessionsOutput, UpdateCompanionChatSessionInput, UpdateCompanionChatSessionOutput, PostCompanionChatMessageInput, PostCompanionChatMessageOutput, GetCompanionChatSessionOutput, ConversationMessageEnvelope, } from './companion-chat-types.js';
2
+ export type { CompanionLLMProvider, CompanionChatEventPublisher, CompanionChatManagerConfig, CompanionChatArtifactStore, CompanionProviderMessage, CompanionProviderChunk, } from './companion-chat-manager.js';
3
3
  export { CompanionChatManager } from './companion-chat-manager.js';
4
4
  export { dispatchCompanionChatRoutes } from './companion-chat-routes.js';
5
5
  export type { CompanionChatRouteContext } from './companion-chat-route-types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/platform/companion/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAC7B,2BAA2B,EAC3B,8BAA8B,EAC9B,gCAAgC,EAChC,+BAA+B,EAC/B,2BAA2B,EAC3B,+BAA+B,EAC/B,gCAAgC,EAChC,+BAA+B,EAC/B,gCAAgC,EAChC,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EACV,oBAAoB,EACpB,2BAA2B,EAC3B,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACzE,YAAY,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAEjF,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC/F,YAAY,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,YAAY,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/platform/companion/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,oBAAoB,EACpB,8BAA8B,EAC9B,mCAAmC,EACnC,oBAAoB,EACpB,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAC7B,2BAA2B,EAC3B,8BAA8B,EAC9B,gCAAgC,EAChC,+BAA+B,EAC/B,2BAA2B,EAC3B,+BAA+B,EAC/B,gCAAgC,EAChC,8BAA8B,EAC9B,+BAA+B,EAC/B,+BAA+B,EAC/B,gCAAgC,EAChC,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EACV,oBAAoB,EACpB,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACzE,YAAY,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAEjF,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC/F,YAAY,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,YAAY,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { ArtifactDescriptor } from '../artifacts/index.js';
1
2
  /**
2
3
  * conversation-message.ts
3
4
  *
@@ -23,6 +24,11 @@ export interface ConversationMessageEnvelope {
23
24
  readonly body: string;
24
25
  readonly source: MessageSource;
25
26
  readonly timestamp: number;
27
+ /** Artifacts attached to this conversation message. */
28
+ readonly attachments?: readonly (ArtifactDescriptor & {
29
+ readonly artifactId: string;
30
+ readonly label?: string | undefined;
31
+ })[] | undefined;
26
32
  /** Optional metadata for tool info, model id, etc. */
27
33
  readonly metadata?: Readonly<Record<string, unknown>> | undefined;
28
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-message.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/conversation-message.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,qBAAqB,GACrB,0BAA0B,GAC1B,oBAAoB,GACpB,WAAW,GACX,QAAQ,GACR,MAAM,CAAC;AAEX;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CACnE"}
1
+ {"version":3,"file":"conversation-message.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/conversation-message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,qBAAqB,GACrB,0BAA0B,GAC1B,oBAAoB,GACpB,WAAW,GACX,QAAQ,GACR,MAAM,CAAC;AAEX;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uDAAuD;IACvD,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC,kBAAkB,GAAG;QACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACrC,CAAC,EAAE,GAAG,SAAS,CAAC;IACjB,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CACnE"}
@@ -1,9 +1 @@
1
- /**
2
- * conversation-message.ts
3
- *
4
- * Shared envelope types for conversation messages flowing through the
5
- * control-plane gateway. All consumers — SSE companion-chat streams,
6
- * TUI-surface follow-up listeners, and web-UI clients — depend on this
7
- * stable shape.
8
- */
9
1
  export {};