@cuylabs/channel-slack-agent-core 0.5.1 → 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 (89) hide show
  1. package/README.md +20 -39
  2. package/dist/{adapter.d.ts → adapter/index.d.ts} +7 -5
  3. package/dist/adapter/index.js +9 -0
  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 +5 -7
  7. package/dist/app.d.ts +9 -4
  8. package/dist/app.js +6 -9
  9. package/dist/artifacts/index.d.ts +57 -0
  10. package/dist/artifacts/index.js +6 -0
  11. package/dist/{assistant.d.ts → assistant/index.d.ts} +6 -4
  12. package/dist/{assistant.js → assistant/index.js} +3 -5
  13. package/dist/{chunk-CYEBGC6G.js → chunk-76SRS54H.js} +5 -5
  14. package/dist/{chunk-M64Z6TYL.js → chunk-7DUO5BMW.js} +16 -6
  15. package/dist/{chunk-NIPAN4KA.js → chunk-A2PLAVW6.js} +2 -3
  16. package/dist/chunk-C7CHMYV6.js +226 -0
  17. package/dist/chunk-C7VSW4ZM.js +548 -0
  18. package/dist/{chunk-JMLB7A2V.js → chunk-DJPKRKGP.js} +5 -5
  19. package/dist/chunk-ELR6MQD7.js +12 -0
  20. package/dist/{chunk-FDRQOG7Q.js → chunk-FQWFB54C.js} +26 -15
  21. package/dist/{chunk-BFUPAJON.js → chunk-MGBNGG4D.js} +59 -37
  22. package/dist/chunk-NNCVHQC4.js +94 -0
  23. package/dist/chunk-P7PFQ3SQ.js +396 -0
  24. package/dist/{chunk-WO4BJMF3.js → chunk-TCNJY7QA.js} +5 -5
  25. package/dist/{chunk-DHPD4XH5.js → chunk-TMADMHBN.js} +210 -29
  26. package/dist/{chunk-IWUYIAY5.js → chunk-VMVQIDNR.js} +5 -7
  27. package/dist/{chunk-IXY3BXU5.js → chunk-X7ILLZZP.js} +359 -2
  28. package/dist/context-fragments-CQEDcjYR.d.ts +30 -0
  29. package/dist/express-assistant.d.ts +6 -3
  30. package/dist/express-assistant.js +4 -7
  31. package/dist/express.d.ts +7 -3
  32. package/dist/express.js +3 -6
  33. package/dist/feedback/index.d.ts +1 -0
  34. package/dist/feedback/index.js +10 -0
  35. package/dist/history/index.d.ts +61 -0
  36. package/dist/history/index.js +8 -0
  37. package/dist/index.d.ts +23 -16
  38. package/dist/index.js +81 -160
  39. package/dist/interactive/index.d.ts +71 -0
  40. package/dist/{interactive.js → interactive/index.js} +9 -4
  41. package/dist/mcp.js +0 -1
  42. package/dist/{options-C7OYeNR-.d.ts → options-BcDReOJv.d.ts} +48 -0
  43. package/dist/{options-Uf-qmQKN.d.ts → options-CdqBABcM.d.ts} +26 -1
  44. package/dist/{shared.d.ts → shared/index.d.ts} +24 -36
  45. package/dist/{shared.js → shared/index.js} +2 -6
  46. package/dist/socket.d.ts +9 -4
  47. package/dist/socket.js +6 -9
  48. package/dist/source/index.d.ts +154 -0
  49. package/dist/source/index.js +38 -0
  50. package/dist/{types-BqRzb_Cd.d.ts → types-CRWzJB5G.d.ts} +35 -0
  51. package/dist/types-CiwGU6zC.d.ts +56 -0
  52. package/dist/views/index.d.ts +8 -0
  53. package/dist/views/index.js +10 -0
  54. package/docs/README.md +18 -0
  55. package/docs/concepts/final-response-artifacts.md +39 -0
  56. package/docs/concepts/interactive-requests.md +43 -0
  57. package/docs/concepts/tool-task-rendering.md +46 -0
  58. package/docs/concepts/view-workflows.md +52 -0
  59. package/docs/reference/boundary.md +22 -0
  60. package/docs/reference/exports.md +26 -0
  61. package/package.json +36 -50
  62. package/dist/adapter.js +0 -13
  63. package/dist/bolt.d.ts +0 -8
  64. package/dist/bolt.js +0 -10
  65. package/dist/chunk-2SUAW6MV.js +0 -12
  66. package/dist/chunk-645NNJIM.js +0 -12
  67. package/dist/chunk-ANIZ5NT4.js +0 -12
  68. package/dist/chunk-GNXWTKQ6.js +0 -48
  69. package/dist/chunk-HFT2FXJP.js +0 -12
  70. package/dist/chunk-I2KLQ2HA.js +0 -22
  71. package/dist/chunk-K2E6A377.js +0 -12
  72. package/dist/chunk-NDVXBI7Z.js +0 -12
  73. package/dist/chunk-PX4RGO3N.js +0 -12
  74. package/dist/chunk-VHGV66M7.js +0 -12
  75. package/dist/diagnostics.d.ts +0 -1
  76. package/dist/diagnostics.js +0 -10
  77. package/dist/feedback.d.ts +0 -1
  78. package/dist/feedback.js +0 -10
  79. package/dist/history.d.ts +0 -1
  80. package/dist/history.js +0 -10
  81. package/dist/interactive.d.ts +0 -30
  82. package/dist/policy.d.ts +0 -1
  83. package/dist/policy.js +0 -10
  84. package/dist/setup.d.ts +0 -1
  85. package/dist/setup.js +0 -10
  86. package/dist/targets.d.ts +0 -1
  87. package/dist/targets.js +0 -10
  88. package/dist/users.d.ts +0 -1
  89. package/dist/users.js +0 -10
package/dist/socket.js CHANGED
@@ -1,15 +1,12 @@
1
1
  import {
2
2
  mountSlackAgentAppSocket,
3
3
  mountSlackAssistantAgentSocket
4
- } from "./chunk-IWUYIAY5.js";
5
- import "./chunk-M64Z6TYL.js";
6
- import "./chunk-BFUPAJON.js";
7
- import "./chunk-VHGV66M7.js";
8
- import "./chunk-FDRQOG7Q.js";
9
- import "./chunk-GNXWTKQ6.js";
10
- import "./chunk-DHPD4XH5.js";
11
- import "./chunk-ANIZ5NT4.js";
12
- import "./chunk-I2KLQ2HA.js";
4
+ } from "./chunk-VMVQIDNR.js";
5
+ import "./chunk-7DUO5BMW.js";
6
+ import "./chunk-MGBNGG4D.js";
7
+ import "./chunk-ELR6MQD7.js";
8
+ import "./chunk-FQWFB54C.js";
9
+ import "./chunk-TMADMHBN.js";
13
10
  export {
14
11
  mountSlackAgentAppSocket,
15
12
  mountSlackAssistantAgentSocket
@@ -0,0 +1,154 @@
1
+ import { AgentEvent, Logger } from '@cuylabs/agent-core';
2
+ import { DispatchEventStore } from '@cuylabs/agent-core/dispatch';
3
+ import { SlackChannelType } from '@cuylabs/channel-slack/core';
4
+
5
+ interface SlackAgentEventQueueState {
6
+ deliveredSequences: Set<number>;
7
+ lastQueuedStatusByKey: Map<string, string>;
8
+ sessionId?: string;
9
+ turnId?: string;
10
+ }
11
+ interface SlackAgentEventQueue {
12
+ push(event: AgentEvent, coalesce?: (previous: AgentEvent, next: AgentEvent) => AgentEvent | undefined): void;
13
+ }
14
+ interface RouteSlackAgentEventOptions {
15
+ event: AgentEvent;
16
+ logger?: Pick<Logger, "debug">;
17
+ onRecord?: (event: AgentEvent, sequence?: number) => void;
18
+ queue: SlackAgentEventQueue;
19
+ sequence?: number;
20
+ state: SlackAgentEventQueueState;
21
+ }
22
+ declare function coalesceSlackAgentEvents(previous: AgentEvent, next: AgentEvent): AgentEvent | undefined;
23
+ declare function routeSlackAgentEvent({ event, logger, onRecord, queue, sequence, state, }: RouteSlackAgentEventOptions): boolean;
24
+ declare function shouldQueueSlackAgentEvent({ event, logger, sequence, state, }: {
25
+ event: AgentEvent;
26
+ logger?: Pick<Logger, "debug">;
27
+ sequence?: number;
28
+ state: SlackAgentEventQueueState;
29
+ }): boolean;
30
+
31
+ declare function immediateSlackTextResponse(text: string): AsyncGenerator<AgentEvent>;
32
+ declare function isSlackCancelMessage(message: string): boolean;
33
+ type SlackTypedApprovalAction = "allow" | "deny" | "remember";
34
+ declare function resolveSlackTypedApprovalAction(message: string): SlackTypedApprovalAction | undefined;
35
+ declare function isRunningAgentTurnError(error: unknown): boolean;
36
+ declare function isAbortLikeError(error: unknown): boolean;
37
+
38
+ type SlackTurnPhase = "starting" | "reasoning" | "tool-running" | "waiting-approval" | "waiting-input" | "streaming" | "completed" | "failed" | "cancelled";
39
+ interface SlackActiveToolCall {
40
+ startedAtMs: number;
41
+ toolCallId: string;
42
+ toolName: string;
43
+ }
44
+ interface SlackTurnActivityState {
45
+ currentTool?: SlackActiveToolCall;
46
+ lastActivityAtMs: number;
47
+ phase: SlackTurnPhase;
48
+ }
49
+ interface SlackTurnStatusVisibilityState extends SlackTurnActivityState {
50
+ eventCounts: Record<string, number>;
51
+ firstEventAtMs?: number;
52
+ firstEventType?: string;
53
+ sessionId?: string;
54
+ startedAtMs: number;
55
+ statusWarningsSent: Set<string>;
56
+ turnId?: string;
57
+ }
58
+ interface SlackTurnStatusVisibilityOptions {
59
+ checkIntervalMs?: number;
60
+ toolStaleWarningMs?: number;
61
+ turnStaleWarningMs?: number;
62
+ }
63
+ interface ResolvedSlackTurnStatusVisibilityOptions {
64
+ checkIntervalMs: number;
65
+ toolStaleWarningMs: number;
66
+ turnStaleWarningMs: number;
67
+ }
68
+ interface SlackTurnStatusVisibilityWarning {
69
+ elapsedMs: number;
70
+ firstEventLatencyMs?: number;
71
+ firstEventType?: string;
72
+ id: string;
73
+ idleMs: number;
74
+ message: string;
75
+ phase: SlackTurnPhase;
76
+ receivedEventCount: number;
77
+ sessionId?: string;
78
+ staleBeforeFirstEvent: boolean;
79
+ thresholdMs: number;
80
+ toolCallId?: string;
81
+ toolName?: string;
82
+ turnId?: string;
83
+ type: "tool" | "turn";
84
+ }
85
+ interface InspectSlackTurnStatusVisibilityOptions {
86
+ formatToolStaleStatus?: (toolName: string) => string;
87
+ formatTurnStaleStatus?: (phase: SlackTurnPhase) => string;
88
+ nowMs?: number;
89
+ options: ResolvedSlackTurnStatusVisibilityOptions;
90
+ state: SlackTurnStatusVisibilityState;
91
+ }
92
+ declare function resolveSlackTurnStatusVisibilityOptions(options: SlackTurnStatusVisibilityOptions | undefined): ResolvedSlackTurnStatusVisibilityOptions;
93
+ declare function shouldInspectSlackTurnStatusVisibility(options: ResolvedSlackTurnStatusVisibilityOptions): boolean;
94
+ declare function recordSlackTurnActivity(state: SlackTurnActivityState, event: AgentEvent, nowMs?: number): void;
95
+ declare function inspectSlackTurnStatusVisibility({ formatToolStaleStatus, formatTurnStaleStatus, nowMs, options, state, }: InspectSlackTurnStatusVisibilityOptions): SlackTurnStatusVisibilityWarning | undefined;
96
+ declare function isSlackWaitingForHumanTurnPhase(phase: SlackTurnPhase): boolean;
97
+ declare function isSlackTerminalTurnPhase(phase: SlackTurnPhase): boolean;
98
+
99
+ type SlackSubagentStartedEvent = Extract<AgentEvent, {
100
+ type: "subagent-start";
101
+ }>;
102
+ type SlackSubagentTerminalEvent = Extract<AgentEvent, {
103
+ type: "subagent-complete" | "subagent-error";
104
+ }>;
105
+ interface SlackSubagentCompletionSlackContext {
106
+ channelId?: string;
107
+ channelType?: SlackChannelType;
108
+ messageTs?: string;
109
+ teamId?: string;
110
+ threadTs?: string;
111
+ }
112
+ interface SlackSubagentCompletionTurnContext {
113
+ sessionId: string;
114
+ slack?: SlackSubagentCompletionSlackContext;
115
+ turnId: string;
116
+ }
117
+ interface SlackSubagentCompletionMessage {
118
+ blocks?: unknown[];
119
+ channel: string;
120
+ text: string;
121
+ thread_ts?: string;
122
+ }
123
+ type SlackSubagentCompletionPoster = (message: SlackSubagentCompletionMessage) => Promise<void>;
124
+ interface SlackSubagentCompletionRun {
125
+ dispatchId: string;
126
+ role: string;
127
+ sessionId: string;
128
+ slack: Required<Pick<SlackSubagentCompletionSlackContext, "channelId" | "threadTs">> & Omit<SlackSubagentCompletionSlackContext, "channelId" | "threadTs">;
129
+ title: string;
130
+ turnId: string;
131
+ }
132
+ interface SlackSubagentCompletionMessageFormatterOptions {
133
+ event: SlackSubagentTerminalEvent;
134
+ run: SlackSubagentCompletionRun;
135
+ }
136
+ interface SlackSubagentCompletionNotifierOptions {
137
+ enabled?: boolean;
138
+ formatMessage?: (options: SlackSubagentCompletionMessageFormatterOptions) => SlackSubagentCompletionMessage;
139
+ logger?: Pick<Logger, "debug" | "info" | "warn">;
140
+ postMessage?: SlackSubagentCompletionPoster;
141
+ }
142
+ declare function createSlackSubagentCompletionNotifier({ enabled, formatMessage, logger, postMessage: initialPostMessage, }?: SlackSubagentCompletionNotifierOptions): {
143
+ clear(): void;
144
+ markResultDeliveredInline: (event: SlackSubagentTerminalEvent) => void;
145
+ markTurnDetached: (turnId: string) => void;
146
+ postDetachedCompletionsFromEventStore: (eventStore: DispatchEventStore) => Promise<void>;
147
+ postTerminalEvent: (event: SlackSubagentTerminalEvent) => Promise<void>;
148
+ setPostMessage(nextPostMessage: SlackSubagentCompletionPoster | undefined): void;
149
+ trackStartedRun: (turn: SlackSubagentCompletionTurnContext, event: SlackSubagentStartedEvent) => void;
150
+ };
151
+ declare function isSlackSubagentTerminalEvent(event: AgentEvent): event is SlackSubagentTerminalEvent;
152
+ declare function formatDefaultSlackSubagentCompletionMessage({ event, run, }: SlackSubagentCompletionMessageFormatterOptions): SlackSubagentCompletionMessage;
153
+
154
+ export { type InspectSlackTurnStatusVisibilityOptions, type ResolvedSlackTurnStatusVisibilityOptions, type RouteSlackAgentEventOptions, type SlackActiveToolCall, type SlackAgentEventQueue, type SlackAgentEventQueueState, type SlackSubagentCompletionMessage, type SlackSubagentCompletionMessageFormatterOptions, type SlackSubagentCompletionNotifierOptions, type SlackSubagentCompletionPoster, type SlackSubagentCompletionRun, type SlackSubagentCompletionSlackContext, type SlackSubagentCompletionTurnContext, type SlackTurnActivityState, type SlackTurnPhase, type SlackTurnStatusVisibilityOptions, type SlackTurnStatusVisibilityState, type SlackTurnStatusVisibilityWarning, type SlackTypedApprovalAction, coalesceSlackAgentEvents, createSlackSubagentCompletionNotifier, formatDefaultSlackSubagentCompletionMessage, immediateSlackTextResponse, inspectSlackTurnStatusVisibility, isAbortLikeError, isRunningAgentTurnError, isSlackCancelMessage, isSlackSubagentTerminalEvent, isSlackTerminalTurnPhase, isSlackWaitingForHumanTurnPhase, recordSlackTurnActivity, resolveSlackTurnStatusVisibilityOptions, resolveSlackTypedApprovalAction, routeSlackAgentEvent, shouldInspectSlackTurnStatusVisibility, shouldQueueSlackAgentEvent };
@@ -0,0 +1,38 @@
1
+ import {
2
+ coalesceSlackAgentEvents,
3
+ createSlackSubagentCompletionNotifier,
4
+ formatDefaultSlackSubagentCompletionMessage,
5
+ immediateSlackTextResponse,
6
+ inspectSlackTurnStatusVisibility,
7
+ isAbortLikeError,
8
+ isRunningAgentTurnError,
9
+ isSlackCancelMessage,
10
+ isSlackSubagentTerminalEvent,
11
+ isSlackTerminalTurnPhase,
12
+ isSlackWaitingForHumanTurnPhase,
13
+ recordSlackTurnActivity,
14
+ resolveSlackTurnStatusVisibilityOptions,
15
+ resolveSlackTypedApprovalAction,
16
+ routeSlackAgentEvent,
17
+ shouldInspectSlackTurnStatusVisibility,
18
+ shouldQueueSlackAgentEvent
19
+ } from "../chunk-C7VSW4ZM.js";
20
+ export {
21
+ coalesceSlackAgentEvents,
22
+ createSlackSubagentCompletionNotifier,
23
+ formatDefaultSlackSubagentCompletionMessage,
24
+ immediateSlackTextResponse,
25
+ inspectSlackTurnStatusVisibility,
26
+ isAbortLikeError,
27
+ isRunningAgentTurnError,
28
+ isSlackCancelMessage,
29
+ isSlackSubagentTerminalEvent,
30
+ isSlackTerminalTurnPhase,
31
+ isSlackWaitingForHumanTurnPhase,
32
+ recordSlackTurnActivity,
33
+ resolveSlackTurnStatusVisibilityOptions,
34
+ resolveSlackTypedApprovalAction,
35
+ routeSlackAgentEvent,
36
+ shouldInspectSlackTurnStatusVisibility,
37
+ shouldQueueSlackAgentEvent
38
+ };
@@ -1,5 +1,6 @@
1
1
  import { Agent, AgentTurnSource, AgentEvent, ApprovalEvent, Logger } from '@cuylabs/agent-core';
2
2
  import { SlackActivityInfo, SlackTurnRequestContext, SlackAssistantStatusUpdate, SlackChatStreamStartArgs, SlackUserIdentity, SlackTurnPreparation } from '@cuylabs/channel-slack/core';
3
+ import { S as SlackEventBridgeOptions } from './options-BcDReOJv.js';
3
4
  import { h as SlackInteractiveRequestHandler } from './interactive-o_NZb-Xg.js';
4
5
 
5
6
  /**
@@ -13,6 +14,9 @@ type HumanInputEvent = Extract<AgentEvent, {
13
14
  type SlackToolStartEvent = Extract<AgentEvent, {
14
15
  type: "tool-start";
15
16
  }>;
17
+ type SlackToolResultEvent = Extract<AgentEvent, {
18
+ type: "tool-result";
19
+ }>;
16
20
  type MaybePromise<T> = T | Promise<T>;
17
21
  /**
18
22
  * Session mapping strategy.
@@ -125,6 +129,13 @@ interface SlackChannelOptions {
125
129
  * @default details use the tool-start status text
126
130
  */
127
131
  formatToolDetails?: (event: SlackToolStartEvent) => string | undefined;
132
+ /**
133
+ * Format completed tool output shown in Slack task cards.
134
+ *
135
+ * Return `undefined` to use the default generic formatter. Return `null` to
136
+ * intentionally omit output for this result.
137
+ */
138
+ formatToolResultOutput?: (event: SlackToolResultEvent) => string | null | undefined;
128
139
  /**
129
140
  * Format the tool-error status text.
130
141
  * @default (toolName) => `⚠️ Tool ${toolName} encountered an error`
@@ -235,6 +246,30 @@ interface SlackChannelOptions {
235
246
  chatStreamFinalArgs?: {
236
247
  blocks?: unknown[];
237
248
  } & Record<string, unknown>;
249
+ /**
250
+ * Optional publisher for rich artifacts derived from the final accumulated
251
+ * answer, such as creating a Slack Canvas for long responses.
252
+ */
253
+ publishFinalResponseArtifact?: SlackEventBridgeOptions["publishFinalResponseArtifact"];
254
+ /**
255
+ * Controls whether final-response artifacts are supplemental or replace long
256
+ * Slack text with a compact artifact pointer.
257
+ *
258
+ * @default "supplemental"
259
+ */
260
+ finalResponseArtifactMode?: SlackEventBridgeOptions["finalResponseArtifactMode"];
261
+ /**
262
+ * Raw-character threshold for replacement-mode streaming suppression.
263
+ *
264
+ * @default 4000
265
+ */
266
+ finalResponseArtifactStreamThreshold?: SlackEventBridgeOptions["finalResponseArtifactStreamThreshold"];
267
+ /** Notice emitted when replacement mode moves the remaining response to an artifact. */
268
+ formatFinalResponseArtifactContinuationNotice?: SlackEventBridgeOptions["formatFinalResponseArtifactContinuationNotice"];
269
+ /** Compact final Slack message emitted after artifact publication succeeds. */
270
+ formatFinalResponseArtifactMessage?: SlackEventBridgeOptions["formatFinalResponseArtifactMessage"];
271
+ /** Diagnostics hook for final-response artifact publishing failures. */
272
+ onFinalResponseArtifactError?: SlackEventBridgeOptions["onFinalResponseArtifactError"];
238
273
  /**
239
274
  * Convert common markdown constructs emitted by models into Slack mrkdwn.
240
275
  *
@@ -0,0 +1,56 @@
1
+ import { App } from '@slack/bolt';
2
+ import { SlackViewPayload, RegisterSlackViewWorkflowOptions, SlackViewWorkflowContext, SlackViewSubmissionAckResponse } from '@cuylabs/channel-slack/views';
3
+
4
+ type SlackAgentViewStateValue = string | string[] | boolean | number | Record<string, unknown> | undefined;
5
+ type SlackAgentViewStateValues = Record<string, Record<string, SlackAgentViewStateValue>>;
6
+ declare function extractSlackAgentViewStateValues(viewOrState: SlackViewPayload | unknown): SlackAgentViewStateValues;
7
+ declare function readSlackAgentViewStateValue(valuesOrView: SlackAgentViewStateValues | SlackViewPayload | unknown, blockId: string, actionId: string): SlackAgentViewStateValue;
8
+
9
+ interface SlackAgentViewWorkflow {
10
+ id: string;
11
+ callbackId: string;
12
+ }
13
+ interface SlackAgentViewWorkflowContext<TMetadata = unknown> extends SlackViewWorkflowContext<TMetadata> {
14
+ workflow: SlackAgentViewWorkflow;
15
+ stateValues: SlackAgentViewStateValues;
16
+ getStateValue(blockId: string, actionId: string): SlackAgentViewStateValue;
17
+ }
18
+ interface SlackAgentViewWorkflowDefinition<TMetadata = unknown> {
19
+ /**
20
+ * Stable product/agent workflow id. Used to derive the default Slack
21
+ * callback id as `${namespace}_${id}`.
22
+ */
23
+ id: string;
24
+ /**
25
+ * Explicit Slack view callback id. Prefer this only when integrating with an
26
+ * existing Slack app surface.
27
+ */
28
+ callbackId?: string;
29
+ decodePrivateMetadata?: RegisterSlackViewWorkflowOptions<TMetadata>["decodePrivateMetadata"];
30
+ onSubmission?: (context: SlackAgentViewWorkflowContext<TMetadata>) => SlackViewSubmissionAckResponse | void | Promise<SlackViewSubmissionAckResponse | void>;
31
+ onClose?: (context: SlackAgentViewWorkflowContext<TMetadata>) => void | Promise<void>;
32
+ onError?: (error: unknown, context: Omit<SlackAgentViewWorkflowContext<TMetadata>, "metadata"> & {
33
+ metadata?: TMetadata | undefined;
34
+ }) => void | Promise<void>;
35
+ }
36
+ interface CreateSlackAgentViewWorkflowControllerOptions {
37
+ /**
38
+ * Namespace for derived Slack callback ids.
39
+ *
40
+ * @default "agent_slack_view"
41
+ */
42
+ namespace?: string;
43
+ workflows?: readonly SlackAgentViewWorkflowDefinition[];
44
+ onError?: (error: unknown, context: Omit<SlackAgentViewWorkflowContext, "metadata"> & {
45
+ metadata?: unknown;
46
+ }) => void | Promise<void>;
47
+ }
48
+ interface SlackAgentViewWorkflowController {
49
+ readonly namespace: string;
50
+ register<TMetadata = unknown>(workflow: SlackAgentViewWorkflowDefinition<TMetadata>): string;
51
+ callbackIdFor(workflowId: string): string;
52
+ list(): SlackAgentViewWorkflow[];
53
+ install(app: App): void;
54
+ }
55
+
56
+ export { type CreateSlackAgentViewWorkflowControllerOptions as C, type SlackAgentViewStateValue as S, type SlackAgentViewStateValues as a, type SlackAgentViewWorkflow as b, type SlackAgentViewWorkflowContext as c, type SlackAgentViewWorkflowController as d, type SlackAgentViewWorkflowDefinition as e, extractSlackAgentViewStateValues as f, readSlackAgentViewStateValue as r };
@@ -0,0 +1,8 @@
1
+ import { C as CreateSlackAgentViewWorkflowControllerOptions, d as SlackAgentViewWorkflowController } from '../types-CiwGU6zC.js';
2
+ export { S as SlackAgentViewStateValue, a as SlackAgentViewStateValues, b as SlackAgentViewWorkflow, c as SlackAgentViewWorkflowContext, e as SlackAgentViewWorkflowDefinition, f as extractSlackAgentViewStateValues, r as readSlackAgentViewStateValue } from '../types-CiwGU6zC.js';
3
+ import '@slack/bolt';
4
+ import '@cuylabs/channel-slack/views';
5
+
6
+ declare function createSlackAgentViewWorkflowController({ namespace, workflows, onError, }?: CreateSlackAgentViewWorkflowControllerOptions): SlackAgentViewWorkflowController;
7
+
8
+ export { CreateSlackAgentViewWorkflowControllerOptions, SlackAgentViewWorkflowController, createSlackAgentViewWorkflowController };
@@ -0,0 +1,10 @@
1
+ import {
2
+ createSlackAgentViewWorkflowController,
3
+ extractSlackAgentViewStateValues,
4
+ readSlackAgentViewStateValue
5
+ } from "../chunk-C7CHMYV6.js";
6
+ export {
7
+ createSlackAgentViewWorkflowController,
8
+ extractSlackAgentViewStateValues,
9
+ readSlackAgentViewStateValue
10
+ };
package/docs/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # Channel Slack Agent Core Docs
2
+
3
+ `@cuylabs/channel-slack-agent-core` is the `@cuylabs/agent-core` runtime binding
4
+ for direct Slack traffic. It composes `@cuylabs/channel-slack` primitives with
5
+ Agent Core turn sources, event streams, scopes, context fragments, approvals,
6
+ and human-input requests.
7
+
8
+ ## Reference
9
+
10
+ - [Package boundary](reference/boundary.md)
11
+ - [Exports and peer expectations](reference/exports.md)
12
+
13
+ ## Concepts
14
+
15
+ - [Final response artifacts](concepts/final-response-artifacts.md)
16
+ - [Interactive requests](concepts/interactive-requests.md)
17
+ - [Tool task rendering](concepts/tool-task-rendering.md)
18
+ - [View workflows](concepts/view-workflows.md)
@@ -0,0 +1,39 @@
1
+ # Final Response Artifacts
2
+
3
+ Final response artifacts let a Slack host publish a rich surface from the
4
+ completed Agent Core response. The first built-in publisher creates a Slack
5
+ Canvas for long answers and can fall back to a text file when Canvas
6
+ publication is unavailable.
7
+
8
+ ```typescript
9
+ import { createSlackFinalResponseArtifactPublisher } from "@cuylabs/channel-slack-agent-core/artifacts";
10
+
11
+ const publishFinalResponseArtifact = createSlackFinalResponseArtifactPublisher({
12
+ minCharacters: 4000,
13
+ title: "Agent response",
14
+ fallback: "file",
15
+ });
16
+
17
+ await mountSlackAgentApp({
18
+ source,
19
+ publishFinalResponseArtifact,
20
+ finalResponseArtifactMode: "replace",
21
+ finalResponseArtifactStreamThreshold: 4000,
22
+ });
23
+ ```
24
+
25
+ By default, `finalResponseArtifactMode` is `"supplemental"`: the Slack response
26
+ is finalized normally, then the artifact is published as an extra surface.
27
+
28
+ Use `"replace"` when long answers should move to the artifact instead of being
29
+ duplicated in chat. In chat-stream mode, the bridge streams text until
30
+ `finalResponseArtifactStreamThreshold`, appends a continuation notice, and then
31
+ publishes the full final text as a Canvas/file at completion. If publication
32
+ does not produce an artifact, the bridge falls back to the full Slack text.
33
+
34
+ The publisher receives the raw final text, formatted Slack text, the Slack Web
35
+ API client, and the target channel/thread. Short responses are skipped.
36
+
37
+ Canvas and file publication use `@cuylabs/channel-slack/artifacts`, so the
38
+ required Slack scopes are the same: `canvases:write` for Canvas and
39
+ `files:write` for file fallback.
@@ -0,0 +1,43 @@
1
+ # Interactive Requests
2
+
3
+ Slack interactive requests render Agent Core approval and human-input requests
4
+ as Slack buttons and modals.
5
+
6
+ ```typescript
7
+ import {
8
+ createPostgresSlackInteractiveRequestStore,
9
+ createSlackInteractiveController,
10
+ } from "@cuylabs/channel-slack-agent-core/interactive";
11
+
12
+ const interactiveStore = createPostgresSlackInteractiveRequestStore({
13
+ connectionString: process.env.DATABASE_URL,
14
+ schema: "agent",
15
+ });
16
+
17
+ const interactive = createSlackInteractiveController({
18
+ store: interactiveStore,
19
+ namespace: "my_agent_slack",
20
+ requestTimeoutMs: 5 * 60 * 1000,
21
+ });
22
+
23
+ // Wire these into the Agent Core runtime:
24
+ // approval: { onRequest: interactive.approval.onRequest }
25
+ // humanInput: { onRequest: interactive.humanInput.onRequest }
26
+
27
+ // Wire the controller into the Slack app surface:
28
+ // installSlackAgentAppSurface(boltApp, { source, interactive, ... })
29
+ ```
30
+
31
+ ## Store Choices
32
+
33
+ - `createInMemorySlackInteractiveRequestStore` is useful for tests and local
34
+ single-process apps.
35
+ - `createPostgresSlackInteractiveRequestStore` persists pending requests across
36
+ restarts and lets multiple Slack workers resolve the same request safely.
37
+
38
+ The Postgres store uses one table keyed by request ID. `resolve(...)` is
39
+ idempotent: the first resolution wins, and later duplicate button clicks return
40
+ the original resolution without overwriting it.
41
+
42
+ Call `close()` during shutdown when the store owns its `pg` pool. Call
43
+ `prune()` manually when you disable the background prune timer.
@@ -0,0 +1,46 @@
1
+ # Tool Task Rendering
2
+
3
+ `chat-stream` mode can render Agent Core tool activity as Slack task updates.
4
+ The bridge owns the generic event-to-Slack mapping, while applications can
5
+ format titles, in-progress details, and completed output.
6
+
7
+ Use these hooks when a tool result has structured metadata that should be shown
8
+ more cleanly than the generic stringified result:
9
+
10
+ - `formatToolTitle(toolName)` controls the Slack task title.
11
+ - `formatToolDetails(event)` controls the in-progress task details for a
12
+ `tool-start` event.
13
+ - `formatToolResultOutput(event)` controls the completed task output for a
14
+ `tool-result` event.
15
+
16
+ `formatToolResultOutput` receives the full `tool-result` event, including
17
+ `toolName`, `toolCallId`, `result`, and any tool metadata preserved by Agent
18
+ Core. Return `undefined` to use the default formatter. Return `null` to omit the
19
+ completed task output intentionally.
20
+
21
+ ```ts
22
+ createSlackChannelAdapter({
23
+ source,
24
+ streamingMode: "chat-stream",
25
+ formatToolTitle: (toolName) => (toolName === "plan" ? "Plan" : toolName),
26
+ formatToolResultOutput: (event) => {
27
+ if (event.toolName !== "plan") {
28
+ return undefined;
29
+ }
30
+
31
+ const entries = readPlanEntries(event.metadata);
32
+ if (!entries) {
33
+ return undefined;
34
+ }
35
+
36
+ return entries
37
+ .map(
38
+ (entry) => `${entry.status === "done" ? "[x]" : "[ ]"} ${entry.title}`,
39
+ )
40
+ .join("\n");
41
+ },
42
+ });
43
+ ```
44
+
45
+ Keep task rows compact. Slack task updates are a visible progress projection for
46
+ the current turn, not a durable audit log or replacement for the final answer.
@@ -0,0 +1,52 @@
1
+ # View Workflows
2
+
3
+ Agent view workflows connect Slack modal submissions to agent or product logic.
4
+ They sit above `@cuylabs/channel-slack/views`: the lower package owns Slack Web
5
+ API/Bolt mechanics, while this package adds namespaced callback ids, decoded
6
+ metadata, submitted state values, and app-surface mounting.
7
+
8
+ ```typescript
9
+ import {
10
+ encodeSlackViewPrivateMetadata,
11
+ openSlackModal,
12
+ } from "@cuylabs/channel-slack/views";
13
+ import { createSlackAgentViewWorkflowController } from "@cuylabs/channel-slack-agent-core/views";
14
+
15
+ const viewWorkflows = createSlackAgentViewWorkflowController({
16
+ namespace: "cdo",
17
+ workflows: [
18
+ {
19
+ id: "incident_triage",
20
+ onSubmission: async ({ metadata, stateValues, getStateValue, actor }) => {
21
+ const severity = getStateValue("severity", "value");
22
+ // Load product-owned workflow state by metadata.workflowId, validate the
23
+ // submitted values, then continue an agent turn or product workflow.
24
+ return { response_action: "clear" };
25
+ },
26
+ },
27
+ ],
28
+ });
29
+
30
+ await openSlackModal({
31
+ client,
32
+ triggerId,
33
+ view: {
34
+ type: "modal",
35
+ callback_id: viewWorkflows.callbackIdFor("incident_triage"),
36
+ private_metadata: encodeSlackViewPrivateMetadata({
37
+ workflowId: "triage-123",
38
+ }),
39
+ title: { type: "plain_text", text: "Triage incident" },
40
+ submit: { type: "plain_text", text: "Continue" },
41
+ blocks: [],
42
+ },
43
+ });
44
+ ```
45
+
46
+ Pass the controller to `mountSlackAgentApp` / `installSlackAgentAppSurface` as
47
+ `viewWorkflows`. The controller installs `view_submission` and `view_closed`
48
+ handlers on the underlying Bolt app.
49
+
50
+ Keep `private_metadata` compact. Store durable workflow state in an application
51
+ database or existing request store and put only routing keys, such as
52
+ `workflowId`, `requestId`, or `sessionId`, into the modal.
@@ -0,0 +1,22 @@
1
+ # Package Boundary
2
+
3
+ This package owns only the `@cuylabs/agent-core` Slack binding.
4
+
5
+ ## In This Package
6
+
7
+ - Mapping Slack turns to `AgentTurnSource.chat(...)`.
8
+ - Creating Agent Core scopes and context fragments.
9
+ - Converting `AgentEvent` streams to Slack messages or chat streams.
10
+ - Mounting Agent Core sources on Express Events API and Socket Mode surfaces.
11
+ - Binding Slack Assistant lifecycle handlers to Agent Core turns.
12
+ - Handling Agent Core approval and human-input requests in Slack.
13
+ - Agent Core helpers for Slack history context fragments and source events.
14
+
15
+ ## Outside This Package
16
+
17
+ - Generic Slack activity parsing, formatting, setup, auth, policy, history,
18
+ targets, users, entrypoints, artifacts, and transport factories.
19
+ - Product prompts, tools, audit policy, privacy rules, and deployment policy.
20
+ - Slack app configuration outside the reusable setup helpers.
21
+
22
+ Generic Slack mechanics live in `@cuylabs/channel-slack`.
@@ -0,0 +1,26 @@
1
+ # Exports
2
+
3
+ Use feature subpaths when you only need one adapter surface. Generic Slack
4
+ primitives should be imported from `@cuylabs/channel-slack` directly.
5
+
6
+ | Export | Depends on | Notes |
7
+ | ----------------------------------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
8
+ | `@cuylabs/channel-slack-agent-core` | `@cuylabs/agent-core`, selected Slack peers | Full adapter surface re-export |
9
+ | `@cuylabs/channel-slack-agent-core/adapter` | `@slack/bolt`, `@slack/web-api` types | Classic app mention, DM, and passive channel-message adapter |
10
+ | `@cuylabs/channel-slack-agent-core/app` | `@slack/bolt`, `@slack/web-api` | Direct app factory for mounted Slack surfaces |
11
+ | `@cuylabs/channel-slack-agent-core/app-surface` | `@slack/bolt`, `@slack/web-api` types | Shared surface installer for Assistant, mentions, DMs, feedback, and interactions |
12
+ | `@cuylabs/channel-slack-agent-core/artifacts` | `@cuylabs/channel-slack/artifacts` | Agent Core final-response artifact publishers for Slack surfaces |
13
+ | `@cuylabs/channel-slack-agent-core/assistant` | `@slack/bolt`, `@slack/web-api` types | Slack Assistant bridge and lifecycle handlers |
14
+ | `@cuylabs/channel-slack-agent-core/express` | `@slack/bolt`, `express` | Express Events API mounting for classic Slack surfaces |
15
+ | `@cuylabs/channel-slack-agent-core/express-assistant` | `@slack/bolt`, `express` | Express Events API mounting for Slack Assistant |
16
+ | `@cuylabs/channel-slack-agent-core/feedback` | `@slack/bolt`, `@slack/types` | Agent Core feedback binding helpers |
17
+ | `@cuylabs/channel-slack-agent-core/history` | `@slack/web-api`, `@cuylabs/agent-core` types | Agent Core turn history context fragment assembly |
18
+ | `@cuylabs/channel-slack-agent-core/interactive` | `@slack/bolt`, `@slack/types`; `pg` only when using connection-string Postgres storage | Agent Core approval and human-input binding for Slack |
19
+ | `@cuylabs/channel-slack-agent-core/mcp` | `@cuylabs/agent-core/mcp` types | Slack OAuth token bridge for Agent Core MCP setup |
20
+ | `@cuylabs/channel-slack-agent-core/shared` | `@cuylabs/agent-core` types | Context fragments, event bridge, and interactive request contracts |
21
+ | `@cuylabs/channel-slack-agent-core/socket` | `@slack/bolt` | Socket Mode mounting helpers |
22
+ | `@cuylabs/channel-slack-agent-core/source` | `@cuylabs/agent-core` types | Source event queue, response helpers, and status visibility helpers |
23
+ | `@cuylabs/channel-slack-agent-core/views` | `@cuylabs/channel-slack/views`, `@slack/bolt` | Agent/product Slack modal workflow controller and submitted state helpers |
24
+
25
+ For generic Slack package exports, see
26
+ `@cuylabs/channel-slack/docs/reference/exports.md`.