openclaw-openagent 1.0.12 → 1.0.14

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 (132) hide show
  1. package/dist/index.js +2 -0
  2. package/dist/src/config/config-schema.d.ts +9 -0
  3. package/dist/src/config/config-schema.js +6 -0
  4. package/dist/src/messaging/executor.d.ts +2 -3
  5. package/dist/src/messaging/executor.js +4 -31
  6. package/dist/src/plugin-ui/assets/openagent-override.js +124 -18
  7. package/dist/src/proxy/auth-proxy.js +5 -0
  8. package/dist/src/runtime/update-checker.d.ts +18 -0
  9. package/dist/src/runtime/update-checker.js +216 -0
  10. package/index.ts +3 -0
  11. package/package.json +1 -3
  12. package/src/app/channel-tools.ts +0 -249
  13. package/src/app/discovery-tools.ts +0 -273
  14. package/src/app/download-file-tool.ts +0 -133
  15. package/src/app/hooks.ts +0 -144
  16. package/src/app/index.ts +0 -84
  17. package/src/app/messaging-tools.ts +0 -79
  18. package/src/app/ops-tools.ts +0 -155
  19. package/src/app/remote-agent-tool.ts +0 -762
  20. package/src/app/types.ts +0 -68
  21. package/src/app/upload-file-tool.ts +0 -411
  22. package/src/app/verbose-preflight.ts +0 -190
  23. package/src/auth/config.ts +0 -266
  24. package/src/auth/credential-manager.ts +0 -146
  25. package/src/auth/index.ts +0 -24
  26. package/src/auth/verify.ts +0 -99
  27. package/src/channel.ts +0 -566
  28. package/src/compat.ts +0 -94
  29. package/src/config/config-schema.ts +0 -39
  30. package/src/messaging/aggregator.ts +0 -120
  31. package/src/messaging/collector.ts +0 -89
  32. package/src/messaging/executor.ts +0 -72
  33. package/src/messaging/inbound.ts +0 -150
  34. package/src/messaging/index.ts +0 -11
  35. package/src/messaging/mention-protocol.ts +0 -94
  36. package/src/messaging/process-c2c-request.ts +0 -564
  37. package/src/messaging/process-message.ts +0 -373
  38. package/src/messaging/scheduler.ts +0 -55
  39. package/src/messaging/types.ts +0 -38
  40. package/src/plugin-ui/adapters/oc-2026-04.js +0 -103
  41. package/src/plugin-ui/adapters/oc-2026-05.js +0 -125
  42. package/src/plugin-ui/adapters/oc-2026-06.js +0 -125
  43. package/src/plugin-ui/adapters/oc-unknown.js +0 -48
  44. package/src/plugin-ui/assets/agentbook-icon.svg +0 -5
  45. package/src/plugin-ui/assets/bg.png +0 -0
  46. package/src/plugin-ui/assets/icon.png +0 -0
  47. package/src/plugin-ui/assets/magic.svg +0 -5
  48. package/src/plugin-ui/assets/openagent-override.js +0 -11156
  49. package/src/plugin-ui/build.cjs +0 -463
  50. package/src/plugin-ui/index.ts +0 -18
  51. package/src/plugin-ui/modules/agent-book/panel/agent-book.js +0 -570
  52. package/src/plugin-ui/modules/agent-book/panel/agent-card.js +0 -170
  53. package/src/plugin-ui/modules/agent-book/panel/agent-data.js +0 -643
  54. package/src/plugin-ui/modules/agent-book/panel/inject-ui.js +0 -665
  55. package/src/plugin-ui/modules/agent-book/panel/mention-state.js +0 -206
  56. package/src/plugin-ui/modules/agent-book/panel/styles.js +0 -833
  57. package/src/plugin-ui/modules/agent-book/panel/theme-adapter.js +0 -86
  58. package/src/plugin-ui/modules/agent-book/remote-agent-tool/components-core.js +0 -295
  59. package/src/plugin-ui/modules/agent-book/remote-agent-tool/thought-chain-card.js +0 -211
  60. package/src/plugin-ui/modules/agent-book/scanner.js +0 -131
  61. package/src/plugin-ui/modules/agent-book/travelcard/travel-cards.js +0 -500
  62. package/src/plugin-ui/modules/agent-book/travelcard/travel-engine.js +0 -652
  63. package/src/plugin-ui/modules/agent-book/travelcard/travel-styles.js +0 -256
  64. package/src/plugin-ui/modules/loader/bootstrap.js +0 -38
  65. package/src/plugin-ui/modules/loader/shared-state.js +0 -838
  66. package/src/plugin-ui/modules/loader/ws-intercept.js +0 -199
  67. package/src/plugin-ui/modules/remote-agent/chunk-parser.js +0 -161
  68. package/src/plugin-ui/modules/remote-agent/execution-card.js +0 -530
  69. package/src/plugin-ui/modules/remote-agent/markdown-renderer.js +0 -256
  70. package/src/plugin-ui/modules/remote-agent/media-links.js +0 -151
  71. package/src/plugin-ui/modules/remote-agent/native-style-adapter.js +0 -134
  72. package/src/plugin-ui/modules/remote-agent/output-card.js +0 -342
  73. package/src/plugin-ui/modules/remote-agent/progress-store.js +0 -363
  74. package/src/plugin-ui/modules/remote-agent/render-hooks.js +0 -1700
  75. package/src/plugin-ui/modules/remote-agent/styles.js +0 -896
  76. package/src/plugin-ui/modules/remote-agent/tool-card-model.js +0 -130
  77. package/src/plugin-ui/postinstall-deploy.cjs +0 -52
  78. package/src/plugin-ui/ui-extension-loader/backup.ts +0 -92
  79. package/src/plugin-ui/ui-extension-loader/index.ts +0 -276
  80. package/src/plugin-ui/ui-extension-loader/locator.ts +0 -152
  81. package/src/plugin-ui/ui-extension-loader/manifest.ts +0 -57
  82. package/src/plugin-ui/ui-extension-loader/registry-regex.ts +0 -944
  83. package/src/plugin-ui/ui-extension-loader/removed-extensions.ts +0 -70
  84. package/src/plugin-ui/ui-extension-loader/types.ts +0 -72
  85. package/src/proxy/auth-proxy.ts +0 -409
  86. package/src/runtime/account.ts +0 -549
  87. package/src/runtime/index.ts +0 -7
  88. package/src/runtime/plugin-runtime.ts +0 -94
  89. package/src/runtime/registry.ts +0 -71
  90. package/src/sdk/CLASS_MAP.md +0 -143
  91. package/src/sdk/index.d.ts +0 -126
  92. package/src/sdk/index.js +0 -23990
  93. package/src/sdk/modules/cloud-search-module.js +0 -1117
  94. package/src/sdk/modules/follow-module.js +0 -1069
  95. package/src/sdk/modules/group-module.js +0 -7397
  96. package/src/sdk/modules/relationship-module.js +0 -2269
  97. package/src/sdk/modules/signaling-module.js +0 -1468
  98. package/src/sdk/modules/tim-upload-plugin.js +0 -730
  99. package/src/sdk/node-env/http-request.js +0 -90
  100. package/src/sdk/node-env/index.js +0 -57
  101. package/src/sdk/node-env/storage.js +0 -114
  102. package/src/sdk/package.json +0 -10
  103. package/src/sdk/tsconfig.json +0 -16
  104. package/src/state/pending-invocation-store.ts +0 -43
  105. package/src/state/store.ts +0 -756
  106. package/src/tim/c2c.ts +0 -451
  107. package/src/tim/channels.ts +0 -364
  108. package/src/tim/client.ts +0 -330
  109. package/src/tim/index.ts +0 -18
  110. package/src/tim/messages.ts +0 -166
  111. package/src/tim/sdk-logger-init.ts +0 -50
  112. package/src/tools.ts +0 -10
  113. package/src/transport/factory.ts +0 -95
  114. package/src/transport/oasn/index.ts +0 -17
  115. package/src/transport/oasn/oasn-agent-card.ts +0 -111
  116. package/src/transport/oasn/oasn-discovery.ts +0 -108
  117. package/src/transport/oasn/oasn-files.ts +0 -210
  118. package/src/transport/oasn/oasn-http.ts +0 -529
  119. package/src/transport/oasn/oasn-invocation.ts +0 -604
  120. package/src/transport/oasn/oasn-normalize.ts +0 -133
  121. package/src/transport/oasn/oasn-register.ts +0 -33
  122. package/src/transport/oasn/oasn-transport.ts +0 -318
  123. package/src/transport/oasn/oasn-types.ts +0 -404
  124. package/src/transport/tim/index.ts +0 -8
  125. package/src/transport/tim/tim-transport.ts +0 -515
  126. package/src/transport/types.ts +0 -538
  127. package/src/types/openclaw-plugin-sdk-media-store.d.ts +0 -9
  128. package/src/types/openclaw.d.ts +0 -97
  129. package/src/types/tencentcloud-chat.d.ts +0 -15
  130. package/src/util/http.ts +0 -113
  131. package/src/util/logger.ts +0 -131
  132. package/src/util/url-resolver.ts +0 -77
@@ -1,120 +0,0 @@
1
- /**
2
- * WindowAggregator — Message batching and ChannelDelta builder
3
- *
4
- * Buffers messages per channel with three flush triggers:
5
- * 1. @mention → immediate flush
6
- * 2. Buffer full → flush at maxBatchSize
7
- * 3. Timer → flush after batchWindowMs
8
- */
9
-
10
- import { logger } from '../util/logger.js';
11
- import type { RawMessage, ChannelDelta } from './types.js';
12
-
13
- export interface AggregatorConfig {
14
- batchWindowMs: number;
15
- maxBatchSize: number;
16
- }
17
-
18
- interface ChannelWindow {
19
- channelId: string;
20
- messages: RawMessage[];
21
- timer: ReturnType<typeof setTimeout> | null;
22
- }
23
-
24
- export class WindowAggregator {
25
- private windows = new Map<string, ChannelWindow>();
26
- private config: AggregatorConfig;
27
- public onDelta: ((delta: ChannelDelta) => void) | null = null;
28
-
29
- constructor(config: Partial<AggregatorConfig> = {}) {
30
- this.config = {
31
- batchWindowMs: config.batchWindowMs || 60_000,
32
- maxBatchSize: config.maxBatchSize || 20,
33
- };
34
- }
35
-
36
- updateConfig(newConfig: Partial<AggregatorConfig>): void {
37
- Object.assign(this.config, newConfig);
38
- }
39
-
40
- append(rawMessage: RawMessage): void {
41
- const channelId = rawMessage.channelId;
42
- const win = this._getOrCreate(channelId);
43
- win.messages.push(rawMessage);
44
-
45
- // Immediate flush on @mention
46
- if (rawMessage.mentionsMe) {
47
- this.flush(channelId, 'mention');
48
- return;
49
- }
50
-
51
- // Buffer full
52
- if (win.messages.length >= this.config.maxBatchSize) {
53
- this.flush(channelId, 'buffer_full');
54
- return;
55
- }
56
-
57
- // Start timer if not running
58
- if (!win.timer) {
59
- win.timer = setTimeout(
60
- () => this.flush(channelId, 'timeout'),
61
- this.config.batchWindowMs,
62
- );
63
- }
64
- }
65
-
66
- flush(channelId: string, reason: string): void {
67
- const win = this.windows.get(channelId);
68
- if (!win || win.messages.length === 0) return;
69
-
70
- const messages = win.messages.splice(0);
71
- if (win.timer) {
72
- clearTimeout(win.timer);
73
- win.timer = null;
74
- }
75
-
76
- const hasMention = messages.some(m => m.mentionsMe);
77
- const participants = [...new Set(messages.map(m => m.nick || m.from))];
78
- const source = messages[0]?.source || 'push';
79
-
80
- const delta: ChannelDelta = {
81
- channelId,
82
- channelName: channelId,
83
- messageCount: messages.length,
84
- participants,
85
- hasMention,
86
- urgency: hasMention ? 1.0 : Math.min(0.1 * messages.length, 0.9),
87
- messages,
88
- source,
89
- flushReason: reason,
90
- };
91
-
92
- logger.debug(`[aggregator] FLUSH ch=${channelId} reason=${reason} msgs=${messages.length} mention=${hasMention}`);
93
-
94
- if (this.onDelta) {
95
- this.onDelta(delta);
96
- }
97
- }
98
-
99
- flushAll(): void {
100
- for (const channelId of this.windows.keys()) {
101
- this.flush(channelId, 'shutdown');
102
- }
103
- }
104
-
105
- stop(): void {
106
- for (const win of this.windows.values()) {
107
- if (win.timer) clearTimeout(win.timer);
108
- }
109
- this.windows.clear();
110
- }
111
-
112
- private _getOrCreate(channelId: string): ChannelWindow {
113
- let win = this.windows.get(channelId);
114
- if (!win) {
115
- win = { channelId, messages: [], timer: null };
116
- this.windows.set(channelId, win);
117
- }
118
- return win;
119
- }
120
- }
@@ -1,89 +0,0 @@
1
- /**
2
- * Collector — Message deduplication and distribution
3
- *
4
- * Deduplicates incoming messages using StateStore (or in-memory fallback).
5
- * Agent's own messages are marked seen but NOT forwarded to aggregator.
6
- *
7
- * Authoritative writer for StateStore fields:
8
- * - last_visit: updated on ingest() success
9
- * - last_msg_seq: updated on ingest() when msg has sequence
10
- */
11
-
12
- import { logger } from '../util/logger.js';
13
- import type { StateStore } from '../state/store.js';
14
- import type { WindowAggregator } from './aggregator.js';
15
- import type { RawMessage } from './types.js';
16
-
17
- export class Collector {
18
- private aggregator: WindowAggregator;
19
- private store: StateStore | null;
20
- private agentId: string;
21
- private _memSeen = new Set<string>();
22
- private _memCleanupTimer: ReturnType<typeof setInterval> | null = null;
23
-
24
- constructor(aggregator: WindowAggregator, store: StateStore | null = null, agentId = '') {
25
- this.aggregator = aggregator;
26
- this.store = store;
27
- this.agentId = agentId;
28
- }
29
-
30
- ingest(rawMessage: RawMessage): void {
31
- if (this._hasSeen(rawMessage.id)) {
32
- logger.debug(`[collector] DEDUP skip id=${rawMessage.id}`);
33
- return;
34
- }
35
-
36
- // Mark as seen
37
- this._markSeen(rawMessage.id, rawMessage.channelId);
38
-
39
- // Update StateStore: last_visit + last_msg_seq
40
- if (this.store) {
41
- this.store.updateLastVisit(rawMessage.channelId);
42
- if (rawMessage.seq != null) {
43
- this.store.updateLastMsgSeq(rawMessage.channelId, rawMessage.seq);
44
- }
45
- }
46
-
47
- // Agent's own messages: mark seen but don't trigger agent turns
48
- if (this.agentId && rawMessage.from === this.agentId) {
49
- logger.debug(`[collector] SELF msg id=${rawMessage.id} (marked seen, no turn)`);
50
- return;
51
- }
52
-
53
- logger.debug(`[collector] NEW msg id=${rawMessage.id} ch=${rawMessage.channelId} from=${rawMessage.nick}`);
54
- this.aggregator.append(rawMessage);
55
- }
56
-
57
- ingestBatch(rawMessages: RawMessage[]): void {
58
- for (const msg of rawMessages) {
59
- this.ingest(msg);
60
- }
61
- }
62
-
63
- private _hasSeen(messageId: string): boolean {
64
- if (this.store) return this.store.hasSeen(messageId);
65
- return this._memSeen.has(messageId);
66
- }
67
-
68
- private _markSeen(messageId: string, channelId: string): void {
69
- if (this.store) {
70
- this.store.markSeen(messageId, channelId);
71
- } else {
72
- this._memSeen.add(messageId);
73
- }
74
- }
75
-
76
- startCleanup(intervalMs = 600_000): void {
77
- if (this.store) return; // StateStore handles its own cleanup
78
- this._memCleanupTimer = setInterval(() => {
79
- this._memSeen.clear();
80
- }, intervalMs);
81
- }
82
-
83
- stop(): void {
84
- if (this._memCleanupTimer) {
85
- clearInterval(this._memCleanupTimer);
86
- this._memCleanupTimer = null;
87
- }
88
- }
89
- }
@@ -1,72 +0,0 @@
1
- /**
2
- * ActionExecutor — Triggers OpenClaw agent turn via CLI
3
- *
4
- * Uses `openclaw agent` to inject inbound messages.
5
- * Agent replies via openagent_send_message tool call.
6
- */
7
-
8
- import { execFile } from 'node:child_process';
9
- import { promisify } from 'node:util';
10
-
11
- import { logger } from '../util/logger.js';
12
- import type { ChannelDelta } from './types.js';
13
-
14
- const execFileAsync = promisify(execFile);
15
-
16
- export class ActionExecutor {
17
- private accountId = 'default';
18
- private openclawBin = 'openclaw';
19
-
20
- setAccountId(accountId: string): void {
21
- this.accountId = accountId || 'default';
22
- }
23
-
24
- async handleDelta(delta: ChannelDelta): Promise<void> {
25
- const text = this._formatDeltaText(delta);
26
-
27
- logger.info(`[executor] INBOUND ch=${delta.channelId} msgs=${delta.messageCount} mention=${delta.hasMention}`);
28
-
29
- try {
30
- const args = [
31
- 'agent',
32
- '--agent', 'main',
33
- '--channel', 'openagent',
34
- '--message', text,
35
- '--session-id', `openagent:${delta.channelId}`,
36
- '--json',
37
- ];
38
-
39
- const { stdout, stderr } = await execFileAsync(this.openclawBin, args, {
40
- timeout: 120_000,
41
- env: { ...process.env },
42
- });
43
-
44
- if (stderr) {
45
- logger.debug(`[executor] stderr: ${stderr.substring(0, 500)}`);
46
- }
47
- if (stdout) {
48
- logger.info(`[executor] Agent turn completed for ch=${delta.channelId}`);
49
- }
50
- } catch (err) {
51
- logger.error(`[executor] Agent turn failed: ${(err as Error).message}`);
52
- }
53
- }
54
-
55
- private _formatDeltaText(delta: ChannelDelta): string {
56
- const { channelId, messages, hasMention } = delta;
57
- const mentionTag = hasMention ? ' ⚡ @mention' : '';
58
-
59
- let messageSection: string;
60
- if (messages.length === 1) {
61
- const m = messages[0]!;
62
- messageSection = `[Channel ${channelId}${mentionTag}] ${m.nick}: ${m.text}`;
63
- } else {
64
- const summary = messages.map(m => `[${m.nick}] ${m.text}`).join('\n');
65
- messageSection = `📬 ${messages.length} new messages in channel ${channelId}${mentionTag}:\n${summary}`;
66
- }
67
-
68
- const instruction = `[INSTRUCTION: Reply ONLY in channel ${channelId} using openagent_send_message. After calling the tool, respond with ONLY: NO_REPLY (this prevents your reply from leaking to the chat UI). Do NOT visit other channels. Do NOT send status reports. Just reply naturally to the conversation above, or stay silent if you have nothing to add.]`;
69
-
70
- return `${messageSection}\n\n${instruction}`;
71
- }
72
- }
@@ -1,150 +0,0 @@
1
- /**
2
- * Inbound — TIM push message → standard OpenClaw MsgContext conversion
3
- *
4
- * This module converts the TIM SDK's RawPushMessage into the standard
5
- * MsgContext shape expected by channelRuntime.reply.dispatchReplyFromConfig().
6
- *
7
- * v3.4.0: Added BodyForAgent, InboundHistory, GroupSystemPrompt, GroupSubject,
8
- * ConversationLabel, Surface, SenderId, RawBody, CommandBody to match
9
- * the official plugin contract (Signal, LINE, Discord).
10
- * See: docs/audit/008-inbound-context-gap.md
11
- *
12
- * Reference: docs/reference/plugins/openclaw-weixin/src/messaging/inbound.ts
13
- */
14
-
15
- import type { RawPushMessage } from '../tim/client.js';
16
-
17
- // ── Types ──
18
-
19
- /** History entry for InboundHistory field. */
20
- export interface InboundHistoryEntry {
21
- sender: string;
22
- body: string;
23
- timestamp: number;
24
- }
25
-
26
- /** Extra context not available from the raw TIM message alone. */
27
- export interface InboundExtras {
28
- /** Group display name (fetched from TIM group profile) */
29
- groupName?: string;
30
- /** Group-level system prompt (from channel skill / notification field) */
31
- groupSystemPrompt?: string;
32
- /** Recent message history for this channel */
33
- inboundHistory?: InboundHistoryEntry[];
34
- }
35
-
36
- /**
37
- * Standard inbound context for the OpenClaw pipeline.
38
- * Field names MUST match the OpenClaw MsgContext contract.
39
- */
40
- export interface OpenagentMsgContext {
41
- /** Message text body (may include envelope in future) */
42
- Body: string;
43
- /** Current message original text — LLM prompt main body */
44
- BodyForAgent: string;
45
- /** Raw message body for command detection */
46
- RawBody: string;
47
- /** Command detection text */
48
- CommandBody: string;
49
- /** Sender user ID */
50
- From: string;
51
- /** Destination (channel ID for group chats) */
52
- To: string;
53
- /** Account ID this message belongs to */
54
- AccountId: string;
55
- /** Sender machine ID */
56
- SenderId: string;
57
- /** Sender display name */
58
- SenderName: string;
59
- /** Human-readable conversation label */
60
- ConversationLabel: string;
61
- /** Group name / subject */
62
- GroupSubject: string;
63
- /** Channel plugin identifier */
64
- OriginatingChannel: 'openagent';
65
- /** Original destination identifier */
66
- OriginatingTo: string;
67
- /** Unique message ID */
68
- MessageSid: string;
69
- /** Message timestamp (ms) */
70
- Timestamp?: number;
71
- /** Provider identifier */
72
- Provider: 'openagent';
73
- /** Platform surface identifier */
74
- Surface: 'openagent';
75
- /** Chat type: OpenAgent is group-only */
76
- ChatType: 'group';
77
- /** Whether the message @mentioned our agent */
78
- WasMentioned?: boolean;
79
- /** Session key override (set after resolveAgentRoute) */
80
- SessionKey?: string;
81
- /** Whether sender is authorized for slash commands */
82
- CommandAuthorized?: boolean;
83
- /** Group-level system prompt (channel skill / rules) */
84
- GroupSystemPrompt?: string;
85
- /** Recent message history for this channel */
86
- InboundHistory?: InboundHistoryEntry[];
87
- }
88
-
89
- // ── Conversion ──
90
-
91
- /**
92
- * Convert a TIM RawPushMessage to the standard MsgContext.
93
- *
94
- * Mapping:
95
- * raw.text → Body, BodyForAgent, RawBody, CommandBody
96
- * raw.from → From, SenderId
97
- * raw.channelId → To, OriginatingTo
98
- * raw.nick → SenderName
99
- * raw.id → MessageSid
100
- * raw.time → Timestamp
101
- * raw.mentionsMe → WasMentioned
102
- * extras.groupName → GroupSubject, ConversationLabel
103
- * extras.groupSystemPrompt → GroupSystemPrompt
104
- * extras.inboundHistory → InboundHistory
105
- */
106
- export function timMessageToMsgContext(
107
- raw: RawPushMessage,
108
- accountId: string,
109
- extras?: InboundExtras,
110
- ): OpenagentMsgContext {
111
- const senderName = raw.nick || raw.from;
112
- const groupName = extras?.groupName || raw.channelId;
113
-
114
- return {
115
- // ── Message body (4 variants per official contract) ──
116
- Body: raw.text,
117
- BodyForAgent: raw.text,
118
- RawBody: raw.text,
119
- CommandBody: raw.text,
120
-
121
- // ── Routing ──
122
- From: raw.from,
123
- To: raw.channelId,
124
- AccountId: accountId,
125
-
126
- // ── Sender info ──
127
- SenderId: raw.from,
128
- SenderName: senderName,
129
-
130
- // ── Group info ──
131
- ConversationLabel: groupName,
132
- GroupSubject: groupName,
133
-
134
- // ── Channel metadata ──
135
- OriginatingChannel: 'openagent',
136
- OriginatingTo: raw.channelId,
137
- MessageSid: raw.id,
138
- Timestamp: raw.time,
139
- Provider: 'openagent',
140
- Surface: 'openagent',
141
- ChatType: 'group',
142
-
143
- // ── Flags ──
144
- WasMentioned: raw.mentionsMe,
145
-
146
- // ── Enriched context (from extras) ──
147
- GroupSystemPrompt: extras?.groupSystemPrompt || undefined,
148
- InboundHistory: extras?.inboundHistory,
149
- };
150
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Messaging — Module barrel export
3
- *
4
- * v3.2.0: New channelRuntime-based pipeline (inbound + process-message).
5
- * Legacy modules (collector, aggregator, scheduler, executor) are retained
6
- * on disk but no longer exported or referenced.
7
- */
8
-
9
- export { timMessageToMsgContext, type OpenagentMsgContext } from './inbound.js';
10
- export { processOneMessage, type ProcessMessageDeps } from './process-message.js';
11
- export type { RawMessage, ChannelDelta, HistoryMessage } from './types.js';
@@ -1,94 +0,0 @@
1
- /**
2
- * Mention Protocol — Bot-to-Bot communication in mention-only groups
3
- *
4
- * Pure function module — no side effects, no shared state.
5
- *
6
- * When a group has gm_req_mention=1, bots need to:
7
- * 1. Know the group's "social rule" (must @-mention to trigger others)
8
- * 2. Know who's in the group (member list)
9
- * 3. Have their text-level @mentions translated to TIM protocol-level atUserList
10
- *
11
- * See: docs/audit/012-mention-mode-bot-to-bot-v3.4.4.md
12
- */
13
-
14
- // ── Types ──
15
-
16
- export interface MentionMember {
17
- id: string;
18
- nick: string;
19
- }
20
-
21
- // ── Regex utility ──
22
-
23
- function escapeRegex(s: string): string {
24
- return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
25
- }
26
-
27
- // ── Prompt injection ──
28
-
29
- /**
30
- * Build the mention protocol prompt to inject into GroupSystemPrompt.
31
- * Tells the AI: this group is mention-only, here are the members,
32
- * you must @mention them to communicate.
33
- *
34
- * Returns empty string if no other members exist.
35
- */
36
- export function buildMentionPrompt(
37
- members: MentionMember[],
38
- selfId: string,
39
- ): string {
40
- const others = members.filter(m => m.id !== selfId);
41
- if (others.length === 0) return '';
42
-
43
- const memberList = others
44
- .map(m => `- ${m.nick} (mention as: @${m.nick})`)
45
- .join('\n');
46
-
47
- return [
48
- '[GROUP COMMUNICATION PROTOCOL]',
49
- 'This group uses mention-only mode.',
50
- 'Your messages will ONLY be seen by members you @-mention.',
51
- 'To mention someone, write @their_name in your message.',
52
- '',
53
- 'Group members:',
54
- memberList,
55
- '',
56
- `Example: "@${others[0].nick} what do you think?"`,
57
- '[/GROUP COMMUNICATION PROTOCOL]',
58
- ].join('\n');
59
- }
60
-
61
- // ── Text → atUserList extraction ──
62
-
63
- /**
64
- * Extract @-mention targets from AI output text.
65
- *
66
- * Strategy: iterate the known member list and search for each nick
67
- * in the text. This is more robust than parsing @-tokens from text,
68
- * because it handles:
69
- * - Space after @: "@ 投资人Bot"
70
- * - Case mismatch: "@投资人bot"
71
- * - Trailing punct: "@投资人Bot,你好"
72
- * - Multiple @: "@BotA @BotB hi"
73
- *
74
- * Only matches when @ prefix is present — mentioning a name without @
75
- * (e.g. "投资人Bot说得对") does NOT trigger a match.
76
- *
77
- * Returns an array of userIDs suitable for TIM createTextAtMessage.
78
- * Returns empty array if no matches found.
79
- */
80
- export function extractAtTargets(
81
- text: string,
82
- members: MentionMember[],
83
- selfId: string,
84
- ): string[] {
85
- const results: string[] = [];
86
- for (const member of members) {
87
- if (member.id === selfId) continue;
88
- const pattern = new RegExp(`@\\s*${escapeRegex(member.nick)}`, 'i');
89
- if (pattern.test(text)) {
90
- results.push(member.id);
91
- }
92
- }
93
- return results;
94
- }