@ganglion/xacpx 0.13.0 → 0.14.1
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/README.md +79 -460
- package/dist/bridge/bridge-main.js +112 -5
- package/dist/cli.js +436 -101
- package/dist/commands/handlers/session-handler.d.ts +3 -9
- package/dist/commands/router-types.d.ts +2 -5
- package/dist/control/control-event-bus.d.ts +10 -0
- package/dist/control/control-service.d.ts +15 -0
- package/dist/control/upload-store.d.ts +28 -0
- package/dist/i18n/types.d.ts +1 -0
- package/dist/plugin-api.js +2 -0
- package/dist/transport/types.d.ts +37 -4
- package/dist/weixin/agent/interface.d.ts +4 -4
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CommandRouterContext, RouterResponse, SessionInteractionOps, SessionLifecycleOps, SessionRenderRecoveryOps } from "../router-types";
|
|
2
|
-
import type { PromptMediaInput, ResolvedSession } from "../../transport/types";
|
|
2
|
+
import type { AgentCommand, PromptMediaInput, PromptUsage, ResolvedSession } from "../../transport/types";
|
|
3
3
|
import type { PlanEntry, ToolUseEvent } from "../../channels/types.js";
|
|
4
4
|
import type { PerfSpan } from "../../perf/perf-tracer";
|
|
5
5
|
import type { HelpTopicMetadata } from "../help/help-types";
|
|
@@ -39,11 +39,5 @@ export declare function handleSessionReset(context: SessionHandlerContext, chatK
|
|
|
39
39
|
export declare function handleSessionTail(context: SessionHandlerContext, chatKey: string, lines?: number): Promise<RouterResponse>;
|
|
40
40
|
export declare function handleSessionRemove(context: SessionHandlerContext, chatKey: string, alias: string): Promise<RouterResponse>;
|
|
41
41
|
export declare function handleSessionArchive(context: SessionHandlerContext, chatKey: string, alias: string, archive: (internalAlias: string) => Promise<void>): Promise<RouterResponse>;
|
|
42
|
-
export declare function handlePromptWithSession(context: SessionHandlerContext, session: ResolvedSession, chatKey: string, text: string, reply?: (text: string) => Promise<void>, replyContextToken?: string, accountId?: string, media?: PromptMediaInput, abortSignal?: AbortSignal, onToolEvent?: (event: ToolUseEvent) => void | Promise<void>, onThought?: (chunk: string) => void | Promise<void>, perfSpan?: PerfSpan, metadata?: ChatRequestMetadata, onPlan?: (entries: PlanEntry[]) => void | Promise<void>, onUsage?: (usage:
|
|
43
|
-
|
|
44
|
-
size: number;
|
|
45
|
-
}) => void | Promise<void>): Promise<RouterResponse>;
|
|
46
|
-
export declare function handlePrompt(context: SessionHandlerContext, chatKey: string, text: string, reply?: (text: string) => Promise<void>, replyContextToken?: string, accountId?: string, media?: PromptMediaInput, abortSignal?: AbortSignal, onToolEvent?: (event: ToolUseEvent) => void | Promise<void>, onThought?: (chunk: string) => void | Promise<void>, perfSpan?: PerfSpan, metadata?: ChatRequestMetadata, onPlan?: (entries: PlanEntry[]) => void | Promise<void>, onUsage?: (usage: {
|
|
47
|
-
used: number;
|
|
48
|
-
size: number;
|
|
49
|
-
}) => void | Promise<void>): Promise<RouterResponse>;
|
|
42
|
+
export declare function handlePromptWithSession(context: SessionHandlerContext, session: ResolvedSession, chatKey: string, text: string, reply?: (text: string) => Promise<void>, replyContextToken?: string, accountId?: string, media?: PromptMediaInput, abortSignal?: AbortSignal, onToolEvent?: (event: ToolUseEvent) => void | Promise<void>, onThought?: (chunk: string) => void | Promise<void>, perfSpan?: PerfSpan, metadata?: ChatRequestMetadata, onPlan?: (entries: PlanEntry[]) => void | Promise<void>, onUsage?: (usage: PromptUsage) => void | Promise<void>, onCommands?: (commands: AgentCommand[]) => void | Promise<void>): Promise<RouterResponse>;
|
|
43
|
+
export declare function handlePrompt(context: SessionHandlerContext, chatKey: string, text: string, reply?: (text: string) => Promise<void>, replyContextToken?: string, accountId?: string, media?: PromptMediaInput, abortSignal?: AbortSignal, onToolEvent?: (event: ToolUseEvent) => void | Promise<void>, onThought?: (chunk: string) => void | Promise<void>, perfSpan?: PerfSpan, metadata?: ChatRequestMetadata, onPlan?: (entries: PlanEntry[]) => void | Promise<void>, onUsage?: (usage: PromptUsage) => void | Promise<void>, onCommands?: (commands: AgentCommand[]) => void | Promise<void>): Promise<RouterResponse>;
|
|
@@ -3,7 +3,7 @@ import type { AppConfig } from "../config/types";
|
|
|
3
3
|
import type { AppLogger } from "../logging/app-logger";
|
|
4
4
|
import type { OrchestrationService } from "../orchestration/orchestration-service";
|
|
5
5
|
import type { SessionService } from "../sessions/session-service";
|
|
6
|
-
import type { PromptMediaInput, ReplyQuotaContext, SessionTransport } from "../transport/types";
|
|
6
|
+
import type { AgentCommand, PromptMediaInput, PromptUsage, ReplyQuotaContext, SessionTransport } from "../transport/types";
|
|
7
7
|
import type { QuotaManager } from "../weixin/messaging/quota-manager.js";
|
|
8
8
|
import type { PlanEntry, ToolUseEvent } from "../channels/types.js";
|
|
9
9
|
import type { PerfSpan } from "../perf/perf-tracer";
|
|
@@ -113,10 +113,7 @@ export interface SessionInteractionOps {
|
|
|
113
113
|
cancelled: boolean;
|
|
114
114
|
message: string;
|
|
115
115
|
}>;
|
|
116
|
-
promptTransportSession: (session: import("../transport/types").ResolvedSession, text: string, reply?: (text: string) => Promise<void>, replyContext?: ReplyQuotaContext, media?: PromptMediaInput, abortSignal?: AbortSignal, onToolEvent?: (event: ToolUseEvent) => void | Promise<void>, onThought?: (chunk: string) => void | Promise<void>, perfSpan?: PerfSpan, onPlan?: (entries: PlanEntry[]) => void | Promise<void>, onUsage?: (usage: {
|
|
117
|
-
used: number;
|
|
118
|
-
size: number;
|
|
119
|
-
}) => void | Promise<void>) => Promise<{
|
|
116
|
+
promptTransportSession: (session: import("../transport/types").ResolvedSession, text: string, reply?: (text: string) => Promise<void>, replyContext?: ReplyQuotaContext, media?: PromptMediaInput, abortSignal?: AbortSignal, onToolEvent?: (event: ToolUseEvent) => void | Promise<void>, onThought?: (chunk: string) => void | Promise<void>, perfSpan?: PerfSpan, onPlan?: (entries: PlanEntry[]) => void | Promise<void>, onUsage?: (usage: PromptUsage) => void | Promise<void>, onCommands?: (commands: AgentCommand[]) => void | Promise<void>) => Promise<{
|
|
120
117
|
text: string;
|
|
121
118
|
}>;
|
|
122
119
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AppLogger } from "../logging/app-logger";
|
|
2
2
|
import type { ToolUseEvent, PlanEntry } from "../channels/types";
|
|
3
|
+
import type { AgentCommand, UsageBreakdown, UsageCost } from "../transport/types";
|
|
3
4
|
import type { NativeHistoryMessage } from "../transport/native-session-history";
|
|
4
5
|
export interface ScheduledOrigin {
|
|
5
6
|
taskId: string;
|
|
@@ -37,6 +38,13 @@ export type ControlEvent = {
|
|
|
37
38
|
sessionAlias: string;
|
|
38
39
|
used: number;
|
|
39
40
|
size: number;
|
|
41
|
+
cost?: UsageCost;
|
|
42
|
+
breakdown?: UsageBreakdown;
|
|
43
|
+
} | {
|
|
44
|
+
type: "agent-commands";
|
|
45
|
+
chatKey: string;
|
|
46
|
+
sessionAlias: string;
|
|
47
|
+
commands: AgentCommand[];
|
|
40
48
|
} | {
|
|
41
49
|
type: "turn-finished";
|
|
42
50
|
chatKey: string;
|
|
@@ -46,6 +54,8 @@ export type ControlEvent = {
|
|
|
46
54
|
cancelled?: boolean;
|
|
47
55
|
} | {
|
|
48
56
|
type: "sessions-changed";
|
|
57
|
+
} | {
|
|
58
|
+
type: "workspaces-changed";
|
|
49
59
|
} | {
|
|
50
60
|
type: "scheduled-changed";
|
|
51
61
|
chatKey: string;
|
|
@@ -9,6 +9,8 @@ import type { OrchestrationTaskRecord } from "../orchestration/orchestration-typ
|
|
|
9
9
|
import type { ControlEventBus } from "./control-event-bus";
|
|
10
10
|
import type { AgentCatalogEntry } from "../config/agent-catalog";
|
|
11
11
|
import { type DirListing, type FileContent, type SearchResult, type WorkspaceDiff } from "./workspace-fs";
|
|
12
|
+
import type { PromptAttachmentRef } from "@ganglion/xacpx-relay-protocol";
|
|
13
|
+
import type { UploadStore } from "./upload-store.js";
|
|
12
14
|
export interface ControlSessionInfo {
|
|
13
15
|
alias: string;
|
|
14
16
|
agent: string;
|
|
@@ -63,6 +65,7 @@ export interface ControlServiceDeps {
|
|
|
63
65
|
create(name: string, cwd: string, description?: string): Promise<ControlWorkspaceInfo>;
|
|
64
66
|
remove(name: string): Promise<void>;
|
|
65
67
|
};
|
|
68
|
+
uploadStore: UploadStore;
|
|
66
69
|
}
|
|
67
70
|
export interface ControlPromptInput {
|
|
68
71
|
chatKey: string;
|
|
@@ -71,6 +74,7 @@ export interface ControlPromptInput {
|
|
|
71
74
|
accountId?: string;
|
|
72
75
|
senderId: string;
|
|
73
76
|
isOwner?: boolean;
|
|
77
|
+
media?: PromptAttachmentRef[];
|
|
74
78
|
}
|
|
75
79
|
export interface ControlPromptResult {
|
|
76
80
|
ok: boolean;
|
|
@@ -105,6 +109,17 @@ export declare class ControlService {
|
|
|
105
109
|
readWorkspaceFile(workspace: string, path: string): Promise<FileContent>;
|
|
106
110
|
workspaceGitDiff(workspace: string, path?: string): Promise<WorkspaceDiff>;
|
|
107
111
|
searchWorkspace(workspace: string, query: string): Promise<SearchResult>;
|
|
112
|
+
uploadFile(input: {
|
|
113
|
+
filename: string;
|
|
114
|
+
content: string;
|
|
115
|
+
mimeType: string;
|
|
116
|
+
}): Promise<{
|
|
117
|
+
id: string;
|
|
118
|
+
path: string;
|
|
119
|
+
filename: string;
|
|
120
|
+
mimeType: string;
|
|
121
|
+
size: number;
|
|
122
|
+
}>;
|
|
108
123
|
/** Read a session's current model and the agent-advertised available ids. */
|
|
109
124
|
getSessionModel(chatKey: string, alias: string): Promise<{
|
|
110
125
|
current?: string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface UploadStoreOptions {
|
|
2
|
+
rootDir?: string;
|
|
3
|
+
maxBytes?: number;
|
|
4
|
+
ttlMs?: number;
|
|
5
|
+
now?: () => Date;
|
|
6
|
+
}
|
|
7
|
+
export interface SavedUpload {
|
|
8
|
+
id: string;
|
|
9
|
+
path: string;
|
|
10
|
+
filename: string;
|
|
11
|
+
mimeType: string;
|
|
12
|
+
size: number;
|
|
13
|
+
}
|
|
14
|
+
/** Strip directory components and traversal segments, leaving a safe basename. */
|
|
15
|
+
export declare function sanitizeUploadFilename(raw: string): string;
|
|
16
|
+
export declare class UploadStore {
|
|
17
|
+
private readonly rootDir;
|
|
18
|
+
private readonly maxBytes;
|
|
19
|
+
private readonly ttlMs;
|
|
20
|
+
private readonly now;
|
|
21
|
+
constructor(opts?: UploadStoreOptions);
|
|
22
|
+
/** Sandbox root all uploads are written under. Callers may use this to verify a
|
|
23
|
+
* media filePath actually originated from a control.upload (defense-in-depth). */
|
|
24
|
+
get root(): string;
|
|
25
|
+
save(filename: string, base64: string, mimeType: string): Promise<SavedUpload>;
|
|
26
|
+
/** Remove upload dirs whose mtime is older than the TTL. Returns count removed. */
|
|
27
|
+
cleanup(): Promise<number>;
|
|
28
|
+
}
|
package/dist/i18n/types.d.ts
CHANGED
|
@@ -809,6 +809,7 @@ export interface MiscMessages {
|
|
|
809
809
|
defaultHomeWorkspaceDescription: string;
|
|
810
810
|
pluginChannelFeishu: string;
|
|
811
811
|
pluginChannelYuanbao: string;
|
|
812
|
+
pluginChannelRelay: string;
|
|
812
813
|
pluginChannelInstallHint: (channelType: string, packageName: string) => string;
|
|
813
814
|
orchestrationSuggestion1: string;
|
|
814
815
|
orchestrationSuggestion2: string;
|
package/dist/plugin-api.js
CHANGED
|
@@ -1050,6 +1050,7 @@ var init_misc = __esm(() => {
|
|
|
1050
1050
|
defaultHomeWorkspaceDescription: "Home directory",
|
|
1051
1051
|
pluginChannelFeishu: "Feishu channel",
|
|
1052
1052
|
pluginChannelYuanbao: "Tencent Yuanbao channel",
|
|
1053
|
+
pluginChannelRelay: "Relay hub connector (drive this instance from a self-hosted relay hub)",
|
|
1053
1054
|
pluginChannelInstallHint: (channelType, packageName) => `Channel ${channelType} requires a plugin: xacpx plugin add ${packageName}`,
|
|
1054
1055
|
orchestrationSuggestion1: "Run /tasks --stuck to locate stuck tasks",
|
|
1055
1056
|
orchestrationSuggestion2: "/task <id> shows the full timeline to locate errors",
|
|
@@ -2146,6 +2147,7 @@ var init_misc2 = __esm(() => {
|
|
|
2146
2147
|
defaultHomeWorkspaceDescription: "用户主目录",
|
|
2147
2148
|
pluginChannelFeishu: "飞书频道",
|
|
2148
2149
|
pluginChannelYuanbao: "腾讯元宝频道",
|
|
2150
|
+
pluginChannelRelay: "Relay hub 连接器(从自托管 relay hub 遥控这台实例)",
|
|
2149
2151
|
pluginChannelInstallHint: (channelType, packageName) => `频道 ${channelType} 需要安装插件:xacpx plugin add ${packageName}`,
|
|
2150
2152
|
orchestrationSuggestion1: "查看 /tasks --stuck 定位卡住的任务",
|
|
2151
2153
|
orchestrationSuggestion2: "/task <id> 可看完整时间线定位错误点",
|
|
@@ -3,6 +3,37 @@ import type { QuotaManager } from "../weixin/messaging/quota-manager.js";
|
|
|
3
3
|
import type { PlanEntry, ToolUseEvent } from "../channels/types.js";
|
|
4
4
|
import type { ToolEventMode } from "./tool-event-mode.js";
|
|
5
5
|
export type { ToolEventMode } from "./tool-event-mode.js";
|
|
6
|
+
/** Cumulative session cost the agent reported (ACP `usage_update.cost`). Both optional. */
|
|
7
|
+
export interface UsageCost {
|
|
8
|
+
amount?: number;
|
|
9
|
+
currency?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Per-turn token breakdown from ACP `usage_update._meta.usage` (Claude reports it;
|
|
13
|
+
* codex may omit). All fields optional — treat missing as "unknown", not zero.
|
|
14
|
+
*/
|
|
15
|
+
export interface UsageBreakdown {
|
|
16
|
+
inputTokens?: number;
|
|
17
|
+
outputTokens?: number;
|
|
18
|
+
cachedReadTokens?: number;
|
|
19
|
+
cachedWriteTokens?: number;
|
|
20
|
+
thoughtTokens?: number;
|
|
21
|
+
totalTokens?: number;
|
|
22
|
+
}
|
|
23
|
+
/** Context-usage side-channel payload: window fill plus optional cost & token breakdown. */
|
|
24
|
+
export interface PromptUsage {
|
|
25
|
+
used: number;
|
|
26
|
+
size: number;
|
|
27
|
+
cost?: UsageCost;
|
|
28
|
+
breakdown?: UsageBreakdown;
|
|
29
|
+
}
|
|
30
|
+
/** An agent-advertised slash command (ACP `available_commands_update`). */
|
|
31
|
+
export interface AgentCommand {
|
|
32
|
+
name: string;
|
|
33
|
+
description?: string;
|
|
34
|
+
/** Whether the command accepts an argument (ACP advertised a non-null `input`). */
|
|
35
|
+
hasInput?: boolean;
|
|
36
|
+
}
|
|
6
37
|
export interface ReplyQuotaContext {
|
|
7
38
|
chatKey: string;
|
|
8
39
|
quota: QuotaManager;
|
|
@@ -125,10 +156,12 @@ export interface PromptOptions {
|
|
|
125
156
|
* scalar (re-sent during a turn). Optional — only agents that report it fire this
|
|
126
157
|
* (e.g. claude does, codex does not), and text channels omit the handler.
|
|
127
158
|
*/
|
|
128
|
-
onUsage?: (usage:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
159
|
+
onUsage?: (usage: PromptUsage) => void | Promise<void>;
|
|
160
|
+
/**
|
|
161
|
+
* Agent-advertised slash commands (ACP `available_commands_update`). Replace-latest
|
|
162
|
+
* list, re-sent when the agent updates it. Optional — not every adapter advertises.
|
|
163
|
+
*/
|
|
164
|
+
onCommands?: (commands: AgentCommand[]) => void | Promise<void>;
|
|
132
165
|
/**
|
|
133
166
|
* How tool_call / tool_call_update events are surfaced for this prompt.
|
|
134
167
|
*
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ChannelMediaAttachment, OutboundChannelMedia } from "../../channels/media-types.js";
|
|
2
2
|
import type { PlanEntry, ScheduledSessionDescriptor, ToolUseEvent } from "../../channels/types.js";
|
|
3
|
+
import type { AgentCommand, PromptUsage } from "../../transport/types.js";
|
|
3
4
|
import type { PerfSpan } from "../../perf/perf-tracer.js";
|
|
4
5
|
/**
|
|
5
6
|
* Agent interface — any AI backend that can handle a chat message.
|
|
@@ -51,10 +52,9 @@ export interface ChatRequest {
|
|
|
51
52
|
/** Structured plan/todo side-channel; see PromptOptions.onPlan. */
|
|
52
53
|
onPlan?: (entries: PlanEntry[]) => void | Promise<void>;
|
|
53
54
|
/** Context-usage side-channel; see PromptOptions.onUsage. */
|
|
54
|
-
onUsage?: (usage:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}) => void | Promise<void>;
|
|
55
|
+
onUsage?: (usage: PromptUsage) => void | Promise<void>;
|
|
56
|
+
/** Agent-advertised slash commands; see PromptOptions.onCommands. */
|
|
57
|
+
onCommands?: (commands: AgentCommand[]) => void | Promise<void>;
|
|
58
58
|
/**
|
|
59
59
|
* Optional per-turn performance tracing span. When `logging.perf.enabled` is
|
|
60
60
|
* true, the channel handler attaches a `PerfSpan` so downstream layers can
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ganglion/xacpx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "随时随地通过聊天频道(微信 / 飞书 / 元宝等)远程控制 `acpx` 上的 Claude Code、Codex 等 Agents。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"acpx",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
87
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
88
|
-
"acpx": "^0.
|
|
88
|
+
"acpx": "^0.11.0",
|
|
89
89
|
"node-pty": "^1.1.0",
|
|
90
90
|
"proper-lockfile": "^4.1.2",
|
|
91
91
|
"protobufjs": "^7.5.6",
|