fix: make apiProxy injection optional

Resolves the optional apiProxy injection, keeps HTML as the compatibility default, synchronizes generated entrypoints, and adds a regression test.
This commit is contained in:
徐跃恒
2026-09-15 21:36:14 +08:00
committed by GitHub
parent 93f3bec975
commit 72e1d399a7
7 changed files with 22 additions and 13 deletions
+1 -1
View File
@@ -174,7 +174,7 @@ dsh plugin --profile web add D:\path\to\dsh-telegram-channel
| `allowAllUsers` | `true` 仅调试 | | `allowAllUsers` | `true` 仅调试 |
| `maxMessageLength` | 默认 4096 | | `maxMessageLength` | 默认 4096 |
| `pollingTimeoutSec` | 默认 30 | | `pollingTimeoutSec` | 默认 30 |
| `rendering` | `rich`(默认,原生 Rich Message)或 `html`(旧 Markdown→HTML 兼容) | | `rendering` | `html`(默认,兼容所有客户端)或 `rich`(原生 Rich Message) |
若本机用了 HTTP(S)_PROXY 访问 Telegram,插件会自动走代理(无需再设 `NODE_USE_ENV_PROXY`)。 若本机用了 HTTP(S)_PROXY 访问 Telegram,插件会自动走代理(无需再设 `NODE_USE_ENV_PROXY`)。
+2 -1
View File
@@ -61,7 +61,8 @@ export class TelegramBridge {
}); });
this.sleep = options.sleep ?? defaultSleep; this.sleep = options.sleep ?? defaultSleep;
this.maxMessageLength = options.maxMessageLength ?? 4096; this.maxMessageLength = options.maxMessageLength ?? 4096;
this.renderingMode = options.rendering === 'html' ? 'html' : 'rich'; // HTML is the compatibility default; opt into Rich Messages explicitly.
this.renderingMode = options.rendering === 'rich' ? 'rich' : 'html';
} }
start() { start() {
this.disposeSessionListener?.(); this.disposeSessionListener?.();
+2 -1
View File
@@ -1,7 +1,8 @@
import type { Context } from '@deepseek-ai/cordis'; import type { Context } from '@deepseek-ai/cordis';
import Schema from '@deepseek-ai/schemastery'; import Schema from '@deepseek-ai/schemastery';
export declare const name = "dsh-telegram-channel"; export declare const name = "dsh-telegram-channel";
/** agents: followup; apiProxy: workspace/session catalog + /model (Cordis requires inject to read ctx.apiProxy). */ /** agents: followup; apiProxy is optional and resolved at runtime via ctx.get;
* when absent, catalog helpers degrade to the live-agents view. */
export declare const inject: string[]; export declare const inject: string[];
export interface TelegramChannelConfig { export interface TelegramChannelConfig {
token?: string; token?: string;
+5 -4
View File
@@ -1,15 +1,16 @@
import Schema from '@deepseek-ai/schemastery'; import Schema from '@deepseek-ai/schemastery';
import { TelegramBridge } from './bridge.js'; import { TelegramBridge } from './bridge.js';
export const name = 'dsh-telegram-channel'; export const name = 'dsh-telegram-channel';
/** agents: followup; apiProxy: workspace/session catalog + /model (Cordis requires inject to read ctx.apiProxy). */ /** agents: followup; apiProxy is optional and resolved at runtime via ctx.get;
export const inject = ['agents', 'apiProxy']; * when absent, catalog helpers degrade to the live-agents view. */
export const inject = ['agents'];
export const Config = Schema.object({ export const Config = Schema.object({
token: Schema.string().default(''), token: Schema.string().default(''),
allowedUserIds: Schema.array(Schema.number()).default([]), allowedUserIds: Schema.array(Schema.number()).default([]),
allowAllUsers: Schema.boolean().default(false), allowAllUsers: Schema.boolean().default(false),
maxMessageLength: Schema.number().default(4096), maxMessageLength: Schema.number().default(4096),
pollingTimeoutSec: Schema.number().default(30), pollingTimeoutSec: Schema.number().default(30),
rendering: Schema.string().default('rich'), rendering: Schema.string().default('html'),
}); });
function resolveAllowedUserIds(config) { function resolveAllowedUserIds(config) {
if (config.allowedUserIds && config.allowedUserIds.length > 0) { if (config.allowedUserIds && config.allowedUserIds.length > 0) {
@@ -37,7 +38,7 @@ export function apply(ctx, config) {
allowAllUsers: config.allowAllUsers ?? false, allowAllUsers: config.allowAllUsers ?? false,
maxMessageLength: config.maxMessageLength ?? 4096, maxMessageLength: config.maxMessageLength ?? 4096,
pollingTimeoutSec: config.pollingTimeoutSec ?? 30, pollingTimeoutSec: config.pollingTimeoutSec ?? 30,
rendering: config.rendering === 'html' ? 'html' : 'rich', rendering: config.rendering === 'rich' ? 'rich' : 'html',
}); });
ctx.effect(() => { ctx.effect(() => {
bridge.start(); bridge.start();
+2 -1
View File
@@ -121,7 +121,8 @@ export class TelegramBridge {
}) })
this.sleep = options.sleep ?? defaultSleep this.sleep = options.sleep ?? defaultSleep
this.maxMessageLength = options.maxMessageLength ?? 4096 this.maxMessageLength = options.maxMessageLength ?? 4096
this.renderingMode = options.rendering === 'html' ? 'html' : 'rich' // HTML is the compatibility default; opt into Rich Messages explicitly.
this.renderingMode = options.rendering === 'rich' ? 'rich' : 'html'
} }
start(): void { start(): void {
+5 -4
View File
@@ -3,8 +3,9 @@ import Schema from '@deepseek-ai/schemastery'
import { TelegramBridge } from './bridge.js' import { TelegramBridge } from './bridge.js'
export const name = 'dsh-telegram-channel' export const name = 'dsh-telegram-channel'
/** agents: followup; apiProxy: workspace/session catalog + /model (Cordis requires inject to read ctx.apiProxy). */ /** agents: followup; apiProxy is optional and resolved at runtime via ctx.get;
export const inject = ['agents', 'apiProxy'] * when absent, catalog helpers degrade to the live-agents view. */
export const inject = ['agents']
export interface TelegramChannelConfig { export interface TelegramChannelConfig {
token?: string token?: string
@@ -21,7 +22,7 @@ export const Config: Schema<TelegramChannelConfig> = Schema.object({
allowAllUsers: Schema.boolean().default(false), allowAllUsers: Schema.boolean().default(false),
maxMessageLength: Schema.number().default(4096), maxMessageLength: Schema.number().default(4096),
pollingTimeoutSec: Schema.number().default(30), pollingTimeoutSec: Schema.number().default(30),
rendering: Schema.string().default('rich'), rendering: Schema.string().default('html'),
}) })
function resolveAllowedUserIds(config: TelegramChannelConfig): number[] { function resolveAllowedUserIds(config: TelegramChannelConfig): number[] {
@@ -53,7 +54,7 @@ export function apply(ctx: Context, config: TelegramChannelConfig): void {
allowAllUsers: config.allowAllUsers ?? false, allowAllUsers: config.allowAllUsers ?? false,
maxMessageLength: config.maxMessageLength ?? 4096, maxMessageLength: config.maxMessageLength ?? 4096,
pollingTimeoutSec: config.pollingTimeoutSec ?? 30, pollingTimeoutSec: config.pollingTimeoutSec ?? 30,
rendering: config.rendering === 'html' ? 'html' : 'rich', rendering: config.rendering === 'rich' ? 'rich' : 'html',
}) })
ctx.effect(() => { ctx.effect(() => {
bridge.start() bridge.start()
+5 -1
View File
@@ -1,6 +1,10 @@
import assert from 'node:assert/strict' import assert from 'node:assert/strict'
import test from 'node:test' import test from 'node:test'
import { apply } from '../src/index.ts' import { apply, inject } from '../src/index.ts'
test('apiProxy is optional and is not a hard Cordis dependency', () => {
assert.deepEqual(inject, ['agents'])
})
test('apply without token does not throw and does not start effect', () => { test('apply without token does not throw and does not start effect', () => {
const effects: string[] = [] const effects: string[] = []