@xpert-ai/plugin-sdk 3.7.2 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.js +773 -0
- package/index.esm.js +747 -1
- package/package.json +2 -1
- package/src/index.d.ts +2 -0
- package/src/lib/agent/handoff/agent-chat.contract.d.ts +20 -0
- package/src/lib/agent/handoff/handoff-processor.decorator.d.ts +11 -0
- package/src/lib/agent/handoff/handoff-processor.registry.d.ts +6 -0
- package/src/lib/agent/handoff/handoff.interface.d.ts +17 -0
- package/src/lib/agent/handoff/index.d.ts +6 -0
- package/src/lib/agent/handoff/message-type.d.ts +24 -0
- package/src/lib/agent/handoff/types.d.ts +110 -0
- package/src/lib/agent/index.d.ts +1 -0
- package/src/lib/agent/middleware/runtime.d.ts +2 -0
- package/src/lib/agent/middleware/strategy.interface.d.ts +5 -1
- package/src/lib/agent/middleware/types.d.ts +2 -2
- package/src/lib/ai-model/utils/index.d.ts +1 -0
- package/src/lib/ai-model/utils/limits.d.ts +4 -0
- package/src/lib/channel/cancel-conversation.command.d.ts +14 -0
- package/src/lib/channel/index.d.ts +4 -0
- package/src/lib/channel/strategy.decorator.d.ts +23 -0
- package/src/lib/channel/strategy.interface.d.ts +345 -0
- package/src/lib/channel/strategy.registry.d.ts +30 -0
- package/src/lib/core/permissions/analytics.d.ts +46 -0
- package/src/lib/core/{permissions.d.ts → permissions/general.d.ts} +9 -12
- package/src/lib/core/permissions/handoff.d.ts +36 -0
- package/src/lib/core/permissions/index.d.ts +24 -0
- package/src/lib/core/permissions/operation.d.ts +8 -0
- package/src/lib/core/permissions/user.d.ts +29 -0
- package/src/lib/integration/strategy.interface.d.ts +3 -1
- package/src/lib/sandbox/index.d.ts +8 -0
- package/src/lib/sandbox/protocol.d.ts +265 -0
- package/src/lib/sandbox/sandbox.d.ts +70 -0
- package/src/lib/sandbox/sandbox.decorator.d.ts +2 -0
- package/src/lib/sandbox/sandbox.interface.d.ts +38 -0
- package/src/lib/sandbox/sandbox.registry.d.ts +6 -0
- package/src/lib/toolset/strategy.interface.d.ts +2 -6
- package/src/lib/types.d.ts +7 -1
- package/src/lib/workflow/node/strategy.interface.d.ts +4 -2
- package/src/lib/workflow/trigger/strategy.interface.d.ts +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xpert-ai/plugin-sdk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"license": "AGPL-3.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"@langchain/core": "*",
|
|
22
22
|
"@metad/contracts": "*",
|
|
23
|
+
"@metad/ocap-core": "*",
|
|
23
24
|
"@nestjs/common": "*",
|
|
24
25
|
"@nestjs/core": "*",
|
|
25
26
|
"@nestjs/cqrs": "*",
|
package/src/index.d.ts
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { TChatOptions, TChatRequest } from '@metad/contracts';
|
|
2
|
+
export declare const AGENT_CHAT_DISPATCH_MESSAGE_TYPE: import("./message-type").StructuredHandoffMessageType;
|
|
3
|
+
export interface AgentChatCallbackTarget {
|
|
4
|
+
messageType: string;
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
context?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface AgentChatDispatchPayload extends Record<string, unknown> {
|
|
9
|
+
request: TChatRequest;
|
|
10
|
+
options: TChatOptions;
|
|
11
|
+
callback: AgentChatCallbackTarget;
|
|
12
|
+
}
|
|
13
|
+
export interface AgentChatCallbackEnvelopePayload extends Record<string, unknown> {
|
|
14
|
+
kind: 'stream' | 'complete' | 'error';
|
|
15
|
+
sourceMessageId: string;
|
|
16
|
+
sequence: number;
|
|
17
|
+
event?: unknown;
|
|
18
|
+
error?: string;
|
|
19
|
+
context?: Record<string, unknown>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HandoffProcessorMetadata } from './handoff.interface';
|
|
2
|
+
/**
|
|
3
|
+
* Handoff Processor meta key。
|
|
4
|
+
*/
|
|
5
|
+
export declare const HANDOFF_PROCESSOR_STRATEGY = "HANDOFF_PROCESSOR_STRATEGY";
|
|
6
|
+
/**
|
|
7
|
+
* Declare on a provider:
|
|
8
|
+
* 1) Which message types it handles
|
|
9
|
+
* 2) Default execution policy (lane/timeout)
|
|
10
|
+
*/
|
|
11
|
+
export declare function HandoffProcessorStrategy(provider: string, metadata: HandoffProcessorMetadata): <TFunction extends Function, Y>(target: object | TFunction, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DiscoveryService, Reflector } from '@nestjs/core';
|
|
2
|
+
import { BaseStrategyRegistry } from '../../strategy';
|
|
3
|
+
import { IHandoffProcessor } from './handoff.interface';
|
|
4
|
+
export declare class HandoffProcessorRegistry extends BaseStrategyRegistry<IHandoffProcessor> {
|
|
5
|
+
constructor(discoveryService: DiscoveryService, reflector: Reflector);
|
|
6
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { HandoffMessage, ProcessContext, ProcessorPolicy, ProcessResult } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Handoff Processor interface.
|
|
4
|
+
* - Processor focus only on message processing logic; scheduling, retries, concurrency, and cancellation are handled uniformly by Dispatcher + Queue.
|
|
5
|
+
*/
|
|
6
|
+
export interface IHandoffProcessor<TPayload extends Record<string, unknown> = Record<string, unknown>> {
|
|
7
|
+
process(message: HandoffMessage<TPayload>, ctx: ProcessContext): Promise<ProcessResult>;
|
|
8
|
+
}
|
|
9
|
+
export interface HandoffProcessorMetadata {
|
|
10
|
+
types: string[];
|
|
11
|
+
policy: ProcessorPolicy;
|
|
12
|
+
}
|
|
13
|
+
export interface ResolvedHandoffProcessor {
|
|
14
|
+
type: string;
|
|
15
|
+
processor: IHandoffProcessor;
|
|
16
|
+
metadata: HandoffProcessorMetadata;
|
|
17
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured message types (suggested format):
|
|
3
|
+
* - channel.{provider}.{action}.v{number}
|
|
4
|
+
* - agent.{action}.v{number}
|
|
5
|
+
* - system.{action}.v{number}
|
|
6
|
+
* - plugin.{domain}.{action}.v{number}
|
|
7
|
+
*
|
|
8
|
+
* Note: At runtime, any string type is still allowed, facilitating dynamic extension by plugins.
|
|
9
|
+
*/
|
|
10
|
+
export type StructuredHandoffMessageType = `channel.${string}.${string}.v${number}` | `agent.${string}.v${number}` | `system.${string}.v${number}` | `plugin.${string}.${string}.v${number}`;
|
|
11
|
+
/**
|
|
12
|
+
* Unified construction of channel message types to avoid manual string errors.
|
|
13
|
+
* Example: channel.lark.inbound.v1
|
|
14
|
+
*/
|
|
15
|
+
export declare function defineChannelMessageType(provider: string, action: string, version: number): StructuredHandoffMessageType;
|
|
16
|
+
/**
|
|
17
|
+
* Unified construction of agent message types.
|
|
18
|
+
* Example: agent.handoff.v1
|
|
19
|
+
*/
|
|
20
|
+
export declare function defineAgentMessageType(action: string, version: number): StructuredHandoffMessageType;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a type conforms to the structured naming convention (format only, no semantic validation).
|
|
23
|
+
*/
|
|
24
|
+
export declare function isStructuredMessageType(type: string): boolean;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handoff execution types.
|
|
3
|
+
*
|
|
4
|
+
* Note:
|
|
5
|
+
* - Two-gate lane/session permit logic has been removed.
|
|
6
|
+
* - Lane is now an execution tag for observability and soft policy only.
|
|
7
|
+
*/
|
|
8
|
+
export type LaneName = 'main' | 'subagent' | 'cron' | 'nested';
|
|
9
|
+
export type RunSource = 'chat' | 'xpert' | 'lark' | 'analytics' | 'api';
|
|
10
|
+
export interface RunMetadata {
|
|
11
|
+
runId: string;
|
|
12
|
+
sessionKey: string;
|
|
13
|
+
lane: LaneName;
|
|
14
|
+
source: RunSource;
|
|
15
|
+
startedAt: number;
|
|
16
|
+
expiresAt?: number;
|
|
17
|
+
controller: AbortController;
|
|
18
|
+
conversationId?: string;
|
|
19
|
+
executionId?: string;
|
|
20
|
+
integrationId?: string;
|
|
21
|
+
userId?: string;
|
|
22
|
+
tenantId?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface LaneStats {
|
|
25
|
+
lane: string;
|
|
26
|
+
active: number;
|
|
27
|
+
queued: number;
|
|
28
|
+
maxConcurrent: number;
|
|
29
|
+
draining: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface RunOptions {
|
|
32
|
+
runId: string;
|
|
33
|
+
sessionKey?: string;
|
|
34
|
+
globalLane?: LaneName;
|
|
35
|
+
abortController: AbortController;
|
|
36
|
+
source?: RunSource;
|
|
37
|
+
conversationId?: string;
|
|
38
|
+
executionId?: string;
|
|
39
|
+
integrationId?: string;
|
|
40
|
+
userId?: string;
|
|
41
|
+
tenantId?: string;
|
|
42
|
+
timeoutMs?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface ExecutionConfig {
|
|
45
|
+
lanes: Record<LaneName, number>;
|
|
46
|
+
runTtlMs: number;
|
|
47
|
+
}
|
|
48
|
+
export declare const DEFAULT_EXECUTION_CONFIG: ExecutionConfig;
|
|
49
|
+
/**
|
|
50
|
+
* Handoff message envelope (v1).
|
|
51
|
+
* Using `type` with a string allows plugins to dynamically expand at runtime without needing to modify the core type definition.
|
|
52
|
+
*/
|
|
53
|
+
export interface HandoffMessage<TPayload extends Record<string, unknown> = Record<string, unknown>> {
|
|
54
|
+
id: string;
|
|
55
|
+
/**
|
|
56
|
+
* Message type, used for processor resolution.
|
|
57
|
+
*/
|
|
58
|
+
type: string;
|
|
59
|
+
version: number;
|
|
60
|
+
tenantId: string;
|
|
61
|
+
sessionKey: string;
|
|
62
|
+
businessKey: string;
|
|
63
|
+
attempt: number;
|
|
64
|
+
maxAttempts: number;
|
|
65
|
+
enqueuedAt: number;
|
|
66
|
+
traceId: string;
|
|
67
|
+
parentMessageId?: string;
|
|
68
|
+
payload: TPayload;
|
|
69
|
+
headers?: HandoffMessageHeaders;
|
|
70
|
+
}
|
|
71
|
+
export interface HandoffMessageHeaders extends Record<string, string> {
|
|
72
|
+
organizationId?: string;
|
|
73
|
+
userId?: string;
|
|
74
|
+
language?: string;
|
|
75
|
+
threadId?: string;
|
|
76
|
+
conversationId?: string;
|
|
77
|
+
sourceAgent?: string;
|
|
78
|
+
targetAgent?: string;
|
|
79
|
+
source?: RunSource;
|
|
80
|
+
requestedLane?: LaneName;
|
|
81
|
+
integrationId?: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Processor execution policy: declared by the Processor, executed uniformly by the Dispatcher.
|
|
85
|
+
*/
|
|
86
|
+
export interface ProcessorPolicy {
|
|
87
|
+
lane: LaneName;
|
|
88
|
+
timeoutMs?: number;
|
|
89
|
+
}
|
|
90
|
+
export interface ProcessContext {
|
|
91
|
+
runId: string;
|
|
92
|
+
traceId: string;
|
|
93
|
+
abortSignal: AbortSignal;
|
|
94
|
+
/**
|
|
95
|
+
* Optional local-process event channel for queue waiters (e.g. SSE connection awaiting this message).
|
|
96
|
+
* This is intentionally process-local and best-effort.
|
|
97
|
+
*/
|
|
98
|
+
emit?: (event: unknown) => void;
|
|
99
|
+
}
|
|
100
|
+
export type ProcessResult = {
|
|
101
|
+
status: 'ok';
|
|
102
|
+
outbound?: HandoffMessage[];
|
|
103
|
+
} | {
|
|
104
|
+
status: 'retry';
|
|
105
|
+
delayMs: number;
|
|
106
|
+
reason?: string;
|
|
107
|
+
} | {
|
|
108
|
+
status: 'dead';
|
|
109
|
+
reason: string;
|
|
110
|
+
};
|
package/src/lib/agent/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Runtime as LangGraphRuntime } from "@langchain/langgraph";
|
|
2
2
|
import type { BaseMessage } from "@langchain/core/messages";
|
|
3
|
+
import { TSandboxConfigurable } from "@metad/contracts";
|
|
3
4
|
/**
|
|
4
5
|
* Type for the agent's built-in state properties.
|
|
5
6
|
*/
|
|
@@ -51,6 +52,7 @@ export type WithMaybeContext<TContext> = undefined extends TContext ? {
|
|
|
51
52
|
export type Runtime<TContext = unknown> = Partial<Omit<LangGraphRuntime<TContext>, "context" | "configurable">> & WithMaybeContext<TContext> & {
|
|
52
53
|
configurable?: {
|
|
53
54
|
thread_id?: string;
|
|
55
|
+
sandbox?: TSandboxConfigurable | null;
|
|
54
56
|
[key: string]: unknown;
|
|
55
57
|
};
|
|
56
58
|
};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { IWFNMiddleware, TAgentMiddlewareMeta } from '@metad/contracts';
|
|
2
|
-
import {
|
|
2
|
+
import { StructuredToolInterface } from "@langchain/core/tools";
|
|
3
|
+
import { RunnableToolLike } from '@langchain/core/runnables';
|
|
4
|
+
import { AgentMiddleware } from './types';
|
|
5
|
+
import { PromiseOrValue } from '../../types';
|
|
3
6
|
export interface IAgentMiddlewareContext {
|
|
4
7
|
tenantId: string;
|
|
5
8
|
userId: string;
|
|
@@ -9,6 +12,7 @@ export interface IAgentMiddlewareContext {
|
|
|
9
12
|
xpertId?: string;
|
|
10
13
|
agentKey?: string;
|
|
11
14
|
node: IWFNMiddleware;
|
|
15
|
+
tools: Map<string, StructuredToolInterface | RunnableToolLike>;
|
|
12
16
|
}
|
|
13
17
|
export interface IAgentMiddlewareStrategy<T = unknown> {
|
|
14
18
|
meta: TAgentMiddlewareMeta;
|
|
@@ -4,8 +4,9 @@ import { DynamicStructuredTool, DynamicTool, StructuredToolInterface } from '@la
|
|
|
4
4
|
import type { ToolCall, ToolMessage } from "@langchain/core/messages/tool";
|
|
5
5
|
import { InferInteropZodOutput, InteropZodObject } from '@langchain/core/utils/types';
|
|
6
6
|
import { RunnableToolLike } from '@langchain/core/runnables';
|
|
7
|
-
import { AgentBuiltInState, Runtime } from './runtime';
|
|
8
7
|
import { Command } from '@langchain/langgraph';
|
|
8
|
+
import { AgentBuiltInState, Runtime } from './runtime';
|
|
9
|
+
import { PromiseOrValue } from '../../types';
|
|
9
10
|
export type ServerTool = Record<string, unknown>;
|
|
10
11
|
export type ClientTool = StructuredToolInterface | DynamicTool | RunnableToolLike;
|
|
11
12
|
export type NormalizedSchemaInput<TSchema extends InteropZodObject | undefined | never = any> = [TSchema] extends [never] ? AgentBuiltInState : TSchema extends InteropZodObject ? InferInteropZodOutput<TSchema> & AgentBuiltInState : TSchema extends Record<string, unknown> ? TSchema & AgentBuiltInState : AgentBuiltInState;
|
|
@@ -15,7 +16,6 @@ type NormalizeContextSchema<TContextSchema extends InteropZodObject | undefined
|
|
|
15
16
|
*/
|
|
16
17
|
export declare const JUMP_TO_TARGETS: readonly ["model", "tools", "end"];
|
|
17
18
|
export type JumpToTarget = (typeof JUMP_TO_TARGETS)[number];
|
|
18
|
-
export type PromiseOrValue<T> = T | Promise<T>;
|
|
19
19
|
/**
|
|
20
20
|
* Result type for middleware functions.
|
|
21
21
|
*/
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { BaseLanguageModel } from "@langchain/core/language_models/base";
|
|
2
|
+
import { ICopilotModel } from "@metad/contracts";
|
|
3
|
+
export declare function getModelContextSize(input: BaseLanguageModel | ICopilotModel): number | undefined;
|
|
4
|
+
export declare function normalizeContextSize(value: unknown): number | undefined;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ICommand } from '@nestjs/cqrs';
|
|
2
|
+
export declare class CancelConversationCommand implements ICommand {
|
|
3
|
+
readonly input: {
|
|
4
|
+
conversationId?: string;
|
|
5
|
+
threadId?: string;
|
|
6
|
+
executionId?: string;
|
|
7
|
+
};
|
|
8
|
+
static readonly type = "[Chat Conversation] Cancel";
|
|
9
|
+
constructor(input: {
|
|
10
|
+
conversationId?: string;
|
|
11
|
+
threadId?: string;
|
|
12
|
+
executionId?: string;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metadata key for chat channel
|
|
3
|
+
*/
|
|
4
|
+
export declare const CHAT_CHANNEL = "CHAT_CHANNEL";
|
|
5
|
+
/**
|
|
6
|
+
* Decorator for chat channel implementations
|
|
7
|
+
*
|
|
8
|
+
* Use this decorator to register a chat channel implementation.
|
|
9
|
+
* The decorated class will be automatically discovered and registered
|
|
10
|
+
* to ChatChannelRegistry on module initialization.
|
|
11
|
+
*
|
|
12
|
+
* @param type - The channel type identifier (e.g., 'lark', 'wecom', 'dingtalk')
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* @Injectable()
|
|
17
|
+
* @ChatChannel('lark')
|
|
18
|
+
* export class LarkChatChannel implements IChatChannel {
|
|
19
|
+
* // Implementation
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare const ChatChannel: (type: string) => import("@nestjs/common").CustomDecorator<string>;
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { IIntegration } from '@metad/contracts';
|
|
4
|
+
import { Request, Response, NextFunction } from 'express';
|
|
5
|
+
/**
|
|
6
|
+
* Channel metadata
|
|
7
|
+
*/
|
|
8
|
+
export type TChatChannelMeta = {
|
|
9
|
+
/**
|
|
10
|
+
* Channel type identifier
|
|
11
|
+
*/
|
|
12
|
+
type: string;
|
|
13
|
+
/**
|
|
14
|
+
* Display name
|
|
15
|
+
*/
|
|
16
|
+
label: string;
|
|
17
|
+
/**
|
|
18
|
+
* Description
|
|
19
|
+
*/
|
|
20
|
+
description?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Icon
|
|
23
|
+
*/
|
|
24
|
+
icon?: string;
|
|
25
|
+
/**
|
|
26
|
+
* JSON Schema for integration configuration
|
|
27
|
+
*/
|
|
28
|
+
configSchema?: Record<string, any>;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Channel capabilities declaration
|
|
32
|
+
*/
|
|
33
|
+
export type TChatChannelCapabilities = {
|
|
34
|
+
/** Supports Markdown messages */
|
|
35
|
+
markdown: boolean;
|
|
36
|
+
/** Supports interactive cards */
|
|
37
|
+
card: boolean;
|
|
38
|
+
/** Supports card button interactions */
|
|
39
|
+
cardAction: boolean;
|
|
40
|
+
/** Supports editing/updating messages */
|
|
41
|
+
updateMessage: boolean;
|
|
42
|
+
/** Supports @mentions */
|
|
43
|
+
mention: boolean;
|
|
44
|
+
/** Supports group chat */
|
|
45
|
+
group: boolean;
|
|
46
|
+
/** Supports message threads/replies */
|
|
47
|
+
thread?: boolean;
|
|
48
|
+
/** Supports media messages (images, files) */
|
|
49
|
+
media?: boolean;
|
|
50
|
+
/** Maximum characters per message (auto-chunked if exceeded), e.g., Telegram 4096, Discord 2000 */
|
|
51
|
+
textChunkLimit?: number;
|
|
52
|
+
/** Supports streaming message updates (typewriter effect) */
|
|
53
|
+
streamingUpdate?: boolean;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Inbound message - unified format from different platforms
|
|
57
|
+
*/
|
|
58
|
+
export type TChatInboundMessage = {
|
|
59
|
+
/** Platform message ID */
|
|
60
|
+
messageId: string;
|
|
61
|
+
/** Chat ID */
|
|
62
|
+
chatId: string;
|
|
63
|
+
/** Chat type: private, group, channel, thread */
|
|
64
|
+
chatType: 'private' | 'group' | 'channel' | 'thread';
|
|
65
|
+
/** Sender ID (platform user ID) */
|
|
66
|
+
senderId: string;
|
|
67
|
+
/** Sender name */
|
|
68
|
+
senderName?: string;
|
|
69
|
+
/** Message content (text) */
|
|
70
|
+
content: string;
|
|
71
|
+
/** Content type */
|
|
72
|
+
contentType: 'text' | 'image' | 'file' | 'card_action' | 'voice';
|
|
73
|
+
/** List of mentioned users */
|
|
74
|
+
mentions?: Array<{
|
|
75
|
+
id: string;
|
|
76
|
+
name?: string;
|
|
77
|
+
}>;
|
|
78
|
+
/** Reply-to message ID */
|
|
79
|
+
replyToMessageId?: string;
|
|
80
|
+
/** Thread ID (for threaded conversations) */
|
|
81
|
+
threadId?: string;
|
|
82
|
+
/** Timestamp */
|
|
83
|
+
timestamp: number;
|
|
84
|
+
/** Platform raw event data */
|
|
85
|
+
raw: any;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Card action event - triggered when user clicks card button
|
|
89
|
+
*/
|
|
90
|
+
export type TChatCardAction<V = unknown> = {
|
|
91
|
+
/** Action type/tag */
|
|
92
|
+
type: string;
|
|
93
|
+
/** Action value */
|
|
94
|
+
value: V;
|
|
95
|
+
/** Message ID the card belongs to */
|
|
96
|
+
messageId: string;
|
|
97
|
+
/** Chat ID */
|
|
98
|
+
chatId: string;
|
|
99
|
+
/** User ID who triggered the action */
|
|
100
|
+
userId: string;
|
|
101
|
+
/** Raw event data */
|
|
102
|
+
raw: any;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Chat context - used for sending messages
|
|
106
|
+
*/
|
|
107
|
+
export type TChatContext = {
|
|
108
|
+
/** Integration configuration */
|
|
109
|
+
integration: IIntegration;
|
|
110
|
+
/** Chat ID */
|
|
111
|
+
chatId: string;
|
|
112
|
+
/** Target user ID (for private chat) */
|
|
113
|
+
userId?: string;
|
|
114
|
+
/** Thread ID (for thread replies) */
|
|
115
|
+
threadId?: string;
|
|
116
|
+
/** Reply-to message ID */
|
|
117
|
+
replyToMessageId?: string;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Send result
|
|
121
|
+
*/
|
|
122
|
+
export type TChatSendResult = {
|
|
123
|
+
/** Success status */
|
|
124
|
+
success: boolean;
|
|
125
|
+
/** Message ID */
|
|
126
|
+
messageId?: string;
|
|
127
|
+
/** Error message */
|
|
128
|
+
error?: string;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Event handling context
|
|
132
|
+
*/
|
|
133
|
+
export type TChatEventContext<TConfig = any> = {
|
|
134
|
+
/** Integration configuration */
|
|
135
|
+
integration: IIntegration<TConfig>;
|
|
136
|
+
/** Tenant ID */
|
|
137
|
+
tenantId: string;
|
|
138
|
+
/** Organization ID */
|
|
139
|
+
organizationId: string;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Event handling callbacks
|
|
143
|
+
*/
|
|
144
|
+
export type TChatEventHandlers = {
|
|
145
|
+
/** Called when message is received */
|
|
146
|
+
onMessage?: (message: TChatInboundMessage, ctx: TChatEventContext) => Promise<void>;
|
|
147
|
+
/** Called on card interaction */
|
|
148
|
+
onCardAction?: (action: TChatCardAction, ctx: TChatEventContext) => Promise<void>;
|
|
149
|
+
/** Called when @mentioned in group chat */
|
|
150
|
+
onMention?: (message: TChatInboundMessage, ctx: TChatEventContext) => Promise<void>;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Chat channel interface
|
|
154
|
+
*
|
|
155
|
+
* For bidirectional messaging platforms (Lark, WeCom, DingTalk, Slack, etc.)
|
|
156
|
+
* Supports: receive message → invoke Xpert → reply message
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* @Injectable()
|
|
161
|
+
* @ChatChannel('lark')
|
|
162
|
+
* export class LarkChatChannel implements IChatChannel {
|
|
163
|
+
* meta = { type: 'lark', label: 'Lark', ... }
|
|
164
|
+
*
|
|
165
|
+
* createEventHandler(ctx, handlers) {
|
|
166
|
+
* // Return Express middleware for handling Webhook
|
|
167
|
+
* }
|
|
168
|
+
*
|
|
169
|
+
* async sendText(ctx, content) {
|
|
170
|
+
* // Send text message via Lark API
|
|
171
|
+
* }
|
|
172
|
+
* }
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export interface IChatChannel<TConfig = any, TEvent = any> {
|
|
176
|
+
/**
|
|
177
|
+
* Channel metadata
|
|
178
|
+
*/
|
|
179
|
+
meta: TChatChannelMeta;
|
|
180
|
+
/**
|
|
181
|
+
* Channel capabilities declaration
|
|
182
|
+
*/
|
|
183
|
+
capabilities: TChatChannelCapabilities;
|
|
184
|
+
/**
|
|
185
|
+
* Create Webhook/event handler
|
|
186
|
+
*
|
|
187
|
+
* Returns Express middleware for handling inbound Webhooks.
|
|
188
|
+
* The middleware should:
|
|
189
|
+
* 1. Verify request (signature, token)
|
|
190
|
+
* 2. Parse event
|
|
191
|
+
* 3. Call appropriate handler callbacks (onMessage, onCardAction, etc.)
|
|
192
|
+
*
|
|
193
|
+
* @param ctx - Event context containing integration configuration
|
|
194
|
+
* @param handlers - Callback functions for different event types
|
|
195
|
+
* @returns Express middleware
|
|
196
|
+
*/
|
|
197
|
+
createEventHandler(ctx: TChatEventContext<TConfig>, handlers: TChatEventHandlers): (req: Request, res: Response, next?: NextFunction) => Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* Parse inbound event to unified message format
|
|
200
|
+
*
|
|
201
|
+
* @param event - Platform raw event
|
|
202
|
+
* @param ctx - Event context
|
|
203
|
+
* @returns Parsed message, or null if not a message event
|
|
204
|
+
*/
|
|
205
|
+
parseInboundMessage?(event: TEvent, ctx: TChatEventContext<TConfig>): TChatInboundMessage | null;
|
|
206
|
+
/**
|
|
207
|
+
* Parse card action event
|
|
208
|
+
*
|
|
209
|
+
* @param event - Platform raw event
|
|
210
|
+
* @param ctx - Event context
|
|
211
|
+
* @returns Parsed card action, or null if not a card action event
|
|
212
|
+
*/
|
|
213
|
+
parseCardAction?(event: TEvent, ctx: TChatEventContext<TConfig>): TChatCardAction | null;
|
|
214
|
+
/**
|
|
215
|
+
* Check if bot is @mentioned in message
|
|
216
|
+
*
|
|
217
|
+
* @param message - Inbound message
|
|
218
|
+
* @param botId - Bot's user ID on the platform
|
|
219
|
+
* @returns True if bot is mentioned
|
|
220
|
+
*/
|
|
221
|
+
isBotMentioned?(message: TChatInboundMessage, botId: string): boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Send text message
|
|
224
|
+
*
|
|
225
|
+
* @param ctx - Chat context
|
|
226
|
+
* @param content - Text content
|
|
227
|
+
* @returns Send result
|
|
228
|
+
*/
|
|
229
|
+
sendText(ctx: TChatContext, content: string): Promise<TChatSendResult>;
|
|
230
|
+
/**
|
|
231
|
+
* Send Markdown message
|
|
232
|
+
*
|
|
233
|
+
* @param ctx - Chat context
|
|
234
|
+
* @param content - Markdown content
|
|
235
|
+
* @returns Send result
|
|
236
|
+
*/
|
|
237
|
+
sendMarkdown?(ctx: TChatContext, content: string): Promise<TChatSendResult>;
|
|
238
|
+
/**
|
|
239
|
+
* Send interactive card
|
|
240
|
+
*
|
|
241
|
+
* @param ctx - Chat context
|
|
242
|
+
* @param card - Card content (platform-specific format)
|
|
243
|
+
* @returns Send result
|
|
244
|
+
*/
|
|
245
|
+
sendCard?(ctx: TChatContext, card: any): Promise<TChatSendResult>;
|
|
246
|
+
/**
|
|
247
|
+
* Send media message (image, file)
|
|
248
|
+
*
|
|
249
|
+
* @param ctx - Chat context
|
|
250
|
+
* @param media - Media info
|
|
251
|
+
* @returns Send result
|
|
252
|
+
*/
|
|
253
|
+
sendMedia?(ctx: TChatContext, media: {
|
|
254
|
+
/** Media type */
|
|
255
|
+
type: 'image' | 'file' | 'audio' | 'video';
|
|
256
|
+
/** Media URL */
|
|
257
|
+
url?: string;
|
|
258
|
+
/** Media content (Buffer) */
|
|
259
|
+
content?: Buffer;
|
|
260
|
+
/** Filename */
|
|
261
|
+
filename?: string;
|
|
262
|
+
}): Promise<TChatSendResult>;
|
|
263
|
+
/**
|
|
264
|
+
* Update/edit sent message
|
|
265
|
+
*
|
|
266
|
+
* @param ctx - Chat context
|
|
267
|
+
* @param messageId - Message ID to update
|
|
268
|
+
* @param content - New content
|
|
269
|
+
* @returns Send result
|
|
270
|
+
*/
|
|
271
|
+
updateMessage?(ctx: TChatContext, messageId: string, content: string | any): Promise<TChatSendResult>;
|
|
272
|
+
/**
|
|
273
|
+
* Get bot information
|
|
274
|
+
*
|
|
275
|
+
* @param integration - Integration configuration
|
|
276
|
+
* @returns Bot info (ID, name, avatar, etc.)
|
|
277
|
+
*/
|
|
278
|
+
getBotInfo?(integration: IIntegration<TConfig>): Promise<{
|
|
279
|
+
/** Bot ID */
|
|
280
|
+
id: string;
|
|
281
|
+
/** Bot name */
|
|
282
|
+
name?: string;
|
|
283
|
+
/** Bot avatar URL */
|
|
284
|
+
avatar?: string;
|
|
285
|
+
}>;
|
|
286
|
+
/**
|
|
287
|
+
* Validate integration configuration
|
|
288
|
+
*
|
|
289
|
+
* @param config - Configuration to validate
|
|
290
|
+
* @returns Validation result
|
|
291
|
+
*/
|
|
292
|
+
validateConfig?(config: TConfig): Promise<{
|
|
293
|
+
/** Is valid */
|
|
294
|
+
valid: boolean;
|
|
295
|
+
/** Error list */
|
|
296
|
+
errors?: string[];
|
|
297
|
+
}>;
|
|
298
|
+
/**
|
|
299
|
+
* Test connection
|
|
300
|
+
*
|
|
301
|
+
* @param integration - Integration to test
|
|
302
|
+
* @returns Test result
|
|
303
|
+
*/
|
|
304
|
+
testConnection?(integration: IIntegration<TConfig>): Promise<{
|
|
305
|
+
/** Success status */
|
|
306
|
+
success: boolean;
|
|
307
|
+
/** Message */
|
|
308
|
+
message?: string;
|
|
309
|
+
}>;
|
|
310
|
+
/**
|
|
311
|
+
* Get channel runtime status (for monitoring and operations)
|
|
312
|
+
*
|
|
313
|
+
* @param integration - Integration configuration
|
|
314
|
+
* @returns Channel status
|
|
315
|
+
*/
|
|
316
|
+
getStatus?(integration: IIntegration<TConfig>): Promise<TChatChannelStatus>;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Channel runtime status (for monitoring)
|
|
320
|
+
*/
|
|
321
|
+
export type TChatChannelStatus = {
|
|
322
|
+
/** Is connected/running */
|
|
323
|
+
connected: boolean;
|
|
324
|
+
/** Last activity timestamp */
|
|
325
|
+
lastActivityAt?: number;
|
|
326
|
+
/** Last inbound message timestamp */
|
|
327
|
+
lastInboundAt?: number;
|
|
328
|
+
/** Last outbound message timestamp */
|
|
329
|
+
lastOutboundAt?: number;
|
|
330
|
+
/** Last error message */
|
|
331
|
+
error?: string;
|
|
332
|
+
};
|
|
333
|
+
/**
|
|
334
|
+
* Common platform message length limits
|
|
335
|
+
*/
|
|
336
|
+
export declare const CHAT_CHANNEL_TEXT_LIMITS: Record<string, number>;
|
|
337
|
+
/**
|
|
338
|
+
* Chunk long text by specified length
|
|
339
|
+
*
|
|
340
|
+
* @param text - Text to chunk
|
|
341
|
+
* @param limit - Maximum characters per chunk
|
|
342
|
+
* @param mode - Chunking mode: 'text' splits by character, 'markdown' tries to preserve paragraphs
|
|
343
|
+
* @returns Array of chunked text
|
|
344
|
+
*/
|
|
345
|
+
export declare function chunkText(text: string, limit: number, mode?: 'text' | 'markdown'): string[];
|