@sentry/junior 0.203.0 → 0.204.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-CMyTD4DD.js +17509 -0
- package/dist/agent-hooks-Bbcp9e33.js +4040 -0
- package/dist/agent-runner-DNb1A49M.js +678 -0
- package/dist/api/schema.d.ts +2728 -2639
- package/dist/api/schema.js +4 -169
- package/dist/api.d.ts +23 -17
- package/dist/api.js +3881 -5326
- package/dist/app-B1TOqBI8.d.ts +246 -0
- package/dist/app.d.ts +4 -520
- package/dist/app.js +9522 -11875
- package/dist/auth-pause-state-DosEalIG.js +168 -0
- package/dist/catalog-runtime-BReos-D4.js +7 -0
- package/dist/checkpoint-CNrPyRJN.js +2450 -0
- package/dist/cli/chat.d.ts +20 -0
- package/dist/cli/chat.js +229 -336
- package/dist/cli/check.d.ts +8 -0
- package/dist/cli/check.js +513 -806
- package/dist/cli/env.d.ts +13 -0
- package/dist/cli/env.js +63 -12
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.js +90 -159
- package/dist/cli/main.d.ts +6 -0
- package/dist/cli/main.js +43 -64
- package/dist/cli/plugins.d.ts +13 -0
- package/dist/cli/plugins.js +148 -227
- package/dist/cli/run.d.ts +16 -0
- package/dist/cli/run.js +52 -8
- package/dist/cli/snapshot-create.d.ts +4 -0
- package/dist/cli/snapshot-create.js +71 -125
- package/dist/cli/upgrade.d.ts +15 -0
- package/dist/cli/upgrade.js +232 -335
- package/dist/config-nGCW1OTG.js +941 -0
- package/dist/context-B45_WqVX.js +298 -0
- package/dist/conversation-privacy-B4voFRSm.js +182 -0
- package/dist/conversation-work-C6y3T5Hx.js +51 -0
- package/dist/credential-sync-kXr1hvO1.js +2660 -0
- package/dist/db-BeyXKJOI.d.ts +5 -0
- package/dist/destinations-BeBiJeEM.js +29 -0
- package/dist/execution-stats-DWfSihcH.js +373 -0
- package/dist/executor-DcMSlI5c.js +721 -0
- package/dist/experimental-CIXf7Uye.js +46 -0
- package/dist/history-ClE4toxe.d.ts +32 -0
- package/dist/history-CqTuSAdI.js +441 -0
- package/dist/instrumentation.d.ts +3 -3
- package/dist/instrumentation.js +130 -176
- package/dist/job-queue-Drn_LXlM.js +63 -0
- package/dist/logging-BzAk1S_s.js +1210 -0
- package/dist/model-profile-CZmVoGdX.js +49 -0
- package/dist/nitro.d.ts +31 -36
- package/dist/nitro.js +275 -456
- package/dist/oauth-callback-server-JiftokvA.js +130 -0
- package/dist/oauth-relay-CdCnu80W.js +62 -0
- package/dist/package-discovery-7a9YqLhE.js +455 -0
- package/dist/pending-auth-CWmSdZVg.js +185 -0
- package/dist/plugin-module-BKGOXca2.js +81 -0
- package/dist/plugins-BI9A1vKA.d.ts +95 -0
- package/dist/plugins-egKWjgue.js +99 -0
- package/dist/private-trace-result-BLvBjy_e.js +16 -0
- package/dist/profile-CrT5nXbw.js +861 -0
- package/dist/registry-DH1xUo2N.js +1419 -0
- package/dist/reporting-schema-DosTN__Q.js +105 -0
- package/dist/resolve-CZHnfxaS.js +546 -0
- package/dist/rolldown-runtime-B4FMCO8f.js +28 -0
- package/dist/runner-CZV2sC46.js +392 -0
- package/dist/sandbox-egress-signals-bHZfmhbd.js +46 -0
- package/dist/schema-Rn8-XEaN.js +1140 -0
- package/dist/sentry-CD3SdJl-.js +26 -0
- package/dist/skills-CIcDQSgM.js +316 -0
- package/dist/spawn-DdkUFRmq.js +29 -0
- package/dist/stats-DTUbAb88.js +2634 -0
- package/dist/store-C5qxF2ac.d.ts +208 -0
- package/dist/task-queue-CJIR4RF7.js +136 -0
- package/dist/task-runner-D-O3A-Cp.js +639 -0
- package/dist/thread-state-CRc9jTJS.js +431 -0
- package/dist/turn-execution-BkinIdJF.js +47 -0
- package/dist/turn-lifecycle-DQV19VTW.js +54 -0
- package/dist/usage-D3EbSO7w.js +296 -0
- package/dist/usage-schema-CKaDkH_j.js +20 -0
- package/dist/validation-C2CR-OX3.js +40 -0
- package/dist/vercel-queue-DIkVcfK4.js +167 -0
- package/dist/vercel.d.ts +6 -6
- package/dist/vercel.js +14 -6
- package/dist/version-CnXZ614E.d.ts +5 -0
- package/dist/version-DxcWdoKa.js +8 -0
- package/dist/version.d.ts +2 -4
- package/dist/version.js +2 -6
- package/dist/web-authorization-RMBxAR_t.js +76 -0
- package/dist/web-input-3EPfpf55.js +494 -0
- package/dist/work-fGofI7Op.js +509 -0
- package/dist/worker-CsOLq-mR.js +625 -0
- package/package.json +8 -8
- package/dist/agent-hooks-GB2VPTNA.js +0 -51
- package/dist/catalog-runtime-UBLIWD3O.js +0 -14
- package/dist/chunk-2LYHWMR4.js +0 -46
- package/dist/chunk-352OWAZH.js +0 -320
- package/dist/chunk-3Y47VMHV.js +0 -6
- package/dist/chunk-3YJSKOWF.js +0 -164
- package/dist/chunk-4KSSKTQ5.js +0 -229
- package/dist/chunk-4UO6FK4G.js +0 -64
- package/dist/chunk-5AHX53NQ.js +0 -717
- package/dist/chunk-5J3E5FWA.js +0 -700
- package/dist/chunk-5PDAG6O3.js +0 -206
- package/dist/chunk-6Y5B5PEX.js +0 -80
- package/dist/chunk-7GWQ5S5R.js +0 -2086
- package/dist/chunk-7H2VZTWN.js +0 -103
- package/dist/chunk-7NL7T6VU.js +0 -406
- package/dist/chunk-A5L27LE4.js +0 -387
- package/dist/chunk-ADIAWL34.js +0 -81
- package/dist/chunk-ASTEMBKJ.js +0 -519
- package/dist/chunk-CEMMLV5L.js +0 -98
- package/dist/chunk-CM5HNV2W.js +0 -131
- package/dist/chunk-CRTRBBRI.js +0 -105
- package/dist/chunk-DA2KGZZI.js +0 -13
- package/dist/chunk-DIB4GX3G.js +0 -8
- package/dist/chunk-DKIJ2RP5.js +0 -68
- package/dist/chunk-DWPN6SCH.js +0 -172
- package/dist/chunk-EDKUFGPL.js +0 -64
- package/dist/chunk-ENY6SKIU.js +0 -1228
- package/dist/chunk-F4MGCZOX.js +0 -2943
- package/dist/chunk-FA6POGLH.js +0 -70
- package/dist/chunk-FSUR7GTG.js +0 -20475
- package/dist/chunk-GKEOHJL5.js +0 -1856
- package/dist/chunk-GMCB6W5Y.js +0 -333
- package/dist/chunk-IE2VPG7O.js +0 -1135
- package/dist/chunk-IZ5B5IHQ.js +0 -3656
- package/dist/chunk-JAL3CH4G.js +0 -27
- package/dist/chunk-KIIEUXD3.js +0 -1764
- package/dist/chunk-KXU4NIL7.js +0 -692
- package/dist/chunk-MTM5IFCY.js +0 -1190
- package/dist/chunk-N7TMSOZH.js +0 -235
- package/dist/chunk-NCEBK6PH.js +0 -36
- package/dist/chunk-NHJU2ZAL.js +0 -56
- package/dist/chunk-P6KTRNVC.js +0 -321
- package/dist/chunk-PDO5BLNM.js +0 -22
- package/dist/chunk-PDRNLLFT.js +0 -3295
- package/dist/chunk-PEQXYSSE.js +0 -45
- package/dist/chunk-PKEX2AQX.js +0 -198
- package/dist/chunk-PSJCGIGO.js +0 -1163
- package/dist/chunk-PZUSUL55.js +0 -506
- package/dist/chunk-R45M4TUS.js +0 -37
- package/dist/chunk-RC745GGZ.js +0 -122
- package/dist/chunk-SP3QKZXJ.js +0 -820
- package/dist/chunk-TXKUKMVO.js +0 -417
- package/dist/chunk-UE4GPWSD.js +0 -931
- package/dist/chunk-UIE3R5XU.js +0 -17
- package/dist/chunk-UXPG6ZIN.js +0 -84
- package/dist/chunk-VFUK3X5B.js +0 -50
- package/dist/chunk-VNMJWREK.js +0 -787
- package/dist/chunk-VZ7CSOX2.js +0 -706
- package/dist/chunk-WCNQJKFT.js +0 -10
- package/dist/chunk-WDZR3QQM.js +0 -135
- package/dist/chunk-WLYVJCHV.js +0 -1433
- package/dist/chunk-WS7NAFTM.js +0 -1520
- package/dist/chunk-X6GDDWQH.js +0 -60
- package/dist/chunk-XPDEYNQI.js +0 -102
- package/dist/chunk-XRW44VGM.js +0 -58
- package/dist/chunk-Y2CM7HXH.js +0 -111
- package/dist/chunk-Y7X25LFY.js +0 -15
- package/dist/conversation-work-VIOQ5ZF3.js +0 -54
- package/dist/db-NGDJV7YH.js +0 -26
- package/dist/discovery-DWVDM7UK.js +0 -44
- package/dist/experimental-P5FZM4CU.js +0 -12
- package/dist/oauth-callback-server-YFY7YEGK.js +0 -243
- package/dist/oauth-relay-5XPVRPYB.js +0 -8
- package/dist/plugins-YTYJMMJF.js +0 -14
- package/dist/runner-ORTNSB2Q.js +0 -522
- package/dist/sandbox-egress-signals-FIL7EGPR.js +0 -73
- package/dist/sentry-MB3NL3IR.js +0 -42
- package/dist/skills-H376WQOH.js +0 -27
- package/dist/spawn-T43WHLOS.js +0 -42
- package/dist/task-runner-LBZWF32V.js +0 -36
- package/dist/validation-REJLRKI6.js +0 -17
- package/dist/work-3KJ3RE76.js +0 -51
- package/dist/worker-QFEBU72E.js +0 -24
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { p as authorizationId } from "./agent-CMyTD4DD.js";
|
|
2
|
+
import { S as withLogContext, u as logException, y as setTags } from "./logging-BzAk1S_s.js";
|
|
3
|
+
import { t as credentialContextForActor } from "./context-B45_WqVX.js";
|
|
4
|
+
import { Ct as getConversationEventStore, Tt as getConversationStore } from "./agent-hooks-Bbcp9e33.js";
|
|
5
|
+
import { $ as persistConversationMessages, P as commitAcceptedReply, Q as hydrateConversationMessages, R as loadProjection, W as recordAuthorizationCompleted, d as persistWithRetry, dt as recordDeliveredAssistantMessage, it as buildConversationContext, jt as stripRuntimeTurnContext, lt as markConversationMessage, pt as upsertConversationMessage, r as saveTurnCheckpoint, ut as normalizeConversationText } from "./checkpoint-CNrPyRJN.js";
|
|
6
|
+
import { S as startActiveTurn, s as getAssistantReplyText, x as markTurnFailed } from "./pending-auth-CWmSdZVg.js";
|
|
7
|
+
import { n as scheduleSessionCompletedPluginTasks, t as processPluginTask } from "./task-runner-D-O3A-Cp.js";
|
|
8
|
+
import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-DQV19VTW.js";
|
|
9
|
+
import { n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-CRc9jTJS.js";
|
|
10
|
+
import { d as buildDeliveredTurnStatePatch, r as finalizeFailedTurnReplyWithEvent, t as completeAuthPauseTurn } from "./auth-pause-state-DosEalIG.js";
|
|
11
|
+
import { randomUUID } from "node:crypto";
|
|
12
|
+
import { createLocalSource, localDestinationSchema } from "@sentry/junior-plugin-api";
|
|
13
|
+
//#region src/chat/local/runner.ts
|
|
14
|
+
const SENTRY_EVENT_ID_PATTERN = /^[a-f0-9]{32}$/i;
|
|
15
|
+
const LOCAL_FAILURE_EVENT_NAMES = {
|
|
16
|
+
agent_run_failed: "local.agent_run.failed",
|
|
17
|
+
delivery_failed: "local.reply.delivery.failed",
|
|
18
|
+
model_execution_failed: "local.model.execution.failed",
|
|
19
|
+
persistence_failed: "local.turn.persistence.failed"
|
|
20
|
+
};
|
|
21
|
+
function localDestination(conversationId) {
|
|
22
|
+
const parsed = localDestinationSchema.safeParse({
|
|
23
|
+
platform: "local",
|
|
24
|
+
conversationId
|
|
25
|
+
});
|
|
26
|
+
if (!parsed.success) throw new Error("Invalid local conversation id");
|
|
27
|
+
return parsed.data;
|
|
28
|
+
}
|
|
29
|
+
function localTurnId() {
|
|
30
|
+
return `local-turn-${randomUUID()}`;
|
|
31
|
+
}
|
|
32
|
+
function localRunId() {
|
|
33
|
+
return `local-run-${randomUUID()}`;
|
|
34
|
+
}
|
|
35
|
+
function captureLocalBoundaryFailure(args) {
|
|
36
|
+
setTags({
|
|
37
|
+
conversationId: args.conversationId,
|
|
38
|
+
...args.runId ? { runId: args.runId } : void 0
|
|
39
|
+
});
|
|
40
|
+
const eventId = args.capture(args.error, LOCAL_FAILURE_EVENT_NAMES[args.failureCode], { "app.ai.failure_code": args.failureCode });
|
|
41
|
+
return eventId && SENTRY_EVENT_ID_PATTERN.test(eventId) ? eventId : void 0;
|
|
42
|
+
}
|
|
43
|
+
/** Load durable local Pi history from the conversation-event projection. */
|
|
44
|
+
async function loadLocalPiMessages(args) {
|
|
45
|
+
const projection = await loadProjection({ conversationId: args.conversationId });
|
|
46
|
+
if (projection.length === 0) return;
|
|
47
|
+
return stripRuntimeTurnContext(projection);
|
|
48
|
+
}
|
|
49
|
+
/** Run one local CLI message through Junior's shared agent-run boundary. */
|
|
50
|
+
async function runLocalAgentTurn(input, deps) {
|
|
51
|
+
return withLogContext({
|
|
52
|
+
conversationId: input.conversationId,
|
|
53
|
+
destinationName: input.conversationId,
|
|
54
|
+
messageConversationId: input.conversationId,
|
|
55
|
+
platform: "local",
|
|
56
|
+
userId: "local-cli",
|
|
57
|
+
userName: "local"
|
|
58
|
+
}, () => runLocalAgentTurnInContext(input, deps));
|
|
59
|
+
}
|
|
60
|
+
async function runLocalAgentTurnInContext(input, deps) {
|
|
61
|
+
const text = input.message.trim();
|
|
62
|
+
if (!text) throw new Error("Local agent message must not be empty");
|
|
63
|
+
const destination = localDestination(input.conversationId);
|
|
64
|
+
const source = createLocalSource(destination.conversationId);
|
|
65
|
+
const lifecycle = new ConversationTurnLifecycleService(getConversationEventStore());
|
|
66
|
+
await getConversationStore().recordActivity({
|
|
67
|
+
conversationId: input.conversationId,
|
|
68
|
+
destination,
|
|
69
|
+
nowMs: Date.now(),
|
|
70
|
+
source: "local",
|
|
71
|
+
visibility: "private"
|
|
72
|
+
});
|
|
73
|
+
const persisted = await getPersistedThreadState(input.conversationId);
|
|
74
|
+
const conversation = coerceThreadConversationState(persisted);
|
|
75
|
+
await hydrateConversationMessages({
|
|
76
|
+
conversation,
|
|
77
|
+
conversationId: input.conversationId
|
|
78
|
+
});
|
|
79
|
+
let sandboxRef = getPersistedSandboxState(persisted);
|
|
80
|
+
const initialSandboxRef = sandboxRef;
|
|
81
|
+
const turnId = localTurnId();
|
|
82
|
+
const userMessageId = `${turnId}:user`;
|
|
83
|
+
const startedAtMs = Date.now();
|
|
84
|
+
upsertConversationMessage(conversation, {
|
|
85
|
+
id: userMessageId,
|
|
86
|
+
role: "user",
|
|
87
|
+
text: normalizeConversationText(text),
|
|
88
|
+
createdAtMs: startedAtMs,
|
|
89
|
+
author: {
|
|
90
|
+
fullName: "Local CLI",
|
|
91
|
+
userId: "local-cli",
|
|
92
|
+
userName: "local"
|
|
93
|
+
},
|
|
94
|
+
meta: {
|
|
95
|
+
explicitMention: true,
|
|
96
|
+
replied: false
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
await persistConversationMessages({
|
|
100
|
+
conversation,
|
|
101
|
+
conversationId: input.conversationId
|
|
102
|
+
});
|
|
103
|
+
await lifecycle.start({
|
|
104
|
+
conversationId: input.conversationId,
|
|
105
|
+
createdAtMs: Date.now(),
|
|
106
|
+
inputMessageIds: [userMessageId],
|
|
107
|
+
surface: "internal",
|
|
108
|
+
turnId
|
|
109
|
+
});
|
|
110
|
+
startActiveTurn({
|
|
111
|
+
conversation,
|
|
112
|
+
nextTurnId: turnId
|
|
113
|
+
});
|
|
114
|
+
let reply;
|
|
115
|
+
let completedState;
|
|
116
|
+
let failureCode = "persistence_failed";
|
|
117
|
+
let modelFailureEventId;
|
|
118
|
+
let modelFailureReason;
|
|
119
|
+
let modelFailureCaptureAttempted = false;
|
|
120
|
+
let currentRunId;
|
|
121
|
+
let completionSliceId = 1;
|
|
122
|
+
const localActor = {
|
|
123
|
+
fullName: "Local CLI",
|
|
124
|
+
platform: "local",
|
|
125
|
+
userId: "local-cli",
|
|
126
|
+
userName: "local"
|
|
127
|
+
};
|
|
128
|
+
let assistantMessageDelivered = false;
|
|
129
|
+
/** Print and record one completed assistant message in local conversation order. */
|
|
130
|
+
const deliverAssistantMessage = async (reply) => {
|
|
131
|
+
const message = typeof reply === "string" ? void 0 : reply;
|
|
132
|
+
const text = typeof reply === "string" ? reply : getAssistantReplyText(reply);
|
|
133
|
+
if (!text?.trim()) return;
|
|
134
|
+
failureCode = "delivery_failed";
|
|
135
|
+
await deps.deliverReply({ text });
|
|
136
|
+
assistantMessageDelivered = true;
|
|
137
|
+
const recordedMessageId = recordDeliveredAssistantMessage({
|
|
138
|
+
conversation,
|
|
139
|
+
sessionId: turnId,
|
|
140
|
+
text,
|
|
141
|
+
userMessageId
|
|
142
|
+
});
|
|
143
|
+
try {
|
|
144
|
+
await persistWithRetry(() => message ? commitAcceptedReply({
|
|
145
|
+
agentMessage: message,
|
|
146
|
+
conversation,
|
|
147
|
+
conversationMessageId: recordedMessageId,
|
|
148
|
+
conversationId: input.conversationId
|
|
149
|
+
}) : persistConversationMessages({
|
|
150
|
+
conversation,
|
|
151
|
+
conversationId: input.conversationId
|
|
152
|
+
}));
|
|
153
|
+
} catch (error) {
|
|
154
|
+
logException(/* @__PURE__ */ new Error("Accepted assistant message persistence failed"), "local.assistant.message_post_delivery_persist.failed", { "error.type": error instanceof Error ? error.name : typeof error });
|
|
155
|
+
}
|
|
156
|
+
failureCode = "agent_run_failed";
|
|
157
|
+
};
|
|
158
|
+
try {
|
|
159
|
+
await persistThreadStateById(input.conversationId, { conversation });
|
|
160
|
+
const piMessages = await loadLocalPiMessages({ conversationId: input.conversationId });
|
|
161
|
+
failureCode = "agent_run_failed";
|
|
162
|
+
const runAgent = async (messages) => {
|
|
163
|
+
currentRunId = localRunId();
|
|
164
|
+
setTags({ runId: currentRunId });
|
|
165
|
+
const authorization = deps.authorization ? {
|
|
166
|
+
createState: deps.authorization.createState,
|
|
167
|
+
deliver: deps.authorization.deliver
|
|
168
|
+
} : void 0;
|
|
169
|
+
return await deps.agentRunner.run({
|
|
170
|
+
conversationId: input.conversationId,
|
|
171
|
+
turnId,
|
|
172
|
+
runId: currentRunId,
|
|
173
|
+
instruction: {
|
|
174
|
+
text,
|
|
175
|
+
context: buildConversationContext(conversation, { excludeMessageId: userMessageId })
|
|
176
|
+
},
|
|
177
|
+
history: messages,
|
|
178
|
+
actor: localActor,
|
|
179
|
+
credentialContext: credentialContextForActor(localActor),
|
|
180
|
+
destination,
|
|
181
|
+
source,
|
|
182
|
+
surface: "internal",
|
|
183
|
+
authorization,
|
|
184
|
+
...deps.authorization ? void 0 : { disabledFeatures: ["interactive-auth"] },
|
|
185
|
+
environment: { sandboxEgressSignals: deps.sandboxEgressSignals },
|
|
186
|
+
state: {
|
|
187
|
+
pendingAuth: conversation.processing.pendingAuth,
|
|
188
|
+
sandboxRef
|
|
189
|
+
},
|
|
190
|
+
onEvent: async (event) => {
|
|
191
|
+
if (event.type === "status") {
|
|
192
|
+
await deps.onStatus?.(event.text);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (event.type === "tool_started") {
|
|
196
|
+
await deps.onToolInvocation?.({
|
|
197
|
+
params: event.params,
|
|
198
|
+
toolName: event.toolName
|
|
199
|
+
});
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (event.type === "tool_finished") await deps.onToolResult?.(event.report);
|
|
203
|
+
},
|
|
204
|
+
delivery: deliverAssistantMessage,
|
|
205
|
+
durability: {
|
|
206
|
+
onSandboxRefChanged: async (nextSandboxRef) => {
|
|
207
|
+
sandboxRef = nextSandboxRef;
|
|
208
|
+
await persistThreadStateById(input.conversationId, {
|
|
209
|
+
conversation,
|
|
210
|
+
sandboxRef
|
|
211
|
+
});
|
|
212
|
+
},
|
|
213
|
+
recordPendingAuth: async (pendingAuth) => {
|
|
214
|
+
conversation.processing.pendingAuth = pendingAuth;
|
|
215
|
+
await persistThreadStateById(input.conversationId, {
|
|
216
|
+
conversation,
|
|
217
|
+
sandboxRef
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
};
|
|
223
|
+
let outcome = await runAgent(piMessages);
|
|
224
|
+
while (outcome.status === "awaiting_auth") {
|
|
225
|
+
const pendingAuth = conversation.processing.pendingAuth;
|
|
226
|
+
if (!pendingAuth || !deps.authorization) throw new Error("Local OAuth requires an active callback server and authorization delivery.");
|
|
227
|
+
completeAuthPauseTurn({
|
|
228
|
+
conversation,
|
|
229
|
+
sessionId: turnId
|
|
230
|
+
});
|
|
231
|
+
await persistThreadStateById(input.conversationId, {
|
|
232
|
+
conversation,
|
|
233
|
+
sandboxRef
|
|
234
|
+
});
|
|
235
|
+
await deps.authorization.wait();
|
|
236
|
+
await recordAuthorizationCompleted({
|
|
237
|
+
conversationId: input.conversationId,
|
|
238
|
+
kind: pendingAuth.kind,
|
|
239
|
+
provider: pendingAuth.provider,
|
|
240
|
+
actorId: pendingAuth.actorId,
|
|
241
|
+
authorizationId: authorizationId({
|
|
242
|
+
sessionId: turnId,
|
|
243
|
+
kind: pendingAuth.kind,
|
|
244
|
+
provider: pendingAuth.provider
|
|
245
|
+
})
|
|
246
|
+
});
|
|
247
|
+
completionSliceId += 1;
|
|
248
|
+
outcome = await runAgent(await loadLocalPiMessages({ conversationId: input.conversationId }));
|
|
249
|
+
}
|
|
250
|
+
if (outcome.status !== "completed") throw new Error(`Local agent run ended with ${outcome.status}`);
|
|
251
|
+
reply = outcome.result;
|
|
252
|
+
modelFailureCaptureAttempted = reply.diagnostics.outcome !== "success";
|
|
253
|
+
const finalized = finalizeFailedTurnReplyWithEvent({
|
|
254
|
+
reply,
|
|
255
|
+
logException
|
|
256
|
+
});
|
|
257
|
+
reply = finalized.reply;
|
|
258
|
+
modelFailureEventId = finalized.eventId;
|
|
259
|
+
modelFailureReason = finalized.failureReason;
|
|
260
|
+
if (reply.diagnostics.outcome !== "success") await deliverAssistantMessage(reply.text);
|
|
261
|
+
completedState = buildDeliveredTurnStatePatch({
|
|
262
|
+
conversation,
|
|
263
|
+
reply,
|
|
264
|
+
sessionId: turnId,
|
|
265
|
+
userMessageId
|
|
266
|
+
});
|
|
267
|
+
} catch (error) {
|
|
268
|
+
deps.authorization?.cancel();
|
|
269
|
+
const failureEventId = modelFailureCaptureAttempted && failureCode === "agent_run_failed" ? modelFailureEventId : captureLocalBoundaryFailure({
|
|
270
|
+
capture: logException,
|
|
271
|
+
conversationId: input.conversationId,
|
|
272
|
+
error,
|
|
273
|
+
failureCode,
|
|
274
|
+
runId: currentRunId
|
|
275
|
+
});
|
|
276
|
+
try {
|
|
277
|
+
markTurnFailed({
|
|
278
|
+
conversation,
|
|
279
|
+
nowMs: Date.now(),
|
|
280
|
+
sessionId: turnId,
|
|
281
|
+
userMessageId,
|
|
282
|
+
markConversationMessage
|
|
283
|
+
});
|
|
284
|
+
await persistThreadStateById(input.conversationId, {
|
|
285
|
+
conversation,
|
|
286
|
+
sandboxRef: initialSandboxRef ?? null
|
|
287
|
+
});
|
|
288
|
+
} catch (persistenceError) {
|
|
289
|
+
const persistenceEventId = captureLocalBoundaryFailure({
|
|
290
|
+
capture: logException,
|
|
291
|
+
conversationId: input.conversationId,
|
|
292
|
+
error: persistenceError,
|
|
293
|
+
failureCode: "persistence_failed",
|
|
294
|
+
runId: currentRunId
|
|
295
|
+
});
|
|
296
|
+
await lifecycle.fail({
|
|
297
|
+
conversationId: input.conversationId,
|
|
298
|
+
createdAtMs: Date.now(),
|
|
299
|
+
...persistenceEventId ? { eventId: persistenceEventId } : void 0,
|
|
300
|
+
failureCode: "persistence_failed",
|
|
301
|
+
turnId
|
|
302
|
+
});
|
|
303
|
+
throw new AggregateError([error, persistenceError], "Local turn failure state could not be persisted");
|
|
304
|
+
}
|
|
305
|
+
await lifecycle.fail({
|
|
306
|
+
conversationId: input.conversationId,
|
|
307
|
+
createdAtMs: Date.now(),
|
|
308
|
+
...failureEventId ? { eventId: failureEventId } : void 0,
|
|
309
|
+
failureCode,
|
|
310
|
+
turnId
|
|
311
|
+
});
|
|
312
|
+
throw error;
|
|
313
|
+
}
|
|
314
|
+
deps.authorization?.cancel();
|
|
315
|
+
try {
|
|
316
|
+
await persistThreadStateById(input.conversationId, {
|
|
317
|
+
conversation: completedState.conversation,
|
|
318
|
+
sandboxRef: reply.sandboxRef ?? sandboxRef
|
|
319
|
+
});
|
|
320
|
+
if (reply.piMessages?.length) await saveTurnCheckpoint({
|
|
321
|
+
mode: "completed",
|
|
322
|
+
conversationId: input.conversationId,
|
|
323
|
+
turnId,
|
|
324
|
+
sliceId: completionSliceId,
|
|
325
|
+
messages: reply.piMessages,
|
|
326
|
+
durationMs: reply.diagnostics.durationMs,
|
|
327
|
+
usage: reply.diagnostics.usage,
|
|
328
|
+
destination,
|
|
329
|
+
source,
|
|
330
|
+
actor: localActor,
|
|
331
|
+
surface: "internal"
|
|
332
|
+
});
|
|
333
|
+
} catch (error) {
|
|
334
|
+
const persistenceEventId = captureLocalBoundaryFailure({
|
|
335
|
+
capture: logException,
|
|
336
|
+
conversationId: input.conversationId,
|
|
337
|
+
error,
|
|
338
|
+
failureCode: "persistence_failed",
|
|
339
|
+
runId: currentRunId
|
|
340
|
+
});
|
|
341
|
+
await lifecycle.fail({
|
|
342
|
+
conversationId: input.conversationId,
|
|
343
|
+
createdAtMs: Date.now(),
|
|
344
|
+
...persistenceEventId ? { eventId: persistenceEventId } : void 0,
|
|
345
|
+
failureCode: "persistence_failed",
|
|
346
|
+
turnId
|
|
347
|
+
});
|
|
348
|
+
throw error;
|
|
349
|
+
}
|
|
350
|
+
if (reply.diagnostics.outcome === "success") await lifecycle.complete({
|
|
351
|
+
conversationId: input.conversationId,
|
|
352
|
+
createdAtMs: Date.now(),
|
|
353
|
+
outcome: assistantMessageDelivered ? "success" : "no_reply",
|
|
354
|
+
turnId
|
|
355
|
+
});
|
|
356
|
+
else await lifecycle.fail({
|
|
357
|
+
conversationId: input.conversationId,
|
|
358
|
+
createdAtMs: Date.now(),
|
|
359
|
+
...modelFailureEventId ? { eventId: modelFailureEventId } : void 0,
|
|
360
|
+
failureCode: "model_execution_failed",
|
|
361
|
+
...modelFailureReason ? { failureReason: modelFailureReason } : void 0,
|
|
362
|
+
turnId
|
|
363
|
+
});
|
|
364
|
+
if (reply.diagnostics.outcome === "success") try {
|
|
365
|
+
await scheduleSessionCompletedPluginTasks({
|
|
366
|
+
conversationId: input.conversationId,
|
|
367
|
+
sessionId: turnId
|
|
368
|
+
}, { send: async (message) => {
|
|
369
|
+
try {
|
|
370
|
+
await processPluginTask(message);
|
|
371
|
+
} catch (error) {
|
|
372
|
+
logException(error, "local.plugin.session_completion_task.failed", {
|
|
373
|
+
conversationId: input.conversationId,
|
|
374
|
+
pluginName: message.plugin,
|
|
375
|
+
taskName: message.name,
|
|
376
|
+
turnId
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
} });
|
|
380
|
+
} catch (error) {
|
|
381
|
+
logException(error, "local.plugin.session_completion_task.failed", {
|
|
382
|
+
conversationId: input.conversationId,
|
|
383
|
+
turnId
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
return {
|
|
387
|
+
conversationId: input.conversationId,
|
|
388
|
+
outcome: reply.diagnostics.outcome
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
//#endregion
|
|
392
|
+
export { runLocalAgentTurn };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Z as sandboxEgressSignalsResponseSchema } from "./agent-CMyTD4DD.js";
|
|
2
|
+
//#region src/chat/local/sandbox-egress-signals.ts
|
|
3
|
+
const SANDBOX_EGRESS_SIGNALS_PATH = "/api/internal/sandbox-egress/signals";
|
|
4
|
+
const LOCAL_DEV_SERVER_TIMEOUT_MS = 1e3;
|
|
5
|
+
function signalRequest(baseUrl, credentialToken) {
|
|
6
|
+
return {
|
|
7
|
+
headers: { "x-junior-sandbox-egress-token": credentialToken },
|
|
8
|
+
url: `${baseUrl}${SANDBOX_EGRESS_SIGNALS_PATH}`
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
async function requestLocalDevServer(request, init) {
|
|
12
|
+
try {
|
|
13
|
+
return await fetch(request.url, {
|
|
14
|
+
...init,
|
|
15
|
+
headers: request.headers,
|
|
16
|
+
signal: AbortSignal.timeout(LOCAL_DEV_SERVER_TIMEOUT_MS)
|
|
17
|
+
});
|
|
18
|
+
} catch {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Create authenticated sandbox egress signal transport to the loopback dev server. */
|
|
23
|
+
function createLocalSandboxEgressSignalTransport(baseUrl) {
|
|
24
|
+
return {
|
|
25
|
+
clear: async (credentialToken) => {
|
|
26
|
+
const response = await requestLocalDevServer(signalRequest(baseUrl, credentialToken), { method: "DELETE" });
|
|
27
|
+
if (!response) return;
|
|
28
|
+
if (!response.ok) throw new Error(`Could not clear dev-server sandbox egress signals: HTTP ${response.status}`);
|
|
29
|
+
},
|
|
30
|
+
consume: async (credentialToken) => {
|
|
31
|
+
const response = await requestLocalDevServer(signalRequest(baseUrl, credentialToken));
|
|
32
|
+
if (!response) return {};
|
|
33
|
+
if (!response.ok) throw new Error(`Could not consume dev-server sandbox egress signals: HTTP ${response.status}`);
|
|
34
|
+
const value = sandboxEgressSignalsResponseSchema.safeParse(await response.json());
|
|
35
|
+
if (!value.success) throw new Error("Dev-server sandbox egress signals were invalid");
|
|
36
|
+
const authRequired = value.data.auth_required;
|
|
37
|
+
const permissionDenied = value.data.permission_denied;
|
|
38
|
+
return {
|
|
39
|
+
...authRequired ? { authRequired } : void 0,
|
|
40
|
+
...permissionDenied ? { permissionDenied } : void 0
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { createLocalSandboxEgressSignalTransport };
|