@xopcai/xopc 0.0.157 → 0.0.159
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/dashscope/src/image-generation-provider.js +1 -1
- package/dist/extensions/fal/src/image-generation-provider.js +1 -1
- package/dist/extensions/google/src/image-generation-provider.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{action-boundary-settings-panel-zQ_w0sPl.js → action-boundary-settings-panel-CaRK2vIy.js} +1 -1
- package/dist/gateway/static/root/assets/{activity-store-CddlQHam.js → activity-store-C-57rvkX.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DOfTopIk.js → agent-avatar-dicebear-BeVf03hx.js} +1 -1
- package/dist/gateway/static/root/assets/agents-P05C4A-3.js +2 -0
- package/dist/gateway/static/root/assets/{api-NUlcaaV9.js → api-BjcBIV2O.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-J0-z_uc1.js → app-management-settings-panel-BG2ulMYw.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CMaQOx2C.js → appearance-settings-0Kjenr2T.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DANGrBpN.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BVwE70GV.js → archive-plugin-ChiNnH1e.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-aj5U56K9.js → attachment-load-pbBlQR-g.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-CKz8rxAb.js → automation-suggestion-card-CTZDOyDy.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-BXfGL_cm.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-Ie6owbEw.js → binary-plugins-BeZGzpGF.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BaDrd5GJ.js → block-editor-BnDmhN5Z.js} +3 -3
- package/dist/gateway/static/root/assets/browser-settings-page-534luV0B.js +8 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-BjO4YD-O.js → capability-presets-api-Ii36j_7v.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-bwezWQpF.js → capability-presets-settings-panel-Cl3dw4yh.js} +2 -2
- package/dist/gateway/static/root/assets/{channel-recipient-api-BisDU_DH.js → channel-recipient-api-CFqrSi5K.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-M91zFJVi.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-vooEF4lG.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-DGjjzBIH.js → connector-logo-CiLxuZ8S.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-CV5UulW6.js +2 -0
- package/dist/gateway/static/root/assets/{desktop-pet-CoQ4Edck.js → desktop-pet-Cil2eSpW.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings--sjUYeNX.js → desktop-pet-settings-DwsC6l5F.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-CpmfFDx3.js → directory-picker-path-field-CC2VL5Mc.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-D7rRROE7.js → dreaming-settings-KY7ZfVsy.js} +3 -3
- package/dist/gateway/static/root/assets/{extension-debug-page-BzqW3ssG.js → extension-debug-page-C8KBeucs.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CKDbBzVR.js → extension-page-CV-5Kcyk.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DjNMSdRz.js → extension-settings-page-DvUtDrAu.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-CUEAZEld.js → gateway-config-api-DXfVeJLc.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-BpJ0v56l.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CbMPgpHX.js → gateway-startup-retry-cxQ94qMm.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-lMHD-2CX.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-yPmF-G7b.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-C-Vq8VR9.js → goals-config-api-P8VhLqYF.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-BHTCKobG.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-DVrTDWYS.js → goals-settings-DHXyaH_O.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-Dv8qA4E7.js → heartbeat-settings-CNckP_Dv.js} +1 -1
- package/dist/gateway/static/root/assets/index-BgZhEOkN.css +1 -0
- package/dist/gateway/static/root/assets/{index-DHRxn7Sy.js → index-BuqGh2SW.js} +65 -65
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DEKtMZbg.js → keyboard-shortcuts-settings-jXmv1RVX.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-zpp_wciE.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-DQT2lZk7.js → local-apps-page-Cs5LKjtc.js} +1 -1
- package/dist/gateway/static/root/assets/locale-store-C_M71MK9.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-B4CRYqYR.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-Cp6NxQJr.js → markdown-split-BFqeSNte.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Dv1cQK2J.js → media-plugins-Cc8379gq.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-Bwu1tG3T.js → messages-BuT0SR1R.js} +4 -4
- package/dist/gateway/static/root/assets/models-hub-panel-1hdoAoB_.js +2 -0
- package/dist/gateway/static/root/assets/{notes-page-CePZ2we1.js → notes-page-DlGU4ipo.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-DQEAZTA5.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-C1jBfKTZ.js → page-tabs-kFOswGlG.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Cl9anbg0.js → preview-open-alternatives-CvjuvABg.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-Bp9bC7A6.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-RNorFXTw.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-BqRTcM_6.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-CWu_o1ta.js → save-bar-controls-DwrD7ODx.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-DuZbqL7X.js → schedule-field-Ba4WzTmE.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-Bixut-2d.js → schema-form-DvydL8eF.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-B2EfW1cm.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CklL85T4.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-C_7lCtCp.js → settings-collapsible-section-LaQqGGej.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-D0DPTbO0.js → settings-form-section-DruI__qO.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-tN-9u8dj.js → settings-loading-skeleton-UvA-eDhF.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-C2L9g3kd.js → settings-page-5oCGSebm.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-CBUOPmx_.js → settings-page-layout-DG-XMIPu.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-D3my1HgB.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BiSh0nLu.js → share-preview-page-FLVeTrRt.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DVxgjrsP.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-Bcu58ZaF.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-CDd-84FE.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-h7uqbQ-n.js → system-settings-panel-CeK93xVi.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-DjYRaF0J.js → theme-store-C8ohIHhw.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-BkqBD32C.js → typed-models-lib-D1Lr2gG0.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-DiWtF12K.js → use-channel-catalog-BWzou5ar.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-1OyJnTyR.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-C4770AsA.js → voice-api-key-field-B2ncRwHS.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-BZlY4PZL.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-DPXMrneY.js +1 -0
- package/dist/gateway/static/root/assets/work-page-CTERoqyv.js +1 -0
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-Bynqe4kV.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-CLgsnqFQ.js +11 -0
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +14 -0
- package/dist/src/agent/image/generation/openai-compatible-image-provider.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +10 -3
- package/dist/src/agent/tools/send-media.js +20 -70
- package/dist/src/agent/tools/tool-media.d.ts +9 -0
- package/dist/src/agent/tools/tool-media.js +58 -0
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/connectors/catalog.js +2 -3
- package/dist/src/connectors/composio-catalog.d.ts +11 -1
- package/dist/src/connectors/composio-catalog.js +37 -7
- package/dist/src/connectors/composio.js +2 -1
- package/dist/src/gateway/agent-run-relay.d.ts +2 -0
- package/dist/src/gateway/agent-run-relay.js +114 -14
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/chat-stream/mapper.d.ts +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +27 -42
- package/dist/src/gateway/chat-stream/thinking-delta-coalescer.d.ts +7 -0
- package/dist/src/gateway/chat-stream/thinking-delta-coalescer.js +103 -0
- package/dist/src/gateway/hono/routes/connectors.js +10 -22
- package/dist/src/gateway/hono/sse.d.ts +1 -1
- package/dist/src/gateway/hono/sse.js +1 -1
- package/dist/src/gateway/service/run-gateway-agent.js +5 -1
- package/dist/src/media/session-references.js +9 -6
- package/dist/src/session/client-history.d.ts +1 -0
- package/dist/src/session/client-history.js +56 -12
- package/dist/src/session/types.d.ts +1 -0
- package/dist/src/storage/sqlite/connector-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/connector-repository.js +12 -1
- package/dist/src/storage/sqlite/index.d.ts +1 -1
- package/dist/src/storage/sqlite/index.js +2 -2
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/agents-RZNd9xMI.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-BOeTZgdL.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-wYN1N-Il.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-DD3djQtX.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-Bohv9YRy.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-h3VHD5Uq.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-LIAkMlN-.js +0 -2
- package/dist/gateway/static/root/assets/gateway-settings-h1wWBrxD.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-xfO0R5Bx.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-CVVKF2hY.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-W666NFIU.js +0 -2
- package/dist/gateway/static/root/assets/index-gpwk8Nro.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-y5WmNSyZ.js +0 -2
- package/dist/gateway/static/root/assets/locale-store-d9Cylz62.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-DMQaC4Jn.js +0 -7
- package/dist/gateway/static/root/assets/models-hub-panel-CoYDJvX_.js +0 -2
- package/dist/gateway/static/root/assets/notes-workbench-C9B-7EsK.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-DG_P8S7e.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-C1pro-bG.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DDj6t0SQ.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-C1aZFTTX.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CwRP1Nsl.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DFjG5i48.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-Bh2T05Hp.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-ppRtNzpM.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-Dnw1xKKm.js +0 -2
- package/dist/gateway/static/root/assets/user-context-page-09T5O8lO.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-D__GQy1R.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-CAIgG4im.js +0 -1
- package/dist/gateway/static/root/assets/work-page-CkZvIUpT.js +0 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-qqixrSRL.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-THxdPWzb.js +0 -11
- package/dist/src/connectors/registries/modelscope.d.ts +0 -2
- package/dist/src/connectors/registries/modelscope.js +0 -228
- package/dist/src/connectors/registries/official-mcp.d.ts +0 -2
- package/dist/src/connectors/registries/official-mcp.js +0 -140
- package/dist/src/connectors/registries/search.d.ts +0 -12
- package/dist/src/connectors/registries/search.js +0 -87
- package/dist/src/connectors/registries/smithery.d.ts +0 -2
- package/dist/src/connectors/registries/smithery.js +0 -97
- package/dist/src/connectors/registries/types.d.ts +0 -20
- package/dist/src/connectors/registries/types.js +0 -1
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=20260713-1" />
|
|
12
12
|
<link rel="manifest" href="/site.webmanifest?v=20260713-1" />
|
|
13
13
|
<title>xopc</title>
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-BuqGh2SW.js"></script>
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-aKtaBQYM.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-zJ_50EbN.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BOUWij0V.js">
|
|
@@ -24,15 +24,15 @@
|
|
|
24
24
|
<link rel="modulepreload" crossorigin href="/assets/check-BODqo66o.js">
|
|
25
25
|
<link rel="modulepreload" crossorigin href="/assets/circle-alert-RzVebuX2.js">
|
|
26
26
|
<link rel="modulepreload" crossorigin href="/assets/middleware-Pd0e8Igk.js">
|
|
27
|
-
<link rel="modulepreload" crossorigin href="/assets/messages-
|
|
28
|
-
<link rel="modulepreload" crossorigin href="/assets/locale-store-
|
|
27
|
+
<link rel="modulepreload" crossorigin href="/assets/messages-BuT0SR1R.js">
|
|
28
|
+
<link rel="modulepreload" crossorigin href="/assets/locale-store-C_M71MK9.js">
|
|
29
29
|
<link rel="modulepreload" crossorigin href="/assets/schemas-DgQq6Z5S.js">
|
|
30
30
|
<link rel="modulepreload" crossorigin href="/assets/config-reload-event-Bjh2zoKp.js">
|
|
31
31
|
<link rel="modulepreload" crossorigin href="/assets/copy-to-clipboard-HOJ79TWv.js">
|
|
32
|
-
<link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-
|
|
33
|
-
<link rel="modulepreload" crossorigin href="/assets/activity-store-
|
|
34
|
-
<link rel="modulepreload" crossorigin href="/assets/theme-store-
|
|
35
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
32
|
+
<link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-cxQ94qMm.js">
|
|
33
|
+
<link rel="modulepreload" crossorigin href="/assets/activity-store-C-57rvkX.js">
|
|
34
|
+
<link rel="modulepreload" crossorigin href="/assets/theme-store-C8ohIHhw.js">
|
|
35
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BgZhEOkN.css">
|
|
36
36
|
</head>
|
|
37
37
|
<body>
|
|
38
38
|
<div id="root"></div>
|
package/dist/package.js
CHANGED
|
@@ -173,6 +173,20 @@ function sanitizeToolResultDetailsForPersistence(details) {
|
|
|
173
173
|
out.sessions = src.sessions.slice(0, MAX_PERSISTED_DETAIL_SESSION_COUNT).map(sanitizePersistedSessionDetail);
|
|
174
174
|
if (src.sessions.length > MAX_PERSISTED_DETAIL_SESSION_COUNT) out.sessionsTruncated = src.sessions.length - MAX_PERSISTED_DETAIL_SESSION_COUNT;
|
|
175
175
|
}
|
|
176
|
+
if (Array.isArray(src.media)) out.media = src.media.slice(0, 12).map((item) => {
|
|
177
|
+
if (!item || typeof item !== "object") return item;
|
|
178
|
+
const media = item;
|
|
179
|
+
return Object.fromEntries([
|
|
180
|
+
"id",
|
|
181
|
+
"bucket",
|
|
182
|
+
"type",
|
|
183
|
+
"mimeType",
|
|
184
|
+
"name",
|
|
185
|
+
"size",
|
|
186
|
+
"uri",
|
|
187
|
+
"path"
|
|
188
|
+
].filter((key) => media[key] !== void 0).map((key) => [key, media[key]]));
|
|
189
|
+
});
|
|
176
190
|
return enforcePersistedDetailsByteCap(out, src, originalSize);
|
|
177
191
|
}
|
|
178
192
|
function capToolResultDetails(msg) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createLogger } from "../../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../../utils/logger.js";
|
|
3
|
+
import { imageAssetFromBase64, imageFileExtensionForMimeType } from "./image-assets.js";
|
|
3
4
|
import { pickTimeoutMsOrFallback } from "../../../media-shared/http/deadline.js";
|
|
4
5
|
import { privateNetworkPolicyToSsrfGuardOptions } from "../../../media-shared/http/private-network.js";
|
|
5
6
|
import { resolveProviderHttpRequestConfig } from "../../../media-shared/http/resolve-provider-http-request-config.js";
|
|
6
7
|
import { postJsonRequest, postMultipartRequest } from "../../../media-shared/http/provider-http.js";
|
|
7
8
|
import "../../../media-shared/http/index.js";
|
|
8
|
-
import { imageAssetFromBase64, imageFileExtensionForMimeType } from "./image-assets.js";
|
|
9
9
|
//#region src/agent/image/generation/openai-compatible-image-provider.ts
|
|
10
10
|
init_logger();
|
|
11
11
|
const log = createLogger("ImageGen:OpenAICompat");
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getAgentDefaultImageGenerationModelConfig, init_schema } from "../../config/schema.js";
|
|
2
|
+
import { imageAssetFromDataUrl, imageFileExtensionForMimeType, mimeTypeFromFileName, parseImageDataUrl, sniffImageMimeType } from "../image/generation/image-assets.js";
|
|
3
|
+
import { persistToolMedia } from "./tool-media.js";
|
|
2
4
|
import { applyImageGenerationModelConfigDefaults } from "../image/image-helpers.js";
|
|
3
5
|
import { isFailoverError } from "../failover-error.js";
|
|
4
|
-
import { imageAssetFromDataUrl, imageFileExtensionForMimeType, mimeTypeFromFileName, parseImageDataUrl, sniffImageMimeType } from "../image/generation/image-assets.js";
|
|
5
6
|
import { getImageGenerationProvider } from "../image/generation/provider-registry.js";
|
|
6
7
|
import { generateImage, listImageGenerationProvidersSummary } from "../image/generation/runtime.js";
|
|
7
8
|
import path from "node:path";
|
|
@@ -174,7 +175,7 @@ function createImageGenerateTool(options) {
|
|
|
174
175
|
return {
|
|
175
176
|
name: "image_generate",
|
|
176
177
|
label: "Image Generation",
|
|
177
|
-
description: "Generate images with the configured image-generation model
|
|
178
|
+
description: "Generate and attach images with the configured image-generation model. Use action=\"list\" to see providers. Also saves files under workspace/media/generated/. Do not call send_media for generated images.",
|
|
178
179
|
parameters: ImageGenerateToolSchema,
|
|
179
180
|
async execute(_toolCallId, args) {
|
|
180
181
|
const params = args;
|
|
@@ -254,7 +255,12 @@ function createImageGenerateTool(options) {
|
|
|
254
255
|
...filename ? { filenameHint: filename } : {}
|
|
255
256
|
});
|
|
256
257
|
const workspaceRelativePaths = paths.map((p) => path.relative(options.workspace, p).split(path.sep).join("/"));
|
|
257
|
-
const
|
|
258
|
+
const media = await Promise.all(result.images.map((image, index) => persistToolMedia({
|
|
259
|
+
buffer: image.buffer,
|
|
260
|
+
filePath: paths[index],
|
|
261
|
+
mediaType: "photo"
|
|
262
|
+
})));
|
|
263
|
+
const lines = [`Generated and attached ${paths.length} image(s) with ${result.provider}/${result.model}.`, ...paths.map((p) => `Saved: ${p}`)];
|
|
258
264
|
for (const note of buildNormalizationNotes(result.normalization, result.ignoredOverrides)) lines.push(note);
|
|
259
265
|
return {
|
|
260
266
|
content: [{
|
|
@@ -266,6 +272,7 @@ function createImageGenerateTool(options) {
|
|
|
266
272
|
model: result.model,
|
|
267
273
|
paths,
|
|
268
274
|
workspaceRelativePaths,
|
|
275
|
+
media,
|
|
269
276
|
attempts: result.attempts,
|
|
270
277
|
...result.normalization ? { normalization: result.normalization } : {},
|
|
271
278
|
...result.ignoredOverrides.length > 0 ? { ignoredOverrides: result.ignoredOverrides } : {},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { checkFileSafety } from "../prompt/safety.js";
|
|
2
2
|
import { resolvePathUnderWorkspace } from "./tool-paths.js";
|
|
3
|
+
import { persistToolMedia } from "./tool-media.js";
|
|
3
4
|
import { basename } from "node:path";
|
|
4
5
|
import { readFile } from "fs/promises";
|
|
5
6
|
import { Type } from "@sinclair/typebox";
|
|
@@ -14,61 +15,6 @@ const SendMediaSchema = Type.Object({
|
|
|
14
15
|
}, { description: "Type of media to send (auto-detected if not specified)" })),
|
|
15
16
|
caption: Type.Optional(Type.String({ description: "Caption for the media" }))
|
|
16
17
|
});
|
|
17
|
-
function detectMediaType(filePath) {
|
|
18
|
-
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
19
|
-
const imageExts = [
|
|
20
|
-
"jpg",
|
|
21
|
-
"jpeg",
|
|
22
|
-
"png",
|
|
23
|
-
"gif",
|
|
24
|
-
"webp",
|
|
25
|
-
"bmp"
|
|
26
|
-
];
|
|
27
|
-
const videoExts = [
|
|
28
|
-
"mp4",
|
|
29
|
-
"mov",
|
|
30
|
-
"avi",
|
|
31
|
-
"webm",
|
|
32
|
-
"mkv"
|
|
33
|
-
];
|
|
34
|
-
const audioExts = [
|
|
35
|
-
"mp3",
|
|
36
|
-
"wav",
|
|
37
|
-
"ogg",
|
|
38
|
-
"m4a",
|
|
39
|
-
"flac"
|
|
40
|
-
];
|
|
41
|
-
if (imageExts.includes(ext || "")) return "photo";
|
|
42
|
-
if (videoExts.includes(ext || "")) return "video";
|
|
43
|
-
if (audioExts.includes(ext || "")) return "audio";
|
|
44
|
-
return "document";
|
|
45
|
-
}
|
|
46
|
-
function detectMimeType(filePath) {
|
|
47
|
-
return {
|
|
48
|
-
jpg: "image/jpeg",
|
|
49
|
-
jpeg: "image/jpeg",
|
|
50
|
-
png: "image/png",
|
|
51
|
-
gif: "image/gif",
|
|
52
|
-
webp: "image/webp",
|
|
53
|
-
bmp: "image/bmp",
|
|
54
|
-
svg: "image/svg+xml",
|
|
55
|
-
mp4: "video/mp4",
|
|
56
|
-
mov: "video/quicktime",
|
|
57
|
-
avi: "video/x-msvideo",
|
|
58
|
-
webm: "video/webm",
|
|
59
|
-
mp3: "audio/mpeg",
|
|
60
|
-
wav: "audio/wav",
|
|
61
|
-
ogg: "audio/ogg",
|
|
62
|
-
m4a: "audio/mp4",
|
|
63
|
-
flac: "audio/flac",
|
|
64
|
-
pdf: "application/pdf",
|
|
65
|
-
doc: "application/msword",
|
|
66
|
-
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
67
|
-
txt: "text/plain",
|
|
68
|
-
zip: "application/zip",
|
|
69
|
-
rar: "application/x-rar-compressed"
|
|
70
|
-
}[filePath.split(".").pop()?.toLowerCase() || ""] || "application/octet-stream";
|
|
71
|
-
}
|
|
72
18
|
function createSendMediaTool(workspace, bus, getContext) {
|
|
73
19
|
return {
|
|
74
20
|
name: "send_media",
|
|
@@ -95,26 +41,30 @@ function createSendMediaTool(workspace, bus, getContext) {
|
|
|
95
41
|
details: {}
|
|
96
42
|
};
|
|
97
43
|
try {
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
44
|
+
const fileBuffer = await readFile(resolved);
|
|
45
|
+
const media = await persistToolMedia({
|
|
46
|
+
buffer: fileBuffer,
|
|
47
|
+
filePath: resolved,
|
|
48
|
+
...p.mediaType ? { mediaType: p.mediaType } : {}
|
|
49
|
+
});
|
|
50
|
+
if (ctx.channel !== "webchat") {
|
|
51
|
+
const msg = {
|
|
52
|
+
channel: ctx.channel,
|
|
53
|
+
chat_id: ctx.chatId,
|
|
54
|
+
content: p.caption || "",
|
|
55
|
+
mediaUrl: `data:${media.mimeType};base64,${fileBuffer.toString("base64")}`,
|
|
56
|
+
mediaType: media.type
|
|
57
|
+
};
|
|
58
|
+
await bus.publishOutbound(msg);
|
|
59
|
+
}
|
|
110
60
|
return {
|
|
111
61
|
content: [{
|
|
112
62
|
type: "text",
|
|
113
|
-
text:
|
|
63
|
+
text: `Media attached: ${basename(resolved)} (${media.type})`
|
|
114
64
|
}],
|
|
115
65
|
details: {
|
|
116
|
-
|
|
117
|
-
|
|
66
|
+
media: [media],
|
|
67
|
+
...p.caption ? { caption: p.caption } : {}
|
|
118
68
|
}
|
|
119
69
|
};
|
|
120
70
|
} catch (error) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MediaRef } from '../../media/types.js';
|
|
2
|
+
export type ToolMediaType = 'photo' | 'video' | 'audio' | 'document';
|
|
3
|
+
export declare function detectToolMediaMimeType(buffer: Buffer, filePath: string): string;
|
|
4
|
+
export declare function mediaTypeFromMimeType(mimeType: string): ToolMediaType;
|
|
5
|
+
export declare function persistToolMedia(params: {
|
|
6
|
+
buffer: Buffer;
|
|
7
|
+
filePath: string;
|
|
8
|
+
mediaType?: ToolMediaType;
|
|
9
|
+
}): Promise<MediaRef>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { sniffImageMimeType } from "../image/generation/image-assets.js";
|
|
2
|
+
import { mimeTypeFromMediaPath, saveMediaBuffer } from "../../media/store.js";
|
|
3
|
+
import { basename } from "node:path";
|
|
4
|
+
//#region src/agent/tools/tool-media.ts
|
|
5
|
+
const MAX_TOOL_MEDIA_BYTES = 50 * 1024 * 1024;
|
|
6
|
+
function hasImageMagic(buffer) {
|
|
7
|
+
if (buffer.length >= 8 && buffer.subarray(0, 8).equals(Buffer.from([
|
|
8
|
+
137,
|
|
9
|
+
80,
|
|
10
|
+
78,
|
|
11
|
+
71,
|
|
12
|
+
13,
|
|
13
|
+
10,
|
|
14
|
+
26,
|
|
15
|
+
10
|
|
16
|
+
]))) return true;
|
|
17
|
+
if (buffer.length >= 3 && buffer.subarray(0, 3).equals(Buffer.from([
|
|
18
|
+
255,
|
|
19
|
+
216,
|
|
20
|
+
255
|
|
21
|
+
]))) return true;
|
|
22
|
+
if (buffer.length >= 4 && buffer.subarray(0, 4).toString("ascii") === "GIF8") return true;
|
|
23
|
+
return buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP";
|
|
24
|
+
}
|
|
25
|
+
function detectToolMediaMimeType(buffer, filePath) {
|
|
26
|
+
if (hasImageMagic(buffer)) return sniffImageMimeType(buffer).mimeType;
|
|
27
|
+
if (buffer.length >= 5 && buffer.subarray(0, 5).toString("ascii") === "%PDF-") return "application/pdf";
|
|
28
|
+
return mimeTypeFromMediaPath(filePath);
|
|
29
|
+
}
|
|
30
|
+
function mediaTypeFromMimeType(mimeType) {
|
|
31
|
+
if (mimeType === "image/svg+xml") return "document";
|
|
32
|
+
if (mimeType.startsWith("image/")) return "photo";
|
|
33
|
+
if (mimeType.startsWith("video/")) return "video";
|
|
34
|
+
if (mimeType.startsWith("audio/")) return "audio";
|
|
35
|
+
return "document";
|
|
36
|
+
}
|
|
37
|
+
async function persistToolMedia(params) {
|
|
38
|
+
const name = basename(params.filePath);
|
|
39
|
+
const mimeType = detectToolMediaMimeType(params.buffer, params.filePath);
|
|
40
|
+
const saved = await saveMediaBuffer(params.buffer, {
|
|
41
|
+
bucket: "outbound",
|
|
42
|
+
contentType: mimeType,
|
|
43
|
+
originalFilename: name,
|
|
44
|
+
maxBytes: MAX_TOOL_MEDIA_BYTES
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
id: saved.id,
|
|
48
|
+
bucket: saved.bucket,
|
|
49
|
+
type: params.mediaType ?? mediaTypeFromMimeType(mimeType),
|
|
50
|
+
mimeType: saved.contentType,
|
|
51
|
+
name,
|
|
52
|
+
size: saved.size,
|
|
53
|
+
uri: saved.uri,
|
|
54
|
+
path: saved.path
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
export { detectToolMediaMimeType, mediaTypeFromMimeType, persistToolMedia };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
|
|
1
2
|
import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
|
|
2
3
|
import "../agent-manifest/index.js";
|
|
3
|
-
import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
|
|
4
4
|
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
5
5
|
import { agentExists, getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
6
6
|
//#region src/config/agent-profile.ts
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { isXopcDatabaseOpen } from "../storage/sqlite/connection.js";
|
|
2
|
-
import { getCachedConnectorCatalogEntry
|
|
2
|
+
import { getCachedConnectorCatalogEntry } from "../storage/sqlite/connector-repository.js";
|
|
3
3
|
import { listConnectorProviderDefinitions, listConnectorProviders } from "./providers.js";
|
|
4
4
|
//#region src/connectors/catalog.ts
|
|
5
5
|
const CONNECTOR_BY_ID = new Map(listConnectorProviderDefinitions().map((connector) => [connector.id, connector]));
|
|
6
6
|
function listConnectorCatalog() {
|
|
7
|
-
|
|
8
|
-
return [...new Map(definitions.map((connector) => [connector.id, connector])).values()].sort((left, right) => left.displayName.localeCompare(right.displayName));
|
|
7
|
+
return listConnectorProviderDefinitions().sort((left, right) => left.displayName.localeCompare(right.displayName));
|
|
9
8
|
}
|
|
10
9
|
function getConnectorDefinition(connectorId) {
|
|
11
10
|
const providerDefinition = CONNECTOR_BY_ID.get(connectorId);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComposioSessionsAdapter, type ComposioToolkitCatalogItem } from './composio-sessions.js';
|
|
2
|
-
import type { ConnectorDefinition } from './types.js';
|
|
2
|
+
import type { ConnectorDefinition, ConnectorVerificationLevel } from './types.js';
|
|
3
3
|
export declare const COMPOSIO_RECOMMENDED_TOOLKITS: readonly ["gmail", "googlecalendar", "googledrive", "notion", "slack", "github", "linear", "outlook", "microsoft_teams", "jira", "dropbox", "todoist"];
|
|
4
4
|
export declare const COMPOSIO_AGENT_READY_TOOLKITS: readonly ["gmail", "googlecalendar", "googledrive", "notion", "slack", "github", "linear", "outlook", "microsoft_teams", "jira", "dropbox", "todoist", "discord", "googledocs", "googlesheets", "trello", "asana", "clickup", "twitter", "spotify", "telegram", "whatsapp", "shopify", "stripe", "hubspot", "salesforce", "airtable", "figma", "youtube", "one_drive", "excel"];
|
|
5
5
|
export type ComposioAgentReadyToolkit = typeof COMPOSIO_AGENT_READY_TOOLKITS[number];
|
|
@@ -10,10 +10,20 @@ export type ComposioCatalogResult = {
|
|
|
10
10
|
source: 'live' | 'cache';
|
|
11
11
|
stale: boolean;
|
|
12
12
|
fetchedAt?: string;
|
|
13
|
+
meta: {
|
|
14
|
+
page: number;
|
|
15
|
+
pageSize: number;
|
|
16
|
+
total: number;
|
|
17
|
+
totalPages: number;
|
|
18
|
+
};
|
|
13
19
|
};
|
|
14
20
|
export declare function listComposioConnectorCatalog(options?: {
|
|
15
21
|
principalId?: string;
|
|
16
22
|
refresh?: boolean;
|
|
17
23
|
adapter?: ComposioSessionsAdapter;
|
|
18
24
|
now?: number;
|
|
25
|
+
query?: string;
|
|
26
|
+
page?: number;
|
|
27
|
+
pageSize?: number;
|
|
28
|
+
verification?: 'all' | ConnectorVerificationLevel;
|
|
19
29
|
}): Promise<ComposioCatalogResult>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { listCachedConnectorCatalogEntries,
|
|
1
|
+
import { listCachedConnectorCatalogEntries, replaceConnectorCatalogEntries } from "../storage/sqlite/connector-repository.js";
|
|
2
2
|
import { ComposioSessionsAdapter } from "./composio-sessions.js";
|
|
3
3
|
import { composioIntegrationStrategy } from "./integration-strategy.js";
|
|
4
4
|
//#region src/connectors/composio-catalog.ts
|
|
@@ -191,7 +191,7 @@ function connectorDefinitionFromComposioToolkit(item) {
|
|
|
191
191
|
description: CONNECTOR_DESCRIPTIONS[slug] ?? `Connect ${item.name} so agents can use approved actions on your behalf.`,
|
|
192
192
|
category: categoryForToolkit(slug),
|
|
193
193
|
kind: "composio",
|
|
194
|
-
source: "
|
|
194
|
+
source: "registry",
|
|
195
195
|
capabilities: item.isNoAuth ? [
|
|
196
196
|
"tools",
|
|
197
197
|
"events",
|
|
@@ -229,12 +229,42 @@ function connectorDefinitionFromComposioToolkit(item) {
|
|
|
229
229
|
integrationStrategy: composioIntegrationStrategy(slug)
|
|
230
230
|
};
|
|
231
231
|
}
|
|
232
|
+
function projectComposioCatalog(connectors, options) {
|
|
233
|
+
const query = options.query?.trim().toLocaleLowerCase() ?? "";
|
|
234
|
+
const verification = options.verification ?? "all";
|
|
235
|
+
const filtered = connectors.map((connector) => ({
|
|
236
|
+
...connector,
|
|
237
|
+
source: "registry"
|
|
238
|
+
})).filter((connector) => {
|
|
239
|
+
if (verification !== "all" && connector.verificationLevel !== verification) return false;
|
|
240
|
+
if (!query) return true;
|
|
241
|
+
return [
|
|
242
|
+
connector.displayName,
|
|
243
|
+
connector.description,
|
|
244
|
+
connector.category,
|
|
245
|
+
...connector.tags ?? []
|
|
246
|
+
].some((value) => value.toLocaleLowerCase().includes(query));
|
|
247
|
+
});
|
|
248
|
+
const pageSize = Math.max(1, Math.min(options.pageSize ?? 24, 100));
|
|
249
|
+
const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
|
|
250
|
+
const page = Math.max(1, Math.min(options.page ?? 1, totalPages));
|
|
251
|
+
const start = (page - 1) * pageSize;
|
|
252
|
+
return {
|
|
253
|
+
connectors: filtered.slice(start, start + pageSize),
|
|
254
|
+
meta: {
|
|
255
|
+
page,
|
|
256
|
+
pageSize,
|
|
257
|
+
total: filtered.length,
|
|
258
|
+
totalPages
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
232
262
|
async function listComposioConnectorCatalog(options = {}) {
|
|
233
263
|
const now = options.now ?? Date.now();
|
|
234
264
|
const cached = listCachedConnectorCatalogEntries("composio");
|
|
235
265
|
const freshCached = cached.filter((entry) => !entry.expiresAt || Date.parse(entry.expiresAt) > now);
|
|
236
266
|
if (!options.refresh && freshCached.length > 0) return {
|
|
237
|
-
|
|
267
|
+
...projectComposioCatalog(freshCached.map((entry) => entry.definition), options),
|
|
238
268
|
source: "cache",
|
|
239
269
|
stale: false,
|
|
240
270
|
fetchedAt: freshCached[0]?.fetchedAt
|
|
@@ -244,15 +274,15 @@ async function listComposioConnectorCatalog(options = {}) {
|
|
|
244
274
|
const fetchedAt = new Date(now).toISOString();
|
|
245
275
|
const expiresAt = new Date(now + CATALOG_CACHE_TTL_MS).toISOString();
|
|
246
276
|
const connectors = toolkits.map(connectorDefinitionFromComposioToolkit);
|
|
247
|
-
|
|
277
|
+
replaceConnectorCatalogEntries("composio", connectors.map((definition) => ({
|
|
248
278
|
connectorId: definition.id,
|
|
249
279
|
provider: "composio",
|
|
250
280
|
definition,
|
|
251
281
|
fetchedAt,
|
|
252
282
|
expiresAt
|
|
253
|
-
});
|
|
283
|
+
})));
|
|
254
284
|
return {
|
|
255
|
-
connectors,
|
|
285
|
+
...projectComposioCatalog(connectors, options),
|
|
256
286
|
source: "live",
|
|
257
287
|
stale: false,
|
|
258
288
|
fetchedAt
|
|
@@ -260,7 +290,7 @@ async function listComposioConnectorCatalog(options = {}) {
|
|
|
260
290
|
} catch (error) {
|
|
261
291
|
if (cached.length === 0) throw error;
|
|
262
292
|
return {
|
|
263
|
-
|
|
293
|
+
...projectComposioCatalog(cached.map((entry) => entry.definition), options),
|
|
264
294
|
source: "cache",
|
|
265
295
|
stale: true,
|
|
266
296
|
fetchedAt: cached[0]?.fetchedAt
|
|
@@ -7,7 +7,9 @@ export type RelayEvent = {
|
|
|
7
7
|
type: string;
|
|
8
8
|
} & Record<string, unknown>;
|
|
9
9
|
export declare class AgentRunRelay {
|
|
10
|
+
private readonly maxEvents;
|
|
10
11
|
private runs;
|
|
12
|
+
constructor(maxEvents?: number);
|
|
11
13
|
ensureRun(runId: string, sessionKey: string): void;
|
|
12
14
|
getSessionKey(runId: string): string | undefined;
|
|
13
15
|
hasRun(runId: string): boolean;
|
|
@@ -5,8 +5,84 @@ init_logger();
|
|
|
5
5
|
const log = createLogger("Gateway:AgentRunRelay");
|
|
6
6
|
const COMPLETE_TTL_MS = 5 * 6e4;
|
|
7
7
|
const MAX_EVENTS = 8e3;
|
|
8
|
+
const COMPACT_TO_RATIO = .75;
|
|
9
|
+
const MAX_MERGED_DELTA_CHARS = 16 * 1024;
|
|
10
|
+
const REPLAY_DELTA_TYPES = new Set([
|
|
11
|
+
"assistant_delta",
|
|
12
|
+
"thinking_delta",
|
|
13
|
+
"command_output_delta",
|
|
14
|
+
"review_delta"
|
|
15
|
+
]);
|
|
16
|
+
function eventSeq(event) {
|
|
17
|
+
return typeof event.seq === "number" ? event.seq : void 0;
|
|
18
|
+
}
|
|
19
|
+
function findEventAtOrAfter(events, seq) {
|
|
20
|
+
let low = 0;
|
|
21
|
+
let high = events.length;
|
|
22
|
+
while (low < high) {
|
|
23
|
+
const middle = low + Math.floor((high - low) / 2);
|
|
24
|
+
if ((eventSeq(events[middle]) ?? Number.MAX_SAFE_INTEGER) < seq) low = middle + 1;
|
|
25
|
+
else high = middle;
|
|
26
|
+
}
|
|
27
|
+
return events[low];
|
|
28
|
+
}
|
|
29
|
+
function recordValue(value) {
|
|
30
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
31
|
+
}
|
|
32
|
+
function sameDeltaStream(left, right) {
|
|
33
|
+
if (left.type !== right.type || !REPLAY_DELTA_TYPES.has(left.type)) return false;
|
|
34
|
+
const leftPayload = recordValue(left.payload);
|
|
35
|
+
const rightPayload = recordValue(right.payload);
|
|
36
|
+
if (!leftPayload || !rightPayload) return false;
|
|
37
|
+
return [
|
|
38
|
+
"messageId",
|
|
39
|
+
"toolCallId",
|
|
40
|
+
"reviewId",
|
|
41
|
+
"stream"
|
|
42
|
+
].every((key) => leftPayload[key] === rightPayload[key]);
|
|
43
|
+
}
|
|
44
|
+
function mergeReplayDelta(events, event) {
|
|
45
|
+
const previous = events.at(-1);
|
|
46
|
+
if (!previous || !sameDeltaStream(previous, event)) return false;
|
|
47
|
+
const previousPayload = recordValue(previous.payload);
|
|
48
|
+
const payload = recordValue(event.payload);
|
|
49
|
+
const previousDelta = previousPayload?.delta;
|
|
50
|
+
const delta = payload?.delta;
|
|
51
|
+
if (typeof previousDelta !== "string" || typeof delta !== "string") return false;
|
|
52
|
+
if (previousDelta.length + delta.length > MAX_MERGED_DELTA_CHARS) return false;
|
|
53
|
+
events[events.length - 1] = {
|
|
54
|
+
...previous,
|
|
55
|
+
payload: {
|
|
56
|
+
...previousPayload,
|
|
57
|
+
delta: previousDelta + delta
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
function compactEvents(events, targetSize) {
|
|
63
|
+
let remaining = Math.max(0, events.length - targetSize);
|
|
64
|
+
const retained = [];
|
|
65
|
+
const removedByType = {};
|
|
66
|
+
for (const event of events) {
|
|
67
|
+
if (remaining > 0 && REPLAY_DELTA_TYPES.has(event.type)) {
|
|
68
|
+
remaining -= 1;
|
|
69
|
+
removedByType[event.type] = (removedByType[event.type] ?? 0) + 1;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
retained.push(event);
|
|
73
|
+
}
|
|
74
|
+
if (remaining > 0) for (const event of retained.splice(0, remaining)) removedByType[event.type] = (removedByType[event.type] ?? 0) + 1;
|
|
75
|
+
return {
|
|
76
|
+
events: retained,
|
|
77
|
+
removedByType
|
|
78
|
+
};
|
|
79
|
+
}
|
|
8
80
|
var AgentRunRelay = class {
|
|
9
81
|
runs = /* @__PURE__ */ new Map();
|
|
82
|
+
constructor(maxEvents = MAX_EVENTS) {
|
|
83
|
+
this.maxEvents = maxEvents;
|
|
84
|
+
if (!Number.isInteger(maxEvents) || maxEvents < 2) throw new Error("AgentRunRelay maxEvents must be an integer greater than 1");
|
|
85
|
+
}
|
|
10
86
|
ensureRun(runId, sessionKey) {
|
|
11
87
|
if (this.runs.has(runId)) return;
|
|
12
88
|
this.runs.set(runId, {
|
|
@@ -14,7 +90,9 @@ var AgentRunRelay = class {
|
|
|
14
90
|
events: [],
|
|
15
91
|
nextSeq: 1,
|
|
16
92
|
done: false,
|
|
17
|
-
waiters: []
|
|
93
|
+
waiters: [],
|
|
94
|
+
subscriberCount: 0,
|
|
95
|
+
compactionWarned: false
|
|
18
96
|
});
|
|
19
97
|
}
|
|
20
98
|
getSessionKey(runId) {
|
|
@@ -31,12 +109,22 @@ var AgentRunRelay = class {
|
|
|
31
109
|
runId,
|
|
32
110
|
seq: state.nextSeq++
|
|
33
111
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
max
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
112
|
+
const merged = state.subscriberCount === 0 && mergeReplayDelta(state.events, relayed);
|
|
113
|
+
if (!merged && state.events.length >= this.maxEvents) {
|
|
114
|
+
const targetSize = Math.max(1, Math.floor(this.maxEvents * COMPACT_TO_RATIO));
|
|
115
|
+
const compacted = compactEvents(state.events, targetSize);
|
|
116
|
+
state.events = compacted.events;
|
|
117
|
+
if (!state.compactionWarned) {
|
|
118
|
+
state.compactionWarned = true;
|
|
119
|
+
log.warn({
|
|
120
|
+
runId,
|
|
121
|
+
max: this.maxEvents,
|
|
122
|
+
retained: state.events.length,
|
|
123
|
+
removedByType: compacted.removedByType
|
|
124
|
+
}, "Relay replay buffer compacted; old delta events are no longer resumable");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (!merged) state.events.push(relayed);
|
|
40
128
|
const waiters = state.waiters.splice(0);
|
|
41
129
|
for (const w of waiters) w();
|
|
42
130
|
return relayed;
|
|
@@ -55,13 +143,25 @@ var AgentRunRelay = class {
|
|
|
55
143
|
async *subscribe(runId) {
|
|
56
144
|
const state = this.runs.get(runId);
|
|
57
145
|
if (!state) throw new Error("UNKNOWN_RUN");
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
146
|
+
state.subscriberCount += 1;
|
|
147
|
+
try {
|
|
148
|
+
let nextSeq = eventSeq(state.events[0]) ?? state.nextSeq;
|
|
149
|
+
while (true) {
|
|
150
|
+
const earliestSeq = eventSeq(state.events[0]);
|
|
151
|
+
if (earliestSeq !== void 0 && nextSeq < earliestSeq) nextSeq = earliestSeq;
|
|
152
|
+
const available = findEventAtOrAfter(state.events, nextSeq);
|
|
153
|
+
if (available) {
|
|
154
|
+
nextSeq = (eventSeq(available) ?? nextSeq) + 1;
|
|
155
|
+
yield available;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (state.done) break;
|
|
159
|
+
await new Promise((resolve) => {
|
|
160
|
+
state.waiters.push(resolve);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
} finally {
|
|
164
|
+
state.subscriberCount -= 1;
|
|
65
165
|
}
|
|
66
166
|
}
|
|
67
167
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
|
|
2
1
|
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
|
|
2
|
+
import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
|
|
3
3
|
import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
|
|
4
4
|
import { WORKSPACE_FILES, init_paths, resolveUserProfilePath } from "../config/paths.js";
|
|
5
5
|
import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
|
|
@@ -14,7 +14,6 @@ export declare class ChatStreamMapper {
|
|
|
14
14
|
private assistantIndex;
|
|
15
15
|
private currentAssistantMessageId;
|
|
16
16
|
private lastAssistantMessageId;
|
|
17
|
-
private currentAssistantText;
|
|
18
17
|
private currentAssistantReviewEmitted;
|
|
19
18
|
private toolCallToMessageId;
|
|
20
19
|
private turnDiffs;
|
|
@@ -30,6 +29,7 @@ export declare class ChatStreamMapper {
|
|
|
30
29
|
error(message: string, code?: string): ChatStreamEvent[];
|
|
31
30
|
private mapMessageStart;
|
|
32
31
|
private mapMessageUpdate;
|
|
32
|
+
private mapAssistantSnapshot;
|
|
33
33
|
private mapMessageEnd;
|
|
34
34
|
private mapToolStart;
|
|
35
35
|
private mapToolUpdate;
|