@promptbook/cli 0.112.0-111 → 0.112.0-113
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/README.md +7 -7
- package/apps/agents-server/README.md +1 -1
- package/apps/agents-server/next.config.ts +20 -1
- package/apps/agents-server/src/app/admin/servers/CreateServerDialog.tsx +16 -0
- package/apps/agents-server/src/app/admin/servers/useCreateServerWizard.ts +31 -5
- package/apps/agents-server/src/app/api/admin/code-runners/route.ts +1 -1
- package/apps/agents-server/src/app/api/admin/servers/route.ts +5 -0
- package/apps/agents-server/src/app/api/internal/user-chat-jobs/run/route.ts +1 -1
- package/apps/agents-server/src/app/api/metadata/route.ts +4 -0
- package/apps/agents-server/src/database/customJavascript.ts +62 -1
- package/apps/agents-server/src/database/customStylesheet.ts +60 -1
- package/apps/agents-server/src/database/getMetadata.ts +84 -3
- package/apps/agents-server/src/instrumentation-client.ts +28 -0
- package/apps/agents-server/src/instrumentation.ts +19 -0
- package/apps/agents-server/src/sentry.edge.config.ts +18 -0
- package/apps/agents-server/src/sentry.server.config.ts +19 -0
- package/apps/agents-server/src/utils/codeRunnerConfiguration.ts +1 -1
- package/apps/agents-server/src/utils/errorReporting/agentsServerSentryContext.ts +203 -0
- package/apps/agents-server/src/utils/errorReporting/registerServerErrorSentryLogging.ts +381 -0
- package/apps/agents-server/src/utils/errorReporting/sendApplicationErrorReportToSentry.ts +43 -152
- package/apps/agents-server/src/utils/errorReporting/sentrySdkConfig.ts +237 -0
- package/apps/agents-server/src/utils/errorReporting/sentryStore.ts +187 -0
- package/apps/agents-server/src/utils/externalChatRunner/createExternalAgentRepositoryFiles.ts +2 -2
- package/apps/agents-server/src/utils/serverManagement/createManagedServer/bootstrapManagedServer.ts +3 -1
- package/apps/agents-server/src/utils/serverManagement/createManagedServer/normalizeCreateServerInput.ts +6 -0
- package/apps/agents-server/src/utils/serverManagement/createManagedServer/seedServerDefaultAgents.ts +7 -3
- package/apps/agents-server/src/utils/serverManagement/createManagedServer.ts +5 -0
- package/apps/agents-server/src/utils/userChat/listUserChats.ts +109 -0
- package/apps/agents-server/src/utils/userChat/triggerUserChatJobWorker.ts +54 -19
- package/apps/agents-server/src/utils/vpsConfiguration.ts +1 -1
- package/esm/index.es.js +9256 -8795
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-agent-chat/executeAgentChatTurn.d.ts +28 -0
- package/esm/scripts/run-agent-chat/runAgentChat.d.ts +5 -0
- package/esm/scripts/run-agent-chat/runAgentExec.d.ts +11 -0
- package/esm/scripts/run-agent-messages/messages/createAgentRunnerSystemMessage.d.ts +10 -0
- package/esm/scripts/run-codex-prompts/common/resolveInlineOrFileText.d.ts +14 -0
- package/esm/src/_packages/node.index.d.ts +20 -0
- package/esm/src/_packages/types.index.d.ts +16 -0
- package/esm/src/book-3.0/BookNodeAgentSource.d.ts +38 -0
- package/esm/src/book-3.0/CliAgent.d.ts +68 -0
- package/esm/src/book-3.0/CliAgent.test.d.ts +1 -0
- package/esm/src/book-3.0/LiteAgent.d.ts +68 -0
- package/esm/src/book-3.0/LiteAgent.test.d.ts +1 -0
- package/esm/src/book-components/BookEditor/BookEditorAboutPromptbookInformation.d.ts +12 -0
- package/esm/src/cli/cli-commands/agent/agentCliOptions.d.ts +29 -0
- package/esm/src/cli/cli-commands/agent/chat.d.ts +10 -0
- package/esm/src/cli/cli-commands/agent/exec.d.ts +10 -0
- package/esm/src/cli/cli-commands/agent/run.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agent.d.ts +14 -0
- package/esm/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +2 -2
- package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +9 -9
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -1
- package/src/_packages/node.index.ts +20 -0
- package/src/_packages/types.index.ts +16 -0
- package/src/book-3.0/BookNodeAgentSource.ts +135 -0
- package/src/book-3.0/CliAgent.ts +236 -0
- package/src/book-3.0/LiteAgent.ts +463 -0
- package/src/book-components/BookEditor/BookEditor.module.css +61 -0
- package/src/book-components/BookEditor/BookEditorAboutPromptbookInformation.tsx +74 -0
- package/src/book-components/BookEditor/BookEditorActionbar.tsx +3 -3
- package/src/cli/cli-commands/agent/agentCliOptions.ts +63 -0
- package/src/cli/cli-commands/agent/chat.ts +54 -0
- package/src/cli/cli-commands/agent/exec.ts +60 -0
- package/src/cli/cli-commands/agent.ts +45 -0
- package/src/cli/cli-commands/agents-server/startAgentsServer.ts +2 -2
- package/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.ts +1 -1
- package/src/cli/cli-commands/common/promptRunnerCliOptions.ts +27 -23
- package/src/cli/promptbookCli.ts +2 -0
- package/src/other/templates/getTemplatesPipelineCollection.ts +809 -901
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -0
- package/umd/index.umd.js +9255 -8794
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-agent-chat/executeAgentChatTurn.d.ts +28 -0
- package/umd/scripts/run-agent-chat/runAgentChat.d.ts +5 -0
- package/umd/scripts/run-agent-chat/runAgentExec.d.ts +11 -0
- package/umd/scripts/run-agent-messages/messages/createAgentRunnerSystemMessage.d.ts +10 -0
- package/umd/scripts/run-codex-prompts/common/resolveInlineOrFileText.d.ts +14 -0
- package/umd/src/_packages/node.index.d.ts +20 -0
- package/umd/src/_packages/types.index.d.ts +16 -0
- package/umd/src/book-3.0/BookNodeAgentSource.d.ts +38 -0
- package/umd/src/book-3.0/CliAgent.d.ts +68 -0
- package/umd/src/book-3.0/CliAgent.test.d.ts +1 -0
- package/umd/src/book-3.0/LiteAgent.d.ts +68 -0
- package/umd/src/book-3.0/LiteAgent.test.d.ts +1 -0
- package/umd/src/book-components/BookEditor/BookEditorAboutPromptbookInformation.d.ts +12 -0
- package/umd/src/cli/cli-commands/agent/agentCliOptions.d.ts +29 -0
- package/umd/src/cli/cli-commands/agent/chat.d.ts +10 -0
- package/umd/src/cli/cli-commands/agent/exec.d.ts +10 -0
- package/umd/src/cli/cli-commands/agent/run.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agent.d.ts +14 -0
- package/umd/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +2 -2
- package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +9 -9
- package/umd/src/version.d.ts +1 -1
|
@@ -1,146 +1,18 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/nextjs';
|
|
1
2
|
import type { ApplicationErrorReportPayload } from './applicationErrorHandling';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* Endpoint content type used when sending JSON payloads to Sentry.
|
|
10
|
-
*/
|
|
11
|
-
const JSON_CONTENT_TYPE = 'application/json';
|
|
3
|
+
import { enrichSentryStorePayloadWithAgentsServerContext } from './agentsServerSentryContext';
|
|
4
|
+
import {
|
|
5
|
+
createSentryTimestamp,
|
|
6
|
+
resolveRequiredSentryDsn,
|
|
7
|
+
sendSentryStorePayload,
|
|
8
|
+
type SentryStorePayload,
|
|
9
|
+
} from './sentryStore';
|
|
12
10
|
|
|
13
11
|
/**
|
|
14
12
|
* Logger name visible in Sentry events.
|
|
15
13
|
*/
|
|
16
14
|
const SENTRY_APPLICATION_ERROR_LOGGER = 'agents-server.application-error';
|
|
17
15
|
|
|
18
|
-
/**
|
|
19
|
-
* Number of milliseconds in one second.
|
|
20
|
-
*/
|
|
21
|
-
const MILLISECONDS_IN_SECOND = 1000;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Minimal Sentry DSN parts needed for store API requests.
|
|
25
|
-
*/
|
|
26
|
-
type SentryDsnParts = {
|
|
27
|
-
/**
|
|
28
|
-
* Store endpoint derived from DSN host/project.
|
|
29
|
-
*/
|
|
30
|
-
storeEndpoint: URL;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Payload shape submitted to the Sentry store endpoint.
|
|
35
|
-
*/
|
|
36
|
-
type SentryStorePayload = {
|
|
37
|
-
/**
|
|
38
|
-
* Event platform.
|
|
39
|
-
*/
|
|
40
|
-
platform: 'javascript';
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Event level.
|
|
44
|
-
*/
|
|
45
|
-
level: 'error';
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Event logger value.
|
|
49
|
-
*/
|
|
50
|
-
logger: string;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Seconds since UNIX epoch.
|
|
54
|
-
*/
|
|
55
|
-
timestamp: number;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Human readable message.
|
|
59
|
-
*/
|
|
60
|
-
message: string;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Server/deployment name.
|
|
64
|
-
*/
|
|
65
|
-
server_name: string;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Diagnostic tags used for filtering.
|
|
69
|
-
*/
|
|
70
|
-
tags: Record<string, string>;
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Structured exception details.
|
|
74
|
-
*/
|
|
75
|
-
exception: {
|
|
76
|
-
/**
|
|
77
|
-
* Individual exception list.
|
|
78
|
-
*/
|
|
79
|
-
values: Array<{
|
|
80
|
-
/**
|
|
81
|
-
* Exception type.
|
|
82
|
-
*/
|
|
83
|
-
type: string;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Exception message.
|
|
87
|
-
*/
|
|
88
|
-
value: string;
|
|
89
|
-
}>;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Additional diagnostic payload.
|
|
94
|
-
*/
|
|
95
|
-
extra: Record<string, string | null>;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Resolves Sentry DSN from environment.
|
|
100
|
-
*
|
|
101
|
-
* @returns Raw DSN string.
|
|
102
|
-
* @throws Error when DSN is missing.
|
|
103
|
-
*/
|
|
104
|
-
function resolveSentryDsn(): string {
|
|
105
|
-
const dsn = process.env.SENTRY_DSN ?? process.env.NEXT_PUBLIC_SENTRY_DSN;
|
|
106
|
-
if (!dsn) {
|
|
107
|
-
throw new Error('Missing Sentry DSN. Configure SENTRY_DSN or NEXT_PUBLIC_SENTRY_DSN.');
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return dsn;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Parses a DSN into pieces required for Sentry store API requests.
|
|
115
|
-
*
|
|
116
|
-
* @param dsn - Raw Sentry DSN.
|
|
117
|
-
* @returns Parsed DSN details.
|
|
118
|
-
* @throws Error when DSN format is invalid.
|
|
119
|
-
*/
|
|
120
|
-
function parseSentryDsn(dsn: string): SentryDsnParts {
|
|
121
|
-
const dsnUrl = new URL(dsn);
|
|
122
|
-
const pathSegments = dsnUrl.pathname.split('/').filter(Boolean);
|
|
123
|
-
const projectId = pathSegments.at(-1);
|
|
124
|
-
const pathPrefix = pathSegments.slice(0, -1).join('/');
|
|
125
|
-
|
|
126
|
-
if (!projectId) {
|
|
127
|
-
throw new Error('Invalid Sentry DSN: missing project ID.');
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (!dsnUrl.username) {
|
|
131
|
-
throw new Error('Invalid Sentry DSN: missing public key.');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const basePath = pathPrefix ? `/${pathPrefix}` : '';
|
|
135
|
-
const storeEndpoint = new URL(`${dsnUrl.protocol}//${dsnUrl.host}${basePath}/api/${projectId}/store/`);
|
|
136
|
-
storeEndpoint.searchParams.set('sentry_key', dsnUrl.username);
|
|
137
|
-
storeEndpoint.searchParams.set('sentry_version', SENTRY_PROTOCOL_VERSION);
|
|
138
|
-
|
|
139
|
-
return {
|
|
140
|
-
storeEndpoint,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
|
|
144
16
|
/**
|
|
145
17
|
* Creates the Sentry-compatible JSON payload from the application report.
|
|
146
18
|
*
|
|
@@ -148,11 +20,11 @@ function parseSentryDsn(dsn: string): SentryDsnParts {
|
|
|
148
20
|
* @returns Sentry store payload.
|
|
149
21
|
*/
|
|
150
22
|
function createSentryStorePayload(report: ApplicationErrorReportPayload): SentryStorePayload {
|
|
151
|
-
return {
|
|
23
|
+
return enrichSentryStorePayloadWithAgentsServerContext({
|
|
152
24
|
platform: 'javascript',
|
|
153
25
|
level: 'error',
|
|
154
26
|
logger: SENTRY_APPLICATION_ERROR_LOGGER,
|
|
155
|
-
timestamp:
|
|
27
|
+
timestamp: createSentryTimestamp(),
|
|
156
28
|
message: report.errorMessage,
|
|
157
29
|
server_name: report.serverName,
|
|
158
30
|
tags: {
|
|
@@ -174,7 +46,7 @@ function createSentryStorePayload(report: ApplicationErrorReportPayload): Sentry
|
|
|
174
46
|
pageUrl: report.pageUrl ?? null,
|
|
175
47
|
reportedAt: report.reportedAt,
|
|
176
48
|
},
|
|
177
|
-
};
|
|
49
|
+
});
|
|
178
50
|
}
|
|
179
51
|
|
|
180
52
|
/**
|
|
@@ -183,20 +55,39 @@ function createSentryStorePayload(report: ApplicationErrorReportPayload): Sentry
|
|
|
183
55
|
* @param report - Structured browser report payload.
|
|
184
56
|
*/
|
|
185
57
|
export async function sendApplicationErrorReportToSentry(report: ApplicationErrorReportPayload): Promise<void> {
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
58
|
+
const sentryPayload = createSentryStorePayload(report);
|
|
59
|
+
|
|
60
|
+
if (Sentry.getClient()) {
|
|
61
|
+
Sentry.captureException(createApplicationErrorSdkException(report, sentryPayload), {
|
|
62
|
+
level: sentryPayload.level,
|
|
63
|
+
tags: sentryPayload.tags,
|
|
64
|
+
extra: sentryPayload.extra,
|
|
65
|
+
});
|
|
66
|
+
await Sentry.flush(2000);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
189
69
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
headers: {
|
|
193
|
-
'Content-Type': JSON_CONTENT_TYPE,
|
|
194
|
-
},
|
|
195
|
-
body: JSON.stringify(payload),
|
|
196
|
-
});
|
|
70
|
+
await sendSentryStorePayload(sentryPayload, resolveRequiredSentryDsn());
|
|
71
|
+
}
|
|
197
72
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Rebuilds an `Error` object from a browser application report so the SDK can parse stack frames.
|
|
75
|
+
*
|
|
76
|
+
* @param report - Browser-generated application error report.
|
|
77
|
+
* @param sentryPayload - Structured Sentry payload created from the report.
|
|
78
|
+
* @returns Error object with the original browser stack when available.
|
|
79
|
+
*/
|
|
80
|
+
function createApplicationErrorSdkException(
|
|
81
|
+
report: ApplicationErrorReportPayload,
|
|
82
|
+
sentryPayload: SentryStorePayload,
|
|
83
|
+
): Error {
|
|
84
|
+
const error = new Error(sentryPayload.message);
|
|
85
|
+
|
|
86
|
+
error.name = report.errorName || 'Error';
|
|
87
|
+
|
|
88
|
+
if (report.errorStack?.trim()) {
|
|
89
|
+
error.stack = report.errorStack;
|
|
201
90
|
}
|
|
91
|
+
|
|
92
|
+
return error;
|
|
202
93
|
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { BOOK_LANGUAGE_VERSION, PROMPTBOOK_ENGINE_VERSION } from '../../../../../src/version';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default Sentry project DSN for Promptbook Agents Server telemetry.
|
|
5
|
+
*
|
|
6
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_SENTRY_DSN =
|
|
9
|
+
'https://986f734e9cddaeeec33e2a360f7d0b62@o4508778158030848.ingest.de.sentry.io/4511534509785168';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Sentry organization slug used by build-time SDK tooling.
|
|
13
|
+
*
|
|
14
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
15
|
+
*/
|
|
16
|
+
export const SENTRY_ORGANIZATION = 'promptbook';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Sentry project slug used by build-time SDK tooling.
|
|
20
|
+
*
|
|
21
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
22
|
+
*/
|
|
23
|
+
export const SENTRY_PROJECT = 's22';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Performance tracing sample rate requested for the Agents Server.
|
|
27
|
+
*
|
|
28
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
29
|
+
*/
|
|
30
|
+
export const SENTRY_TRACES_SAMPLE_RATE = 1.0;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Browser-side targets that should receive distributed tracing headers.
|
|
34
|
+
*
|
|
35
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
36
|
+
*/
|
|
37
|
+
export const SENTRY_TRACE_PROPAGATION_TARGETS: Array<string | RegExp> = [
|
|
38
|
+
'localhost',
|
|
39
|
+
/^\/api\//,
|
|
40
|
+
/^https:\/\/.*\.ptbk\.io\/api\//,
|
|
41
|
+
/^https:\/\/.*\.vercel\.app\/api\//,
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Release name used for Agents Server Sentry events.
|
|
46
|
+
*/
|
|
47
|
+
const AGENTS_SERVER_SENTRY_RELEASE_NAME = 'promptbook-agents-server';
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Fallback text used in Sentry tags when a value is not configured.
|
|
51
|
+
*/
|
|
52
|
+
const UNKNOWN_SENTRY_CONTEXT_VALUE = 'unknown';
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Maximum length kept for Sentry tag values.
|
|
56
|
+
*/
|
|
57
|
+
const MAX_SENTRY_TAG_VALUE_LENGTH = 200;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Resolves the browser-safe Sentry DSN.
|
|
61
|
+
*
|
|
62
|
+
* @returns Browser-safe Sentry DSN.
|
|
63
|
+
*
|
|
64
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
65
|
+
*/
|
|
66
|
+
export function resolveBrowserSentryDsn(): string {
|
|
67
|
+
return process.env.NEXT_PUBLIC_SENTRY_DSN ?? DEFAULT_SENTRY_DSN;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Resolves the server-side Sentry DSN.
|
|
72
|
+
*
|
|
73
|
+
* @returns Server-side Sentry DSN.
|
|
74
|
+
*
|
|
75
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
76
|
+
*/
|
|
77
|
+
export function resolveServerSentryDsn(): string {
|
|
78
|
+
return process.env.SENTRY_DSN ?? resolveBrowserSentryDsn();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Resolves the most specific deployment environment name available.
|
|
83
|
+
*
|
|
84
|
+
* @returns Environment name suitable for Sentry.
|
|
85
|
+
*
|
|
86
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
87
|
+
*/
|
|
88
|
+
export function resolveSentrySdkEnvironment(): string {
|
|
89
|
+
return (
|
|
90
|
+
getFirstNonEmptyString(
|
|
91
|
+
process.env.SENTRY_ENVIRONMENT,
|
|
92
|
+
process.env.NEXT_PUBLIC_VERCEL_TARGET_ENV,
|
|
93
|
+
process.env.VERCEL_TARGET_ENV,
|
|
94
|
+
process.env.NEXT_PUBLIC_VERCEL_ENV,
|
|
95
|
+
process.env.VERCEL_ENV,
|
|
96
|
+
process.env.PROMPTBOOK_REPOSITORY_REF,
|
|
97
|
+
process.env.NODE_ENV,
|
|
98
|
+
) ?? UNKNOWN_SENTRY_CONTEXT_VALUE
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Resolves the current deployment commit hash from common hosting environment variables.
|
|
104
|
+
*
|
|
105
|
+
* @returns Commit hash or null when unavailable.
|
|
106
|
+
*
|
|
107
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
108
|
+
*/
|
|
109
|
+
export function resolveSentrySdkCommitHash(): string | null {
|
|
110
|
+
return getFirstNonEmptyString(
|
|
111
|
+
process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,
|
|
112
|
+
process.env.VERCEL_GIT_COMMIT_SHA,
|
|
113
|
+
process.env.PROMPTBOOK_COMMIT_SHA,
|
|
114
|
+
process.env.GIT_COMMIT_SHA,
|
|
115
|
+
process.env.COMMIT_SHA,
|
|
116
|
+
process.env.SOURCE_VERSION,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Resolves the current repository branch or deployment ref.
|
|
122
|
+
*
|
|
123
|
+
* @returns Repository branch/ref or null when unavailable.
|
|
124
|
+
*
|
|
125
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
126
|
+
*/
|
|
127
|
+
export function resolveSentrySdkRepositoryBranch(): string | null {
|
|
128
|
+
return getFirstNonEmptyString(
|
|
129
|
+
process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF,
|
|
130
|
+
process.env.VERCEL_GIT_COMMIT_REF,
|
|
131
|
+
process.env.PROMPTBOOK_REPOSITORY_REF,
|
|
132
|
+
process.env.GIT_BRANCH,
|
|
133
|
+
process.env.BRANCH_NAME,
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Resolves the Sentry release name for the current Agents Server build.
|
|
139
|
+
*
|
|
140
|
+
* @returns Release identifier suitable for Sentry.
|
|
141
|
+
*
|
|
142
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
143
|
+
*/
|
|
144
|
+
export function resolveSentrySdkRelease(): string {
|
|
145
|
+
const appPackageVersion = normalizeOptionalString(process.env.npm_package_version) ?? PROMPTBOOK_ENGINE_VERSION;
|
|
146
|
+
const commitHash = resolveSentrySdkCommitHash();
|
|
147
|
+
|
|
148
|
+
if (!commitHash) {
|
|
149
|
+
return `${AGENTS_SERVER_SENTRY_RELEASE_NAME}@${appPackageVersion}`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return `${AGENTS_SERVER_SENTRY_RELEASE_NAME}@${appPackageVersion}+${commitHash}`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Creates shared filterable Sentry tags for Agents Server events.
|
|
157
|
+
*
|
|
158
|
+
* @returns Sanitized Sentry tags.
|
|
159
|
+
*
|
|
160
|
+
* @private internal Sentry SDK configuration for Agents Server
|
|
161
|
+
*/
|
|
162
|
+
export function createSentrySdkTags(): Record<string, string> {
|
|
163
|
+
return createSentryTags({
|
|
164
|
+
promptbookEngineVersion: PROMPTBOOK_ENGINE_VERSION,
|
|
165
|
+
bookLanguageVersion: BOOK_LANGUAGE_VERSION,
|
|
166
|
+
appPackageVersion: normalizeOptionalString(process.env.npm_package_version) ?? PROMPTBOOK_ENGINE_VERSION,
|
|
167
|
+
commitHash: resolveSentrySdkCommitHash(),
|
|
168
|
+
repositoryBranch: resolveSentrySdkRepositoryBranch(),
|
|
169
|
+
deploymentEnvironment: resolveSentrySdkEnvironment(),
|
|
170
|
+
vercelEnvironment: getFirstNonEmptyString(process.env.NEXT_PUBLIC_VERCEL_ENV, process.env.VERCEL_ENV),
|
|
171
|
+
targetEnvironment: getFirstNonEmptyString(
|
|
172
|
+
process.env.NEXT_PUBLIC_VERCEL_TARGET_ENV,
|
|
173
|
+
process.env.VERCEL_TARGET_ENV,
|
|
174
|
+
),
|
|
175
|
+
nextRuntime: process.env.NEXT_RUNTIME,
|
|
176
|
+
nodeEnvironment: process.env.NODE_ENV,
|
|
177
|
+
vercelRegion: process.env.VERCEL_REGION,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Creates Sentry tag values, preserving missing values as explicit `unknown` markers.
|
|
183
|
+
*
|
|
184
|
+
* @param values - Raw tag values.
|
|
185
|
+
* @returns Sanitized Sentry tags.
|
|
186
|
+
*/
|
|
187
|
+
function createSentryTags(values: Record<string, string | null | undefined>): Record<string, string> {
|
|
188
|
+
return Object.fromEntries(
|
|
189
|
+
Object.entries(values).map(([key, value]) => [key, sanitizeSentryTagValue(value)]),
|
|
190
|
+
) as Record<string, string>;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Normalizes one value for use as a Sentry tag.
|
|
195
|
+
*
|
|
196
|
+
* @param value - Optional tag value.
|
|
197
|
+
* @returns Non-empty bounded tag value.
|
|
198
|
+
*/
|
|
199
|
+
function sanitizeSentryTagValue(value: string | null | undefined): string {
|
|
200
|
+
const normalizedValue = normalizeOptionalString(value) ?? UNKNOWN_SENTRY_CONTEXT_VALUE;
|
|
201
|
+
|
|
202
|
+
return normalizedValue.replace(/\s+/gu, ' ').slice(0, MAX_SENTRY_TAG_VALUE_LENGTH);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Returns the first non-empty string from a list.
|
|
207
|
+
*
|
|
208
|
+
* @param values - Candidate values in priority order.
|
|
209
|
+
* @returns First trimmed string or null.
|
|
210
|
+
*/
|
|
211
|
+
function getFirstNonEmptyString(...values: Array<string | null | undefined>): string | null {
|
|
212
|
+
for (const value of values) {
|
|
213
|
+
const normalizedValue = normalizeOptionalString(value);
|
|
214
|
+
|
|
215
|
+
if (normalizedValue) {
|
|
216
|
+
return normalizedValue;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Trims one optional environment value.
|
|
225
|
+
*
|
|
226
|
+
* @param value - Raw optional value.
|
|
227
|
+
* @returns Trimmed string or null.
|
|
228
|
+
*/
|
|
229
|
+
function normalizeOptionalString(value: string | null | undefined): string | null {
|
|
230
|
+
if (typeof value !== 'string') {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const normalizedValue = value.trim();
|
|
235
|
+
|
|
236
|
+
return normalizedValue || null;
|
|
237
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentry protocol version used for store endpoint requests.
|
|
3
|
+
*/
|
|
4
|
+
const SENTRY_PROTOCOL_VERSION = '7';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Endpoint content type used when sending JSON payloads to Sentry.
|
|
8
|
+
*/
|
|
9
|
+
const JSON_CONTENT_TYPE = 'application/json';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Number of milliseconds in one second.
|
|
13
|
+
*/
|
|
14
|
+
const MILLISECONDS_IN_SECOND = 1000;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Minimal Sentry DSN parts needed for store endpoint requests.
|
|
18
|
+
*/
|
|
19
|
+
type SentryDsnParts = {
|
|
20
|
+
/**
|
|
21
|
+
* Store endpoint derived from DSN host/project.
|
|
22
|
+
*/
|
|
23
|
+
storeEndpoint: URL;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Payload shape submitted to the Sentry store endpoint.
|
|
28
|
+
*/
|
|
29
|
+
export type SentryStorePayload = {
|
|
30
|
+
/**
|
|
31
|
+
* Event platform.
|
|
32
|
+
*/
|
|
33
|
+
platform: 'javascript';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Event level.
|
|
37
|
+
*/
|
|
38
|
+
level: 'error';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Logger name visible in Sentry events.
|
|
42
|
+
*/
|
|
43
|
+
logger: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Seconds since UNIX epoch.
|
|
47
|
+
*/
|
|
48
|
+
timestamp: number;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Human readable message.
|
|
52
|
+
*/
|
|
53
|
+
message: string;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Sentry release identifier.
|
|
57
|
+
*/
|
|
58
|
+
release?: string;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Deployment environment such as production, preview, or staging.
|
|
62
|
+
*/
|
|
63
|
+
environment?: string;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Server/deployment name.
|
|
67
|
+
*/
|
|
68
|
+
server_name: string;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Optional diagnostic tags used for filtering.
|
|
72
|
+
*/
|
|
73
|
+
tags?: Record<string, string>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Optional structured exception details.
|
|
77
|
+
*/
|
|
78
|
+
exception?: {
|
|
79
|
+
/**
|
|
80
|
+
* Individual exception list.
|
|
81
|
+
*/
|
|
82
|
+
values: Array<{
|
|
83
|
+
/**
|
|
84
|
+
* Exception type.
|
|
85
|
+
*/
|
|
86
|
+
type: string;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Exception message.
|
|
90
|
+
*/
|
|
91
|
+
value: string;
|
|
92
|
+
}>;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Optional additional diagnostic payload.
|
|
97
|
+
*/
|
|
98
|
+
extra?: Record<string, unknown>;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Resolves Sentry DSN from environment when configured.
|
|
103
|
+
*
|
|
104
|
+
* @returns Raw DSN string or `null` when telemetry is not configured.
|
|
105
|
+
*/
|
|
106
|
+
export function resolveOptionalSentryDsn(): string | null {
|
|
107
|
+
return process.env.SENTRY_DSN ?? process.env.NEXT_PUBLIC_SENTRY_DSN ?? null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Resolves Sentry DSN from environment.
|
|
112
|
+
*
|
|
113
|
+
* @returns Raw DSN string.
|
|
114
|
+
* @throws Error when DSN is missing.
|
|
115
|
+
*/
|
|
116
|
+
export function resolveRequiredSentryDsn(): string {
|
|
117
|
+
const sentryDsn = resolveOptionalSentryDsn();
|
|
118
|
+
|
|
119
|
+
if (!sentryDsn) {
|
|
120
|
+
throw new Error('Missing Sentry DSN. Configure SENTRY_DSN or NEXT_PUBLIC_SENTRY_DSN.');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return sentryDsn;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Parses a DSN into pieces required for Sentry store API requests.
|
|
128
|
+
*
|
|
129
|
+
* @param sentryDsn - Raw Sentry DSN.
|
|
130
|
+
* @returns Parsed DSN details.
|
|
131
|
+
* @throws Error when DSN format is invalid.
|
|
132
|
+
*/
|
|
133
|
+
function parseSentryDsn(sentryDsn: string): SentryDsnParts {
|
|
134
|
+
const sentryDsnUrl = new URL(sentryDsn);
|
|
135
|
+
const pathSegments = sentryDsnUrl.pathname.split('/').filter(Boolean);
|
|
136
|
+
const projectId = pathSegments.at(-1);
|
|
137
|
+
const pathPrefix = pathSegments.slice(0, -1).join('/');
|
|
138
|
+
|
|
139
|
+
if (!projectId) {
|
|
140
|
+
throw new Error('Invalid Sentry DSN: missing project ID.');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!sentryDsnUrl.username) {
|
|
144
|
+
throw new Error('Invalid Sentry DSN: missing public key.');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const basePath = pathPrefix ? `/${pathPrefix}` : '';
|
|
148
|
+
const storeEndpoint = new URL(`${sentryDsnUrl.protocol}//${sentryDsnUrl.host}${basePath}/api/${projectId}/store/`);
|
|
149
|
+
storeEndpoint.searchParams.set('sentry_key', sentryDsnUrl.username);
|
|
150
|
+
storeEndpoint.searchParams.set('sentry_version', SENTRY_PROTOCOL_VERSION);
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
storeEndpoint,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Creates a current Sentry timestamp expressed in seconds.
|
|
159
|
+
*
|
|
160
|
+
* @returns Current event timestamp in seconds.
|
|
161
|
+
*/
|
|
162
|
+
export function createSentryTimestamp(): number {
|
|
163
|
+
return Date.now() / MILLISECONDS_IN_SECOND;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Sends one Sentry store payload.
|
|
168
|
+
*
|
|
169
|
+
* @param payload - Fully constructed Sentry store payload.
|
|
170
|
+
* @param sentryDsn - Raw Sentry DSN used to derive the store endpoint.
|
|
171
|
+
*/
|
|
172
|
+
export async function sendSentryStorePayload(payload: SentryStorePayload, sentryDsn: string): Promise<void> {
|
|
173
|
+
const { storeEndpoint } = parseSentryDsn(sentryDsn);
|
|
174
|
+
|
|
175
|
+
const response = await fetch(storeEndpoint, {
|
|
176
|
+
method: 'POST',
|
|
177
|
+
headers: {
|
|
178
|
+
'Content-Type': JSON_CONTENT_TYPE,
|
|
179
|
+
},
|
|
180
|
+
body: JSON.stringify(payload),
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
if (!response.ok) {
|
|
184
|
+
const responseBody = await response.text();
|
|
185
|
+
throw new Error(`Sentry rejected error report (${response.status}): ${responseBody}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
package/apps/agents-server/src/utils/externalChatRunner/createExternalAgentRepositoryFiles.ts
CHANGED
|
@@ -53,9 +53,9 @@ function createExternalAgentRepositoryPackageJson(): string {
|
|
|
53
53
|
scripts: {
|
|
54
54
|
start: 'npm run agent:run',
|
|
55
55
|
'agent:run':
|
|
56
|
-
'npx ptbk agent-folder run-agent --
|
|
56
|
+
'npx ptbk agent-folder run-agent --harness github-copilot --model gpt-5.4 --thinking-level high --auto-pull --auto-push',
|
|
57
57
|
'agent-local:run':
|
|
58
|
-
'ts-node ../../promptbook/src/cli/test/ptbk.ts agent-folder run-agent --
|
|
58
|
+
'ts-node ../../promptbook/src/cli/test/ptbk.ts agent-folder run-agent --harness github-copilot --model gpt-5.4 --auto-pull --auto-push',
|
|
59
59
|
},
|
|
60
60
|
},
|
|
61
61
|
null,
|
package/apps/agents-server/src/utils/serverManagement/createManagedServer/bootstrapManagedServer.ts
CHANGED
|
@@ -47,7 +47,9 @@ export async function bootstrapManagedServer(input: NormalizedCreateServerInput)
|
|
|
47
47
|
await applyManagedServerMigrations(client, input, sqlRecorder, migrationLogger);
|
|
48
48
|
await seedServerUsers(client, input, sqlRecorder);
|
|
49
49
|
await seedServerMetadata(client, input, sqlRecorder);
|
|
50
|
-
|
|
50
|
+
if (input.isDefaultAgentsInstalled) {
|
|
51
|
+
await seedServerDefaultAgents(client, input, sqlRecorder);
|
|
52
|
+
}
|
|
51
53
|
|
|
52
54
|
await client.query('COMMIT');
|
|
53
55
|
sqlRecorder.addStatement('COMMIT');
|
|
@@ -51,6 +51,11 @@ export type NormalizedCreateServerInput = {
|
|
|
51
51
|
* Initial metadata rows inserted during bootstrap.
|
|
52
52
|
*/
|
|
53
53
|
readonly metadataEntries: ReadonlyArray<ServerMetadataSeedEntry>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Whether bundled default agents from `agents/default` should be created during bootstrap.
|
|
57
|
+
*/
|
|
58
|
+
readonly isDefaultAgentsInstalled: boolean;
|
|
54
59
|
};
|
|
55
60
|
|
|
56
61
|
/**
|
|
@@ -103,5 +108,6 @@ export function normalizeCreateServerInput(input: CreateServerInput): Normalized
|
|
|
103
108
|
iconUrl,
|
|
104
109
|
initialSettings: input.initialSettings,
|
|
105
110
|
}),
|
|
111
|
+
isDefaultAgentsInstalled: input.isDefaultAgentsInstalled !== false,
|
|
106
112
|
};
|
|
107
113
|
}
|