@promptbook/cli 0.112.0-134 → 0.112.0-136

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.
Files changed (94) hide show
  1. package/apps/agents-server/README.md +0 -1
  2. package/apps/agents-server/src/app/admin/chat-feedback/page.tsx +2 -4
  3. package/apps/agents-server/src/app/admin/chat-history/page.tsx +2 -4
  4. package/apps/agents-server/src/app/admin/metadata/MetadataClient.tsx +246 -15
  5. package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +237 -4
  6. package/apps/agents-server/src/app/api/admin/update/log/route.ts +42 -0
  7. package/apps/agents-server/src/app/api/agents/[agentName]/route.ts +28 -9
  8. package/apps/agents-server/src/app/api/agents/export/route.ts +41 -0
  9. package/apps/agents-server/src/app/api/agents/import/route.ts +168 -0
  10. package/apps/agents-server/src/app/api/chat/route.ts +29 -7
  11. package/apps/agents-server/src/app/api/chat-feedback/export/route.ts +2 -2
  12. package/apps/agents-server/src/app/api/chat-feedback/route.ts +3 -3
  13. package/apps/agents-server/src/app/api/chat-history/[id]/route.ts +2 -2
  14. package/apps/agents-server/src/app/api/chat-history/export/route.ts +2 -2
  15. package/apps/agents-server/src/app/api/chat-history/route.ts +3 -3
  16. package/apps/agents-server/src/app/api/chat-streaming/route.ts +29 -0
  17. package/apps/agents-server/src/app/api/elevenlabs/tts/route.ts +60 -2
  18. package/apps/agents-server/src/app/api/federated-agents/route.ts +1 -1
  19. package/apps/agents-server/src/app/api/images/[filename]/route.ts +102 -0
  20. package/apps/agents-server/src/app/api/metadata/export/route.ts +34 -0
  21. package/apps/agents-server/src/app/api/metadata/import/route.ts +46 -0
  22. package/apps/agents-server/src/app/api/openai/v1/audio/transcriptions/route.ts +111 -2
  23. package/apps/agents-server/src/app/api/page-preview/check/route.ts +18 -0
  24. package/apps/agents-server/src/app/api/page-preview/screenshot/route.ts +15 -8
  25. package/apps/agents-server/src/app/api/team-agent-profile/route.ts +20 -0
  26. package/apps/agents-server/src/app/layout.tsx +1 -1
  27. package/apps/agents-server/src/components/AgentContextMenu/useAgentContextMenuItems.ts +27 -19
  28. package/apps/agents-server/src/components/Homepage/AgentsList.tsx +31 -1
  29. package/apps/agents-server/src/components/Homepage/AgentsListHeader.tsx +60 -1
  30. package/apps/agents-server/src/components/Homepage/useAgentsListImportExportState.ts +523 -0
  31. package/apps/agents-server/src/components/Homepage/useAgentsListState.ts +16 -0
  32. package/apps/agents-server/src/constants/defaultAgentAvatarVisual.ts +1 -1
  33. package/apps/agents-server/src/database/metadataDefaults.ts +0 -21
  34. package/apps/agents-server/src/database/migrations/2026-06-2700-default-agent-avatar-visual-octopus3d4.sql +16 -0
  35. package/apps/agents-server/src/database/seedCoreAgents.ts +235 -0
  36. package/apps/agents-server/src/database/seedDefaultAgents.ts +32 -1
  37. package/apps/agents-server/src/search/createDefaultServerSearchProviders/createFederatedAgentsSearchProvider.ts +1 -1
  38. package/apps/agents-server/src/tools/$provideAgentCollectionForServer.ts +2 -9
  39. package/apps/agents-server/src/utils/agentOwnership.ts +54 -5
  40. package/apps/agents-server/src/utils/agentsTransfer/createAgentsExportZipStream.ts +68 -0
  41. package/apps/agents-server/src/utils/agentsTransfer/importAgentsFromFiles.ts +852 -0
  42. package/apps/agents-server/src/utils/backup/createBooksBackupZipStream.ts +15 -2
  43. package/apps/agents-server/src/utils/defaultAgents/loadDefaultAgentBooks.ts +46 -4
  44. package/apps/agents-server/src/utils/findAgentForCallerWriteAccess.ts +36 -0
  45. package/apps/agents-server/src/utils/getFederatedServers.ts +3 -74
  46. package/apps/agents-server/src/utils/getWellKnownAgentUrl.ts +10 -4
  47. package/apps/agents-server/src/utils/metadataConfigurationTransfer.ts +426 -0
  48. package/apps/agents-server/src/utils/paidApiRequestGuard.ts +241 -0
  49. package/apps/agents-server/src/utils/serverManagement/createManagedServer/bootstrapManagedServer.ts +2 -5
  50. package/apps/agents-server/src/utils/serverManagement/createManagedServer/seedServerCoreAgents.ts +162 -0
  51. package/apps/agents-server/src/utils/userChat/createRunUserChatJobExecutionContext.ts +36 -8
  52. package/apps/agents-server/src/utils/userChat/persistUserChatJobProgressCard.ts +11 -2
  53. package/apps/agents-server/src/utils/userChat/resolveUserChatProgressToolHighlights.ts +100 -0
  54. package/apps/agents-server/src/utils/userChat/runUserChatJob.ts +4 -3
  55. package/apps/agents-server/src/utils/userChat/userChatProgressCard.ts +272 -27
  56. package/apps/agents-server/src/utils/validateApiKey.ts +7 -3
  57. package/apps/agents-server/src/utils/vpsSelfUpdate.ts +110 -0
  58. package/esm/index.es.js +795 -39
  59. package/esm/index.es.js.map +1 -1
  60. package/esm/src/_packages/core.index.d.ts +0 -2
  61. package/esm/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
  62. package/esm/src/avatars/visuals/octopus3d4AvatarVisual.d.ts +7 -0
  63. package/esm/src/utils/validators/url/isValidAgentUrl.d.ts +5 -0
  64. package/esm/src/version.d.ts +1 -1
  65. package/package.json +1 -1
  66. package/servers.ts +1 -16
  67. package/src/_packages/core.index.ts +0 -2
  68. package/src/avatars/types/AvatarVisualDefinition.ts +1 -0
  69. package/src/avatars/visuals/avatarVisualRegistry.ts +2 -0
  70. package/src/avatars/visuals/octopus3d4AvatarVisual.ts +1295 -0
  71. package/src/other/templates/getTemplatesPipelineCollection.ts +762 -883
  72. package/src/utils/agents/resolveAgentAvatarImageUrl.ts +1 -1
  73. package/src/utils/validators/url/isValidAgentUrl.ts +5 -7
  74. package/src/version.ts +2 -2
  75. package/src/versions.txt +2 -1
  76. package/umd/index.umd.js +795 -39
  77. package/umd/index.umd.js.map +1 -1
  78. package/umd/src/_packages/core.index.d.ts +0 -2
  79. package/umd/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
  80. package/umd/src/avatars/visuals/octopus3d4AvatarVisual.d.ts +7 -0
  81. package/umd/src/utils/validators/url/isValidAgentUrl.d.ts +5 -0
  82. package/umd/src/version.d.ts +1 -1
  83. package/apps/agents-server/src/utils/defaultFederatedAgents/DefaultFederatedAgentsSyncOptions.ts +0 -9
  84. package/apps/agents-server/src/utils/defaultFederatedAgents/ensureDefaultFederatedAgentExists.ts +0 -277
  85. package/apps/agents-server/src/utils/defaultFederatedAgents/fetchCoreOrganizationPayload.ts +0 -39
  86. package/apps/agents-server/src/utils/defaultFederatedAgents/fetchFederatedAgentBook.ts +0 -43
  87. package/apps/agents-server/src/utils/defaultFederatedAgents/fetchWithDefaultFederatedAgentTimeout.ts +0 -28
  88. package/apps/agents-server/src/utils/defaultFederatedAgents/getDefaultFederatedAgentSyncPool.ts +0 -38
  89. package/apps/agents-server/src/utils/defaultFederatedAgents/loadActiveLocalAgentIdsByNormalizedName.ts +0 -41
  90. package/apps/agents-server/src/utils/defaultFederatedAgents/loadDefaultFederatedAgentSyncMetadata.ts +0 -76
  91. package/apps/agents-server/src/utils/defaultFederatedAgents/quoteIdentifier.ts +0 -11
  92. package/apps/agents-server/src/utils/defaultFederatedAgents/scheduleDefaultFederatedAgentsSync.ts +0 -88
  93. package/apps/agents-server/src/utils/defaultFederatedAgents/selectDefaultFederatedAgentsFromOrganizationPayload.ts +0 -181
  94. package/apps/agents-server/src/utils/defaultFederatedAgents/synchronizeDefaultFederatedAgents.ts +0 -77
@@ -221,7 +221,6 @@ import { normalizeChatAttachments } from '../utils/chat/chatAttachments/normaliz
221
221
  import { resolveChatAttachmentContents } from '../utils/chat/chatAttachments/resolveChatAttachmentContents';
222
222
  import { aboutPromptbookInformation } from '../utils/misc/aboutPromptbookInformation';
223
223
  import { $generateBookBoilerplate } from '../utils/random/$generateBookBoilerplate';
224
- import { CORE_AGENTS_SERVER } from '../../servers';
225
224
  import { CORE_AGENTS_SERVER_WELL_KNOWN_AGENT_NAMES } from '../../servers';
226
225
  import { PUBLIC_AGENTS_SERVERS } from '../../servers';
227
226
  export { BOOK_LANGUAGE_VERSION, PROMPTBOOK_ENGINE_VERSION };
@@ -447,6 +446,5 @@ export { normalizeChatAttachments };
447
446
  export { resolveChatAttachmentContents };
448
447
  export { aboutPromptbookInformation };
449
448
  export { $generateBookBoilerplate };
450
- export { CORE_AGENTS_SERVER };
451
449
  export { CORE_AGENTS_SERVER_WELL_KNOWN_AGENT_NAMES };
452
450
  export { PUBLIC_AGENTS_SERVERS };
@@ -7,7 +7,7 @@ import type { AvatarDefinition } from './AvatarDefinition';
7
7
  *
8
8
  * @private shared contract for the avatar rendering system
9
9
  */
10
- export type AvatarVisualId = 'pixel-art' | 'octopus' | 'octopus2' | 'octopus3' | 'octopus3d' | 'octopus3d2' | 'octopus3d3' | 'ascii-octopus' | 'minecraft' | 'minecraft2' | 'fractal' | 'orb';
10
+ export type AvatarVisualId = 'pixel-art' | 'octopus' | 'octopus2' | 'octopus3' | 'octopus3d' | 'octopus3d2' | 'octopus3d3' | 'octopus3d4' | 'ascii-octopus' | 'minecraft' | 'minecraft2' | 'fractal' | 'orb';
11
11
  /**
12
12
  * Derived color palette used by avatar visuals.
13
13
  *
@@ -0,0 +1,7 @@
1
+ import type { AvatarVisualDefinition } from '../types/AvatarVisualDefinition';
2
+ /**
3
+ * Octopus 3D 4 avatar visual.
4
+ *
5
+ * @private built-in avatar visual
6
+ */
7
+ export declare const octopus3d4AvatarVisual: AvatarVisualDefinition;
@@ -8,6 +8,11 @@ import type { really_unknown } from '../../organization/really_unknown';
8
8
  * - `isValidAgentUrl` *(this one)* which tests just agent URL
9
9
  * - `isValidPipelineUrl` which tests just pipeline URL
10
10
  *
11
+ * Note: This is a pure structural validator and does not block private/internal network
12
+ * addresses. Callers that fetch the URL server-side from an untrusted network context must
13
+ * additionally apply the `assertSafeUrl` SSRF guard from the Agents Server before any
14
+ * outbound request.
15
+ *
11
16
  * @public exported from `@promptbook/utils`
12
17
  */
13
18
  export declare function isValidAgentUrl(url: really_unknown): url is string_agent_url;
@@ -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-133`).
18
+ * It follows semantic versioning (e.g., `0.112.0-135`).
19
19
  *
20
20
  * @generated
21
21
  */
@@ -1,9 +0,0 @@
1
- /**
2
- * Minimal context needed to schedule or execute one default federated-agent sync pass.
3
- *
4
- * @private shared type for `scheduleDefaultFederatedAgentsSync`
5
- */
6
- export type DefaultFederatedAgentsSyncOptions = {
7
- readonly tablePrefix: string;
8
- readonly localServerUrl: string;
9
- };
@@ -1,277 +0,0 @@
1
- import { type Pool, type PoolClient } from 'pg';
2
- import { prepareAgentSourceForPersistence } from '../../../../../src/collection/agent-collection/constructors/agent-collection-in-supabase/prepareAgentSourceForPersistence';
3
- import type { string_book } from '../../../../../src/book-2.0/agent-source/string_book';
4
- import { normalizeAgentName } from '../../../../../src/book-2.0/agent-source/normalizeAgentName';
5
- import { ZERO_USAGE } from '../../../../../src/execution/utils/usage-constants';
6
- import { $randomBase58 } from '../../../../../src/utils/random/$randomBase58';
7
- import { PROMPTBOOK_ENGINE_VERSION } from '../../../../../src/version';
8
- import type { AgentVisibility } from '../agentVisibility';
9
- import type { DefaultFederatedAgentCandidate } from './selectDefaultFederatedAgentsFromOrganizationPayload';
10
- import { quoteIdentifier } from './quoteIdentifier';
11
-
12
- /**
13
- * Table basename storing per-server sync state and locking rows.
14
- */
15
- const DEFAULT_FEDERATED_AGENT_TABLE_BASENAME = 'DefaultFederatedAgent';
16
-
17
- /**
18
- * Length of generated local permanent ids for cloned default agents.
19
- */
20
- const DEFAULT_FEDERATED_AGENT_PERMANENT_ID_LENGTH = 14;
21
-
22
- /**
23
- * Ensures one Core default agent exists locally while serializing writes through a DB row lock.
24
- *
25
- * @param options - Current sync inputs.
26
- * @returns Existing or newly created local permanent id.
27
- *
28
- * @private internal utility of `scheduleDefaultFederatedAgentsSync`
29
- */
30
- export async function ensureDefaultFederatedAgentExists(options: {
31
- readonly pool: Pool;
32
- readonly tablePrefix: string;
33
- readonly defaultVisibility: AgentVisibility;
34
- readonly candidate: DefaultFederatedAgentCandidate;
35
- readonly remoteAgentSource: string_book;
36
- }): Promise<string> {
37
- const client = await options.pool.connect();
38
-
39
- try {
40
- await client.query('BEGIN');
41
- await upsertDefaultFederatedAgentSyncRow(client, options.tablePrefix, options.candidate);
42
- await lockAgentWrites(client, options.tablePrefix);
43
-
44
- const existingPermanentId = await findActiveLocalPermanentIdByNormalizedName(
45
- client,
46
- options.tablePrefix,
47
- options.candidate.normalizedName,
48
- );
49
-
50
- if (existingPermanentId) {
51
- await updateDefaultFederatedAgentLocalPermanentId(
52
- client,
53
- options.tablePrefix,
54
- options.candidate.normalizedName,
55
- existingPermanentId,
56
- );
57
- await client.query('COMMIT');
58
- return existingPermanentId;
59
- }
60
-
61
- const newPermanentId = await insertClonedDefaultFederatedAgent(client, {
62
- tablePrefix: options.tablePrefix,
63
- defaultVisibility: options.defaultVisibility,
64
- remoteAgentSource: options.remoteAgentSource,
65
- });
66
-
67
- await updateDefaultFederatedAgentLocalPermanentId(
68
- client,
69
- options.tablePrefix,
70
- options.candidate.normalizedName,
71
- newPermanentId,
72
- );
73
-
74
- await client.query('COMMIT');
75
- return newPermanentId;
76
- } catch (error) {
77
- try {
78
- await client.query('ROLLBACK');
79
- } catch {
80
- // Keep the original error visible.
81
- }
82
- throw error;
83
- } finally {
84
- client.release();
85
- }
86
- }
87
-
88
- /**
89
- * Inserts or updates the sync-state row for one normalized default agent name.
90
- *
91
- * The `ON CONFLICT ... DO UPDATE` path keeps the row locked for the current transaction.
92
- *
93
- * @param client - Transaction-bound PostgreSQL client.
94
- * @param tablePrefix - Current server table prefix.
95
- * @param candidate - Candidate being synchronized.
96
- */
97
- async function upsertDefaultFederatedAgentSyncRow(
98
- client: PoolClient,
99
- tablePrefix: string,
100
- candidate: DefaultFederatedAgentCandidate,
101
- ): Promise<void> {
102
- const syncTableName = quoteIdentifier(`${tablePrefix}${DEFAULT_FEDERATED_AGENT_TABLE_BASENAME}`);
103
-
104
- await client.query(
105
- `
106
- INSERT INTO ${syncTableName} (
107
- "normalizedName",
108
- "sourceServerUrl",
109
- "sourceAgentIdentifier",
110
- "updatedAt"
111
- )
112
- VALUES ($1, $2, $3, now())
113
- ON CONFLICT ("normalizedName")
114
- DO UPDATE
115
- SET
116
- "sourceServerUrl" = EXCLUDED."sourceServerUrl",
117
- "sourceAgentIdentifier" = EXCLUDED."sourceAgentIdentifier",
118
- "updatedAt" = now()
119
- `,
120
- [candidate.normalizedName, new URL(candidate.sourceAgentUrl).origin, candidate.sourceAgentIdentifier],
121
- );
122
- }
123
-
124
- /**
125
- * Blocks concurrent writes to the current server's agent table during the critical recheck/create section.
126
- *
127
- * @param client - Transaction-bound PostgreSQL client.
128
- * @param tablePrefix - Current server table prefix.
129
- */
130
- async function lockAgentWrites(client: PoolClient, tablePrefix: string): Promise<void> {
131
- const agentTableName = quoteIdentifier(`${tablePrefix}Agent`);
132
- await client.query(`LOCK TABLE ${agentTableName} IN SHARE ROW EXCLUSIVE MODE`);
133
- }
134
-
135
- /**
136
- * Finds the oldest active local agent whose normalized name matches the requested value.
137
- *
138
- * @param client - Transaction-bound PostgreSQL client.
139
- * @param tablePrefix - Current server table prefix.
140
- * @param normalizedName - Stable normalized lookup key.
141
- * @returns Matching permanent id or `null`.
142
- */
143
- async function findActiveLocalPermanentIdByNormalizedName(
144
- client: PoolClient,
145
- tablePrefix: string,
146
- normalizedName: string,
147
- ): Promise<string | null> {
148
- const agentTableName = quoteIdentifier(`${tablePrefix}Agent`);
149
- const result = await client.query<{ agentName: string; permanentId: string | null }>(
150
- `
151
- SELECT "agentName", "permanentId"
152
- FROM ${agentTableName}
153
- WHERE "deletedAt" IS NULL
154
- ORDER BY "createdAt" ASC
155
- `,
156
- );
157
-
158
- for (const row of result.rows) {
159
- if (!row.permanentId) {
160
- continue;
161
- }
162
-
163
- if (normalizeAgentName(row.agentName) === normalizedName) {
164
- return row.permanentId;
165
- }
166
- }
167
-
168
- return null;
169
- }
170
-
171
- /**
172
- * Persists a freshly cloned default agent together with its initial history snapshot.
173
- *
174
- * @param client - Transaction-bound PostgreSQL client.
175
- * @param options - Insert inputs.
176
- * @returns Permanent id of the stored local agent.
177
- */
178
- async function insertClonedDefaultFederatedAgent(
179
- client: PoolClient,
180
- options: {
181
- readonly tablePrefix: string;
182
- readonly defaultVisibility: AgentVisibility;
183
- readonly remoteAgentSource: string_book;
184
- },
185
- ): Promise<string> {
186
- const preparedAgentSource = prepareAgentSourceForPersistence(options.remoteAgentSource);
187
- const permanentId = preparedAgentSource.permanentId || $randomBase58(DEFAULT_FEDERATED_AGENT_PERMANENT_ID_LENGTH);
188
- const createdAt = new Date().toISOString();
189
- const agentTableName = quoteIdentifier(`${options.tablePrefix}Agent`);
190
- const agentHistoryTableName = quoteIdentifier(`${options.tablePrefix}AgentHistory`);
191
-
192
- await client.query(
193
- `
194
- INSERT INTO ${agentTableName} (
195
- "agentName",
196
- "createdAt",
197
- "updatedAt",
198
- "permanentId",
199
- "agentHash",
200
- "agentSource",
201
- "agentProfile",
202
- "promptbookEngineVersion",
203
- "usage",
204
- "visibility"
205
- )
206
- VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb, $8, $9::jsonb, $10)
207
- `,
208
- [
209
- preparedAgentSource.agentProfile.agentName,
210
- createdAt,
211
- null,
212
- permanentId,
213
- preparedAgentSource.agentProfile.agentHash,
214
- preparedAgentSource.agentSource,
215
- JSON.stringify(preparedAgentSource.agentProfile),
216
- PROMPTBOOK_ENGINE_VERSION,
217
- JSON.stringify(ZERO_USAGE),
218
- options.defaultVisibility,
219
- ],
220
- );
221
-
222
- await client.query(
223
- `
224
- INSERT INTO ${agentHistoryTableName} (
225
- "createdAt",
226
- "agentName",
227
- "permanentId",
228
- "agentHash",
229
- "previousAgentHash",
230
- "agentSource",
231
- "promptbookEngineVersion",
232
- "versionName"
233
- )
234
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
235
- `,
236
- [
237
- createdAt,
238
- preparedAgentSource.agentProfile.agentName,
239
- permanentId,
240
- preparedAgentSource.agentProfile.agentHash,
241
- null,
242
- preparedAgentSource.agentSource,
243
- PROMPTBOOK_ENGINE_VERSION,
244
- null,
245
- ],
246
- );
247
-
248
- return permanentId;
249
- }
250
-
251
- /**
252
- * Stores the resolved local permanent id back into the sync-state table.
253
- *
254
- * @param client - Transaction-bound PostgreSQL client.
255
- * @param tablePrefix - Current server table prefix.
256
- * @param normalizedName - Stable normalized lookup key.
257
- * @param localPermanentId - Local permanent id to store.
258
- */
259
- async function updateDefaultFederatedAgentLocalPermanentId(
260
- client: PoolClient,
261
- tablePrefix: string,
262
- normalizedName: string,
263
- localPermanentId: string,
264
- ): Promise<void> {
265
- const syncTableName = quoteIdentifier(`${tablePrefix}${DEFAULT_FEDERATED_AGENT_TABLE_BASENAME}`);
266
-
267
- await client.query(
268
- `
269
- UPDATE ${syncTableName}
270
- SET
271
- "localPermanentId" = $2,
272
- "updatedAt" = now()
273
- WHERE "normalizedName" = $1
274
- `,
275
- [normalizedName, localPermanentId],
276
- );
277
- }
@@ -1,39 +0,0 @@
1
- import { spaceTrim } from '@promptbook-local/utils';
2
- import { DatabaseError } from '../../../../../src/errors/DatabaseError';
3
- import type { FederatedOrganizationPayload } from './selectDefaultFederatedAgentsFromOrganizationPayload';
4
- import { fetchWithDefaultFederatedAgentTimeout } from './fetchWithDefaultFederatedAgentTimeout';
5
-
6
- /**
7
- * Fetches the Core public organization snapshot.
8
- *
9
- * @param coreServerUrl - Base URL of the Core server.
10
- * @returns Parsed organization payload.
11
- *
12
- * @private internal utility of `scheduleDefaultFederatedAgentsSync`
13
- */
14
- export async function fetchCoreOrganizationPayload(coreServerUrl: string): Promise<FederatedOrganizationPayload> {
15
- const endpoint = new URL('/api/agent-organization', ensureTrailingSlash(coreServerUrl)).href;
16
- const response = await fetchWithDefaultFederatedAgentTimeout(endpoint);
17
-
18
- if (!response.ok) {
19
- throw new DatabaseError(
20
- spaceTrim(`
21
- Failed to fetch default federated agents metadata from \`${endpoint}\`.
22
-
23
- Received \`${response.status} ${response.statusText}\`.
24
- `),
25
- );
26
- }
27
-
28
- return (await response.json()) as FederatedOrganizationPayload;
29
- }
30
-
31
- /**
32
- * Normalizes a server base URL so relative `URL` construction stays predictable.
33
- *
34
- * @param value - Raw base URL.
35
- * @returns Base URL with exactly one trailing slash.
36
- */
37
- function ensureTrailingSlash(value: string): string {
38
- return `${value.replace(/\/+$/g, '')}/`;
39
- }
@@ -1,43 +0,0 @@
1
- import { spaceTrim } from '@promptbook-local/utils';
2
- import type { string_book } from '../../../../../src/book-2.0/agent-source/string_book';
3
- import { DatabaseError } from '../../../../../src/errors/DatabaseError';
4
- import { fetchWithDefaultFederatedAgentTimeout } from './fetchWithDefaultFederatedAgentTimeout';
5
-
6
- /**
7
- * Fetches the effective book source of one remote public agent.
8
- *
9
- * @param agentRouteUrl - Canonical remote agent route.
10
- * @returns Remote book content as plain text.
11
- *
12
- * @private internal utility of `scheduleDefaultFederatedAgentsSync`
13
- */
14
- export async function fetchFederatedAgentBook(agentRouteUrl: string): Promise<string_book> {
15
- const endpoint = buildFederatedAgentBookUrl(agentRouteUrl);
16
- const response = await fetchWithDefaultFederatedAgentTimeout(endpoint);
17
-
18
- if (!response.ok) {
19
- throw new DatabaseError(
20
- spaceTrim(`
21
- Failed to fetch default federated agent source from \`${endpoint}\`.
22
-
23
- Received \`${response.status} ${response.statusText}\`.
24
- `),
25
- );
26
- }
27
-
28
- return (await response.text()) as string_book;
29
- }
30
-
31
- /**
32
- * Builds the public book endpoint URL for one remote agent route.
33
- *
34
- * @param agentRouteUrl - Canonical remote agent route.
35
- * @returns Absolute remote `/api/book` URL.
36
- */
37
- function buildFederatedAgentBookUrl(agentRouteUrl: string): string {
38
- const routeUrl = new URL(agentRouteUrl);
39
- routeUrl.search = '';
40
- routeUrl.hash = '';
41
- routeUrl.pathname = `${routeUrl.pathname.replace(/\/+$/g, '')}/api/book`;
42
- return routeUrl.href;
43
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * Timeout used for remote Core HTTP requests.
3
- */
4
- const DEFAULT_FEDERATED_AGENT_FETCH_TIMEOUT_MS = 10_000;
5
-
6
- /**
7
- * Executes one HTTP request with a fixed abort timeout.
8
- *
9
- * @param url - Absolute request URL.
10
- * @returns Successful or unsuccessful fetch response.
11
- *
12
- * @private internal utility of `scheduleDefaultFederatedAgentsSync`
13
- */
14
- export async function fetchWithDefaultFederatedAgentTimeout(url: string): Promise<Response> {
15
- const abortController = new AbortController();
16
- const timeout = setTimeout(() => abortController.abort(), DEFAULT_FEDERATED_AGENT_FETCH_TIMEOUT_MS);
17
-
18
- try {
19
- return await fetch(url, {
20
- method: 'GET',
21
- cache: 'no-store',
22
- headers: { Accept: 'application/json, text/plain;q=0.9, */*;q=0.1' },
23
- signal: abortController.signal,
24
- });
25
- } finally {
26
- clearTimeout(timeout);
27
- }
28
- }
@@ -1,38 +0,0 @@
1
- import { spaceTrim } from '@promptbook-local/utils';
2
- import { Pool } from 'pg';
3
- import { DatabaseError } from '../../../../../src/errors/DatabaseError';
4
- import { resolveDatabaseMigrationConnectionStringFromEnvironment } from '../../database/runDatabaseMigrations';
5
-
6
- /**
7
- * Shared PostgreSQL pool reused by default-agent sync helpers.
8
- */
9
- let defaultFederatedAgentSyncPool: Pool | null = null;
10
-
11
- /**
12
- * Resolves the shared PostgreSQL pool used by this feature.
13
- *
14
- * @returns Shared PostgreSQL pool.
15
- *
16
- * @private internal utility of `scheduleDefaultFederatedAgentsSync`
17
- */
18
- export function getDefaultFederatedAgentSyncPool(): Pool {
19
- if (defaultFederatedAgentSyncPool) {
20
- return defaultFederatedAgentSyncPool;
21
- }
22
-
23
- const connectionString = resolveDatabaseMigrationConnectionStringFromEnvironment();
24
- if (!connectionString) {
25
- throw new DatabaseError(
26
- spaceTrim(`
27
- Cannot synchronize default federated agents because \`POSTGRES_URL\` or \`DATABASE_URL\` is missing.
28
- `),
29
- );
30
- }
31
-
32
- defaultFederatedAgentSyncPool = new Pool({
33
- connectionString,
34
- ssl: { rejectUnauthorized: false },
35
- });
36
-
37
- return defaultFederatedAgentSyncPool;
38
- }
@@ -1,41 +0,0 @@
1
- import type { Pool } from 'pg';
2
- import { normalizeAgentName } from '../../../../../src/book-2.0/agent-source/normalizeAgentName';
3
- import { quoteIdentifier } from './quoteIdentifier';
4
-
5
- /**
6
- * Loads active local agents and indexes them by normalized name.
7
- *
8
- * @param pool - Shared PostgreSQL pool.
9
- * @param tablePrefix - Current server table prefix.
10
- * @returns Normalized-name lookup of active local permanent ids.
11
- *
12
- * @private internal utility of `scheduleDefaultFederatedAgentsSync`
13
- */
14
- export async function loadActiveLocalAgentIdsByNormalizedName(
15
- pool: Pool,
16
- tablePrefix: string,
17
- ): Promise<Map<string, string>> {
18
- const agentTableName = quoteIdentifier(`${tablePrefix}Agent`);
19
- const result = await pool.query<{ agentName: string; permanentId: string | null }>(
20
- `
21
- SELECT "agentName", "permanentId"
22
- FROM ${agentTableName}
23
- WHERE "deletedAt" IS NULL
24
- ORDER BY "createdAt" ASC
25
- `,
26
- );
27
-
28
- const activeAgentsByNormalizedName = new Map<string, string>();
29
- for (const row of result.rows) {
30
- if (!row.permanentId) {
31
- continue;
32
- }
33
-
34
- const normalizedName = normalizeAgentName(row.agentName);
35
- if (!activeAgentsByNormalizedName.has(normalizedName)) {
36
- activeAgentsByNormalizedName.set(normalizedName, row.permanentId);
37
- }
38
- }
39
-
40
- return activeAgentsByNormalizedName;
41
- }
@@ -1,76 +0,0 @@
1
- import type { Pool } from 'pg';
2
- import {
3
- DEFAULT_AGENT_VISIBILITY,
4
- DEFAULT_VISIBILITY_METADATA_KEY,
5
- LEGACY_DEFAULT_VISIBILITY_METADATA_KEY,
6
- parseAgentVisibility,
7
- type AgentVisibility,
8
- } from '../agentVisibility';
9
- import { quoteIdentifier } from './quoteIdentifier';
10
-
11
- /**
12
- * Metadata key storing the canonical Core server URL.
13
- */
14
- const CORE_SERVER_METADATA_KEY = 'CORE_SERVER';
15
-
16
- /**
17
- * Loads the small metadata subset needed by the sync logic.
18
- *
19
- * @param pool - Shared PostgreSQL pool.
20
- * @param tablePrefix - Current server table prefix.
21
- * @returns Core server URL and effective default visibility.
22
- *
23
- * @private internal utility of `scheduleDefaultFederatedAgentsSync`
24
- */
25
- export async function loadDefaultFederatedAgentSyncMetadata(
26
- pool: Pool,
27
- tablePrefix: string,
28
- ): Promise<{ coreServerUrl: string | null; defaultVisibility: AgentVisibility }> {
29
- const metadataTableName = quoteIdentifier(`${tablePrefix}Metadata`);
30
- const result = await pool.query<{ key: string; value: string | null }>(
31
- `
32
- SELECT "key", "value"
33
- FROM ${metadataTableName}
34
- WHERE "key" = ANY($1)
35
- `,
36
- [[CORE_SERVER_METADATA_KEY, DEFAULT_VISIBILITY_METADATA_KEY, LEGACY_DEFAULT_VISIBILITY_METADATA_KEY]],
37
- );
38
-
39
- const metadataByKey = new Map<string, string | null>();
40
- for (const row of result.rows) {
41
- metadataByKey.set(row.key, row.value);
42
- }
43
-
44
- return {
45
- coreServerUrl: normalizeOptionalServerUrl(metadataByKey.get(CORE_SERVER_METADATA_KEY) || null),
46
- defaultVisibility: parseAgentVisibility(
47
- metadataByKey.get(DEFAULT_VISIBILITY_METADATA_KEY) || metadataByKey.get(LEGACY_DEFAULT_VISIBILITY_METADATA_KEY),
48
- DEFAULT_AGENT_VISIBILITY,
49
- ),
50
- };
51
- }
52
-
53
- /**
54
- * Normalizes an optional server URL so equality checks ignore trailing slashes.
55
- *
56
- * @param value - Raw server URL.
57
- * @returns Normalized URL or `null`.
58
- */
59
- function normalizeOptionalServerUrl(value: string | null): string | null {
60
- if (!value) {
61
- return null;
62
- }
63
-
64
- const normalizedValue = value.trim();
65
- return normalizedValue === '' ? null : ensureTrailingSlash(normalizedValue);
66
- }
67
-
68
- /**
69
- * Ensures a server base URL always ends with a single slash.
70
- *
71
- * @param value - Raw server URL.
72
- * @returns Base URL with one trailing slash.
73
- */
74
- function ensureTrailingSlash(value: string): string {
75
- return `${value.replace(/\/+$/g, '')}/`;
76
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Quotes one PostgreSQL identifier safely.
3
- *
4
- * @param identifier - Raw SQL identifier.
5
- * @returns Quoted identifier.
6
- *
7
- * @private internal utility of `scheduleDefaultFederatedAgentsSync`
8
- */
9
- export function quoteIdentifier(identifier: string): string {
10
- return `"${identifier.replace(/"/g, '""')}"`;
11
- }