@promptbook/cli 0.112.0-106 → 0.112.0-108

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.
@@ -90,6 +90,17 @@ const JSON_COLUMNS_BY_TABLE = new Map<string, ReadonlySet<string>>([
90
90
  ['ShibbolethAuthenticationAttempt', new Set(['rawAttributes'])],
91
91
  ]);
92
92
 
93
+ /**
94
+ * Columns that must always be surfaced as strings even when an older SQLite
95
+ * table was created with numeric affinity.
96
+ */
97
+ const TEXT_COLUMNS_BY_TABLE = new Map<string, ReadonlySet<string>>([['Metadata', new Set(['key', 'value', 'note'])]]);
98
+
99
+ /**
100
+ * Table-specific integer columns whose names would otherwise be ambiguous.
101
+ */
102
+ const INTEGER_COLUMNS_BY_TABLE = new Map<string, ReadonlySet<string>>([['ServerLimit', new Set(['value'])]]);
103
+
93
104
  /**
94
105
  * Boolean columns stored as integers by SQLite and restored as booleans.
95
106
  */
@@ -833,6 +844,7 @@ function ensureTable(
833
844
 
834
845
  database.exec(
835
846
  `ALTER TABLE ${quoteIdentifier(tableName)} ADD COLUMN ${quoteIdentifier(column)} ${resolveSqliteColumnType(
847
+ tableBaseName,
836
848
  column,
837
849
  )}`,
838
850
  );
@@ -1294,6 +1306,9 @@ function serializeValue(tableName: string, column: string, value: unknown): unkn
1294
1306
  if (value === null) {
1295
1307
  return null;
1296
1308
  }
1309
+ if (isTextColumn(tableName, column)) {
1310
+ return String(value);
1311
+ }
1297
1312
  if (isJsonColumn(tableName, column)) {
1298
1313
  return typeof value === 'string' ? value : JSON.stringify(value);
1299
1314
  }
@@ -1312,6 +1327,8 @@ function deserializeRow(tableName: string, row: Record<string, unknown>): Record
1312
1327
  for (const [column, value] of Object.entries(row)) {
1313
1328
  if (value === null || value === undefined) {
1314
1329
  result[column] = null;
1330
+ } else if (isTextColumn(tableName, column)) {
1331
+ result[column] = String(value);
1315
1332
  } else if (isJsonColumn(tableName, column) && typeof value === 'string') {
1316
1333
  result[column] = parseJsonValue(value);
1317
1334
  } else if (BOOLEAN_COLUMNS.has(column)) {
@@ -1339,16 +1356,50 @@ function parseJsonValue(value: string): unknown {
1339
1356
  * Resolves whether a column is JSON for a specific table.
1340
1357
  */
1341
1358
  function isJsonColumn(tableName: string, column: string): boolean {
1342
- return JSON_COLUMNS_BY_TABLE.get(resolveTableBaseName(tableName))?.has(column) || false;
1359
+ return isJsonColumnForTableBaseName(resolveTableBaseName(tableName), column);
1360
+ }
1361
+
1362
+ /**
1363
+ * Resolves whether a column is JSON for a specific table base name.
1364
+ */
1365
+ function isJsonColumnForTableBaseName(tableBaseName: string, column: string): boolean {
1366
+ return JSON_COLUMNS_BY_TABLE.get(tableBaseName)?.has(column) || false;
1367
+ }
1368
+
1369
+ /**
1370
+ * Resolves whether a column should be forced to a string for a specific table.
1371
+ */
1372
+ function isTextColumn(tableName: string, column: string): boolean {
1373
+ return isTextColumnForTableBaseName(resolveTableBaseName(tableName), column);
1374
+ }
1375
+
1376
+ /**
1377
+ * Resolves whether a column should be forced to a string for a specific table base name.
1378
+ */
1379
+ function isTextColumnForTableBaseName(tableBaseName: string, column: string): boolean {
1380
+ return TEXT_COLUMNS_BY_TABLE.get(tableBaseName)?.has(column) || false;
1381
+ }
1382
+
1383
+ /**
1384
+ * Resolves whether a column is known to be numeric for a specific table base name.
1385
+ */
1386
+ function isIntegerColumnForTableBaseName(tableBaseName: string, column: string): boolean {
1387
+ return INTEGER_COLUMNS_BY_TABLE.get(tableBaseName)?.has(column) || false;
1343
1388
  }
1344
1389
 
1345
1390
  /**
1346
1391
  * Resolves SQLite column affinity for dynamically added columns.
1347
1392
  */
1348
- function resolveSqliteColumnType(column: string): string {
1393
+ function resolveSqliteColumnType(tableBaseName: string, column: string): string {
1394
+ if (isTextColumnForTableBaseName(tableBaseName, column) || isJsonColumnForTableBaseName(tableBaseName, column)) {
1395
+ return 'TEXT';
1396
+ }
1349
1397
  if (BOOLEAN_COLUMNS.has(column)) {
1350
1398
  return 'INTEGER';
1351
1399
  }
1400
+ if (isIntegerColumnForTableBaseName(tableBaseName, column)) {
1401
+ return 'INTEGER';
1402
+ }
1352
1403
  if (
1353
1404
  column === 'id' ||
1354
1405
  column.endsWith('Id') ||
@@ -1357,8 +1408,7 @@ function resolveSqliteColumnType(column: string): string {
1357
1408
  column.endsWith('Bytes') ||
1358
1409
  column === 'sortOrder' ||
1359
1410
  column === 'attemptCount' ||
1360
- column === 'runCount' ||
1361
- column === 'value'
1411
+ column === 'runCount'
1362
1412
  ) {
1363
1413
  return 'INTEGER';
1364
1414
  }
package/esm/index.es.js CHANGED
@@ -58,7 +58,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
58
58
  * @generated
59
59
  * @see https://github.com/webgptorg/promptbook
60
60
  */
61
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-106';
61
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-108';
62
62
  /**
63
63
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
64
64
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -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-105`).
18
+ * It follows semantic versioning (e.g., `0.112.0-107`).
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-106",
3
+ "version": "0.112.0-108",
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,