@sentry/junior 0.112.0 → 0.113.0
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/dist/{agent-hooks-6MVTPKP4.js → agent-hooks-BKEMWR3Z.js} +8 -8
- package/dist/api/conversations/cursor.d.ts +17 -0
- package/dist/api/conversations/detail.d.ts +16 -18
- package/dist/api/conversations/event-list.d.ts +91 -0
- package/dist/api/conversations/event-page.d.ts +18 -0
- package/dist/api/conversations/events.d.ts +5 -1
- package/dist/api/conversations/projection.d.ts +6 -1
- package/dist/api/schema/conversation.d.ts +132 -51
- package/dist/api/schema.d.ts +2 -2
- package/dist/api/schema.js +7 -1
- package/dist/api.js +444 -138
- package/dist/app.js +20 -20
- package/dist/{catalog-runtime-UEO25P2J.js → catalog-runtime-6XYOUVRZ.js} +5 -5
- package/dist/chat/pi/transcript.d.ts +2 -0
- package/dist/chat/services/provider-error.d.ts +39 -0
- package/dist/chat/services/provider-retry.d.ts +3 -6
- package/dist/chat/task-execution/state.d.ts +2 -2
- package/dist/chat/task-execution/store.d.ts +1 -1
- package/dist/{chunk-CSS7JHEM.js → chunk-36UJA3OD.js} +1 -1
- package/dist/{chunk-4EJO4HIC.js → chunk-3CTIAKSS.js} +1 -1
- package/dist/{chunk-66IP6WED.js → chunk-4VKFQPCW.js} +4 -4
- package/dist/{chunk-GJG67YFS.js → chunk-4WZ7YKDF.js} +2 -2
- package/dist/{chunk-SKEMI4IF.js → chunk-DXRPHBOU.js} +132 -23
- package/dist/{chunk-GR4IB6OQ.js → chunk-H5ON7XTE.js} +73 -28
- package/dist/{chunk-X3SP5RDW.js → chunk-HMRVILWZ.js} +1 -1
- package/dist/{chunk-2FJ6WEYV.js → chunk-K5BXPM74.js} +1 -1
- package/dist/{chunk-QIALGHRN.js → chunk-LLKDNPYV.js} +2 -2
- package/dist/{chunk-ZHP4KNF7.js → chunk-LR2SKL5Y.js} +1 -1
- package/dist/{chunk-AU2JVUDF.js → chunk-NP7TYFYR.js} +1 -1
- package/dist/{chunk-TZU3R5OC.js → chunk-OXE5ZUTS.js} +1 -1
- package/dist/{chunk-NDQL4ESR.js → chunk-QTS66GMR.js} +2 -2
- package/dist/{chunk-PK4ETCUQ.js → chunk-RCBUZGIT.js} +217 -199
- package/dist/{chunk-JE23YR3X.js → chunk-UKGNSJQQ.js} +50 -42
- package/dist/{chunk-AWNDKI5K.js → chunk-WBB22ANL.js} +20 -15
- package/dist/{chunk-VBSVNOLA.js → chunk-YJ44UT7D.js} +5 -5
- package/dist/{chunk-IV2O4HQJ.js → chunk-ZRSUCJGA.js} +1 -1
- package/dist/cli/chat.js +19 -19
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +11 -11
- package/dist/cli/snapshot-warmup.js +8 -8
- package/dist/cli/upgrade.js +5 -5
- package/dist/{db-P5H5RVQV.js → db-2ASK6MV6.js} +5 -5
- package/dist/instrumentation.js +2 -2
- package/dist/nitro.js +2 -2
- package/dist/{runner-B4ZDUO3R.js → runner-L363K62Z.js} +12 -13
- package/dist/{skills-GWTOZ3XV.js → skills-VCPG3NOO.js} +6 -6
- package/dist/{validation-QFIC6XH6.js → validation-GY7AJBLC.js} +6 -6
- package/dist/version.js +1 -1
- package/package.json +6 -6
package/dist/app.js
CHANGED
|
@@ -6,14 +6,14 @@ import {
|
|
|
6
6
|
processPluginTask,
|
|
7
7
|
requireTurnFailureEventId,
|
|
8
8
|
scheduleSessionCompletedPluginTasks
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-WBB22ANL.js";
|
|
10
10
|
import {
|
|
11
11
|
GET,
|
|
12
12
|
buildSentryConversationUrl,
|
|
13
13
|
conversationVisibilityFromSlackChannelType,
|
|
14
14
|
resolveSlackChannelTypeFromMessage,
|
|
15
15
|
resolveSlackConversationContext
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-K5BXPM74.js";
|
|
17
17
|
import "./chunk-2ZTTXTSZ.js";
|
|
18
18
|
import {
|
|
19
19
|
ConversationQueueMessageRejectedError,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
import {
|
|
32
32
|
validatePluginEgressCredentialHooks,
|
|
33
33
|
validatePluginRegistrations
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-3CTIAKSS.js";
|
|
35
35
|
import {
|
|
36
36
|
defineJuniorPlugins,
|
|
37
37
|
pluginCatalogConfigFromEnv,
|
|
@@ -84,7 +84,7 @@ import {
|
|
|
84
84
|
splitSlackReplyText,
|
|
85
85
|
startOAuthFlow,
|
|
86
86
|
truncateStatusText
|
|
87
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-H5ON7XTE.js";
|
|
88
88
|
import {
|
|
89
89
|
ConversationTurnBoundaryError,
|
|
90
90
|
CooperativeTurnYieldError,
|
|
@@ -140,11 +140,13 @@ import {
|
|
|
140
140
|
recordAuthorizationCompleted,
|
|
141
141
|
recordDeliveredAssistantMessage,
|
|
142
142
|
startActiveTurn,
|
|
143
|
+
stripRuntimeTurnContext,
|
|
144
|
+
trimTrailingAssistantMessages,
|
|
143
145
|
turnHasReply,
|
|
144
146
|
updateConversationStats,
|
|
145
147
|
upsertConversationMessage
|
|
146
|
-
} from "./chunk-
|
|
147
|
-
import "./chunk-
|
|
148
|
+
} from "./chunk-DXRPHBOU.js";
|
|
149
|
+
import "./chunk-4VKFQPCW.js";
|
|
148
150
|
import "./chunk-MU6HHZEN.js";
|
|
149
151
|
import "./chunk-PDO5BLNM.js";
|
|
150
152
|
import "./chunk-UIE3R5XU.js";
|
|
@@ -163,12 +165,12 @@ import {
|
|
|
163
165
|
validatePlugins,
|
|
164
166
|
verifyScheduledTaskCredentialSubject,
|
|
165
167
|
verifySlackDirectCredentialSubject
|
|
166
|
-
} from "./chunk-
|
|
168
|
+
} from "./chunk-YJ44UT7D.js";
|
|
167
169
|
import {
|
|
168
170
|
acquireActiveLock,
|
|
169
171
|
getDefaultRedisStateAdapterFor,
|
|
170
172
|
getStateAdapter
|
|
171
|
-
} from "./chunk-
|
|
173
|
+
} from "./chunk-HMRVILWZ.js";
|
|
172
174
|
import {
|
|
173
175
|
SlackActionError,
|
|
174
176
|
downloadPrivateSlackFile,
|
|
@@ -179,7 +181,7 @@ import {
|
|
|
179
181
|
normalizeSlackConversationId,
|
|
180
182
|
runWithSlackInstallationToken,
|
|
181
183
|
runWithWorkspaceTeamId
|
|
182
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-QTS66GMR.js";
|
|
183
185
|
import {
|
|
184
186
|
contextProvenance,
|
|
185
187
|
createSlackDestination,
|
|
@@ -193,7 +195,7 @@ import {
|
|
|
193
195
|
requireSlackDestination,
|
|
194
196
|
sameDestination,
|
|
195
197
|
withConversationEventLock
|
|
196
|
-
} from "./chunk-
|
|
198
|
+
} from "./chunk-LLKDNPYV.js";
|
|
197
199
|
import {
|
|
198
200
|
juniorConversationEvents,
|
|
199
201
|
juniorConversations
|
|
@@ -219,10 +221,8 @@ import {
|
|
|
219
221
|
modelIdForProfile,
|
|
220
222
|
normalizeSlackEmojiName,
|
|
221
223
|
setSlackReactionConfig,
|
|
222
|
-
standardModelId
|
|
223
|
-
|
|
224
|
-
trimTrailingAssistantMessages
|
|
225
|
-
} from "./chunk-PK4ETCUQ.js";
|
|
224
|
+
standardModelId
|
|
225
|
+
} from "./chunk-RCBUZGIT.js";
|
|
226
226
|
import {
|
|
227
227
|
juniorDestinations
|
|
228
228
|
} from "./chunk-VFUK3X5B.js";
|
|
@@ -234,16 +234,16 @@ import {
|
|
|
234
234
|
} from "./chunk-6Y5L4BOM.js";
|
|
235
235
|
import {
|
|
236
236
|
discoverSkills
|
|
237
|
-
} from "./chunk-
|
|
237
|
+
} from "./chunk-4WZ7YKDF.js";
|
|
238
238
|
import {
|
|
239
239
|
pluginCatalogRuntime
|
|
240
|
-
} from "./chunk-
|
|
240
|
+
} from "./chunk-LR2SKL5Y.js";
|
|
241
241
|
import {
|
|
242
242
|
buildOAuthTokenRequest,
|
|
243
243
|
credentialSubjectSchema,
|
|
244
244
|
hasRequiredOAuthScope,
|
|
245
245
|
parseOAuthTokenResponse
|
|
246
|
-
} from "./chunk-
|
|
246
|
+
} from "./chunk-OXE5ZUTS.js";
|
|
247
247
|
import {
|
|
248
248
|
createActor,
|
|
249
249
|
createSlackActor,
|
|
@@ -268,7 +268,7 @@ import {
|
|
|
268
268
|
setTags,
|
|
269
269
|
withContext,
|
|
270
270
|
withSpan
|
|
271
|
-
} from "./chunk-
|
|
271
|
+
} from "./chunk-36UJA3OD.js";
|
|
272
272
|
import {
|
|
273
273
|
isRecord,
|
|
274
274
|
parseSlackChannelId,
|
|
@@ -285,10 +285,10 @@ import {
|
|
|
285
285
|
} from "./chunk-3V7OFJZC.js";
|
|
286
286
|
import {
|
|
287
287
|
JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
|
|
288
|
-
} from "./chunk-
|
|
288
|
+
} from "./chunk-NP7TYFYR.js";
|
|
289
289
|
import {
|
|
290
290
|
JUNIOR_VERSION
|
|
291
|
-
} from "./chunk-
|
|
291
|
+
} from "./chunk-ZRSUCJGA.js";
|
|
292
292
|
import "./chunk-MLKGABMK.js";
|
|
293
293
|
|
|
294
294
|
// src/app.ts
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
pluginCatalogRuntime
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-LR2SKL5Y.js";
|
|
4
|
+
import "./chunk-OXE5ZUTS.js";
|
|
5
5
|
import "./chunk-C4MZ3GP5.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-36UJA3OD.js";
|
|
7
7
|
import "./chunk-42WRQLJ6.js";
|
|
8
8
|
import "./chunk-6GWA276C.js";
|
|
9
9
|
import "./chunk-B3IT5END.js";
|
|
10
10
|
import "./chunk-3V7OFJZC.js";
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-NP7TYFYR.js";
|
|
12
|
+
import "./chunk-ZRSUCJGA.js";
|
|
13
13
|
import "./chunk-MLKGABMK.js";
|
|
14
14
|
export {
|
|
15
15
|
pluginCatalogRuntime
|
|
@@ -19,6 +19,8 @@ export declare function isToolResultError(result: unknown): boolean;
|
|
|
19
19
|
export declare function normalizeToolNameFromResult(result: unknown): string | undefined;
|
|
20
20
|
/** Extract role string from a raw Pi message. */
|
|
21
21
|
export declare function getPiMessageRole(value: unknown): string | undefined;
|
|
22
|
+
/** Return whether Pi can continue directly from the current history tail. */
|
|
23
|
+
export declare function isContinuablePiBoundary(messages: readonly PiMessage[]): boolean;
|
|
22
24
|
/** Concatenate text content parts from an assistant message. */
|
|
23
25
|
export declare function extractAssistantText(message: AssistantMessage): string;
|
|
24
26
|
/** Return assistant messages that belong to the terminal post-tool reply phase. */
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize failures at the model-provider boundary.
|
|
3
|
+
*
|
|
4
|
+
* Junior owns stable failure kinds, safe user copy, and telemetry fields. Pi
|
|
5
|
+
* remains the source of truth for retrying assistant error messages.
|
|
6
|
+
*/
|
|
7
|
+
export type ProviderErrorKind = "auth" | "permission" | "rate_limit" | "capacity" | "timeout" | "network" | "server" | "invalid_request" | "invalid_response" | "quota" | "content_policy" | "unknown";
|
|
8
|
+
interface ProviderErrorOptions {
|
|
9
|
+
kind?: ProviderErrorKind;
|
|
10
|
+
modelId?: string;
|
|
11
|
+
/** Pi's decision for an assistant error; explicit terminal kinds still win. */
|
|
12
|
+
retryable?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface ProviderErrorDetails {
|
|
15
|
+
kind: ProviderErrorKind;
|
|
16
|
+
modelId?: string;
|
|
17
|
+
retryable: boolean;
|
|
18
|
+
retryAfterMs?: number;
|
|
19
|
+
status?: number;
|
|
20
|
+
}
|
|
21
|
+
/** Structured failure produced at an AI provider boundary. */
|
|
22
|
+
export declare class ProviderError extends Error {
|
|
23
|
+
readonly code = "provider_error";
|
|
24
|
+
readonly kind: ProviderErrorKind;
|
|
25
|
+
readonly modelId?: string;
|
|
26
|
+
readonly retryable: boolean;
|
|
27
|
+
readonly retryAfterMs?: number;
|
|
28
|
+
readonly status?: number;
|
|
29
|
+
constructor(details: ProviderErrorDetails);
|
|
30
|
+
}
|
|
31
|
+
/** Normalize SDK, Gateway, and Pi failures into one provider error contract. */
|
|
32
|
+
export declare function createProviderError(error: unknown, options?: ProviderErrorOptions): ProviderError;
|
|
33
|
+
/** Return whether a provider-boundary error should be retried. */
|
|
34
|
+
export declare function isProviderRetryError(error: unknown): error is ProviderError;
|
|
35
|
+
/** Return stable, sanitized copy suitable for a terminal user response. */
|
|
36
|
+
export declare function getProviderErrorUserMessage(error: ProviderError): string;
|
|
37
|
+
/** Return safe structured fields for terminal failure telemetry. */
|
|
38
|
+
export declare function getProviderErrorAttributes(error: ProviderError): Record<string, unknown>;
|
|
39
|
+
export {};
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
+
import { type AssistantMessage } from "@earendil-works/pi-ai";
|
|
1
2
|
import type { PiMessage } from "@/chat/pi/messages";
|
|
2
|
-
/**
|
|
3
|
-
export declare function createProviderError(error: unknown): Error;
|
|
4
|
-
/** Return whether a provider-boundary error should be retried by the worker. */
|
|
5
|
-
export declare function isProviderRetryError(error: unknown): boolean;
|
|
6
|
-
/** Build the next provider retry step from Pi history, if the turn can resume. */
|
|
3
|
+
/** Apply Junior's retry budget to a retryable Pi assistant failure. */
|
|
7
4
|
export declare function nextProviderRetry(args: {
|
|
8
5
|
attempt: number;
|
|
6
|
+
failure?: AssistantMessage;
|
|
9
7
|
messages: PiMessage[];
|
|
10
|
-
retryableFailure: boolean;
|
|
11
8
|
}): {
|
|
12
9
|
delayMs: number;
|
|
13
10
|
messages: PiMessage[];
|
|
@@ -16,8 +16,8 @@ export declare const CONVERSATION_WORK_MAX_DELIVERY_ATTEMPTS = 5;
|
|
|
16
16
|
declare const inboundMessageSourceSchema: z.ZodEnum<{
|
|
17
17
|
slack: "slack";
|
|
18
18
|
plugin: "plugin";
|
|
19
|
-
api: "api";
|
|
20
19
|
local: "local";
|
|
20
|
+
api: "api";
|
|
21
21
|
internal: "internal";
|
|
22
22
|
resource_event: "resource_event";
|
|
23
23
|
scheduler: "scheduler";
|
|
@@ -66,8 +66,8 @@ export declare const inboundMessageSchema: z.ZodObject<{
|
|
|
66
66
|
source: z.ZodEnum<{
|
|
67
67
|
slack: "slack";
|
|
68
68
|
plugin: "plugin";
|
|
69
|
-
api: "api";
|
|
70
69
|
local: "local";
|
|
70
|
+
api: "api";
|
|
71
71
|
internal: "internal";
|
|
72
72
|
resource_event: "resource_event";
|
|
73
73
|
scheduler: "scheduler";
|
|
@@ -114,7 +114,7 @@ export declare function drainConversationMailbox(args: Parameters<typeof workSta
|
|
|
114
114
|
metadata?: Record<string, unknown> | undefined;
|
|
115
115
|
};
|
|
116
116
|
receivedAtMs: number;
|
|
117
|
-
source: "slack" | "plugin" | "
|
|
117
|
+
source: "slack" | "plugin" | "local" | "api" | "internal" | "resource_event" | "scheduler";
|
|
118
118
|
attemptCount?: number | undefined;
|
|
119
119
|
injectedAtMs?: number | undefined;
|
|
120
120
|
}[]>;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SANDBOX_WORKSPACE_ROOT,
|
|
3
3
|
getStateAdapter
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HMRVILWZ.js";
|
|
5
5
|
import {
|
|
6
6
|
sleep
|
|
7
7
|
} from "./chunk-4ZNGQH7C.js";
|
|
8
8
|
import {
|
|
9
9
|
toOptionalTrimmed
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-RCBUZGIT.js";
|
|
11
11
|
import {
|
|
12
12
|
pluginCatalogRuntime
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-LR2SKL5Y.js";
|
|
14
14
|
import {
|
|
15
15
|
setSpanAttributes,
|
|
16
16
|
setSpanStatus,
|
|
17
17
|
withSpan
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-36UJA3OD.js";
|
|
19
19
|
|
|
20
20
|
// src/chat/sandbox/runtime-dependencies.ts
|
|
21
21
|
var GLOBAL_RUNTIME_DEPENDENCIES = [
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-MU6HHZEN.js";
|
|
5
5
|
import {
|
|
6
6
|
getStateAdapter
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HMRVILWZ.js";
|
|
8
8
|
import {
|
|
9
9
|
contextProvenance,
|
|
10
10
|
createSqlConversationEventStore,
|
|
@@ -15,20 +15,17 @@ import {
|
|
|
15
15
|
instructionProvenanceFor,
|
|
16
16
|
sanitizePostgresJson,
|
|
17
17
|
withConversationEventLock
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-LLKDNPYV.js";
|
|
19
19
|
import {
|
|
20
20
|
sleep
|
|
21
21
|
} from "./chunk-4ZNGQH7C.js";
|
|
22
22
|
import {
|
|
23
23
|
botConfig,
|
|
24
24
|
escapeXml,
|
|
25
|
-
getPiMessageRole,
|
|
26
25
|
resolveGatewayModel,
|
|
27
|
-
retainRuntimeTurnContext,
|
|
28
26
|
standardModelId,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} from "./chunk-PK4ETCUQ.js";
|
|
27
|
+
unwrapCurrentInstruction
|
|
28
|
+
} from "./chunk-RCBUZGIT.js";
|
|
32
29
|
import {
|
|
33
30
|
toStoredSlackActor
|
|
34
31
|
} from "./chunk-C4MZ3GP5.js";
|
|
@@ -37,7 +34,7 @@ import {
|
|
|
37
34
|
logException,
|
|
38
35
|
logWarn,
|
|
39
36
|
setSpanAttributes
|
|
40
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-36UJA3OD.js";
|
|
41
38
|
import {
|
|
42
39
|
isRecord,
|
|
43
40
|
parseSlackMessageTs,
|
|
@@ -45,6 +42,111 @@ import {
|
|
|
45
42
|
toOptionalString
|
|
46
43
|
} from "./chunk-42WRQLJ6.js";
|
|
47
44
|
|
|
45
|
+
// src/chat/turn-context-tag.ts
|
|
46
|
+
var TURN_CONTEXT_TAG = "runtime-turn-context";
|
|
47
|
+
|
|
48
|
+
// src/chat/pi/transcript.ts
|
|
49
|
+
var RUNTIME_TURN_CONTEXT_START = `<${TURN_CONTEXT_TAG}>`;
|
|
50
|
+
function userMessageContent(message) {
|
|
51
|
+
const record = message;
|
|
52
|
+
return record.role === "user" && Array.isArray(record.content) ? record.content : void 0;
|
|
53
|
+
}
|
|
54
|
+
function isRuntimeTurnContextPart(part) {
|
|
55
|
+
return part !== null && typeof part === "object" && part.type === "text" && typeof part.text === "string" && part.text.startsWith(RUNTIME_TURN_CONTEXT_START);
|
|
56
|
+
}
|
|
57
|
+
var EMBEDDED_THREAD_CONTEXT_TAGS = [
|
|
58
|
+
"recent-thread-messages",
|
|
59
|
+
"thread-compactions",
|
|
60
|
+
"thread-transcript",
|
|
61
|
+
"thread-background"
|
|
62
|
+
];
|
|
63
|
+
var EMBEDDED_THREAD_CONTEXT_PATTERN = new RegExp(
|
|
64
|
+
`<(${EMBEDDED_THREAD_CONTEXT_TAGS.join("|")})(?:\\s[^>]*)?>[\\s\\S]*?</\\1>`,
|
|
65
|
+
"g"
|
|
66
|
+
);
|
|
67
|
+
function isAssistantMessage(value) {
|
|
68
|
+
return typeof value === "object" && value !== null && value.role === "assistant";
|
|
69
|
+
}
|
|
70
|
+
function isToolResultMessage(value) {
|
|
71
|
+
return typeof value === "object" && value !== null && value.role === "toolResult";
|
|
72
|
+
}
|
|
73
|
+
function isToolResultError(result) {
|
|
74
|
+
if (!result || typeof result !== "object") return false;
|
|
75
|
+
return Boolean(result.isError);
|
|
76
|
+
}
|
|
77
|
+
function normalizeToolNameFromResult(result) {
|
|
78
|
+
if (!result || typeof result !== "object") return void 0;
|
|
79
|
+
const record = result;
|
|
80
|
+
if (typeof record.toolName === "string" && record.toolName.length > 0) {
|
|
81
|
+
return record.toolName;
|
|
82
|
+
}
|
|
83
|
+
if (typeof record.name === "string" && record.name.length > 0) {
|
|
84
|
+
return record.name;
|
|
85
|
+
}
|
|
86
|
+
return void 0;
|
|
87
|
+
}
|
|
88
|
+
function getPiMessageRole(value) {
|
|
89
|
+
if (!value || typeof value !== "object") {
|
|
90
|
+
return void 0;
|
|
91
|
+
}
|
|
92
|
+
const role = value.role;
|
|
93
|
+
return typeof role === "string" ? role : void 0;
|
|
94
|
+
}
|
|
95
|
+
function isContinuablePiBoundary(messages) {
|
|
96
|
+
const lastRole = getPiMessageRole(messages.at(-1));
|
|
97
|
+
return lastRole === "user" || lastRole === "toolResult";
|
|
98
|
+
}
|
|
99
|
+
function extractAssistantText(message) {
|
|
100
|
+
const content = message.content ?? [];
|
|
101
|
+
return content.filter(
|
|
102
|
+
(part) => part.type === "text" && typeof part.text === "string"
|
|
103
|
+
).map((part) => part.text).join("\n");
|
|
104
|
+
}
|
|
105
|
+
function getTerminalAssistantMessages(messages) {
|
|
106
|
+
let lastNonAssistantIndex = -1;
|
|
107
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
108
|
+
if (!isAssistantMessage(messages[index])) {
|
|
109
|
+
lastNonAssistantIndex = index;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return messages.slice(lastNonAssistantIndex + 1).filter(isAssistantMessage);
|
|
114
|
+
}
|
|
115
|
+
function trimTrailingAssistantMessages(messages) {
|
|
116
|
+
let end = messages.length;
|
|
117
|
+
while (end > 0 && getPiMessageRole(messages[end - 1]) === "assistant") {
|
|
118
|
+
end -= 1;
|
|
119
|
+
}
|
|
120
|
+
return end === messages.length ? [...messages] : messages.slice(0, end);
|
|
121
|
+
}
|
|
122
|
+
function hasRuntimeTurnContext(messages) {
|
|
123
|
+
return messages.some(
|
|
124
|
+
(message) => userMessageContent(message)?.some(isRuntimeTurnContextPart)
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
function retainRuntimeTurnContext(messages) {
|
|
128
|
+
return messages.flatMap((message) => {
|
|
129
|
+
const runtimeContent = userMessageContent(message)?.filter(isRuntimeTurnContextPart) ?? [];
|
|
130
|
+
return runtimeContent.length > 0 ? [{ ...message, content: runtimeContent }] : [];
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function instructionTextForProjection(text) {
|
|
134
|
+
const withoutContext = text.replace(EMBEDDED_THREAD_CONTEXT_PATTERN, "").trim();
|
|
135
|
+
return unwrapCurrentInstruction(withoutContext) ?? withoutContext;
|
|
136
|
+
}
|
|
137
|
+
function stripRuntimeTurnContext(messages) {
|
|
138
|
+
return messages.flatMap((message) => {
|
|
139
|
+
const content = userMessageContent(message);
|
|
140
|
+
if (!content) return [message];
|
|
141
|
+
const nextContent = content.filter(
|
|
142
|
+
(part) => !isRuntimeTurnContextPart(part)
|
|
143
|
+
);
|
|
144
|
+
if (nextContent.length === content.length) return [message];
|
|
145
|
+
if (nextContent.length === 0) return [];
|
|
146
|
+
return [{ ...message, content: nextContent }];
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
48
150
|
// src/chat/conversations/projection.ts
|
|
49
151
|
import { isDeepStrictEqual } from "util";
|
|
50
152
|
|
|
@@ -1033,13 +1135,9 @@ function addDurationMs(prior, current) {
|
|
|
1033
1135
|
}, void 0);
|
|
1034
1136
|
return total;
|
|
1035
1137
|
}
|
|
1036
|
-
function isContinuableBoundary(messages) {
|
|
1037
|
-
const lastRole = getPiMessageRole(messages.at(-1));
|
|
1038
|
-
return lastRole === "user" || lastRole === "toolResult";
|
|
1039
|
-
}
|
|
1040
1138
|
function resumableBoundary(messages, fallbackMessages) {
|
|
1041
1139
|
const current = trimTrailingAssistantMessages(messages);
|
|
1042
|
-
if (current.length > 0 &&
|
|
1140
|
+
if (current.length > 0 && isContinuablePiBoundary(current)) {
|
|
1043
1141
|
return current;
|
|
1044
1142
|
}
|
|
1045
1143
|
return trimTrailingAssistantMessages(fallbackMessages ?? []);
|
|
@@ -1059,7 +1157,7 @@ async function loadTurnSessionRecord(ctx) {
|
|
|
1059
1157
|
};
|
|
1060
1158
|
}
|
|
1061
1159
|
async function persistRunningSessionRecord(args) {
|
|
1062
|
-
if (args.messages.length === 0 || !
|
|
1160
|
+
if (args.messages.length === 0 || !isContinuablePiBoundary(args.messages)) {
|
|
1063
1161
|
return false;
|
|
1064
1162
|
}
|
|
1065
1163
|
try {
|
|
@@ -1184,7 +1282,7 @@ async function persistAuthPauseSessionRecord(args) {
|
|
|
1184
1282
|
args.messages,
|
|
1185
1283
|
latestSessionRecord?.piMessages
|
|
1186
1284
|
);
|
|
1187
|
-
if (piMessages.length > 0 && !
|
|
1285
|
+
if (piMessages.length > 0 && !isContinuablePiBoundary(piMessages)) {
|
|
1188
1286
|
return void 0;
|
|
1189
1287
|
}
|
|
1190
1288
|
return await upsertAgentTurnSessionRecord({
|
|
@@ -1241,7 +1339,7 @@ async function persistContinuationSessionRecord(args) {
|
|
|
1241
1339
|
args.messages,
|
|
1242
1340
|
latestSessionRecord?.piMessages
|
|
1243
1341
|
);
|
|
1244
|
-
if (piMessages.length === 0 || !
|
|
1342
|
+
if (piMessages.length === 0 || !isContinuablePiBoundary(piMessages)) {
|
|
1245
1343
|
return void 0;
|
|
1246
1344
|
}
|
|
1247
1345
|
const cumulativeDurationMs = addDurationMs(
|
|
@@ -1322,17 +1420,14 @@ async function persistContinuationSessionRecord(args) {
|
|
|
1322
1420
|
}
|
|
1323
1421
|
async function persistYieldSessionRecord(args) {
|
|
1324
1422
|
try {
|
|
1423
|
+
const piMessages = [...args.messages];
|
|
1424
|
+
if (piMessages.length === 0 || !isContinuablePiBoundary(piMessages)) {
|
|
1425
|
+
return void 0;
|
|
1426
|
+
}
|
|
1325
1427
|
const latestSessionRecord = await getAgentTurnSessionRecord(
|
|
1326
1428
|
args.conversationId,
|
|
1327
1429
|
args.sessionId
|
|
1328
1430
|
);
|
|
1329
|
-
const piMessages = resumableBoundary(
|
|
1330
|
-
args.messages,
|
|
1331
|
-
latestSessionRecord?.piMessages
|
|
1332
|
-
);
|
|
1333
|
-
if (piMessages.length === 0 || !isContinuableBoundary(piMessages)) {
|
|
1334
|
-
return void 0;
|
|
1335
|
-
}
|
|
1336
1431
|
return await upsertAgentTurnSessionRecord({
|
|
1337
1432
|
...args.channelName ?? latestSessionRecord?.channelName ? { channelName: args.channelName ?? latestSessionRecord?.channelName } : {},
|
|
1338
1433
|
conversationId: args.conversationId,
|
|
@@ -2533,6 +2628,20 @@ function isPendingAuthLatestRequest(conversation, pendingAuth) {
|
|
|
2533
2628
|
}
|
|
2534
2629
|
|
|
2535
2630
|
export {
|
|
2631
|
+
TURN_CONTEXT_TAG,
|
|
2632
|
+
isAssistantMessage,
|
|
2633
|
+
isToolResultMessage,
|
|
2634
|
+
isToolResultError,
|
|
2635
|
+
normalizeToolNameFromResult,
|
|
2636
|
+
getPiMessageRole,
|
|
2637
|
+
isContinuablePiBoundary,
|
|
2638
|
+
extractAssistantText,
|
|
2639
|
+
getTerminalAssistantMessages,
|
|
2640
|
+
trimTrailingAssistantMessages,
|
|
2641
|
+
hasRuntimeTurnContext,
|
|
2642
|
+
retainRuntimeTurnContext,
|
|
2643
|
+
instructionTextForProjection,
|
|
2644
|
+
stripRuntimeTurnContext,
|
|
2536
2645
|
loadProjection,
|
|
2537
2646
|
loadConversationProjection,
|
|
2538
2647
|
openConversationProjection,
|