@cuylabs/channel-slack-agent-core 0.6.0 → 0.7.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.
Files changed (49) hide show
  1. package/README.md +7 -0
  2. package/dist/adapter/index.d.ts +6 -3
  3. package/dist/adapter/index.js +2 -2
  4. package/dist/{adapter-Cmd2C90g.d.ts → adapter-B3CI611y.d.ts} +1 -1
  5. package/dist/app-surface.d.ts +13 -3
  6. package/dist/app-surface.js +4 -4
  7. package/dist/app.d.ts +7 -3
  8. package/dist/app.js +5 -5
  9. package/dist/artifacts/index.d.ts +57 -0
  10. package/dist/artifacts/index.js +6 -0
  11. package/dist/assistant/index.d.ts +5 -3
  12. package/dist/assistant/index.js +2 -2
  13. package/dist/{chunk-FNT4TXNQ.js → chunk-76SRS54H.js} +1 -1
  14. package/dist/{chunk-P7KK5GQG.js → chunk-7DUO5BMW.js} +11 -2
  15. package/dist/chunk-C7CHMYV6.js +226 -0
  16. package/dist/{chunk-5NQYLOAW.js → chunk-DJPKRKGP.js} +1 -1
  17. package/dist/{chunk-TIQGJ52F.js → chunk-FQWFB54C.js} +14 -2
  18. package/dist/{chunk-ZDVD46RT.js → chunk-MGBNGG4D.js} +23 -1
  19. package/dist/chunk-NNCVHQC4.js +94 -0
  20. package/dist/{chunk-VCXPNQRB.js → chunk-TCNJY7QA.js} +1 -1
  21. package/dist/{chunk-NOVWLAVP.js → chunk-TMADMHBN.js} +209 -20
  22. package/dist/{chunk-QEJ7TAZJ.js → chunk-VMVQIDNR.js} +2 -2
  23. package/dist/{chunk-J6CW2RGO.js → chunk-X7ILLZZP.js} +359 -2
  24. package/dist/express-assistant.d.ts +4 -2
  25. package/dist/express-assistant.js +3 -3
  26. package/dist/express.d.ts +5 -2
  27. package/dist/express.js +3 -3
  28. package/dist/history/index.d.ts +7 -3
  29. package/dist/index.d.ts +12 -6
  30. package/dist/index.js +28 -10
  31. package/dist/interactive/index.d.ts +43 -2
  32. package/dist/interactive/index.js +9 -3
  33. package/dist/{options-C7OYeNR-.d.ts → options-BcDReOJv.d.ts} +48 -0
  34. package/dist/{options-Uf-qmQKN.d.ts → options-CdqBABcM.d.ts} +26 -1
  35. package/dist/shared/index.d.ts +20 -6
  36. package/dist/shared/index.js +1 -1
  37. package/dist/socket.d.ts +7 -3
  38. package/dist/socket.js +5 -5
  39. package/dist/{types-BqRzb_Cd.d.ts → types-CRWzJB5G.d.ts} +35 -0
  40. package/dist/types-CiwGU6zC.d.ts +56 -0
  41. package/dist/views/index.d.ts +8 -0
  42. package/dist/views/index.js +10 -0
  43. package/docs/README.md +7 -0
  44. package/docs/concepts/final-response-artifacts.md +39 -0
  45. package/docs/concepts/interactive-requests.md +43 -0
  46. package/docs/concepts/tool-task-rendering.md +46 -0
  47. package/docs/concepts/view-workflows.md +52 -0
  48. package/docs/reference/exports.md +18 -16
  49. package/package.json +14 -4
package/README.md CHANGED
@@ -22,6 +22,10 @@ Install Slack peer dependencies for the surfaces you use:
22
22
  npm install @slack/bolt @slack/web-api express
23
23
  ```
24
24
 
25
+ Postgres-backed interactive request storage lazy-loads `pg` when you pass a
26
+ connection string. Install `pg` only when your application uses that helper
27
+ without injecting its own client.
28
+
25
29
  ## Quick Start
26
30
 
27
31
  Socket Mode:
@@ -51,4 +55,7 @@ await mountSlackAgent(agent, {
51
55
 
52
56
  - [Package boundary](docs/reference/boundary.md)
53
57
  - [Exports and peer expectations](docs/reference/exports.md)
58
+ - [Interactive requests](docs/concepts/interactive-requests.md)
59
+ - [Final response artifacts](docs/concepts/final-response-artifacts.md)
60
+ - [Tool task rendering](docs/concepts/tool-task-rendering.md)
54
61
  - [Docs index](docs/README.md)
@@ -1,8 +1,11 @@
1
- export { c as createSlackChannelAdapter } from '../adapter-Cmd2C90g.js';
2
- import { a as SlackChannelOptions } from '../types-BqRzb_Cd.js';
3
- export { S as SlackChannelAdapter, b as SlackSessionStrategy, c as SlackStreamingMode, d as SlackToolStartEvent } from '../types-BqRzb_Cd.js';
1
+ export { c as createSlackChannelAdapter } from '../adapter-B3CI611y.js';
2
+ import { a as SlackChannelOptions } from '../types-CRWzJB5G.js';
3
+ export { S as SlackChannelAdapter, b as SlackSessionStrategy, c as SlackStreamingMode, d as SlackToolStartEvent } from '../types-CRWzJB5G.js';
4
4
  import { SlackActivityInfo } from '@cuylabs/channel-slack/core';
5
5
  import '@cuylabs/agent-core';
6
+ import '../options-BcDReOJv.js';
7
+ import '../artifacts/index.js';
8
+ import '@cuylabs/channel-slack/artifacts';
6
9
  import '../interactive-o_NZb-Xg.js';
7
10
 
8
11
  /**
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createSlackChannelAdapter,
3
3
  createSlackSessionMap
4
- } from "../chunk-TIQGJ52F.js";
5
- import "../chunk-NOVWLAVP.js";
4
+ } from "../chunk-FQWFB54C.js";
5
+ import "../chunk-TMADMHBN.js";
6
6
  export {
7
7
  createSlackChannelAdapter,
8
8
  createSlackSessionMap
@@ -1,4 +1,4 @@
1
- import { a as SlackChannelOptions, S as SlackChannelAdapter } from './types-BqRzb_Cd.js';
1
+ import { a as SlackChannelOptions, S as SlackChannelAdapter } from './types-CRWzJB5G.js';
2
2
 
3
3
  /**
4
4
  * Slack Channel Adapter
@@ -1,14 +1,18 @@
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-Uf-qmQKN.js';
5
- import { a as SlackChannelOptions } from './types-BqRzb_Cd.js';
4
+ import { C as CreateSlackAssistantBridgeOptions, b as SlackAssistantFeedbackConfig, S as SlackAssistantBridge } from './options-CdqBABcM.js';
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';
8
8
  import { c as SlackInteractiveController } from './types-Crpil4kb.js';
9
+ import { d as SlackAgentViewWorkflowController } from './types-CiwGU6zC.js';
9
10
  import './interactive-o_NZb-Xg.js';
10
- import './options-C7OYeNR-.js';
11
+ import './options-BcDReOJv.js';
12
+ import './artifacts/index.js';
13
+ import '@cuylabs/channel-slack/artifacts';
11
14
  import '@cuylabs/channel-slack/assistant';
15
+ import '@cuylabs/channel-slack/views';
12
16
 
13
17
  /**
14
18
  * Shared installer for the direct Slack app surfaces.
@@ -62,6 +66,12 @@ interface SlackAgentAppSurfaceOptions extends Omit<CreateSlackAssistantBridgeOpt
62
66
  * the agent config, or with `interactive.onResolve` for server-backed turns.
63
67
  */
64
68
  interactive?: SlackInteractiveController;
69
+ /**
70
+ * Product/agent Slack modal workflow controller. Use this for workflows that
71
+ * are richer than approval/human-input, such as incident triage forms or
72
+ * report-generation setup modals.
73
+ */
74
+ viewWorkflows?: SlackAgentViewWorkflowController;
65
75
  }
66
76
  interface SlackAgentAppSurfaceResult {
67
77
  bridge: SlackAssistantBridge;
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  installSlackAgentAppSurface
3
- } from "./chunk-P7KK5GQG.js";
4
- import "./chunk-ZDVD46RT.js";
3
+ } from "./chunk-7DUO5BMW.js";
4
+ import "./chunk-MGBNGG4D.js";
5
5
  import "./chunk-ELR6MQD7.js";
6
- import "./chunk-TIQGJ52F.js";
7
- import "./chunk-NOVWLAVP.js";
6
+ import "./chunk-FQWFB54C.js";
7
+ import "./chunk-TMADMHBN.js";
8
8
  export {
9
9
  installSlackAgentAppSurface
10
10
  };
package/dist/app.d.ts CHANGED
@@ -5,15 +5,19 @@ 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-Uf-qmQKN.js';
8
+ import { S as SlackAssistantBridge } from './options-CdqBABcM.js';
9
9
  import '@cuylabs/agent-core';
10
10
  import '@slack/web-api';
11
- import './types-BqRzb_Cd.js';
11
+ import './types-CRWzJB5G.js';
12
12
  import '@cuylabs/channel-slack/core';
13
+ import './options-BcDReOJv.js';
14
+ import './artifacts/index.js';
15
+ import '@cuylabs/channel-slack/artifacts';
13
16
  import './interactive-o_NZb-Xg.js';
14
17
  import '@cuylabs/channel-slack/feedback';
15
18
  import './types-Crpil4kb.js';
16
- import './options-C7OYeNR-.js';
19
+ import './types-CiwGU6zC.js';
20
+ import '@cuylabs/channel-slack/views';
17
21
  import '@cuylabs/channel-slack/assistant';
18
22
 
19
23
  /**
package/dist/app.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  mountSlackAgentApp
3
- } from "./chunk-FNT4TXNQ.js";
4
- import "./chunk-P7KK5GQG.js";
5
- import "./chunk-ZDVD46RT.js";
3
+ } from "./chunk-76SRS54H.js";
4
+ import "./chunk-7DUO5BMW.js";
5
+ import "./chunk-MGBNGG4D.js";
6
6
  import "./chunk-ELR6MQD7.js";
7
- import "./chunk-TIQGJ52F.js";
8
- import "./chunk-NOVWLAVP.js";
7
+ import "./chunk-FQWFB54C.js";
8
+ import "./chunk-TMADMHBN.js";
9
9
  export {
10
10
  mountSlackAgentApp
11
11
  };
@@ -0,0 +1,57 @@
1
+ import { SlackArtifactClient, SlackArtifactPublication } from '@cuylabs/channel-slack/artifacts';
2
+
3
+ interface SlackFinalResponseArtifactContext {
4
+ text: string;
5
+ formattedText: string;
6
+ client: SlackArtifactClient;
7
+ channelId: string;
8
+ threadTs?: string;
9
+ }
10
+ interface SlackFinalResponseArtifactResult {
11
+ publication: SlackArtifactPublication;
12
+ }
13
+ type SlackFinalResponseArtifactDeliveryMode = "supplemental" | "replace";
14
+ type SlackFinalResponseArtifactPublisher = (context: SlackFinalResponseArtifactContext) => Promise<SlackFinalResponseArtifactResult | undefined>;
15
+ type SlackFinalResponseArtifactValueResolver<T> = T | ((context: SlackFinalResponseArtifactContext) => T | Promise<T>);
16
+ interface CreateSlackFinalResponseArtifactPublisherOptions {
17
+ /**
18
+ * Minimum raw-response characters required before publishing an artifact.
19
+ *
20
+ * @default 4000
21
+ */
22
+ minCharacters?: number;
23
+ /**
24
+ * Canvas/file title.
25
+ *
26
+ * @default "Agent response"
27
+ */
28
+ title?: SlackFinalResponseArtifactValueResolver<string | undefined>;
29
+ /**
30
+ * Optional Slack artifact summary.
31
+ */
32
+ summary?: SlackFinalResponseArtifactValueResolver<string | undefined>;
33
+ /**
34
+ * Prefer creating a channel canvas when the Slack client exposes
35
+ * `conversations.canvases.create`.
36
+ *
37
+ * @default true
38
+ */
39
+ channelCanvas?: boolean;
40
+ /**
41
+ * Fallback when Canvas publication fails.
42
+ *
43
+ * @default "file"
44
+ */
45
+ fallback?: "file" | "none";
46
+ /**
47
+ * Called after a Canvas or fallback file is published.
48
+ */
49
+ onPublished?: (result: SlackFinalResponseArtifactResult, context: SlackFinalResponseArtifactContext) => void | Promise<void>;
50
+ /**
51
+ * Called when Canvas publication fails and no fallback publication succeeds.
52
+ */
53
+ onError?: (error: unknown, context: SlackFinalResponseArtifactContext) => void | Promise<void>;
54
+ }
55
+ declare function createSlackFinalResponseArtifactPublisher({ minCharacters, title, summary, channelCanvas, fallback, onPublished, onError, }?: CreateSlackFinalResponseArtifactPublisherOptions): SlackFinalResponseArtifactPublisher;
56
+
57
+ export { type CreateSlackFinalResponseArtifactPublisherOptions, type SlackFinalResponseArtifactContext, type SlackFinalResponseArtifactDeliveryMode, type SlackFinalResponseArtifactPublisher, type SlackFinalResponseArtifactResult, type SlackFinalResponseArtifactValueResolver, createSlackFinalResponseArtifactPublisher };
@@ -0,0 +1,6 @@
1
+ import {
2
+ createSlackFinalResponseArtifactPublisher
3
+ } from "../chunk-NNCVHQC4.js";
4
+ export {
5
+ createSlackFinalResponseArtifactPublisher
6
+ };
@@ -1,12 +1,14 @@
1
- import { C as CreateSlackAssistantBridgeOptions, S as SlackAssistantBridge } from '../options-Uf-qmQKN.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-Uf-qmQKN.js';
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';
3
3
  export { ParsedAssistantUserMessage, createSlackAssistantThreadContextStore, parseSlackMessageActivityFromMessageEvent } from '@cuylabs/channel-slack/assistant';
4
4
  import '@cuylabs/agent-core';
5
5
  import '@slack/bolt';
6
6
  import '@slack/web-api';
7
7
  import '@cuylabs/channel-slack/core';
8
8
  import '../interactive-o_NZb-Xg.js';
9
- import '../options-C7OYeNR-.js';
9
+ import '../options-BcDReOJv.js';
10
+ import '../artifacts/index.js';
11
+ import '@cuylabs/channel-slack/artifacts';
10
12
  import '@cuylabs/channel-slack/feedback';
11
13
 
12
14
  /**
@@ -3,9 +3,9 @@ import {
3
3
  createSlackAssistantThreadContextStore,
4
4
  parseSlackMessageActivityFromMessageEvent,
5
5
  resolveAssistantSessionId
6
- } from "../chunk-ZDVD46RT.js";
6
+ } from "../chunk-MGBNGG4D.js";
7
7
  import "../chunk-ELR6MQD7.js";
8
- import "../chunk-NOVWLAVP.js";
8
+ import "../chunk-TMADMHBN.js";
9
9
  export {
10
10
  createSlackAssistantBridge,
11
11
  createSlackAssistantThreadContextStore,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  installSlackAgentAppSurface
3
- } from "./chunk-P7KK5GQG.js";
3
+ } from "./chunk-7DUO5BMW.js";
4
4
 
5
5
  // src/app.ts
6
6
  import {
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  createSlackAssistantBridge
3
- } from "./chunk-ZDVD46RT.js";
3
+ } from "./chunk-MGBNGG4D.js";
4
4
  import {
5
5
  createSlackFeedbackBlock,
6
6
  registerSlackFeedbackAction
7
7
  } from "./chunk-ELR6MQD7.js";
8
8
  import {
9
9
  createSlackChannelAdapter
10
- } from "./chunk-TIQGJ52F.js";
10
+ } from "./chunk-FQWFB54C.js";
11
11
 
12
12
  // src/app-surface.ts
13
13
  var DEFAULT_TIMEOUT_MS = 12e4;
@@ -26,6 +26,7 @@ function installSlackAgentAppSurface(boltApp, options) {
26
26
  prepareTurn,
27
27
  resolveSession,
28
28
  interactive,
29
+ viewWorkflows,
29
30
  ...assistantBridgeOptions
30
31
  } = options;
31
32
  const feedbackConfig = feedbackOption === false ? void 0 : feedbackOption ?? (onFeedback ? { onFeedback } : {});
@@ -63,6 +64,7 @@ function installSlackAgentAppSurface(boltApp, options) {
63
64
  formatToolTitle: assistantBridgeOptions.formatToolTitle,
64
65
  formatToolUpdate: assistantBridgeOptions.formatToolUpdate,
65
66
  formatToolDetails: assistantBridgeOptions.formatToolDetails,
67
+ formatToolResultOutput: assistantBridgeOptions.formatToolResultOutput,
66
68
  formatToolError: assistantBridgeOptions.formatToolError,
67
69
  formatReasoningUpdate: assistantBridgeOptions.formatReasoningUpdate,
68
70
  chatStreamBufferSize: assistantBridgeOptions.chatStreamBufferSize,
@@ -70,6 +72,12 @@ function installSlackAgentAppSurface(boltApp, options) {
70
72
  ...assistantBridgeOptions.chatStreamStartArgs ?? {},
71
73
  task_display_mode: assistantBridgeOptions.taskDisplayMode ?? "timeline"
72
74
  },
75
+ publishFinalResponseArtifact: assistantBridgeOptions.publishFinalResponseArtifact,
76
+ finalResponseArtifactMode: assistantBridgeOptions.finalResponseArtifactMode,
77
+ finalResponseArtifactStreamThreshold: assistantBridgeOptions.finalResponseArtifactStreamThreshold,
78
+ formatFinalResponseArtifactContinuationNotice: assistantBridgeOptions.formatFinalResponseArtifactContinuationNotice,
79
+ formatFinalResponseArtifactMessage: assistantBridgeOptions.formatFinalResponseArtifactMessage,
80
+ onFinalResponseArtifactError: assistantBridgeOptions.onFinalResponseArtifactError,
73
81
  ...typeof assistantBridgeOptions.initialStatus === "object" && assistantBridgeOptions.initialStatus !== null ? { initialStatus: assistantBridgeOptions.initialStatus } : {},
74
82
  ...formatting?.formatChatMarkdown !== void 0 ? { formatChatMarkdown: formatting.formatChatMarkdown } : {},
75
83
  ...formatting?.formatMessageText ? { formatMessageText: formatting.formatMessageText } : {},
@@ -101,6 +109,7 @@ function installSlackAgentAppSurface(boltApp, options) {
101
109
  });
102
110
  }
103
111
  interactive?.install(boltApp);
112
+ viewWorkflows?.install(boltApp);
104
113
  return { bridge };
105
114
  }
106
115
  function mergeChatStreamFinalArgs(base, feedbackBlock) {
@@ -0,0 +1,226 @@
1
+ // src/views/controller.ts
2
+ import { registerSlackViewWorkflow } from "@cuylabs/channel-slack/views";
3
+
4
+ // src/views/state.ts
5
+ function extractSlackAgentViewStateValues(viewOrState) {
6
+ const state = isRecord(viewOrState) ? isRecord(viewOrState.state) ? viewOrState.state : viewOrState : {};
7
+ const rawValues = isRecord(state.values) ? state.values : {};
8
+ const values = {};
9
+ for (const [blockId, rawActions] of Object.entries(rawValues)) {
10
+ if (!isRecord(rawActions)) {
11
+ continue;
12
+ }
13
+ const actions = {};
14
+ for (const [actionId, rawAction] of Object.entries(rawActions)) {
15
+ actions[actionId] = extractSlackAgentViewActionValue(rawAction);
16
+ }
17
+ values[blockId] = actions;
18
+ }
19
+ return values;
20
+ }
21
+ function readSlackAgentViewStateValue(valuesOrView, blockId, actionId) {
22
+ const values = looksLikeExtractedStateValues(valuesOrView) ? valuesOrView : extractSlackAgentViewStateValues(valuesOrView);
23
+ return values[blockId]?.[actionId];
24
+ }
25
+ function extractSlackAgentViewActionValue(rawAction) {
26
+ if (!isRecord(rawAction)) {
27
+ return void 0;
28
+ }
29
+ if ("value" in rawAction && typeof rawAction.value !== "undefined") {
30
+ return normalizeValue(rawAction.value);
31
+ }
32
+ if (isRecord(rawAction.selected_option)) {
33
+ return readOptionValue(rawAction.selected_option);
34
+ }
35
+ if (Array.isArray(rawAction.selected_options)) {
36
+ return rawAction.selected_options.map(readOptionValue).filter(isString);
37
+ }
38
+ for (const field of [
39
+ "selected_user",
40
+ "selected_users",
41
+ "selected_channel",
42
+ "selected_channels",
43
+ "selected_conversation",
44
+ "selected_conversations",
45
+ "selected_date",
46
+ "selected_time",
47
+ "selected_date_time"
48
+ ]) {
49
+ const value = rawAction[field];
50
+ if (typeof value !== "undefined") {
51
+ return normalizeValue(value);
52
+ }
53
+ }
54
+ if (typeof rawAction.checked === "boolean") {
55
+ return rawAction.checked;
56
+ }
57
+ return rawAction;
58
+ }
59
+ function readOptionValue(option) {
60
+ if (!isRecord(option)) {
61
+ return "";
62
+ }
63
+ if (typeof option.value === "string") {
64
+ return option.value;
65
+ }
66
+ const text = option.text;
67
+ if (isRecord(text) && typeof text.text === "string") {
68
+ return text.text;
69
+ }
70
+ return "";
71
+ }
72
+ function normalizeValue(value) {
73
+ if (typeof value === "string" || typeof value === "boolean" || typeof value === "number") {
74
+ return value;
75
+ }
76
+ if (Array.isArray(value)) {
77
+ return value.filter(isString);
78
+ }
79
+ return isRecord(value) ? value : void 0;
80
+ }
81
+ function looksLikeExtractedStateValues(value) {
82
+ if (!isRecord(value) || "state" in value || "values" in value) {
83
+ return false;
84
+ }
85
+ return Object.values(value).every(isRecord);
86
+ }
87
+ function isRecord(value) {
88
+ return typeof value === "object" && value !== null;
89
+ }
90
+ function isString(value) {
91
+ return typeof value === "string";
92
+ }
93
+
94
+ // src/views/controller.ts
95
+ var DEFAULT_NAMESPACE = "agent_slack_view";
96
+ var installedCallbackIds = /* @__PURE__ */ new WeakMap();
97
+ function createSlackAgentViewWorkflowController({
98
+ namespace = DEFAULT_NAMESPACE,
99
+ workflows = [],
100
+ onError
101
+ } = {}) {
102
+ const normalizedNamespace = normalizeIdentifier(namespace, "namespace");
103
+ const registeredWorkflows = /* @__PURE__ */ new Map();
104
+ const installedApps = /* @__PURE__ */ new Set();
105
+ function register(workflow) {
106
+ const workflowId = normalizeIdentifier(workflow.id, "workflow id");
107
+ if (!workflow.onSubmission && !workflow.onClose) {
108
+ throw new Error(
109
+ `Slack agent view workflow '${workflowId}' must define onSubmission or onClose.`
110
+ );
111
+ }
112
+ if (registeredWorkflows.has(workflowId)) {
113
+ throw new Error(`Duplicate Slack agent view workflow id: ${workflowId}`);
114
+ }
115
+ const callbackId = normalizeOptionalIdentifier(workflow.callbackId) ?? callbackIdFromWorkflowId(normalizedNamespace, workflowId);
116
+ if ([...registeredWorkflows.values()].some(
117
+ (item) => item.callbackId === callbackId
118
+ )) {
119
+ throw new Error(`Duplicate Slack view callback id: ${callbackId}`);
120
+ }
121
+ const registered = {
122
+ ...workflow,
123
+ id: workflowId,
124
+ callbackId
125
+ };
126
+ registeredWorkflows.set(workflowId, registered);
127
+ for (const app of installedApps) {
128
+ installWorkflow(app, registered);
129
+ }
130
+ return callbackId;
131
+ }
132
+ function callbackIdFor(workflowId) {
133
+ const normalizedWorkflowId = normalizeIdentifier(workflowId, "workflow id");
134
+ return registeredWorkflows.get(normalizedWorkflowId)?.callbackId ?? callbackIdFromWorkflowId(normalizedNamespace, normalizedWorkflowId);
135
+ }
136
+ function list() {
137
+ return [...registeredWorkflows.values()].map(({ id, callbackId }) => ({
138
+ id,
139
+ callbackId
140
+ }));
141
+ }
142
+ function install(app) {
143
+ installedApps.add(app);
144
+ for (const workflow of registeredWorkflows.values()) {
145
+ installWorkflow(app, workflow);
146
+ }
147
+ }
148
+ function installWorkflow(app, workflow) {
149
+ const callbackIds = callbackIdsForApp(app);
150
+ if (callbackIds.has(workflow.callbackId)) {
151
+ throw new Error(
152
+ `Slack view callback id '${workflow.callbackId}' is already installed on this Bolt app.`
153
+ );
154
+ }
155
+ callbackIds.add(workflow.callbackId);
156
+ registerSlackViewWorkflow({
157
+ boltApp: app,
158
+ callbackId: workflow.callbackId,
159
+ ...workflow.decodePrivateMetadata ? { decodePrivateMetadata: workflow.decodePrivateMetadata } : {},
160
+ ...workflow.onSubmission ? {
161
+ onSubmission: async (context) => await workflow.onSubmission(enrichContext(workflow, context))
162
+ } : {},
163
+ ...workflow.onClose ? {
164
+ onClose: async (context) => await workflow.onClose(enrichContext(workflow, context))
165
+ } : {},
166
+ onError: async (error, context) => {
167
+ const enriched = enrichContext(workflow, {
168
+ ...context,
169
+ metadata: context.metadata
170
+ });
171
+ if (workflow.onError) {
172
+ await workflow.onError(error, enriched);
173
+ return;
174
+ }
175
+ await onError?.(error, enriched);
176
+ }
177
+ });
178
+ }
179
+ for (const workflow of workflows) {
180
+ register(workflow);
181
+ }
182
+ return {
183
+ namespace: normalizedNamespace,
184
+ register,
185
+ callbackIdFor,
186
+ list,
187
+ install
188
+ };
189
+ }
190
+ function enrichContext(workflow, context) {
191
+ const stateValues = extractSlackAgentViewStateValues(context.view);
192
+ return {
193
+ ...context,
194
+ workflow: { id: workflow.id, callbackId: workflow.callbackId },
195
+ stateValues,
196
+ getStateValue: (blockId, actionId) => readSlackAgentViewStateValue(stateValues, blockId, actionId)
197
+ };
198
+ }
199
+ function callbackIdsForApp(app) {
200
+ let callbackIds = installedCallbackIds.get(app);
201
+ if (!callbackIds) {
202
+ callbackIds = /* @__PURE__ */ new Set();
203
+ installedCallbackIds.set(app, callbackIds);
204
+ }
205
+ return callbackIds;
206
+ }
207
+ function callbackIdFromWorkflowId(namespace, workflowId) {
208
+ return `${namespace}_${workflowId}`;
209
+ }
210
+ function normalizeOptionalIdentifier(value) {
211
+ const normalized = value?.trim();
212
+ return normalized ? normalized : void 0;
213
+ }
214
+ function normalizeIdentifier(value, label) {
215
+ const normalized = value.trim().replace(/[^A-Za-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "");
216
+ if (!normalized) {
217
+ throw new Error(`Slack agent view workflow ${label} cannot be empty.`);
218
+ }
219
+ return normalized;
220
+ }
221
+
222
+ export {
223
+ extractSlackAgentViewStateValues,
224
+ readSlackAgentViewStateValue,
225
+ createSlackAgentViewWorkflowController
226
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createSlackAssistantBridge
3
- } from "./chunk-ZDVD46RT.js";
3
+ } from "./chunk-MGBNGG4D.js";
4
4
 
5
5
  // src/express-assistant.ts
6
6
  import {
@@ -2,7 +2,7 @@ import {
2
2
  UnsupportedSlackInteractiveRequestError,
3
3
  bridgeAgentEventsToSlack,
4
4
  resolveSlackEventBridgeOptions
5
- } from "./chunk-NOVWLAVP.js";
5
+ } from "./chunk-TMADMHBN.js";
6
6
 
7
7
  // src/adapter/adapter.ts
8
8
  import { withinScope } from "@cuylabs/agent-core";
@@ -73,6 +73,11 @@ function buildThreadPayload(info, respondInThread) {
73
73
  function buildResponseSink(say, client, info, respondInThread, chatStreamStartArgs, sayStream) {
74
74
  const threadPayload = buildThreadPayload(info, respondInThread);
75
75
  return {
76
+ artifactClient: client,
77
+ artifactTarget: {
78
+ channelId: info.channelId,
79
+ ...threadPayload.thread_ts ? { threadTs: threadPayload.thread_ts } : {}
80
+ },
76
81
  async postMessage(text) {
77
82
  const result = await say({ text, ...threadPayload });
78
83
  const response = result;
@@ -167,6 +172,7 @@ function createSlackChannelAdapter(options) {
167
172
  formatToolTitle: options.formatToolTitle,
168
173
  formatToolUpdate: options.formatToolUpdate,
169
174
  formatToolDetails: options.formatToolDetails,
175
+ formatToolResultOutput: options.formatToolResultOutput,
170
176
  formatToolError: options.formatToolError,
171
177
  formatReasoningUpdate: options.formatReasoningUpdate,
172
178
  interactiveMode: options.interactiveMode,
@@ -180,7 +186,13 @@ function createSlackChannelAdapter(options) {
180
186
  maxTaskUpdates: options.maxTaskUpdates,
181
187
  maxTaskUpdateTextChars: options.maxTaskUpdateTextChars,
182
188
  maxTaskUpdateFieldChars: options.maxTaskUpdateFieldChars,
183
- chatStreamFinalArgs: options.chatStreamFinalArgs
189
+ chatStreamFinalArgs: options.chatStreamFinalArgs,
190
+ publishFinalResponseArtifact: options.publishFinalResponseArtifact,
191
+ finalResponseArtifactMode: options.finalResponseArtifactMode,
192
+ finalResponseArtifactStreamThreshold: options.finalResponseArtifactStreamThreshold,
193
+ formatFinalResponseArtifactContinuationNotice: options.formatFinalResponseArtifactContinuationNotice,
194
+ formatFinalResponseArtifactMessage: options.formatFinalResponseArtifactMessage,
195
+ onFinalResponseArtifactError: options.onFinalResponseArtifactError
184
196
  }
185
197
  );
186
198
  const timeout = options.timeout ?? 12e4;
@@ -7,7 +7,7 @@ import {
7
7
  UnsupportedSlackInteractiveRequestError,
8
8
  bridgeAgentEventsToSlack,
9
9
  resolveSlackEventBridgeOptions
10
- } from "./chunk-NOVWLAVP.js";
10
+ } from "./chunk-TMADMHBN.js";
11
11
 
12
12
  // src/assistant/bridge.ts
13
13
  import { Assistant } from "@slack/bolt";
@@ -239,6 +239,11 @@ function createAssistantSink(params) {
239
239
  return stream;
240
240
  }
241
241
  return {
242
+ artifactClient: params.client,
243
+ artifactTarget: {
244
+ channelId: params.channel,
245
+ threadTs: params.threadTs
246
+ },
242
247
  async postMessage() {
243
248
  throw new Error(
244
249
  "Assistant bridge uses chat-stream mode and does not support postMessage."
@@ -427,6 +432,7 @@ function createUserMessageHandler(deps) {
427
432
  ...options.formatToolTitle ? { formatToolTitle: options.formatToolTitle } : {},
428
433
  ...options.formatToolUpdate ? { formatToolUpdate: options.formatToolUpdate } : {},
429
434
  ...options.formatToolDetails ? { formatToolDetails: options.formatToolDetails } : {},
435
+ ...options.formatToolResultOutput ? { formatToolResultOutput: options.formatToolResultOutput } : {},
430
436
  ...options.formatToolError ? { formatToolError: options.formatToolError } : {},
431
437
  ...options.formatReasoningUpdate ? { formatReasoningUpdate: options.formatReasoningUpdate } : {},
432
438
  ...options.chatStreamBufferSize !== void 0 ? { chatStreamBufferSize: options.chatStreamBufferSize } : {},
@@ -434,6 +440,22 @@ function createUserMessageHandler(deps) {
434
440
  ...options.maxTaskUpdateTextChars !== void 0 ? { maxTaskUpdateTextChars: options.maxTaskUpdateTextChars } : {},
435
441
  ...options.maxTaskUpdateFieldChars !== void 0 ? { maxTaskUpdateFieldChars: options.maxTaskUpdateFieldChars } : {},
436
442
  ...chatStreamFinalArgs ? { chatStreamFinalArgs } : {},
443
+ ...options.publishFinalResponseArtifact ? {
444
+ publishFinalResponseArtifact: options.publishFinalResponseArtifact
445
+ } : {},
446
+ ...options.finalResponseArtifactMode ? { finalResponseArtifactMode: options.finalResponseArtifactMode } : {},
447
+ ...options.finalResponseArtifactStreamThreshold !== void 0 ? {
448
+ finalResponseArtifactStreamThreshold: options.finalResponseArtifactStreamThreshold
449
+ } : {},
450
+ ...options.formatFinalResponseArtifactContinuationNotice ? {
451
+ formatFinalResponseArtifactContinuationNotice: options.formatFinalResponseArtifactContinuationNotice
452
+ } : {},
453
+ ...options.formatFinalResponseArtifactMessage ? {
454
+ formatFinalResponseArtifactMessage: options.formatFinalResponseArtifactMessage
455
+ } : {},
456
+ ...options.onFinalResponseArtifactError ? {
457
+ onFinalResponseArtifactError: options.onFinalResponseArtifactError
458
+ } : {},
437
459
  formatMessageText: messageFormatter,
438
460
  onStatusChange: async (label, event) => {
439
461
  const update = await resolveStatusUpdate(