opencode-bridge 2.9.0-beta
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/.env.example +131 -0
- package/LICENSE +674 -0
- package/README.md +1195 -0
- package/bin/opencode-bridge.js +31 -0
- package/dist/commands/effort.d.ts +9 -0
- package/dist/commands/effort.d.ts.map +1 -0
- package/dist/commands/effort.js +56 -0
- package/dist/commands/effort.js.map +1 -0
- package/dist/commands/parser.d.ts +37 -0
- package/dist/commands/parser.d.ts.map +1 -0
- package/dist/commands/parser.js +355 -0
- package/dist/commands/parser.js.map +1 -0
- package/dist/config.d.ts +91 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +340 -0
- package/dist/config.js.map +1 -0
- package/dist/feishu/cards-stream.d.ts +65 -0
- package/dist/feishu/cards-stream.d.ts.map +1 -0
- package/dist/feishu/cards-stream.js +448 -0
- package/dist/feishu/cards-stream.js.map +1 -0
- package/dist/feishu/cards.d.ts +81 -0
- package/dist/feishu/cards.d.ts.map +1 -0
- package/dist/feishu/cards.js +560 -0
- package/dist/feishu/cards.js.map +1 -0
- package/dist/feishu/client.d.ts +132 -0
- package/dist/feishu/client.d.ts.map +1 -0
- package/dist/feishu/client.js +952 -0
- package/dist/feishu/client.js.map +1 -0
- package/dist/feishu/streamer.d.ts +30 -0
- package/dist/feishu/streamer.d.ts.map +1 -0
- package/dist/feishu/streamer.js +95 -0
- package/dist/feishu/streamer.js.map +1 -0
- package/dist/handlers/card-action.d.ts +12 -0
- package/dist/handlers/card-action.d.ts.map +1 -0
- package/dist/handlers/card-action.js +154 -0
- package/dist/handlers/card-action.js.map +1 -0
- package/dist/handlers/command.d.ts +76 -0
- package/dist/handlers/command.d.ts.map +1 -0
- package/dist/handlers/command.js +1773 -0
- package/dist/handlers/command.js.map +1 -0
- package/dist/handlers/discord.d.ts +78 -0
- package/dist/handlers/discord.d.ts.map +1 -0
- package/dist/handlers/discord.js +1832 -0
- package/dist/handlers/discord.js.map +1 -0
- package/dist/handlers/file-sender.d.ts +22 -0
- package/dist/handlers/file-sender.d.ts.map +1 -0
- package/dist/handlers/file-sender.js +183 -0
- package/dist/handlers/file-sender.js.map +1 -0
- package/dist/handlers/group.d.ts +21 -0
- package/dist/handlers/group.d.ts.map +1 -0
- package/dist/handlers/group.js +414 -0
- package/dist/handlers/group.js.map +1 -0
- package/dist/handlers/lifecycle.d.ts +17 -0
- package/dist/handlers/lifecycle.d.ts.map +1 -0
- package/dist/handlers/lifecycle.js +129 -0
- package/dist/handlers/lifecycle.js.map +1 -0
- package/dist/handlers/p2p.d.ts +44 -0
- package/dist/handlers/p2p.d.ts.map +1 -0
- package/dist/handlers/p2p.js +625 -0
- package/dist/handlers/p2p.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1562 -0
- package/dist/index.js.map +1 -0
- package/dist/opencode/client.d.ts +176 -0
- package/dist/opencode/client.d.ts.map +1 -0
- package/dist/opencode/client.js +1126 -0
- package/dist/opencode/client.js.map +1 -0
- package/dist/opencode/delayed-handler.d.ts +33 -0
- package/dist/opencode/delayed-handler.d.ts.map +1 -0
- package/dist/opencode/delayed-handler.js +74 -0
- package/dist/opencode/delayed-handler.js.map +1 -0
- package/dist/opencode/output-buffer.d.ts +56 -0
- package/dist/opencode/output-buffer.d.ts.map +1 -0
- package/dist/opencode/output-buffer.js +202 -0
- package/dist/opencode/output-buffer.js.map +1 -0
- package/dist/opencode/question-handler.d.ts +61 -0
- package/dist/opencode/question-handler.d.ts.map +1 -0
- package/dist/opencode/question-handler.js +183 -0
- package/dist/opencode/question-handler.js.map +1 -0
- package/dist/opencode/question-parser.d.ts +9 -0
- package/dist/opencode/question-parser.d.ts.map +1 -0
- package/dist/opencode/question-parser.js +69 -0
- package/dist/opencode/question-parser.js.map +1 -0
- package/dist/opencode/session-queue.d.ts +16 -0
- package/dist/opencode/session-queue.d.ts.map +1 -0
- package/dist/opencode/session-queue.js +41 -0
- package/dist/opencode/session-queue.js.map +1 -0
- package/dist/permissions/handler.d.ts +36 -0
- package/dist/permissions/handler.d.ts.map +1 -0
- package/dist/permissions/handler.js +141 -0
- package/dist/permissions/handler.js.map +1 -0
- package/dist/platform/adapters/discord-adapter.d.ts +45 -0
- package/dist/platform/adapters/discord-adapter.d.ts.map +1 -0
- package/dist/platform/adapters/discord-adapter.js +497 -0
- package/dist/platform/adapters/discord-adapter.js.map +1 -0
- package/dist/platform/adapters/feishu-adapter.d.ts +29 -0
- package/dist/platform/adapters/feishu-adapter.d.ts.map +1 -0
- package/dist/platform/adapters/feishu-adapter.js +150 -0
- package/dist/platform/adapters/feishu-adapter.js.map +1 -0
- package/dist/platform/registry.d.ts +41 -0
- package/dist/platform/registry.d.ts.map +1 -0
- package/dist/platform/registry.js +87 -0
- package/dist/platform/registry.js.map +1 -0
- package/dist/platform/types.d.ts +92 -0
- package/dist/platform/types.d.ts.map +1 -0
- package/dist/platform/types.js +4 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/reliability/audit-log.d.ts +93 -0
- package/dist/reliability/audit-log.d.ts.map +1 -0
- package/dist/reliability/audit-log.js +248 -0
- package/dist/reliability/audit-log.js.map +1 -0
- package/dist/reliability/config-guard.d.ts +42 -0
- package/dist/reliability/config-guard.d.ts.map +1 -0
- package/dist/reliability/config-guard.js +264 -0
- package/dist/reliability/config-guard.js.map +1 -0
- package/dist/reliability/conversation-heartbeat.d.ts +37 -0
- package/dist/reliability/conversation-heartbeat.d.ts.map +1 -0
- package/dist/reliability/conversation-heartbeat.js +179 -0
- package/dist/reliability/conversation-heartbeat.js.map +1 -0
- package/dist/reliability/cron-api-server.d.ts +13 -0
- package/dist/reliability/cron-api-server.d.ts.map +1 -0
- package/dist/reliability/cron-api-server.js +247 -0
- package/dist/reliability/cron-api-server.js.map +1 -0
- package/dist/reliability/cron-control.d.ts +34 -0
- package/dist/reliability/cron-control.d.ts.map +1 -0
- package/dist/reliability/cron-control.js +864 -0
- package/dist/reliability/cron-control.js.map +1 -0
- package/dist/reliability/cron-semantic.d.ts +9 -0
- package/dist/reliability/cron-semantic.d.ts.map +1 -0
- package/dist/reliability/cron-semantic.js +208 -0
- package/dist/reliability/cron-semantic.js.map +1 -0
- package/dist/reliability/environment-doctor.d.ts +56 -0
- package/dist/reliability/environment-doctor.d.ts.map +1 -0
- package/dist/reliability/environment-doctor.js +213 -0
- package/dist/reliability/environment-doctor.js.map +1 -0
- package/dist/reliability/job-registry.d.ts +26 -0
- package/dist/reliability/job-registry.d.ts.map +1 -0
- package/dist/reliability/job-registry.js +77 -0
- package/dist/reliability/job-registry.js.map +1 -0
- package/dist/reliability/opencode-probe.d.ts +37 -0
- package/dist/reliability/opencode-probe.d.ts.map +1 -0
- package/dist/reliability/opencode-probe.js +195 -0
- package/dist/reliability/opencode-probe.js.map +1 -0
- package/dist/reliability/opencode-restart.d.ts +42 -0
- package/dist/reliability/opencode-restart.d.ts.map +1 -0
- package/dist/reliability/opencode-restart.js +155 -0
- package/dist/reliability/opencode-restart.js.map +1 -0
- package/dist/reliability/proactive-heartbeat.d.ts +39 -0
- package/dist/reliability/proactive-heartbeat.d.ts.map +1 -0
- package/dist/reliability/proactive-heartbeat.js +147 -0
- package/dist/reliability/proactive-heartbeat.js.map +1 -0
- package/dist/reliability/process-check-job.d.ts +73 -0
- package/dist/reliability/process-check-job.d.ts.map +1 -0
- package/dist/reliability/process-check-job.js +254 -0
- package/dist/reliability/process-check-job.js.map +1 -0
- package/dist/reliability/process-guard.d.ts +53 -0
- package/dist/reliability/process-guard.d.ts.map +1 -0
- package/dist/reliability/process-guard.js +344 -0
- package/dist/reliability/process-guard.js.map +1 -0
- package/dist/reliability/recovery-reporter.d.ts +37 -0
- package/dist/reliability/recovery-reporter.d.ts.map +1 -0
- package/dist/reliability/recovery-reporter.js +161 -0
- package/dist/reliability/recovery-reporter.js.map +1 -0
- package/dist/reliability/rescue-executor.d.ts +52 -0
- package/dist/reliability/rescue-executor.d.ts.map +1 -0
- package/dist/reliability/rescue-executor.js +244 -0
- package/dist/reliability/rescue-executor.js.map +1 -0
- package/dist/reliability/rescue-policy.d.ts +39 -0
- package/dist/reliability/rescue-policy.d.ts.map +1 -0
- package/dist/reliability/rescue-policy.js +85 -0
- package/dist/reliability/rescue-policy.js.map +1 -0
- package/dist/reliability/runtime-cron-dispatcher.d.ts +30 -0
- package/dist/reliability/runtime-cron-dispatcher.d.ts.map +1 -0
- package/dist/reliability/runtime-cron-dispatcher.js +100 -0
- package/dist/reliability/runtime-cron-dispatcher.js.map +1 -0
- package/dist/reliability/runtime-cron-orphan.d.ts +18 -0
- package/dist/reliability/runtime-cron-orphan.d.ts.map +1 -0
- package/dist/reliability/runtime-cron-orphan.js +87 -0
- package/dist/reliability/runtime-cron-orphan.js.map +1 -0
- package/dist/reliability/runtime-cron-registry.d.ts +4 -0
- package/dist/reliability/runtime-cron-registry.d.ts.map +1 -0
- package/dist/reliability/runtime-cron-registry.js +8 -0
- package/dist/reliability/runtime-cron-registry.js.map +1 -0
- package/dist/reliability/runtime-cron.d.ts +75 -0
- package/dist/reliability/runtime-cron.d.ts.map +1 -0
- package/dist/reliability/runtime-cron.js +309 -0
- package/dist/reliability/runtime-cron.js.map +1 -0
- package/dist/reliability/scheduler.d.ts +38 -0
- package/dist/reliability/scheduler.d.ts.map +1 -0
- package/dist/reliability/scheduler.js +174 -0
- package/dist/reliability/scheduler.js.map +1 -0
- package/dist/reliability/types.d.ts +151 -0
- package/dist/reliability/types.d.ts.map +1 -0
- package/dist/reliability/types.js +178 -0
- package/dist/reliability/types.js.map +1 -0
- package/dist/router/action-handlers.d.ts +27 -0
- package/dist/router/action-handlers.d.ts.map +1 -0
- package/dist/router/action-handlers.js +226 -0
- package/dist/router/action-handlers.js.map +1 -0
- package/dist/router/opencode-event-hub.d.ts +159 -0
- package/dist/router/opencode-event-hub.d.ts.map +1 -0
- package/dist/router/opencode-event-hub.js +589 -0
- package/dist/router/opencode-event-hub.js.map +1 -0
- package/dist/router/root-router.d.ts +94 -0
- package/dist/router/root-router.d.ts.map +1 -0
- package/dist/router/root-router.js +214 -0
- package/dist/router/root-router.js.map +1 -0
- package/dist/store/chat-session.d.ts +150 -0
- package/dist/store/chat-session.d.ts.map +1 -0
- package/dist/store/chat-session.js +640 -0
- package/dist/store/chat-session.js.map +1 -0
- package/dist/store/session-directory.d.ts +12 -0
- package/dist/store/session-directory.d.ts.map +1 -0
- package/dist/store/session-directory.js +47 -0
- package/dist/store/session-directory.js.map +1 -0
- package/dist/store/session-group.d.ts +19 -0
- package/dist/store/session-group.d.ts.map +1 -0
- package/dist/store/session-group.js +92 -0
- package/dist/store/session-group.js.map +1 -0
- package/dist/store/user-session.d.ts +19 -0
- package/dist/store/user-session.d.ts.map +1 -0
- package/dist/store/user-session.js +112 -0
- package/dist/store/user-session.js.map +1 -0
- package/dist/utils/async-queue.d.ts +12 -0
- package/dist/utils/async-queue.d.ts.map +1 -0
- package/dist/utils/async-queue.js +51 -0
- package/dist/utils/async-queue.js.map +1 -0
- package/dist/utils/directory-policy.d.ts +50 -0
- package/dist/utils/directory-policy.d.ts.map +1 -0
- package/dist/utils/directory-policy.js +379 -0
- package/dist/utils/directory-policy.js.map +1 -0
- package/dist/utils/session-title.d.ts +2 -0
- package/dist/utils/session-title.d.ts.map +1 -0
- package/dist/utils/session-title.js +10 -0
- package/dist/utils/session-title.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 故障分类与救援状态机类型定义
|
|
3
|
+
*
|
|
4
|
+
* 本模块定义桥接服务可靠性相关的故障分类体系和救援状态机。
|
|
5
|
+
* 用于统一故障检测、状态管理和恢复策略。
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 故障类型分类
|
|
9
|
+
*
|
|
10
|
+
* 按故障来源和性质分为:
|
|
11
|
+
* - 桥接启动故障 (bridge_boot_failed): 桥接服务自身启动失败
|
|
12
|
+
* - 桥接陈旧故障 (bridge_stale): 桥接会话/状态过期
|
|
13
|
+
* - OpenCode TCP 连接故障 (opencode_tcp_down): TCP 层连接超时/拒绝
|
|
14
|
+
* - OpenCode HTTP 服务故障 (opencode_http_down): HTTP 层响应异常
|
|
15
|
+
* - OpenCode 认证故障 (opencode_auth_invalid): 401/403 认证失败
|
|
16
|
+
* - 事件流陈旧故障 (event_stream_stale): SSE 事件流停滞
|
|
17
|
+
*/
|
|
18
|
+
export declare enum FailureType {
|
|
19
|
+
/** 桥接启动失败 - 端口占用/配置错误等 */
|
|
20
|
+
BRIDGE_BOOT_FAILED = "bridge_boot_failed",
|
|
21
|
+
/** 桥接状态陈旧 - 会话映射过期/缓存失效 */
|
|
22
|
+
BRIDGE_STALE = "bridge_stale",
|
|
23
|
+
/** OpenCode TCP 连接故障 - 连接超时/拒绝/重置 */
|
|
24
|
+
OPENCODE_TCP_DOWN = "opencode_tcp_down",
|
|
25
|
+
/** OpenCode HTTP 服务故障 - HTTP 响应超时/5xx 错误 */
|
|
26
|
+
OPENCODE_HTTP_DOWN = "opencode_http_down",
|
|
27
|
+
/** OpenCode 认证失败 - 401/403 认证无效 */
|
|
28
|
+
OPENCODE_AUTH_INVALID = "opencode_auth_invalid",
|
|
29
|
+
/** 事件流陈旧 - SSE 连接停滞/心跳丢失 */
|
|
30
|
+
EVENT_STREAM_STALE = "event_stream_stale"
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 救援状态机状态
|
|
34
|
+
*
|
|
35
|
+
* 状态跃迁规则:
|
|
36
|
+
* - healthy -> suspect: 检测到潜在故障
|
|
37
|
+
* - suspect -> healthy: 故障消失/自愈
|
|
38
|
+
* - suspect -> degraded: 故障确认
|
|
39
|
+
* - degraded -> repairing: 启动自动修复
|
|
40
|
+
* - degraded -> manual_required: 需要人工介入
|
|
41
|
+
* - repairing -> recovered: 修复成功
|
|
42
|
+
* - repairing -> degraded: 修复失败回退
|
|
43
|
+
* - repairing -> manual_required: 修复失败需人工
|
|
44
|
+
* - recovered -> healthy: 观察期结束后恢复正常
|
|
45
|
+
* - manual_required -> healthy: 人工处理后恢复
|
|
46
|
+
*/
|
|
47
|
+
export declare enum RescueState {
|
|
48
|
+
/** 健康状态 - 所有系统正常 */
|
|
49
|
+
HEALTHY = "healthy",
|
|
50
|
+
/** 可疑状态 - 检测到潜在异常待确认 */
|
|
51
|
+
SUSPECT = "suspect",
|
|
52
|
+
/** 降级状态 - 故障确认但服务仍可用 */
|
|
53
|
+
DEGRADED = "degraded",
|
|
54
|
+
/** 修复中状态 - 正在执行自动恢复流程 */
|
|
55
|
+
REPAIRING = "repairing",
|
|
56
|
+
/** 已恢复状态 - 修复完成待观察确认 */
|
|
57
|
+
RECOVERED = "recovered",
|
|
58
|
+
/** 需人工介入 - 自动修复失败需人工处理 */
|
|
59
|
+
MANUAL_REQUIRED = "manual_required"
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 状态跃迁规则定义
|
|
63
|
+
*
|
|
64
|
+
* 禁止的跃迁:
|
|
65
|
+
* - healthy -> repairing: 健康状态不能直接跳修复
|
|
66
|
+
* - healthy -> recovered: 健康状态不能直接跳已恢复
|
|
67
|
+
* - healthy -> manual_required: 健康状态不能直接跳人工
|
|
68
|
+
* - suspect -> repairing: 可疑状态需先确认故障
|
|
69
|
+
* - suspect -> recovered: 可疑状态不能直接跳已恢复
|
|
70
|
+
* - degraded -> healthy: 降级状态需经过修复流程
|
|
71
|
+
* - repairing -> healthy: 修复中需先确认恢复再观察
|
|
72
|
+
* - manual_required -> 任意状态 (除 healthy): 人工介入后必须观察
|
|
73
|
+
*/
|
|
74
|
+
export declare const VALID_STATE_TRANSITIONS: Record<RescueState, RescueState[]>;
|
|
75
|
+
/**
|
|
76
|
+
* 故障到初始救援状态的映射
|
|
77
|
+
*
|
|
78
|
+
* 不同故障类型触发不同的初始响应策略
|
|
79
|
+
*/
|
|
80
|
+
export declare const FAILURE_TO_INITIAL_STATE: Record<FailureType, RescueState>;
|
|
81
|
+
/**
|
|
82
|
+
* 验证状态跃迁是否合法
|
|
83
|
+
*
|
|
84
|
+
* @param from 当前状态
|
|
85
|
+
* @param to 目标状态
|
|
86
|
+
* @returns 是否允许跃迁
|
|
87
|
+
*/
|
|
88
|
+
export declare function isValidStateTransition(from: RescueState, to: RescueState): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* 状态跃迁验证器类
|
|
91
|
+
*
|
|
92
|
+
* 提供带错误信息的跃迁验证
|
|
93
|
+
*/
|
|
94
|
+
export declare class StateTransitionValidator {
|
|
95
|
+
private currentState;
|
|
96
|
+
constructor(initialState?: RescueState);
|
|
97
|
+
/**
|
|
98
|
+
* 尝试执行状态跃迁
|
|
99
|
+
*
|
|
100
|
+
* @param nextState 目标状态
|
|
101
|
+
* @returns 是否成功
|
|
102
|
+
* @throws 当跃迁非法时抛出错误
|
|
103
|
+
*/
|
|
104
|
+
transitionTo(nextState: RescueState): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* 检查跃迁是否合法(不执行实际跃迁)
|
|
107
|
+
*
|
|
108
|
+
* @param nextState 目标状态
|
|
109
|
+
* @returns 是否允许
|
|
110
|
+
*/
|
|
111
|
+
canTransitionTo(nextState: RescueState): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* 获取当前状态
|
|
114
|
+
*/
|
|
115
|
+
getState(): RescueState;
|
|
116
|
+
/**
|
|
117
|
+
* 重置状态
|
|
118
|
+
*/
|
|
119
|
+
reset(initialState?: RescueState): void;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 故障事件接口
|
|
123
|
+
*
|
|
124
|
+
* 用于在系统内部传递故障信息
|
|
125
|
+
*/
|
|
126
|
+
export interface FailureEvent {
|
|
127
|
+
/** 故障类型 */
|
|
128
|
+
type: FailureType;
|
|
129
|
+
/** 故障发生时间戳 */
|
|
130
|
+
timestamp: number;
|
|
131
|
+
/** 故障详细描述 */
|
|
132
|
+
message: string;
|
|
133
|
+
/** 相关错误对象(可选) */
|
|
134
|
+
error?: Error;
|
|
135
|
+
/** 附加上下文信息 */
|
|
136
|
+
context?: Record<string, unknown>;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 救援状态变更事件接口
|
|
140
|
+
*/
|
|
141
|
+
export interface StateChangeEvent {
|
|
142
|
+
/** 变更前状态 */
|
|
143
|
+
from: RescueState;
|
|
144
|
+
/** 变更后状态 */
|
|
145
|
+
to: RescueState;
|
|
146
|
+
/** 变更原因 */
|
|
147
|
+
reason: string;
|
|
148
|
+
/** 变更时间戳 */
|
|
149
|
+
timestamp: number;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/reliability/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;GAUG;AACH,oBAAY,WAAW;IACrB,0BAA0B;IAC1B,kBAAkB,uBAAuB;IAEzC,2BAA2B;IAC3B,YAAY,iBAAiB;IAE7B,qCAAqC;IACrC,iBAAiB,sBAAsB;IAEvC,4CAA4C;IAC5C,kBAAkB,uBAAuB;IAEzC,mCAAmC;IACnC,qBAAqB,0BAA0B;IAE/C,4BAA4B;IAC5B,kBAAkB,uBAAuB;CAC1C;AAED;;;;;;;;;;;;;;GAcG;AACH,oBAAY,WAAW;IACrB,oBAAoB;IACpB,OAAO,YAAY;IAEnB,wBAAwB;IACxB,OAAO,YAAY;IAEnB,wBAAwB;IACxB,QAAQ,aAAa;IAErB,yBAAyB;IACzB,SAAS,cAAc;IAEvB,wBAAwB;IACxB,SAAS,cAAc;IAEvB,0BAA0B;IAC1B,eAAe,oBAAoB;CACpC;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,CAwBtE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,WAAW,EAAE,WAAW,CAOrE,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,GAAG,OAAO,CAMlF;AAED;;;;GAIG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,YAAY,CAAc;gBAEtB,YAAY,GAAE,WAAiC;IAO3D;;;;;;OAMG;IACH,YAAY,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO;IAW7C;;;;;OAKG;IACH,eAAe,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO;IAIhD;;OAEG;IACH,QAAQ,IAAI,WAAW;IAIvB;;OAEG;IACH,KAAK,CAAC,YAAY,GAAE,WAAiC,GAAG,IAAI;CAG7D;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,cAAc;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,cAAc;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY;IACZ,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY;IACZ,EAAE,EAAE,WAAW,CAAC;IAChB,WAAW;IACX,MAAM,EAAE,MAAM,CAAC;IACf,YAAY;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 故障分类与救援状态机类型定义
|
|
3
|
+
*
|
|
4
|
+
* 本模块定义桥接服务可靠性相关的故障分类体系和救援状态机。
|
|
5
|
+
* 用于统一故障检测、状态管理和恢复策略。
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 故障类型分类
|
|
9
|
+
*
|
|
10
|
+
* 按故障来源和性质分为:
|
|
11
|
+
* - 桥接启动故障 (bridge_boot_failed): 桥接服务自身启动失败
|
|
12
|
+
* - 桥接陈旧故障 (bridge_stale): 桥接会话/状态过期
|
|
13
|
+
* - OpenCode TCP 连接故障 (opencode_tcp_down): TCP 层连接超时/拒绝
|
|
14
|
+
* - OpenCode HTTP 服务故障 (opencode_http_down): HTTP 层响应异常
|
|
15
|
+
* - OpenCode 认证故障 (opencode_auth_invalid): 401/403 认证失败
|
|
16
|
+
* - 事件流陈旧故障 (event_stream_stale): SSE 事件流停滞
|
|
17
|
+
*/
|
|
18
|
+
export var FailureType;
|
|
19
|
+
(function (FailureType) {
|
|
20
|
+
/** 桥接启动失败 - 端口占用/配置错误等 */
|
|
21
|
+
FailureType["BRIDGE_BOOT_FAILED"] = "bridge_boot_failed";
|
|
22
|
+
/** 桥接状态陈旧 - 会话映射过期/缓存失效 */
|
|
23
|
+
FailureType["BRIDGE_STALE"] = "bridge_stale";
|
|
24
|
+
/** OpenCode TCP 连接故障 - 连接超时/拒绝/重置 */
|
|
25
|
+
FailureType["OPENCODE_TCP_DOWN"] = "opencode_tcp_down";
|
|
26
|
+
/** OpenCode HTTP 服务故障 - HTTP 响应超时/5xx 错误 */
|
|
27
|
+
FailureType["OPENCODE_HTTP_DOWN"] = "opencode_http_down";
|
|
28
|
+
/** OpenCode 认证失败 - 401/403 认证无效 */
|
|
29
|
+
FailureType["OPENCODE_AUTH_INVALID"] = "opencode_auth_invalid";
|
|
30
|
+
/** 事件流陈旧 - SSE 连接停滞/心跳丢失 */
|
|
31
|
+
FailureType["EVENT_STREAM_STALE"] = "event_stream_stale";
|
|
32
|
+
})(FailureType || (FailureType = {}));
|
|
33
|
+
/**
|
|
34
|
+
* 救援状态机状态
|
|
35
|
+
*
|
|
36
|
+
* 状态跃迁规则:
|
|
37
|
+
* - healthy -> suspect: 检测到潜在故障
|
|
38
|
+
* - suspect -> healthy: 故障消失/自愈
|
|
39
|
+
* - suspect -> degraded: 故障确认
|
|
40
|
+
* - degraded -> repairing: 启动自动修复
|
|
41
|
+
* - degraded -> manual_required: 需要人工介入
|
|
42
|
+
* - repairing -> recovered: 修复成功
|
|
43
|
+
* - repairing -> degraded: 修复失败回退
|
|
44
|
+
* - repairing -> manual_required: 修复失败需人工
|
|
45
|
+
* - recovered -> healthy: 观察期结束后恢复正常
|
|
46
|
+
* - manual_required -> healthy: 人工处理后恢复
|
|
47
|
+
*/
|
|
48
|
+
export var RescueState;
|
|
49
|
+
(function (RescueState) {
|
|
50
|
+
/** 健康状态 - 所有系统正常 */
|
|
51
|
+
RescueState["HEALTHY"] = "healthy";
|
|
52
|
+
/** 可疑状态 - 检测到潜在异常待确认 */
|
|
53
|
+
RescueState["SUSPECT"] = "suspect";
|
|
54
|
+
/** 降级状态 - 故障确认但服务仍可用 */
|
|
55
|
+
RescueState["DEGRADED"] = "degraded";
|
|
56
|
+
/** 修复中状态 - 正在执行自动恢复流程 */
|
|
57
|
+
RescueState["REPAIRING"] = "repairing";
|
|
58
|
+
/** 已恢复状态 - 修复完成待观察确认 */
|
|
59
|
+
RescueState["RECOVERED"] = "recovered";
|
|
60
|
+
/** 需人工介入 - 自动修复失败需人工处理 */
|
|
61
|
+
RescueState["MANUAL_REQUIRED"] = "manual_required";
|
|
62
|
+
})(RescueState || (RescueState = {}));
|
|
63
|
+
/**
|
|
64
|
+
* 状态跃迁规则定义
|
|
65
|
+
*
|
|
66
|
+
* 禁止的跃迁:
|
|
67
|
+
* - healthy -> repairing: 健康状态不能直接跳修复
|
|
68
|
+
* - healthy -> recovered: 健康状态不能直接跳已恢复
|
|
69
|
+
* - healthy -> manual_required: 健康状态不能直接跳人工
|
|
70
|
+
* - suspect -> repairing: 可疑状态需先确认故障
|
|
71
|
+
* - suspect -> recovered: 可疑状态不能直接跳已恢复
|
|
72
|
+
* - degraded -> healthy: 降级状态需经过修复流程
|
|
73
|
+
* - repairing -> healthy: 修复中需先确认恢复再观察
|
|
74
|
+
* - manual_required -> 任意状态 (除 healthy): 人工介入后必须观察
|
|
75
|
+
*/
|
|
76
|
+
export const VALID_STATE_TRANSITIONS = {
|
|
77
|
+
[RescueState.HEALTHY]: [
|
|
78
|
+
RescueState.SUSPECT
|
|
79
|
+
],
|
|
80
|
+
[RescueState.SUSPECT]: [
|
|
81
|
+
RescueState.HEALTHY,
|
|
82
|
+
RescueState.DEGRADED
|
|
83
|
+
],
|
|
84
|
+
[RescueState.DEGRADED]: [
|
|
85
|
+
RescueState.REPAIRING,
|
|
86
|
+
RescueState.MANUAL_REQUIRED
|
|
87
|
+
],
|
|
88
|
+
[RescueState.REPAIRING]: [
|
|
89
|
+
RescueState.RECOVERED,
|
|
90
|
+
RescueState.DEGRADED,
|
|
91
|
+
RescueState.MANUAL_REQUIRED
|
|
92
|
+
],
|
|
93
|
+
[RescueState.RECOVERED]: [
|
|
94
|
+
RescueState.HEALTHY,
|
|
95
|
+
RescueState.SUSPECT
|
|
96
|
+
],
|
|
97
|
+
[RescueState.MANUAL_REQUIRED]: [
|
|
98
|
+
RescueState.HEALTHY
|
|
99
|
+
]
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* 故障到初始救援状态的映射
|
|
103
|
+
*
|
|
104
|
+
* 不同故障类型触发不同的初始响应策略
|
|
105
|
+
*/
|
|
106
|
+
export const FAILURE_TO_INITIAL_STATE = {
|
|
107
|
+
[FailureType.BRIDGE_BOOT_FAILED]: RescueState.MANUAL_REQUIRED,
|
|
108
|
+
[FailureType.BRIDGE_STALE]: RescueState.SUSPECT,
|
|
109
|
+
[FailureType.OPENCODE_TCP_DOWN]: RescueState.SUSPECT,
|
|
110
|
+
[FailureType.OPENCODE_HTTP_DOWN]: RescueState.SUSPECT,
|
|
111
|
+
[FailureType.OPENCODE_AUTH_INVALID]: RescueState.DEGRADED,
|
|
112
|
+
[FailureType.EVENT_STREAM_STALE]: RescueState.SUSPECT
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* 验证状态跃迁是否合法
|
|
116
|
+
*
|
|
117
|
+
* @param from 当前状态
|
|
118
|
+
* @param to 目标状态
|
|
119
|
+
* @returns 是否允许跃迁
|
|
120
|
+
*/
|
|
121
|
+
export function isValidStateTransition(from, to) {
|
|
122
|
+
const validTargets = VALID_STATE_TRANSITIONS[from];
|
|
123
|
+
if (!validTargets) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return validTargets.includes(to);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 状态跃迁验证器类
|
|
130
|
+
*
|
|
131
|
+
* 提供带错误信息的跃迁验证
|
|
132
|
+
*/
|
|
133
|
+
export class StateTransitionValidator {
|
|
134
|
+
currentState;
|
|
135
|
+
constructor(initialState = RescueState.HEALTHY) {
|
|
136
|
+
if (!Object.values(RescueState).includes(initialState)) {
|
|
137
|
+
throw new Error(`无效的初始状态:${initialState}`);
|
|
138
|
+
}
|
|
139
|
+
this.currentState = initialState;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 尝试执行状态跃迁
|
|
143
|
+
*
|
|
144
|
+
* @param nextState 目标状态
|
|
145
|
+
* @returns 是否成功
|
|
146
|
+
* @throws 当跃迁非法时抛出错误
|
|
147
|
+
*/
|
|
148
|
+
transitionTo(nextState) {
|
|
149
|
+
if (!isValidStateTransition(this.currentState, nextState)) {
|
|
150
|
+
throw new Error(`非法的状态跃迁:${this.currentState} -> ${nextState}。` +
|
|
151
|
+
`允许的跃迁:${VALID_STATE_TRANSITIONS[this.currentState].join(', ') || '无'}`);
|
|
152
|
+
}
|
|
153
|
+
this.currentState = nextState;
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* 检查跃迁是否合法(不执行实际跃迁)
|
|
158
|
+
*
|
|
159
|
+
* @param nextState 目标状态
|
|
160
|
+
* @returns 是否允许
|
|
161
|
+
*/
|
|
162
|
+
canTransitionTo(nextState) {
|
|
163
|
+
return isValidStateTransition(this.currentState, nextState);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 获取当前状态
|
|
167
|
+
*/
|
|
168
|
+
getState() {
|
|
169
|
+
return this.currentState;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 重置状态
|
|
173
|
+
*/
|
|
174
|
+
reset(initialState = RescueState.HEALTHY) {
|
|
175
|
+
this.currentState = initialState;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/reliability/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 路由器动作处理器
|
|
3
|
+
*
|
|
4
|
+
* 从 index.ts 抽取的权限和问题处理逻辑,
|
|
5
|
+
* 通过依赖注入方式提供给 RootRouter。
|
|
6
|
+
*/
|
|
7
|
+
import type { FeishuCardActionEvent } from '../feishu/client.js';
|
|
8
|
+
import type { FeishuMessageEvent } from '../feishu/client.js';
|
|
9
|
+
import type { CardActionResponse } from './root-router.js';
|
|
10
|
+
/**
|
|
11
|
+
* Timeline 回调类型
|
|
12
|
+
*/
|
|
13
|
+
export type UpsertTimelineNote = (bufferKey: string, noteKey: string, text: string, variant?: 'retry' | 'compaction' | 'question' | 'error' | 'permission') => void;
|
|
14
|
+
/**
|
|
15
|
+
* 创建权限动作处理器
|
|
16
|
+
*/
|
|
17
|
+
export declare function createPermissionActionCallbacks(upsertTimelineNote: UpsertTimelineNote): {
|
|
18
|
+
handlePermissionAction: (actionValue: Record<string, unknown>, action: 'permission_allow' | 'permission_deny') => Promise<CardActionResponse>;
|
|
19
|
+
tryHandlePendingPermissionByText: (event: FeishuMessageEvent) => Promise<boolean>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* 创建问题动作处理器
|
|
23
|
+
*/
|
|
24
|
+
export declare function createQuestionActionCallbacks(): {
|
|
25
|
+
handleQuestionSkipAction: (event: FeishuCardActionEvent, actionValue: Record<string, unknown>) => Promise<CardActionResponse>;
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=action-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-handlers.d.ts","sourceRoot":"","sources":["../../src/router/action-handlers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAQ3D;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,YAAY,KACnE,IAAI,CAAC;AAiEV;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,kBAAkB,EAAE,kBAAkB,GACrC;IACD,sBAAsB,EAAE,CACtB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,MAAM,EAAE,kBAAkB,GAAG,iBAAiB,KAC3C,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,gCAAgC,EAAE,CAChC,KAAK,EAAE,kBAAkB,KACtB,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB,CAuLA;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI;IAC/C,wBAAwB,EAAE,CACxB,KAAK,EAAE,qBAAqB,EAC5B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACjC,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAClC,CAyCA"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 路由器动作处理器
|
|
3
|
+
*
|
|
4
|
+
* 从 index.ts 抽取的权限和问题处理逻辑,
|
|
5
|
+
* 通过依赖注入方式提供给 RootRouter。
|
|
6
|
+
*/
|
|
7
|
+
import { chatSessionStore } from '../store/chat-session.js';
|
|
8
|
+
import { permissionHandler } from '../permissions/handler.js';
|
|
9
|
+
import { opencodeClient } from '../opencode/client.js';
|
|
10
|
+
import { outputBuffer } from '../opencode/output-buffer.js';
|
|
11
|
+
import { feishuClient } from '../feishu/client.js';
|
|
12
|
+
import { groupHandler } from '../handlers/group.js';
|
|
13
|
+
// 辅助函数
|
|
14
|
+
const toTrimmedString = (value) => {
|
|
15
|
+
if (typeof value !== 'string')
|
|
16
|
+
return undefined;
|
|
17
|
+
const trimmed = value.trim();
|
|
18
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
19
|
+
};
|
|
20
|
+
const toInteger = (value) => {
|
|
21
|
+
if (typeof value === 'number' && Number.isInteger(value))
|
|
22
|
+
return value;
|
|
23
|
+
if (typeof value === 'string' && value.trim().length > 0) {
|
|
24
|
+
const parsed = Number(value);
|
|
25
|
+
return Number.isInteger(parsed) ? parsed : undefined;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
};
|
|
29
|
+
const parsePermissionDecision = (raw) => {
|
|
30
|
+
const normalized = raw.normalize('NFKC').trim().toLowerCase();
|
|
31
|
+
if (!normalized)
|
|
32
|
+
return null;
|
|
33
|
+
const compact = normalized
|
|
34
|
+
.replace(/[\s\u3000]+/g, '')
|
|
35
|
+
.replace(/[。!!,.,;;::\-]/g, '');
|
|
36
|
+
const hasAlways = compact.includes('始终') ||
|
|
37
|
+
compact.includes('永久') ||
|
|
38
|
+
compact.includes('always') ||
|
|
39
|
+
compact.includes('记住') ||
|
|
40
|
+
compact.includes('总是');
|
|
41
|
+
const containsAny = (words) => {
|
|
42
|
+
return words.some(word => compact === word || compact.includes(word));
|
|
43
|
+
};
|
|
44
|
+
const isDeny = compact === 'n' ||
|
|
45
|
+
compact === 'no' ||
|
|
46
|
+
compact === '否' ||
|
|
47
|
+
compact === '拒绝' ||
|
|
48
|
+
containsAny(['拒绝', '不同意', '不允许', 'deny']);
|
|
49
|
+
if (isDeny) {
|
|
50
|
+
return { allow: false, remember: false };
|
|
51
|
+
}
|
|
52
|
+
const isAllow = compact === 'y' ||
|
|
53
|
+
compact === 'yes' ||
|
|
54
|
+
compact === 'ok' ||
|
|
55
|
+
compact === 'always' ||
|
|
56
|
+
compact === '允许' ||
|
|
57
|
+
compact === '始终允许' ||
|
|
58
|
+
containsAny(['允许', '同意', '通过', '批准', 'allow']);
|
|
59
|
+
if (isAllow) {
|
|
60
|
+
return { allow: true, remember: hasAlways };
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* 创建权限动作处理器
|
|
66
|
+
*/
|
|
67
|
+
export function createPermissionActionCallbacks(upsertTimelineNote) {
|
|
68
|
+
const resolvePermissionDirectoryOptions = (sessionId, chatIdHint) => {
|
|
69
|
+
const conversation = chatSessionStore.getConversationBySessionId(sessionId);
|
|
70
|
+
const boundSession = conversation
|
|
71
|
+
? chatSessionStore.getSessionByConversation(conversation.platform, conversation.conversationId)
|
|
72
|
+
: undefined;
|
|
73
|
+
const queueHintSession = chatIdHint
|
|
74
|
+
? chatSessionStore.getSession(chatIdHint)
|
|
75
|
+
: undefined;
|
|
76
|
+
const directory = boundSession?.resolvedDirectory
|
|
77
|
+
|| queueHintSession?.resolvedDirectory
|
|
78
|
+
|| boundSession?.defaultDirectory
|
|
79
|
+
|| queueHintSession?.defaultDirectory;
|
|
80
|
+
const fallbackDirectories = Array.from(new Set([
|
|
81
|
+
boundSession?.resolvedDirectory,
|
|
82
|
+
boundSession?.defaultDirectory,
|
|
83
|
+
queueHintSession?.resolvedDirectory,
|
|
84
|
+
queueHintSession?.defaultDirectory,
|
|
85
|
+
...chatSessionStore.getKnownDirectories(),
|
|
86
|
+
].filter((value) => typeof value === 'string' && value.trim().length > 0)));
|
|
87
|
+
return {
|
|
88
|
+
...(directory ? { directory } : {}),
|
|
89
|
+
...(fallbackDirectories.length > 0 ? { fallbackDirectories } : {}),
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
const handlePermissionAction = async (actionValue, action) => {
|
|
93
|
+
const sessionId = toTrimmedString(actionValue.sessionId);
|
|
94
|
+
const permissionId = toTrimmedString(actionValue.permissionId);
|
|
95
|
+
if (!sessionId || !permissionId) {
|
|
96
|
+
return {
|
|
97
|
+
toast: {
|
|
98
|
+
type: 'error',
|
|
99
|
+
content: '权限参数缺失',
|
|
100
|
+
i18n_content: { zh_cn: '权限参数缺失', en_us: 'Missing permission params' },
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const allow = action === 'permission_allow';
|
|
105
|
+
const rememberRaw = typeof actionValue.remember === 'string'
|
|
106
|
+
? actionValue.remember.normalize('NFKC').trim().toLowerCase()
|
|
107
|
+
: actionValue.remember;
|
|
108
|
+
const remember = rememberRaw === true ||
|
|
109
|
+
rememberRaw === 1 ||
|
|
110
|
+
rememberRaw === '1' ||
|
|
111
|
+
rememberRaw === 'true' ||
|
|
112
|
+
rememberRaw === 'always' ||
|
|
113
|
+
rememberRaw === '始终允许';
|
|
114
|
+
const permissionDirectoryOptions = resolvePermissionDirectoryOptions(sessionId);
|
|
115
|
+
const responded = await opencodeClient.respondToPermission(sessionId, permissionId, allow, remember, permissionDirectoryOptions);
|
|
116
|
+
if (!responded) {
|
|
117
|
+
console.error(`[权限] 响应失败: session=${sessionId}, permission=${permissionId}`);
|
|
118
|
+
return {
|
|
119
|
+
toast: {
|
|
120
|
+
type: 'error',
|
|
121
|
+
content: '权限响应失败',
|
|
122
|
+
i18n_content: { zh_cn: '权限响应失败', en_us: 'Permission response failed' },
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
console.log(`[权限] 卡片响应成功: session=${sessionId}, permission=${permissionId}, allow=${allow}, remember=${remember}`);
|
|
127
|
+
const permissionChatId = chatSessionStore.getChatId(sessionId);
|
|
128
|
+
if (permissionChatId) {
|
|
129
|
+
const bufferKey = `chat:${permissionChatId}`;
|
|
130
|
+
const removed = permissionHandler.resolveForChat(permissionChatId, permissionId);
|
|
131
|
+
if (removed) {
|
|
132
|
+
const resolvedText = allow
|
|
133
|
+
? remember ? `✅ 已允许并记住权限:${removed.tool}` : `✅ 已允许权限:${removed.tool}`
|
|
134
|
+
: `❌ 已拒绝权限:${removed.tool}`;
|
|
135
|
+
upsertTimelineNote(bufferKey, `permission-result:${sessionId}:${permissionId}:${allow ? 'allow' : 'deny'}:${remember ? 'always' : 'once'}`, resolvedText, 'permission');
|
|
136
|
+
}
|
|
137
|
+
outputBuffer.touch(bufferKey);
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
toast: {
|
|
141
|
+
type: allow ? 'success' : 'error',
|
|
142
|
+
content: allow ? '已允许' : '已拒绝',
|
|
143
|
+
i18n_content: { zh_cn: allow ? '已允许' : '已拒绝', en_us: allow ? 'Allowed' : 'Denied' },
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
const tryHandlePendingPermissionByText = async (event) => {
|
|
148
|
+
if (event.chatType !== 'group')
|
|
149
|
+
return false;
|
|
150
|
+
const trimmedContent = event.content.trim();
|
|
151
|
+
if (!trimmedContent || trimmedContent.startsWith('/'))
|
|
152
|
+
return false;
|
|
153
|
+
const pending = permissionHandler.peekForChat(event.chatId);
|
|
154
|
+
if (!pending)
|
|
155
|
+
return false;
|
|
156
|
+
const decision = parsePermissionDecision(trimmedContent);
|
|
157
|
+
if (!decision) {
|
|
158
|
+
await feishuClient.reply(event.messageId, '当前有待确认权限,请回复:允许 / 拒绝 / 始终允许(也支持 y / n / always)');
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
const permissionDirectoryOptions = resolvePermissionDirectoryOptions(pending.sessionId, event.chatId);
|
|
162
|
+
const responded = await opencodeClient.respondToPermission(pending.sessionId, pending.permissionId, decision.allow, decision.remember, permissionDirectoryOptions);
|
|
163
|
+
if (!responded) {
|
|
164
|
+
console.error(`[权限] 文本响应失败: chat=${event.chatId}`);
|
|
165
|
+
await feishuClient.reply(event.messageId, '权限响应失败,请重试');
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
console.log(`[权限] 文本响应成功: chat=${event.chatId}, session=${pending.sessionId}, permission=${pending.permissionId}, allow=${decision.allow}, remember=${decision.remember}`);
|
|
169
|
+
const removed = permissionHandler.resolveForChat(event.chatId, pending.permissionId);
|
|
170
|
+
const bufferKey = `chat:${event.chatId}`;
|
|
171
|
+
if (!outputBuffer.get(bufferKey)) {
|
|
172
|
+
outputBuffer.getOrCreate(bufferKey, event.chatId, pending.sessionId, event.messageId);
|
|
173
|
+
}
|
|
174
|
+
const toolName = removed?.tool || pending.tool || '工具';
|
|
175
|
+
const resolvedText = decision.allow
|
|
176
|
+
? decision.remember ? `✅ 已允许并记住权限:${toolName}` : `✅ 已允许权限:${toolName}`
|
|
177
|
+
: `❌ 已拒绝权限:${toolName}`;
|
|
178
|
+
upsertTimelineNote(bufferKey, `permission-result-text:${pending.sessionId}:${pending.permissionId}:${decision.allow ? 'allow' : 'deny'}:${decision.remember ? 'always' : 'once'}`, resolvedText, 'permission');
|
|
179
|
+
outputBuffer.touch(bufferKey);
|
|
180
|
+
await feishuClient.reply(event.messageId, decision.allow ? (decision.remember ? '已允许并记住该权限' : '已允许该权限') : '已拒绝该权限');
|
|
181
|
+
return true;
|
|
182
|
+
};
|
|
183
|
+
return {
|
|
184
|
+
handlePermissionAction,
|
|
185
|
+
tryHandlePendingPermissionByText,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 创建问题动作处理器
|
|
190
|
+
*/
|
|
191
|
+
export function createQuestionActionCallbacks() {
|
|
192
|
+
const handleQuestionSkipAction = async (event, actionValue) => {
|
|
193
|
+
const chatId = toTrimmedString(actionValue.chatId) || event.chatId;
|
|
194
|
+
const requestId = toTrimmedString(actionValue.requestId);
|
|
195
|
+
const questionIndex = toInteger(actionValue.questionIndex);
|
|
196
|
+
if (!chatId) {
|
|
197
|
+
return {
|
|
198
|
+
toast: {
|
|
199
|
+
type: 'error',
|
|
200
|
+
content: '无法定位会话',
|
|
201
|
+
i18n_content: { zh_cn: '无法定位会话', en_us: 'Failed to locate chat' },
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const result = await groupHandler.handleQuestionSkipAction({
|
|
206
|
+
chatId,
|
|
207
|
+
messageId: event.messageId,
|
|
208
|
+
requestId,
|
|
209
|
+
questionIndex,
|
|
210
|
+
});
|
|
211
|
+
if (result === 'applied') {
|
|
212
|
+
return { toast: { type: 'success', content: '已跳过本题', i18n_content: { zh_cn: '已跳过本题', en_us: 'Question skipped' } } };
|
|
213
|
+
}
|
|
214
|
+
if (result === 'stale_card') {
|
|
215
|
+
return { toast: { type: 'error', content: '请操作最新问题状态', i18n_content: { zh_cn: '请操作最新问题状态', en_us: 'Please use latest question state' } } };
|
|
216
|
+
}
|
|
217
|
+
if (result === 'not_found') {
|
|
218
|
+
return { toast: { type: 'error', content: '当前没有待回答问题', i18n_content: { zh_cn: '当前没有待回答问题', en_us: 'No pending question' } } };
|
|
219
|
+
}
|
|
220
|
+
return { toast: { type: 'error', content: '跳过失败,请重试', i18n_content: { zh_cn: '跳过失败,请重试', en_us: 'Skip failed, try again' } } };
|
|
221
|
+
};
|
|
222
|
+
return {
|
|
223
|
+
handleQuestionSkipAction,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=action-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-handlers.js","sourceRoot":"","sources":["../../src/router/action-handlers.ts"],"names":[],"mappings":"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"}
|