@promptbook/cli 0.112.0-133 → 0.112.0-134
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/src/app/agents/[agentName]/api/book/route.ts +2 -0
- package/apps/agents-server/src/app/api/agents/[agentName]/route.ts +5 -0
- package/apps/agents-server/src/app/api/v1/agents/[agentId]/route.ts +4 -0
- package/apps/agents-server/src/app/api/v1/agents/route.ts +2 -0
- package/apps/agents-server/src/app/recycle-bin/actions.ts +3 -0
- package/apps/agents-server/src/database/migrations/2026-06-2600-agent-directory-performance-indexes.sql +14 -0
- package/apps/agents-server/src/database/sqlite/$provideLocalSqliteSupabase.ts +92 -1
- package/apps/agents-server/src/utils/userChat/listUserChats.ts +5 -1
- package/esm/index.es.js +1 -1
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/other/templates/getTemplatesPipelineCollection.ts +1039 -789
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/index.umd.js +1 -1
- package/umd/src/version.d.ts +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
2
2
|
import { $provideAgentReferenceResolver } from '@/src/utils/agentReferenceResolver/$provideAgentReferenceResolver';
|
|
3
|
+
import { invalidateCachedActiveOrganizationSnapshots } from '@/src/utils/agentOrganization/loadAgentOrganizationState';
|
|
3
4
|
import {
|
|
4
5
|
parseBookScopedAgentIdentifier,
|
|
5
6
|
resolveBookScopedAgentContext,
|
|
@@ -172,6 +173,7 @@ export async function PUT(request: Request, { params }: { params: Promise<{ agen
|
|
|
172
173
|
|
|
173
174
|
const agentId = await collection.getAgentPermanentId(agentName);
|
|
174
175
|
await collection.updateAgentSource(agentId, agentSource, { versionName });
|
|
176
|
+
invalidateCachedActiveOrganizationSnapshots();
|
|
175
177
|
// <- TODO: [🐱🚀] Properly type as string_book
|
|
176
178
|
|
|
177
179
|
return new Response(
|
|
@@ -12,6 +12,7 @@ import { NextResponse } from 'next/server';
|
|
|
12
12
|
import { buildAgentNameOrIdFilter } from '@/src/utils/agentIdentifier';
|
|
13
13
|
import { getCurrentUser } from '@/src/utils/getCurrentUser';
|
|
14
14
|
import { resolveServerAgentContext } from '@/src/utils/resolveServerAgentContext';
|
|
15
|
+
import { invalidateCachedActiveOrganizationSnapshots } from '@/src/utils/agentOrganization/loadAgentOrganizationState';
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Handles patch.
|
|
@@ -45,6 +46,7 @@ export async function PATCH(request: Request, { params }: { params: Promise<{ ag
|
|
|
45
46
|
localServerUrl: new URL(request.url).origin,
|
|
46
47
|
fallbackResolver: baseAgentReferenceResolver,
|
|
47
48
|
});
|
|
49
|
+
invalidateCachedActiveOrganizationSnapshots();
|
|
48
50
|
|
|
49
51
|
return NextResponse.json({
|
|
50
52
|
success: true,
|
|
@@ -74,6 +76,8 @@ export async function PATCH(request: Request, { params }: { params: Promise<{ ag
|
|
|
74
76
|
return NextResponse.json({ success: false, error: updateResult.error.message }, { status: 500 });
|
|
75
77
|
}
|
|
76
78
|
|
|
79
|
+
invalidateCachedActiveOrganizationSnapshots();
|
|
80
|
+
|
|
77
81
|
return NextResponse.json({ success: true });
|
|
78
82
|
} catch (error) {
|
|
79
83
|
return NextResponse.json(
|
|
@@ -97,6 +101,7 @@ export async function DELETE(request: Request, { params }: { params: Promise<{ a
|
|
|
97
101
|
|
|
98
102
|
const agentId = await collection.getAgentPermanentId(agentName);
|
|
99
103
|
await collection.deleteAgent(agentId);
|
|
104
|
+
invalidateCachedActiveOrganizationSnapshots();
|
|
100
105
|
return NextResponse.json({ success: true });
|
|
101
106
|
} catch (error) {
|
|
102
107
|
return NextResponse.json(
|
|
@@ -6,6 +6,7 @@ import { $getTableName } from '@/src/database/$getTableName';
|
|
|
6
6
|
import { $provideSupabaseForServer } from '@/src/database/$provideSupabaseForServer';
|
|
7
7
|
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
8
8
|
import { $provideServer } from '@/src/tools/$provideServer';
|
|
9
|
+
import { invalidateCachedActiveOrganizationSnapshots } from '@/src/utils/agentOrganization/loadAgentOrganizationState';
|
|
9
10
|
import { findOwnedAgentByIdentifier, findOwnedFolderById, type OwnedAgentRow } from '@/src/utils/agentOwnership';
|
|
10
11
|
import {
|
|
11
12
|
getNextOwnedAgentSortOrder,
|
|
@@ -155,6 +156,8 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
|
|
|
155
156
|
return metadataUpdateResponse;
|
|
156
157
|
}
|
|
157
158
|
|
|
159
|
+
invalidateCachedActiveOrganizationSnapshots();
|
|
160
|
+
|
|
158
161
|
return createUpdatedOwnedAgentResponse(request, identityResult.identity.userId, existingAgent);
|
|
159
162
|
} catch (error) {
|
|
160
163
|
return mapOwnedAgentLookupErrorToResponse(request, error);
|
|
@@ -192,6 +195,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise
|
|
|
192
195
|
|
|
193
196
|
const collection = await $provideAgentCollectionForServer();
|
|
194
197
|
await collection.deleteAgent(existingAgent.permanentId || existingAgent.agentName);
|
|
198
|
+
invalidateCachedActiveOrganizationSnapshots();
|
|
195
199
|
|
|
196
200
|
return createManagementApiJsonResponse(request, { success: true });
|
|
197
201
|
} catch (error) {
|
|
@@ -4,6 +4,7 @@ import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentColle
|
|
|
4
4
|
import { $provideServer } from '@/src/tools/$provideServer';
|
|
5
5
|
import { findOwnedFolderById, findOwnedAgentByIdentifier } from '@/src/utils/agentOwnership';
|
|
6
6
|
import { createAgentWithDefaultVisibility } from '@/src/utils/createAgentWithDefaultVisibility';
|
|
7
|
+
import { invalidateCachedActiveOrganizationSnapshots } from '@/src/utils/agentOrganization/loadAgentOrganizationState';
|
|
7
8
|
import {
|
|
8
9
|
searchOwnedAgents,
|
|
9
10
|
getNextOwnedAgentSortOrder,
|
|
@@ -141,6 +142,7 @@ export async function POST(request: NextRequest) {
|
|
|
141
142
|
sortOrder,
|
|
142
143
|
userId: identityResult.identity.userId,
|
|
143
144
|
});
|
|
145
|
+
invalidateCachedActiveOrganizationSnapshots();
|
|
144
146
|
const persistedRow = await findOwnedAgentByIdentifier(identityResult.identity.userId, createdAgent.permanentId);
|
|
145
147
|
|
|
146
148
|
if (!persistedRow) {
|
|
@@ -4,6 +4,7 @@ import { restoreAgentAndFolders } from '@/src/utils/agentOrganization/restoreAge
|
|
|
4
4
|
import { revalidatePath } from 'next/cache';
|
|
5
5
|
import { isUserAdmin } from '../../utils/isUserAdmin';
|
|
6
6
|
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
7
|
+
import { invalidateCachedActiveOrganizationSnapshots } from '@/src/utils/agentOrganization/loadAgentOrganizationState';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Restores a deleted agent from the recycle bin.
|
|
@@ -16,6 +17,7 @@ export async function restoreDeletedAgent(agentName: string) {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
await restoreAgentAndFolders(agentName);
|
|
20
|
+
invalidateCachedActiveOrganizationSnapshots();
|
|
19
21
|
|
|
20
22
|
revalidatePath('/recycle-bin');
|
|
21
23
|
revalidatePath(`/agents/${agentName}`);
|
|
@@ -35,6 +37,7 @@ export async function deleteAgent(agentName: string) {
|
|
|
35
37
|
const collection = await $provideAgentCollectionForServer();
|
|
36
38
|
|
|
37
39
|
await collection.deleteAgent(agentName);
|
|
40
|
+
invalidateCachedActiveOrganizationSnapshots();
|
|
38
41
|
|
|
39
42
|
revalidatePath('/recycle-bin');
|
|
40
43
|
revalidatePath(`/agents/${agentName}`);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
CREATE INDEX IF NOT EXISTS "prefix_Agent_deletedAt_sortOrder_agentName_idx"
|
|
2
|
+
ON "prefix_Agent" ("deletedAt", "sortOrder", "agentName");
|
|
3
|
+
|
|
4
|
+
CREATE INDEX IF NOT EXISTS "prefix_Agent_visibility_deletedAt_sortOrder_agentName_idx"
|
|
5
|
+
ON "prefix_Agent" ("visibility", "deletedAt", "sortOrder", "agentName");
|
|
6
|
+
|
|
7
|
+
CREATE INDEX IF NOT EXISTS "prefix_AgentFolder_deletedAt_parentId_sortOrder_name_idx"
|
|
8
|
+
ON "prefix_AgentFolder" ("deletedAt", "parentId", "sortOrder", "name");
|
|
9
|
+
|
|
10
|
+
CREATE INDEX IF NOT EXISTS "prefix_UserChat_userId_agentPermanentId_source_createdAt_idx"
|
|
11
|
+
ON "prefix_UserChat" ("userId", "agentPermanentId", "source", "createdAt" DESC);
|
|
12
|
+
|
|
13
|
+
CREATE INDEX IF NOT EXISTS "prefix_UserChat_agentPermanentId_source_userId_createdAt_idx"
|
|
14
|
+
ON "prefix_UserChat" ("agentPermanentId", "source", "userId", "createdAt" DESC);
|
|
@@ -65,6 +65,14 @@ type LocalSqliteUpsertOptions = {
|
|
|
65
65
|
readonly onConflict?: string;
|
|
66
66
|
};
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Read index definition for hot SQLite queries.
|
|
70
|
+
*/
|
|
71
|
+
type LocalSqliteReadIndex = {
|
|
72
|
+
readonly name: string;
|
|
73
|
+
readonly columns: ReadonlyArray<string>;
|
|
74
|
+
};
|
|
75
|
+
|
|
68
76
|
/**
|
|
69
77
|
* Columns whose values are persisted as JSON text in local SQLite.
|
|
70
78
|
*/
|
|
@@ -141,6 +149,51 @@ const UNIQUE_INDEX_COLUMNS_BY_TABLE = new Map<string, ReadonlyArray<ReadonlyArra
|
|
|
141
149
|
['UserPushSubscription', [['endpoint']]],
|
|
142
150
|
]);
|
|
143
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Non-unique indexes for frequent standalone VPS reads.
|
|
154
|
+
*/
|
|
155
|
+
const READ_INDEXES_BY_TABLE = new Map<string, ReadonlyArray<LocalSqliteReadIndex>>([
|
|
156
|
+
[
|
|
157
|
+
'Agent',
|
|
158
|
+
[
|
|
159
|
+
{ name: 'agentName_lookup', columns: ['agentName'] },
|
|
160
|
+
{ name: 'active_directory', columns: ['deletedAt', 'sortOrder', 'agentName'] },
|
|
161
|
+
{ name: 'public_active_directory', columns: ['visibility', 'deletedAt', 'sortOrder', 'agentName'] },
|
|
162
|
+
],
|
|
163
|
+
],
|
|
164
|
+
[
|
|
165
|
+
'AgentFolder',
|
|
166
|
+
[{ name: 'active_directory', columns: ['deletedAt', 'parentId', 'sortOrder', 'name'] }],
|
|
167
|
+
],
|
|
168
|
+
[
|
|
169
|
+
'UserChat',
|
|
170
|
+
[
|
|
171
|
+
{ name: 'user_agent_source_createdAt', columns: ['userId', 'agentPermanentId', 'source', 'createdAt'] },
|
|
172
|
+
{ name: 'agent_source_user_createdAt', columns: ['agentPermanentId', 'source', 'userId', 'createdAt'] },
|
|
173
|
+
],
|
|
174
|
+
],
|
|
175
|
+
[
|
|
176
|
+
'UserChatJob',
|
|
177
|
+
[
|
|
178
|
+
{ name: 'ready_queue', columns: ['status', 'cancelRequestedAt', 'queuedAt', 'createdAt'] },
|
|
179
|
+
{ name: 'active_chat_scope', columns: ['chatId', 'userId', 'agentPermanentId', 'status', 'createdAt'] },
|
|
180
|
+
{ name: 'agent_chat_status', columns: ['agentPermanentId', 'chatId', 'status'] },
|
|
181
|
+
{ name: 'running_lease', columns: ['status', 'leaseExpiresAt'] },
|
|
182
|
+
],
|
|
183
|
+
],
|
|
184
|
+
[
|
|
185
|
+
'UserChatTimeout',
|
|
186
|
+
[
|
|
187
|
+
{ name: 'ready_due', columns: ['status', 'cancelRequestedAt', 'pausedAt', 'dueAt', 'createdAt'] },
|
|
188
|
+
{
|
|
189
|
+
name: 'active_chat_scope',
|
|
190
|
+
columns: ['chatId', 'userId', 'agentPermanentId', 'status', 'pausedAt', 'dueAt', 'createdAt'],
|
|
191
|
+
},
|
|
192
|
+
{ name: 'running_lease', columns: ['status', 'leaseExpiresAt'] },
|
|
193
|
+
],
|
|
194
|
+
],
|
|
195
|
+
]);
|
|
196
|
+
|
|
144
197
|
/**
|
|
145
198
|
* Known unique conflict columns used when `.upsert` omits `onConflict`.
|
|
146
199
|
*/
|
|
@@ -179,6 +232,20 @@ export function $resetLocalSqliteSupabaseForTests(): void {
|
|
|
179
232
|
localSqliteSupabase = null;
|
|
180
233
|
}
|
|
181
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Ensures read indexes for a table that is queried through direct SQLite SQL.
|
|
237
|
+
*
|
|
238
|
+
* @param tableName - Actual table name, including any server prefix.
|
|
239
|
+
*
|
|
240
|
+
* @private internal SQLite utility of Agents Server
|
|
241
|
+
*/
|
|
242
|
+
export function ensureLocalSqliteTableReadIndexes(tableName: string): void {
|
|
243
|
+
const database = $provideAgentsServerSqliteDatabase();
|
|
244
|
+
const tableBaseName = resolveTableBaseName(tableName);
|
|
245
|
+
|
|
246
|
+
ensureTable(database, tableName, resolveReadIndexColumns(tableBaseName));
|
|
247
|
+
}
|
|
248
|
+
|
|
182
249
|
/**
|
|
183
250
|
* Supabase-shaped client with only the table query surface used by Agents Server.
|
|
184
251
|
*/
|
|
@@ -836,8 +903,9 @@ function ensureTable(
|
|
|
836
903
|
const columnsToEnsure = uniqueStrings([...requiredColumns, ...resolveUniqueIndexColumns(tableBaseName)]).filter(
|
|
837
904
|
(column) => column !== '*' && column !== 'id',
|
|
838
905
|
);
|
|
906
|
+
const columnsToEnsureWithIndexes = uniqueStrings([...columnsToEnsure, ...resolveReadIndexColumns(tableBaseName)]);
|
|
839
907
|
|
|
840
|
-
for (const column of
|
|
908
|
+
for (const column of columnsToEnsureWithIndexes) {
|
|
841
909
|
if (existingColumns.has(column)) {
|
|
842
910
|
continue;
|
|
843
911
|
}
|
|
@@ -852,6 +920,7 @@ function ensureTable(
|
|
|
852
920
|
}
|
|
853
921
|
|
|
854
922
|
ensureUniqueIndexes(database, tableName, tableBaseName);
|
|
923
|
+
ensureReadIndexes(database, tableName, tableBaseName);
|
|
855
924
|
}
|
|
856
925
|
|
|
857
926
|
/**
|
|
@@ -871,6 +940,21 @@ function ensureUniqueIndexes(database: AgentsServerSqliteDatabase, tableName: st
|
|
|
871
940
|
}
|
|
872
941
|
}
|
|
873
942
|
|
|
943
|
+
/**
|
|
944
|
+
* Creates known read indexes after required columns exist.
|
|
945
|
+
*/
|
|
946
|
+
function ensureReadIndexes(database: AgentsServerSqliteDatabase, tableName: string, tableBaseName: string): void {
|
|
947
|
+
const readIndexes = READ_INDEXES_BY_TABLE.get(tableBaseName) || [];
|
|
948
|
+
|
|
949
|
+
for (const readIndex of readIndexes) {
|
|
950
|
+
const indexName = `index_${sanitizeSqlIdentifier(tableName)}_${sanitizeSqlIdentifier(readIndex.name)}`;
|
|
951
|
+
const columnSql = readIndex.columns.map(quoteIdentifier).join(', ');
|
|
952
|
+
database.exec(
|
|
953
|
+
`CREATE INDEX IF NOT EXISTS ${quoteIdentifier(indexName)} ON ${quoteIdentifier(tableName)} (${columnSql})`,
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
874
958
|
/**
|
|
875
959
|
* Inserts one row into the table.
|
|
876
960
|
*/
|
|
@@ -1441,6 +1525,13 @@ function resolveUniqueIndexColumns(tableBaseName: string): Array<string> {
|
|
|
1441
1525
|
return (UNIQUE_INDEX_COLUMNS_BY_TABLE.get(tableBaseName) || []).flatMap((columns) => [...columns]);
|
|
1442
1526
|
}
|
|
1443
1527
|
|
|
1528
|
+
/**
|
|
1529
|
+
* Resolves columns participating in known read indexes.
|
|
1530
|
+
*/
|
|
1531
|
+
function resolveReadIndexColumns(tableBaseName: string): Array<string> {
|
|
1532
|
+
return (READ_INDEXES_BY_TABLE.get(tableBaseName) || []).flatMap((readIndex) => [...readIndex.columns]);
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1444
1535
|
/**
|
|
1445
1536
|
* Resolves upsert conflict columns.
|
|
1446
1537
|
*/
|
|
@@ -2,6 +2,7 @@ import { $getTableName } from '@/src/database/$getTableName';
|
|
|
2
2
|
import { $provideClientSql } from '@/src/database/$provideClientSql';
|
|
3
3
|
import { isAgentsServerSqliteMode } from '@/src/database/agentsServerDatabaseMode';
|
|
4
4
|
import { $provideAgentsServerSqliteDatabase } from '@/src/database/sqlite/$provideAgentsServerSqliteDatabase';
|
|
5
|
+
import { ensureLocalSqliteTableReadIndexes } from '@/src/database/sqlite/$provideLocalSqliteSupabase';
|
|
5
6
|
import type { ListUserChatsOptions, UserChatRecord } from './UserChatRecord';
|
|
6
7
|
import type { UserChatSource } from './UserChatSource';
|
|
7
8
|
import type { UserChatRow } from './UserChatRow';
|
|
@@ -168,7 +169,10 @@ export async function listUserChatSummarySeeds(options: ListUserChatsOptions): P
|
|
|
168
169
|
* @private function of `userChat`
|
|
169
170
|
*/
|
|
170
171
|
async function listUserChatSummarySeedsViaSqlite(options: ListUserChatsOptions): Promise<Array<UserChatSummarySeed>> {
|
|
171
|
-
const
|
|
172
|
+
const rawUserChatTableName = await $getTableName('UserChat');
|
|
173
|
+
ensureLocalSqliteTableReadIndexes(rawUserChatTableName);
|
|
174
|
+
|
|
175
|
+
const userChatTableName = quoteIdentifier(rawUserChatTableName);
|
|
172
176
|
const shouldLoadExternalChats = options.viewerIsAdmin && options.includeExternalChats;
|
|
173
177
|
const whereClause = shouldLoadExternalChats
|
|
174
178
|
? `
|
package/esm/index.es.js
CHANGED
|
@@ -59,7 +59,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
59
59
|
* @generated
|
|
60
60
|
* @see https://github.com/webgptorg/promptbook
|
|
61
61
|
*/
|
|
62
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
62
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-134';
|
|
63
63
|
/**
|
|
64
64
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
65
65
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
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-133`).
|
|
19
19
|
*
|
|
20
20
|
* @generated
|
|
21
21
|
*/
|
package/package.json
CHANGED