@cuylabs/channel-slack-agent-core 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { AgentTurnSource, Logger } from '@cuylabs/agent-core';
2
2
  import { App } from '@slack/bolt';
3
3
  import { WebClient } from '@slack/web-api';
4
- import { C as CreateSlackAssistantBridgeOptions, b as SlackAssistantFeedbackConfig, S as SlackAssistantBridge } from './options-CdqBABcM.js';
4
+ import { C as CreateSlackAssistantBridgeOptions, d as SlackAssistantFeedbackConfig, S as SlackAssistantBridge } from './options-C7-VXmhD.js';
5
5
  import { a as SlackChannelOptions } from './types-CRWzJB5G.js';
6
6
  import { SlackTurnRequestContext, SlackAssistantUtilities, SlackTurnPreparation } from '@cuylabs/channel-slack/core';
7
7
  import { SlackFeedbackHandler } from '@cuylabs/channel-slack/feedback';
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  installSlackAgentAppSurface
3
- } from "./chunk-7DUO5BMW.js";
4
- import "./chunk-MGBNGG4D.js";
3
+ } from "./chunk-6T6N4MRK.js";
4
+ import "./chunk-7YZWCSML.js";
5
5
  import "./chunk-ELR6MQD7.js";
6
6
  import "./chunk-FQWFB54C.js";
7
7
  import "./chunk-TMADMHBN.js";
package/dist/app.d.ts CHANGED
@@ -5,7 +5,7 @@ import { CreateSlackBoltAppOptions } from '@cuylabs/channel-slack/transports/htt
5
5
  import { SlackDirectAuthOptions, SlackDirectAuthMode } from '@cuylabs/channel-slack/auth';
6
6
  import { SlackAgentAppSurfaceOptions } from './app-surface.js';
7
7
  export { MountSlackAgentAppTurnRequestContext } from './app-surface.js';
8
- import { S as SlackAssistantBridge } from './options-CdqBABcM.js';
8
+ import { S as SlackAssistantBridge } from './options-C7-VXmhD.js';
9
9
  import '@cuylabs/agent-core';
10
10
  import '@slack/web-api';
11
11
  import './types-CRWzJB5G.js';
package/dist/app.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  mountSlackAgentApp
3
- } from "./chunk-76SRS54H.js";
4
- import "./chunk-7DUO5BMW.js";
5
- import "./chunk-MGBNGG4D.js";
3
+ } from "./chunk-236WN6JD.js";
4
+ import "./chunk-6T6N4MRK.js";
5
+ import "./chunk-7YZWCSML.js";
6
6
  import "./chunk-ELR6MQD7.js";
7
7
  import "./chunk-FQWFB54C.js";
8
8
  import "./chunk-TMADMHBN.js";
@@ -1,5 +1,5 @@
1
- import { C as CreateSlackAssistantBridgeOptions, S as SlackAssistantBridge } from '../options-CdqBABcM.js';
2
- export { A as AssistantLifecycleArgs, a as AssistantThreadStartedArgs, M as MaybePromise, b as SlackAssistantFeedbackConfig, c as SlackAssistantSessionStrategy, d as SlackAssistantStatusContext, e as SlackAssistantThreadContextStoreLike, f as SlackAssistantThreadStartedContext, g as SlackAssistantTurnPreparation, h as SlackAssistantUserMessageContext, r as resolveAssistantSessionId } from '../options-CdqBABcM.js';
1
+ import { C as CreateSlackAssistantBridgeOptions, S as SlackAssistantBridge } from '../options-C7-VXmhD.js';
2
+ export { A as AssistantLifecycleArgs, a as AssistantThreadStartedArgs, M as MaybePromise, b as SlackAssistantCancelControlOptions, c as SlackAssistantCancelControlVisibleWhen, d as SlackAssistantFeedbackConfig, e as SlackAssistantSessionStrategy, f as SlackAssistantStatusContext, g as SlackAssistantThreadContextStoreLike, h as SlackAssistantThreadStartedContext, i as SlackAssistantTurnCancelContext, j as SlackAssistantTurnControlsOptions, k as SlackAssistantTurnPreparation, l as SlackAssistantUserMessageContext, r as resolveAssistantSessionId } from '../options-C7-VXmhD.js';
3
3
  export { ParsedAssistantUserMessage, createSlackAssistantThreadContextStore, parseSlackMessageActivityFromMessageEvent } from '@cuylabs/channel-slack/assistant';
4
4
  import '@cuylabs/agent-core';
5
5
  import '@slack/bolt';
@@ -3,7 +3,7 @@ import {
3
3
  createSlackAssistantThreadContextStore,
4
4
  parseSlackMessageActivityFromMessageEvent,
5
5
  resolveAssistantSessionId
6
- } from "../chunk-MGBNGG4D.js";
6
+ } from "../chunk-7YZWCSML.js";
7
7
  import "../chunk-ELR6MQD7.js";
8
8
  import "../chunk-TMADMHBN.js";
9
9
  export {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  installSlackAgentAppSurface
3
- } from "./chunk-7DUO5BMW.js";
3
+ } from "./chunk-6T6N4MRK.js";
4
4
 
5
5
  // src/app.ts
6
6
  import {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createSlackAssistantBridge
3
- } from "./chunk-MGBNGG4D.js";
3
+ } from "./chunk-7YZWCSML.js";
4
4
 
5
5
  // src/express-assistant.ts
6
6
  import {
@@ -1,9 +1,8 @@
1
1
  import {
2
2
  createSlackAssistantBridge
3
- } from "./chunk-MGBNGG4D.js";
3
+ } from "./chunk-7YZWCSML.js";
4
4
  import {
5
- createSlackFeedbackBlock,
6
- registerSlackFeedbackAction
5
+ createSlackFeedbackBlock
7
6
  } from "./chunk-ELR6MQD7.js";
8
7
  import {
9
8
  createSlackChannelAdapter
@@ -49,7 +48,7 @@ function installSlackAgentAppSurface(boltApp, options) {
49
48
  ...resolveSession ? { resolveSession: toAssistantResolveSession(resolveSession) } : {},
50
49
  ...interactive ? { handleInteractiveRequest: interactive.handleInteractiveRequest } : {}
51
50
  });
52
- boltApp.assistant(bridge.assistant);
51
+ bridge.install(boltApp);
53
52
  const channelAdapter = createSlackChannelAdapter({
54
53
  source: channelSource,
55
54
  sessionStrategy: assistantBridgeOptions.sessionStrategy,
@@ -99,15 +98,6 @@ function installSlackAgentAppSurface(boltApp, options) {
99
98
  } : {}
100
99
  });
101
100
  channelAdapter.mount(boltApp);
102
- if (feedbackConfig) {
103
- const feedbackSessionStrategy = assistantBridgeOptions.sessionStrategy ?? "thread-aware";
104
- registerSlackFeedbackAction(boltApp, {
105
- ...feedbackConfig,
106
- resolveSessionId: (ctx) => resolveFeedbackSessionId(ctx, feedbackSessionStrategy),
107
- onFeedback: feedbackConfig.onFeedback ?? (async (_ctx) => {
108
- })
109
- });
110
- }
111
101
  interactive?.install(boltApp);
112
102
  viewWorkflows?.install(boltApp);
113
103
  return { bridge };
@@ -191,17 +181,6 @@ function formatErrorForLog(error) {
191
181
  }
192
182
  return String(error);
193
183
  }
194
- function resolveFeedbackSessionId(context, strategy) {
195
- const threadTs = context.threadTs ?? context.messageTs;
196
- switch (strategy) {
197
- case "channel-id":
198
- return context.channelId;
199
- case "user-per-thread":
200
- return `${context.channelId}:${threadTs}:${context.userId}`;
201
- default:
202
- return `${context.channelId}:${threadTs}`;
203
- }
204
- }
205
184
 
206
185
  export {
207
186
  installSlackAgentAppSurface
@@ -11,6 +11,7 @@ import {
11
11
 
12
12
  // src/assistant/bridge.ts
13
13
  import { Assistant } from "@slack/bolt";
14
+ import { resolveSlackTurnCancelActionId as resolveSlackTurnCancelActionId2 } from "@cuylabs/channel-slack/turn-controls";
14
15
 
15
16
  // src/assistant/options.ts
16
17
  var DEFAULT_INITIAL_REPLY = "Hi, how can I help?";
@@ -294,7 +295,7 @@ function createAssistantInteractiveResponder(params) {
294
295
 
295
296
  // src/assistant/lifecycle/user-message.ts
296
297
  function createUserMessageHandler(deps) {
297
- const { options, feedbackBlock, sessionStrategy } = deps;
298
+ const { options, feedbackBlock, sessionStrategy, turnControlController } = deps;
298
299
  const taskDisplayMode = options.taskDisplayMode ?? "timeline";
299
300
  const messageFormatter = resolveSlackMessageFormatter(
300
301
  options.formatChatMarkdown ?? {}
@@ -497,6 +498,17 @@ function createUserMessageHandler(deps) {
497
498
  });
498
499
  const abortController = new AbortController();
499
500
  timeoutId = timeoutMs > 0 ? setTimeout(() => abortController.abort(), timeoutMs) : void 0;
501
+ const cancelControl = turnControlController?.createCancelControl({
502
+ abortController,
503
+ channel,
504
+ client,
505
+ logger: diagnosticsLogger,
506
+ sessionId,
507
+ ...teamId ? { teamId } : {},
508
+ threadTs,
509
+ userId: userId ?? "unknown"
510
+ });
511
+ cancelControl?.show("turn-start");
500
512
  await runWithSlackTurnContext(
501
513
  {
502
514
  slackActivity: parsed,
@@ -533,6 +545,7 @@ function createUserMessageHandler(deps) {
533
545
  const translated = (async function* () {
534
546
  try {
535
547
  for await (const event of events) {
548
+ cancelControl?.sync(event);
536
549
  if (event.type === "error") {
537
550
  translatedError = toError(
538
551
  event.error
@@ -561,6 +574,8 @@ ${formatStreamError(translatedError)}`
561
574
  ${formatStreamError(translatedError)}`
562
575
  };
563
576
  yield { type: "complete" };
577
+ } finally {
578
+ cancelControl?.clear("turn-finished");
564
579
  }
565
580
  })();
566
581
  const finalText = await bridgeAgentEventsToSlack(
@@ -617,6 +632,213 @@ ${formatStreamError(translatedError)}`
617
632
  };
618
633
  }
619
634
 
635
+ // src/assistant/turn-controls.ts
636
+ import { randomUUID } from "crypto";
637
+ import {
638
+ createSlackTurnCancelMessage,
639
+ registerSlackTurnCancelAction,
640
+ resolveSlackTurnCancelActionId
641
+ } from "@cuylabs/channel-slack/turn-controls";
642
+ function createSlackAssistantTurnControlController(options) {
643
+ const resolvedCancelOptions = resolveCancelOptions(options);
644
+ if (!resolvedCancelOptions) {
645
+ return void 0;
646
+ }
647
+ const cancelOptions = resolvedCancelOptions;
648
+ const actionId = resolveSlackTurnCancelActionId(cancelOptions.actionId);
649
+ const activeControls = /* @__PURE__ */ new Map();
650
+ function install(app) {
651
+ registerSlackTurnCancelAction(app, {
652
+ actionId,
653
+ onCancel: (context) => handleCancelAction(context)
654
+ });
655
+ }
656
+ function createCancelControl(controlOptions) {
657
+ const control = {
658
+ abortController: controlOptions.abortController,
659
+ channel: controlOptions.channel,
660
+ client: controlOptions.client,
661
+ controlId: randomUUID(),
662
+ logger: controlOptions.logger,
663
+ pending: Promise.resolve(),
664
+ sessionId: controlOptions.sessionId,
665
+ ...controlOptions.teamId ? { teamId: controlOptions.teamId } : {},
666
+ threadTs: controlOptions.threadTs,
667
+ userId: controlOptions.userId,
668
+ visible: false
669
+ };
670
+ activeControls.set(control.controlId, control);
671
+ return {
672
+ show(reason) {
673
+ showCancelControl(control, reason);
674
+ },
675
+ clear(reason) {
676
+ clearCancelControl(control, reason);
677
+ },
678
+ sync(event) {
679
+ syncCancelControlForEvent(control, event);
680
+ }
681
+ };
682
+ }
683
+ async function handleCancelAction(context) {
684
+ const control = activeControls.get(context.controlId);
685
+ if (!control) {
686
+ await context.deleteMessage().catch(() => void 0);
687
+ await acknowledge(context, cancelOptions.alreadyCompletedAck);
688
+ return;
689
+ }
690
+ if (context.userId !== control.userId) {
691
+ await acknowledge(context, cancelOptions.unauthorizedAck);
692
+ return;
693
+ }
694
+ clearCancelControl(control, "button-cancel");
695
+ activeControls.delete(control.controlId);
696
+ if (!control.abortController.signal.aborted) {
697
+ control.abortController.abort(createSlackTurnCancelledError());
698
+ }
699
+ await cancelOptions.onCancel?.({
700
+ controlId: control.controlId,
701
+ sessionId: control.sessionId,
702
+ channelId: control.channel,
703
+ threadTs: control.threadTs,
704
+ userId: control.userId,
705
+ ...control.teamId ? { teamId: control.teamId } : {}
706
+ });
707
+ await acknowledge(context, cancelOptions.canceledAck);
708
+ }
709
+ function showCancelControl(control, reason) {
710
+ if (control.visible || control.abortController.signal.aborted) {
711
+ return;
712
+ }
713
+ control.visible = true;
714
+ enqueueControlUpdate(control, "show", reason, async () => {
715
+ const message = createSlackTurnCancelMessage({
716
+ actionId,
717
+ controlId: control.controlId,
718
+ messageText: cancelOptions.messageText,
719
+ buttonText: cancelOptions.buttonText,
720
+ sessionId: control.sessionId
721
+ });
722
+ if (control.target) {
723
+ await control.client.chat.update({
724
+ channel: control.target.channel,
725
+ ts: control.target.ts,
726
+ text: message.text,
727
+ blocks: message.blocks
728
+ });
729
+ return;
730
+ }
731
+ const response = await control.client.chat.postMessage({
732
+ channel: control.channel,
733
+ thread_ts: control.threadTs,
734
+ text: message.text,
735
+ blocks: message.blocks
736
+ });
737
+ if (response.channel && response.ts) {
738
+ control.target = { channel: response.channel, ts: response.ts };
739
+ }
740
+ });
741
+ }
742
+ function clearCancelControl(control, reason) {
743
+ const terminal = isTerminalClearReason(reason);
744
+ if (terminal) {
745
+ activeControls.delete(control.controlId);
746
+ }
747
+ if (!control.visible) {
748
+ return;
749
+ }
750
+ control.visible = false;
751
+ enqueueControlUpdate(control, "clear", reason, async () => {
752
+ if (!control.target) {
753
+ return;
754
+ }
755
+ const target = control.target;
756
+ control.target = void 0;
757
+ await control.client.chat.delete({
758
+ channel: target.channel,
759
+ ts: target.ts
760
+ });
761
+ });
762
+ }
763
+ function syncCancelControlForEvent(control, event) {
764
+ switch (event.type) {
765
+ case "text-start":
766
+ case "text-delta":
767
+ case "text-end":
768
+ if (cancelOptions.visibleWhen === "before-output") {
769
+ clearCancelControl(control, "streaming-started");
770
+ }
771
+ break;
772
+ case "reasoning-start":
773
+ case "reasoning-delta":
774
+ case "reasoning-end":
775
+ case "tool-start":
776
+ case "approval-request":
777
+ case "human-input-request":
778
+ showCancelControl(control, event.type);
779
+ break;
780
+ case "status":
781
+ if (isWaitingForAgentStatus(event.status)) {
782
+ showCancelControl(control, `status:${event.status}`);
783
+ } else if (event.status === "idle" || event.status === "error") {
784
+ clearCancelControl(control, `status:${event.status}`);
785
+ }
786
+ break;
787
+ case "complete":
788
+ clearCancelControl(control, "turn-finished");
789
+ break;
790
+ case "error":
791
+ clearCancelControl(control, "turn-error");
792
+ break;
793
+ default:
794
+ break;
795
+ }
796
+ }
797
+ function enqueueControlUpdate(control, action, reason, update) {
798
+ control.pending = control.pending.then(update);
799
+ control.pending = control.pending.catch((error) => {
800
+ control.logger.warn?.("Slack turn cancel control update failed", {
801
+ action,
802
+ controlId: control.controlId,
803
+ error: formatErrorForLog(error),
804
+ reason,
805
+ sessionId: control.sessionId
806
+ });
807
+ });
808
+ }
809
+ async function acknowledge(context, text) {
810
+ if (text === false) {
811
+ return;
812
+ }
813
+ await context.acknowledgeEphemeral(text ?? "Canceled the running request.");
814
+ }
815
+ return { install, createCancelControl };
816
+ }
817
+ function resolveCancelOptions(options) {
818
+ if (!options?.cancel) {
819
+ return void 0;
820
+ }
821
+ const input = options.cancel === true ? {} : options.cancel;
822
+ return {
823
+ ...input,
824
+ visibleWhen: input.visibleWhen ?? "before-output",
825
+ canceledAck: input.canceledAck ?? "Canceled the running request.",
826
+ alreadyCompletedAck: input.alreadyCompletedAck ?? "That request is no longer running.",
827
+ unauthorizedAck: input.unauthorizedAck ?? "Only the user who started this request can cancel it."
828
+ };
829
+ }
830
+ function isWaitingForAgentStatus(status) {
831
+ return status === "processing" || status === "thinking" || status === "reasoning" || status === "calling-tool" || status === "waiting-approval" || status === "waiting-input";
832
+ }
833
+ function isTerminalClearReason(reason) {
834
+ return reason === "streaming-started" || reason === "turn-finished" || reason === "turn-error" || reason === "button-cancel";
835
+ }
836
+ function createSlackTurnCancelledError() {
837
+ return Object.assign(new Error("Slack turn was cancelled by the user."), {
838
+ category: "cancelled"
839
+ });
840
+ }
841
+
620
842
  // src/assistant/bridge.ts
621
843
  import { createSlackAssistantThreadContextStore } from "@cuylabs/channel-slack/assistant";
622
844
  function createSlackAssistantBridge(options) {
@@ -634,13 +856,20 @@ function createSlackAssistantBridge(options) {
634
856
  const feedbackConfig = options.feedback === false ? void 0 : options.feedback ?? {};
635
857
  const feedbackBlock = feedbackConfig ? createSlackFeedbackBlock(feedbackConfig) : void 0;
636
858
  const feedbackActionId = feedbackConfig?.actionId ?? SLACK_FEEDBACK_ACTION_ID;
859
+ const turnControlController = createSlackAssistantTurnControlController(
860
+ options.turnControls
861
+ );
862
+ const turnCancelActionId = turnControlController ? resolveSlackTurnCancelActionId2(
863
+ resolveTurnCancelActionIdOption(options.turnControls)
864
+ ) : void 0;
637
865
  const threadStarted = createThreadStartedHandler(options);
638
866
  const threadContextChanged = createThreadContextChangedHandler();
639
867
  const threadContextStore = options.threadContextStore ?? createSlackAssistantThreadContextStore();
640
868
  const userMessage = createUserMessageHandler({
641
869
  options,
642
870
  feedbackBlock,
643
- sessionStrategy
871
+ sessionStrategy,
872
+ ...turnControlController ? { turnControlController } : {}
644
873
  });
645
874
  const config = {
646
875
  threadStarted,
@@ -662,13 +891,21 @@ function createSlackAssistantBridge(options) {
662
891
  })
663
892
  });
664
893
  }
894
+ turnControlController?.install(app);
665
895
  }
666
896
  return {
667
897
  assistant,
668
898
  install,
669
- ...feedbackConfig ? { feedbackActionId } : {}
899
+ ...feedbackConfig ? { feedbackActionId } : {},
900
+ ...turnCancelActionId ? { turnCancelActionId } : {}
670
901
  };
671
902
  }
903
+ function resolveTurnCancelActionIdOption(options) {
904
+ if (!options || !options.cancel) {
905
+ return void 0;
906
+ }
907
+ return typeof options.cancel === "object" ? options.cancel.actionId : void 0;
908
+ }
672
909
 
673
910
  // src/assistant/index.ts
674
911
  import {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  installSlackAgentAppSurface
3
- } from "./chunk-7DUO5BMW.js";
3
+ } from "./chunk-6T6N4MRK.js";
4
4
  import {
5
5
  createSlackAssistantBridge
6
- } from "./chunk-MGBNGG4D.js";
6
+ } from "./chunk-7YZWCSML.js";
7
7
 
8
8
  // src/socket.ts
9
9
  import { createSlackSocketBoltApp } from "@cuylabs/channel-slack/transports/socket";
@@ -3,7 +3,7 @@ import { Application } from 'express';
3
3
  import { App, ExpressReceiver } from '@slack/bolt';
4
4
  import { CreateSlackBoltAppOptions } from '@cuylabs/channel-slack/transports/http';
5
5
  import { SlackDirectAuthOptions, SlackDirectAuthMode } from '@cuylabs/channel-slack/auth';
6
- import { C as CreateSlackAssistantBridgeOptions, b as SlackAssistantFeedbackConfig, S as SlackAssistantBridge } from './options-CdqBABcM.js';
6
+ import { C as CreateSlackAssistantBridgeOptions, d as SlackAssistantFeedbackConfig, S as SlackAssistantBridge } from './options-C7-VXmhD.js';
7
7
  import { SlackFeedbackHandler } from '@cuylabs/channel-slack/feedback';
8
8
  import '@cuylabs/agent-core';
9
9
  import '@slack/web-api';
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  mountSlackAssistantAgent
3
- } from "./chunk-DJPKRKGP.js";
4
- import "./chunk-MGBNGG4D.js";
3
+ } from "./chunk-2R7B7NJR.js";
4
+ import "./chunk-7YZWCSML.js";
5
5
  import "./chunk-ELR6MQD7.js";
6
6
  import "./chunk-TMADMHBN.js";
7
7
  export {
@@ -4,7 +4,7 @@ import { MountSlackAgentAppTurnRequestContext } from '../app-surface.js';
4
4
  import { a as SlackContextFragmentPayload } from '../context-fragments-CQEDcjYR.js';
5
5
  import '@slack/bolt';
6
6
  import '@slack/web-api';
7
- import '../options-CdqBABcM.js';
7
+ import '../options-C7-VXmhD.js';
8
8
  import '@cuylabs/channel-slack/core';
9
9
  import '../interactive-o_NZb-Xg.js';
10
10
  import '../options-BcDReOJv.js';
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export { c as createSlackChannelAdapter } from './adapter-B3CI611y.js';
6
6
  export { S as SlackChannelAdapter, a as SlackChannelOptions, b as SlackSessionStrategy, c as SlackStreamingMode, d as SlackToolStartEvent } from './types-CRWzJB5G.js';
7
7
  export { SlackSessionMap, createSlackSessionMap } from './adapter/index.js';
8
8
  export { createSlackAssistantBridge } from './assistant/index.js';
9
- export { A as AssistantLifecycleArgs, a as AssistantThreadStartedArgs, C as CreateSlackAssistantBridgeOptions, M as MaybePromise, S as SlackAssistantBridge, b as SlackAssistantFeedbackConfig, c as SlackAssistantSessionStrategy, d as SlackAssistantStatusContext, e as SlackAssistantThreadContextStoreLike, f as SlackAssistantThreadStartedContext, g as SlackAssistantTurnPreparation, h as SlackAssistantUserMessageContext, r as resolveAssistantSessionId } from './options-CdqBABcM.js';
9
+ export { A as AssistantLifecycleArgs, a as AssistantThreadStartedArgs, C as CreateSlackAssistantBridgeOptions, M as MaybePromise, S as SlackAssistantBridge, b as SlackAssistantCancelControlOptions, c as SlackAssistantCancelControlVisibleWhen, d as SlackAssistantFeedbackConfig, e as SlackAssistantSessionStrategy, f as SlackAssistantStatusContext, g as SlackAssistantThreadContextStoreLike, h as SlackAssistantThreadStartedContext, i as SlackAssistantTurnCancelContext, j as SlackAssistantTurnControlsOptions, k as SlackAssistantTurnPreparation, l as SlackAssistantUserMessageContext, r as resolveAssistantSessionId } from './options-C7-VXmhD.js';
10
10
  export { ParsedAssistantUserMessage, createSlackAssistantThreadContextStore, parseSlackMessageActivityFromMessageEvent } from '@cuylabs/channel-slack/assistant';
11
11
  export { CreateSlackFinalResponseArtifactPublisherOptions, SlackFinalResponseArtifactContext, SlackFinalResponseArtifactDeliveryMode, SlackFinalResponseArtifactPublisher, SlackFinalResponseArtifactResult, SlackFinalResponseArtifactValueResolver, createSlackFinalResponseArtifactPublisher } from './artifacts/index.js';
12
12
  export { LoadSlackAgentTurnHistoryContextOptions, SlackAgentTurnHistoryContextResult, SlackAgentTurnHistoryOptions, SlackAgentTurnHistoryProfileResolver, emptySlackAgentTurnHistoryContextResult, loadSlackAgentTurnHistoryContext } from './history/index.js';
package/dist/index.js CHANGED
@@ -50,10 +50,10 @@ import {
50
50
  } from "./chunk-C7CHMYV6.js";
51
51
  import {
52
52
  mountSlackAgentApp
53
- } from "./chunk-76SRS54H.js";
53
+ } from "./chunk-236WN6JD.js";
54
54
  import {
55
55
  mountSlackAssistantAgent
56
- } from "./chunk-DJPKRKGP.js";
56
+ } from "./chunk-2R7B7NJR.js";
57
57
  import {
58
58
  mountSlackAgent
59
59
  } from "./chunk-TCNJY7QA.js";
@@ -64,14 +64,14 @@ import {
64
64
  import {
65
65
  mountSlackAgentAppSocket,
66
66
  mountSlackAssistantAgentSocket
67
- } from "./chunk-VMVQIDNR.js";
68
- import "./chunk-7DUO5BMW.js";
67
+ } from "./chunk-YSDFYHPC.js";
68
+ import "./chunk-6T6N4MRK.js";
69
69
  import {
70
70
  createSlackAssistantBridge,
71
71
  createSlackAssistantThreadContextStore,
72
72
  parseSlackMessageActivityFromMessageEvent,
73
73
  resolveAssistantSessionId
74
- } from "./chunk-MGBNGG4D.js";
74
+ } from "./chunk-7YZWCSML.js";
75
75
  import "./chunk-ELR6MQD7.js";
76
76
  import {
77
77
  createSlackChannelAdapter,
@@ -7,6 +7,29 @@ import { S as SlackEventBridgeOptions } from './options-BcDReOJv.js';
7
7
  import { SlackFeedbackBlockOptions, SlackFeedbackHandler } from '@cuylabs/channel-slack/feedback';
8
8
  import { ParsedAssistantUserMessage } from '@cuylabs/channel-slack/assistant';
9
9
 
10
+ type SlackAssistantCancelControlVisibleWhen = "before-output" | "always-while-active";
11
+ interface SlackAssistantCancelControlOptions {
12
+ actionId?: string;
13
+ buttonText?: string;
14
+ messageText?: string;
15
+ visibleWhen?: SlackAssistantCancelControlVisibleWhen;
16
+ canceledAck?: string | false;
17
+ alreadyCompletedAck?: string | false;
18
+ unauthorizedAck?: string | false;
19
+ onCancel?: (context: SlackAssistantTurnCancelContext) => MaybePromise<void>;
20
+ }
21
+ interface SlackAssistantTurnControlsOptions {
22
+ cancel?: true | SlackAssistantCancelControlOptions;
23
+ }
24
+ interface SlackAssistantTurnCancelContext {
25
+ controlId: string;
26
+ sessionId: string;
27
+ channelId: string;
28
+ threadTs: string;
29
+ userId: string;
30
+ teamId?: string;
31
+ }
32
+
10
33
  /**
11
34
  * Session strategies for the Bolt Assistant bridge.
12
35
  *
@@ -187,6 +210,13 @@ interface CreateSlackAssistantBridgeOptions {
187
210
  * - `false`: omit the feedback block entirely.
188
211
  */
189
212
  feedback?: SlackAssistantFeedbackConfig | false;
213
+ /**
214
+ * Optional active-turn controls rendered in Slack while an assistant turn is
215
+ * running. The cancel control aborts the underlying `AgentTurnSource` via
216
+ * the per-turn `AbortSignal`, so any runtime implementing that contract can
217
+ * participate without Slack-specific code.
218
+ */
219
+ turnControls?: SlackAssistantTurnControlsOptions;
190
220
  /**
191
221
  * Bridge options forwarded to `bridgeAgentEventsToSlack`. Streaming mode is
192
222
  * pinned to `"chat-stream"` and cannot be overridden here.
@@ -283,6 +313,11 @@ interface SlackAssistantBridge {
283
313
  * The resolved feedback action id, or `undefined` when feedback is disabled.
284
314
  */
285
315
  feedbackActionId?: string;
316
+ /**
317
+ * The resolved cancel action id, or `undefined` when turn cancel controls are
318
+ * disabled.
319
+ */
320
+ turnCancelActionId?: string;
286
321
  }
287
322
 
288
- export { type AssistantLifecycleArgs as A, type CreateSlackAssistantBridgeOptions as C, type MaybePromise as M, type SlackAssistantBridge as S, type AssistantThreadStartedArgs as a, type SlackAssistantFeedbackConfig as b, type SlackAssistantSessionStrategy as c, type SlackAssistantStatusContext as d, type SlackAssistantThreadContextStoreLike as e, type SlackAssistantThreadStartedContext as f, type SlackAssistantTurnPreparation as g, type SlackAssistantUserMessageContext as h, resolveAssistantSessionId as r };
323
+ export { type AssistantLifecycleArgs as A, type CreateSlackAssistantBridgeOptions as C, type MaybePromise as M, type SlackAssistantBridge as S, type AssistantThreadStartedArgs as a, type SlackAssistantCancelControlOptions as b, type SlackAssistantCancelControlVisibleWhen as c, type SlackAssistantFeedbackConfig as d, type SlackAssistantSessionStrategy as e, type SlackAssistantStatusContext as f, type SlackAssistantThreadContextStoreLike as g, type SlackAssistantThreadStartedContext as h, type SlackAssistantTurnCancelContext as i, type SlackAssistantTurnControlsOptions as j, type SlackAssistantTurnPreparation as k, type SlackAssistantUserMessageContext as l, resolveAssistantSessionId as r };
package/dist/socket.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { App } from '@slack/bolt';
2
2
  import { CreateSlackSocketBoltAppOptions } from '@cuylabs/channel-slack/transports/socket';
3
3
  import { SlackDirectAuthOptions, SlackDirectAuthMode } from '@cuylabs/channel-slack/auth';
4
- import { S as SlackAssistantBridge, C as CreateSlackAssistantBridgeOptions, b as SlackAssistantFeedbackConfig } from './options-CdqBABcM.js';
4
+ import { S as SlackAssistantBridge, C as CreateSlackAssistantBridgeOptions, d as SlackAssistantFeedbackConfig } from './options-C7-VXmhD.js';
5
5
  import { SlackAgentAppSurfaceOptions } from './app-surface.js';
6
6
  import { SlackFeedbackHandler } from '@cuylabs/channel-slack/feedback';
7
7
  import '@cuylabs/agent-core';
package/dist/socket.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  mountSlackAgentAppSocket,
3
3
  mountSlackAssistantAgentSocket
4
- } from "./chunk-VMVQIDNR.js";
5
- import "./chunk-7DUO5BMW.js";
6
- import "./chunk-MGBNGG4D.js";
4
+ } from "./chunk-YSDFYHPC.js";
5
+ import "./chunk-6T6N4MRK.js";
6
+ import "./chunk-7YZWCSML.js";
7
7
  import "./chunk-ELR6MQD7.js";
8
8
  import "./chunk-FQWFB54C.js";
9
9
  import "./chunk-TMADMHBN.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cuylabs/channel-slack-agent-core",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Slack adapter for @cuylabs/agent-core built on @cuylabs/channel-slack",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -94,7 +94,7 @@
94
94
  ],
95
95
  "dependencies": {
96
96
  "@cuylabs/agent-core": "^7.2.0",
97
- "@cuylabs/channel-slack": "^0.7.0"
97
+ "@cuylabs/channel-slack": "^0.8.0"
98
98
  },
99
99
  "peerDependencies": {
100
100
  "@slack/bolt": ">=4.7.3",