reflectt-node 0.1.17 → 0.1.19
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/activationEvents.d.ts +3 -1
- package/dist/activationEvents.d.ts.map +1 -1
- package/dist/activationEvents.js +5 -0
- package/dist/activationEvents.js.map +1 -1
- package/dist/canvas-auto-state.d.ts +9 -3
- package/dist/canvas-auto-state.d.ts.map +1 -1
- package/dist/canvas-auto-state.js +43 -8
- package/dist/canvas-auto-state.js.map +1 -1
- package/dist/canvas-interactive.d.ts +52 -0
- package/dist/canvas-interactive.d.ts.map +1 -0
- package/dist/canvas-interactive.js +401 -0
- package/dist/canvas-interactive.js.map +1 -0
- package/dist/canvas-multiplexer.d.ts +3 -0
- package/dist/canvas-multiplexer.d.ts.map +1 -1
- package/dist/canvas-multiplexer.js +28 -0
- package/dist/canvas-multiplexer.js.map +1 -1
- package/dist/canvas-push.d.ts +9 -0
- package/dist/canvas-push.d.ts.map +1 -0
- package/dist/canvas-push.js +169 -0
- package/dist/canvas-push.js.map +1 -0
- package/dist/canvas-query.d.ts +26 -0
- package/dist/canvas-query.d.ts.map +1 -0
- package/dist/canvas-query.js +369 -0
- package/dist/canvas-query.js.map +1 -0
- package/dist/canvas-routes.d.ts +59 -8
- package/dist/canvas-routes.d.ts.map +1 -1
- package/dist/canvas-routes.js +422 -7
- package/dist/canvas-routes.js.map +1 -1
- package/dist/canvas-slots.d.ts +1 -1
- package/dist/canvas-takeover.d.ts +19 -0
- package/dist/canvas-takeover.d.ts.map +1 -0
- package/dist/canvas-takeover.js +121 -0
- package/dist/canvas-takeover.js.map +1 -0
- package/dist/canvas-types.d.ts +1 -1
- package/dist/canvas-types.d.ts.map +1 -1
- package/dist/canvas-types.js +1 -0
- package/dist/canvas-types.js.map +1 -1
- package/dist/cloud.d.ts.map +1 -1
- package/dist/cloud.js +19 -0
- package/dist/cloud.js.map +1 -1
- package/dist/ghost-signup-nudge.d.ts +43 -0
- package/dist/ghost-signup-nudge.d.ts.map +1 -0
- package/dist/ghost-signup-nudge.js +175 -0
- package/dist/ghost-signup-nudge.js.map +1 -0
- package/dist/presence.d.ts +1 -0
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js.map +1 -1
- package/dist/restart-drift-guard.d.ts +9 -0
- package/dist/restart-drift-guard.d.ts.map +1 -0
- package/dist/restart-drift-guard.js +80 -0
- package/dist/restart-drift-guard.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +251 -1309
- package/dist/server.js.map +1 -1
- package/dist/tasks.d.ts +1 -0
- package/dist/tasks.d.ts.map +1 -1
- package/dist/tasks.js +95 -18
- package/dist/tasks.js.map +1 -1
- package/dist/workflow-templates.d.ts.map +1 -1
- package/dist/workflow-templates.js +41 -1
- package/dist/workflow-templates.js.map +1 -1
- package/package.json +2 -2
- package/public/docs.md +5 -1
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Canvas push + artifact routes — extracted from server.ts
|
|
3
|
+
// Phase 2 canvas route extraction (task-1773689755389)
|
|
4
|
+
export async function canvasPushRoutes(app, deps) {
|
|
5
|
+
const { eventBus, queueCanvasPushEvent } = deps;
|
|
6
|
+
// POST /canvas/push — agent pushes a visual event to the canvas.
|
|
7
|
+
// Types: utterance, work_released, handoff, canvas_response, rich
|
|
8
|
+
app.post('/canvas/push', async (request, reply) => {
|
|
9
|
+
const body = request.body;
|
|
10
|
+
const type = typeof body.type === 'string' ? body.type : 'utterance';
|
|
11
|
+
const agentId = typeof body.agentId === 'string' ? body.agentId.toLowerCase() : 'agent';
|
|
12
|
+
const VALID_PUSH_TYPES = new Set(['utterance', 'thought', 'work_released', 'handoff', 'canvas_response', 'rich']);
|
|
13
|
+
if (!VALID_PUSH_TYPES.has(type)) {
|
|
14
|
+
reply.status(400);
|
|
15
|
+
return { success: false, message: `type must be one of: ${[...VALID_PUSH_TYPES].join(', ')}` };
|
|
16
|
+
}
|
|
17
|
+
const now = Date.now();
|
|
18
|
+
let payload = { type, agentId, t: now };
|
|
19
|
+
if (type === 'utterance') {
|
|
20
|
+
const raw = typeof body.text === 'string' ? body.text.trim() : '';
|
|
21
|
+
const text = raw.slice(0, 60);
|
|
22
|
+
const ttl = typeof body.ttl === 'number' && body.ttl > 0 ? Math.min(body.ttl, 15_000) : 4_000;
|
|
23
|
+
payload = { ...payload, text, ttl };
|
|
24
|
+
}
|
|
25
|
+
else if (type === 'thought') {
|
|
26
|
+
// Agent thought bubble - shows what agent is thinking in real-time
|
|
27
|
+
// Emit as expression type for frontend compatibility
|
|
28
|
+
const raw = typeof body.text === 'string' ? body.text.trim() : '';
|
|
29
|
+
const text = raw.slice(0, 200);
|
|
30
|
+
const ttl = typeof body.ttl === 'number' && body.ttl > 0 ? Math.min(body.ttl, 30_000) : 8_000;
|
|
31
|
+
const THOUGHT_COLORS = {
|
|
32
|
+
link: '#60a5fa', kai: '#fb923c', pixel: '#a78bfa', sage: '#34d399',
|
|
33
|
+
scout: '#fbbf24', echo: '#f472b6', rhythm: '#6ee7b7', spark: '#f97316',
|
|
34
|
+
};
|
|
35
|
+
eventBus.emit({
|
|
36
|
+
id: `cmsg-thought-${now}-${Math.random().toString(36).slice(2, 8)}`,
|
|
37
|
+
type: 'canvas_message',
|
|
38
|
+
timestamp: now,
|
|
39
|
+
data: {
|
|
40
|
+
type: 'expression',
|
|
41
|
+
expression: 'thought',
|
|
42
|
+
agentId,
|
|
43
|
+
agentColor: THOUGHT_COLORS[agentId] ?? '#60a5fa',
|
|
44
|
+
text,
|
|
45
|
+
ttl,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
// Also emit legacy canvas_push for backwards compatibility
|
|
49
|
+
payload = { ...payload, type: 'expression', expression: 'thought', text, ttl };
|
|
50
|
+
}
|
|
51
|
+
else if (type === 'work_released') {
|
|
52
|
+
const text = typeof body.text === 'string' ? body.text.slice(0, 80) : 'work shipped';
|
|
53
|
+
const intensity = typeof body.intensity === 'number'
|
|
54
|
+
? Math.min(1, Math.max(0.1, body.intensity)) : 0.6;
|
|
55
|
+
const taskTitle = typeof body.taskTitle === 'string' ? body.taskTitle : undefined;
|
|
56
|
+
payload = { ...payload, text, intensity, taskTitle };
|
|
57
|
+
}
|
|
58
|
+
else if (type === 'handoff') {
|
|
59
|
+
const toAgentId = typeof body.toAgentId === 'string' ? body.toAgentId.toLowerCase() : '';
|
|
60
|
+
if (!toAgentId) {
|
|
61
|
+
reply.status(400);
|
|
62
|
+
return { success: false, message: 'handoff requires toAgentId' };
|
|
63
|
+
}
|
|
64
|
+
const taskTitle = typeof body.taskTitle === 'string' ? body.taskTitle : undefined;
|
|
65
|
+
const text = typeof body.text === 'string' ? body.text.slice(0, 80) : undefined;
|
|
66
|
+
payload = { ...payload, toAgentId, taskTitle, text };
|
|
67
|
+
}
|
|
68
|
+
else if (type === 'rich') {
|
|
69
|
+
const content = body.content;
|
|
70
|
+
if (!content || typeof content !== 'object') {
|
|
71
|
+
reply.status(400);
|
|
72
|
+
return { success: false, message: 'rich push requires content object' };
|
|
73
|
+
}
|
|
74
|
+
const richContent = {};
|
|
75
|
+
if (typeof content.markdown === 'string')
|
|
76
|
+
richContent.markdown = content.markdown.slice(0, 10_000);
|
|
77
|
+
if (typeof content.code === 'string')
|
|
78
|
+
richContent.code = content.code.slice(0, 10_000);
|
|
79
|
+
if (typeof content.language === 'string')
|
|
80
|
+
richContent.language = content.language.slice(0, 30);
|
|
81
|
+
if (typeof content.image === 'string')
|
|
82
|
+
richContent.image = content.image.slice(0, 2000);
|
|
83
|
+
if (typeof content.svg === 'string')
|
|
84
|
+
richContent.svg = content.svg.slice(0, 50_000);
|
|
85
|
+
if (typeof content.html === 'string')
|
|
86
|
+
richContent.html = content.html.slice(0, 20_000);
|
|
87
|
+
if (typeof content.title === 'string')
|
|
88
|
+
richContent.title = content.title.slice(0, 200);
|
|
89
|
+
const position = typeof body.position === 'object' && body.position
|
|
90
|
+
? { x: Number(body.position.x) || 0, y: Number(body.position.y) || 0 }
|
|
91
|
+
: undefined;
|
|
92
|
+
const layer = typeof body.layer === 'string' && ['background', 'stage', 'overlay'].includes(body.layer)
|
|
93
|
+
? body.layer : 'stage';
|
|
94
|
+
const ttl = typeof body.ttl === 'number' && body.ttl > 0 ? Math.min(body.ttl, 120_000) : 30_000;
|
|
95
|
+
const size = typeof body.size === 'object' && body.size
|
|
96
|
+
? { w: Number(body.size.w) || 400, h: Number(body.size.h) || 300 }
|
|
97
|
+
: undefined;
|
|
98
|
+
payload = { ...payload, content: richContent, position, layer, ttl, size };
|
|
99
|
+
const RICH_COLORS = {
|
|
100
|
+
link: '#60a5fa', kai: '#fb923c', pixel: '#a78bfa', sage: '#34d399',
|
|
101
|
+
scout: '#fbbf24', echo: '#f472b6', rhythm: '#6ee7b7', spark: '#f97316',
|
|
102
|
+
};
|
|
103
|
+
eventBus.emit({
|
|
104
|
+
id: `cmsg-rich-${now}-${Math.random().toString(36).slice(2, 8)}`,
|
|
105
|
+
type: 'canvas_message',
|
|
106
|
+
timestamp: now,
|
|
107
|
+
data: {
|
|
108
|
+
type: 'rich',
|
|
109
|
+
agentId,
|
|
110
|
+
agentColor: RICH_COLORS[agentId] ?? '#60a5fa',
|
|
111
|
+
content: richContent,
|
|
112
|
+
layer,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
else if (type === 'canvas_response') {
|
|
117
|
+
const card = body.card;
|
|
118
|
+
if (!card || typeof card.type !== 'string') {
|
|
119
|
+
reply.status(400);
|
|
120
|
+
return { success: false, message: 'canvas_response requires card with type field' };
|
|
121
|
+
}
|
|
122
|
+
const query = typeof body.query === 'string' ? body.query.slice(0, 200) : undefined;
|
|
123
|
+
payload = { ...payload, card, query };
|
|
124
|
+
const RESP_COLORS = {
|
|
125
|
+
link: '#60a5fa', kai: '#fb923c', pixel: '#a78bfa', sage: '#34d399',
|
|
126
|
+
scout: '#f472b6', echo: '#fbbf24', rhythm: '#6ee7b7', spark: '#f97316',
|
|
127
|
+
};
|
|
128
|
+
const agentColor = RESP_COLORS[agentId] ?? '#60a5fa';
|
|
129
|
+
eventBus.emit({
|
|
130
|
+
id: `cmsg-${now}-${Math.random().toString(36).slice(2, 8)}`,
|
|
131
|
+
type: 'canvas_message',
|
|
132
|
+
timestamp: now,
|
|
133
|
+
data: { ...card, agentId, agentColor, query },
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
eventBus.emit({ id: `push-${now}-${Math.random().toString(36).slice(2, 6)}`, type: 'canvas_push', timestamp: now, data: payload });
|
|
137
|
+
queueCanvasPushEvent({ ...payload, _event: 'canvas_push' });
|
|
138
|
+
// Track canvas_first_action activation event (idempotent)
|
|
139
|
+
const { emitActivationEvent: emitActPush } = await import('./activationEvents.js');
|
|
140
|
+
emitActPush('canvas_first_action', agentId, { action: 'canvas_push', pushType: type }).catch(() => { });
|
|
141
|
+
return { success: true, type, agentId };
|
|
142
|
+
});
|
|
143
|
+
// POST /canvas/artifact — emit a proof artifact that drifts through the canvas
|
|
144
|
+
app.post('/canvas/artifact', async (request, reply) => {
|
|
145
|
+
const body = request.body;
|
|
146
|
+
const VALID_TYPES = new Set(['commit', 'pr', 'test', 'run', 'approval']);
|
|
147
|
+
const type = typeof body.type === 'string' && VALID_TYPES.has(body.type) ? body.type : 'run';
|
|
148
|
+
const agentId = typeof body.agentId === 'string' ? body.agentId.toLowerCase() : 'agent';
|
|
149
|
+
const title = typeof body.title === 'string' ? body.title.slice(0, 80) : 'work shipped';
|
|
150
|
+
const url = typeof body.url === 'string' ? body.url : undefined;
|
|
151
|
+
const taskId = typeof body.taskId === 'string' ? body.taskId : undefined;
|
|
152
|
+
const now = Date.now();
|
|
153
|
+
const AGENT_COLORS = {
|
|
154
|
+
link: '#60a5fa', kai: '#fb923c', pixel: '#a78bfa',
|
|
155
|
+
sage: '#34d399', scout: '#fbbf24', echo: '#f472b6',
|
|
156
|
+
rhythm: '#a3e635', swift: '#38bdf8', kotlin: '#f97316',
|
|
157
|
+
};
|
|
158
|
+
const agentColor = AGENT_COLORS[agentId] ?? '#94a3b8';
|
|
159
|
+
const payload = { type, agentId, agentColor, title, url, taskId, timestamp: now };
|
|
160
|
+
eventBus.emit({
|
|
161
|
+
id: `artifact-${now}-${Math.random().toString(36).slice(2, 6)}`,
|
|
162
|
+
type: 'canvas_artifact',
|
|
163
|
+
timestamp: now,
|
|
164
|
+
data: payload,
|
|
165
|
+
});
|
|
166
|
+
return { success: true, type, agentId, title };
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=canvas-push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-push.js","sourceRoot":"","sources":["../src/canvas-push.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import type { eventBus as eventBusInstance } from './events.js';
|
|
3
|
+
interface CanvasStateEntry {
|
|
4
|
+
state: string;
|
|
5
|
+
updatedAt: number;
|
|
6
|
+
payload?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
interface CanvasQueryDeps {
|
|
9
|
+
eventBus: typeof eventBusInstance;
|
|
10
|
+
canvasStateMap: Map<string, CanvasStateEntry>;
|
|
11
|
+
taskManager: {
|
|
12
|
+
listTasks: (opts: Record<string, unknown>) => any[];
|
|
13
|
+
};
|
|
14
|
+
chatManager: {
|
|
15
|
+
sendMessage: (msg: Record<string, unknown>) => Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
getCanvasSession: (sessionId: string) => Array<{
|
|
18
|
+
role: string;
|
|
19
|
+
content: string;
|
|
20
|
+
}>;
|
|
21
|
+
pushCanvasSession: (sessionId: string, role: string, content: string) => void;
|
|
22
|
+
listHosts: (opts: Record<string, unknown>) => any[];
|
|
23
|
+
}
|
|
24
|
+
export declare function canvasQueryRoutes(app: FastifyInstance, deps: CanvasQueryDeps): Promise<void>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=canvas-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-query.d.ts","sourceRoot":"","sources":["../src/canvas-query.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE/D,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,OAAO,gBAAgB,CAAA;IACjC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IAC7C,WAAW,EAAE;QAAE,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,GAAG,EAAE,CAAA;KAAE,CAAA;IACpE,WAAW,EAAE;QAAE,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAA;IAC7E,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACjF,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7E,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,GAAG,EAAE,CAAA;CACpD;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC,CAmXf"}
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Canvas query route — extracted from server.ts
|
|
3
|
+
// Phase 2 canvas route extraction (task-1773689755389)
|
|
4
|
+
export async function canvasQueryRoutes(app, deps) {
|
|
5
|
+
const { eventBus, canvasStateMap, taskManager, chatManager, getCanvasSession, pushCanvasSession, listHosts } = deps;
|
|
6
|
+
// POST /canvas/query — human asks the canvas a question; agent responds with a typed card
|
|
7
|
+
app.post('/canvas/query', async (request, reply) => {
|
|
8
|
+
// Support both JSON and multipart/form-data (task-1773673285236)
|
|
9
|
+
// JSON: { query, attachments: [{ name, type, data (base64) }], sessionId?, agentId? }
|
|
10
|
+
// Multipart: fields query, sessionId?, agentId? + file parts
|
|
11
|
+
const contentType = String(request.headers['content-type'] ?? '');
|
|
12
|
+
const isMultipart = contentType.includes('multipart/form-data');
|
|
13
|
+
let query = '';
|
|
14
|
+
let sessionIdRaw;
|
|
15
|
+
let agentIdRaw;
|
|
16
|
+
const attachments = [];
|
|
17
|
+
if (isMultipart) {
|
|
18
|
+
try {
|
|
19
|
+
const parts = request.parts({ limits: { fileSize: 10 * 1024 * 1024, files: 5 } });
|
|
20
|
+
for await (const part of parts) {
|
|
21
|
+
if (part.type === 'field') {
|
|
22
|
+
const val = typeof part.value === 'string' ? part.value : '';
|
|
23
|
+
if (part.fieldname === 'query' || part.fieldname === 'text')
|
|
24
|
+
query = val.trim();
|
|
25
|
+
else if (part.fieldname === 'sessionId')
|
|
26
|
+
sessionIdRaw = val;
|
|
27
|
+
else if (part.fieldname === 'agentId')
|
|
28
|
+
agentIdRaw = val;
|
|
29
|
+
}
|
|
30
|
+
else if (part.type === 'file') {
|
|
31
|
+
const chunks = [];
|
|
32
|
+
for await (const chunk of part.file)
|
|
33
|
+
chunks.push(chunk);
|
|
34
|
+
const buf = Buffer.concat(chunks);
|
|
35
|
+
if (buf.length > 0 && buf.length <= 10 * 1024 * 1024) {
|
|
36
|
+
attachments.push({
|
|
37
|
+
name: String(part.filename ?? 'file').slice(0, 255),
|
|
38
|
+
type: String(part.mimetype ?? 'application/octet-stream'),
|
|
39
|
+
data: buf.toString('base64'),
|
|
40
|
+
sizeBytes: buf.length,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (mpErr) {
|
|
47
|
+
reply.status(400);
|
|
48
|
+
return { success: false, message: 'Invalid multipart body' };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// JSON path (backward compatible)
|
|
53
|
+
const body = request.body;
|
|
54
|
+
query = typeof body.query === 'string' ? body.query.trim() : '';
|
|
55
|
+
sessionIdRaw = typeof body.sessionId === 'string' ? body.sessionId : undefined;
|
|
56
|
+
agentIdRaw = typeof body.agentId === 'string' ? body.agentId : undefined;
|
|
57
|
+
// Extract base64 file attachments from JSON body
|
|
58
|
+
// Shape: [{ name: string, type: string, data: string (base64) }]
|
|
59
|
+
const rawAttachments = Array.isArray(body.attachments) ? body.attachments : [];
|
|
60
|
+
for (const att of rawAttachments.slice(0, 5)) { // Max 5 files
|
|
61
|
+
if (typeof att === 'object' && att && typeof att.name === 'string' && typeof att.data === 'string') {
|
|
62
|
+
const sizeBytes = Math.ceil((att.data.length * 3) / 4); // base64 → byte estimate
|
|
63
|
+
if (sizeBytes > 10 * 1024 * 1024)
|
|
64
|
+
continue; // Skip files > 10MB
|
|
65
|
+
attachments.push({
|
|
66
|
+
name: String(att.name).slice(0, 255),
|
|
67
|
+
type: String(att.type || 'application/octet-stream'),
|
|
68
|
+
data: att.data,
|
|
69
|
+
sizeBytes,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (!query || query.length > 500) {
|
|
75
|
+
reply.status(400);
|
|
76
|
+
return { success: false, message: 'query is required (max 500 chars)' };
|
|
77
|
+
}
|
|
78
|
+
// Session continuity: client passes sessionId (UUID) so follow-up questions have context
|
|
79
|
+
const sessionId = sessionIdRaw && sessionIdRaw.length > 0
|
|
80
|
+
? sessionIdRaw.trim().slice(0, 64)
|
|
81
|
+
: null;
|
|
82
|
+
const sessionTurns = sessionId ? getCanvasSession(sessionId) : [];
|
|
83
|
+
// Default: if no agent specified, return team status directly (don't route to specific agent)
|
|
84
|
+
const responderId = agentIdRaw ? agentIdRaw.trim() : null;
|
|
85
|
+
const IDENTITY_COLORS_Q = {
|
|
86
|
+
link: '#60a5fa', kai: '#fb923c', pixel: '#a78bfa',
|
|
87
|
+
sage: '#34d399', scout: '#fbbf24', echo: '#f472b6',
|
|
88
|
+
};
|
|
89
|
+
const agentColor = responderId ? (IDENTITY_COLORS_Q[responderId] ?? '#60a5fa') : '#60a5fa';
|
|
90
|
+
// If no specific agent requested, return team status directly without agent routing
|
|
91
|
+
if (!responderId) {
|
|
92
|
+
const allTasks = taskManager.listTasks({});
|
|
93
|
+
const doingTasks = allTasks.filter((t) => t.status === 'doing').slice(0, 5);
|
|
94
|
+
const todoCount = allTasks.filter((t) => t.status === 'todo').length;
|
|
95
|
+
const validatingCount = allTasks.filter((t) => t.status === 'validating').length;
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
card: {
|
|
99
|
+
type: 'tasks',
|
|
100
|
+
data: {
|
|
101
|
+
items: doingTasks.map((t) => ({
|
|
102
|
+
agentId: t.assignee || 'unassigned',
|
|
103
|
+
title: t.title,
|
|
104
|
+
state: t.status,
|
|
105
|
+
})),
|
|
106
|
+
todoCount,
|
|
107
|
+
doingCount: doingTasks.length,
|
|
108
|
+
validatingCount,
|
|
109
|
+
},
|
|
110
|
+
agentId: 'assistant',
|
|
111
|
+
agentColor: '#60a5fa',
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// Gather live context to inject into LLM
|
|
116
|
+
const allTasksForQuery = taskManager.listTasks({});
|
|
117
|
+
const activeTasks = [];
|
|
118
|
+
const doingTasks = allTasksForQuery.filter((t) => t.status === 'doing').slice(0, 10);
|
|
119
|
+
const validatingTasks = allTasksForQuery.filter((t) => t.status === 'validating').slice(0, 5);
|
|
120
|
+
for (const t of [...doingTasks, ...validatingTasks]) {
|
|
121
|
+
activeTasks.push({ id: t.id, title: t.title ?? '', assignee: t.assignee ?? 'unassigned', status: t.status, priority: t.priority ?? 'P2' });
|
|
122
|
+
}
|
|
123
|
+
const todoCount = allTasksForQuery.filter((t) => t.status === 'todo').length;
|
|
124
|
+
const doingCount = doingTasks.length;
|
|
125
|
+
const validatingCount = validatingTasks.length;
|
|
126
|
+
// Build agent orb context
|
|
127
|
+
const now = Date.now();
|
|
128
|
+
const STALE_AGENT_MS = 10 * 60 * 1000;
|
|
129
|
+
const activeAgentSummary = [];
|
|
130
|
+
for (const [agentId, entry] of canvasStateMap) {
|
|
131
|
+
if (now - entry.updatedAt > STALE_AGENT_MS)
|
|
132
|
+
continue;
|
|
133
|
+
const payload = entry.payload ?? {};
|
|
134
|
+
const state = String(payload.presenceState ?? entry.state);
|
|
135
|
+
const task = payload.activeTask?.title ?? null;
|
|
136
|
+
activeAgentSummary.push(`${agentId}: ${state}${task ? ` — working on "${task.slice(0, 50)}"` : ''}`);
|
|
137
|
+
}
|
|
138
|
+
// Classify query intent to choose card type
|
|
139
|
+
const lower = query.toLowerCase();
|
|
140
|
+
const isTasksQuery = /working on|team doing|team status|happening|active|shipping|tasks|who.?s|what.?s the team/.test(lower);
|
|
141
|
+
const isRevenueQuery = /revenue|mrr|arr|money|sales|customers|paid|billing/.test(lower);
|
|
142
|
+
const isOnboardingQuery = /onboard|get started|how do i|where do i start|first step/.test(lower);
|
|
143
|
+
const isHostsQuery = /show me hosts|host status|server status|machine|node/.test(lower);
|
|
144
|
+
let card;
|
|
145
|
+
// Build tasks card from live data (no LLM needed — deterministic)
|
|
146
|
+
if (isTasksQuery) {
|
|
147
|
+
const items = activeTasks.slice(0, 5).map(t => ({
|
|
148
|
+
agentId: t.assignee,
|
|
149
|
+
agentColor: IDENTITY_COLORS_Q[t.assignee] ?? '#94a3b8',
|
|
150
|
+
title: t.title,
|
|
151
|
+
state: t.status,
|
|
152
|
+
}));
|
|
153
|
+
const overflow = Math.max(0, activeTasks.length - 5);
|
|
154
|
+
card = {
|
|
155
|
+
type: 'tasks',
|
|
156
|
+
data: { items, overflow, todoCount, doingCount, validatingCount },
|
|
157
|
+
};
|
|
158
|
+
// Store summary for session continuity across all card types
|
|
159
|
+
if (sessionId) {
|
|
160
|
+
pushCanvasSession(sessionId, 'user', query);
|
|
161
|
+
pushCanvasSession(sessionId, 'assistant', `${doingCount} tasks in progress, ${validatingCount} validating, ${todoCount} todo.${items.length > 0 ? ` Active: ${items.map(t => t.title.slice(0, 30)).join('; ')}.` : ''}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else if (isRevenueQuery) {
|
|
165
|
+
// Revenue card — LLM generates honest answer about current state
|
|
166
|
+
const anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
167
|
+
let text = 'Revenue tracking not yet wired. Check Stripe directly.';
|
|
168
|
+
if (anthropicKey) {
|
|
169
|
+
try {
|
|
170
|
+
const resp = await fetch('https://api.anthropic.com/v1/messages', {
|
|
171
|
+
method: 'POST',
|
|
172
|
+
headers: { 'x-api-key': anthropicKey, 'anthropic-version': '2023-06-01', 'content-type': 'application/json' },
|
|
173
|
+
body: JSON.stringify({
|
|
174
|
+
model: 'claude-haiku-4-5',
|
|
175
|
+
max_tokens: 80,
|
|
176
|
+
messages: [{ role: 'user', content: `Team Reflectt is a small AI agent team building reflectt.ai (no paid users yet). User asked: "${query}". Honest 1-sentence answer about revenue status. Be direct.` }],
|
|
177
|
+
}),
|
|
178
|
+
signal: AbortSignal.timeout(8000),
|
|
179
|
+
});
|
|
180
|
+
if (resp.ok) {
|
|
181
|
+
const d = await resp.json();
|
|
182
|
+
text = d.content?.[0]?.text?.trim() ?? text;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch { /* use default */ }
|
|
186
|
+
}
|
|
187
|
+
card = { type: 'info', data: { text } };
|
|
188
|
+
if (sessionId) {
|
|
189
|
+
pushCanvasSession(sessionId, 'user', query);
|
|
190
|
+
pushCanvasSession(sessionId, 'assistant', text);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else if (isOnboardingQuery) {
|
|
194
|
+
card = {
|
|
195
|
+
type: 'onboarding',
|
|
196
|
+
data: {
|
|
197
|
+
step: 1, totalSteps: 3,
|
|
198
|
+
title: 'Welcome to Reflectt',
|
|
199
|
+
body: 'Your agents run on reflectt-node. Install it on any machine and your team appears here in the canvas.',
|
|
200
|
+
ctaLabel: 'Install reflectt-node',
|
|
201
|
+
ctaAction: 'https://reflectt.ai/docs',
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
if (sessionId) {
|
|
205
|
+
pushCanvasSession(sessionId, 'user', query);
|
|
206
|
+
pushCanvasSession(sessionId, 'assistant', 'Showing onboarding: install reflectt-node to bring your team to the canvas.');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else if (isHostsQuery) {
|
|
210
|
+
const rawHosts = listHosts({});
|
|
211
|
+
const hosts = rawHosts.map((h) => ({
|
|
212
|
+
id: h.id,
|
|
213
|
+
name: h.hostname ?? h.id,
|
|
214
|
+
status: h.status,
|
|
215
|
+
version: h.version ?? null,
|
|
216
|
+
agentCount: Array.isArray(h.agents) ? h.agents.length : 0,
|
|
217
|
+
lastSeen: h.last_seen_at,
|
|
218
|
+
}));
|
|
219
|
+
card = { type: 'hosts', data: { hosts } };
|
|
220
|
+
if (sessionId) {
|
|
221
|
+
pushCanvasSession(sessionId, 'user', query);
|
|
222
|
+
const hostSummary = hosts.length > 0
|
|
223
|
+
? `${hosts.length} host${hosts.length > 1 ? 's' : ''}: ${hosts.map((h) => `${h.name} (${h.status})`).join(', ')}.`
|
|
224
|
+
: 'No hosts connected yet.';
|
|
225
|
+
pushCanvasSession(sessionId, 'assistant', hostSummary);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
// General query — route to the actual agent via chat.
|
|
230
|
+
// The agent receives the message in their inbox, processes it through
|
|
231
|
+
// their real context (OpenClaw session), and can respond via canvas_push.
|
|
232
|
+
//
|
|
233
|
+
// This replaces the old standalone LLM call that had no real agent context.
|
|
234
|
+
// The agents ARE the product — queries go to them, not to a disconnected API key.
|
|
235
|
+
//
|
|
236
|
+
// Route: DM to the responder agent on #general (agents subscribe to #general
|
|
237
|
+
// by default — 'canvas' channel is NOT in DEFAULT_INBOX_SUBSCRIPTIONS, so
|
|
238
|
+
// messages posted there are never seen by agents).
|
|
239
|
+
try {
|
|
240
|
+
const attachmentSummary = attachments.length > 0
|
|
241
|
+
? `\n[${attachments.length} file(s) attached: ${attachments.map(a => `${a.name} (${a.type}, ${Math.round(a.sizeBytes / 1024)}KB)`).join(', ')}]`
|
|
242
|
+
: '';
|
|
243
|
+
await chatManager.sendMessage({
|
|
244
|
+
from: 'human',
|
|
245
|
+
to: responderId,
|
|
246
|
+
content: `[canvas] @${responderId} ${query}${attachmentSummary}`,
|
|
247
|
+
channel: 'general',
|
|
248
|
+
metadata: {
|
|
249
|
+
source: 'canvas_query',
|
|
250
|
+
sessionId,
|
|
251
|
+
responderId,
|
|
252
|
+
timestamp: Date.now(),
|
|
253
|
+
reply_via: 'canvas_push', // tells the agent to respond via POST /canvas/push
|
|
254
|
+
...(attachments.length > 0 ? { attachments: attachments.map(a => ({ name: a.name, type: a.type, sizeBytes: a.sizeBytes })) } : {}),
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
// Chat delivery failure is non-fatal — still show the thinking card
|
|
260
|
+
}
|
|
261
|
+
// Return an immediate "thinking" card — the real response will arrive
|
|
262
|
+
// asynchronously via canvas_push/canvas_message when the agent responds.
|
|
263
|
+
const text = `Asking ${responderId}…`;
|
|
264
|
+
// Store the question in session history
|
|
265
|
+
if (sessionId) {
|
|
266
|
+
pushCanvasSession(sessionId, 'user', query);
|
|
267
|
+
}
|
|
268
|
+
card = { type: 'info', data: { text, pending: true, responderId } };
|
|
269
|
+
// ── Timeout fallback: if agent doesn't respond within 15s, send a
|
|
270
|
+
// "no response" card so the UI doesn't hang on "Asking …" forever.
|
|
271
|
+
let responseReceived = false;
|
|
272
|
+
const listenerId = `canvas-query-timeout-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
273
|
+
eventBus.on(listenerId, (event) => {
|
|
274
|
+
if (event.type !== 'canvas_message')
|
|
275
|
+
return;
|
|
276
|
+
const d = event.data;
|
|
277
|
+
if (d?.agentId === responderId && d?.isResponse === true) {
|
|
278
|
+
responseReceived = true;
|
|
279
|
+
eventBus.off(listenerId);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
setTimeout(() => {
|
|
283
|
+
eventBus.off(listenerId);
|
|
284
|
+
if (responseReceived)
|
|
285
|
+
return;
|
|
286
|
+
// Emit a timeout fallback card
|
|
287
|
+
eventBus.emit({
|
|
288
|
+
id: `cmsg-timeout-${Date.now()}`,
|
|
289
|
+
type: 'canvas_message',
|
|
290
|
+
timestamp: Date.now(),
|
|
291
|
+
data: {
|
|
292
|
+
type: 'info',
|
|
293
|
+
data: { text: `${responderId} is busy right now. Try again in a moment, or ask a different agent.`, pending: false },
|
|
294
|
+
agentId: responderId,
|
|
295
|
+
agentColor,
|
|
296
|
+
isResponse: true,
|
|
297
|
+
isTimeout: true,
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
if (sessionId) {
|
|
301
|
+
pushCanvasSession(sessionId, 'assistant', `(${responderId} did not respond within 15s)`);
|
|
302
|
+
}
|
|
303
|
+
}, 15_000);
|
|
304
|
+
}
|
|
305
|
+
// Emit canvas_message on event bus — pulse stream forwards it to all subscribers
|
|
306
|
+
eventBus.emit({
|
|
307
|
+
id: `cmsg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
308
|
+
type: 'canvas_message',
|
|
309
|
+
timestamp: Date.now(),
|
|
310
|
+
data: {
|
|
311
|
+
...card,
|
|
312
|
+
agentId: responderId,
|
|
313
|
+
agentColor,
|
|
314
|
+
query,
|
|
315
|
+
...(attachments.length > 0 ? { attachments: attachments.map(a => ({ name: a.name, type: a.type, sizeBytes: a.sizeBytes })) } : {}),
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
return { success: true, card: { ...card, agentId: responderId, agentColor, ...(attachments.length > 0 ? { attachmentCount: attachments.length } : {}) } };
|
|
319
|
+
});
|
|
320
|
+
// ── Canvas query response bridge ───────────────────────────────────────────
|
|
321
|
+
// When an agent responds to a [canvas] query (via chat), convert their response
|
|
322
|
+
// into a canvas_message event so the browser canvas can display it.
|
|
323
|
+
// This bridges: agent chat response → canvas card.
|
|
324
|
+
eventBus.on('canvas-query-response-bridge', (event) => {
|
|
325
|
+
if (event.type !== 'message_posted')
|
|
326
|
+
return;
|
|
327
|
+
const data = event.data;
|
|
328
|
+
const content = String(data.content ?? '');
|
|
329
|
+
const from = String(data.from ?? '');
|
|
330
|
+
const channel = String(data.channel ?? '');
|
|
331
|
+
// Only bridge messages from agents (not from 'human' or 'system')
|
|
332
|
+
if (from === 'human' || from === 'system' || from === 'github')
|
|
333
|
+
return;
|
|
334
|
+
// Detect canvas responses: messages that start with [canvas-response] or
|
|
335
|
+
// are on the canvas channel from an agent, or mention [canvas] in reply
|
|
336
|
+
const isCanvasResponse = content.startsWith('[canvas-response]')
|
|
337
|
+
|| content.startsWith('[canvas]')
|
|
338
|
+
|| (channel === 'canvas' && from !== 'human');
|
|
339
|
+
if (!isCanvasResponse)
|
|
340
|
+
return;
|
|
341
|
+
// Strip the [canvas-response] / [canvas] prefix
|
|
342
|
+
const cleanContent = content
|
|
343
|
+
.replace(/^\[canvas-response\]\s*/i, '')
|
|
344
|
+
.replace(/^\[canvas\]\s*/i, '')
|
|
345
|
+
.trim();
|
|
346
|
+
if (!cleanContent)
|
|
347
|
+
return;
|
|
348
|
+
const IDENTITY_COLORS_BRIDGE = {
|
|
349
|
+
link: '#60a5fa', kai: '#fb923c', pixel: '#a78bfa',
|
|
350
|
+
sage: '#34d399', scout: '#fbbf24', echo: '#f472b6',
|
|
351
|
+
rhythm: '#a3e635', swift: '#38bdf8',
|
|
352
|
+
};
|
|
353
|
+
const agentColor = IDENTITY_COLORS_BRIDGE[from] ?? '#94a3b8';
|
|
354
|
+
// Emit as canvas_message — browser pulse stream picks it up
|
|
355
|
+
eventBus.emit({
|
|
356
|
+
id: `cmsg-response-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
357
|
+
type: 'canvas_message',
|
|
358
|
+
timestamp: Date.now(),
|
|
359
|
+
data: {
|
|
360
|
+
type: 'info',
|
|
361
|
+
data: { text: cleanContent },
|
|
362
|
+
agentId: from,
|
|
363
|
+
agentColor,
|
|
364
|
+
isResponse: true,
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
//# sourceMappingURL=canvas-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-query.js","sourceRoot":"","sources":["../src/canvas-query.ts"],"names":[],"mappings":"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"}
|