@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.
- package/README.md +20 -39
- package/dist/{adapter.d.ts → adapter/index.d.ts} +7 -5
- package/dist/adapter/index.js +9 -0
- package/dist/{adapter-Cmd2C90g.d.ts → adapter-B3CI611y.d.ts} +1 -1
- package/dist/app-surface.d.ts +13 -3
- package/dist/app-surface.js +5 -7
- package/dist/app.d.ts +9 -4
- package/dist/app.js +6 -9
- package/dist/artifacts/index.d.ts +57 -0
- package/dist/artifacts/index.js +6 -0
- package/dist/{assistant.d.ts → assistant/index.d.ts} +6 -4
- package/dist/{assistant.js → assistant/index.js} +3 -5
- package/dist/{chunk-CYEBGC6G.js → chunk-76SRS54H.js} +5 -5
- package/dist/{chunk-M64Z6TYL.js → chunk-7DUO5BMW.js} +16 -6
- package/dist/{chunk-NIPAN4KA.js → chunk-A2PLAVW6.js} +2 -3
- package/dist/chunk-C7CHMYV6.js +226 -0
- package/dist/chunk-C7VSW4ZM.js +548 -0
- package/dist/{chunk-JMLB7A2V.js → chunk-DJPKRKGP.js} +5 -5
- package/dist/chunk-ELR6MQD7.js +12 -0
- package/dist/{chunk-FDRQOG7Q.js → chunk-FQWFB54C.js} +26 -15
- package/dist/{chunk-BFUPAJON.js → chunk-MGBNGG4D.js} +59 -37
- package/dist/chunk-NNCVHQC4.js +94 -0
- package/dist/chunk-P7PFQ3SQ.js +396 -0
- package/dist/{chunk-WO4BJMF3.js → chunk-TCNJY7QA.js} +5 -5
- package/dist/{chunk-DHPD4XH5.js → chunk-TMADMHBN.js} +210 -29
- package/dist/{chunk-IWUYIAY5.js → chunk-VMVQIDNR.js} +5 -7
- package/dist/{chunk-IXY3BXU5.js → chunk-X7ILLZZP.js} +359 -2
- package/dist/context-fragments-CQEDcjYR.d.ts +30 -0
- package/dist/express-assistant.d.ts +6 -3
- package/dist/express-assistant.js +4 -7
- package/dist/express.d.ts +7 -3
- package/dist/express.js +3 -6
- package/dist/feedback/index.d.ts +1 -0
- package/dist/feedback/index.js +10 -0
- package/dist/history/index.d.ts +61 -0
- package/dist/history/index.js +8 -0
- package/dist/index.d.ts +23 -16
- package/dist/index.js +81 -160
- package/dist/interactive/index.d.ts +71 -0
- package/dist/{interactive.js → interactive/index.js} +9 -4
- package/dist/mcp.js +0 -1
- package/dist/{options-C7OYeNR-.d.ts → options-BcDReOJv.d.ts} +48 -0
- package/dist/{options-Uf-qmQKN.d.ts → options-CdqBABcM.d.ts} +26 -1
- package/dist/{shared.d.ts → shared/index.d.ts} +24 -36
- package/dist/{shared.js → shared/index.js} +2 -6
- package/dist/socket.d.ts +9 -4
- package/dist/socket.js +6 -9
- package/dist/source/index.d.ts +154 -0
- package/dist/source/index.js +38 -0
- package/dist/{types-BqRzb_Cd.d.ts → types-CRWzJB5G.d.ts} +35 -0
- package/dist/types-CiwGU6zC.d.ts +56 -0
- package/dist/views/index.d.ts +8 -0
- package/dist/views/index.js +10 -0
- package/docs/README.md +18 -0
- package/docs/concepts/final-response-artifacts.md +39 -0
- package/docs/concepts/interactive-requests.md +43 -0
- package/docs/concepts/tool-task-rendering.md +46 -0
- package/docs/concepts/view-workflows.md +52 -0
- package/docs/reference/boundary.md +22 -0
- package/docs/reference/exports.md +26 -0
- package/package.json +36 -50
- package/dist/adapter.js +0 -13
- package/dist/bolt.d.ts +0 -8
- package/dist/bolt.js +0 -10
- package/dist/chunk-2SUAW6MV.js +0 -12
- package/dist/chunk-645NNJIM.js +0 -12
- package/dist/chunk-ANIZ5NT4.js +0 -12
- package/dist/chunk-GNXWTKQ6.js +0 -48
- package/dist/chunk-HFT2FXJP.js +0 -12
- package/dist/chunk-I2KLQ2HA.js +0 -22
- package/dist/chunk-K2E6A377.js +0 -12
- package/dist/chunk-NDVXBI7Z.js +0 -12
- package/dist/chunk-PX4RGO3N.js +0 -12
- package/dist/chunk-VHGV66M7.js +0 -12
- package/dist/diagnostics.d.ts +0 -1
- package/dist/diagnostics.js +0 -10
- package/dist/feedback.d.ts +0 -1
- package/dist/feedback.js +0 -10
- package/dist/history.d.ts +0 -1
- package/dist/history.js +0 -10
- package/dist/interactive.d.ts +0 -30
- package/dist/policy.d.ts +0 -1
- package/dist/policy.js +0 -10
- package/dist/setup.d.ts +0 -1
- package/dist/setup.js +0 -10
- package/dist/targets.d.ts +0 -1
- package/dist/targets.js +0 -10
- package/dist/users.d.ts +0 -1
- 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-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
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`.
|