@promptbook/cli 0.113.0-4 → 0.113.0-6
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 +13 -1
- package/apps/agents-server/src/search/createDefaultServerSearchProviders/loadLocalOrganizationSearchDataset.ts +12 -1
- package/apps/agents-server/src/utils/agentOrganization/loadAgentOrganizationState.ts +13 -1
- package/apps/agents-server/src/utils/createLocalAgentSourceImporter.ts +159 -0
- package/apps/agents-server/src/utils/createMissingImportedAgentFallback.ts +60 -0
- package/apps/agents-server/src/utils/customDomainRouting.ts +157 -12
- package/apps/agents-server/src/utils/externalChatRunner/processExternalUserChatJob.ts +1 -1
- package/apps/agents-server/src/utils/importAgentWithFallback.ts +1 -58
- package/apps/agents-server/src/utils/localAgentRouteReferences.ts +167 -0
- package/apps/agents-server/src/utils/localChatRunner/processLocalUserChatJob.ts +1 -1
- package/apps/agents-server/src/utils/managementApi/managementApiAgents.ts +17 -3
- package/apps/agents-server/src/utils/resolveAgentStateFromSource.ts +7 -1
- package/apps/agents-server/src/utils/resolveInheritedAgentSource.ts +54 -5
- package/apps/agents-server/src/utils/resolveServerAgentContext.ts +12 -1
- package/apps/agents-server/src/utils/resolveStoredAgentState.ts +2 -1
- package/apps/agents-server/src/utils/userChat/userChatMessageLifecycle.ts +39 -9
- package/apps/agents-server/tests/e2e/support/ChatHistoryNavigationSupport.ts +5 -0
- package/esm/index.es.js +803 -39
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +20 -0
- package/esm/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +5 -0
- package/esm/scripts/run-codex-prompts/ui/buildCoderRunAgentVisual.d.ts +29 -0
- package/esm/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +4 -0
- package/esm/src/avatars/renderAvatarVisualAsciiArt.d.ts +75 -0
- package/esm/src/utils/ascii-art/$detectTerminalAnsiColorDepth.d.ts +15 -0
- package/esm/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +80 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/avatars/avatarAnimationScheduler.ts +2 -1
- package/src/avatars/renderAvatarVisualAsciiArt.ts +138 -0
- package/src/avatars/visuals/octopus3d3AvatarVisual.ts +6 -2
- package/src/avatars/visuals/octopus3d4AvatarVisual.ts +14 -18
- package/src/cli/cli-commands/agents-server/buildAgentsServer.ts +3 -1
- package/src/cli/cli-commands/coder/boilerplateTemplates.ts +14 -21
- package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +1 -4
- package/src/cli/cli-commands/coder/run.ts +2 -9
- package/src/commitments/TEAM/TEAM.ts +5 -5
- package/src/other/templates/getTemplatesPipelineCollection.ts +781 -943
- package/src/utils/ascii-art/$detectTerminalAnsiColorDepth.ts +45 -0
- package/src/utils/ascii-art/convertImageDataToAsciiArt.ts +396 -0
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -0
- package/umd/index.umd.js +803 -39
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/common/resolveCoderAgent.d.ts +20 -0
- package/umd/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +5 -0
- package/umd/scripts/run-codex-prompts/ui/buildCoderRunAgentVisual.d.ts +29 -0
- package/umd/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +4 -0
- package/umd/src/avatars/renderAvatarVisualAsciiArt.d.ts +75 -0
- package/umd/src/utils/ascii-art/$detectTerminalAnsiColorDepth.d.ts +15 -0
- package/umd/src/utils/ascii-art/convertImageDataToAsciiArt.d.ts +80 -0
- package/umd/src/version.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/common/resolveAgentSystemMessage.d.ts +0 -6
- package/umd/scripts/run-codex-prompts/common/resolveAgentSystemMessage.d.ts +0 -6
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
import { loadFederatedAgentImportConfiguration } from '@/src/utils/federatedAgentImportConfiguration';
|
|
9
9
|
import { getCurrentUser } from '@/src/utils/getCurrentUser';
|
|
10
10
|
import { getWellKnownAgentUrl } from '@/src/utils/getWellKnownAgentUrl';
|
|
11
|
+
import { createLocalAgentSourceImporter } from '@/src/utils/createLocalAgentSourceImporter';
|
|
11
12
|
import { resolveInheritedAgentSource } from '@/src/utils/resolveInheritedAgentSource';
|
|
12
13
|
import { padBook, validateBook } from '@promptbook-local/core';
|
|
13
14
|
import type { string_agent_url } from '@promptbook-local/types';
|
|
@@ -96,13 +97,24 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
96
97
|
const agentSource = resolvedAgentContext.unresolvedAgentSource;
|
|
97
98
|
const agentReferenceResolver = resolvedAgentContext.scopedAgentReferenceResolver;
|
|
98
99
|
const federatedAgentImportConfiguration = await loadFederatedAgentImportConfiguration();
|
|
100
|
+
const adamAgentUrl = await getWellKnownAgentUrl('ADAM');
|
|
101
|
+
const localServerUrl = new URL(request.url).origin;
|
|
102
|
+
const agentSourceImporter = createLocalAgentSourceImporter({
|
|
103
|
+
collection,
|
|
104
|
+
localServerUrls: [localServerUrl],
|
|
105
|
+
localAgentUrls: [adamAgentUrl],
|
|
106
|
+
adamAgentUrl,
|
|
107
|
+
fallbackResolver: baseAgentReferenceResolver,
|
|
108
|
+
federatedAgentImportConfiguration,
|
|
109
|
+
});
|
|
99
110
|
const effectiveAgentSource = await resolveInheritedAgentSource(agentSource, {
|
|
100
|
-
adamAgentUrl
|
|
111
|
+
adamAgentUrl,
|
|
101
112
|
recursionLevel,
|
|
102
113
|
currentAgentUrl: resolvedAgentContext.canonicalAgentUrl,
|
|
103
114
|
inheritancePath: inheritancePath as Array<string_agent_url>,
|
|
104
115
|
agentReferenceResolver,
|
|
105
116
|
federatedAgentImportConfiguration,
|
|
117
|
+
agentSourceImporter,
|
|
106
118
|
});
|
|
107
119
|
const etag = `W/"${computeHash(effectiveAgentSource)}"`;
|
|
108
120
|
|
|
@@ -2,7 +2,9 @@ import { $getTableName } from '../../database/$getTableName';
|
|
|
2
2
|
import { $provideSupabaseForServer } from '../../database/$provideSupabaseForServer';
|
|
3
3
|
import type { AgentsServerDatabase } from '../../database/schema';
|
|
4
4
|
import type { AgentBasicInformation } from '../../../../../src/book-2.0/agent-source/AgentBasicInformation';
|
|
5
|
+
import { $provideAgentCollectionForServer } from '../../tools/$provideAgentCollectionForServer';
|
|
5
6
|
import { $provideAgentReferenceResolver } from '../../utils/agentReferenceResolver/$provideAgentReferenceResolver';
|
|
7
|
+
import { createLocalAgentSourceImporter } from '../../utils/createLocalAgentSourceImporter';
|
|
6
8
|
import { getWellKnownAgentUrl } from '../../utils/getWellKnownAgentUrl';
|
|
7
9
|
import { resolveCurrentOrInternalServerOrigin } from '../../utils/resolveCurrentOrInternalServerOrigin';
|
|
8
10
|
import { resolveStoredAgentStates } from '../../utils/resolveStoredAgentState';
|
|
@@ -85,12 +87,21 @@ export async function loadLocalOrganizationSearchDataset(options: {
|
|
|
85
87
|
const folders = (folderResult.data || []) as AgentFolderSearchRow[];
|
|
86
88
|
const localServerUrl = await resolveCurrentOrInternalServerOrigin();
|
|
87
89
|
const agentReferenceResolver = await $provideAgentReferenceResolver();
|
|
90
|
+
const adamAgentUrl = await getWellKnownAgentUrl('ADAM');
|
|
91
|
+
const agentSourceImporter = createLocalAgentSourceImporter({
|
|
92
|
+
collection: await $provideAgentCollectionForServer(),
|
|
93
|
+
localServerUrls: [localServerUrl],
|
|
94
|
+
localAgentUrls: [adamAgentUrl],
|
|
95
|
+
adamAgentUrl,
|
|
96
|
+
fallbackResolver: agentReferenceResolver,
|
|
97
|
+
});
|
|
88
98
|
const resolvedAgents = await resolveStoredAgentStates(
|
|
89
99
|
(agentResult.data || []) as Array<Pick<AgentSearchRow, 'id' | 'agentName' | 'permanentId' | 'agentSource' | 'folderId' | 'visibility'>>,
|
|
90
100
|
{
|
|
91
101
|
localServerUrl,
|
|
92
|
-
adamAgentUrl
|
|
102
|
+
adamAgentUrl,
|
|
93
103
|
agentReferenceResolver,
|
|
104
|
+
agentSourceImporter,
|
|
94
105
|
},
|
|
95
106
|
);
|
|
96
107
|
const agents = resolvedAgents.map((agent) => ({
|
|
@@ -2,7 +2,9 @@ import type { AgentBasicInformation } from '../../../../../src/book-2.0/agent-so
|
|
|
2
2
|
import { $getTableName } from '../../database/$getTableName';
|
|
3
3
|
import { $provideSupabaseForServer } from '../../database/$provideSupabaseForServer';
|
|
4
4
|
import type { AgentsServerDatabase } from '../../database/schema';
|
|
5
|
+
import { $provideAgentCollectionForServer } from '../../tools/$provideAgentCollectionForServer';
|
|
5
6
|
import { $provideAgentReferenceResolver } from '../agentReferenceResolver/$provideAgentReferenceResolver';
|
|
7
|
+
import { createLocalAgentSourceImporter } from '../createLocalAgentSourceImporter';
|
|
6
8
|
import { getCurrentUser } from '../getCurrentUser';
|
|
7
9
|
import { getWellKnownAgentUrl } from '../getWellKnownAgentUrl';
|
|
8
10
|
import { resolveCurrentOrInternalServerOrigin } from '../resolveCurrentOrInternalServerOrigin';
|
|
@@ -187,14 +189,24 @@ async function loadResolvedOrganizationSnapshot(options: {
|
|
|
187
189
|
|
|
188
190
|
const localServerUrl = await resolveCurrentOrInternalServerOrigin();
|
|
189
191
|
const agentReferenceResolver = await $provideAgentReferenceResolver();
|
|
192
|
+
const adamAgentUrl = await getWellKnownAgentUrl('ADAM');
|
|
193
|
+
const collection = await $provideAgentCollectionForServer();
|
|
194
|
+
const agentSourceImporter = createLocalAgentSourceImporter({
|
|
195
|
+
collection,
|
|
196
|
+
localServerUrls: [localServerUrl],
|
|
197
|
+
localAgentUrls: [adamAgentUrl],
|
|
198
|
+
adamAgentUrl,
|
|
199
|
+
fallbackResolver: agentReferenceResolver,
|
|
200
|
+
});
|
|
190
201
|
const resolvedAgents = await resolveStoredAgentStates(
|
|
191
202
|
(agentResult.data || []) as Array<
|
|
192
203
|
Pick<AgentRow, 'agentName' | 'agentSource' | 'permanentId' | 'visibility' | 'folderId' | 'sortOrder'>
|
|
193
204
|
>,
|
|
194
205
|
{
|
|
195
206
|
localServerUrl,
|
|
196
|
-
adamAgentUrl
|
|
207
|
+
adamAgentUrl,
|
|
197
208
|
agentReferenceResolver,
|
|
209
|
+
agentSourceImporter,
|
|
198
210
|
},
|
|
199
211
|
);
|
|
200
212
|
const agents = resolvedAgents.map((agent) =>
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import type { AgentReferenceResolver } from '../../../../src/book-2.0/agent-source/AgentReferenceResolver';
|
|
2
|
+
import type { AgentCollection } from '../../../../src/collection/agent-collection/AgentCollection';
|
|
3
|
+
import { DEFAULT_MAX_RECURSION } from '../../../../src/config';
|
|
4
|
+
import { NotFoundError } from '../../../../src/errors/NotFoundError';
|
|
5
|
+
import { ParseError } from '../../../../src/errors/ParseError';
|
|
6
|
+
import type { string_agent_url } from '../../../../src/types/typeAliases';
|
|
7
|
+
import { spaceTrim } from '../../../../src/utils/organization/spaceTrim';
|
|
8
|
+
import type { FederatedAgentImportConfiguration } from '../constants/federatedAgentImport';
|
|
9
|
+
import {
|
|
10
|
+
resolveBookScopedAgentContext,
|
|
11
|
+
type ResolvedBookScopedAgentContext,
|
|
12
|
+
} from './agentReferenceResolver/bookScopedAgentReferences';
|
|
13
|
+
import {
|
|
14
|
+
createLocalAgentUrl,
|
|
15
|
+
normalizeLocalAgentUrlReferences,
|
|
16
|
+
normalizeLocalServerUrls,
|
|
17
|
+
resolveLocalAgentRouteReference,
|
|
18
|
+
} from './localAgentRouteReferences';
|
|
19
|
+
import { createMissingImportedAgentFallback } from './createMissingImportedAgentFallback';
|
|
20
|
+
import {
|
|
21
|
+
resolveInheritedAgentSource,
|
|
22
|
+
type AgentSourceImporter,
|
|
23
|
+
} from './resolveInheritedAgentSource';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Dependencies needed for importing same-instance agent sources without HTTP.
|
|
27
|
+
*/
|
|
28
|
+
export type CreateLocalAgentSourceImporterOptions = {
|
|
29
|
+
/**
|
|
30
|
+
* Collection used to load local regular and book-scoped agent sources.
|
|
31
|
+
*/
|
|
32
|
+
readonly collection: Pick<AgentCollection, 'getAgentPermanentId' | 'getAgentSource'>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Server origins that should be treated as this Agents Server instance.
|
|
36
|
+
*/
|
|
37
|
+
readonly localServerUrls: ReadonlyArray<string>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Exact agent URLs that should be treated as local even when their origin is not in `localServerUrls`.
|
|
41
|
+
*/
|
|
42
|
+
readonly localAgentUrls?: ReadonlyArray<string_agent_url>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Adam agent URL used for implicit default inheritance.
|
|
46
|
+
*/
|
|
47
|
+
readonly adamAgentUrl: string_agent_url;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resolver used for compact references that are not book-scoped.
|
|
51
|
+
*/
|
|
52
|
+
readonly fallbackResolver?: AgentReferenceResolver;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Retry configuration used when nested imports leave the local server.
|
|
56
|
+
*/
|
|
57
|
+
readonly federatedAgentImportConfiguration?: FederatedAgentImportConfiguration;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Creates an importer that loads same-instance agent URLs directly from the collection.
|
|
62
|
+
*
|
|
63
|
+
* @param options - Same-instance import dependencies.
|
|
64
|
+
* @returns Importer suitable for `resolveInheritedAgentSource`.
|
|
65
|
+
*/
|
|
66
|
+
export function createLocalAgentSourceImporter(options: CreateLocalAgentSourceImporterOptions): AgentSourceImporter {
|
|
67
|
+
const localServerUrls = normalizeLocalServerUrls(options.localServerUrls);
|
|
68
|
+
const localAgentUrlReferences = normalizeLocalAgentUrlReferences(options.localAgentUrls || []);
|
|
69
|
+
const localAgentSourceImporter: AgentSourceImporter = async (agentUrl, context) => {
|
|
70
|
+
const localRouteReference = resolveLocalAgentRouteReference(agentUrl, localServerUrls, localAgentUrlReferences);
|
|
71
|
+
|
|
72
|
+
if (!localRouteReference) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const nextRecursionLevel = (context.importAgentOptions.recursionLevel || 0) + 1;
|
|
77
|
+
assertRecursionLevel(nextRecursionLevel, agentUrl);
|
|
78
|
+
|
|
79
|
+
let resolvedAgentContext: ResolvedBookScopedAgentContext;
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
resolvedAgentContext = await resolveBookScopedAgentContext({
|
|
83
|
+
collection: options.collection,
|
|
84
|
+
agentIdentifier: localRouteReference.agentIdentifier,
|
|
85
|
+
localServerUrl: localRouteReference.localServerUrl,
|
|
86
|
+
fallbackResolver: options.fallbackResolver,
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error instanceof NotFoundError) {
|
|
90
|
+
return createMissingImportedAgentFallback(agentUrl, 1, error);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return resolveInheritedAgentSource(resolvedAgentContext.unresolvedAgentSource, {
|
|
97
|
+
adamAgentUrl: options.adamAgentUrl,
|
|
98
|
+
recursionLevel: nextRecursionLevel,
|
|
99
|
+
inheritancePath: context.importAgentOptions.inheritancePath,
|
|
100
|
+
currentAgentUrl: resolvedAgentContext.canonicalAgentUrl,
|
|
101
|
+
currentAgentAliases: createCurrentAgentAliases(resolvedAgentContext, localServerUrls),
|
|
102
|
+
agentReferenceResolver: resolvedAgentContext.scopedAgentReferenceResolver,
|
|
103
|
+
federatedAgentImportConfiguration:
|
|
104
|
+
options.federatedAgentImportConfiguration || context.federatedAgentImportConfiguration,
|
|
105
|
+
agentSourceImporter: localAgentSourceImporter,
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
return localAgentSourceImporter;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Throws when direct local importing would exceed the configured recursion limit.
|
|
114
|
+
*
|
|
115
|
+
* @param recursionLevel - Next recursion level.
|
|
116
|
+
* @param agentUrl - Local agent URL being imported.
|
|
117
|
+
*/
|
|
118
|
+
function assertRecursionLevel(recursionLevel: number, agentUrl: string_agent_url): void {
|
|
119
|
+
if (recursionLevel <= DEFAULT_MAX_RECURSION) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
throw new ParseError(
|
|
124
|
+
spaceTrim(
|
|
125
|
+
(block) => `
|
|
126
|
+
Recursion depth ${recursionLevel} exceeds maximum allowed ${DEFAULT_MAX_RECURSION} while importing local agent:
|
|
127
|
+
|
|
128
|
+
${block(agentUrl)}
|
|
129
|
+
`,
|
|
130
|
+
),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Builds cycle-detection aliases for every same-instance origin.
|
|
136
|
+
*
|
|
137
|
+
* @param resolvedAgentContext - Resolved local/book-scoped agent context.
|
|
138
|
+
* @param localServerUrls - Same-instance server origins.
|
|
139
|
+
* @returns Unique local URL aliases for the imported agent.
|
|
140
|
+
*/
|
|
141
|
+
function createCurrentAgentAliases(
|
|
142
|
+
resolvedAgentContext: ResolvedBookScopedAgentContext,
|
|
143
|
+
localServerUrls: ReadonlyArray<string>,
|
|
144
|
+
): Array<string_agent_url> {
|
|
145
|
+
const agentIdentifiers = [
|
|
146
|
+
resolvedAgentContext.canonicalAgentIdentifier,
|
|
147
|
+
resolvedAgentContext.requestedAgentIdentifier,
|
|
148
|
+
resolvedAgentContext.resolvedAgentName,
|
|
149
|
+
].filter((agentIdentifier, index, agentIdentifierList) => agentIdentifierList.indexOf(agentIdentifier) === index);
|
|
150
|
+
const agentAliases = new Set<string>(resolvedAgentContext.currentAgentAliases);
|
|
151
|
+
|
|
152
|
+
for (const localServerUrl of localServerUrls) {
|
|
153
|
+
for (const agentIdentifier of agentIdentifiers) {
|
|
154
|
+
agentAliases.add(createLocalAgentUrl(localServerUrl, agentIdentifier));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return [...agentAliases] as Array<string_agent_url>;
|
|
159
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { padBook } from '../../../../src/book-2.0/agent-source/padBook';
|
|
2
|
+
import { validateBook } from '../../../../src/book-2.0/agent-source/string_book';
|
|
3
|
+
import type { string_agent_url } from '../../../../src/types/typeAliases';
|
|
4
|
+
import type { string_book } from '../../../../src/book-2.0/agent-source/string_book';
|
|
5
|
+
import { spaceTrim } from '../../../../src/utils/organization/spaceTrim';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Collapses one thrown error into a single-line message suitable for `NOTE` commitments.
|
|
9
|
+
*
|
|
10
|
+
* @param agentUrl - Canonical imported agent URL.
|
|
11
|
+
* @param error - Unknown error raised while loading the imported agent.
|
|
12
|
+
* @returns Human-readable single-line failure reason.
|
|
13
|
+
*
|
|
14
|
+
* @private internal helper for imported-agent fallback books
|
|
15
|
+
*/
|
|
16
|
+
function normalizeImportFailureMessage(agentUrl: string_agent_url, error: unknown): string {
|
|
17
|
+
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
18
|
+
const normalizedMessage = rawMessage.replace(/\s+/g, ' ').trim();
|
|
19
|
+
const prefix = `Failed to import agent from "${agentUrl}"`;
|
|
20
|
+
|
|
21
|
+
if (normalizedMessage.startsWith(prefix)) {
|
|
22
|
+
const suffix = normalizedMessage.slice(prefix.length).trim();
|
|
23
|
+
if (suffix.length > 0) {
|
|
24
|
+
return suffix.replace(/^[-:,\s]+/, '').trim() || 'unknown error';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return normalizedMessage || 'unknown error';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Creates the ad-hoc fallback source returned when a referenced agent stays unavailable.
|
|
33
|
+
*
|
|
34
|
+
* @param agentUrl - Canonical imported agent URL.
|
|
35
|
+
* @param attempts - Total number of attempts that were used.
|
|
36
|
+
* @param error - Final error raised by the failed import attempts.
|
|
37
|
+
* @returns Valid fallback book source.
|
|
38
|
+
*
|
|
39
|
+
* @private internal helper for imported-agent fallback books
|
|
40
|
+
*/
|
|
41
|
+
export function createMissingImportedAgentFallback(
|
|
42
|
+
agentUrl: string_agent_url,
|
|
43
|
+
attempts: number,
|
|
44
|
+
error: unknown,
|
|
45
|
+
): string_book {
|
|
46
|
+
const failureMessage = normalizeImportFailureMessage(agentUrl, error);
|
|
47
|
+
|
|
48
|
+
return padBook(
|
|
49
|
+
validateBook(
|
|
50
|
+
spaceTrim(
|
|
51
|
+
`
|
|
52
|
+
Not found agent
|
|
53
|
+
|
|
54
|
+
NOTE This agent was supposed to be imported from ${agentUrl}, but it can not be loaded after ${attempts} attempts because of ${failureMessage}
|
|
55
|
+
CLOSED
|
|
56
|
+
`,
|
|
57
|
+
),
|
|
58
|
+
),
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -1,13 +1,30 @@
|
|
|
1
1
|
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
AgentBasicInformation,
|
|
4
|
+
string_agent_permanent_id,
|
|
5
|
+
string_agent_url,
|
|
6
|
+
string_book,
|
|
7
|
+
} from '../../../../src/_packages/types.index';
|
|
8
|
+
import type { AgentReferenceResolver } from '../../../../src/book-2.0/agent-source/AgentReferenceResolver';
|
|
3
9
|
import type { AgentCollection } from '../../../../src/collection/agent-collection/AgentCollection';
|
|
10
|
+
import { DEFAULT_MAX_RECURSION } from '../../../../src/config';
|
|
11
|
+
import { NotFoundError } from '../../../../src/errors/NotFoundError';
|
|
12
|
+
import { ParseError } from '../../../../src/errors/ParseError';
|
|
13
|
+
import { spaceTrim } from '../../../../src/utils/organization/spaceTrim';
|
|
4
14
|
import { normalizeDomainForMatching } from '../../../../src/utils/validators/url/normalizeDomainForMatching';
|
|
5
15
|
import type { FederatedAgentImportConfiguration } from '../constants/federatedAgentImport';
|
|
6
16
|
import { createServerAgentReferenceResolver } from './agentReferenceResolver/createServerAgentReferenceResolver';
|
|
7
17
|
import { loadFederatedAgentImportConfiguration } from './federatedAgentImportConfiguration';
|
|
8
18
|
import { getFederatedServers } from './getFederatedServers';
|
|
9
19
|
import { getWellKnownAgentUrl } from './getWellKnownAgentUrl';
|
|
10
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
createLocalAgentUrl,
|
|
22
|
+
normalizeLocalAgentUrlReferences,
|
|
23
|
+
normalizeLocalServerUrls,
|
|
24
|
+
resolveLocalAgentRouteReference,
|
|
25
|
+
} from './localAgentRouteReferences';
|
|
26
|
+
import { createMissingImportedAgentFallback } from './createMissingImportedAgentFallback';
|
|
27
|
+
import { resolveInheritedAgentSource, type AgentSourceImporter } from './resolveInheritedAgentSource';
|
|
11
28
|
import { createServerPublicUrl, type ServerRecord } from './serverRegistry';
|
|
12
29
|
|
|
13
30
|
/**
|
|
@@ -111,11 +128,6 @@ type CustomDomainAgentRow = {
|
|
|
111
128
|
readonly agentSource: string;
|
|
112
129
|
};
|
|
113
130
|
|
|
114
|
-
/**
|
|
115
|
-
* Minimal agent identity row used to initialize compact-reference resolution.
|
|
116
|
-
*/
|
|
117
|
-
type CustomDomainAgentReferenceRow = Pick<CustomDomainAgentRow, 'agentName' | 'permanentId'>;
|
|
118
|
-
|
|
119
131
|
/**
|
|
120
132
|
* Minimal resolved metadata needed for custom-domain matching.
|
|
121
133
|
*/
|
|
@@ -127,7 +139,20 @@ type ResolvedCustomDomainMetadata = Pick<AgentBasicInformation, 'links' | 'meta'
|
|
|
127
139
|
* @param agents - Stored server-owned agents.
|
|
128
140
|
* @returns Lightweight collection compatible with the resolver initialization step.
|
|
129
141
|
*/
|
|
130
|
-
function createResolverAgentCollection(agents: ReadonlyArray<
|
|
142
|
+
function createResolverAgentCollection(agents: ReadonlyArray<CustomDomainAgentRow>): AgentCollection {
|
|
143
|
+
const resolveAgent = (agentNameOrPermanentId: string): CustomDomainAgentRow => {
|
|
144
|
+
const agent = agents.find(
|
|
145
|
+
(candidate) =>
|
|
146
|
+
candidate.agentName === agentNameOrPermanentId || candidate.permanentId === agentNameOrPermanentId,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
if (!agent) {
|
|
150
|
+
throw new NotFoundError(`Agent with name or id "${agentNameOrPermanentId}" not found`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return agent;
|
|
154
|
+
};
|
|
155
|
+
|
|
131
156
|
return {
|
|
132
157
|
async listAgents() {
|
|
133
158
|
return agents.map(
|
|
@@ -147,6 +172,13 @@ function createResolverAgentCollection(agents: ReadonlyArray<CustomDomainAgentRe
|
|
|
147
172
|
} satisfies AgentBasicInformation),
|
|
148
173
|
);
|
|
149
174
|
},
|
|
175
|
+
async getAgentPermanentId(agentNameOrPermanentId: string) {
|
|
176
|
+
const agent = resolveAgent(agentNameOrPermanentId);
|
|
177
|
+
return (agent.permanentId || agent.agentName) as string_agent_permanent_id;
|
|
178
|
+
},
|
|
179
|
+
async getAgentSource(agentNameOrPermanentId: string) {
|
|
180
|
+
return resolveAgent(agentNameOrPermanentId).agentSource as string_book;
|
|
181
|
+
},
|
|
150
182
|
} as unknown as AgentCollection;
|
|
151
183
|
}
|
|
152
184
|
|
|
@@ -181,6 +213,108 @@ function createCanonicalLocalAgentUrl(agent: CustomDomainAgentRow, localServerUr
|
|
|
181
213
|
return `${localServerUrl.replace(/\/+$/g, '')}/agents/${encodeURIComponent(canonicalAgentIdentifier)}`;
|
|
182
214
|
}
|
|
183
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Creates an Edge-safe local importer for custom-domain metadata resolution.
|
|
218
|
+
*
|
|
219
|
+
* @param options - Local collection and inheritance dependencies.
|
|
220
|
+
* @returns Local source importer for route-level agent URLs.
|
|
221
|
+
*/
|
|
222
|
+
function createCustomDomainLocalAgentSourceImporter(options: {
|
|
223
|
+
readonly collection: Pick<AgentCollection, 'getAgentPermanentId' | 'getAgentSource'>;
|
|
224
|
+
readonly localServerUrl: string;
|
|
225
|
+
readonly adamAgentUrl: string_agent_url;
|
|
226
|
+
readonly agentReferenceResolver: AgentReferenceResolver;
|
|
227
|
+
readonly federatedAgentImportConfiguration: FederatedAgentImportConfiguration;
|
|
228
|
+
}): AgentSourceImporter {
|
|
229
|
+
const localServerUrls = normalizeLocalServerUrls([options.localServerUrl]);
|
|
230
|
+
const localAgentUrlReferences = normalizeLocalAgentUrlReferences([options.adamAgentUrl]);
|
|
231
|
+
const agentSourceImporter: AgentSourceImporter = async (agentUrl, context) => {
|
|
232
|
+
const localRouteReference = resolveLocalAgentRouteReference(agentUrl, localServerUrls, localAgentUrlReferences);
|
|
233
|
+
|
|
234
|
+
if (!localRouteReference) {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const nextRecursionLevel = (context.importAgentOptions.recursionLevel || 0) + 1;
|
|
239
|
+
assertCustomDomainLocalImportRecursionLevel(nextRecursionLevel, agentUrl);
|
|
240
|
+
|
|
241
|
+
let agentPermanentId: string_agent_permanent_id;
|
|
242
|
+
let unresolvedAgentSource: string_book;
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
agentPermanentId = await options.collection.getAgentPermanentId(localRouteReference.agentIdentifier);
|
|
246
|
+
unresolvedAgentSource = await options.collection.getAgentSource(agentPermanentId);
|
|
247
|
+
} catch (error) {
|
|
248
|
+
if (error instanceof NotFoundError) {
|
|
249
|
+
return createMissingImportedAgentFallback(agentUrl, 1, error);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
throw error;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const resolvedAgentName = readAgentSourceTitle(unresolvedAgentSource) || localRouteReference.agentIdentifier;
|
|
256
|
+
const canonicalAgentUrl = createLocalAgentUrl(localRouteReference.localServerUrl, agentPermanentId);
|
|
257
|
+
|
|
258
|
+
return resolveInheritedAgentSource(unresolvedAgentSource, {
|
|
259
|
+
adamAgentUrl: options.adamAgentUrl,
|
|
260
|
+
recursionLevel: nextRecursionLevel,
|
|
261
|
+
inheritancePath: context.importAgentOptions.inheritancePath,
|
|
262
|
+
currentAgentUrl: canonicalAgentUrl,
|
|
263
|
+
currentAgentAliases: [
|
|
264
|
+
canonicalAgentUrl,
|
|
265
|
+
createLocalAgentUrl(localRouteReference.localServerUrl, localRouteReference.agentIdentifier),
|
|
266
|
+
createLocalAgentUrl(localRouteReference.localServerUrl, resolvedAgentName),
|
|
267
|
+
].filter((value, index, values): value is string_agent_url => values.indexOf(value) === index),
|
|
268
|
+
agentReferenceResolver: options.agentReferenceResolver,
|
|
269
|
+
federatedAgentImportConfiguration:
|
|
270
|
+
options.federatedAgentImportConfiguration || context.federatedAgentImportConfiguration,
|
|
271
|
+
agentSourceImporter,
|
|
272
|
+
});
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
return agentSourceImporter;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Reads the first non-empty title line from one book source.
|
|
280
|
+
*
|
|
281
|
+
* @param agentSource - Agent book source.
|
|
282
|
+
* @returns Title or `null` when the source has no title line.
|
|
283
|
+
*/
|
|
284
|
+
function readAgentSourceTitle(agentSource: string_book): string | null {
|
|
285
|
+
for (const line of agentSource.split(/\r?\n/)) {
|
|
286
|
+
const title = line.trim();
|
|
287
|
+
|
|
288
|
+
if (title) {
|
|
289
|
+
return title;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Throws when direct local importing would exceed the configured recursion limit.
|
|
298
|
+
*
|
|
299
|
+
* @param recursionLevel - Next recursion level.
|
|
300
|
+
* @param agentUrl - Local agent URL being imported.
|
|
301
|
+
*/
|
|
302
|
+
function assertCustomDomainLocalImportRecursionLevel(recursionLevel: number, agentUrl: string_agent_url): void {
|
|
303
|
+
if (recursionLevel <= DEFAULT_MAX_RECURSION) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
throw new ParseError(
|
|
308
|
+
spaceTrim(
|
|
309
|
+
(block) => `
|
|
310
|
+
Recursion depth ${recursionLevel} exceeds maximum allowed ${DEFAULT_MAX_RECURSION} while importing local custom-domain agent:
|
|
311
|
+
|
|
312
|
+
${block(agentUrl)}
|
|
313
|
+
`,
|
|
314
|
+
),
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
|
|
184
318
|
/**
|
|
185
319
|
* Parses only the resolved custom-domain metadata used by proxy routing.
|
|
186
320
|
*
|
|
@@ -254,6 +388,7 @@ async function resolveCustomDomainMetadataForAgent(
|
|
|
254
388
|
readonly adamAgentUrl: string;
|
|
255
389
|
readonly agentReferenceResolver: Awaited<ReturnType<typeof createServerAgentReferenceResolver>>;
|
|
256
390
|
readonly federatedAgentImportConfiguration: FederatedAgentImportConfiguration;
|
|
391
|
+
readonly agentSourceImporter: AgentSourceImporter;
|
|
257
392
|
},
|
|
258
393
|
): Promise<ResolvedCustomDomainMetadata> {
|
|
259
394
|
const resolvedAgentSource = await resolveInheritedAgentSource(agent.agentSource as string_book, {
|
|
@@ -261,6 +396,7 @@ async function resolveCustomDomainMetadataForAgent(
|
|
|
261
396
|
currentAgentUrl: createCanonicalLocalAgentUrl(agent, options.localServerUrl),
|
|
262
397
|
agentReferenceResolver: options.agentReferenceResolver,
|
|
263
398
|
federatedAgentImportConfiguration: options.federatedAgentImportConfiguration,
|
|
399
|
+
agentSourceImporter: options.agentSourceImporter,
|
|
264
400
|
});
|
|
265
401
|
|
|
266
402
|
return parseResolvedCustomDomainMetadata(resolvedAgentSource);
|
|
@@ -309,7 +445,7 @@ export async function resolveCustomDomainAgent(
|
|
|
309
445
|
|
|
310
446
|
const { data: resolverReferenceAgents, error: resolverReferenceError } = await supabase
|
|
311
447
|
.from(tableName)
|
|
312
|
-
.select('agentName, permanentId')
|
|
448
|
+
.select('agentName, permanentId, agentSource')
|
|
313
449
|
.is('deletedAt', null);
|
|
314
450
|
|
|
315
451
|
if (resolverReferenceError || !Array.isArray(resolverReferenceAgents)) {
|
|
@@ -317,13 +453,21 @@ export async function resolveCustomDomainAgent(
|
|
|
317
453
|
}
|
|
318
454
|
|
|
319
455
|
const localServerUrl = createServerPublicUrl(server.domain).href;
|
|
456
|
+
const agentCollection = createResolverAgentCollection(
|
|
457
|
+
resolverReferenceAgents as Array<CustomDomainAgentRow>,
|
|
458
|
+
);
|
|
320
459
|
const agentReferenceResolver = await createServerAgentReferenceResolver({
|
|
321
|
-
agentCollection
|
|
322
|
-
resolverReferenceAgents as Array<CustomDomainAgentReferenceRow>,
|
|
323
|
-
),
|
|
460
|
+
agentCollection,
|
|
324
461
|
localServerUrl,
|
|
325
462
|
federatedServers,
|
|
326
463
|
});
|
|
464
|
+
const agentSourceImporter = createCustomDomainLocalAgentSourceImporter({
|
|
465
|
+
collection: agentCollection,
|
|
466
|
+
localServerUrl,
|
|
467
|
+
adamAgentUrl,
|
|
468
|
+
agentReferenceResolver,
|
|
469
|
+
federatedAgentImportConfiguration,
|
|
470
|
+
});
|
|
327
471
|
|
|
328
472
|
let matchedAgent: CustomDomainAgentRow | undefined;
|
|
329
473
|
|
|
@@ -333,6 +477,7 @@ export async function resolveCustomDomainAgent(
|
|
|
333
477
|
adamAgentUrl,
|
|
334
478
|
agentReferenceResolver,
|
|
335
479
|
federatedAgentImportConfiguration,
|
|
480
|
+
agentSourceImporter,
|
|
336
481
|
});
|
|
337
482
|
|
|
338
483
|
if (matchesResolvedCustomDomain(resolvedMetadata, candidates)) {
|
|
@@ -153,7 +153,7 @@ async function enqueueExternalUserChatJob(job: UserChatJobRecord): Promise<Proce
|
|
|
153
153
|
return { didMutate: false, outcome: 'waiting' };
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
const threadMessages = createUserChatRunnerThreadMessages({
|
|
156
|
+
const threadMessages = await createUserChatRunnerThreadMessages({
|
|
157
157
|
messages: chat.messages,
|
|
158
158
|
userMessageId: job.userMessageId,
|
|
159
159
|
resolveInitialAgentMessage: () => parseAgentSource(agentSourceSnapshot.agentSource).initialMessage,
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { padBook } from '../../../../src/book-2.0/agent-source/padBook';
|
|
2
|
-
import { validateBook } from '../../../../src/book-2.0/agent-source/string_book';
|
|
3
1
|
import type { string_agent_url } from '../../../../src/types/typeAliases';
|
|
4
2
|
import type { string_book } from '../../../../src/book-2.0/agent-source/string_book';
|
|
5
|
-
import { spaceTrim } from '../../../../src/utils/organization/spaceTrim';
|
|
6
3
|
import {
|
|
7
4
|
DEFAULT_FEDERATED_AGENT_IMPORT_CONFIGURATION,
|
|
8
5
|
type FederatedAgentImportConfiguration,
|
|
9
6
|
} from '../constants/federatedAgentImport';
|
|
7
|
+
import { createMissingImportedAgentFallback } from './createMissingImportedAgentFallback';
|
|
10
8
|
import { retryWithBackoff } from './retryWithBackoff';
|
|
11
9
|
import { importAgent, type ImportAgentOptions } from './importAgent';
|
|
12
10
|
|
|
@@ -40,61 +38,6 @@ const cachedFailedImportedAgentFallbackByKey = new Map<string, FailedImportedAge
|
|
|
40
38
|
*/
|
|
41
39
|
const pendingImportedAgentFallbackByKey = new Map<string, Promise<string_book>>();
|
|
42
40
|
|
|
43
|
-
/**
|
|
44
|
-
* Collapses one thrown error into a single-line message suitable for `NOTE` commitments.
|
|
45
|
-
*
|
|
46
|
-
* @param agentUrl - Canonical imported agent URL.
|
|
47
|
-
* @param error - Unknown error raised while loading the imported agent.
|
|
48
|
-
* @returns Human-readable single-line failure reason.
|
|
49
|
-
*
|
|
50
|
-
* @private internal helper for imported-agent fallback books
|
|
51
|
-
*/
|
|
52
|
-
function normalizeImportFailureMessage(agentUrl: string_agent_url, error: unknown): string {
|
|
53
|
-
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
54
|
-
const normalizedMessage = rawMessage.replace(/\s+/g, ' ').trim();
|
|
55
|
-
const prefix = `Failed to import agent from "${agentUrl}"`;
|
|
56
|
-
|
|
57
|
-
if (normalizedMessage.startsWith(prefix)) {
|
|
58
|
-
const suffix = normalizedMessage.slice(prefix.length).trim();
|
|
59
|
-
if (suffix.length > 0) {
|
|
60
|
-
return suffix.replace(/^[-:,\s]+/, '').trim() || 'unknown error';
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return normalizedMessage || 'unknown error';
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Creates the ad-hoc fallback source returned when a federated imported agent stays unavailable.
|
|
69
|
-
*
|
|
70
|
-
* @param agentUrl - Canonical imported agent URL.
|
|
71
|
-
* @param attempts - Total number of attempts that were used.
|
|
72
|
-
* @param error - Final error raised by the failed import attempts.
|
|
73
|
-
* @returns Valid fallback book source.
|
|
74
|
-
*
|
|
75
|
-
* @private internal helper for imported-agent fallback books
|
|
76
|
-
*/
|
|
77
|
-
function createMissingImportedAgentFallback(
|
|
78
|
-
agentUrl: string_agent_url,
|
|
79
|
-
attempts: number,
|
|
80
|
-
error: unknown,
|
|
81
|
-
): string_book {
|
|
82
|
-
const failureMessage = normalizeImportFailureMessage(agentUrl, error);
|
|
83
|
-
|
|
84
|
-
return padBook(
|
|
85
|
-
validateBook(
|
|
86
|
-
spaceTrim(
|
|
87
|
-
`
|
|
88
|
-
Not found agent
|
|
89
|
-
|
|
90
|
-
NOTE This agent was supposed to be imported from ${agentUrl}, but it can not be loaded after ${attempts} attempts because of ${failureMessage}
|
|
91
|
-
CLOSED
|
|
92
|
-
`,
|
|
93
|
-
),
|
|
94
|
-
),
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
41
|
/**
|
|
99
42
|
* Builds the stable cache key used for import-with-fallback memoization.
|
|
100
43
|
*
|