@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.
- package/dist/browser-knowledge.d.ts +27 -0
- package/dist/browser-knowledge.d.ts.map +1 -1
- package/dist/browser-knowledge.js +12 -0
- package/dist/contracts/artifacts/operator-contract.json +441 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-manager.d.ts +38 -2
- package/dist/platform/companion/companion-chat-manager.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-manager.js +162 -10
- package/dist/platform/companion/companion-chat-routes.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-routes.js +66 -4
- package/dist/platform/companion/companion-chat-types.d.ts +25 -0
- package/dist/platform/companion/companion-chat-types.d.ts.map +1 -1
- package/dist/platform/companion/index.d.ts +2 -2
- package/dist/platform/companion/index.d.ts.map +1 -1
- package/dist/platform/control-plane/conversation-message.d.ts +6 -0
- package/dist/platform/control-plane/conversation-message.d.ts.map +1 -1
- package/dist/platform/control-plane/conversation-message.js +0 -8
- package/dist/platform/control-plane/method-catalog-control-core.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-control-core.js +22 -3
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts +1 -0
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-runtime.js +26 -1
- package/dist/platform/daemon/facade-composition.d.ts.map +1 -1
- package/dist/platform/daemon/facade-composition.js +1 -0
- package/dist/platform/providers/builtin-registry.d.ts.map +1 -1
- package/dist/platform/providers/builtin-registry.js +1 -0
- package/dist/platform/types/generated/foundation-client-types.d.ts +1 -1
- package/dist/platform/types/generated/foundation-client-types.d.ts.map +1 -1
- package/dist/platform/types/index.d.ts +1 -1
- package/dist/platform/types/index.d.ts.map +1 -1
- package/dist/platform/version.js +1 -1
- 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 {
|
|
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
|
|
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":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;
|
|
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
|
|
132
|
+
for (const msg of normalizedMessages) {
|
|
119
133
|
if (msg.role === 'user') {
|
|
120
|
-
conversation.addUserMessage(msg
|
|
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:
|
|
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, {
|
|
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,
|
|
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;
|
|
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
|
|
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":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,0CAA0C,CAAC;
|
|
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 {};
|