@promptbook/cli 0.112.0-112 → 0.112.0-114
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/agents/[agentName]/api/user-chats/[chatId]/stream/route.ts +85 -56
- package/apps/agents-server/src/app/agents/[agentName]/chat/useAgentChatHistorySyncEffects.ts +7 -13
- package/apps/agents-server/src/app/api/admin/code-runners/route.ts +1 -1
- package/apps/agents-server/src/app/api/internal/user-chat-jobs/run/route.ts +1 -1
- package/apps/agents-server/src/database/migrations/2026-06-1300-user-chat-active-read-indexes.sql +7 -0
- package/apps/agents-server/src/instrumentation-client.ts +28 -0
- package/apps/agents-server/src/instrumentation.ts +16 -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/agentRouting/resolveAgentRouteTarget.ts +38 -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 +59 -9
- package/apps/agents-server/src/utils/errorReporting/sendApplicationErrorReportToSentry.ts +39 -3
- package/apps/agents-server/src/utils/errorReporting/sentrySdkConfig.ts +237 -0
- package/apps/agents-server/src/utils/errorReporting/sentryStore.ts +10 -0
- package/apps/agents-server/src/utils/externalChatRunner/createExternalAgentRepositoryFiles.ts +2 -2
- package/apps/agents-server/src/utils/userChat/createImmediateUserChatAnswerModelRequirements.ts +15 -12
- package/apps/agents-server/src/utils/userChat/createUserChatDetailPayload.ts +33 -18
- package/apps/agents-server/src/utils/userChat/hasPotentiallyPendingAssistantMessages.ts +26 -0
- package/apps/agents-server/src/utils/userChat/runImmediateUserChatAnswer.ts +1 -1
- 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 +9285 -8807
- 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/scripts/run-codex-prompts/common/runGoScript/printLiveScriptChunk.d.ts +4 -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/LiteAgent.d.ts +68 -0
- package/esm/src/book-components/BookEditor/BookEditorAboutPromptbookInformation.d.ts +12 -0
- package/esm/src/cli/cli-commands/agent/agentCliOptions.d.ts +38 -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 +3 -4
- 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 +468 -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 +92 -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 +44 -0
- package/src/cli/cli-commands/agents-server/startAgentsServer.ts +3 -19
- 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 +747 -771
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -0
- package/umd/index.umd.js +9285 -8807
- 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/scripts/run-codex-prompts/common/runGoScript/printLiveScriptChunk.d.ts +4 -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 +38 -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 +3 -4
- package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +9 -9
- package/umd/src/version.d.ts +1 -1
- /package/esm/src/{cli/cli-commands/agents-server/startAgentsServer.test.d.ts → book-3.0/CliAgent.test.d.ts} +0 -0
- /package/{umd/src/cli/cli-commands/agents-server/startAgentsServer.test.d.ts → esm/src/book-3.0/LiteAgent.test.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -561,11 +561,11 @@ npx ts-node ./src/cli/test/ptbk.ts coder generate-boilerplates --template prompt
|
|
|
561
561
|
|
|
562
562
|
npx ts-node ./src/cli/test/ptbk.ts coder generate-boilerplates --template prompts/templates/agents-server.md
|
|
563
563
|
|
|
564
|
-
npx ts-node ./src/cli/test/ptbk.ts coder run --
|
|
564
|
+
npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md
|
|
565
565
|
|
|
566
|
-
npx ts-node ./src/cli/test/ptbk.ts coder run --
|
|
566
|
+
npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --auto-push
|
|
567
567
|
|
|
568
|
-
npx ts-node ./src/cli/test/ptbk.ts coder run --
|
|
568
|
+
npx ts-node ./src/cli/test/ptbk.ts coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --ignore-git-changes --no-wait
|
|
569
569
|
|
|
570
570
|
npx ts-node ./src/cli/test/ptbk.ts coder find-refactor-candidates
|
|
571
571
|
|
|
@@ -587,11 +587,11 @@ ptbk coder generate-boilerplates
|
|
|
587
587
|
|
|
588
588
|
ptbk coder generate-boilerplates --template prompts/templates/common.md
|
|
589
589
|
|
|
590
|
-
ptbk coder run --
|
|
590
|
+
ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --test npm run test
|
|
591
591
|
|
|
592
|
-
ptbk coder run --
|
|
592
|
+
ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --auto-push
|
|
593
593
|
|
|
594
|
-
ptbk coder run --
|
|
594
|
+
ptbk coder run --harness github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --test npm run test --ignore-git-changes --no-wait
|
|
595
595
|
|
|
596
596
|
ptbk coder find-refactor-candidates
|
|
597
597
|
|
|
@@ -616,7 +616,7 @@ ptbk coder verify
|
|
|
616
616
|
|
|
617
617
|
| Flag | Purpose |
|
|
618
618
|
| -------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
619
|
-
| `--
|
|
619
|
+
| `--harness <name>` | Selects the coding harness. |
|
|
620
620
|
| `--model <model>` | Chooses the runner model; required for `openai-codex` and `gemini`, optional for `github-copilot`. |
|
|
621
621
|
| `--context <text-or-file>` | Appends extra instructions inline or from a file like `AGENTS.md`. |
|
|
622
622
|
| `--test <command>` | Runs a verification command after each prompt attempt and feeds failing output back for retries. |
|
|
@@ -9,7 +9,7 @@ The installed CLI can initialize a local Agents Server project before it starts
|
|
|
9
9
|
```bash
|
|
10
10
|
npm install ptbk
|
|
11
11
|
ptbk agents-server init
|
|
12
|
-
ptbk agents-server start --
|
|
12
|
+
ptbk agents-server start --harness github-copilot --model gpt-5.4 --thinking-level xhigh
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
`ptbk agents-server init` adds missing placeholders to `.env` and local runtime exclusions to `.gitignore` without deleting existing configuration. Use `PTBK_AGENTS_SERVER_DATABASE=supabase` for a Supabase-backed server or `PTBK_AGENTS_SERVER_DATABASE=sqlite` for a standalone local database in `.promptbook`. When using Supabase, fill the initialized values from your project before starting the server. The Supabase project URL and API keys are available in the [Supabase project API settings](https://supabase.com/docs/guides/api/api-keys), and the PostgreSQL connection string is available from the [Supabase database connection guide](https://supabase.com/docs/guides/database/connecting-to-postgres).
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { withSentryConfig } from '@sentry/nextjs';
|
|
1
2
|
import type { NextConfig } from 'next';
|
|
2
3
|
import { readdirSync } from 'fs';
|
|
3
4
|
import path from 'path';
|
|
5
|
+
import { SENTRY_ORGANIZATION, SENTRY_PROJECT } from './src/utils/errorReporting/sentrySdkConfig';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Next.js build output directory.
|
|
@@ -20,6 +22,11 @@ const agentsServerNodeModulesPath = process.env.PTBK_AGENTS_SERVER_NODE_MODULES_
|
|
|
20
22
|
*/
|
|
21
23
|
const isNextValidationIgnored = process.env.PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION === 'true';
|
|
22
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Whether Sentry source maps can be uploaded during production builds.
|
|
27
|
+
*/
|
|
28
|
+
const IS_SENTRY_SOURCE_MAP_UPLOAD_ENABLED = Boolean(process.env.SENTRY_AUTH_TOKEN);
|
|
29
|
+
|
|
23
30
|
/**
|
|
24
31
|
* Exact aliases for local generated Promptbook package entrypoints.
|
|
25
32
|
*/
|
|
@@ -122,7 +129,19 @@ const nextConfig: NextConfig = {
|
|
|
122
129
|
},
|
|
123
130
|
};
|
|
124
131
|
|
|
125
|
-
export default nextConfig
|
|
132
|
+
export default withSentryConfig(nextConfig, {
|
|
133
|
+
org: SENTRY_ORGANIZATION,
|
|
134
|
+
project: SENTRY_PROJECT,
|
|
135
|
+
silent: true,
|
|
136
|
+
sourcemaps: {
|
|
137
|
+
disable: !IS_SENTRY_SOURCE_MAP_UPLOAD_ENABLED,
|
|
138
|
+
},
|
|
139
|
+
webpack: {
|
|
140
|
+
treeshake: {
|
|
141
|
+
removeDebugLogging: true,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
});
|
|
126
145
|
|
|
127
146
|
/**
|
|
128
147
|
* Creates webpack/Turbopack aliases from imports like `@promptbook-local/core` to generated local sources.
|
package/apps/agents-server/src/app/agents/[agentName]/api/user-chats/[chatId]/stream/route.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { CHAT_STREAM_KEEP_ALIVE_INTERVAL_MS } from '@/src/constants/streaming';
|
|
2
2
|
import { isPrivateModeEnabledFromRequest } from '@/src/utils/privateMode';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
createUserChatDetailPayload,
|
|
5
|
+
getUserChat,
|
|
6
|
+
isFrozenUserChatSource,
|
|
7
|
+
listUserChatJobs,
|
|
8
|
+
} from '@/src/utils/userChat';
|
|
9
|
+
import { hasPotentiallyPendingAssistantMessages } from '@/src/utils/userChat/hasPotentiallyPendingAssistantMessages';
|
|
10
|
+
import { listUserChatTimeouts } from '@/src/utils/userChatTimeout/userChatTimeoutStore';
|
|
5
11
|
import { NextResponse } from 'next/server';
|
|
6
12
|
import { resolveUserChatScope } from '../../resolveUserChatScope';
|
|
7
13
|
|
|
@@ -136,17 +142,17 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
136
142
|
return false;
|
|
137
143
|
}
|
|
138
144
|
|
|
139
|
-
const
|
|
140
|
-
const nextSignature = createUserChatDetailSignature(payload);
|
|
145
|
+
const livePollState = await loadLiveUserChatPollingState(currentChat);
|
|
141
146
|
|
|
142
|
-
if (
|
|
143
|
-
|
|
147
|
+
if (livePollState.signature !== lastSnapshotSignature) {
|
|
148
|
+
const payload = await createUserChatDetailPayload(currentChat);
|
|
149
|
+
lastSnapshotSignature = createUserChatPollingSignatureFromDetailPayload(payload);
|
|
144
150
|
if (!enqueueFrame({ type: 'snapshot', payload })) {
|
|
145
151
|
return false;
|
|
146
152
|
}
|
|
147
153
|
}
|
|
148
154
|
|
|
149
|
-
return !isFrozenUserChatSource(
|
|
155
|
+
return !isFrozenUserChatSource(currentChat.source) && livePollState.hasActiveJobs;
|
|
150
156
|
};
|
|
151
157
|
|
|
152
158
|
/**
|
|
@@ -211,69 +217,92 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
211
217
|
}
|
|
212
218
|
|
|
213
219
|
/**
|
|
214
|
-
*
|
|
220
|
+
* Minimal live poll state used to avoid rebuilding the full chat payload when nothing visible changed.
|
|
215
221
|
*/
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
draftMessage: payload.draftMessage || '',
|
|
221
|
-
messages: payload.messages.map(createUserChatMessageSignature),
|
|
222
|
-
activeJobs: payload.activeJobs.map((job) => ({
|
|
223
|
-
id: job.id,
|
|
224
|
-
status: job.status,
|
|
225
|
-
cancelRequestedAt: job.cancelRequestedAt,
|
|
226
|
-
})),
|
|
227
|
-
activeTimeouts: payload.activeTimeouts.map((timeout) => ({
|
|
228
|
-
id: timeout.id,
|
|
229
|
-
status: timeout.status,
|
|
230
|
-
dueAt: timeout.dueAt,
|
|
231
|
-
cancelRequestedAt: timeout.cancelRequestedAt,
|
|
232
|
-
})),
|
|
233
|
-
});
|
|
234
|
-
}
|
|
222
|
+
type LiveUserChatPollState = {
|
|
223
|
+
signature: string;
|
|
224
|
+
hasActiveJobs: boolean;
|
|
225
|
+
};
|
|
235
226
|
|
|
236
227
|
/**
|
|
237
|
-
*
|
|
228
|
+
* Loads the lightweight state needed to decide whether the active chat payload changed.
|
|
229
|
+
*
|
|
230
|
+
* The expensive detail payload does job reconciliation, local-runner synchronization, and full
|
|
231
|
+
* transcript serialization. Polling first with the persisted timestamps + active resource state
|
|
232
|
+
* keeps long-lived chat streams cheap when the conversation is idle.
|
|
233
|
+
*
|
|
234
|
+
* @param chat - Current scoped chat record.
|
|
235
|
+
* @returns Poll signature plus whether the chat should keep using the active-job cadence.
|
|
238
236
|
*/
|
|
239
|
-
function
|
|
240
|
-
|
|
241
|
-
|
|
237
|
+
async function loadLiveUserChatPollingState(chat: NonNullable<Awaited<ReturnType<typeof getUserChat>>>): Promise<LiveUserChatPollState> {
|
|
238
|
+
const shouldInspectActiveJobs = hasPotentiallyPendingAssistantMessages(chat.messages);
|
|
239
|
+
const [activeJobs, activeTimeouts] = await Promise.all([
|
|
240
|
+
shouldInspectActiveJobs
|
|
241
|
+
? listUserChatJobs({
|
|
242
|
+
userId: chat.userId,
|
|
243
|
+
agentPermanentId: chat.agentPermanentId,
|
|
244
|
+
chatId: chat.id,
|
|
245
|
+
onlyActive: true,
|
|
246
|
+
})
|
|
247
|
+
: Promise.resolve([]),
|
|
248
|
+
listUserChatTimeouts({
|
|
249
|
+
userId: chat.userId,
|
|
250
|
+
agentPermanentId: chat.agentPermanentId,
|
|
251
|
+
chatId: chat.id,
|
|
252
|
+
onlyActive: true,
|
|
253
|
+
}),
|
|
254
|
+
]);
|
|
255
|
+
|
|
242
256
|
return {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
replyingTo: message.replyingTo ? JSON.stringify(message.replyingTo) : null,
|
|
251
|
-
progressCard: message.progressCard ? JSON.stringify(message.progressCard) : null,
|
|
252
|
-
ongoingToolCalls: createToolCallsSignature(message.ongoingToolCalls),
|
|
253
|
-
completedToolCalls: createToolCallsSignature(message.completedToolCalls),
|
|
254
|
-
toolCalls: createToolCallsSignature(message.toolCalls),
|
|
257
|
+
signature: createUserChatPollingSignature({
|
|
258
|
+
chatUpdatedAt: chat.updatedAt,
|
|
259
|
+
draftMessage: chat.draftMessage,
|
|
260
|
+
activeJobs,
|
|
261
|
+
activeTimeouts,
|
|
262
|
+
}),
|
|
263
|
+
hasActiveJobs: activeJobs.length > 0,
|
|
255
264
|
};
|
|
256
265
|
}
|
|
257
266
|
|
|
258
267
|
/**
|
|
259
|
-
*
|
|
268
|
+
* Builds the polling signature for a fully hydrated detail payload.
|
|
260
269
|
*/
|
|
261
|
-
function
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
+
function createUserChatPollingSignatureFromDetailPayload(
|
|
271
|
+
payload: Awaited<ReturnType<typeof createUserChatDetailPayload>>,
|
|
272
|
+
): string {
|
|
273
|
+
return createUserChatPollingSignature({
|
|
274
|
+
chatUpdatedAt: payload.chat.updatedAt,
|
|
275
|
+
draftMessage: payload.draftMessage,
|
|
276
|
+
activeJobs: payload.activeJobs,
|
|
277
|
+
activeTimeouts: payload.activeTimeouts,
|
|
278
|
+
});
|
|
270
279
|
}
|
|
271
280
|
|
|
272
281
|
/**
|
|
273
|
-
*
|
|
282
|
+
* Builds a stable signature for the user-visible state that changes stream snapshots.
|
|
274
283
|
*/
|
|
275
|
-
function
|
|
276
|
-
|
|
284
|
+
function createUserChatPollingSignature(options: {
|
|
285
|
+
chatUpdatedAt: string;
|
|
286
|
+
draftMessage: string | null;
|
|
287
|
+
activeJobs: ReadonlyArray<Awaited<ReturnType<typeof createUserChatDetailPayload>>['activeJobs'][number]>;
|
|
288
|
+
activeTimeouts: ReadonlyArray<Awaited<ReturnType<typeof createUserChatDetailPayload>>['activeTimeouts'][number]>;
|
|
289
|
+
}): string {
|
|
290
|
+
return JSON.stringify({
|
|
291
|
+
updatedAt: options.chatUpdatedAt,
|
|
292
|
+
draftMessage: options.draftMessage || '',
|
|
293
|
+
activeJobs: options.activeJobs.map((job) => ({
|
|
294
|
+
id: job.id,
|
|
295
|
+
status: job.status,
|
|
296
|
+
cancelRequestedAt: job.cancelRequestedAt,
|
|
297
|
+
})),
|
|
298
|
+
activeTimeouts: options.activeTimeouts.map((timeout) => ({
|
|
299
|
+
id: timeout.id,
|
|
300
|
+
status: timeout.status,
|
|
301
|
+
dueAt: timeout.dueAt,
|
|
302
|
+
cancelRequestedAt: timeout.cancelRequestedAt,
|
|
303
|
+
pausedAt: timeout.pausedAt,
|
|
304
|
+
})),
|
|
305
|
+
});
|
|
277
306
|
}
|
|
278
307
|
|
|
279
308
|
/**
|
package/apps/agents-server/src/app/agents/[agentName]/chat/useAgentChatHistorySyncEffects.ts
CHANGED
|
@@ -22,13 +22,6 @@ const USER_CHAT_STREAM_RECONNECT_DELAY_MS = 1_500;
|
|
|
22
22
|
*/
|
|
23
23
|
const DISCONNECTED_CHAT_REFRESH_INTERVAL_MS = 4_000;
|
|
24
24
|
|
|
25
|
-
/**
|
|
26
|
-
* Periodic sidebar/list refresh cadence while the active chat stream is healthy.
|
|
27
|
-
*
|
|
28
|
-
* @private function of useAgentChatHistoryClientState
|
|
29
|
-
*/
|
|
30
|
-
const CHAT_LIST_REFRESH_INTERVAL_MS = 20_000;
|
|
31
|
-
|
|
32
25
|
/**
|
|
33
26
|
* Inputs required to register side effects for durable chat-history synchronization.
|
|
34
27
|
*
|
|
@@ -504,7 +497,7 @@ function keepActiveChatStreamConnected(params: {
|
|
|
504
497
|
}
|
|
505
498
|
|
|
506
499
|
/**
|
|
507
|
-
* Refreshes the selected chat
|
|
500
|
+
* Refreshes the selected chat on disconnect polling and on tab visibility/focus changes.
|
|
508
501
|
*
|
|
509
502
|
* @private function of useAgentChatHistoryClientState
|
|
510
503
|
*/
|
|
@@ -529,9 +522,6 @@ function registerActiveChatRefreshPolling(params: {
|
|
|
529
522
|
return undefined;
|
|
530
523
|
}
|
|
531
524
|
|
|
532
|
-
const pollIntervalMs = isActiveChatStreamConnected
|
|
533
|
-
? CHAT_LIST_REFRESH_INTERVAL_MS
|
|
534
|
-
: DISCONNECTED_CHAT_REFRESH_INTERVAL_MS;
|
|
535
525
|
const runRefresh = () => {
|
|
536
526
|
if (typeof document !== 'undefined' && document.hidden) {
|
|
537
527
|
return;
|
|
@@ -540,7 +530,9 @@ function registerActiveChatRefreshPolling(params: {
|
|
|
540
530
|
void refreshActiveChat({ preserveDirtyDraft: true });
|
|
541
531
|
};
|
|
542
532
|
|
|
543
|
-
const interval =
|
|
533
|
+
const interval = isActiveChatStreamConnected
|
|
534
|
+
? null
|
|
535
|
+
: window.setInterval(runRefresh, DISCONNECTED_CHAT_REFRESH_INTERVAL_MS);
|
|
544
536
|
const handleVisibilityChange = () => {
|
|
545
537
|
if (typeof document !== 'undefined' && !document.hidden) {
|
|
546
538
|
runRefresh();
|
|
@@ -554,7 +546,9 @@ function registerActiveChatRefreshPolling(params: {
|
|
|
554
546
|
window.addEventListener('focus', handleFocus);
|
|
555
547
|
|
|
556
548
|
return () => {
|
|
557
|
-
|
|
549
|
+
if (interval !== null) {
|
|
550
|
+
window.clearInterval(interval);
|
|
551
|
+
}
|
|
558
552
|
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
559
553
|
window.removeEventListener('focus', handleFocus);
|
|
560
554
|
};
|
|
@@ -57,7 +57,7 @@ async function handleUserChatJobWorkerRequest(request: Request) {
|
|
|
57
57
|
|
|
58
58
|
after(() =>
|
|
59
59
|
triggerUserChatJobWorker({ origin }).catch((error) =>
|
|
60
|
-
console.
|
|
60
|
+
console.warn('[user-chat-job] requeue failed', error),
|
|
61
61
|
),
|
|
62
62
|
);
|
|
63
63
|
|
package/apps/agents-server/src/database/migrations/2026-06-1300-user-chat-active-read-indexes.sql
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
CREATE INDEX IF NOT EXISTS "prefix_UserChatJob_chatId_userId_agentPermanentId_active_createdAt_idx"
|
|
2
|
+
ON "prefix_UserChatJob" ("chatId", "userId", "agentPermanentId", "createdAt" ASC)
|
|
3
|
+
WHERE "status" IN ('QUEUED', 'RUNNING');
|
|
4
|
+
|
|
5
|
+
CREATE INDEX IF NOT EXISTS "prefix_UserChatTimeout_chatId_userId_agentPermanentId_active_dueAt_idx"
|
|
6
|
+
ON "prefix_UserChatTimeout" ("chatId", "userId", "agentPermanentId", "dueAt" ASC, "createdAt" ASC)
|
|
7
|
+
WHERE "status" IN ('QUEUED', 'RUNNING') AND "pausedAt" IS NULL;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/nextjs';
|
|
2
|
+
import {
|
|
3
|
+
createSentrySdkTags,
|
|
4
|
+
resolveBrowserSentryDsn,
|
|
5
|
+
resolveSentrySdkEnvironment,
|
|
6
|
+
resolveSentrySdkRelease,
|
|
7
|
+
SENTRY_TRACE_PROPAGATION_TARGETS,
|
|
8
|
+
SENTRY_TRACES_SAMPLE_RATE,
|
|
9
|
+
} from './utils/errorReporting/sentrySdkConfig';
|
|
10
|
+
|
|
11
|
+
Sentry.init({
|
|
12
|
+
dsn: resolveBrowserSentryDsn(),
|
|
13
|
+
tracesSampleRate: SENTRY_TRACES_SAMPLE_RATE,
|
|
14
|
+
environment: resolveSentrySdkEnvironment(),
|
|
15
|
+
release: resolveSentrySdkRelease(),
|
|
16
|
+
integrations: [Sentry.browserTracingIntegration()],
|
|
17
|
+
tracePropagationTargets: SENTRY_TRACE_PROPAGATION_TARGETS,
|
|
18
|
+
initialScope: {
|
|
19
|
+
tags: createSentrySdkTags(),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Reports app-router navigation spans to Sentry.
|
|
25
|
+
*
|
|
26
|
+
* @private Sentry hook for Next.js client navigation instrumentation
|
|
27
|
+
*/
|
|
28
|
+
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/nextjs';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Registers startup hooks for the Agents Server runtime.
|
|
3
5
|
*
|
|
@@ -5,11 +7,18 @@
|
|
|
5
7
|
* @private internal startup hook for Agents Server runtime
|
|
6
8
|
*/
|
|
7
9
|
export async function register(): Promise<void> {
|
|
10
|
+
if (process.env.NEXT_RUNTIME === 'edge') {
|
|
11
|
+
await import('./sentry.edge.config');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
if (process.env.NEXT_RUNTIME !== 'nodejs') {
|
|
9
16
|
return;
|
|
10
17
|
}
|
|
11
18
|
|
|
12
19
|
try {
|
|
20
|
+
await import('./sentry.server.config');
|
|
21
|
+
|
|
13
22
|
const { registerServerErrorSentryLogging } = await import('./utils/errorReporting/registerServerErrorSentryLogging');
|
|
14
23
|
registerServerErrorSentryLogging();
|
|
15
24
|
|
|
@@ -25,3 +34,10 @@ export async function register(): Promise<void> {
|
|
|
25
34
|
});
|
|
26
35
|
}
|
|
27
36
|
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Reports request errors from the Next.js app router to Sentry.
|
|
40
|
+
*
|
|
41
|
+
* @private Sentry hook for Next.js request instrumentation
|
|
42
|
+
*/
|
|
43
|
+
export const onRequestError = Sentry.captureRequestError;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/nextjs';
|
|
2
|
+
import {
|
|
3
|
+
createSentrySdkTags,
|
|
4
|
+
resolveBrowserSentryDsn,
|
|
5
|
+
resolveSentrySdkEnvironment,
|
|
6
|
+
resolveSentrySdkRelease,
|
|
7
|
+
SENTRY_TRACES_SAMPLE_RATE,
|
|
8
|
+
} from './utils/errorReporting/sentrySdkConfig';
|
|
9
|
+
|
|
10
|
+
Sentry.init({
|
|
11
|
+
dsn: resolveBrowserSentryDsn(),
|
|
12
|
+
tracesSampleRate: SENTRY_TRACES_SAMPLE_RATE,
|
|
13
|
+
environment: resolveSentrySdkEnvironment(),
|
|
14
|
+
release: resolveSentrySdkRelease(),
|
|
15
|
+
initialScope: {
|
|
16
|
+
tags: createSentrySdkTags(),
|
|
17
|
+
},
|
|
18
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/nextjs';
|
|
2
|
+
import { createAgentsServerSentryContext } from './utils/errorReporting/agentsServerSentryContext';
|
|
3
|
+
import { resolveServerSentryDsn, SENTRY_TRACES_SAMPLE_RATE } from './utils/errorReporting/sentrySdkConfig';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Shared diagnostic context applied to server-side SDK events at initialization time.
|
|
7
|
+
*/
|
|
8
|
+
const agentsServerSentryContext = createAgentsServerSentryContext();
|
|
9
|
+
|
|
10
|
+
Sentry.init({
|
|
11
|
+
dsn: resolveServerSentryDsn(),
|
|
12
|
+
tracesSampleRate: SENTRY_TRACES_SAMPLE_RATE,
|
|
13
|
+
environment: agentsServerSentryContext.environment,
|
|
14
|
+
release: agentsServerSentryContext.release,
|
|
15
|
+
initialScope: {
|
|
16
|
+
tags: agentsServerSentryContext.tags,
|
|
17
|
+
extra: agentsServerSentryContext.extra,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
@@ -102,6 +102,13 @@ async function resolveAgentRouteTargetUncached(
|
|
|
102
102
|
};
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
if (!options?.forceRefresh) {
|
|
106
|
+
const fastLocalRouteTarget = await resolveFastLocalAgentRouteTarget(normalizedReference, localServerUrl);
|
|
107
|
+
if (fastLocalRouteTarget) {
|
|
108
|
+
return fastLocalRouteTarget;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
105
112
|
const resolver = await $provideAgentReferenceResolver({ forceRefresh: options?.forceRefresh });
|
|
106
113
|
let resolvedUrlValue: string;
|
|
107
114
|
|
|
@@ -145,6 +152,37 @@ async function resolveAgentRouteTargetUncached(
|
|
|
145
152
|
};
|
|
146
153
|
}
|
|
147
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Resolves the common local-agent case without constructing the heavier shared reference resolver.
|
|
157
|
+
*
|
|
158
|
+
* Normal page and chat routes almost always target one local agent by its stored name or permanent id.
|
|
159
|
+
* Handling that case up front keeps route resolution cheap while still falling back to the full TEAM/federation
|
|
160
|
+
* resolver for aliases, remote agents, and fuzzy matches.
|
|
161
|
+
*
|
|
162
|
+
* @param reference - Normalized route/reference text.
|
|
163
|
+
* @param localServerUrl - Normalized URL of the current Agents Server instance.
|
|
164
|
+
* @returns Local route target or `null` when a direct lookup does not match.
|
|
165
|
+
*/
|
|
166
|
+
async function resolveFastLocalAgentRouteTarget(
|
|
167
|
+
reference: string,
|
|
168
|
+
localServerUrl: string,
|
|
169
|
+
): Promise<AgentRouteTarget | null> {
|
|
170
|
+
const collection = await $provideAgentCollectionForServer();
|
|
171
|
+
const directMatch = await collection.findAgentBasicInformation(reference);
|
|
172
|
+
|
|
173
|
+
if (!directMatch) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const canonicalAgentId = directMatch.permanentId || directMatch.agentName;
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
kind: 'local',
|
|
181
|
+
canonicalAgentId,
|
|
182
|
+
canonicalUrl: `${localServerUrl}${AGENT_PATH_PREFIX}${encodeURIComponent(canonicalAgentId)}`,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
148
186
|
/**
|
|
149
187
|
* Memoized route-target resolver used for normal page rendering.
|
|
150
188
|
*/
|
|
@@ -37,7 +37,7 @@ export async function readConfiguredCodeRunner(): Promise<ConfiguredCodeRunner>
|
|
|
37
37
|
>;
|
|
38
38
|
|
|
39
39
|
return {
|
|
40
|
-
agent: environmentByKey.
|
|
40
|
+
agent: environmentByKey.PTBK_HARNESS || process.env.PTBK_HARNESS || process.env.PTBK_AGENT || 'github-copilot',
|
|
41
41
|
model: environmentByKey.PTBK_MODEL || process.env.PTBK_MODEL || 'gpt-5.4',
|
|
42
42
|
thinkingLevel: environmentByKey.PTBK_THINKING_LEVEL || process.env.PTBK_THINKING_LEVEL || 'xhigh',
|
|
43
43
|
};
|