@promptbook/cli 0.112.0-81 → 0.112.0-84
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/apps/agents-server/README.md +7 -1
- package/apps/agents-server/src/database/$provideSupabaseForServer.ts +6 -0
- package/apps/agents-server/src/database/agentsServerDatabaseMode.ts +34 -0
- package/apps/agents-server/src/database/sqlite/$provideLocalSqliteSupabase.ts +1445 -0
- package/apps/agents-server/src/database/sqlite/resolveAgentsServerSqliteDatabasePath.ts +13 -0
- package/apps/agents-server/src/tools/$provideServer.ts +29 -2
- package/apps/agents-server/src/utils/serverRegistry.ts +13 -0
- package/apps/agents-server/src/utils/userChat/finalizeUserChatJob.ts +42 -0
- package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/claimNextDueUserChatTimeout.ts +63 -0
- package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/recoverExpiredRunningUserChatTimeouts.ts +47 -0
- package/apps/agents-server/src/utils/validateApiKey.ts +2 -18
- package/esm/apps/agents-server/src/database/agentsServerDatabaseMode.d.ts +20 -0
- package/esm/index.es.js +120 -5
- package/esm/index.es.js.map +1 -1
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -1
- package/src/book-components/Chat/save/pdf/buildChatPdf.ts +3 -26
- package/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.ts +3 -1
- package/src/cli/cli-commands/agents-server/startAgentsServer.ts +148 -3
- package/src/other/templates/getTemplatesPipelineCollection.ts +844 -694
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -0
- package/umd/apps/agents-server/src/database/agentsServerDatabaseMode.d.ts +20 -0
- package/umd/index.umd.js +120 -5
- package/umd/index.umd.js.map +1 -1
- package/umd/src/version.d.ts +1 -1
package/esm/src/version.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare const BOOK_LANGUAGE_VERSION: string_semantic_version;
|
|
|
15
15
|
export declare const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version;
|
|
16
16
|
/**
|
|
17
17
|
* Represents the version string of the Promptbook engine.
|
|
18
|
-
* It follows semantic versioning (e.g., `0.112.0-
|
|
18
|
+
* It follows semantic versioning (e.g., `0.112.0-82`).
|
|
19
19
|
*
|
|
20
20
|
* @generated
|
|
21
21
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@promptbook/cli",
|
|
3
|
-
"version": "0.112.0-
|
|
3
|
+
"version": "0.112.0-84",
|
|
4
4
|
"description": "Promptbook: Create persistent AI agents that turn your company's scattered knowledge into action",
|
|
5
5
|
"private": false,
|
|
6
6
|
"sideEffects": false,
|
|
@@ -155,6 +155,7 @@
|
|
|
155
155
|
"@types/swagger-ui-react": "5.18.0",
|
|
156
156
|
"@types/turndown": "5.0.6",
|
|
157
157
|
"@vercel/blob": "1.1.1",
|
|
158
|
+
"better-sqlite3": "^11.10.0",
|
|
158
159
|
"configchecker": "1.5.132",
|
|
159
160
|
"cross-fetch": "4.0.0",
|
|
160
161
|
"destroyable": "0.12.145",
|
|
@@ -164,16 +164,7 @@ function appendCanvasPagesToPdf(pdf: jsPDF, canvas: HTMLCanvasElement): void {
|
|
|
164
164
|
pdf.addPage();
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
pdf.addImage(
|
|
168
|
-
pageCanvas,
|
|
169
|
-
PDF_PAGE_IMAGE_FORMAT,
|
|
170
|
-
0,
|
|
171
|
-
0,
|
|
172
|
-
pageWidth,
|
|
173
|
-
sliceHeight * imageScale,
|
|
174
|
-
undefined,
|
|
175
|
-
'FAST',
|
|
176
|
-
);
|
|
167
|
+
pdf.addImage(pageCanvas, PDF_PAGE_IMAGE_FORMAT, 0, 0, pageWidth, sliceHeight * imageScale, undefined, 'FAST');
|
|
177
168
|
}
|
|
178
169
|
}
|
|
179
170
|
|
|
@@ -182,11 +173,7 @@ function appendCanvasPagesToPdf(pdf: jsPDF, canvas: HTMLCanvasElement): void {
|
|
|
182
173
|
*
|
|
183
174
|
* @private Internal helper of `buildChatPdf`.
|
|
184
175
|
*/
|
|
185
|
-
function createCanvasPageSlice(
|
|
186
|
-
canvas: HTMLCanvasElement,
|
|
187
|
-
sourceY: number,
|
|
188
|
-
sliceHeight: number,
|
|
189
|
-
): HTMLCanvasElement {
|
|
176
|
+
function createCanvasPageSlice(canvas: HTMLCanvasElement, sourceY: number, sliceHeight: number): HTMLCanvasElement {
|
|
190
177
|
const pageCanvas = document.createElement('canvas');
|
|
191
178
|
const pageCanvasContext = pageCanvas.getContext('2d');
|
|
192
179
|
|
|
@@ -204,17 +191,7 @@ function createCanvasPageSlice(
|
|
|
204
191
|
pageCanvas.height = sliceHeight;
|
|
205
192
|
pageCanvasContext.fillStyle = '#ffffff';
|
|
206
193
|
pageCanvasContext.fillRect(0, 0, pageCanvas.width, pageCanvas.height);
|
|
207
|
-
pageCanvasContext.drawImage(
|
|
208
|
-
canvas,
|
|
209
|
-
0,
|
|
210
|
-
sourceY,
|
|
211
|
-
canvas.width,
|
|
212
|
-
sliceHeight,
|
|
213
|
-
0,
|
|
214
|
-
0,
|
|
215
|
-
canvas.width,
|
|
216
|
-
sliceHeight,
|
|
217
|
-
);
|
|
194
|
+
pageCanvasContext.drawImage(canvas, 0, sourceY, canvas.width, sliceHeight, 0, 0, canvas.width, sliceHeight);
|
|
218
195
|
|
|
219
196
|
return pageCanvas;
|
|
220
197
|
}
|
|
@@ -26,9 +26,11 @@ const AGENTS_SERVER_ENV_DOCUMENTATION_BASE_URL =
|
|
|
26
26
|
const AGENTS_SERVER_ENV_CREATED_COMMENT = '# Created by `ptbk agents-server init` command';
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* Variables required for a local Agents Server backed by
|
|
29
|
+
* Variables required for a local Agents Server backed by Supabase or standalone SQLite.
|
|
30
30
|
*/
|
|
31
31
|
const REQUIRED_AGENTS_SERVER_ENV_VARIABLES: ReadonlyArray<RequiredAgentsServerEnvVariable> = [
|
|
32
|
+
createAgentsServerEnvVariable('PTBK_AGENTS_SERVER_DATABASE', 'supabase'),
|
|
33
|
+
createAgentsServerEnvVariable('PTBK_AGENTS_SERVER_SQLITE_PATH', '.promptbook/agents-server.sqlite'),
|
|
32
34
|
createAgentsServerEnvVariable('OPENAI_API_KEY', ''),
|
|
33
35
|
createAgentsServerEnvVariable('POSTGRES_URL', ''),
|
|
34
36
|
createAgentsServerEnvVariable('NEXT_PUBLIC_SUPABASE_URL', ''),
|
|
@@ -23,6 +23,20 @@ import { ensureAgentsServerBuild, resolveAgentsServerAppPath } from './buildAgen
|
|
|
23
23
|
*/
|
|
24
24
|
const USER_CHAT_JOB_WORKER_POLL_INTERVAL_MS = 2_000;
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Number of identical worker failures suppressed before logging a repeated summary.
|
|
28
|
+
*
|
|
29
|
+
* @private internal constant of `ptbk agents-server`
|
|
30
|
+
*/
|
|
31
|
+
const USER_CHAT_JOB_WORKER_REPEATED_ERROR_LOG_INTERVAL = 10;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Maximum worker response body length shown in foreground diagnostics.
|
|
35
|
+
*
|
|
36
|
+
* @private internal constant of `ptbk agents-server`
|
|
37
|
+
*/
|
|
38
|
+
const USER_CHAT_JOB_WORKER_ERROR_BODY_MAX_LENGTH = 2_000;
|
|
39
|
+
|
|
26
40
|
/**
|
|
27
41
|
* HTTP status used by an idle internal worker tick with no job to process.
|
|
28
42
|
*
|
|
@@ -51,6 +65,20 @@ const AGENTS_SERVER_PROJECT_ENV_FILE_NAME = '.env';
|
|
|
51
65
|
*/
|
|
52
66
|
const PTBK_AGENTS_SERVER_AGENT_ROOT_ENV = 'PTBK_AGENTS_SERVER_AGENT_ROOT';
|
|
53
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Public database mode environment name consumed by the Agents Server app.
|
|
70
|
+
*
|
|
71
|
+
* @private internal constant of `ptbk agents-server`
|
|
72
|
+
*/
|
|
73
|
+
const PTBK_AGENTS_SERVER_DATABASE_ENV = 'PTBK_AGENTS_SERVER_DATABASE';
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Local SQLite file environment name consumed by the Agents Server app.
|
|
77
|
+
*
|
|
78
|
+
* @private internal constant of `ptbk agents-server`
|
|
79
|
+
*/
|
|
80
|
+
const PTBK_AGENTS_SERVER_SQLITE_PATH_ENV = 'PTBK_AGENTS_SERVER_SQLITE_PATH';
|
|
81
|
+
|
|
54
82
|
/**
|
|
55
83
|
* Entropy size for the local-only token shared by the CLI pump and the Next app.
|
|
56
84
|
*
|
|
@@ -114,6 +142,10 @@ type AgentsServerChildEnvironment = NodeJS.ProcessEnv & {
|
|
|
114
142
|
type AgentsServerSupervisorState = {
|
|
115
143
|
isContinuing: boolean;
|
|
116
144
|
uiHandle?: CoderRunUiHandle;
|
|
145
|
+
lastUserChatJobWorkerError?: {
|
|
146
|
+
message: string;
|
|
147
|
+
repeatCount: number;
|
|
148
|
+
};
|
|
117
149
|
nextExit?: {
|
|
118
150
|
code: number | null;
|
|
119
151
|
signal: NodeJS.Signals | null;
|
|
@@ -332,11 +364,17 @@ function forwardChildOutput(
|
|
|
332
364
|
* Creates the subprocess environment for Next and its internal local runner bridge.
|
|
333
365
|
*/
|
|
334
366
|
function createAgentsServerChildEnvironment(port: number_port, agentRootPath: string): AgentsServerChildEnvironment {
|
|
367
|
+
const launchWorkingDirectory = process.cwd();
|
|
368
|
+
|
|
335
369
|
return {
|
|
336
370
|
...process.env,
|
|
337
371
|
PORT: String(port),
|
|
338
372
|
NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL || `http://localhost:${port}`,
|
|
339
373
|
[PTBK_AGENTS_SERVER_AGENT_ROOT_ENV]: agentRootPath,
|
|
374
|
+
[PTBK_AGENTS_SERVER_SQLITE_PATH_ENV]:
|
|
375
|
+
process.env[PTBK_AGENTS_SERVER_SQLITE_PATH_ENV] ||
|
|
376
|
+
join(launchWorkingDirectory, '.promptbook', 'agents-server.sqlite'),
|
|
377
|
+
[PTBK_AGENTS_SERVER_DATABASE_ENV]: process.env[PTBK_AGENTS_SERVER_DATABASE_ENV] || 'supabase',
|
|
340
378
|
// Next loads app-local `.env` values after the CLI has prepared this bridge environment.
|
|
341
379
|
PTBK_AGENTS_SERVER_USER_CHAT_WORKER_TOKEN:
|
|
342
380
|
process.env.PTBK_AGENTS_SERVER_USER_CHAT_WORKER_TOKEN ||
|
|
@@ -380,10 +418,16 @@ function startUserChatJobWorkerPump(options: {
|
|
|
380
418
|
|
|
381
419
|
isTickRunning = true;
|
|
382
420
|
triggerUserChatJobWorkerTick(options)
|
|
421
|
+
.then(() => {
|
|
422
|
+
clearUserChatJobWorkerError(options.state);
|
|
423
|
+
})
|
|
383
424
|
.catch((error) => {
|
|
384
425
|
const message = error instanceof Error ? error.message : String(error);
|
|
385
|
-
|
|
386
|
-
|
|
426
|
+
reportUserChatJobWorkerError({
|
|
427
|
+
logStream: options.logStreams.runner,
|
|
428
|
+
message,
|
|
429
|
+
state: options.state,
|
|
430
|
+
});
|
|
387
431
|
})
|
|
388
432
|
.finally(() => {
|
|
389
433
|
isTickRunning = false;
|
|
@@ -411,10 +455,111 @@ async function triggerUserChatJobWorkerTick(options: {
|
|
|
411
455
|
});
|
|
412
456
|
|
|
413
457
|
if (!response.ok && response.status !== HTTP_NO_CONTENT_STATUS_CODE) {
|
|
414
|
-
|
|
458
|
+
const details = await readUserChatJobWorkerErrorDetails(response);
|
|
459
|
+
throw new Error(createUserChatJobWorkerErrorMessage(response, details));
|
|
415
460
|
}
|
|
416
461
|
}
|
|
417
462
|
|
|
463
|
+
/**
|
|
464
|
+
* Reports worker failures while suppressing identical repeated foreground noise.
|
|
465
|
+
*/
|
|
466
|
+
function reportUserChatJobWorkerError(options: {
|
|
467
|
+
readonly logStream: WriteStream;
|
|
468
|
+
readonly message: string;
|
|
469
|
+
readonly state: AgentsServerSupervisorState;
|
|
470
|
+
}): void {
|
|
471
|
+
const previousError = options.state.lastUserChatJobWorkerError;
|
|
472
|
+
|
|
473
|
+
if (previousError?.message === options.message) {
|
|
474
|
+
const repeatCount = previousError.repeatCount + 1;
|
|
475
|
+
options.state.lastUserChatJobWorkerError = {
|
|
476
|
+
message: options.message,
|
|
477
|
+
repeatCount,
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
if (repeatCount % USER_CHAT_JOB_WORKER_REPEATED_ERROR_LOG_INTERVAL !== 0) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const repeatedMessage = `User chat worker tick is still failing after ${repeatCount} attempts: ${options.message}`;
|
|
485
|
+
logRunnerEvent(options.logStream, repeatedMessage);
|
|
486
|
+
addUiError(options.state, repeatedMessage);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
options.state.lastUserChatJobWorkerError = {
|
|
491
|
+
message: options.message,
|
|
492
|
+
repeatCount: 1,
|
|
493
|
+
};
|
|
494
|
+
logRunnerEvent(options.logStream, `User chat worker tick failed: ${options.message}`);
|
|
495
|
+
addUiError(options.state, options.message);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Resets repeated-error suppression after a successful worker tick.
|
|
500
|
+
*/
|
|
501
|
+
function clearUserChatJobWorkerError(state: AgentsServerSupervisorState): void {
|
|
502
|
+
state.lastUserChatJobWorkerError = undefined;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Reads a worker error payload so foreground logs show the route-level reason.
|
|
507
|
+
*/
|
|
508
|
+
async function readUserChatJobWorkerErrorDetails(response: Response): Promise<string | null> {
|
|
509
|
+
const body = await response.text().catch(() => '');
|
|
510
|
+
const trimmedBody = body.trim();
|
|
511
|
+
|
|
512
|
+
if (!trimmedBody) {
|
|
513
|
+
return null;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
const parsedMessage = parseUserChatJobWorkerErrorMessage(trimmedBody);
|
|
517
|
+
return truncateUserChatJobWorkerErrorDetails(parsedMessage || trimmedBody);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Extracts a readable error message from the worker route JSON response.
|
|
522
|
+
*/
|
|
523
|
+
function parseUserChatJobWorkerErrorMessage(body: string): string | null {
|
|
524
|
+
try {
|
|
525
|
+
const parsedBody = JSON.parse(body) as {
|
|
526
|
+
error?: unknown;
|
|
527
|
+
message?: unknown;
|
|
528
|
+
};
|
|
529
|
+
const errorMessage = typeof parsedBody.error === 'string' ? parsedBody.error : undefined;
|
|
530
|
+
const fallbackMessage = typeof parsedBody.message === 'string' ? parsedBody.message : undefined;
|
|
531
|
+
|
|
532
|
+
return errorMessage || fallbackMessage || null;
|
|
533
|
+
} catch {
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Builds the foreground worker failure message from HTTP status and route details.
|
|
540
|
+
*/
|
|
541
|
+
function createUserChatJobWorkerErrorMessage(response: Response, details: string | null): string {
|
|
542
|
+
const statusText = response.statusText ? ` ${response.statusText}` : '';
|
|
543
|
+
const statusMessage = `${response.status}${statusText}`;
|
|
544
|
+
|
|
545
|
+
if (!details) {
|
|
546
|
+
return `Internal user chat worker returned ${statusMessage}.`;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
return `Internal user chat worker returned ${statusMessage}: ${details}`;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Keeps foreground worker diagnostics bounded when a route returns a large payload.
|
|
554
|
+
*/
|
|
555
|
+
function truncateUserChatJobWorkerErrorDetails(details: string): string {
|
|
556
|
+
if (details.length <= USER_CHAT_JOB_WORKER_ERROR_BODY_MAX_LENGTH) {
|
|
557
|
+
return details;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return `${details.slice(0, USER_CHAT_JOB_WORKER_ERROR_BODY_MAX_LENGTH)}...`;
|
|
561
|
+
}
|
|
562
|
+
|
|
418
563
|
/**
|
|
419
564
|
* Creates file streams for service output persisted below `./logs`.
|
|
420
565
|
*/
|