@symerian/symi 3.1.0 → 3.1.1
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/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +4 -4
- package/dist/bundled/session-memory/handler.js +4 -4
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{chrome-O5GtGEaR.js → chrome-CCtr79A5.js} +4 -4
- package/dist/{chrome-B7_foWil.js → chrome-CLdjGAF1.js} +4 -4
- package/dist/{command-registry-DmjX-MJb.js → command-registry-DtivbkBg.js} +4 -4
- package/dist/{completion-cli-CKczmer5.js → completion-cli-DAtKJGz_.js} +1 -1
- package/dist/{completion-cli-DezSeZQA.js → completion-cli-M9mpw_DS.js} +2 -2
- package/dist/control-ui/js/app.js +34 -2
- package/dist/{deliver-BMg6XjUA.js → deliver-D0zCpBS2.js} +4 -4
- package/dist/{deliver-Cxzii_el.js → deliver-aqjVfua8.js} +4 -4
- package/dist/{doctor-completion-AGw1egU_.js → doctor-completion-BlxU7_DJ.js} +1 -1
- package/dist/{doctor-completion-BCVASe0n.js → doctor-completion-DLx2ecZ2.js} +1 -1
- package/dist/entry.js +1 -1
- package/dist/extensionAPI.js +4 -4
- package/dist/{gateway-cli-CvFiUm5D.js → gateway-cli-BDVuQ5k9.js} +6 -354
- package/dist/{gateway-cli-BZXfKM1n.js → gateway-cli-CjY_Ct2M.js} +6 -354
- package/dist/{glass-ui-ws-CHyGj7GA.js → glass-ui-ws-Bs0VbFCC.js} +1 -1
- package/dist/{glass-ui-ws-BSTHY5PU.js → glass-ui-ws-CLyPSA_9.js} +1 -1
- package/dist/index.js +1 -1
- package/dist/llm-slug-generator.js +4 -4
- package/dist/{manager-BWi2hK4Y.js → manager-3gF-gaOU.js} +1 -1
- package/dist/{manager-BoTf2TBM.js → manager-Do_LVG9R.js} +1 -1
- package/dist/{onboard-BzRDv60Y.js → onboard-lFeJdiGp.js} +1 -1
- package/dist/{onboard-CHrTg-R0.js → onboard-zwQ2t4TE.js} +1 -1
- package/dist/{onboarding-ClbxBHpB.js → onboarding-C0kL3Y5v.js} +1 -1
- package/dist/{onboarding-BGwkx8NB.js → onboarding-CaHVfCVn.js} +1 -1
- package/dist/{onboarding.finalize-D6zND3C7.js → onboarding.finalize-DwXxdw74.js} +3 -3
- package/dist/{onboarding.finalize-BnIBZwze.js → onboarding.finalize-vT6fRWsB.js} +4 -4
- package/dist/{pi-embedded-L-sMlPsa.js → pi-embedded-JU-n_Ppj.js} +10 -10
- package/dist/plugin-sdk/gateway/server-chat.d.ts +47 -0
- package/dist/{program-B8S2KFzC.js → program-C1bTgU2q.js} +2 -2
- package/dist/{program-context-DCb3cVEC.js → program-context-BHvgRRy_.js} +6 -6
- package/dist/{prompt-select-styled-BJ3NsTmX.js → prompt-select-styled--PI8fuuB.js} +1 -1
- package/dist/{prompt-select-styled-ZdXAuRQQ.js → prompt-select-styled-DawD9uin.js} +1 -1
- package/dist/{pw-ai-B9riepO_.js → pw-ai-BlFwd1fC.js} +1 -1
- package/dist/{pw-ai-CYE0188Y.js → pw-ai-Cq1WlDax.js} +1 -1
- package/dist/{register.maintenance-CX4sIokB.js → register.maintenance-D0NfR0wv.js} +5 -5
- package/dist/{register.maintenance-BBxWlFhs.js → register.maintenance-fFzETZM-.js} +4 -4
- package/dist/{register.onboard-UzFm__iV.js → register.onboard-C0eFmAVL.js} +2 -2
- package/dist/{register.onboard-Be8PMN1Z.js → register.onboard-C7aJLoQc.js} +2 -2
- package/dist/{register.setup-w0_6rARS.js → register.setup-CRhnePOD.js} +2 -2
- package/dist/{register.setup-Dq7WlLOL.js → register.setup-XpvVOl8-.js} +2 -2
- package/dist/{register.subclis-Cb1ErrVQ.js → register.subclis-BFq9K0q9.js} +3 -3
- package/dist/{run-main-DmC4wWlp.js → run-main-JPtR4nYb.js} +3 -3
- package/dist/{server-methods-C97G9dYe.js → server-methods-Dj3PCErz.js} +360 -4
- package/dist/{server-methods-DFt60s1H.js → server-methods-RegE5bVx.js} +360 -4
- package/dist/{synthesis-DA7kfAUJ.js → synthesis-CNYpM3bL.js} +4 -4
- package/dist/{synthesis-CPZoVKlB.js → synthesis-CP97tsyU.js} +4 -4
- package/dist/{unified-runner-BdN9pHa8.js → unified-runner-Bjd_KpAr.js} +10 -10
- package/dist/{update-cli-Bg3c9ORr.js → update-cli-DPsa1UFx.js} +5 -5
- package/dist/{update-cli-DZtbV25O.js → update-cli-bgziGI6r.js} +4 -4
- package/package.json +1 -1
|
@@ -12,14 +12,15 @@ import { f as GATEWAY_CLIENT_CAPS, g as hasGatewayClientCap, i as isGatewayMessa
|
|
|
12
12
|
import { c as writeJsonAtomic, o as createAsyncLock, s as readJsonFile } from "./pairing-token-DZAnUH5B.js";
|
|
13
13
|
import { s as pickPrimaryLanIPv4 } from "./net-DZ5Ayk-W.js";
|
|
14
14
|
import { i as normalizeInputProvenance } from "./input-provenance-D0lNkCf6.js";
|
|
15
|
-
import { $n as setTtsEnabled, A as waitForEmbeddedPiRunEnd, Bt as scheduleGatewaySigusr1Restart, C as buildGlassUiProfile, Cn as prepareAgentRun, E as runUnifiedTurn, Fn as isAbortTrigger, G as ensureOutboundSessionEntry, Gn as getTtsProvider, In as stopSubagentsForRequester, Jn as resolveTtsApiKey, K as resolveOutboundSessionRoute, Kn as isTtsEnabled, Mn as normalizeGroupActivation, Mt as persistBrowserProxyFiles, O as abortEmbeddedPiRun, Pn as formatZonedTimestamp, Qn as resolveTtsProviderOrder, R as buildAgentTurnParams, Sn as resolveAgentTimeoutMs, Tn as isSystemEventContextChanged, Ut as loadProviderUsageSummary, V as listTasksInWorkdir, Vn as resolveUserTimezone, Xn as resolveTtsConfig, Y as resolveOutboundTarget, Yn as resolveTtsAutoMode, Z as normalizePollInput, Zn as resolveTtsPrefsPath, a as listSubagentRunsForRequester, br as registerAgentRunContext, c as clearSessionQueues, cn as applyModelOverrideToSessionEntry, dt as writeRestartSentinel, er as setTtsProvider, i as listDescendantRunsForRequester, jn as BARE_SESSION_RESET_PROMPT, jt as applyBrowserProxyPaths, ln as applyVerboseOverride, m as loadSymiPlugins, mt as normalizeCronJobPatch, nn as normalizeSendPolicy, nr as OPENAI_TTS_MODELS, ot as formatDoctorNonInteractiveHint, pt as normalizeCronJobCreate, qn as isTtsProviderConfigured, rn as resolveSendPolicy, rr as OPENAI_TTS_VOICES, tr as textToSpeech, un as parseVerboseOverride, wn as enqueueSystemEvent, x as createReplyDispatcher, y as getChannelActivity, yr as onAgentEvent, z as prepareReplyTurn } from "./subagent-registry-DNcSxvl3.js";
|
|
15
|
+
import { $n as setTtsEnabled, A as waitForEmbeddedPiRunEnd, Bt as scheduleGatewaySigusr1Restart, C as buildGlassUiProfile, Cn as prepareAgentRun, E as runUnifiedTurn, F as classifyOutboundMessage, Fn as isAbortTrigger, G as ensureOutboundSessionEntry, Gn as getTtsProvider, In as stopSubagentsForRequester, Jn as resolveTtsApiKey, K as resolveOutboundSessionRoute, Kn as isTtsEnabled, Mn as normalizeGroupActivation, Mt as persistBrowserProxyFiles, O as abortEmbeddedPiRun, Pn as formatZonedTimestamp, Qn as resolveTtsProviderOrder, R as buildAgentTurnParams, Sn as resolveAgentTimeoutMs, Tn as isSystemEventContextChanged, Ut as loadProviderUsageSummary, V as listTasksInWorkdir, Vn as resolveUserTimezone, Xn as resolveTtsConfig, Y as resolveOutboundTarget, Yn as resolveTtsAutoMode, Z as normalizePollInput, Zn as resolveTtsPrefsPath, a as listSubagentRunsForRequester, br as registerAgentRunContext, c as clearSessionQueues, cn as applyModelOverrideToSessionEntry, dr as DEFAULT_HEARTBEAT_ACK_MAX_CHARS, dt as writeRestartSentinel, er as setTtsProvider, i as listDescendantRunsForRequester, jn as BARE_SESSION_RESET_PROMPT, jt as applyBrowserProxyPaths, ln as applyVerboseOverride, m as loadSymiPlugins, mt as normalizeCronJobPatch, n as countActiveRunsForSession, nn as normalizeSendPolicy, nr as OPENAI_TTS_MODELS, ot as formatDoctorNonInteractiveHint, pt as normalizeCronJobCreate, qn as isTtsProviderConfigured, rn as resolveSendPolicy, rr as OPENAI_TTS_VOICES, tr as textToSpeech, un as parseVerboseOverride, vr as getAgentRunContext, wn as enqueueSystemEvent, x as createReplyDispatcher, y as getChannelActivity, yr as onAgentEvent, z as prepareReplyTurn } from "./subagent-registry-DNcSxvl3.js";
|
|
16
16
|
import { F as resolveMainSessionKey, I as resolveMainSessionKeyFromConfig, J as normalizeSessionDeliveryFields, N as resolveAgentMainSessionKey, P as resolveExplicitAgentSessionKey, R as snapshotSessionOrigin, S as stripEnvelopeFromMessages, _ as capArrayByJsonBytes, d as updateSessionStore, g as archiveSessionTranscripts, h as archiveFileOnDisk, o as loadSessionStore, t as extractDeliveryInfo, v as readSessionMessages, x as resolveSessionTranscriptCandidates, y as readSessionPreviewItemsFromTranscript } from "./sessions-CrQE7gq3.js";
|
|
17
|
+
import { i as isSilentReplyText, n as SILENT_REPLY_TOKEN } from "./tokens-DN4W-XdV.js";
|
|
17
18
|
import { n as listChannelPlugins, r as normalizeChannelId, t as getChannelPlugin } from "./plugins-CYQsm6Gy.js";
|
|
18
19
|
import { n as createBrowserRouteDispatcher } from "./with-timeout-DNvX8V3I.js";
|
|
19
20
|
import { h as getGlobalHookRunner, o as normalizeReplyPayloadsForDelivery, t as deliverOutboundPayloads } from "./deliver-SxI9drJl.js";
|
|
20
21
|
import { t as movePathToTrash } from "./trash-BEXyYJdG.js";
|
|
21
22
|
import { c as resolveStorePath, n as resolveSessionFilePath, r as resolveSessionFilePathOptions, s as resolveSessionTranscriptsDirForAgent } from "./paths-BDcioH8W.js";
|
|
22
|
-
import { a as normalizeElevatedLevel, c as normalizeUsageDisplay, d as supportsXHighThinking, n as formatXHighModelHint, o as normalizeReasoningLevel, s as normalizeThinkLevel, t as formatThinkingLevels } from "./thinking-C72VJ9y9.js";
|
|
23
|
+
import { a as normalizeElevatedLevel, c as normalizeUsageDisplay, d as supportsXHighThinking, l as normalizeVerboseLevel, n as formatXHighModelHint, o as normalizeReasoningLevel, s as normalizeThinkLevel, t as formatThinkingLevels } from "./thinking-C72VJ9y9.js";
|
|
23
24
|
import { a as resolveAgentIdentity, t as createReplyPrefixOptions } from "./reply-prefix-B9wo4eUI.js";
|
|
24
25
|
import { r as getMemorySearchManager } from "./memory-cli-B7Ls3Iv1.js";
|
|
25
26
|
import { _ as requestNodePairing, g as renamePairedNode, h as rejectNodePairing, m as listNodePairing, o as getRemoteSkillEligibility, p as approveNodePairing, y as verifyNodeToken } from "./skill-commands-BFRS0Miy.js";
|
|
@@ -36,7 +37,7 @@ import { t as buildChannelAccountSnapshot } from "./status-CBkcR9vW.js";
|
|
|
36
37
|
import { w as resolveAssistantAvatarUrl } from "./onboard-helpers-CilvN36L.js";
|
|
37
38
|
import { o as isNodeCommandAllowed, s as resolveNodeCommandAllowlist } from "./audit-CHQE7ltJ.js";
|
|
38
39
|
import { r as getStatusSummary } from "./status-er3ceIYD.js";
|
|
39
|
-
import { c as setHeartbeatsEnabled, d as getLastHeartbeatEvent, p as abortHeartbeatRunForSession } from "./health-vDQ4nRJB.js";
|
|
40
|
+
import { c as setHeartbeatsEnabled, d as getLastHeartbeatEvent, p as abortHeartbeatRunForSession, u as resolveHeartbeatVisibility } from "./health-vDQ4nRJB.js";
|
|
40
41
|
import { r as createOutboundSendDeps } from "./outbound-send-deps-KBVliaIJ.js";
|
|
41
42
|
import { m as normalizeUpdateChannel } from "./update-check-CZiE16y_.js";
|
|
42
43
|
import { a as sendApnsAlert, c as parseMessageWithAttachments, i as resolveApnsAuthConfigFromEnv, l as formatForLog, n as normalizeApnsEnvironment, o as sendApnsBackgroundWake, s as normalizeRpcAttachmentsToChatAttachments, t as loadApnsRegistration } from "./push-apns-CZG-Sec1.js";
|
|
@@ -403,6 +404,355 @@ function startGatewayConfigReloader(opts) {
|
|
|
403
404
|
} };
|
|
404
405
|
}
|
|
405
406
|
|
|
407
|
+
//#endregion
|
|
408
|
+
//#region src/gateway/server-chat.ts
|
|
409
|
+
function resolveHeartbeatAckMaxChars() {
|
|
410
|
+
try {
|
|
411
|
+
const cfg = loadConfig();
|
|
412
|
+
return Math.max(0, cfg.agents?.defaults?.heartbeat?.ackMaxChars ?? DEFAULT_HEARTBEAT_ACK_MAX_CHARS);
|
|
413
|
+
} catch {
|
|
414
|
+
return DEFAULT_HEARTBEAT_ACK_MAX_CHARS;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
function resolveHeartbeatContext(runId, sourceRunId) {
|
|
418
|
+
const primary = getAgentRunContext(runId);
|
|
419
|
+
if (primary?.isHeartbeat) return primary;
|
|
420
|
+
if (sourceRunId && sourceRunId !== runId) {
|
|
421
|
+
const source = getAgentRunContext(sourceRunId);
|
|
422
|
+
if (source?.isHeartbeat) return source;
|
|
423
|
+
}
|
|
424
|
+
return primary;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Check if heartbeat ACK/noise should be hidden from interactive chat surfaces.
|
|
428
|
+
*/
|
|
429
|
+
function shouldHideHeartbeatChatOutput(runId, sourceRunId) {
|
|
430
|
+
if (!resolveHeartbeatContext(runId, sourceRunId)?.isHeartbeat) return false;
|
|
431
|
+
try {
|
|
432
|
+
return !resolveHeartbeatVisibility({
|
|
433
|
+
cfg: loadConfig(),
|
|
434
|
+
channel: "webchat"
|
|
435
|
+
}).showOk;
|
|
436
|
+
} catch {
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
function createChatRunRegistry() {
|
|
441
|
+
const chatRunSessions = /* @__PURE__ */ new Map();
|
|
442
|
+
const add = (sessionId, entry) => {
|
|
443
|
+
const queue = chatRunSessions.get(sessionId);
|
|
444
|
+
if (queue) queue.push(entry);
|
|
445
|
+
else chatRunSessions.set(sessionId, [entry]);
|
|
446
|
+
};
|
|
447
|
+
const peek = (sessionId) => chatRunSessions.get(sessionId)?.[0];
|
|
448
|
+
const shift = (sessionId) => {
|
|
449
|
+
const queue = chatRunSessions.get(sessionId);
|
|
450
|
+
if (!queue || queue.length === 0) return;
|
|
451
|
+
const entry = queue.shift();
|
|
452
|
+
if (!queue.length) chatRunSessions.delete(sessionId);
|
|
453
|
+
return entry;
|
|
454
|
+
};
|
|
455
|
+
const remove = (sessionId, clientRunId, sessionKey) => {
|
|
456
|
+
const queue = chatRunSessions.get(sessionId);
|
|
457
|
+
if (!queue || queue.length === 0) return;
|
|
458
|
+
const idx = queue.findIndex((entry) => entry.clientRunId === clientRunId && (sessionKey ? entry.sessionKey === sessionKey : true));
|
|
459
|
+
if (idx < 0) return;
|
|
460
|
+
const [entry] = queue.splice(idx, 1);
|
|
461
|
+
if (!queue.length) chatRunSessions.delete(sessionId);
|
|
462
|
+
return entry;
|
|
463
|
+
};
|
|
464
|
+
const clear = () => {
|
|
465
|
+
chatRunSessions.clear();
|
|
466
|
+
};
|
|
467
|
+
return {
|
|
468
|
+
add,
|
|
469
|
+
peek,
|
|
470
|
+
shift,
|
|
471
|
+
remove,
|
|
472
|
+
clear
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
function createChatRunState() {
|
|
476
|
+
const registry = createChatRunRegistry();
|
|
477
|
+
const buffers = /* @__PURE__ */ new Map();
|
|
478
|
+
const deltaSentAt = /* @__PURE__ */ new Map();
|
|
479
|
+
const pendingDeltaText = /* @__PURE__ */ new Map();
|
|
480
|
+
const abortedRuns = /* @__PURE__ */ new Map();
|
|
481
|
+
const clear = () => {
|
|
482
|
+
registry.clear();
|
|
483
|
+
buffers.clear();
|
|
484
|
+
deltaSentAt.clear();
|
|
485
|
+
pendingDeltaText.clear();
|
|
486
|
+
abortedRuns.clear();
|
|
487
|
+
};
|
|
488
|
+
return {
|
|
489
|
+
registry,
|
|
490
|
+
buffers,
|
|
491
|
+
deltaSentAt,
|
|
492
|
+
pendingDeltaText,
|
|
493
|
+
abortedRuns,
|
|
494
|
+
clear
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
const TOOL_EVENT_RECIPIENT_TTL_MS = 600 * 1e3;
|
|
498
|
+
const TOOL_EVENT_RECIPIENT_FINAL_GRACE_MS = 30 * 1e3;
|
|
499
|
+
function createToolEventRecipientRegistry() {
|
|
500
|
+
const recipients = /* @__PURE__ */ new Map();
|
|
501
|
+
const prune = () => {
|
|
502
|
+
if (recipients.size === 0) return;
|
|
503
|
+
const now = Date.now();
|
|
504
|
+
for (const [runId, entry] of recipients) if (now >= (entry.finalizedAt ? entry.finalizedAt + TOOL_EVENT_RECIPIENT_FINAL_GRACE_MS : entry.updatedAt + TOOL_EVENT_RECIPIENT_TTL_MS)) recipients.delete(runId);
|
|
505
|
+
};
|
|
506
|
+
const add = (runId, connId) => {
|
|
507
|
+
if (!runId || !connId) return;
|
|
508
|
+
const now = Date.now();
|
|
509
|
+
const existing = recipients.get(runId);
|
|
510
|
+
if (existing) {
|
|
511
|
+
existing.connIds.add(connId);
|
|
512
|
+
existing.updatedAt = now;
|
|
513
|
+
} else recipients.set(runId, {
|
|
514
|
+
connIds: new Set([connId]),
|
|
515
|
+
updatedAt: now
|
|
516
|
+
});
|
|
517
|
+
prune();
|
|
518
|
+
};
|
|
519
|
+
const get = (runId) => {
|
|
520
|
+
const entry = recipients.get(runId);
|
|
521
|
+
if (!entry) return;
|
|
522
|
+
entry.updatedAt = Date.now();
|
|
523
|
+
prune();
|
|
524
|
+
return entry.connIds;
|
|
525
|
+
};
|
|
526
|
+
const markFinal = (runId) => {
|
|
527
|
+
const entry = recipients.get(runId);
|
|
528
|
+
if (!entry) return;
|
|
529
|
+
entry.finalizedAt = Date.now();
|
|
530
|
+
prune();
|
|
531
|
+
};
|
|
532
|
+
return {
|
|
533
|
+
add,
|
|
534
|
+
get,
|
|
535
|
+
markFinal
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
function createAgentEventHandler({ broadcast, broadcastToConnIds, nodeSendToSession, agentRunSeq, chatRunState, resolveSessionKeyForRun, clearAgentRunContext, toolEventRecipients }) {
|
|
539
|
+
const emitChatDelta = (sessionKey, clientRunId, sourceRunId, seq, text) => {
|
|
540
|
+
if (isSilentReplyText(text, SILENT_REPLY_TOKEN)) return;
|
|
541
|
+
const prev = chatRunState.buffers.get(clientRunId) ?? "";
|
|
542
|
+
chatRunState.buffers.set(clientRunId, prev + text);
|
|
543
|
+
if (shouldHideHeartbeatChatOutput(clientRunId, sourceRunId)) return;
|
|
544
|
+
const now = Date.now();
|
|
545
|
+
if (now - (chatRunState.deltaSentAt.get(clientRunId) ?? 0) < 150) {
|
|
546
|
+
chatRunState.pendingDeltaText.set(clientRunId, (chatRunState.pendingDeltaText.get(clientRunId) ?? "") + text);
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
const buffered = chatRunState.pendingDeltaText.get(clientRunId) ?? "";
|
|
550
|
+
chatRunState.pendingDeltaText.delete(clientRunId);
|
|
551
|
+
const fullText = buffered + text;
|
|
552
|
+
chatRunState.deltaSentAt.set(clientRunId, now);
|
|
553
|
+
const payload = {
|
|
554
|
+
runId: clientRunId,
|
|
555
|
+
sessionKey,
|
|
556
|
+
seq,
|
|
557
|
+
state: "delta",
|
|
558
|
+
...resolveHeartbeatContext(clientRunId, sourceRunId)?.isHeartbeat ? { isHeartbeat: true } : {},
|
|
559
|
+
message: {
|
|
560
|
+
role: "assistant",
|
|
561
|
+
content: [{
|
|
562
|
+
type: "text",
|
|
563
|
+
text: fullText
|
|
564
|
+
}],
|
|
565
|
+
timestamp: now
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
broadcast("chat", payload, { dropIfSlow: true });
|
|
569
|
+
nodeSendToSession(sessionKey, "chat", payload);
|
|
570
|
+
};
|
|
571
|
+
const emitChatFinal = (sessionKey, clientRunId, sourceRunId, seq, jobState, error) => {
|
|
572
|
+
const remainingDelta = chatRunState.pendingDeltaText.get(clientRunId);
|
|
573
|
+
if (remainingDelta && !shouldHideHeartbeatChatOutput(clientRunId, sourceRunId)) {
|
|
574
|
+
const flushPayload = {
|
|
575
|
+
runId: clientRunId,
|
|
576
|
+
sessionKey,
|
|
577
|
+
seq,
|
|
578
|
+
state: "delta",
|
|
579
|
+
...resolveHeartbeatContext(clientRunId, sourceRunId)?.isHeartbeat ? { isHeartbeat: true } : {},
|
|
580
|
+
message: {
|
|
581
|
+
role: "assistant",
|
|
582
|
+
content: [{
|
|
583
|
+
type: "text",
|
|
584
|
+
text: remainingDelta
|
|
585
|
+
}],
|
|
586
|
+
timestamp: Date.now()
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
broadcast("chat", flushPayload);
|
|
590
|
+
nodeSendToSession(sessionKey, "chat", flushPayload);
|
|
591
|
+
}
|
|
592
|
+
chatRunState.pendingDeltaText.delete(clientRunId);
|
|
593
|
+
const bufferedText = chatRunState.buffers.get(clientRunId)?.trim() ?? "";
|
|
594
|
+
const heartbeatCtx = resolveHeartbeatContext(clientRunId, sourceRunId);
|
|
595
|
+
const isHeartbeatRun = !!heartbeatCtx?.isHeartbeat;
|
|
596
|
+
const heartbeatHidden = isHeartbeatRun && shouldHideHeartbeatChatOutput(clientRunId, sourceRunId);
|
|
597
|
+
const filterResult = isHeartbeatRun && !heartbeatHidden ? {
|
|
598
|
+
action: "deliver",
|
|
599
|
+
output: bufferedText,
|
|
600
|
+
reason: "deliver"
|
|
601
|
+
} : classifyOutboundMessage(bufferedText, {
|
|
602
|
+
isHeartbeat: heartbeatHidden,
|
|
603
|
+
heartbeatAckMaxChars: resolveHeartbeatAckMaxChars()
|
|
604
|
+
});
|
|
605
|
+
const text = filterResult.output.trim();
|
|
606
|
+
const shouldSuppressSilent = filterResult.action === "drop";
|
|
607
|
+
chatRunState.buffers.delete(clientRunId);
|
|
608
|
+
chatRunState.deltaSentAt.delete(clientRunId);
|
|
609
|
+
if (jobState === "done") {
|
|
610
|
+
const payload = {
|
|
611
|
+
runId: clientRunId,
|
|
612
|
+
sessionKey,
|
|
613
|
+
seq,
|
|
614
|
+
state: "final",
|
|
615
|
+
activeSubagentCount: countActiveRunsForSession(sessionKey),
|
|
616
|
+
...heartbeatCtx?.isHeartbeat ? { isHeartbeat: true } : {},
|
|
617
|
+
message: text && !shouldSuppressSilent ? {
|
|
618
|
+
role: "assistant",
|
|
619
|
+
content: [{
|
|
620
|
+
type: "text",
|
|
621
|
+
text
|
|
622
|
+
}],
|
|
623
|
+
timestamp: Date.now()
|
|
624
|
+
} : void 0
|
|
625
|
+
};
|
|
626
|
+
broadcast("chat", payload);
|
|
627
|
+
nodeSendToSession(sessionKey, "chat", payload);
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
const payload = {
|
|
631
|
+
runId: clientRunId,
|
|
632
|
+
sessionKey,
|
|
633
|
+
seq,
|
|
634
|
+
state: "error",
|
|
635
|
+
errorMessage: error ? formatForLog(error) : void 0,
|
|
636
|
+
...heartbeatCtx?.isHeartbeat ? { isHeartbeat: true } : {}
|
|
637
|
+
};
|
|
638
|
+
broadcast("chat", payload);
|
|
639
|
+
nodeSendToSession(sessionKey, "chat", payload);
|
|
640
|
+
};
|
|
641
|
+
const resolveToolVerboseLevel = (runId, sessionKey) => {
|
|
642
|
+
const runVerbose = normalizeVerboseLevel(getAgentRunContext(runId)?.verboseLevel);
|
|
643
|
+
if (runVerbose) return runVerbose;
|
|
644
|
+
if (!sessionKey) return "off";
|
|
645
|
+
try {
|
|
646
|
+
const { cfg, entry } = loadSessionEntry(sessionKey);
|
|
647
|
+
const sessionVerbose = normalizeVerboseLevel(entry?.verboseLevel);
|
|
648
|
+
if (sessionVerbose) return sessionVerbose;
|
|
649
|
+
return normalizeVerboseLevel(cfg.agents?.defaults?.verboseDefault) ?? "off";
|
|
650
|
+
} catch {
|
|
651
|
+
return "off";
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
return (evt) => {
|
|
655
|
+
const chatLink = chatRunState.registry.peek(evt.runId);
|
|
656
|
+
const eventSessionKey = typeof evt.sessionKey === "string" && evt.sessionKey.trim() ? evt.sessionKey : void 0;
|
|
657
|
+
const sessionKey = chatLink?.sessionKey ?? eventSessionKey ?? resolveSessionKeyForRun(evt.runId);
|
|
658
|
+
if (sessionKey?.startsWith("temp:")) return;
|
|
659
|
+
const clientRunId = chatLink?.clientRunId ?? evt.runId;
|
|
660
|
+
const eventRunId = chatLink?.clientRunId ?? evt.runId;
|
|
661
|
+
const eventForClients = chatLink ? {
|
|
662
|
+
...evt,
|
|
663
|
+
runId: eventRunId
|
|
664
|
+
} : evt;
|
|
665
|
+
const isAborted = chatRunState.abortedRuns.has(clientRunId) || chatRunState.abortedRuns.has(evt.runId);
|
|
666
|
+
const heartbeatAgentCtx = resolveHeartbeatContext(clientRunId, evt.runId);
|
|
667
|
+
const agentPayload = {
|
|
668
|
+
...eventForClients,
|
|
669
|
+
...sessionKey ? { sessionKey } : {},
|
|
670
|
+
...heartbeatAgentCtx?.isHeartbeat ? { isHeartbeat: true } : {}
|
|
671
|
+
};
|
|
672
|
+
const last = agentRunSeq.get(evt.runId) ?? 0;
|
|
673
|
+
const isToolEvent = evt.stream === "tool";
|
|
674
|
+
const toolVerbose = isToolEvent ? resolveToolVerboseLevel(evt.runId, sessionKey) : "off";
|
|
675
|
+
const toolPayload = isToolEvent && toolVerbose !== "full" ? (() => {
|
|
676
|
+
const data = evt.data ? { ...evt.data } : {};
|
|
677
|
+
delete data.result;
|
|
678
|
+
delete data.partialResult;
|
|
679
|
+
return sessionKey ? {
|
|
680
|
+
...eventForClients,
|
|
681
|
+
sessionKey,
|
|
682
|
+
data
|
|
683
|
+
} : {
|
|
684
|
+
...eventForClients,
|
|
685
|
+
data
|
|
686
|
+
};
|
|
687
|
+
})() : agentPayload;
|
|
688
|
+
if (evt.seq !== last + 1) broadcast("agent", {
|
|
689
|
+
runId: eventRunId,
|
|
690
|
+
stream: "error",
|
|
691
|
+
ts: Date.now(),
|
|
692
|
+
sessionKey,
|
|
693
|
+
...heartbeatAgentCtx?.isHeartbeat ? { isHeartbeat: true } : {},
|
|
694
|
+
data: {
|
|
695
|
+
reason: "seq gap",
|
|
696
|
+
expected: last + 1,
|
|
697
|
+
received: evt.seq
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
agentRunSeq.set(evt.runId, evt.seq);
|
|
701
|
+
if (isToolEvent) {
|
|
702
|
+
const recipients = toolEventRecipients.get(evt.runId);
|
|
703
|
+
if (recipients && recipients.size > 0) broadcastToConnIds("agent", toolPayload, recipients);
|
|
704
|
+
} else broadcast("agent", agentPayload);
|
|
705
|
+
const lifecyclePhase = evt.stream === "lifecycle" && typeof evt.data?.phase === "string" ? evt.data.phase : null;
|
|
706
|
+
if (lifecyclePhase === "start" && sessionKey && !isAborted) {
|
|
707
|
+
if (!resolveHeartbeatContext(clientRunId, evt.runId)?.isHeartbeat) broadcast("chat", {
|
|
708
|
+
runId: clientRunId,
|
|
709
|
+
sessionKey,
|
|
710
|
+
seq: evt.seq,
|
|
711
|
+
state: "thinking"
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
if (lifecyclePhase && sessionKey && sessionKey.includes(":subagent:")) {
|
|
715
|
+
if (lifecyclePhase === "start") broadcast("subagent", {
|
|
716
|
+
phase: "started",
|
|
717
|
+
sessionKey,
|
|
718
|
+
runId: clientRunId
|
|
719
|
+
});
|
|
720
|
+
else if (lifecyclePhase === "end" || lifecyclePhase === "error") broadcast("subagent", {
|
|
721
|
+
phase: "completed",
|
|
722
|
+
sessionKey,
|
|
723
|
+
runId: clientRunId
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
if (sessionKey) {
|
|
727
|
+
if (!isToolEvent || toolVerbose !== "off") nodeSendToSession(sessionKey, "agent", isToolEvent ? toolPayload : agentPayload);
|
|
728
|
+
if (!isAborted && evt.stream === "assistant" && typeof evt.data?.text === "string") {
|
|
729
|
+
const deltaText = typeof evt.data?.delta === "string" && evt.data.delta ? evt.data.delta : evt.data.text;
|
|
730
|
+
emitChatDelta(sessionKey, clientRunId, evt.runId, evt.seq, deltaText);
|
|
731
|
+
} else if (!isAborted && (lifecyclePhase === "end" || lifecyclePhase === "error")) if (chatLink) {
|
|
732
|
+
const finished = chatRunState.registry.shift(evt.runId);
|
|
733
|
+
if (!finished) {
|
|
734
|
+
clearAgentRunContext(evt.runId);
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
emitChatFinal(finished.sessionKey, finished.clientRunId, evt.runId, evt.seq, lifecyclePhase === "error" ? "error" : "done", evt.data?.error);
|
|
738
|
+
} else emitChatFinal(sessionKey, eventRunId, evt.runId, evt.seq, lifecyclePhase === "error" ? "error" : "done", evt.data?.error);
|
|
739
|
+
else if (isAborted && (lifecyclePhase === "end" || lifecyclePhase === "error")) {
|
|
740
|
+
chatRunState.abortedRuns.delete(clientRunId);
|
|
741
|
+
chatRunState.abortedRuns.delete(evt.runId);
|
|
742
|
+
chatRunState.buffers.delete(clientRunId);
|
|
743
|
+
chatRunState.deltaSentAt.delete(clientRunId);
|
|
744
|
+
if (chatLink) chatRunState.registry.remove(evt.runId, clientRunId, sessionKey);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
if (lifecyclePhase === "end" || lifecyclePhase === "error") {
|
|
748
|
+
toolEventRecipients.markFinal(evt.runId);
|
|
749
|
+
clearAgentRunContext(evt.runId);
|
|
750
|
+
agentRunSeq.delete(evt.runId);
|
|
751
|
+
agentRunSeq.delete(clientRunId);
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
|
|
406
756
|
//#endregion
|
|
407
757
|
//#region src/cron/run-log.ts
|
|
408
758
|
function resolveCronRunLogPath(params) {
|
|
@@ -496,12 +846,14 @@ function resolveChatRunExpiresAtMs(params) {
|
|
|
496
846
|
}
|
|
497
847
|
function broadcastChatAborted(ops, params) {
|
|
498
848
|
const { runId, sessionKey, stopReason, partialText } = params;
|
|
849
|
+
const heartbeatCtx = resolveHeartbeatContext(runId);
|
|
499
850
|
const payload = {
|
|
500
851
|
runId,
|
|
501
852
|
sessionKey,
|
|
502
853
|
seq: (ops.agentRunSeq.get(runId) ?? 0) + 1,
|
|
503
854
|
state: "aborted",
|
|
504
855
|
stopReason,
|
|
856
|
+
...heartbeatCtx?.isHeartbeat ? { isHeartbeat: true } : {},
|
|
505
857
|
message: partialText ? {
|
|
506
858
|
role: "assistant",
|
|
507
859
|
content: [{
|
|
@@ -4110,11 +4462,13 @@ function nextChatSeq(context, runId) {
|
|
|
4110
4462
|
}
|
|
4111
4463
|
function broadcastChatFinal(params) {
|
|
4112
4464
|
const seq = nextChatSeq({ agentRunSeq: params.context.agentRunSeq }, params.runId);
|
|
4465
|
+
const heartbeatCtx = resolveHeartbeatContext(params.runId);
|
|
4113
4466
|
const payload = {
|
|
4114
4467
|
runId: params.runId,
|
|
4115
4468
|
sessionKey: params.sessionKey,
|
|
4116
4469
|
seq,
|
|
4117
4470
|
state: "final",
|
|
4471
|
+
...heartbeatCtx?.isHeartbeat ? { isHeartbeat: true } : {},
|
|
4118
4472
|
message: params.message
|
|
4119
4473
|
};
|
|
4120
4474
|
params.context.broadcast("chat", payload);
|
|
@@ -4123,11 +4477,13 @@ function broadcastChatFinal(params) {
|
|
|
4123
4477
|
}
|
|
4124
4478
|
function broadcastChatError(params) {
|
|
4125
4479
|
const seq = nextChatSeq({ agentRunSeq: params.context.agentRunSeq }, params.runId);
|
|
4480
|
+
const heartbeatCtx = resolveHeartbeatContext(params.runId);
|
|
4126
4481
|
const payload = {
|
|
4127
4482
|
runId: params.runId,
|
|
4128
4483
|
sessionKey: params.sessionKey,
|
|
4129
4484
|
seq,
|
|
4130
4485
|
state: "error",
|
|
4486
|
+
...heartbeatCtx?.isHeartbeat ? { isHeartbeat: true } : {},
|
|
4131
4487
|
errorMessage: params.errorMessage
|
|
4132
4488
|
};
|
|
4133
4489
|
params.context.broadcast("chat", payload);
|
|
@@ -9601,4 +9957,4 @@ async function handleGatewayRequest(opts) {
|
|
|
9601
9957
|
}
|
|
9602
9958
|
|
|
9603
9959
|
//#endregion
|
|
9604
|
-
export {
|
|
9960
|
+
export { createAgentEventHandler as C, startGatewayConfigReloader as E, resolveCronRunLogPath as S, createToolEventRecipientRegistry as T, MAX_PAYLOAD_BYTES as _, loadFavoritesSet as a, abortChatRunById as b, resolveAssistantIdentity as c, formatError as d, loadVoiceWakeConfig as f, MAX_BUFFERED_BYTES as g, HEALTH_REFRESH_INTERVAL_MS as h, safeParseJson as i, listSystemPresence as l, DEDUPE_TTL_MS as m, handleGatewayRequest as n, reconcileFavorites as o, DEDUPE_MAX as p, broadcastPresenceSnapshot as r, DEFAULT_ASSISTANT_IDENTITY as s, coreGatewayHandlers as t, upsertPresence as u, TICK_INTERVAL_MS as v, createChatRunState as w, appendCronRunLog as x, getHandshakeTimeoutMs as y };
|