@abgov/nx-adsp 12.8.0-beta.2 → 12.8.0-beta.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/nx-adsp",
3
- "version": "12.8.0-beta.2",
3
+ "version": "12.8.0-beta.4",
4
4
  "license": "Apache-2.0",
5
5
  "main": "src/index.js",
6
6
  "description": "Government of Alberta - Nx plugin for ADSP apps.",
@@ -25,6 +25,11 @@ export interface AgentResult {
25
25
  * generated and modified files; this function retrieves the workspace state
26
26
  * after the conversation and applies all files to the Nx Tree.
27
27
  *
28
+ * The socket connection and file upload start immediately. While the files
29
+ * are uploading, the developer is prompted for a brief project description.
30
+ * The initial message is sent as soon as both the upload and the description
31
+ * are ready — whichever finishes last.
32
+ *
28
33
  * Returns null if agent-service is unavailable — callers should skip the
29
34
  * agent step gracefully in that case.
30
35
  */
@@ -13,11 +13,17 @@ const AGENT_ID = 'nxAdspAgent';
13
13
  * generated and modified files; this function retrieves the workspace state
14
14
  * after the conversation and applies all files to the Nx Tree.
15
15
  *
16
+ * The socket connection and file upload start immediately. While the files
17
+ * are uploading, the developer is prompted for a brief project description.
18
+ * The initial message is sent as soon as both the upload and the description
19
+ * are ready — whichever finishes last.
20
+ *
16
21
  * Returns null if agent-service is unavailable — callers should skip the
17
22
  * agent step gracefully in that case.
18
23
  */
19
24
  function consultAgent(directoryServiceUrl, accessToken, projectContext, host, projectRoot) {
20
25
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
26
+ var _a;
21
27
  if (!accessToken) {
22
28
  process.stdout.write('\n[nx-adsp] No access token — skipping agent interaction.\n');
23
29
  return null;
@@ -28,52 +34,136 @@ function consultAgent(directoryServiceUrl, accessToken, projectContext, host, pr
28
34
  return null;
29
35
  }
30
36
  process.stdout.write(`\n[nx-adsp] Connecting to agent at ${agentServiceUrl}...\n`);
31
- return new Promise((resolve) => {
32
- const socket = (0, socket_io_client_1.io)(agentServiceUrl, {
33
- auth: { token: accessToken },
34
- // Skip polling go directly to WebSocket to avoid ARO ingress rejecting
35
- // the polling POST with HTTP 400.
36
- transports: ['websocket'],
37
- timeout: 30000,
38
- reconnection: false,
39
- });
40
- const rl = (0, readline_1.createInterface)({ input: process.stdin, output: process.stdout });
41
- const threadId = crypto.randomUUID();
42
- let buffer = '';
43
- let conversationDone = false;
44
- let agentHasResponded = false;
45
- let interrupted = false;
46
- // Ctrl+C — abort the interaction without applying generated files.
47
- rl.on('SIGINT', () => {
48
- interrupted = true;
49
- process.stdout.write('\n');
50
- cleanup(0);
37
+ const threadId = crypto.randomUUID();
38
+ // Start socket connection immediately so file upload overlaps with the description prompt.
39
+ const socket = (0, socket_io_client_1.io)(agentServiceUrl, {
40
+ auth: { token: accessToken },
41
+ // Skip polling go directly to WebSocket to avoid ARO ingress rejecting
42
+ // the polling POST with HTTP 400.
43
+ transports: ['websocket'],
44
+ timeout: 30000,
45
+ reconnection: false,
46
+ });
47
+ const rl = (0, readline_1.createInterface)({ input: process.stdin, output: process.stdout });
48
+ // Coordination: sendInitialMessage is called once BOTH conditions are met:
49
+ // 1. description prompt has been answered (descriptionReady = true)
50
+ // 2. workspace files have been uploaded (workspaceReady = true)
51
+ // Whichever condition is satisfied last triggers the send.
52
+ let description;
53
+ let descriptionReady = false;
54
+ let workspaceReady = false;
55
+ let conversationStarted = false;
56
+ let buffer = '';
57
+ let conversationDone = false;
58
+ let agentHasResponded = false;
59
+ let interrupted = false;
60
+ let resolveConversation;
61
+ const conversationPromise = new Promise((r) => {
62
+ resolveConversation = r;
63
+ });
64
+ const cleanup = (filesWritten) => {
65
+ conversationDone = true;
66
+ rl.close();
67
+ socket.disconnect();
68
+ // Return null only for truly silent skips (no agent, no token, connection failed).
69
+ // Return a result whenever the user was actively engaged (agent responded)
70
+ // OR when they explicitly interrupted (Ctrl+C), so the caller always gets
71
+ // a chance to confirm before proceeding.
72
+ resolveConversation(agentHasResponded || interrupted
73
+ ? { filesWritten, userInteracted: agentHasResponded, interrupted }
74
+ : null);
75
+ };
76
+ const buildInitialMessage = () => {
77
+ const fileNames = Object.keys(projectContext.existingFiles).join(', ');
78
+ const descriptionLine = description
79
+ ? `It is described as: "${description}". `
80
+ : '';
81
+ return (`I am setting up a new ${projectContext.projectType} called "${projectContext.projectName}" ` +
82
+ `for ADSP tenant "${projectContext.tenant}" (nx-adsp plugin version ${projectContext.pluginVersion}). ` +
83
+ descriptionLine +
84
+ `The project files (${fileNames}) have been uploaded to your workspace. ` +
85
+ `What ADSP capabilities would be useful to integrate into this service?`);
86
+ };
87
+ const sendInitialMessage = () => {
88
+ if (conversationStarted)
89
+ return;
90
+ conversationStarted = true;
91
+ process.stdout.write('[nx-adsp] Type your replies at the > prompt. Press Ctrl+D or leave blank to apply generated files.\n\n');
92
+ socket.emit('message', {
93
+ agent: AGENT_ID,
94
+ threadId,
95
+ content: buildInitialMessage(),
96
+ rawChunks: true,
51
97
  });
52
- // Ctrl+D / stdin EOF intentional finish: fetch workspace and apply files.
53
- rl.on('close', () => {
54
- if (!conversationDone && !interrupted) {
98
+ // Show periodic dots while waiting for first agent response, then warn at 2 minutes.
99
+ const dotInterval = setInterval(() => {
100
+ if (!conversationDone && !agentHasResponded)
101
+ process.stdout.write('.');
102
+ else
103
+ clearInterval(dotInterval);
104
+ }, 3000);
105
+ setTimeout(() => {
106
+ clearInterval(dotInterval);
107
+ if (!conversationDone && !agentHasResponded) {
108
+ process.stdout.write('\n[nx-adsp] No response after 2 minutes. ' +
109
+ 'The nxAdspAgent may still be deploying or the LLM is unresponsive. ' +
110
+ 'Press Ctrl+C to skip and continue generation.\n');
111
+ }
112
+ }, 120000);
113
+ };
114
+ const requestWorkspaceState = () => {
115
+ socket.emit('workspace-read', { agent: AGENT_ID, threadId });
116
+ };
117
+ const promptUser = () => {
118
+ rl.question('\n> ', (input) => {
119
+ const trimmed = input.trim();
120
+ if (trimmed) {
121
+ socket.emit('message', {
122
+ agent: AGENT_ID,
123
+ threadId,
124
+ content: trimmed,
125
+ rawChunks: true,
126
+ });
127
+ }
128
+ else {
129
+ // Empty input — apply whatever the agent has generated.
55
130
  requestWorkspaceState();
56
131
  }
57
132
  });
58
- const buildInitialMessage = () => {
59
- const fileNames = Object.keys(projectContext.existingFiles).join(', ');
60
- return (`I am setting up a new ${projectContext.projectType} called "${projectContext.projectName}" ` +
61
- `for ADSP tenant "${projectContext.tenant}" (nx-adsp plugin version ${projectContext.pluginVersion}). ` +
62
- `The project files (${fileNames}) have been uploaded to your workspace. ` +
63
- `What ADSP capabilities would be useful to integrate into this service?`);
64
- };
65
- const sendMessage = (content) => {
66
- socket.emit('message', {
67
- agent: AGENT_ID,
68
- threadId,
69
- content,
70
- rawChunks: true,
71
- });
72
- };
73
- const requestWorkspaceState = () => {
74
- socket.emit('workspace-read', { agent: AGENT_ID, threadId });
75
- };
76
- const uploadFilesToWorkspace = () => {
133
+ };
134
+ const applyWorkspaceFiles = (files) => {
135
+ let count = 0;
136
+ for (const file of files) {
137
+ // Skip files we uploaded that the agent hasn't modified only apply
138
+ // new files and agent-modified versions of existing files.
139
+ const original = projectContext.existingFiles[file.path];
140
+ if (original !== undefined && original === file.content) {
141
+ continue;
142
+ }
143
+ const fullPath = `${projectRoot}/${file.path}`;
144
+ host.write(fullPath, file.content);
145
+ count++;
146
+ }
147
+ return count;
148
+ };
149
+ // Register all socket and readline handlers upfront so they are active
150
+ // while the description prompt is being shown.
151
+ rl.on('SIGINT', () => {
152
+ interrupted = true;
153
+ process.stdout.write('\n');
154
+ cleanup(0);
155
+ });
156
+ rl.on('close', () => {
157
+ if (!conversationDone && !interrupted) {
158
+ requestWorkspaceState();
159
+ }
160
+ });
161
+ socket.on('connect', () => {
162
+ // Connect and upload silently — stdout writes here would interleave with
163
+ // the description prompt that is active concurrently.
164
+ // The server signals handler readiness via socket.send() after its async
165
+ // getServiceConfiguration() resolves; wait for that before uploading.
166
+ socket.once('message', () => {
77
167
  socket.emit('workspace-update', {
78
168
  agent: AGENT_ID,
79
169
  threadId,
@@ -83,121 +173,92 @@ function consultAgent(directoryServiceUrl, accessToken, projectContext, host, pr
83
173
  })),
84
174
  deletes: [],
85
175
  });
86
- };
87
- const promptUser = () => {
88
- rl.question('\n> ', (input) => {
89
- const trimmed = input.trim();
90
- if (trimmed) {
91
- sendMessage(trimmed);
92
- }
93
- else {
94
- // Empty input — apply whatever the agent has generated.
95
- requestWorkspaceState();
96
- }
97
- });
98
- };
99
- const applyWorkspaceFiles = (files) => {
100
- let count = 0;
101
- for (const file of files) {
102
- // Skip files we uploaded that the agent hasn't modified — only apply
103
- // new files and agent-modified versions of existing files.
104
- const original = projectContext.existingFiles[file.path];
105
- if (original !== undefined && original === file.content) {
106
- continue;
107
- }
108
- const fullPath = `${projectRoot}/${file.path}`;
109
- host.write(fullPath, file.content);
110
- count++;
111
- }
112
- return count;
113
- };
114
- const cleanup = (filesWritten) => {
115
- conversationDone = true;
116
- rl.close();
117
- socket.disconnect();
118
- // Return null only for truly silent skips (no agent, no token, connection failed).
119
- // Return a result whenever the user was actively engaged (agent responded)
120
- // OR when they explicitly interrupted (Ctrl+C), so the caller always gets
121
- // a chance to confirm before proceeding.
122
- resolve(agentHasResponded || interrupted
123
- ? { filesWritten, userInteracted: agentHasResponded, interrupted }
124
- : null);
125
- };
126
- socket.on('workspace-updated', () => {
127
- process.stdout.write('[nx-adsp] Project files uploaded to workspace.\n');
128
- process.stdout.write('[nx-adsp] Type your replies at the > prompt. Press Ctrl+D or leave blank to apply generated files.\n\n');
129
- sendMessage(buildInitialMessage());
130
- });
131
- socket.on('connect', () => {
132
- process.stdout.write('[nx-adsp] Connected to agent-service.\n');
133
- process.stdout.write('[nx-adsp] Uploading project files to workspace...\n');
134
- uploadFilesToWorkspace();
135
- // Show periodic dots while waiting for first response, then a warning at 2 minutes.
136
- const dotInterval = setInterval(() => {
137
- if (!conversationDone && !agentHasResponded)
138
- process.stdout.write('.');
139
- else
140
- clearInterval(dotInterval);
141
- }, 3000);
142
- setTimeout(() => {
143
- clearInterval(dotInterval);
144
- if (!conversationDone && !agentHasResponded) {
145
- process.stdout.write('\n[nx-adsp] No response after 2 minutes. ' +
146
- 'The nxAdspAgent may still be deploying or the LLM is unresponsive. ' +
147
- 'Press Ctrl+C to skip and continue generation.\n');
148
- }
149
- }, 120000);
150
176
  });
151
- socket.on('stream', ({ chunk, done }) => {
152
- var _a, _b;
153
- if ((chunk === null || chunk === void 0 ? void 0 : chunk.type) === 'text-delta') {
154
- const text = (_b = (_a = chunk.payload) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : '';
155
- if (!agentHasResponded) {
156
- // Clear the dots line before the first response starts.
157
- process.stdout.write('\n');
158
- }
159
- buffer += text;
160
- agentHasResponded = true;
161
- process.stdout.write(text);
162
- }
163
- if (done) {
164
- if (buffer.length > 0 && !buffer.endsWith('\n')) {
165
- process.stdout.write('\n');
166
- }
167
- buffer = '';
168
- // Agent finished its turn — prompt the user to continue the conversation
169
- // or press Enter to apply whatever the agent has written so far.
170
- promptUser();
171
- }
172
- });
173
- socket.on('workspace-state', ({ files }) => {
174
- // Only apply files the agent added or modified — not unchanged uploaded files.
175
- const written = applyWorkspaceFiles(files !== null && files !== void 0 ? files : []);
176
- if (written > 0) {
177
- process.stdout.write(`\nApplied ${written} file(s) from agent workspace.\n`);
177
+ });
178
+ socket.on('workspace-updated', () => {
179
+ workspaceReady = true;
180
+ if (descriptionReady) {
181
+ // Description was entered before upload finished — send now.
182
+ sendInitialMessage();
183
+ }
184
+ // else: description prompt is still open — post-prompt code will call sendInitialMessage.
185
+ });
186
+ socket.on('stream', ({ chunk, done }) => {
187
+ var _a, _b;
188
+ if ((chunk === null || chunk === void 0 ? void 0 : chunk.type) === 'text-delta') {
189
+ const text = (_b = (_a = chunk.payload) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : '';
190
+ if (!agentHasResponded) {
191
+ // Clear the dots line before the first response starts.
192
+ process.stdout.write('\n');
178
193
  }
179
- else {
180
- process.stdout.write('\nNo files generated by agent.\n');
194
+ buffer += text;
195
+ agentHasResponded = true;
196
+ process.stdout.write(text);
197
+ }
198
+ if (done) {
199
+ if (buffer.length > 0 && !buffer.endsWith('\n')) {
200
+ process.stdout.write('\n');
181
201
  }
182
- cleanup(written);
183
- });
184
- socket.on('session-expired', () => {
185
- process.stdout.write('\nAgent session expired.\n');
186
- requestWorkspaceState();
187
- });
188
- socket.on('connect_error', (err) => {
189
- var _a, _b, _c, _d;
190
- // Log the full error object so we can diagnose the root cause.
191
- const errAny = err;
192
- process.stdout.write(`\n[nx-adsp] Connection failed: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}\n`);
193
- process.stdout.write(`[nx-adsp] Error detail: ${JSON.stringify((_d = (_c = (_b = errAny === null || errAny === void 0 ? void 0 : errAny.description) !== null && _b !== void 0 ? _b : errAny === null || errAny === void 0 ? void 0 : errAny.context) !== null && _c !== void 0 ? _c : errAny === null || errAny === void 0 ? void 0 : errAny.cause) !== null && _d !== void 0 ? _d : 'none')}\n`);
194
- cleanup(0);
195
- });
196
- socket.on('error', (err) => {
197
- process.stdout.write(`\n[nx-adsp] Agent error: ${JSON.stringify(err)}\n`);
198
- requestWorkspaceState();
199
- });
202
+ buffer = '';
203
+ // Agent finished its turn — prompt the user to continue the conversation
204
+ // or press Enter to apply whatever the agent has written so far.
205
+ promptUser();
206
+ }
200
207
  });
208
+ socket.on('workspace-state', ({ files }) => {
209
+ // Only apply files the agent added or modified — not unchanged uploaded files.
210
+ const written = applyWorkspaceFiles(files !== null && files !== void 0 ? files : []);
211
+ if (written > 0) {
212
+ process.stdout.write(`\nApplied ${written} file(s) from agent workspace.\n`);
213
+ }
214
+ else {
215
+ process.stdout.write('\nNo files generated by agent.\n');
216
+ }
217
+ cleanup(written);
218
+ });
219
+ socket.on('session-expired', () => {
220
+ process.stdout.write('\nAgent session expired.\n');
221
+ requestWorkspaceState();
222
+ });
223
+ socket.on('connect_error', (err) => {
224
+ var _a, _b, _c, _d;
225
+ const errAny = err;
226
+ process.stdout.write(`\n[nx-adsp] Connection failed: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}\n`);
227
+ process.stdout.write(`[nx-adsp] Error detail: ${JSON.stringify((_d = (_c = (_b = errAny === null || errAny === void 0 ? void 0 : errAny.description) !== null && _b !== void 0 ? _b : errAny === null || errAny === void 0 ? void 0 : errAny.context) !== null && _c !== void 0 ? _c : errAny === null || errAny === void 0 ? void 0 : errAny.cause) !== null && _d !== void 0 ? _d : 'none')}\n`);
228
+ cleanup(0);
229
+ });
230
+ socket.on('error', (err) => {
231
+ process.stdout.write(`\n[nx-adsp] Agent error: ${JSON.stringify(err)}\n`);
232
+ requestWorkspaceState();
233
+ });
234
+ // Show description prompt while socket connects and uploads files in the background.
235
+ try {
236
+ const { prompt } = yield Promise.resolve().then(() => require('enquirer'));
237
+ const answer = yield prompt({
238
+ type: 'input',
239
+ name: 'description',
240
+ message: `Briefly describe what ${projectContext.projectName} does:`,
241
+ });
242
+ description = ((_a = answer.description) === null || _a === void 0 ? void 0 : _a.trim()) || undefined;
243
+ descriptionReady = true;
244
+ }
245
+ catch (_b) {
246
+ // Ctrl+C or cancellation during the description prompt.
247
+ interrupted = true;
248
+ cleanup(0);
249
+ return conversationPromise;
250
+ }
251
+ if (workspaceReady) {
252
+ // Upload finished while the user was typing — send immediately.
253
+ sendInitialMessage();
254
+ }
255
+ else {
256
+ // Rare: user typed faster than the upload completed. Show a brief status
257
+ // so the prompt doesn't appear to hang.
258
+ process.stdout.write('[nx-adsp] Uploading project files to workspace...\n');
259
+ // workspace-updated handler will call sendInitialMessage once upload completes.
260
+ }
261
+ return conversationPromise;
201
262
  });
202
263
  }
203
264
  function resolveAgentServiceUrl(directoryServiceUrl) {
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../../../packages/nx-adsp/src/utils/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../../../packages/nx-adsp/src/utils/agent.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,12 @@ jest.mock('socket.io-client');
12
12
  jest.mock('@abgov/nx-oc', () => ({ getServiceUrls: jest.fn() }));
13
13
  jest.mock('@nx/devkit', () => ({ Tree: jest.fn() }));
14
14
 
15
+ // Enquirer is dynamically imported inside consultAgent; mock it here so the
16
+ // prompt resolves immediately with an empty description in all tests.
17
+ jest.mock('enquirer', () => ({
18
+ prompt: jest.fn().mockResolvedValue({ description: '' }),
19
+ }));
20
+
15
21
  import { io } from 'socket.io-client';
16
22
  import { getServiceUrls } from '@abgov/nx-oc';
17
23
 
@@ -37,6 +43,9 @@ function makeMockSocket() {
37
43
  on: jest.fn((event: string, handler: (...args: unknown[]) => void) => {
38
44
  handlers[event] = handler;
39
45
  }),
46
+ once: jest.fn((event: string, handler: (...args: unknown[]) => void) => {
47
+ handlers[event] = handler;
48
+ }),
40
49
  emit: jest.fn(),
41
50
  disconnect: jest.fn(),
42
51
  _handlers: handlers,
@@ -46,6 +55,9 @@ function makeMockSocket() {
46
55
  return socket;
47
56
  }
48
57
 
58
+ // Flush the microtask queue so async operations inside consultAgent settle.
59
+ // One tick is enough: the dynamic import and the enquirer mock both resolve
60
+ // as microtasks, so after this all handlers are registered and descriptionReady=true.
49
61
  const flushPromises = () => new Promise(resolve => setTimeout(resolve, 0));
50
62
 
51
63
  describe('consultAgent', () => {
@@ -66,6 +78,7 @@ describe('consultAgent', () => {
66
78
  });
67
79
  const socket = makeMockSocket();
68
80
  const resultPromise = consultAgent('https://directory.example.com', 'token', PROJECT_CONTEXT, mockHost, 'apps/test-service');
81
+ // After one tick: enquirer mock resolves, descriptionReady=true, conversationPromise returned.
69
82
  await flushPromises();
70
83
  socket._handlers['connect_error']?.();
71
84
  expect(await resultPromise).toBeNull();
@@ -79,7 +92,10 @@ describe('consultAgent', () => {
79
92
  const resultPromise = consultAgent('https://directory.example.com', 'token', PROJECT_CONTEXT, mockHost, 'apps/test-service');
80
93
  await flushPromises();
81
94
 
95
+ // descriptionReady=true at this point; workspace-updated fires last → triggers sendInitialMessage.
82
96
  socket._handlers['connect']?.();
97
+ // Server signals readiness via 'message' before workspace-update is safe to send.
98
+ socket._handlers['message']?.('Connected as user...');
83
99
  socket._handlers['workspace-updated']?.();
84
100
  // Simulate agent responding with text (sets agentHasResponded = true)
85
101
  socket._handlers['stream']?.({ chunk: { type: 'text-delta', payload: { text: 'I will add events.' } }, done: false });
@@ -105,8 +121,9 @@ describe('consultAgent', () => {
105
121
  const resultPromise = consultAgent('https://directory.example.com', 'token', PROJECT_CONTEXT, mockHost, 'apps/test-service');
106
122
  await flushPromises();
107
123
 
108
- // connect → workspace-update emitted, then workspace-updated → message emitted
124
+ // connect → server sends 'message' readiness signal → workspace-update emitted workspace-updated → initial message sent
109
125
  socket._handlers['connect']?.();
126
+ socket._handlers['message']?.('Connected as user...');
110
127
  socket._handlers['workspace-updated']?.();
111
128
  socket._handlers['stream']?.({ chunk: { type: 'text-delta', payload: { text: 'What does this service do?' } }, done: false });
112
129
  socket._handlers['stream']?.({ chunk: null, done: true });