@xgjktech/xg_cwork_im 1.19.41 → 1.19.42
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/README.md +4 -4
- package/dist/src/account-connection.d.ts +37 -0
- package/dist/src/account-connection.d.ts.map +1 -0
- package/dist/src/account-connection.js +548 -0
- package/dist/src/account-connection.js.map +1 -0
- package/dist/src/account-reconciler.d.ts +64 -0
- package/dist/src/account-reconciler.d.ts.map +1 -0
- package/dist/src/account-reconciler.js +314 -0
- package/dist/src/account-reconciler.js.map +1 -0
- package/dist/src/account-reconciler.test.d.ts +2 -0
- package/dist/src/account-reconciler.test.d.ts.map +1 -0
- package/dist/src/account-reconciler.test.js +166 -0
- package/dist/src/account-reconciler.test.js.map +1 -0
- package/dist/src/action-run-event.d.ts +20 -0
- package/dist/src/action-run-event.d.ts.map +1 -0
- package/dist/src/action-run-event.js +62 -0
- package/dist/src/action-run-event.js.map +1 -0
- package/dist/src/action-run-event.test.d.ts +2 -0
- package/dist/src/action-run-event.test.d.ts.map +1 -0
- package/dist/src/action-run-event.test.js +83 -0
- package/dist/src/action-run-event.test.js.map +1 -0
- package/dist/src/action-store-access.d.ts +29 -0
- package/dist/src/action-store-access.d.ts.map +1 -0
- package/dist/src/action-store-access.js +81 -0
- package/dist/src/action-store-access.js.map +1 -0
- package/dist/src/action-store-lifecycle.test.d.ts +2 -0
- package/dist/src/action-store-lifecycle.test.d.ts.map +1 -0
- package/dist/src/action-store-lifecycle.test.js +195 -0
- package/dist/src/action-store-lifecycle.test.js.map +1 -0
- package/dist/src/active-cron-context-store.d.ts +20 -0
- package/dist/src/active-cron-context-store.d.ts.map +1 -0
- package/dist/src/active-cron-context-store.js +73 -0
- package/dist/src/active-cron-context-store.js.map +1 -0
- package/dist/src/active-round-registry.d.ts +35 -0
- package/dist/src/active-round-registry.d.ts.map +1 -0
- package/dist/src/active-round-registry.js +85 -0
- package/dist/src/active-round-registry.js.map +1 -0
- package/dist/src/active-round-registry.test.d.ts +2 -0
- package/dist/src/active-round-registry.test.d.ts.map +1 -0
- package/dist/src/active-round-registry.test.js +62 -0
- package/dist/src/active-round-registry.test.js.map +1 -0
- package/dist/src/agent-context-types.d.ts +205 -0
- package/dist/src/agent-context-types.d.ts.map +1 -0
- package/dist/src/agent-context-types.js +132 -0
- package/dist/src/agent-context-types.js.map +1 -0
- package/dist/src/agent-context-types.test.d.ts +2 -0
- package/dist/src/agent-context-types.test.d.ts.map +1 -0
- package/dist/src/agent-context-types.test.js +123 -0
- package/dist/src/agent-context-types.test.js.map +1 -0
- package/dist/src/agent-stream-client-registry.d.ts +8 -0
- package/dist/src/agent-stream-client-registry.d.ts.map +1 -0
- package/dist/src/agent-stream-client-registry.js +19 -0
- package/dist/src/agent-stream-client-registry.js.map +1 -0
- package/dist/src/apply-sync-mapping.d.ts +15 -0
- package/dist/src/apply-sync-mapping.d.ts.map +1 -0
- package/dist/src/apply-sync-mapping.js +98 -0
- package/dist/src/apply-sync-mapping.js.map +1 -0
- package/dist/src/assistant-item-delivery.d.ts +27 -0
- package/dist/src/assistant-item-delivery.d.ts.map +1 -0
- package/dist/src/assistant-item-delivery.js +134 -0
- package/dist/src/assistant-item-delivery.js.map +1 -0
- package/dist/src/assistant-item-delivery.test.d.ts +2 -0
- package/dist/src/assistant-item-delivery.test.d.ts.map +1 -0
- package/dist/src/assistant-item-delivery.test.js +116 -0
- package/dist/src/assistant-item-delivery.test.js.map +1 -0
- package/dist/src/assistant-item-sink.d.ts +17 -0
- package/dist/src/assistant-item-sink.d.ts.map +1 -0
- package/dist/src/assistant-item-sink.js +34 -0
- package/dist/src/assistant-item-sink.js.map +1 -0
- package/dist/src/auth.d.ts +32 -0
- package/dist/src/auth.d.ts.map +1 -0
- package/dist/src/auth.js +70 -0
- package/dist/src/auth.js.map +1 -0
- package/dist/src/auto-model-router.d.ts +36 -0
- package/dist/src/auto-model-router.d.ts.map +1 -0
- package/dist/src/auto-model-router.js +60 -0
- package/dist/src/auto-model-router.js.map +1 -0
- package/dist/src/auto-model-router.test.d.ts +2 -0
- package/dist/src/auto-model-router.test.d.ts.map +1 -0
- package/dist/src/auto-model-router.test.js +99 -0
- package/dist/src/auto-model-router.test.js.map +1 -0
- package/dist/src/block-streaming-config.test.d.ts +2 -0
- package/dist/src/block-streaming-config.test.d.ts.map +1 -0
- package/dist/src/block-streaming-config.test.js +91 -0
- package/dist/src/block-streaming-config.test.js.map +1 -0
- package/dist/src/build-project-prompt.d.ts +40 -0
- package/dist/src/build-project-prompt.d.ts.map +1 -0
- package/dist/src/build-project-prompt.js +183 -0
- package/dist/src/build-project-prompt.js.map +1 -0
- package/dist/src/build-project-prompt.test.d.ts +2 -0
- package/dist/src/build-project-prompt.test.d.ts.map +1 -0
- package/dist/src/build-project-prompt.test.js +100 -0
- package/dist/src/build-project-prompt.test.js.map +1 -0
- package/dist/src/channel-config.d.ts +716 -0
- package/dist/src/channel-config.d.ts.map +1 -0
- package/dist/src/channel-config.js +405 -0
- package/dist/src/channel-config.js.map +1 -0
- package/dist/src/channel-config.test.d.ts +2 -0
- package/dist/src/channel-config.test.d.ts.map +1 -0
- package/dist/src/channel-config.test.js +113 -0
- package/dist/src/channel-config.test.js.map +1 -0
- package/dist/src/channel-disabled-account.test.d.ts +2 -0
- package/dist/src/channel-disabled-account.test.d.ts.map +1 -0
- package/dist/src/channel-disabled-account.test.js +44 -0
- package/dist/src/channel-disabled-account.test.js.map +1 -0
- package/dist/src/channel-log.d.ts +17 -0
- package/dist/src/channel-log.d.ts.map +1 -0
- package/dist/src/channel-log.js +45 -0
- package/dist/src/channel-log.js.map +1 -0
- package/dist/src/channel.d.ts +17 -0
- package/dist/src/channel.d.ts.map +1 -0
- package/dist/src/channel.js +272 -0
- package/dist/src/channel.js.map +1 -0
- package/dist/src/connection-workspace-event.test.d.ts +2 -0
- package/dist/src/connection-workspace-event.test.d.ts.map +1 -0
- package/dist/src/connection-workspace-event.test.js +74 -0
- package/dist/src/connection-workspace-event.test.js.map +1 -0
- package/dist/src/connection.d.ts +110 -0
- package/dist/src/connection.d.ts.map +1 -0
- package/dist/src/connection.js +463 -0
- package/dist/src/connection.js.map +1 -0
- package/dist/src/connection.test.d.ts +2 -0
- package/dist/src/connection.test.d.ts.map +1 -0
- package/dist/src/connection.test.js +110 -0
- package/dist/src/connection.test.js.map +1 -0
- package/dist/src/cron-appkey-binding-store.d.ts +29 -0
- package/dist/src/cron-appkey-binding-store.d.ts.map +1 -0
- package/dist/src/cron-appkey-binding-store.js +239 -0
- package/dist/src/cron-appkey-binding-store.js.map +1 -0
- package/dist/src/cron-appkey-binding-store.test.d.ts +2 -0
- package/dist/src/cron-appkey-binding-store.test.d.ts.map +1 -0
- package/dist/src/cron-appkey-binding-store.test.js +387 -0
- package/dist/src/cron-appkey-binding-store.test.js.map +1 -0
- package/dist/src/deliver-text.d.ts +30 -0
- package/dist/src/deliver-text.d.ts.map +1 -0
- package/dist/src/deliver-text.js +88 -0
- package/dist/src/deliver-text.js.map +1 -0
- package/dist/src/deliver-text.test.d.ts +2 -0
- package/dist/src/deliver-text.test.d.ts.map +1 -0
- package/dist/src/deliver-text.test.js +117 -0
- package/dist/src/deliver-text.test.js.map +1 -0
- package/dist/src/delivery/user-facing-errors.d.ts +1 -0
- package/dist/src/delivery/user-facing-errors.d.ts.map +1 -1
- package/dist/src/delivery/user-facing-errors.js +7 -0
- package/dist/src/delivery/user-facing-errors.js.map +1 -1
- package/dist/src/delivery/user-facing-errors.test.js +12 -1
- package/dist/src/delivery/user-facing-errors.test.js.map +1 -1
- package/dist/src/dispatch-mentioned-reply.d.ts +47 -0
- package/dist/src/dispatch-mentioned-reply.d.ts.map +1 -0
- package/dist/src/dispatch-mentioned-reply.js +997 -0
- package/dist/src/dispatch-mentioned-reply.js.map +1 -0
- package/dist/src/gateway-session-queue.d.ts +37 -0
- package/dist/src/gateway-session-queue.d.ts.map +1 -0
- package/dist/src/gateway-session-queue.js +86 -0
- package/dist/src/gateway-session-queue.js.map +1 -0
- package/dist/src/group-history-tool.d.ts +31 -0
- package/dist/src/group-history-tool.d.ts.map +1 -0
- package/dist/src/group-history-tool.js +177 -0
- package/dist/src/group-history-tool.js.map +1 -0
- package/dist/src/im-tool-progress.d.ts +4 -0
- package/dist/src/im-tool-progress.d.ts.map +1 -0
- package/dist/src/im-tool-progress.js +87 -0
- package/dist/src/im-tool-progress.js.map +1 -0
- package/dist/src/inbound-archive.d.ts +4 -0
- package/dist/src/inbound-archive.d.ts.map +1 -0
- package/dist/src/inbound-archive.js +105 -0
- package/dist/src/inbound-archive.js.map +1 -0
- package/dist/src/inbound-attachment-meta.d.ts +13 -0
- package/dist/src/inbound-attachment-meta.d.ts.map +1 -0
- package/dist/src/inbound-attachment-meta.js +39 -0
- package/dist/src/inbound-attachment-meta.js.map +1 -0
- package/dist/src/inbound-chat-type.d.ts +33 -0
- package/dist/src/inbound-chat-type.d.ts.map +1 -0
- package/dist/src/inbound-chat-type.js +52 -0
- package/dist/src/inbound-chat-type.js.map +1 -0
- package/dist/src/inbound-display.d.ts +41 -0
- package/dist/src/inbound-display.d.ts.map +1 -0
- package/dist/src/inbound-display.js +170 -0
- package/dist/src/inbound-display.js.map +1 -0
- package/dist/src/inbound-file-download.d.ts +15 -0
- package/dist/src/inbound-file-download.d.ts.map +1 -0
- package/dist/src/inbound-file-download.js +48 -0
- package/dist/src/inbound-file-download.js.map +1 -0
- package/dist/src/inbound-input-media.d.ts +43 -0
- package/dist/src/inbound-input-media.d.ts.map +1 -0
- package/dist/src/inbound-input-media.js +230 -0
- package/dist/src/inbound-input-media.js.map +1 -0
- package/dist/src/inbound-media-local.d.ts +49 -0
- package/dist/src/inbound-media-local.d.ts.map +1 -0
- package/dist/src/inbound-media-local.js +194 -0
- package/dist/src/inbound-media-local.js.map +1 -0
- package/dist/src/inbound-model.d.ts +39 -0
- package/dist/src/inbound-model.d.ts.map +1 -0
- package/dist/src/inbound-model.js +66 -0
- package/dist/src/inbound-model.js.map +1 -0
- package/dist/src/inbound-model.test.d.ts +2 -0
- package/dist/src/inbound-model.test.d.ts.map +1 -0
- package/dist/src/inbound-model.test.js +88 -0
- package/dist/src/inbound-model.test.js.map +1 -0
- package/dist/src/inbound-terminal-delivery.d.ts +77 -0
- package/dist/src/inbound-terminal-delivery.d.ts.map +1 -0
- package/dist/src/inbound-terminal-delivery.js +251 -0
- package/dist/src/inbound-terminal-delivery.js.map +1 -0
- package/dist/src/inbound-terminal-state.d.ts +68 -0
- package/dist/src/inbound-terminal-state.d.ts.map +1 -0
- package/dist/src/inbound-terminal-state.js +185 -0
- package/dist/src/inbound-terminal-state.js.map +1 -0
- package/dist/src/inbound-terminal-state.test.d.ts +2 -0
- package/dist/src/inbound-terminal-state.test.d.ts.map +1 -0
- package/dist/src/inbound-terminal-state.test.js +224 -0
- package/dist/src/inbound-terminal-state.test.js.map +1 -0
- package/dist/src/interrupt-round.d.ts +9 -0
- package/dist/src/interrupt-round.d.ts.map +1 -0
- package/dist/src/interrupt-round.js +44 -0
- package/dist/src/interrupt-round.js.map +1 -0
- package/dist/src/interrupt-round.test.d.ts +2 -0
- package/dist/src/interrupt-round.test.d.ts.map +1 -0
- package/dist/src/interrupt-round.test.js +133 -0
- package/dist/src/interrupt-round.test.js.map +1 -0
- package/dist/src/item-event-guard.d.ts +28 -0
- package/dist/src/item-event-guard.d.ts.map +1 -0
- package/dist/src/item-event-guard.js +22 -0
- package/dist/src/item-event-guard.js.map +1 -0
- package/dist/src/item-event-guard.test.d.ts +2 -0
- package/dist/src/item-event-guard.test.d.ts.map +1 -0
- package/dist/src/item-event-guard.test.js +55 -0
- package/dist/src/item-event-guard.test.js.map +1 -0
- package/dist/src/nas-site.d.ts +16 -0
- package/dist/src/nas-site.d.ts.map +1 -0
- package/dist/src/nas-site.js +17 -0
- package/dist/src/nas-site.js.map +1 -0
- package/dist/src/nas-volumes.d.ts +53 -0
- package/dist/src/nas-volumes.d.ts.map +1 -0
- package/dist/src/nas-volumes.js +417 -0
- package/dist/src/nas-volumes.js.map +1 -0
- package/dist/src/nas-volumes.test.d.ts +2 -0
- package/dist/src/nas-volumes.test.d.ts.map +1 -0
- package/dist/src/nas-volumes.test.js +261 -0
- package/dist/src/nas-volumes.test.js.map +1 -0
- package/dist/src/per-message-fallback-notice.d.ts +43 -0
- package/dist/src/per-message-fallback-notice.d.ts.map +1 -0
- package/dist/src/per-message-fallback-notice.js +93 -0
- package/dist/src/per-message-fallback-notice.js.map +1 -0
- package/dist/src/per-message-fallback-notice.test.d.ts +2 -0
- package/dist/src/per-message-fallback-notice.test.d.ts.map +1 -0
- package/dist/src/per-message-fallback-notice.test.js +47 -0
- package/dist/src/per-message-fallback-notice.test.js.map +1 -0
- package/dist/src/per-message-model-pending.d.ts +52 -0
- package/dist/src/per-message-model-pending.d.ts.map +1 -0
- package/dist/src/per-message-model-pending.js +134 -0
- package/dist/src/per-message-model-pending.js.map +1 -0
- package/dist/src/plan-blocked-notice.d.ts +14 -0
- package/dist/src/plan-blocked-notice.d.ts.map +1 -0
- package/dist/src/plan-blocked-notice.js +41 -0
- package/dist/src/plan-blocked-notice.js.map +1 -0
- package/dist/src/plan-blocked-notice.test.d.ts +2 -0
- package/dist/src/plan-blocked-notice.test.d.ts.map +1 -0
- package/dist/src/plan-blocked-notice.test.js +96 -0
- package/dist/src/plan-blocked-notice.test.js.map +1 -0
- package/dist/src/plan-core-adapter.d.ts +54 -0
- package/dist/src/plan-core-adapter.d.ts.map +1 -0
- package/dist/src/plan-core-adapter.js +104 -0
- package/dist/src/plan-core-adapter.js.map +1 -0
- package/dist/src/plan-core-adapter.test.d.ts +2 -0
- package/dist/src/plan-core-adapter.test.d.ts.map +1 -0
- package/dist/src/plan-core-adapter.test.js +183 -0
- package/dist/src/plan-core-adapter.test.js.map +1 -0
- package/dist/src/plan-core-db.d.ts +22 -0
- package/dist/src/plan-core-db.d.ts.map +1 -0
- package/dist/src/plan-core-db.js +91 -0
- package/dist/src/plan-core-db.js.map +1 -0
- package/dist/src/plan-core-db.test.d.ts +2 -0
- package/dist/src/plan-core-db.test.d.ts.map +1 -0
- package/dist/src/plan-core-db.test.js +115 -0
- package/dist/src/plan-core-db.test.js.map +1 -0
- package/dist/src/plan-core-snapshot.d.ts +23 -0
- package/dist/src/plan-core-snapshot.d.ts.map +1 -0
- package/dist/src/plan-core-snapshot.js +66 -0
- package/dist/src/plan-core-snapshot.js.map +1 -0
- package/dist/src/plan-core-snapshot.test.d.ts +2 -0
- package/dist/src/plan-core-snapshot.test.d.ts.map +1 -0
- package/dist/src/plan-core-snapshot.test.js +157 -0
- package/dist/src/plan-core-snapshot.test.js.map +1 -0
- package/dist/src/plan-event-subscription.d.ts +36 -0
- package/dist/src/plan-event-subscription.d.ts.map +1 -0
- package/dist/src/plan-event-subscription.js +57 -0
- package/dist/src/plan-event-subscription.js.map +1 -0
- package/dist/src/plan-event-subscription.test.d.ts +2 -0
- package/dist/src/plan-event-subscription.test.d.ts.map +1 -0
- package/dist/src/plan-event-subscription.test.js +167 -0
- package/dist/src/plan-event-subscription.test.js.map +1 -0
- package/dist/src/plan-stat-event.d.ts +17 -0
- package/dist/src/plan-stat-event.d.ts.map +1 -0
- package/dist/src/plan-stat-event.js +41 -0
- package/dist/src/plan-stat-event.js.map +1 -0
- package/dist/src/plan-stat-event.test.d.ts +2 -0
- package/dist/src/plan-stat-event.test.d.ts.map +1 -0
- package/dist/src/plan-stat-event.test.js +131 -0
- package/dist/src/plan-stat-event.test.js.map +1 -0
- package/dist/src/plan-tool-middleware.d.ts +19 -0
- package/dist/src/plan-tool-middleware.d.ts.map +1 -0
- package/dist/src/plan-tool-middleware.js +63 -0
- package/dist/src/plan-tool-middleware.js.map +1 -0
- package/dist/src/plan-tool-middleware.test.d.ts +2 -0
- package/dist/src/plan-tool-middleware.test.d.ts.map +1 -0
- package/dist/src/plan-tool-middleware.test.js +103 -0
- package/dist/src/plan-tool-middleware.test.js.map +1 -0
- package/dist/src/plan-tool-result.d.ts +18 -0
- package/dist/src/plan-tool-result.d.ts.map +1 -0
- package/dist/src/plan-tool-result.js +77 -0
- package/dist/src/plan-tool-result.js.map +1 -0
- package/dist/src/plan-tool-result.test.d.ts +2 -0
- package/dist/src/plan-tool-result.test.d.ts.map +1 -0
- package/dist/src/plan-tool-result.test.js +129 -0
- package/dist/src/plan-tool-result.test.js.map +1 -0
- package/dist/src/plan-ws-registry.d.ts +15 -0
- package/dist/src/plan-ws-registry.d.ts.map +1 -0
- package/dist/src/plan-ws-registry.js +39 -0
- package/dist/src/plan-ws-registry.js.map +1 -0
- package/dist/src/plan-ws-registry.test.d.ts +2 -0
- package/dist/src/plan-ws-registry.test.d.ts.map +1 -0
- package/dist/src/plan-ws-registry.test.js +61 -0
- package/dist/src/plan-ws-registry.test.js.map +1 -0
- package/dist/src/plugin-dispose.d.ts +22 -0
- package/dist/src/plugin-dispose.d.ts.map +1 -0
- package/dist/src/plugin-dispose.js +66 -0
- package/dist/src/plugin-dispose.js.map +1 -0
- package/dist/src/process-shared-store.d.ts +48 -0
- package/dist/src/process-shared-store.d.ts.map +1 -0
- package/dist/src/process-shared-store.js +89 -0
- package/dist/src/process-shared-store.js.map +1 -0
- package/dist/src/process-shared-store.test.d.ts +2 -0
- package/dist/src/process-shared-store.test.d.ts.map +1 -0
- package/dist/src/process-shared-store.test.js +60 -0
- package/dist/src/process-shared-store.test.js.map +1 -0
- package/dist/src/project-path-normalize.d.ts +30 -0
- package/dist/src/project-path-normalize.d.ts.map +1 -0
- package/dist/src/project-path-normalize.js +101 -0
- package/dist/src/project-path-normalize.js.map +1 -0
- package/dist/src/recommended-system-prompt.d.ts +3 -0
- package/dist/src/recommended-system-prompt.d.ts.map +1 -0
- package/dist/src/recommended-system-prompt.js +8 -0
- package/dist/src/recommended-system-prompt.js.map +1 -0
- package/dist/src/register-exec-env-hook.d.ts +44 -0
- package/dist/src/register-exec-env-hook.d.ts.map +1 -0
- package/dist/src/register-exec-env-hook.js +473 -0
- package/dist/src/register-exec-env-hook.js.map +1 -0
- package/dist/src/register-exec-env-hook.test.d.ts +2 -0
- package/dist/src/register-exec-env-hook.test.d.ts.map +1 -0
- package/dist/src/register-exec-env-hook.test.js +189 -0
- package/dist/src/register-exec-env-hook.test.js.map +1 -0
- package/dist/src/register-group-prompt-hook.d.ts +17 -0
- package/dist/src/register-group-prompt-hook.d.ts.map +1 -0
- package/dist/src/register-group-prompt-hook.js +45 -0
- package/dist/src/register-group-prompt-hook.js.map +1 -0
- package/dist/src/register-group-prompt-hook.test.d.ts +2 -0
- package/dist/src/register-group-prompt-hook.test.d.ts.map +1 -0
- package/dist/src/register-group-prompt-hook.test.js +60 -0
- package/dist/src/register-group-prompt-hook.test.js.map +1 -0
- package/dist/src/register-per-message-model-hook.d.ts +14 -0
- package/dist/src/register-per-message-model-hook.d.ts.map +1 -0
- package/dist/src/register-per-message-model-hook.js +48 -0
- package/dist/src/register-per-message-model-hook.js.map +1 -0
- package/dist/src/register-per-message-model-hook.test.d.ts +2 -0
- package/dist/src/register-per-message-model-hook.test.d.ts.map +1 -0
- package/dist/src/register-per-message-model-hook.test.js +208 -0
- package/dist/src/register-per-message-model-hook.test.js.map +1 -0
- package/dist/src/register-run-model-context-hook.d.ts +11 -0
- package/dist/src/register-run-model-context-hook.d.ts.map +1 -0
- package/dist/src/register-run-model-context-hook.js +23 -0
- package/dist/src/register-run-model-context-hook.js.map +1 -0
- package/dist/src/reply-dispatch-driver.d.ts +89 -0
- package/dist/src/reply-dispatch-driver.d.ts.map +1 -0
- package/dist/src/reply-dispatch-driver.js +294 -0
- package/dist/src/reply-dispatch-driver.js.map +1 -0
- package/dist/src/reply-dispatch-driver.test.d.ts +2 -0
- package/dist/src/reply-dispatch-driver.test.d.ts.map +1 -0
- package/dist/src/reply-dispatch-driver.test.js +363 -0
- package/dist/src/reply-dispatch-driver.test.js.map +1 -0
- package/dist/src/resolve-inbound-group-prompt.d.ts +37 -0
- package/dist/src/resolve-inbound-group-prompt.d.ts.map +1 -0
- package/dist/src/resolve-inbound-group-prompt.js +57 -0
- package/dist/src/resolve-inbound-group-prompt.js.map +1 -0
- package/dist/src/resource-file.d.ts +119 -0
- package/dist/src/resource-file.d.ts.map +1 -0
- package/dist/src/resource-file.js +533 -0
- package/dist/src/resource-file.js.map +1 -0
- package/dist/src/resource-file.test.d.ts +2 -0
- package/dist/src/resource-file.test.d.ts.map +1 -0
- package/dist/src/resource-file.test.js +64 -0
- package/dist/src/resource-file.test.js.map +1 -0
- package/dist/src/run-model-context.d.ts +45 -0
- package/dist/src/run-model-context.d.ts.map +1 -0
- package/dist/src/run-model-context.js +108 -0
- package/dist/src/run-model-context.js.map +1 -0
- package/dist/src/run-model-context.test.d.ts +2 -0
- package/dist/src/run-model-context.test.d.ts.map +1 -0
- package/dist/src/run-model-context.test.js +68 -0
- package/dist/src/run-model-context.test.js.map +1 -0
- package/dist/src/run-usage-session.d.ts +13 -0
- package/dist/src/run-usage-session.d.ts.map +1 -0
- package/dist/src/run-usage-session.js +41 -0
- package/dist/src/run-usage-session.js.map +1 -0
- package/dist/src/run-usage.d.ts +67 -0
- package/dist/src/run-usage.d.ts.map +1 -0
- package/dist/src/run-usage.js +119 -0
- package/dist/src/run-usage.js.map +1 -0
- package/dist/src/run-usage.test.d.ts +2 -0
- package/dist/src/run-usage.test.d.ts.map +1 -0
- package/dist/src/run-usage.test.js +178 -0
- package/dist/src/run-usage.test.js.map +1 -0
- package/dist/src/send-file-event.d.ts +26 -0
- package/dist/src/send-file-event.d.ts.map +1 -0
- package/dist/src/send-file-event.js +33 -0
- package/dist/src/send-file-event.js.map +1 -0
- package/dist/src/send-file-event.test.d.ts +2 -0
- package/dist/src/send-file-event.test.d.ts.map +1 -0
- package/dist/src/send-file-event.test.js +86 -0
- package/dist/src/send-file-event.test.js.map +1 -0
- package/dist/src/send-file-tool.d.ts +81 -0
- package/dist/src/send-file-tool.d.ts.map +1 -0
- package/dist/src/send-file-tool.js +363 -0
- package/dist/src/send-file-tool.js.map +1 -0
- package/dist/src/send-file-tool.test.d.ts +2 -0
- package/dist/src/send-file-tool.test.d.ts.map +1 -0
- package/dist/src/send-file-tool.test.js +176 -0
- package/dist/src/send-file-tool.test.js.map +1 -0
- package/dist/src/send-group-message-tool.d.ts +17 -0
- package/dist/src/send-group-message-tool.d.ts.map +1 -0
- package/dist/src/send-group-message-tool.js +82 -0
- package/dist/src/send-group-message-tool.js.map +1 -0
- package/dist/src/send-service.d.ts +83 -0
- package/dist/src/send-service.d.ts.map +1 -0
- package/dist/src/send-service.js +324 -0
- package/dist/src/send-service.js.map +1 -0
- package/dist/src/send-service.test.d.ts +2 -0
- package/dist/src/send-service.test.d.ts.map +1 -0
- package/dist/src/send-service.test.js +40 -0
- package/dist/src/send-service.test.js.map +1 -0
- package/dist/src/session-env-store.d.ts +55 -0
- package/dist/src/session-env-store.d.ts.map +1 -0
- package/dist/src/session-env-store.js +328 -0
- package/dist/src/session-env-store.js.map +1 -0
- package/dist/src/session-env-store.test.d.ts +2 -0
- package/dist/src/session-env-store.test.d.ts.map +1 -0
- package/dist/src/session-env-store.test.js +151 -0
- package/dist/src/session-env-store.test.js.map +1 -0
- package/dist/src/session-group-prompt.d.ts +34 -0
- package/dist/src/session-group-prompt.d.ts.map +1 -0
- package/dist/src/session-group-prompt.js +101 -0
- package/dist/src/session-group-prompt.js.map +1 -0
- package/dist/src/session-group-prompt.test.d.ts +2 -0
- package/dist/src/session-group-prompt.test.d.ts.map +1 -0
- package/dist/src/session-group-prompt.test.js +72 -0
- package/dist/src/session-group-prompt.test.js.map +1 -0
- package/dist/src/session-im-context.d.ts +15 -0
- package/dist/src/session-im-context.d.ts.map +1 -0
- package/dist/src/session-im-context.js +54 -0
- package/dist/src/session-im-context.js.map +1 -0
- package/dist/src/session-model-fallback.d.ts +13 -0
- package/dist/src/session-model-fallback.d.ts.map +1 -0
- package/dist/src/session-model-fallback.js +24 -0
- package/dist/src/session-model-fallback.js.map +1 -0
- package/dist/src/subagent-monitor.d.ts +45 -0
- package/dist/src/subagent-monitor.d.ts.map +1 -0
- package/dist/src/subagent-monitor.js +498 -0
- package/dist/src/subagent-monitor.js.map +1 -0
- package/dist/src/subagent-monitor.test.d.ts +2 -0
- package/dist/src/subagent-monitor.test.d.ts.map +1 -0
- package/dist/src/subagent-monitor.test.js +335 -0
- package/dist/src/subagent-monitor.test.js.map +1 -0
- package/dist/src/sync-mapping-types.d.ts +220 -0
- package/dist/src/sync-mapping-types.d.ts.map +1 -0
- package/dist/src/sync-mapping-types.js +55 -0
- package/dist/src/sync-mapping-types.js.map +1 -0
- package/dist/src/sync-service-client.d.ts +29 -0
- package/dist/src/sync-service-client.d.ts.map +1 -0
- package/dist/src/sync-service-client.js +72 -0
- package/dist/src/sync-service-client.js.map +1 -0
- package/dist/src/thinking-ws-progress.d.ts +24 -0
- package/dist/src/thinking-ws-progress.d.ts.map +1 -0
- package/dist/src/thinking-ws-progress.js +45 -0
- package/dist/src/thinking-ws-progress.js.map +1 -0
- package/dist/src/thinking-ws-progress.test.d.ts +2 -0
- package/dist/src/thinking-ws-progress.test.d.ts.map +1 -0
- package/dist/src/thinking-ws-progress.test.js +38 -0
- package/dist/src/thinking-ws-progress.test.js.map +1 -0
- package/dist/src/tool-event-adapter.d.ts +31 -0
- package/dist/src/tool-event-adapter.d.ts.map +1 -0
- package/dist/src/tool-event-adapter.js +83 -0
- package/dist/src/tool-event-adapter.js.map +1 -0
- package/dist/src/tool-event-adapter.test.d.ts +2 -0
- package/dist/src/tool-event-adapter.test.d.ts.map +1 -0
- package/dist/src/tool-event-adapter.test.js +93 -0
- package/dist/src/tool-event-adapter.test.js.map +1 -0
- package/dist/src/tool-json-result.d.ts +14 -0
- package/dist/src/tool-json-result.d.ts.map +1 -0
- package/dist/src/tool-json-result.js +20 -0
- package/dist/src/tool-json-result.js.map +1 -0
- package/dist/src/turn-agent-event-subscription.d.ts +29 -0
- package/dist/src/turn-agent-event-subscription.d.ts.map +1 -0
- package/dist/src/turn-agent-event-subscription.js +289 -0
- package/dist/src/turn-agent-event-subscription.js.map +1 -0
- package/dist/src/turn-agent-event-subscription.test.d.ts +2 -0
- package/dist/src/turn-agent-event-subscription.test.d.ts.map +1 -0
- package/dist/src/turn-agent-event-subscription.test.js +165 -0
- package/dist/src/turn-agent-event-subscription.test.js.map +1 -0
- package/dist/src/turn-deliver-buffer.d.ts +60 -0
- package/dist/src/turn-deliver-buffer.d.ts.map +1 -0
- package/dist/src/turn-deliver-buffer.js +133 -0
- package/dist/src/turn-deliver-buffer.js.map +1 -0
- package/dist/src/turn-deliver-buffer.test.d.ts +2 -0
- package/dist/src/turn-deliver-buffer.test.d.ts.map +1 -0
- package/dist/src/turn-deliver-buffer.test.js +184 -0
- package/dist/src/turn-deliver-buffer.test.js.map +1 -0
- package/dist/src/turn-end-controller.d.ts +61 -0
- package/dist/src/turn-end-controller.d.ts.map +1 -0
- package/dist/src/turn-end-controller.js +239 -0
- package/dist/src/turn-end-controller.js.map +1 -0
- package/dist/src/turn-end-controller.test.d.ts +2 -0
- package/dist/src/turn-end-controller.test.d.ts.map +1 -0
- package/dist/src/turn-end-controller.test.js +97 -0
- package/dist/src/turn-end-controller.test.js.map +1 -0
- package/dist/src/types.d.ts +433 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +32 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/user-facing-errors.d.ts +32 -0
- package/dist/src/user-facing-errors.d.ts.map +1 -0
- package/dist/src/user-facing-errors.js +120 -0
- package/dist/src/user-facing-errors.js.map +1 -0
- package/dist/src/user-facing-errors.test.d.ts +2 -0
- package/dist/src/user-facing-errors.test.d.ts.map +1 -0
- package/dist/src/user-facing-errors.test.js +102 -0
- package/dist/src/user-facing-errors.test.js.map +1 -0
- package/dist/src/workspace-event-protocol.d.ts +3 -0
- package/dist/src/workspace-event-protocol.d.ts.map +1 -0
- package/dist/src/workspace-event-protocol.js +3 -0
- package/dist/src/workspace-event-protocol.js.map +1 -0
- package/dist/src/workspace-event-scheduler.d.ts +54 -0
- package/dist/src/workspace-event-scheduler.d.ts.map +1 -0
- package/dist/src/workspace-event-scheduler.js +131 -0
- package/dist/src/workspace-event-scheduler.js.map +1 -0
- package/dist/src/workspace-event-scheduler.test.d.ts +2 -0
- package/dist/src/workspace-event-scheduler.test.d.ts.map +1 -0
- package/dist/src/workspace-event-scheduler.test.js +157 -0
- package/dist/src/workspace-event-scheduler.test.js.map +1 -0
- package/dist/src/workspace-event.d.ts +28 -0
- package/dist/src/workspace-event.d.ts.map +1 -0
- package/dist/src/workspace-event.js +674 -0
- package/dist/src/workspace-event.js.map +1 -0
- package/dist/src/workspace-event.test.d.ts +2 -0
- package/dist/src/workspace-event.test.d.ts.map +1 -0
- package/dist/src/workspace-event.test.js +265 -0
- package/dist/src/workspace-event.test.js.map +1 -0
- package/dist/src/ws-inbound-schema.d.ts +14 -0
- package/dist/src/ws-inbound-schema.d.ts.map +1 -0
- package/dist/src/ws-inbound-schema.js +68 -0
- package/dist/src/ws-inbound-schema.js.map +1 -0
- package/dist/src/ws-inbound-schema.test.d.ts +2 -0
- package/dist/src/ws-inbound-schema.test.d.ts.map +1 -0
- package/dist/src/ws-inbound-schema.test.js +58 -0
- package/dist/src/ws-inbound-schema.test.js.map +1 -0
- package/dist/src/ws-run-event-unmapped.d.ts +10 -0
- package/dist/src/ws-run-event-unmapped.d.ts.map +1 -0
- package/dist/src/ws-run-event-unmapped.js +16 -0
- package/dist/src/ws-run-event-unmapped.js.map +1 -0
- package/dist/src/ws-run-event-unmapped.test.d.ts +2 -0
- package/dist/src/ws-run-event-unmapped.test.d.ts.map +1 -0
- package/dist/src/ws-run-event-unmapped.test.js +15 -0
- package/dist/src/ws-run-event-unmapped.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 一轮 dispatch 内的 assistant 正文段缓冲:
|
|
3
|
+
* - 同段修稿(新文延展/包住旧文)→ 覆盖
|
|
4
|
+
* - 流式分块新段 → 追加合并
|
|
5
|
+
* 在 tool 边界或轮次结束冲刷 HTTP。
|
|
6
|
+
*/
|
|
7
|
+
import { normalizeDeliverComparableText } from "./deliver-text.js";
|
|
8
|
+
/** deliver 正文/附件是否值得写入 buffer 或立即 HTTP。 */
|
|
9
|
+
export function isDeliverPayloadSendable(args) {
|
|
10
|
+
return Boolean(args.textPart) || (args.hasMedia && !args.isThinking);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 新文是否像对旧文的「修稿/延展」(可安全覆盖),而非另一完整分块。
|
|
14
|
+
* 无权威 OpenClaw 标记,偏保守:宁可追加重复,不可覆盖丢段。
|
|
15
|
+
*/
|
|
16
|
+
export function isDeliverTextRevision(oldText, newText) {
|
|
17
|
+
const oldN = normalizeDeliverComparableText(oldText);
|
|
18
|
+
const newN = normalizeDeliverComparableText(newText);
|
|
19
|
+
if (!oldN)
|
|
20
|
+
return true;
|
|
21
|
+
if (!newN)
|
|
22
|
+
return true;
|
|
23
|
+
if (oldN === newN)
|
|
24
|
+
return true;
|
|
25
|
+
if (newN.startsWith(oldN) || newN.includes(oldN))
|
|
26
|
+
return true;
|
|
27
|
+
if (oldN.startsWith(newN))
|
|
28
|
+
return true;
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 段边界 / 轮末 flush 时,判断是否可用 `onPartialReply` 全量快照覆盖 deliver 拼接文本。
|
|
33
|
+
* 仅当快照(归一化后)与缓冲文本相等或为其超集时才覆盖,避免流式竞态下快照落后导致截断丢内容。
|
|
34
|
+
*/
|
|
35
|
+
export function snapshotSupersedesBufferText(snapshot, bufferText) {
|
|
36
|
+
const ns = normalizeDeliverComparableText(snapshot);
|
|
37
|
+
const nb = normalizeDeliverComparableText(bufferText);
|
|
38
|
+
if (!ns)
|
|
39
|
+
return false;
|
|
40
|
+
if (!nb)
|
|
41
|
+
return true;
|
|
42
|
+
return ns === nb || ns.includes(nb);
|
|
43
|
+
}
|
|
44
|
+
function mergeAppendedEntry(prev, next) {
|
|
45
|
+
const textPart = `${prev.rawTextPart}${next.rawTextPart}`;
|
|
46
|
+
const hasMedia = prev.hasMedia || next.hasMedia;
|
|
47
|
+
const payload = {
|
|
48
|
+
...prev.payload,
|
|
49
|
+
...next.payload,
|
|
50
|
+
text: textPart,
|
|
51
|
+
};
|
|
52
|
+
if (prev.payload.markdown != null || next.payload.markdown != null) {
|
|
53
|
+
payload.markdown = textPart;
|
|
54
|
+
}
|
|
55
|
+
if (!next.hasMedia && prev.hasMedia) {
|
|
56
|
+
if (prev.payload.mediaUrl != null)
|
|
57
|
+
payload.mediaUrl = prev.payload.mediaUrl;
|
|
58
|
+
if (prev.payload.mediaUrls != null)
|
|
59
|
+
payload.mediaUrls = prev.payload.mediaUrls;
|
|
60
|
+
}
|
|
61
|
+
const rawTextPart = `${prev.rawTextPart}${next.rawTextPart}`;
|
|
62
|
+
return { payload, textPart, rawTextPart, hasMedia };
|
|
63
|
+
}
|
|
64
|
+
export class TurnDeliverBuffer {
|
|
65
|
+
buffer;
|
|
66
|
+
lastFlushedComparable = "";
|
|
67
|
+
stats = {
|
|
68
|
+
writeCount: 0,
|
|
69
|
+
revisionOverwriteCount: 0,
|
|
70
|
+
segmentAppendCount: 0,
|
|
71
|
+
flushInterimCount: 0,
|
|
72
|
+
flushFinalCount: 0,
|
|
73
|
+
skippedDuplicateFlushCount: 0,
|
|
74
|
+
};
|
|
75
|
+
hasContent() {
|
|
76
|
+
return this.buffer !== undefined;
|
|
77
|
+
}
|
|
78
|
+
getStats() {
|
|
79
|
+
return { ...this.stats };
|
|
80
|
+
}
|
|
81
|
+
write(entry) {
|
|
82
|
+
this.stats.writeCount++;
|
|
83
|
+
if (!this.buffer) {
|
|
84
|
+
this.buffer = entry;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (isDeliverTextRevision(this.buffer.textPart, entry.textPart)) {
|
|
88
|
+
this.stats.revisionOverwriteCount++;
|
|
89
|
+
this.buffer = entry;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.stats.segmentAppendCount++;
|
|
93
|
+
this.buffer = mergeAppendedEntry(this.buffer, entry);
|
|
94
|
+
}
|
|
95
|
+
takeForFlush(kind) {
|
|
96
|
+
if (!this.buffer) {
|
|
97
|
+
return { status: "empty" };
|
|
98
|
+
}
|
|
99
|
+
const comparable = buildFlushComparable(this.buffer);
|
|
100
|
+
const entry = this.buffer;
|
|
101
|
+
// 仅抑制「纯文重复」;带附件的 flush 必须发出(interim 纯文 → final 文+附件)。
|
|
102
|
+
if (comparable.length > 0 &&
|
|
103
|
+
comparable === this.lastFlushedComparable &&
|
|
104
|
+
!entry.hasMedia) {
|
|
105
|
+
this.stats.skippedDuplicateFlushCount++;
|
|
106
|
+
this.clear();
|
|
107
|
+
return { status: "skipped_duplicate", entry };
|
|
108
|
+
}
|
|
109
|
+
this.clear();
|
|
110
|
+
if (kind === "interim") {
|
|
111
|
+
this.stats.flushInterimCount++;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this.stats.flushFinalCount++;
|
|
115
|
+
}
|
|
116
|
+
if (comparable.length > 0) {
|
|
117
|
+
this.lastFlushedComparable = comparable;
|
|
118
|
+
}
|
|
119
|
+
return { status: "ready", entry };
|
|
120
|
+
}
|
|
121
|
+
clear() {
|
|
122
|
+
this.buffer = undefined;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function buildFlushComparable(entry) {
|
|
126
|
+
const text = normalizeDeliverComparableText(entry.textPart);
|
|
127
|
+
if (text)
|
|
128
|
+
return text;
|
|
129
|
+
if (entry.hasMedia)
|
|
130
|
+
return "[media-only]";
|
|
131
|
+
return "";
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=turn-deliver-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-deliver-buffer.js","sourceRoot":"","sources":["../../src/turn-deliver-buffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-deliver-buffer.test.d.ts","sourceRoot":"","sources":["../../src/turn-deliver-buffer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { isDeliverPayloadSendable, isDeliverTextRevision, snapshotSupersedesBufferText, TurnDeliverBuffer, } from "./turn-deliver-buffer.js";
|
|
4
|
+
const HOUTONG_BODY_LOOSE = `确实是这个问题:昨天那版虽然用了内嵌 SVG,但你现在的文档预览器没有把 SVG 正常渲染出来,所以流程看不到。
|
|
5
|
+
|
|
6
|
+
我已经重新生成了一版**纯 Markdown 可读版**:
|
|
7
|
+
|
|
8
|
+
- 不用 SVG
|
|
9
|
+
新文件:
|
|
10
|
+
|
|
11
|
+
-----`;
|
|
12
|
+
const HOUTONG_BODY_TIGHT = `确实是这个问题:昨天那版虽然用了内嵌 SVG,但你现在的文档预览器没有把 SVG 正常渲染出来,所以流程看不到。
|
|
13
|
+
我已经重新生成了一版**纯 Markdown 可读版**:
|
|
14
|
+
- 不用 SVG
|
|
15
|
+
新文件:`;
|
|
16
|
+
const WORLD_CUP_PARTIAL = `| 场次 | 时间 |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| 1 | 21:00 |
|
|
19
|
+
| 2 |`;
|
|
20
|
+
const WORLD_CUP_FULL = `| 场次 | 时间 |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| 1 | 21:00 |
|
|
23
|
+
| 2 | 00:00 |
|
|
24
|
+
| 3 | 03:00 |`;
|
|
25
|
+
const RT002_PART1 = `BEGIN_123
|
|
26
|
+
|
|
27
|
+
## 一、背景
|
|
28
|
+
|
|
29
|
+
随着人工智能技术的快速发展,企业级AI助手在提升工作效率中发挥着日益重要的作用。`;
|
|
30
|
+
const RT002_PART2 = `- 工具调用的完整日志必须被记录,包括调用时间、调用者、工具名称。
|
|
31
|
+
|
|
32
|
+
## 六、审计
|
|
33
|
+
|
|
34
|
+
审计是AI助手治理的监督机制。`;
|
|
35
|
+
function entry(textPart, hasMedia = false) {
|
|
36
|
+
return {
|
|
37
|
+
payload: { text: textPart, ...(hasMedia ? { mediaUrl: "/tmp/a.md" } : {}) },
|
|
38
|
+
textPart,
|
|
39
|
+
rawTextPart: textPart,
|
|
40
|
+
hasMedia,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
describe("isDeliverPayloadSendable", () => {
|
|
44
|
+
it("accepts text or non-thinking media", () => {
|
|
45
|
+
assert.equal(isDeliverPayloadSendable({ textPart: "hi", hasMedia: false }), true);
|
|
46
|
+
assert.equal(isDeliverPayloadSendable({ textPart: "", hasMedia: true }), true);
|
|
47
|
+
assert.equal(isDeliverPayloadSendable({ textPart: "", hasMedia: true, isThinking: true }), false);
|
|
48
|
+
assert.equal(isDeliverPayloadSendable({ textPart: "", hasMedia: false }), false);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe("isDeliverTextRevision", () => {
|
|
52
|
+
it("treats growth / containment as revision", () => {
|
|
53
|
+
assert.equal(isDeliverTextRevision(WORLD_CUP_PARTIAL, WORLD_CUP_FULL), true);
|
|
54
|
+
assert.equal(isDeliverTextRevision("abc", "abcdef"), true);
|
|
55
|
+
assert.equal(isDeliverTextRevision("abcdef", "abc"), true);
|
|
56
|
+
});
|
|
57
|
+
it("treats disjoint later chunk as not revision", () => {
|
|
58
|
+
assert.equal(isDeliverTextRevision(RT002_PART1, RT002_PART2), false);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe("snapshotSupersedesBufferText", () => {
|
|
62
|
+
it("allows override when snapshot equals buffer after normalization", () => {
|
|
63
|
+
// buffer 用 \n\n 连接分块,snapshot 为连续段落(单 \n)→ 归一化后相等
|
|
64
|
+
const buffer = "第一段\n\n第二段";
|
|
65
|
+
const snapshot = "第一段\n第二段";
|
|
66
|
+
assert.equal(snapshotSupersedesBufferText(snapshot, buffer), true);
|
|
67
|
+
});
|
|
68
|
+
it("allows override when snapshot is a superset (full > chunk)", () => {
|
|
69
|
+
assert.equal(snapshotSupersedesBufferText(WORLD_CUP_FULL, WORLD_CUP_PARTIAL), true);
|
|
70
|
+
});
|
|
71
|
+
it("refuses override when snapshot lags behind buffer (would truncate)", () => {
|
|
72
|
+
// 竞态:快照还没追上 deliver 的完整块 → 不能覆盖,否则截断丢内容
|
|
73
|
+
assert.equal(snapshotSupersedesBufferText(WORLD_CUP_PARTIAL, WORLD_CUP_FULL), false);
|
|
74
|
+
});
|
|
75
|
+
it("empty snapshot never supersedes; empty buffer always superseded", () => {
|
|
76
|
+
assert.equal(snapshotSupersedesBufferText("", "abc"), false);
|
|
77
|
+
assert.equal(snapshotSupersedesBufferText("abc", ""), true);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe("TurnDeliverBuffer", () => {
|
|
81
|
+
it("revision overwrite keeps last version (and media)", () => {
|
|
82
|
+
const buf = new TurnDeliverBuffer();
|
|
83
|
+
buf.write(entry(HOUTONG_BODY_LOOSE));
|
|
84
|
+
buf.write(entry(HOUTONG_BODY_TIGHT));
|
|
85
|
+
buf.write(entry(HOUTONG_BODY_TIGHT, true));
|
|
86
|
+
const final = buf.takeForFlush("final");
|
|
87
|
+
assert.equal(final.status, "ready");
|
|
88
|
+
if (final.status === "ready") {
|
|
89
|
+
assert.equal(final.entry.textPart, HOUTONG_BODY_TIGHT);
|
|
90
|
+
assert.equal(final.entry.hasMedia, true);
|
|
91
|
+
}
|
|
92
|
+
assert.equal(buf.getStats().writeCount, 3);
|
|
93
|
+
assert.ok(buf.getStats().revisionOverwriteCount >= 1);
|
|
94
|
+
assert.equal(buf.getStats().flushFinalCount, 1);
|
|
95
|
+
});
|
|
96
|
+
it("appends additive stream chunks so BEGIN is not lost", () => {
|
|
97
|
+
const buf = new TurnDeliverBuffer();
|
|
98
|
+
buf.write(entry(RT002_PART1));
|
|
99
|
+
buf.write(entry(RT002_PART2));
|
|
100
|
+
const final = buf.takeForFlush("final");
|
|
101
|
+
assert.equal(final.status, "ready");
|
|
102
|
+
if (final.status === "ready") {
|
|
103
|
+
assert.ok(final.entry.textPart.includes("BEGIN_123"));
|
|
104
|
+
assert.ok(final.entry.textPart.includes("## 六、审计"));
|
|
105
|
+
assert.ok(final.entry.textPart.includes(RT002_PART1.trim()));
|
|
106
|
+
assert.ok(final.entry.textPart.includes(RT002_PART2.trim()));
|
|
107
|
+
}
|
|
108
|
+
assert.equal(buf.getStats().segmentAppendCount, 1);
|
|
109
|
+
assert.equal(buf.getStats().revisionOverwriteCount, 0);
|
|
110
|
+
});
|
|
111
|
+
it("interim flush clears buffer; final holds post-tool segment", () => {
|
|
112
|
+
const buf = new TurnDeliverBuffer();
|
|
113
|
+
buf.write(entry("先说明"));
|
|
114
|
+
const interim = buf.takeForFlush("interim");
|
|
115
|
+
assert.equal(interim.status, "ready");
|
|
116
|
+
buf.write(entry("最终结论"));
|
|
117
|
+
const final = buf.takeForFlush("final");
|
|
118
|
+
assert.equal(final.status, "ready");
|
|
119
|
+
if (final.status === "ready") {
|
|
120
|
+
assert.equal(final.entry.textPart, "最终结论");
|
|
121
|
+
}
|
|
122
|
+
assert.equal(buf.getStats().flushInterimCount, 1);
|
|
123
|
+
assert.equal(buf.getStats().flushFinalCount, 1);
|
|
124
|
+
});
|
|
125
|
+
it("skips final flush when comparable matches last interim (text-only)", () => {
|
|
126
|
+
const buf = new TurnDeliverBuffer();
|
|
127
|
+
buf.write(entry("正在查询…"));
|
|
128
|
+
assert.equal(buf.takeForFlush("interim").status, "ready");
|
|
129
|
+
buf.write(entry("正在查询…"));
|
|
130
|
+
assert.equal(buf.takeForFlush("final").status, "skipped_duplicate");
|
|
131
|
+
assert.equal(buf.getStats().skippedDuplicateFlushCount, 1);
|
|
132
|
+
assert.equal(buf.getStats().flushFinalCount, 0);
|
|
133
|
+
const dup = buf.takeForFlush("final");
|
|
134
|
+
assert.equal(dup.status, "empty");
|
|
135
|
+
});
|
|
136
|
+
it("skipped_duplicate still exposes entry for callers", () => {
|
|
137
|
+
const buf = new TurnDeliverBuffer();
|
|
138
|
+
buf.write(entry("说明文字"));
|
|
139
|
+
assert.equal(buf.takeForFlush("interim").status, "ready");
|
|
140
|
+
const withNoise = "说明文字\n\n_🟡 ↑111k ↓164 · 63%ctx · openai/gpt-5.5_";
|
|
141
|
+
buf.write(entry(withNoise));
|
|
142
|
+
const skipped = buf.takeForFlush("final");
|
|
143
|
+
assert.equal(skipped.status, "skipped_duplicate");
|
|
144
|
+
if (skipped.status === "skipped_duplicate") {
|
|
145
|
+
assert.equal(skipped.entry.textPart, withNoise);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
it("does not skip final when same text gains attachment after interim", () => {
|
|
149
|
+
const buf = new TurnDeliverBuffer();
|
|
150
|
+
buf.write(entry("说明文字"));
|
|
151
|
+
assert.equal(buf.takeForFlush("interim").status, "ready");
|
|
152
|
+
buf.write(entry("说明文字", true));
|
|
153
|
+
const final = buf.takeForFlush("final");
|
|
154
|
+
assert.equal(final.status, "ready");
|
|
155
|
+
if (final.status === "ready") {
|
|
156
|
+
assert.equal(final.entry.hasMedia, true);
|
|
157
|
+
assert.equal(final.entry.textPart, "说明文字");
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
it("world cup table revision: only full table in final flush", () => {
|
|
161
|
+
const buf = new TurnDeliverBuffer();
|
|
162
|
+
buf.write(entry(WORLD_CUP_PARTIAL));
|
|
163
|
+
buf.write(entry(WORLD_CUP_FULL));
|
|
164
|
+
const final = buf.takeForFlush("final");
|
|
165
|
+
assert.equal(final.status, "ready");
|
|
166
|
+
if (final.status === "ready") {
|
|
167
|
+
assert.equal(final.entry.textPart, WORLD_CUP_FULL);
|
|
168
|
+
}
|
|
169
|
+
assert.equal(buf.getStats().revisionOverwriteCount, 1);
|
|
170
|
+
assert.equal(buf.getStats().segmentAppendCount, 0);
|
|
171
|
+
});
|
|
172
|
+
it("multi-tool: two interim + one final", () => {
|
|
173
|
+
const buf = new TurnDeliverBuffer();
|
|
174
|
+
buf.write(entry("段1"));
|
|
175
|
+
assert.equal(buf.takeForFlush("interim").status, "ready");
|
|
176
|
+
buf.write(entry("段2"));
|
|
177
|
+
assert.equal(buf.takeForFlush("interim").status, "ready");
|
|
178
|
+
buf.write(entry("结论"));
|
|
179
|
+
assert.equal(buf.takeForFlush("final").status, "ready");
|
|
180
|
+
assert.equal(buf.getStats().flushInterimCount, 2);
|
|
181
|
+
assert.equal(buf.getStats().flushFinalCount, 1);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
//# sourceMappingURL=turn-deliver-buffer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-deliver-buffer.test.js","sourceRoot":"","sources":["../../src/turn-deliver-buffer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 整轮(user-turn)结束仲裁。
|
|
3
|
+
*
|
|
4
|
+
* OpenClaw 7.1+ / 8.x(lifecycle 语义一致;245 实测为 2026.7.1-2):父会话(主会话)
|
|
5
|
+
* 自己的 finish 就是它某段 run 的 lifecycle `end/error` 终态且 `yielded !== true`
|
|
6
|
+
* (`yielded:true` 只出现在该段挂起了子任务、会话被挂起等待 resume 时——核心据此把
|
|
7
|
+
* requester 保留为可唤醒)。因此:
|
|
8
|
+
* - 「yield 段终态」≠ 整轮结束(主会话还会 resume 继续派发/产出最终答复);
|
|
9
|
+
* - 「非 yield 段终态」= 主会话 finish:该段不会再挂起子任务、不会再被唤醒。
|
|
10
|
+
*
|
|
11
|
+
* 收尾条件(防御性补强,主判据仍是主会话的非 yield finish):
|
|
12
|
+
* dispatch 已返回 ∧ 无段在跑(segmentActive=false,避免拿旧段终态收尾)
|
|
13
|
+
* ∧ 无运行中子任务(兜非标准边界:异常/乱序下非 yield 终态先于子任务结束到达)
|
|
14
|
+
* ∧ 已出现非 yield 段终态。
|
|
15
|
+
*
|
|
16
|
+
* 本模块只维护进程级共享的每轮状态与「可收尾」信号,不持有任何 WS/HTTP 副作用:
|
|
17
|
+
* - wrapper finally、subagent spawn/end、lifecycle start/end、以及组内活动心跳都来喂状态;
|
|
18
|
+
* - dispatch-mentioned-reply 在 wrapper 里 await 本模块的可收尾信号后再发 RUN_USAGE/FINISHED;
|
|
19
|
+
* - 子任务完成但主会话无法被唤醒(announce/handoff 投递,不再产生 resume 终态)、
|
|
20
|
+
* 或 lifecycle 事件完全不可达(订阅不可用等环境)时,靠静默兜底定时器收尾,保证不悬挂。
|
|
21
|
+
*/
|
|
22
|
+
export interface TurnSegmentTerminalInfo {
|
|
23
|
+
phase: "end" | "error";
|
|
24
|
+
yielded?: boolean;
|
|
25
|
+
stopReason?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function turnOnDispatchReturned(roundKey: string, gen: number): void;
|
|
28
|
+
/** index.ts `subagent_spawned`:记录本轮见过子任务并 +1 活跃数。 */
|
|
29
|
+
export declare function turnOnSubagentSpawn(roundKey: string, gen: number): void;
|
|
30
|
+
/** index.ts `subagent_ended` / monitor settle:活跃子任务数 -1 并重新评估。 */
|
|
31
|
+
export declare function turnOnSubagentEnded(roundKey: string, gen: number): void;
|
|
32
|
+
/**
|
|
33
|
+
* 监控层对账:本轮全部已知子任务完成(settle 触发)。与 subagent_ended 事件互补,
|
|
34
|
+
* 覆盖个别 ended 事件丢失导致计数器不为 0、从而永远等不到收尾信号的情况。
|
|
35
|
+
*/
|
|
36
|
+
export declare function turnOnAllChildrenDone(roundKey: string, gen: number): void;
|
|
37
|
+
/** lifecycle start(父会话新段开始):清掉旧终态,等待该段终态。 */
|
|
38
|
+
export declare function turnOnSegmentStart(roundKey: string, gen: number): void;
|
|
39
|
+
/** lifecycle end/error(父会话某段结束):记录是否 yield 后评估。 */
|
|
40
|
+
export declare function turnOnSegmentEnd(roundKey: string, gen: number, info: TurnSegmentTerminalInfo): void;
|
|
41
|
+
/**
|
|
42
|
+
* 组内活动心跳(before_tool_call / thinking / assistant 等属于本轮的其它事件):
|
|
43
|
+
* 说明父会话仍在工作,取消静默收尾计时,但不算“段已结束”。
|
|
44
|
+
*/
|
|
45
|
+
export declare function turnOnActivity(roundKey: string, gen: number): void;
|
|
46
|
+
/** wrapper 侧首次建轮后登记状态;sawSubagent 由后续 spawn 事件置位。 */
|
|
47
|
+
export declare function turnEnsureRound(roundKey: string, gen: number): void;
|
|
48
|
+
export declare function turnIsSawSubagent(roundKey: string, gen: number): boolean;
|
|
49
|
+
export declare function turnIsEligible(roundKey: string, gen: number): boolean;
|
|
50
|
+
/** 收尾完成 / 中断 / 插件卸载后清理。 */
|
|
51
|
+
export declare function turnForget(roundKey: string, gen: number): void;
|
|
52
|
+
/** 插件卸载时清理全部轮次状态。 */
|
|
53
|
+
export declare function disposeTurnEndController(): void;
|
|
54
|
+
/** 单测辅助。 */
|
|
55
|
+
export declare function __resetTurnEndControllerForTests(): void;
|
|
56
|
+
/** 单测辅助:缩短各计时窗口,避免真实等待。 */
|
|
57
|
+
export declare function __configureTurnEndForTests(overrides: {
|
|
58
|
+
nonYieldDebounceMs?: number;
|
|
59
|
+
noLifecycleFallbackMs?: number;
|
|
60
|
+
}): void;
|
|
61
|
+
//# sourceMappingURL=turn-end-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-end-controller.d.ts","sourceRoot":"","sources":["../../src/turn-end-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,MAAM,WAAW,uBAAuB;IACpC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AA2GD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAQ1E;AAED,qDAAqD;AACrD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAUvE;AAED,kEAAkE;AAClE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAQvE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAQzE;AAED,6CAA6C;AAC7C,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAWtE;AAED,mDAAmD;AACnD,wBAAgB,gBAAgB,CAC5B,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,uBAAuB,GAC9B,IAAI,CAYN;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAUlE;AAED,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAiBnE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAExE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAErE;AAED,2BAA2B;AAC3B,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAM9D;AAED,qBAAqB;AACrB,wBAAgB,wBAAwB,IAAI,IAAI,CAK/C;AAED,YAAY;AACZ,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD;AAED,2BAA2B;AAC3B,wBAAgB,0BAA0B,CAAC,SAAS,EAAE;IAClD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAClC,GAAG,IAAI,CAGP"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 整轮(user-turn)结束仲裁。
|
|
3
|
+
*
|
|
4
|
+
* OpenClaw 7.1+ / 8.x(lifecycle 语义一致;245 实测为 2026.7.1-2):父会话(主会话)
|
|
5
|
+
* 自己的 finish 就是它某段 run 的 lifecycle `end/error` 终态且 `yielded !== true`
|
|
6
|
+
* (`yielded:true` 只出现在该段挂起了子任务、会话被挂起等待 resume 时——核心据此把
|
|
7
|
+
* requester 保留为可唤醒)。因此:
|
|
8
|
+
* - 「yield 段终态」≠ 整轮结束(主会话还会 resume 继续派发/产出最终答复);
|
|
9
|
+
* - 「非 yield 段终态」= 主会话 finish:该段不会再挂起子任务、不会再被唤醒。
|
|
10
|
+
*
|
|
11
|
+
* 收尾条件(防御性补强,主判据仍是主会话的非 yield finish):
|
|
12
|
+
* dispatch 已返回 ∧ 无段在跑(segmentActive=false,避免拿旧段终态收尾)
|
|
13
|
+
* ∧ 无运行中子任务(兜非标准边界:异常/乱序下非 yield 终态先于子任务结束到达)
|
|
14
|
+
* ∧ 已出现非 yield 段终态。
|
|
15
|
+
*
|
|
16
|
+
* 本模块只维护进程级共享的每轮状态与「可收尾」信号,不持有任何 WS/HTTP 副作用:
|
|
17
|
+
* - wrapper finally、subagent spawn/end、lifecycle start/end、以及组内活动心跳都来喂状态;
|
|
18
|
+
* - dispatch-mentioned-reply 在 wrapper 里 await 本模块的可收尾信号后再发 RUN_USAGE/FINISHED;
|
|
19
|
+
* - 子任务完成但主会话无法被唤醒(announce/handoff 投递,不再产生 resume 终态)、
|
|
20
|
+
* 或 lifecycle 事件完全不可达(订阅不可用等环境)时,靠静默兜底定时器收尾,保证不悬挂。
|
|
21
|
+
*/
|
|
22
|
+
import { getSharedMap } from "./process-shared-store.js";
|
|
23
|
+
/** 非 yield 终态到达后、置可收尾前的防抖(吞掉与 resume 的竞态)。 */
|
|
24
|
+
let NON_YIELD_DEBOUNCE_MS = 1_500;
|
|
25
|
+
/** 完全没有 lifecycle 事件(订阅不可用)时的兜底窗口。 */
|
|
26
|
+
let NO_LIFECYCLE_FALLBACK_MS = 30_000;
|
|
27
|
+
const states = getSharedMap("turn-end-states");
|
|
28
|
+
const DIAG = "[xg_cwork_im] [turn-diag]";
|
|
29
|
+
function stateOf(roundKey, gen) {
|
|
30
|
+
const s = states.get(roundKey);
|
|
31
|
+
if (!s || s.gen !== gen)
|
|
32
|
+
return undefined;
|
|
33
|
+
return s;
|
|
34
|
+
}
|
|
35
|
+
function clearTimer(s) {
|
|
36
|
+
if (s.timer !== undefined) {
|
|
37
|
+
clearTimeout(s.timer);
|
|
38
|
+
s.timer = undefined;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function isQuiescent(s) {
|
|
42
|
+
return s.dispatchReturned && !s.segmentActive && s.activeChildren <= 0;
|
|
43
|
+
}
|
|
44
|
+
/** 防抖置位:静默窗口内无新事件才真正 eligible(避免与 resume 的毫秒级竞态)。 */
|
|
45
|
+
function setEligible(roundKey, gen, s, reason) {
|
|
46
|
+
clearTimer(s);
|
|
47
|
+
s.timer = setTimeout(() => {
|
|
48
|
+
s.timer = undefined;
|
|
49
|
+
const cur = stateOf(roundKey, gen);
|
|
50
|
+
if (!cur)
|
|
51
|
+
return;
|
|
52
|
+
if (isQuiescent(cur) && !cur.eligible) {
|
|
53
|
+
cur.eligible = true;
|
|
54
|
+
console.log(`${DIAG} eligible round=${roundKey}#${gen} reason=${reason} ` +
|
|
55
|
+
`children=${cur.activeChildren} segActive=${cur.segmentActive} ` +
|
|
56
|
+
`lifecycleSeen=${cur.lifecycleSeen}`);
|
|
57
|
+
}
|
|
58
|
+
}, NON_YIELD_DEBOUNCE_MS);
|
|
59
|
+
s.timer.unref?.();
|
|
60
|
+
}
|
|
61
|
+
function armTimer(roundKey, s, delayMs, reason) {
|
|
62
|
+
if (s.timer !== undefined)
|
|
63
|
+
return;
|
|
64
|
+
console.log(`${DIAG} fallback arm round=${roundKey}#${s.gen} reason=${reason} delayMs=${delayMs} ` +
|
|
65
|
+
`children=${s.activeChildren} segActive=${s.segmentActive}`);
|
|
66
|
+
s.timer = setTimeout(() => {
|
|
67
|
+
s.timer = undefined;
|
|
68
|
+
const cur = stateOf(roundKey, s.gen);
|
|
69
|
+
if (!cur)
|
|
70
|
+
return;
|
|
71
|
+
if (isQuiescent(cur) && !cur.eligible) {
|
|
72
|
+
cur.eligible = true;
|
|
73
|
+
console.log(`${DIAG} eligible round=${roundKey}#${s.gen} reason=fallback:${reason} ` +
|
|
74
|
+
`children=${cur.activeChildren} segActive=${cur.segmentActive}`);
|
|
75
|
+
}
|
|
76
|
+
}, delayMs);
|
|
77
|
+
s.timer.unref?.();
|
|
78
|
+
}
|
|
79
|
+
/** 任一事件后统一评估:满足「已非段中、无子任务、dispatch 已返回」时决定防抖收尾或等待。 */
|
|
80
|
+
function reevaluate(roundKey, s) {
|
|
81
|
+
if (!s.dispatchReturned)
|
|
82
|
+
return;
|
|
83
|
+
if (!isQuiescent(s)) {
|
|
84
|
+
// 还有段在跑 / 还有子任务:绝不收尾,也不保留旧的可收尾状态。
|
|
85
|
+
s.eligible = false;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (s.lifecycleSeen && s.lastEnd) {
|
|
89
|
+
if (s.lastEnd.yielded !== true) {
|
|
90
|
+
// 主会话 finish:最新一段父 run 是非 yield 终态 → 不会再 resume → 防抖后收尾。
|
|
91
|
+
setEligible(roundKey, s.gen, s, "non-yield-end");
|
|
92
|
+
}
|
|
93
|
+
// 段以 yield 结束:父会话因派发子任务被挂起,等待 core 把子任务完成结果 announce
|
|
94
|
+
// 回父会话(resume)。该投递时延不受控(实测可到分钟级、与子任务时长无关),
|
|
95
|
+
// 绝不能靠“N 秒没 resume 就收尾”的死窗口提前 FINISHED——那会拆除 round,使同轮
|
|
96
|
+
// 之后新派发的子任务对不上 round、丢 SUBAGENT_STAT。这里不做任何事:
|
|
97
|
+
// - resume 到来 → turnOnSegmentStart 取消旧状态并重新按新段终态评估;
|
|
98
|
+
// - 父会话确实永不被唤醒的极端场景 → 由 dispatch wrapper 的 30 分钟上限兜底。
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// 完全没见到 lifecycle(订阅不可用等):纯兜底窗口收尾,防悬挂。
|
|
102
|
+
armTimer(roundKey, s, NO_LIFECYCLE_FALLBACK_MS, "no-lifecycle-seen");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export function turnOnDispatchReturned(roundKey, gen) {
|
|
106
|
+
const s = stateOf(roundKey, gen);
|
|
107
|
+
if (!s)
|
|
108
|
+
return;
|
|
109
|
+
s.dispatchReturned = true;
|
|
110
|
+
console.log(`${DIAG} dispatchReturned round=${roundKey}#${gen} children=${s.activeChildren} segActive=${s.segmentActive}`);
|
|
111
|
+
reevaluate(roundKey, s);
|
|
112
|
+
}
|
|
113
|
+
/** index.ts `subagent_spawned`:记录本轮见过子任务并 +1 活跃数。 */
|
|
114
|
+
export function turnOnSubagentSpawn(roundKey, gen) {
|
|
115
|
+
const s = stateOf(roundKey, gen);
|
|
116
|
+
if (!s)
|
|
117
|
+
return;
|
|
118
|
+
s.sawSubagent = true;
|
|
119
|
+
s.activeChildren += 1;
|
|
120
|
+
clearTimer(s);
|
|
121
|
+
s.eligible = false;
|
|
122
|
+
console.log(`${DIAG} spawn round=${roundKey}#${gen} activeChildren=${s.activeChildren} sawSubagent=${s.sawSubagent}`);
|
|
123
|
+
}
|
|
124
|
+
/** index.ts `subagent_ended` / monitor settle:活跃子任务数 -1 并重新评估。 */
|
|
125
|
+
export function turnOnSubagentEnded(roundKey, gen) {
|
|
126
|
+
const s = stateOf(roundKey, gen);
|
|
127
|
+
if (!s)
|
|
128
|
+
return;
|
|
129
|
+
if (s.activeChildren > 0)
|
|
130
|
+
s.activeChildren -= 1;
|
|
131
|
+
console.log(`${DIAG} childEnded round=${roundKey}#${gen} activeChildren=${s.activeChildren}`);
|
|
132
|
+
reevaluate(roundKey, s);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 监控层对账:本轮全部已知子任务完成(settle 触发)。与 subagent_ended 事件互补,
|
|
136
|
+
* 覆盖个别 ended 事件丢失导致计数器不为 0、从而永远等不到收尾信号的情况。
|
|
137
|
+
*/
|
|
138
|
+
export function turnOnAllChildrenDone(roundKey, gen) {
|
|
139
|
+
const s = stateOf(roundKey, gen);
|
|
140
|
+
if (!s)
|
|
141
|
+
return;
|
|
142
|
+
s.activeChildren = 0;
|
|
143
|
+
console.log(`${DIAG} allChildrenDone round=${roundKey}#${gen} (settle reconcile)`);
|
|
144
|
+
reevaluate(roundKey, s);
|
|
145
|
+
}
|
|
146
|
+
/** lifecycle start(父会话新段开始):清掉旧终态,等待该段终态。 */
|
|
147
|
+
export function turnOnSegmentStart(roundKey, gen) {
|
|
148
|
+
const s = stateOf(roundKey, gen);
|
|
149
|
+
if (!s)
|
|
150
|
+
return;
|
|
151
|
+
s.lifecycleSeen = true;
|
|
152
|
+
s.segmentActive = true;
|
|
153
|
+
s.lastEnd = undefined;
|
|
154
|
+
s.eligible = false;
|
|
155
|
+
clearTimer(s);
|
|
156
|
+
console.log(`${DIAG} segmentStart round=${roundKey}#${gen} (resume/new segment begins)`);
|
|
157
|
+
}
|
|
158
|
+
/** lifecycle end/error(父会话某段结束):记录是否 yield 后评估。 */
|
|
159
|
+
export function turnOnSegmentEnd(roundKey, gen, info) {
|
|
160
|
+
const s = stateOf(roundKey, gen);
|
|
161
|
+
if (!s)
|
|
162
|
+
return;
|
|
163
|
+
s.lifecycleSeen = true;
|
|
164
|
+
s.segmentActive = false;
|
|
165
|
+
s.lastEnd = { ...info, at: Date.now() };
|
|
166
|
+
console.log(`${DIAG} segmentEnd round=${roundKey}#${gen} phase=${info.phase} ` +
|
|
167
|
+
`yielded=${info.yielded === true} stopReason=${info.stopReason ?? "(none)"} ` +
|
|
168
|
+
`children=${s.activeChildren}`);
|
|
169
|
+
reevaluate(roundKey, s);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 组内活动心跳(before_tool_call / thinking / assistant 等属于本轮的其它事件):
|
|
173
|
+
* 说明父会话仍在工作,取消静默收尾计时,但不算“段已结束”。
|
|
174
|
+
*/
|
|
175
|
+
export function turnOnActivity(roundKey, gen) {
|
|
176
|
+
const s = stateOf(roundKey, gen);
|
|
177
|
+
if (!s)
|
|
178
|
+
return;
|
|
179
|
+
if (s.timer !== undefined) {
|
|
180
|
+
console.debug(`${DIAG} activity cancels fallback round=${roundKey}#${gen} (timer cleared)`);
|
|
181
|
+
}
|
|
182
|
+
clearTimer(s);
|
|
183
|
+
s.eligible = false;
|
|
184
|
+
}
|
|
185
|
+
/** wrapper 侧首次建轮后登记状态;sawSubagent 由后续 spawn 事件置位。 */
|
|
186
|
+
export function turnEnsureRound(roundKey, gen) {
|
|
187
|
+
const existing = states.get(roundKey);
|
|
188
|
+
if (existing && existing.gen === gen)
|
|
189
|
+
return;
|
|
190
|
+
if (existing) {
|
|
191
|
+
// 同一 group 的新一代轮次:清掉旧代计时与状态,避免旧代事件/定时器干扰新轮。
|
|
192
|
+
clearTimer(existing);
|
|
193
|
+
console.log(`${DIAG} ensure new generation round=${roundKey}#${gen} (was #${existing.gen})`);
|
|
194
|
+
}
|
|
195
|
+
states.set(roundKey, {
|
|
196
|
+
gen,
|
|
197
|
+
sawSubagent: false,
|
|
198
|
+
activeChildren: 0,
|
|
199
|
+
dispatchReturned: false,
|
|
200
|
+
lifecycleSeen: false,
|
|
201
|
+
segmentActive: false,
|
|
202
|
+
eligible: false,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
export function turnIsSawSubagent(roundKey, gen) {
|
|
206
|
+
return stateOf(roundKey, gen)?.sawSubagent === true;
|
|
207
|
+
}
|
|
208
|
+
export function turnIsEligible(roundKey, gen) {
|
|
209
|
+
return stateOf(roundKey, gen)?.eligible === true;
|
|
210
|
+
}
|
|
211
|
+
/** 收尾完成 / 中断 / 插件卸载后清理。 */
|
|
212
|
+
export function turnForget(roundKey, gen) {
|
|
213
|
+
const s = stateOf(roundKey, gen);
|
|
214
|
+
if (!s)
|
|
215
|
+
return;
|
|
216
|
+
console.log(`${DIAG} forget round=${roundKey}#${gen} (round finished/cleaned)`);
|
|
217
|
+
clearTimer(s);
|
|
218
|
+
states.delete(roundKey);
|
|
219
|
+
}
|
|
220
|
+
/** 插件卸载时清理全部轮次状态。 */
|
|
221
|
+
export function disposeTurnEndController() {
|
|
222
|
+
for (const s of states.values()) {
|
|
223
|
+
if (s.timer !== undefined)
|
|
224
|
+
clearTimeout(s.timer);
|
|
225
|
+
}
|
|
226
|
+
states.clear();
|
|
227
|
+
}
|
|
228
|
+
/** 单测辅助。 */
|
|
229
|
+
export function __resetTurnEndControllerForTests() {
|
|
230
|
+
disposeTurnEndController();
|
|
231
|
+
}
|
|
232
|
+
/** 单测辅助:缩短各计时窗口,避免真实等待。 */
|
|
233
|
+
export function __configureTurnEndForTests(overrides) {
|
|
234
|
+
if (overrides.nonYieldDebounceMs !== undefined)
|
|
235
|
+
NON_YIELD_DEBOUNCE_MS = overrides.nonYieldDebounceMs;
|
|
236
|
+
if (overrides.noLifecycleFallbackMs !== undefined)
|
|
237
|
+
NO_LIFECYCLE_FALLBACK_MS = overrides.noLifecycleFallbackMs;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=turn-end-controller.js.map
|