mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-09 00:33:20 +08:00
fix(weixin): align long-reply limits across runtime
This commit is contained in:
parent
868372fb04
commit
5e07137c44
7 changed files with 178 additions and 165 deletions
310
lib/index.js
310
lib/index.js
File diff suppressed because one or more lines are too long
|
|
@ -5,7 +5,10 @@ import { join, resolve } from 'node:path';
|
|||
import { WeixinConfigStore } from '../../../../src/channels/weixin/config-store.mjs';
|
||||
import { HarnessClient } from '../../../../src/channels/weixin/harness-client.mjs';
|
||||
import { WeixinStateStore } from '../../../../src/channels/weixin/state-store.mjs';
|
||||
import { createWeixinApi } from '../../../../src/channels/weixin/weixin-api.mjs';
|
||||
import {
|
||||
createWeixinApi,
|
||||
DEFAULT_WEIXIN_MAX_MESSAGE_CHARS,
|
||||
} from '../../../../src/channels/weixin/weixin-api.mjs';
|
||||
import { WeixinController } from '../../../../src/channels/weixin/weixin-controller.mjs';
|
||||
import { WeixinRuntime } from '../../../../src/channels/weixin/weixin-runtime.mjs';
|
||||
import {
|
||||
|
|
@ -113,7 +116,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|||
harness: workspaceScope.harness,
|
||||
state: workspaceScope.state,
|
||||
replyTimeoutMs: config.replyTimeoutMs ?? 600_000,
|
||||
maxMessageChars: config.maxMessageChars ?? 4_000,
|
||||
maxMessageChars: config.maxMessageChars ?? DEFAULT_WEIXIN_MAX_MESSAGE_CHARS,
|
||||
logger: {
|
||||
error: (...args) => logger.error?.(`[${botId}]`, ...args),
|
||||
warn: (...args) => logger.warn?.(`[${botId}]`, ...args),
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ export const WEIXIN_QR_BASE_URL = 'https://ilinkai.weixin.qq.com/';
|
|||
export const WEIXIN_PROTOCOL_VERSION = '2.4.6';
|
||||
export const DEFAULT_BOT_TYPE = '3';
|
||||
export const WEIXIN_CDN_BASE_URL = 'https://novac2c.cdn.weixin.qq.com/c2c';
|
||||
export const DEFAULT_WEIXIN_MAX_MESSAGE_CHARS = 1_800;
|
||||
|
||||
const WEIXIN_CDN_HOST = 'novac2c.cdn.weixin.qq.com';
|
||||
|
||||
|
|
@ -744,7 +745,7 @@ export function weixinMessageId(message) {
|
|||
return nonEmptyString(message?.client_id);
|
||||
}
|
||||
|
||||
export function splitWeixinText(text, maxChars = 4_000) {
|
||||
export function splitWeixinText(text, maxChars = DEFAULT_WEIXIN_MAX_MESSAGE_CHARS) {
|
||||
if (text.length <= maxChars) return [text];
|
||||
const chunks = [];
|
||||
let remaining = text;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import {
|
||||
DEFAULT_WEIXIN_MAX_MESSAGE_CHARS,
|
||||
extractWeixinFiles,
|
||||
extractWeixinImages,
|
||||
extractWeixinText,
|
||||
|
|
@ -184,7 +185,7 @@ export class WeixinHarnessBridge {
|
|||
status = createWeixinBridgeStatus(),
|
||||
logger = console,
|
||||
replyTimeoutMs = 600_000,
|
||||
maxMessageChars = 1_800,
|
||||
maxMessageChars = DEFAULT_WEIXIN_MAX_MESSAGE_CHARS,
|
||||
signal,
|
||||
}) {
|
||||
if (!api || typeof api.sendText !== 'function') throw new TypeError('Weixin API is required');
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { WeixinApiError } from './weixin-api.mjs';
|
||||
import { DEFAULT_WEIXIN_MAX_MESSAGE_CHARS, WeixinApiError } from './weixin-api.mjs';
|
||||
import { createWeixinBridgeStatus, WeixinHarnessBridge } from './weixin-bridge.mjs';
|
||||
import {
|
||||
connectionTestTarget,
|
||||
|
|
@ -109,7 +109,7 @@ export class WeixinRuntime {
|
|||
state,
|
||||
logger = console,
|
||||
replyTimeoutMs = 600_000,
|
||||
maxMessageChars = 4_000,
|
||||
maxMessageChars = DEFAULT_WEIXIN_MAX_MESSAGE_CHARS,
|
||||
startRetryDelaysMs,
|
||||
}) {
|
||||
if (!api || !config || !token || !harness || !state) {
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ test('Weixin production has no per-bot result-file Gate', async (t) => {
|
|||
|
||||
assert.equal(Object.hasOwn(runtimes[0], 'outboundArtifactsEnabled'), false);
|
||||
assert.equal(Object.hasOwn(runtimes[1], 'outboundArtifactsEnabled'), false);
|
||||
assert.equal(runtimes[0].maxMessageChars, 1_800);
|
||||
assert.equal(runtimes[1].maxMessageChars, 1_800);
|
||||
await production.close();
|
||||
|
||||
const productionWithDefault = await createProductionController(ctx, { dataDir }, internals);
|
||||
|
|
@ -72,5 +74,6 @@ test('Weixin production has no per-bot result-file Gate', async (t) => {
|
|||
token: 'host-only',
|
||||
});
|
||||
assert.equal(Object.hasOwn(runtimes[2], 'outboundArtifactsEnabled'), false);
|
||||
assert.equal(runtimes[2].maxMessageChars, 1_800);
|
||||
await productionWithDefault.close();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ test('runtime verifies the token, consumes getUpdates, replies, persists cursor,
|
|||
const calls = [];
|
||||
let pollCount = 0;
|
||||
let askSignal;
|
||||
const answer = '答'.repeat(2_000);
|
||||
const stateData = { cursor: '', seen: new Set(), session: null };
|
||||
const api = {
|
||||
notifyStart: async (request) => calls.push(['start', request.token]),
|
||||
|
|
@ -133,7 +134,7 @@ test('runtime verifies the token, consumes getUpdates, replies, persists cursor,
|
|||
createSession: async () => 'session-1',
|
||||
ask: async (_sessionId, _text, options) => {
|
||||
askSignal = options.signal;
|
||||
return '回答';
|
||||
return answer;
|
||||
},
|
||||
},
|
||||
state,
|
||||
|
|
@ -145,10 +146,14 @@ test('runtime verifies the token, consumes getUpdates, replies, persists cursor,
|
|||
await flush();
|
||||
await flush();
|
||||
assert.equal(stateData.cursor, 'cursor-next');
|
||||
assert.deepEqual(calls.slice(0, 2), [
|
||||
['start', 'bot-token'],
|
||||
['send', '回答', 'context-7'],
|
||||
assert.equal(calls[0][0], 'start');
|
||||
assert.deepEqual(calls.slice(1, 3).map((call) => call[1].length), [1_800, 200]);
|
||||
assert.equal(calls.slice(1, 3).map((call) => call[1]).join(''), answer);
|
||||
assert.deepEqual(calls.slice(1, 3).map((call) => call[2]), [
|
||||
'context-7',
|
||||
'context-7',
|
||||
]);
|
||||
assert.equal(runtime.status.messagesReplied, 1);
|
||||
assert.equal(askSignal.aborted, false);
|
||||
await runtime.stop();
|
||||
assert.equal(askSignal.aborted, true);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue