@xopcai/xopc 0.0.252 → 0.0.253
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/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/src/inbound-processor.js +2 -2
- package/dist/extensions/telegram/src/plugin.js +3 -2
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-w3eq3YpP.js → activity-store-CeS1bgXP.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-k039rbUz.js → agent-avatar-dicebear-BdF3HhCW.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Bs34Kp0K.js +1 -0
- package/dist/gateway/static/root/assets/{agents-Bmth_bSQ.js → agents-DARlgjTm.js} +1 -1
- package/dist/gateway/static/root/assets/{api-2joIfbrH.js → api-zMPeC0yU.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-ByJ4kiD0.js → app-management-settings-panel-BaAFln8W.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BK2Jga-B.js → appearance-settings-CXvsoBlw.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-B3ky7cWU.js → apps-page-BhgvfBJT.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-DMDKtYpi.js → archive-plugin-C0o_mVQI.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-B764Ql3Z.js → attachment-load-B5Ry3tGL.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-D-sO8CZe.js → automations-page-DY5QAEQd.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-BzX4lILP.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-fxtzYRpv.js → binary-plugins-BydpEgBA.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Bcjtvckh.js → block-editor-D0CpUOMo.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-BSmnusjD.js → browser-automation-inputs-DzbTsGI6.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-DC_OQIBk.js → browser-automations-page-D7fZYjni.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-C1FojyG6.js → browser-settings-page-BBdMqxl0.js} +1 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-D_WfftDW.js +7 -0
- package/dist/gateway/static/root/assets/channels-settings-bdRLT9KA.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-BuWjIG_a.js → channels-status-swr-BGGRTkn6.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-5SevEo_I.js → chat-terminal-dock-_CP4nvlg.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-CPDjU5wU.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-DtsfalBM.js → cron-expression-g2U8Rllf.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-tDEQV5TP.js → date-picker-SmVlhtj_.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-HhNwg0Y2.js → dependency-picker-D-0gcbbM.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-acU4Li-C.js → desktop-pet-Cl3JRIu6.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-R84AR0Pe.js → desktop-pet-settings-D7kvWQ9H.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CrLlRkSN.js → extension-debug-page-DtP2tJHY.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BH5lmZXE.js → extension-page-CphZDdoT.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BscjNAd1.js → extension-settings-page-CsxVLV4-.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-9HidFZUd.js → gateway-config-swr-BW3Bx-aV.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-DxBZ05dX.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-DRCPXONr.js → gateway-startup-retry-DAq74TZe.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-K5Zhl2rx.js → heartbeat-settings-DWcKsIoZ.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-BdvLZKQZ.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-CR6Kle8H.js → image-generation-api-MPuaXDRs.js} +1 -1
- package/dist/gateway/static/root/assets/index-C7RDs6S-.js +74 -0
- package/dist/gateway/static/root/assets/index-Cu8xqZQ9.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B1QR49-7.js → keyboard-shortcuts-settings-CfhaTqgE.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-wicoV-ti.js → local-app-workbench-page-CR6asX7L.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-C74It-T8.js → local-apps-page-g01W3kEK.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-BfZGZKSs.js → locale-store-BkeaPZpn.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-xX-7S49A.js → logs-page-ZP4QTWoC.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-1kNnYL97.js → management-settings-DeGxJF_Z.js} +1 -1
- package/dist/gateway/static/root/assets/markdown-view-Ca7BRBLL.js +201 -0
- package/dist/gateway/static/root/assets/{media-plugins-B5c0AoS1.js → media-plugins-FmOhmzlD.js} +1 -1
- package/dist/gateway/static/root/assets/messages-C72stReU.js +3 -0
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-CsIZqK51.js → mobile-pairing-wizard-BXNbn05L.js} +1 -1
- package/dist/gateway/static/root/assets/note-detail-panel-EeVeF4II.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-D7bMff96.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-CqJN6Ljz.js → page-tabs-pyukZ1PJ.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DqRIGxf4.js → preview-open-alternatives-slFHoMUe.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-DE2nPE_K.js → product-open-page-CXa3FNNk.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BDF88VdN.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-DeTD6pu1.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-Bpy8XX-5.js → registry-api-CviQoUBf.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CxKrdQ6a.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Bb4b74-P.js → runtime-tools-settings-panel-O9D9o7-O.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-DoPU5j3J.js → schema-form-8FesicnL.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DUFJN-2t.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CcSYDjaH.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-Ci-9WajJ.js → settings-form-section-CBic9TFH.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-CL_2F95D.js → settings-page-Xz66_Mjg.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-C6DuwrP5.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-XUA3oKQX.js → share-preview-page--JpjwB58.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CovcdHSC.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CrHagTsE.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-sXXAZDc9.js → skills-page-fVKExKv5.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DD79Bl1I.js → skills-page.utils-Yv9u3uJp.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BEH64qBV.js → system-settings-panel-CCWjVdc2.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-I8hueJnG.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-CISSxU1c.js → theme-store-BtkaVpMm.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-DrKDhnJm.js → tunnel-api-C__W9BaN.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-CPYePL-Q.js → use-autosave-Dow9RRcq.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-CU6nxmoM.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-DKqzrCXx.js → voice-api-key-field-CvF3lEyx.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-e9xWjwBX.js → voice-config-api-BEUVAyM6.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-kTQug6bq.js → work-discovery-overlay-B9PDfReq.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-m9SKj_GT.js → workflow-run-setup-panel-kWGFkhjz.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-B4Is5E42.js +5 -0
- package/dist/gateway/static/root/index.html +10 -10
- package/dist/package.js +1 -1
- package/dist/packages/realtime-protocol/src/voice.js +6 -1
- package/dist/src/agent/agent-manager.js +20 -3
- package/dist/src/agent/embedded/execution-context.d.ts +2 -1
- package/dist/src/agent/embedded/execution-context.js +10 -4
- package/dist/src/agent/embedded/index.d.ts +1 -1
- package/dist/src/agent/embedded/index.js +2 -2
- package/dist/src/agent/embedded/run-for-session.js +4 -3
- package/dist/src/agent/embedded/run-turn.js +22 -3
- package/dist/src/agent/embedded/types.d.ts +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +6 -3
- package/dist/src/agent/service/process-direct-streaming.js +6 -3
- package/dist/src/agent/service.d.ts +2 -0
- package/dist/src/agent/service.js +21 -7
- package/dist/src/agent/tools/clarify-tool.d.ts +17 -3
- package/dist/src/agent/tools/clarify-tool.js +27 -32
- package/dist/src/agent/tools/cli-clarify.js +23 -8
- package/dist/src/agent/tools/factory.js +14 -4
- package/dist/src/automations/domain/validation.d.ts +4 -4
- package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +5 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +5 -1
- package/dist/src/gateway/clarify-runtime.d.ts +7 -5
- package/dist/src/gateway/clarify-runtime.js +8 -11
- package/dist/src/gateway/ephemeral-clarification-waiter.d.ts +17 -0
- package/dist/src/gateway/ephemeral-clarification-waiter.js +46 -0
- package/dist/src/gateway/hono/routes/agent-stream.js +44 -18
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +10 -2
- package/dist/src/gateway/hono/routes/side-chats.js +24 -4
- package/dist/src/gateway/security/gateway-scopes.js +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +25 -36
- package/dist/src/gateway/service/agent-runner.js +103 -32
- package/dist/src/gateway/service/run-gateway-agent.js +5 -2
- package/dist/src/gateway/service/session-input-coordinator.js +4 -1
- package/dist/src/gateway/service/sessions-api.js +1 -1
- package/dist/src/gateway/service.d.ts +4 -2
- package/dist/src/gateway/service.js +26 -10
- package/dist/src/gateway/side-chat/manager.d.ts +2 -1
- package/dist/src/gateway/side-chat/manager.js +5 -4
- package/dist/src/gateway/side-chat/run-service.d.ts +5 -1
- package/dist/src/gateway/side-chat/run-service.js +24 -23
- package/dist/src/gateway/side-chat/types.d.ts +3 -1
- package/dist/src/storage/sqlite/clarification-wait-repository.d.ts +41 -0
- package/dist/src/storage/sqlite/clarification-wait-repository.js +418 -0
- package/dist/src/storage/sqlite/index.d.ts +2 -1
- package/dist/src/storage/sqlite/index.js +2 -1
- package/dist/src/storage/sqlite/migrations/154_session_clarification_waits.sql +60 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/session-input-repository.d.ts +11 -6
- package/dist/src/voice/realtime/agentEngine.js +7 -2
- package/dist/src/voice/realtime/runtime.types.d.ts +5 -0
- package/package.json +3 -3
- package/skills/creative/hatch-pet/SKILL.md +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-D4J4oq8p.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-Ds5-_-9z.js +0 -6
- package/dist/gateway/static/root/assets/capabilities-settings-panel-Bs59UCut.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-CM9vNmoo.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BPZ44D-V.js +0 -2
- package/dist/gateway/static/root/assets/gateway-settings-BxLcW6ij.js +0 -1
- package/dist/gateway/static/root/assets/home-page-CZAg9RBv.js +0 -1
- package/dist/gateway/static/root/assets/index-D4Ykja-U.js +0 -72
- package/dist/gateway/static/root/assets/index-zIJ3AXgR.css +0 -2
- package/dist/gateway/static/root/assets/markdown-view-DjiwT28p.js +0 -201
- package/dist/gateway/static/root/assets/messages-DaIwVWar.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-CfWxopl4.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-CYN-LCHJ.js +0 -8
- package/dist/gateway/static/root/assets/project-detail-page-B5G3LzDq.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CuVK2mKu.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-Dnd73xWt.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-XL4LyKZe.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-0ForzDSS.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DVws6XZc.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BwDvcacF.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BJjrATqE.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-0jxMi75O.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-B6zLDfDl.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-Bcd1XqP7.js +0 -5
- package/dist/src/gateway/clarify-bridge.d.ts +0 -46
- package/dist/src/gateway/clarify-bridge.js +0 -111
|
@@ -3,6 +3,7 @@ import { init_logger } from "../../utils/logger.js";
|
|
|
3
3
|
import { parseTurnOutcome } from "../../../packages/gateway-contract/src/turn-outcome.js";
|
|
4
4
|
import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
5
5
|
import { init_providers, resolveModel } from "../../providers/index.js";
|
|
6
|
+
import { runWithEmbeddedExecutionSession } from "./execution-context.js";
|
|
6
7
|
import { resolveAgentTurnTimeoutMs } from "../orchestration/run-agent-turn-with-timeout.js";
|
|
7
8
|
import { resolvePromptCachePolicy } from "../../providers/prompt-cache-plan.js";
|
|
8
9
|
import { evaluateContextBudget } from "../memory/context-budget.js";
|
|
@@ -27,7 +28,7 @@ async function runEmbeddedTurnForSession(params) {
|
|
|
27
28
|
parentSignal: params.abortSignal
|
|
28
29
|
});
|
|
29
30
|
const finish = async (result) => {
|
|
30
|
-
if (result.stopReason === "connection_required") return result;
|
|
31
|
+
if (result.stopReason === "connection_required" || result.stopReason === "clarification_required") return result;
|
|
31
32
|
try {
|
|
32
33
|
const rows = await sessionStore.loadTranscriptRows(sessionKey);
|
|
33
34
|
const hasTurn = rows.some((source) => {
|
|
@@ -180,7 +181,7 @@ async function runEmbeddedTurnForSession(params) {
|
|
|
180
181
|
total: resolvedCandidates.length
|
|
181
182
|
}, "Agent model fallback started");
|
|
182
183
|
try {
|
|
183
|
-
const turnResult = await runXopcEmbeddedTurn({
|
|
184
|
+
const turnResult = await runWithEmbeddedExecutionSession(sessionKey, () => runXopcEmbeddedTurn({
|
|
184
185
|
sessionKey,
|
|
185
186
|
runId,
|
|
186
187
|
userMessage: userMessageForTurn,
|
|
@@ -199,7 +200,7 @@ async function runEmbeddedTurnForSession(params) {
|
|
|
199
200
|
onEvent: params.onEvent,
|
|
200
201
|
onAgentEvent: (event) => agentManager.emitRuntimeEvent(sessionKey, event),
|
|
201
202
|
resumeLastUserMessage
|
|
202
|
-
});
|
|
203
|
+
}), runId);
|
|
203
204
|
if (turnResult.ok) {
|
|
204
205
|
if (isFallbackAttempt) log.info({
|
|
205
206
|
sessionKey,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { getClarificationResumeInput, isClarificationSuspended } from "../../storage/sqlite/clarification-wait-repository.js";
|
|
3
4
|
import { getConnectionResumeInput, isConnectionSuspended } from "../../storage/sqlite/connection-wait-repository.js";
|
|
4
5
|
import { EmbeddedRunConflictError, abortEmbeddedRun, acquireEmbeddedRunLease, queueEmbeddedSteer } from "./runs.js";
|
|
5
6
|
import { lastAssistantPlainText, subscribeEmbeddedSessionEvents } from "./subscribe-session.js";
|
|
@@ -235,6 +236,7 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
235
236
|
});
|
|
236
237
|
let policyStopped = false;
|
|
237
238
|
let connectionStopped = false;
|
|
239
|
+
let clarificationStopped = false;
|
|
238
240
|
params.turnPolicy?.reset();
|
|
239
241
|
session.agent.beforeToolCall = async (context, signal) => {
|
|
240
242
|
if (connectionStopped) return {
|
|
@@ -242,6 +244,11 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
242
244
|
reason: "Waiting for the user to connect an app.",
|
|
243
245
|
terminate: true
|
|
244
246
|
};
|
|
247
|
+
if (clarificationStopped) return {
|
|
248
|
+
block: true,
|
|
249
|
+
reason: "Waiting for the user to answer.",
|
|
250
|
+
terminate: true
|
|
251
|
+
};
|
|
245
252
|
const decision = await params.turnPolicy?.beforeToolCall(context, signal);
|
|
246
253
|
if (decision?.block) {
|
|
247
254
|
policyStopped ||= decision.terminate === true;
|
|
@@ -259,6 +266,7 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
259
266
|
};
|
|
260
267
|
session.agent.afterToolCall = async (context) => {
|
|
261
268
|
connectionStopped ||= isConnectionSuspended(sessionKey, runId);
|
|
269
|
+
clarificationStopped ||= isClarificationSuspended(sessionKey, runId);
|
|
262
270
|
const scoped = context.toolCall.name === "read_file" ? await instructions.forTool(context.toolCall.name, context.args) : "";
|
|
263
271
|
const checked = await verification.afterTool(context);
|
|
264
272
|
if (scoped) checked.result.content.unshift({
|
|
@@ -273,7 +281,7 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
273
281
|
};
|
|
274
282
|
session.agent.shouldStopAfterTurn = (context) => {
|
|
275
283
|
policyStopped ||= params.turnPolicy?.shouldStopAfterTurn(context) ?? false;
|
|
276
|
-
return policyStopped || connectionStopped;
|
|
284
|
+
return policyStopped || connectionStopped || clarificationStopped;
|
|
277
285
|
};
|
|
278
286
|
unsubscribe = subscribeEmbeddedSessionEvents(session, (event) => {
|
|
279
287
|
if (event.type === "message_end" && event.message.role === "assistant") recordPromptCacheTouch(sessionKey, resolvedModel, event.message.usage);
|
|
@@ -290,11 +298,17 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
290
298
|
try {
|
|
291
299
|
await runAgentTurnWithTimeout(session.agent, async () => {
|
|
292
300
|
const connectionResume = getConnectionResumeInput(sessionKey, runId);
|
|
301
|
+
const clarificationResume = getClarificationResumeInput(sessionKey, runId);
|
|
293
302
|
if (connectionResume) await session.sendCustomMessage({
|
|
294
303
|
customType: "connection_resume",
|
|
295
304
|
content: connectionResume.content,
|
|
296
305
|
display: false
|
|
297
306
|
}, { triggerTurn: true });
|
|
307
|
+
else if (clarificationResume) await session.sendCustomMessage({
|
|
308
|
+
customType: "clarification_resume",
|
|
309
|
+
content: clarificationResume.content,
|
|
310
|
+
display: false
|
|
311
|
+
}, { triggerTurn: true });
|
|
298
312
|
else if (params.resumeLastUserMessage) await session.agent.continue();
|
|
299
313
|
else {
|
|
300
314
|
const text = userMessageToPromptText(userMessage);
|
|
@@ -302,7 +316,8 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
302
316
|
await session.prompt(text, images.length > 0 ? { images } : void 0);
|
|
303
317
|
}
|
|
304
318
|
await session.agent.waitForIdle();
|
|
305
|
-
|
|
319
|
+
clarificationStopped ||= isClarificationSuspended(sessionKey, runId);
|
|
320
|
+
if (connectionStopped || clarificationStopped) return;
|
|
306
321
|
await maybeRetryTurnAfterTransientLlmFailure(session.agent, {
|
|
307
322
|
sessionKey,
|
|
308
323
|
log,
|
|
@@ -330,6 +345,10 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
330
345
|
runId,
|
|
331
346
|
sessionKey
|
|
332
347
|
});
|
|
348
|
+
if (clarificationStopped) runner.piSm.appendCustomEntry("clarification_required", {
|
|
349
|
+
runId,
|
|
350
|
+
sessionKey
|
|
351
|
+
});
|
|
333
352
|
runner.piSm.appendCustomEntry("coding_verification", {
|
|
334
353
|
runId,
|
|
335
354
|
workspace: workspaceDir,
|
|
@@ -356,7 +375,7 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
356
375
|
});
|
|
357
376
|
return {
|
|
358
377
|
ok: true,
|
|
359
|
-
...connectionStopped ? { stopReason: "connection_required" } : {},
|
|
378
|
+
...connectionStopped ? { stopReason: "connection_required" } : clarificationStopped ? { stopReason: "clarification_required" } : {},
|
|
360
379
|
lastAssistantText: lastAssistantPlainText(session)
|
|
361
380
|
};
|
|
362
381
|
} finally {
|
|
@@ -89,7 +89,7 @@ export type RunXopcEmbeddedTurnParams = {
|
|
|
89
89
|
};
|
|
90
90
|
export type RunXopcEmbeddedTurnResult = {
|
|
91
91
|
ok: boolean;
|
|
92
|
-
stopReason?: 'connection_required';
|
|
92
|
+
stopReason?: 'connection_required' | 'clarification_required';
|
|
93
93
|
/** False for harness failures that must not trigger another model attempt. */
|
|
94
94
|
retryable?: boolean;
|
|
95
95
|
errorMessage?: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getClarificationResumeInput } from "../../storage/sqlite/clarification-wait-repository.js";
|
|
1
2
|
import { getConnectionResumeInput } from "../../storage/sqlite/connection-wait-repository.js";
|
|
2
3
|
import { resolveImageHandlingStrategy } from "../image/vision-detection.js";
|
|
3
4
|
import { hydrateUserTurnForLlm } from "../inbound/attachment-pipeline.js";
|
|
@@ -87,6 +88,8 @@ async function tryRunSlashCommand(deps, ctx, content, options) {
|
|
|
87
88
|
async function runDirectAgentTurn(deps, input) {
|
|
88
89
|
const turnId = input.runId ?? crypto.randomUUID();
|
|
89
90
|
const isConnectionResume = Boolean(getConnectionResumeInput(input.sessionKey, turnId));
|
|
91
|
+
const isClarificationResume = Boolean(getClarificationResumeInput(input.sessionKey, turnId));
|
|
92
|
+
const isResume = isConnectionResume || isClarificationResume;
|
|
90
93
|
const userPlain = extractAgentUserPlainText(input.userMessage);
|
|
91
94
|
const userContext = await deps.agentManager.prepareUserTurnContext(input.userMessage, input.sessionKey, turnId);
|
|
92
95
|
const sourceContexts = input.sourceContexts ?? [];
|
|
@@ -111,11 +114,11 @@ async function runDirectAgentTurn(deps, input) {
|
|
|
111
114
|
getConfig: () => deps.config,
|
|
112
115
|
abortSignal: input.abortSignal,
|
|
113
116
|
deadlineAtMs: input.deadlineAtMs,
|
|
114
|
-
beforeTurn:
|
|
117
|
+
beforeTurn: isResume ? void 0 : () => deps.agentManager.beginBackgroundReviewUserTurn(input.sessionKey),
|
|
115
118
|
onEvent: input.onEvent
|
|
116
119
|
});
|
|
117
|
-
if (!
|
|
118
|
-
if (!
|
|
120
|
+
if (!isResume) await deps.agentManager.afterAgentTurn(input.sessionKey, userPlain, turnId);
|
|
121
|
+
if (!isResume && result.stopReason !== "connection_required" && result.stopReason !== "clarification_required") deps.agentManager.scheduleBackgroundReviewAfterUserTurn(input.sessionKey);
|
|
119
122
|
return result;
|
|
120
123
|
}
|
|
121
124
|
//#endregion
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getClarificationResumeInput } from "../../storage/sqlite/clarification-wait-repository.js";
|
|
1
2
|
import { getConnectionResumeInput } from "../../storage/sqlite/connection-wait-repository.js";
|
|
2
3
|
import { readAgentMessageContent } from "../memory/agent-message-access.js";
|
|
3
4
|
import { abortEmbeddedRun } from "../embedded/runs.js";
|
|
@@ -126,6 +127,8 @@ function pushAssistantReceipt(queue, text, runId, metadata) {
|
|
|
126
127
|
async function* runProcessDirectStreaming(deps, input) {
|
|
127
128
|
const sessionKey = input.sessionKey ?? "agent:main:main";
|
|
128
129
|
const isConnectionResume = Boolean(input.runId && getConnectionResumeInput(sessionKey, input.runId));
|
|
130
|
+
const isClarificationResume = Boolean(input.runId && getClarificationResumeInput(sessionKey, input.runId));
|
|
131
|
+
const isInternalResume = isConnectionResume || isClarificationResume;
|
|
129
132
|
const { channel, chatId } = await deps.resolveSessionEndpoint(sessionKey);
|
|
130
133
|
const context = deps.initDirectStreamingSession(sessionKey, channel, chatId, input.origin);
|
|
131
134
|
const queue = new AsyncQueue({
|
|
@@ -276,7 +279,7 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
276
279
|
if (sourceContext && !sourceContexts.some((context) => context.kind === sourceContext.kind && context.sourceId === sourceContext.sourceId)) sourceContexts.push(sourceContext);
|
|
277
280
|
}
|
|
278
281
|
}
|
|
279
|
-
if (channel === "webchat" && !
|
|
282
|
+
if (channel === "webchat" && !isInternalResume) {
|
|
280
283
|
pushVisible({
|
|
281
284
|
type: "user_message",
|
|
282
285
|
timestamp: userMessage.timestamp ?? Date.now(),
|
|
@@ -287,7 +290,7 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
287
290
|
if (textForAgent.trim()) deps.enqueueProvisionalSessionTitle?.(sessionKey, textForAgent);
|
|
288
291
|
}
|
|
289
292
|
const pendingUserMessage = sourceContexts.length > 0 ? injectSourceContextsIntoUserMessage(userMessage, sourceContexts) : userMessage;
|
|
290
|
-
if (!
|
|
293
|
+
if (!isInternalResume) setPendingTranscriptUserMessage(sessionKey, pendingUserMessage);
|
|
291
294
|
try {
|
|
292
295
|
const result = await deps.agentManager.withSkillCapabilities(sessionKey, skillTurn.activatedCapabilityNames, () => runDirectAgentTurn({
|
|
293
296
|
sessionStore: deps.sessionStore,
|
|
@@ -314,7 +317,7 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
314
317
|
content: formatStreamError(result.errorMessage)
|
|
315
318
|
});
|
|
316
319
|
} finally {
|
|
317
|
-
if (!
|
|
320
|
+
if (!isInternalResume) clearPendingTranscriptUserMessage(sessionKey, pendingUserMessage);
|
|
318
321
|
}
|
|
319
322
|
} catch (err) {
|
|
320
323
|
if (err instanceof AsyncQueueOverflowError) {
|
|
@@ -121,12 +121,14 @@ export declare class AgentService {
|
|
|
121
121
|
refreshUserProfileContext(): void;
|
|
122
122
|
getMemoryManager(): import("./memory/manager.js").MemoryManager;
|
|
123
123
|
getModelForSession(sessionKey: string): string;
|
|
124
|
+
getThinkingLevelForSession(sessionKey: string): ThinkingLevel;
|
|
124
125
|
/** Run a full tool-capable turn against a caller-owned, non-persistent transcript. */
|
|
125
126
|
runEphemeralTurn(params: {
|
|
126
127
|
executionSessionKey: string;
|
|
127
128
|
parentSessionKey: string;
|
|
128
129
|
runId: string;
|
|
129
130
|
content: string;
|
|
131
|
+
attachments?: InboundAttachmentInput[];
|
|
130
132
|
modelRef: string;
|
|
131
133
|
thinkingLevel?: ThinkingLevel;
|
|
132
134
|
transcriptRuntime: EmbeddedTranscriptRuntime;
|
|
@@ -19,6 +19,7 @@ import "../user-model/index.js";
|
|
|
19
19
|
import { resolveAgentTurnTimeoutMs } from "./orchestration/run-agent-turn-with-timeout.js";
|
|
20
20
|
import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
|
|
21
21
|
import { persistInboundAttachments } from "../channels/attachments/inbound-persist.js";
|
|
22
|
+
import { buildTranscriptUserMessage, hydrateUserTurnForLlm } from "./inbound/attachment-pipeline.js";
|
|
22
23
|
import { runXopcEmbeddedTurn } from "./embedded/run-turn.js";
|
|
23
24
|
import { resolveResponseLanguageForSession } from "./prompt/response-language.js";
|
|
24
25
|
import { normalizeSkillInstallTarget } from "./skills/install-target.js";
|
|
@@ -577,19 +578,31 @@ var AgentService = class {
|
|
|
577
578
|
getModelForSession(sessionKey) {
|
|
578
579
|
return this.modelManager.getModelForSession(sessionKey);
|
|
579
580
|
}
|
|
581
|
+
getThinkingLevelForSession(sessionKey) {
|
|
582
|
+
return this.agentManager.getOrCreateAgent(sessionKey).state.thinkingLevel ?? "medium";
|
|
583
|
+
}
|
|
580
584
|
/** Run a full tool-capable turn against a caller-owned, non-persistent transcript. */
|
|
581
585
|
async runEphemeralTurn(params) {
|
|
582
586
|
const agent = this.agentManager.getOrCreateAgent(params.parentSessionKey);
|
|
583
587
|
const workspaceDir = this.agentManager.getResolvedWorkspaceForSession(params.parentSessionKey);
|
|
584
588
|
const model = resolveModel(params.modelRef);
|
|
589
|
+
const prepared = await this.prepareInboundAttachments(params.executionSessionKey, params.attachments);
|
|
590
|
+
const userMessage = await buildTranscriptUserMessage({
|
|
591
|
+
text: params.content,
|
|
592
|
+
prepared,
|
|
593
|
+
sessionKey: params.parentSessionKey,
|
|
594
|
+
modelRef: params.modelRef,
|
|
595
|
+
config: this.effectiveAppConfig(),
|
|
596
|
+
agentManager: this.agentManager
|
|
597
|
+
});
|
|
598
|
+
const llmTurn = await hydrateUserTurnForLlm({
|
|
599
|
+
message: userMessage,
|
|
600
|
+
modelRef: params.modelRef
|
|
601
|
+
});
|
|
585
602
|
return runWithEmbeddedExecutionSession(params.executionSessionKey, () => runXopcEmbeddedTurn({
|
|
586
603
|
sessionKey: params.executionSessionKey,
|
|
587
604
|
runId: params.runId,
|
|
588
|
-
userMessage
|
|
589
|
-
role: "user",
|
|
590
|
-
content: params.content,
|
|
591
|
-
timestamp: Date.now()
|
|
592
|
-
},
|
|
605
|
+
userMessage,
|
|
593
606
|
model,
|
|
594
607
|
modelRef: params.modelRef,
|
|
595
608
|
tools: agent.state.tools,
|
|
@@ -600,8 +613,9 @@ var AgentService = class {
|
|
|
600
613
|
timeoutMs: resolveAgentTurnTimeoutMs(this.effectiveAppConfig(), params.parentSessionKey),
|
|
601
614
|
turnPolicy: this.agentManager.createAgentTurnPolicy(params.parentSessionKey),
|
|
602
615
|
abortSignal: params.abortSignal,
|
|
603
|
-
onEvent: params.onEvent
|
|
604
|
-
|
|
616
|
+
onEvent: params.onEvent,
|
|
617
|
+
images: llmTurn.images
|
|
618
|
+
}), params.runId);
|
|
605
619
|
}
|
|
606
620
|
async switchModelForSession(sessionKey, modelId) {
|
|
607
621
|
if (!await this.modelManager.switchModelForSession(sessionKey, modelId)) return false;
|
|
@@ -3,11 +3,25 @@ export type ClarifyRequestPayload = {
|
|
|
3
3
|
kind?: 'approval';
|
|
4
4
|
question: string;
|
|
5
5
|
choices?: string[];
|
|
6
|
-
|
|
6
|
+
suggestedAnswer?: string;
|
|
7
|
+
/** Stable hash of the exact operation guarded by an approval. */
|
|
8
|
+
approvalKey?: string;
|
|
7
9
|
};
|
|
8
|
-
export type
|
|
10
|
+
export type ClarifyRequestResult = {
|
|
11
|
+
status: 'answered';
|
|
12
|
+
answer: string;
|
|
13
|
+
} | {
|
|
14
|
+
status: 'waiting';
|
|
15
|
+
waitId: string;
|
|
16
|
+
expiresAt?: number;
|
|
17
|
+
};
|
|
18
|
+
export type GatewayClarifyRequestFn = (context: {
|
|
19
|
+
sessionKey: string;
|
|
20
|
+
runId: string;
|
|
21
|
+
toolCallId: string;
|
|
22
|
+
}, request: ClarifyRequestPayload) => Promise<ClarifyRequestResult>;
|
|
9
23
|
export interface ClarifyToolDeps {
|
|
10
24
|
/** Resolve a per-turn callback; returns null when clarification is unavailable. */
|
|
11
|
-
resolveAskUser: () => ((request: ClarifyRequestPayload) => Promise<
|
|
25
|
+
resolveAskUser: (toolCallId: string) => ((request: ClarifyRequestPayload) => Promise<ClarifyRequestResult>) | null;
|
|
12
26
|
}
|
|
13
27
|
export declare function createClarifyTool(deps: ClarifyToolDeps): AgentTool;
|
|
@@ -7,7 +7,7 @@ const ClarifySchema = Type.Object({
|
|
|
7
7
|
minItems: 2,
|
|
8
8
|
maxItems: 10
|
|
9
9
|
})),
|
|
10
|
-
|
|
10
|
+
suggestedAnswer: Type.Optional(Type.String({ description: "Optional recommendation shown to the user. It is never selected automatically." }))
|
|
11
11
|
});
|
|
12
12
|
function waitForAbort(signal) {
|
|
13
13
|
return new Promise((_, reject) => {
|
|
@@ -23,40 +23,42 @@ function createClarifyTool(deps) {
|
|
|
23
23
|
return {
|
|
24
24
|
name: "clarify",
|
|
25
25
|
label: "❓ Clarify",
|
|
26
|
-
description: "Ask the user a clarifying question and
|
|
26
|
+
description: "Ask the user a clarifying question and pause the objective until they respond.\n\nUse this when you need more information to proceed correctly, rather than guessing.\n\nWHEN TO USE:\n- Ambiguous instructions with multiple valid interpretations\n- Missing critical information (which file, which approach, etc.)\n- Confirming destructive or irreversible actions\n\nWHEN NOT TO USE:\n- When you can reasonably infer the answer from context\n- For trivial decisions that do not affect the task\n- When the user explicitly said \"just do it\" or \"your choice\"\n\nTIPS:\n- Provide choices when there are clear options (faster for the user)\n- Keep questions short and specific\n- Include a suggested answer when one option is clearly more likely",
|
|
27
27
|
parameters: ClarifySchema,
|
|
28
|
-
async execute(
|
|
28
|
+
async execute(toolCallId, params, signal) {
|
|
29
29
|
const p = params;
|
|
30
|
-
const askUser = deps.resolveAskUser();
|
|
31
|
-
if (!askUser) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
};
|
|
39
|
-
return {
|
|
40
|
-
content: [{
|
|
41
|
-
type: "text",
|
|
42
|
-
text: "Clarification is not available in this environment (no active webchat run). Provide a default or proceed with the best assumption."
|
|
43
|
-
}],
|
|
44
|
-
details: { answer: "" }
|
|
45
|
-
};
|
|
46
|
-
}
|
|
30
|
+
const askUser = deps.resolveAskUser(toolCallId);
|
|
31
|
+
if (!askUser) return {
|
|
32
|
+
content: [{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: "Clarification is not available in this environment. Proceed with the best safe assumption or explain what is missing."
|
|
35
|
+
}],
|
|
36
|
+
details: { answer: "" }
|
|
37
|
+
};
|
|
47
38
|
const payload = {
|
|
48
39
|
question: p.question,
|
|
49
40
|
choices: p.choices,
|
|
50
|
-
|
|
41
|
+
suggestedAnswer: p.suggestedAnswer
|
|
51
42
|
};
|
|
52
43
|
try {
|
|
53
|
-
const
|
|
44
|
+
const result = await Promise.race([askUser(payload), waitForAbort(signal)]);
|
|
45
|
+
if (result.status === "waiting") return {
|
|
46
|
+
content: [{
|
|
47
|
+
type: "text",
|
|
48
|
+
text: "Waiting for the user to answer this clarification. End the current run now."
|
|
49
|
+
}],
|
|
50
|
+
details: {
|
|
51
|
+
answer: "",
|
|
52
|
+
waitId: result.waitId,
|
|
53
|
+
status: result.status
|
|
54
|
+
}
|
|
55
|
+
};
|
|
54
56
|
return {
|
|
55
57
|
content: [{
|
|
56
58
|
type: "text",
|
|
57
|
-
text: `User answered: ${answer}`
|
|
59
|
+
text: `User answered: ${result.answer}`
|
|
58
60
|
}],
|
|
59
|
-
details: { answer }
|
|
61
|
+
details: { answer: result.answer }
|
|
60
62
|
};
|
|
61
63
|
} catch (error) {
|
|
62
64
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -65,14 +67,7 @@ function createClarifyTool(deps) {
|
|
|
65
67
|
type: "text",
|
|
66
68
|
text: "Clarification cancelled (run aborted)."
|
|
67
69
|
}],
|
|
68
|
-
details: { answer:
|
|
69
|
-
};
|
|
70
|
-
if (p.default !== void 0 && p.default !== "" && message.toLowerCase().includes("timeout")) return {
|
|
71
|
-
content: [{
|
|
72
|
-
type: "text",
|
|
73
|
-
text: `User did not respond in time. Using default: ${p.default}`
|
|
74
|
-
}],
|
|
75
|
-
details: { answer: p.default }
|
|
70
|
+
details: { answer: "" }
|
|
76
71
|
};
|
|
77
72
|
return {
|
|
78
73
|
content: [{
|
|
@@ -5,7 +5,7 @@ import * as readline from "node:readline/promises";
|
|
|
5
5
|
* stdin/stdout prompts for `clarify` when running the CLI agent (no gateway).
|
|
6
6
|
*/
|
|
7
7
|
function createCliReadlineClarifyRequestFn() {
|
|
8
|
-
return async (
|
|
8
|
+
return async (_context, req) => {
|
|
9
9
|
const rl = readline.createInterface({
|
|
10
10
|
input: stdin,
|
|
11
11
|
output: stdout
|
|
@@ -15,19 +15,34 @@ function createCliReadlineClarifyRequestFn() {
|
|
|
15
15
|
if (choices && choices.length >= 2) {
|
|
16
16
|
stdout.write(`\n${req.question}\n`);
|
|
17
17
|
choices.forEach((c, i) => stdout.write(` ${i + 1}) ${c}\n`));
|
|
18
|
-
if (req.
|
|
18
|
+
if (req.suggestedAnswer) stdout.write(` (recommended: ${req.suggestedAnswer})\n`);
|
|
19
19
|
const raw = (await rl.question("Choice (number or exact text): ")).trim();
|
|
20
20
|
const n = parseInt(raw, 10);
|
|
21
|
-
if (!Number.isNaN(n) && n >= 1 && n <= choices.length) return
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
if (!Number.isNaN(n) && n >= 1 && n <= choices.length) return {
|
|
22
|
+
status: "answered",
|
|
23
|
+
answer: choices[n - 1]
|
|
24
|
+
};
|
|
25
|
+
if (raw) return {
|
|
26
|
+
status: "answered",
|
|
27
|
+
answer: raw
|
|
28
|
+
};
|
|
29
|
+
if (req.suggestedAnswer) return {
|
|
30
|
+
status: "answered",
|
|
31
|
+
answer: req.suggestedAnswer
|
|
32
|
+
};
|
|
24
33
|
throw new Error("No answer provided");
|
|
25
34
|
}
|
|
26
35
|
stdout.write(`\n${req.question}\n`);
|
|
27
|
-
if (req.
|
|
36
|
+
if (req.suggestedAnswer) stdout.write(`(Press Enter for recommendation: ${req.suggestedAnswer})\n`);
|
|
28
37
|
const raw = (await rl.question("> ")).trim();
|
|
29
|
-
if (raw) return
|
|
30
|
-
|
|
38
|
+
if (raw) return {
|
|
39
|
+
status: "answered",
|
|
40
|
+
answer: raw
|
|
41
|
+
};
|
|
42
|
+
if (req.suggestedAnswer) return {
|
|
43
|
+
status: "answered",
|
|
44
|
+
answer: req.suggestedAnswer
|
|
45
|
+
};
|
|
31
46
|
throw new Error("No answer provided");
|
|
32
47
|
} finally {
|
|
33
48
|
rl.close();
|
|
@@ -7,7 +7,7 @@ import { getSessionTaskPlan, setSessionTaskPlan } from "../../storage/sqlite/ses
|
|
|
7
7
|
import "../../storage/sqlite/index.js";
|
|
8
8
|
import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
|
|
9
9
|
import { resolveEffectiveAgentConfigForSession } from "../../config/agent-profile.js";
|
|
10
|
-
import { getEmbeddedExecutionSession } from "../embedded/execution-context.js";
|
|
10
|
+
import { getEmbeddedExecutionRunId, getEmbeddedExecutionSession } from "../embedded/execution-context.js";
|
|
11
11
|
import { wrapToolsWithProtection } from "./executor.js";
|
|
12
12
|
import { EXTERNAL_TOOL_NAMES } from "../external-tools/gateway-tools.js";
|
|
13
13
|
import { buildRuntimeEnvironment } from "../../runtime-tools/environment.js";
|
|
@@ -215,15 +215,25 @@ var AgentToolsFactory = class AgentToolsFactory {
|
|
|
215
215
|
createSessionStatusTool(),
|
|
216
216
|
createMemoryMaintenanceTool({ getConfig: () => this.deps.getConfig?.() }),
|
|
217
217
|
createToolManualTool(),
|
|
218
|
-
createClarifyTool({ resolveAskUser: () => {
|
|
218
|
+
createClarifyTool({ resolveAskUser: (toolCallId) => {
|
|
219
219
|
const req = this.deps.gatewayClarify?.requestClarification;
|
|
220
220
|
if (!req) return null;
|
|
221
221
|
const executionSession = getEmbeddedExecutionSession();
|
|
222
|
-
|
|
222
|
+
const runId = getEmbeddedExecutionRunId();
|
|
223
|
+
if (executionSession && runId) return (request) => req({
|
|
224
|
+
sessionKey: executionSession,
|
|
225
|
+
runId,
|
|
226
|
+
toolCallId
|
|
227
|
+
}, request);
|
|
223
228
|
const ctx = this.deps.getCurrentContext();
|
|
224
229
|
if (!ctx?.sessionKey) return null;
|
|
225
230
|
if (!CLARIFY_SUPPORTED_CHANNELS.has(ctx.channel)) return null;
|
|
226
|
-
|
|
231
|
+
if (!runId) return null;
|
|
232
|
+
return (request) => req({
|
|
233
|
+
sessionKey: ctx.sessionKey,
|
|
234
|
+
runId,
|
|
235
|
+
toolCallId
|
|
236
|
+
}, request);
|
|
227
237
|
} }),
|
|
228
238
|
createTodoTool({
|
|
229
239
|
getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,
|
|
@@ -117,9 +117,9 @@ export declare const AutomationActionSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
|
|
|
117
117
|
type: z.ZodLiteral<"add_wait">;
|
|
118
118
|
wait: z.ZodObject<{
|
|
119
119
|
kind: z.ZodEnum<{
|
|
120
|
+
approval: "approval";
|
|
120
121
|
dependency: "dependency";
|
|
121
122
|
user_input: "user_input";
|
|
122
|
-
approval: "approval";
|
|
123
123
|
external_event: "external_event";
|
|
124
124
|
scheduled_time: "scheduled_time";
|
|
125
125
|
retry_backoff: "retry_backoff";
|
|
@@ -294,9 +294,9 @@ export declare const AutomationSchema: z.ZodObject<{
|
|
|
294
294
|
type: z.ZodLiteral<"add_wait">;
|
|
295
295
|
wait: z.ZodObject<{
|
|
296
296
|
kind: z.ZodEnum<{
|
|
297
|
+
approval: "approval";
|
|
297
298
|
dependency: "dependency";
|
|
298
299
|
user_input: "user_input";
|
|
299
|
-
approval: "approval";
|
|
300
300
|
external_event: "external_event";
|
|
301
301
|
scheduled_time: "scheduled_time";
|
|
302
302
|
retry_backoff: "retry_backoff";
|
|
@@ -456,9 +456,9 @@ export declare const CreateAutomationSchema: z.ZodObject<{
|
|
|
456
456
|
type: z.ZodLiteral<"add_wait">;
|
|
457
457
|
wait: z.ZodObject<{
|
|
458
458
|
kind: z.ZodEnum<{
|
|
459
|
+
approval: "approval";
|
|
459
460
|
dependency: "dependency";
|
|
460
461
|
user_input: "user_input";
|
|
461
|
-
approval: "approval";
|
|
462
462
|
external_event: "external_event";
|
|
463
463
|
scheduled_time: "scheduled_time";
|
|
464
464
|
retry_backoff: "retry_backoff";
|
|
@@ -645,9 +645,9 @@ export declare const UpdateAutomationSchema: z.ZodObject<{
|
|
|
645
645
|
type: z.ZodLiteral<"add_wait">;
|
|
646
646
|
wait: z.ZodObject<{
|
|
647
647
|
kind: z.ZodEnum<{
|
|
648
|
+
approval: "approval";
|
|
648
649
|
dependency: "dependency";
|
|
649
650
|
user_input: "user_input";
|
|
650
|
-
approval: "approval";
|
|
651
651
|
external_event: "external_event";
|
|
652
652
|
scheduled_time: "scheduled_time";
|
|
653
653
|
retry_backoff: "retry_backoff";
|
|
@@ -79,7 +79,7 @@ export declare function buildAutomationDraftResponse(draft: GeneratedAutomationD
|
|
|
79
79
|
} | {
|
|
80
80
|
type: "add_wait";
|
|
81
81
|
wait: {
|
|
82
|
-
kind: "
|
|
82
|
+
kind: "approval" | "dependency" | "user_input" | "external_event" | "scheduled_time" | "retry_backoff" | "paused";
|
|
83
83
|
reason: string;
|
|
84
84
|
condition: Record<string, unknown>;
|
|
85
85
|
resumeAt?: number;
|
|
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
|
|
|
52
52
|
id: "database-schema",
|
|
53
53
|
label: "Database schema",
|
|
54
54
|
status: "pass",
|
|
55
|
-
message: `SQLite schema v${status.dbVersion} (current release
|
|
55
|
+
message: `SQLite schema v${status.dbVersion} (current release v154).`,
|
|
56
56
|
hints: []
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -95,9 +95,13 @@ var ChatStreamMapper = class {
|
|
|
95
95
|
})];
|
|
96
96
|
case "clarify_request": return [this.make("clarify_request", {
|
|
97
97
|
requestId: String(event.requestId ?? ""),
|
|
98
|
+
kind: event.kind === "approval" ? "approval" : "input",
|
|
98
99
|
question: String(event.question ?? ""),
|
|
99
100
|
choices: Array.isArray(event.choices) ? event.choices.filter((x) => typeof x === "string") : void 0,
|
|
100
|
-
|
|
101
|
+
suggestedAnswer: typeof event.suggestedAnswer === "string" ? event.suggestedAnswer : void 0,
|
|
102
|
+
version: typeof event.version === "number" ? event.version : 1,
|
|
103
|
+
createdAt: typeof event.createdAt === "number" ? event.createdAt : Date.now(),
|
|
104
|
+
expiresAt: typeof event.expiresAt === "number" ? event.expiresAt : void 0,
|
|
101
105
|
petFeedback: createPetFeedback("clarify")
|
|
102
106
|
})];
|
|
103
107
|
case "turn_outcome": {
|
|
@@ -200,9 +200,13 @@ export type TtsAudioEvent = ChatStreamEnvelope<'tts_audio', {
|
|
|
200
200
|
}>;
|
|
201
201
|
export type ClarifyRequestEvent = ChatStreamEnvelope<'clarify_request', {
|
|
202
202
|
requestId: string;
|
|
203
|
+
kind: 'input' | 'approval';
|
|
203
204
|
question: string;
|
|
204
205
|
choices?: string[];
|
|
205
|
-
|
|
206
|
+
suggestedAnswer?: string;
|
|
207
|
+
version: number;
|
|
208
|
+
createdAt: number;
|
|
209
|
+
expiresAt?: number;
|
|
206
210
|
petFeedback: PetFeedback;
|
|
207
211
|
}>;
|
|
208
212
|
export type RunEndEvent = ChatStreamEnvelope<'run_end', {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export declare function
|
|
1
|
+
export type ClarificationChannelRuntime = {
|
|
2
|
+
answerChoice(requestId: string, choiceIndex: number, idempotencyKey: string): boolean;
|
|
3
|
+
answerText(sessionKey: string, text: string, idempotencyKey: string): boolean;
|
|
4
|
+
};
|
|
5
|
+
export declare function registerClarificationChannelRuntime(next: ClarificationChannelRuntime | null): void;
|
|
6
|
+
export declare function answerClarificationChoiceFromChannel(requestId: string, choiceIndex: number, idempotencyKey: string): boolean;
|
|
7
|
+
export declare function answerClarificationTextFromChannel(sessionKey: string, text: string, idempotencyKey: string): boolean;
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
//#region src/gateway/clarify-runtime.ts
|
|
2
|
-
let
|
|
3
|
-
function
|
|
4
|
-
|
|
2
|
+
let runtime = null;
|
|
3
|
+
function registerClarificationChannelRuntime(next) {
|
|
4
|
+
runtime = next;
|
|
5
5
|
}
|
|
6
|
-
function
|
|
7
|
-
return
|
|
6
|
+
function answerClarificationChoiceFromChannel(requestId, choiceIndex, idempotencyKey) {
|
|
7
|
+
return runtime?.answerChoice(requestId, choiceIndex, idempotencyKey) ?? false;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
return
|
|
11
|
-
}
|
|
12
|
-
function tryConsumeTelegramClarifyFreeText(sessionKey, text) {
|
|
13
|
-
return bridgeRef?.tryConsumeFreeTextReply(sessionKey, text) ?? false;
|
|
9
|
+
function answerClarificationTextFromChannel(sessionKey, text, idempotencyKey) {
|
|
10
|
+
return runtime?.answerText(sessionKey, text, idempotencyKey) ?? false;
|
|
14
11
|
}
|
|
15
12
|
//#endregion
|
|
16
|
-
export {
|
|
13
|
+
export { answerClarificationChoiceFromChannel, answerClarificationTextFromChannel, registerClarificationChannelRuntime };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ClarifyRequestPayload } from '../agent/tools/clarify-tool.js';
|
|
2
|
+
export type ClarificationStreamEvent = {
|
|
3
|
+
type: string;
|
|
4
|
+
} & Record<string, unknown>;
|
|
5
|
+
/** In-memory waiter exclusively for caller-owned ephemeral runs such as side chat. */
|
|
6
|
+
export declare class EphemeralClarificationWaiter {
|
|
7
|
+
private readonly pending;
|
|
8
|
+
start(input: {
|
|
9
|
+
runId: string;
|
|
10
|
+
publish: (event: ClarificationStreamEvent) => void;
|
|
11
|
+
request: ClarifyRequestPayload;
|
|
12
|
+
beforeResponse?: () => boolean;
|
|
13
|
+
}): Promise<string>;
|
|
14
|
+
answer(requestId: string, answer: string): boolean;
|
|
15
|
+
cancelForRun(runId: string): void;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
}
|