@ganglion/xacpx 0.22.1-beta.0 → 0.23.0-beta.0
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/dist/bridge/bridge-main.js +98 -8
- package/dist/channels/types.d.ts +22 -0
- package/dist/cli.js +2479 -204
- package/dist/control/control-event-bus.d.ts +6 -0
- package/dist/control/control-service.d.ts +147 -3
- package/dist/control/session-turn-runner.d.ts +25 -1
- package/dist/control/turn-queue.d.ts +22 -6
- package/dist/control/turn-support.d.ts +14 -1
- package/dist/orchestration/agent-messaging-error.d.ts +15 -0
- package/dist/orchestration/agent-messaging-types.d.ts +112 -0
- package/dist/orchestration/orchestration-service.d.ts +2 -0
- package/dist/orchestration/orchestration-types.d.ts +4 -0
- package/dist/orchestration/service/coordinator-registry-service.d.ts +1 -1
- package/dist/orchestration/service/human-delegation-service.d.ts +1 -1
- package/dist/orchestration/service/rpc-delegation-service.d.ts +1 -1
- package/dist/orchestration/service/task-approval-service.d.ts +1 -1
- package/dist/orchestration/service/worker-session-manager.d.ts +1 -1
- package/dist/orchestration/worker-launch.d.ts +4 -0
- package/dist/state/state-store.d.ts +3 -3
- package/dist/transport/command-timeouts.d.ts +1 -1
- package/dist/transport/message-injection.d.ts +18 -0
- package/dist/transport/types.d.ts +5 -0
- package/dist/weixin/agent/interface.d.ts +5 -0
- package/package.json +1 -1
|
@@ -2071,6 +2071,30 @@ var init_prompt_output = __esm(() => {
|
|
|
2071
2071
|
};
|
|
2072
2072
|
});
|
|
2073
2073
|
|
|
2074
|
+
// src/transport/message-injection.ts
|
|
2075
|
+
function isMessageInjectionErrorCode(value) {
|
|
2076
|
+
return typeof value === "string" && MESSAGE_INJECTION_ERROR_CODES.has(value);
|
|
2077
|
+
}
|
|
2078
|
+
var MESSAGE_INJECTION_ERROR_CODES, MessageInjectionError;
|
|
2079
|
+
var init_message_injection = __esm(() => {
|
|
2080
|
+
MESSAGE_INJECTION_ERROR_CODES = new Set([
|
|
2081
|
+
"TARGET_NOT_RUNNING",
|
|
2082
|
+
"TARGET_NOT_STEERABLE",
|
|
2083
|
+
"TARGET_NOT_INTERRUPTIBLE",
|
|
2084
|
+
"DELIVERY_RACE",
|
|
2085
|
+
"DELIVERY_TIMEOUT",
|
|
2086
|
+
"DELIVERY_FAILED"
|
|
2087
|
+
]);
|
|
2088
|
+
MessageInjectionError = class MessageInjectionError extends Error {
|
|
2089
|
+
code;
|
|
2090
|
+
name = "MessageInjectionError";
|
|
2091
|
+
constructor(code, message) {
|
|
2092
|
+
super(message);
|
|
2093
|
+
this.code = code;
|
|
2094
|
+
}
|
|
2095
|
+
};
|
|
2096
|
+
});
|
|
2097
|
+
|
|
2074
2098
|
// src/process/spawn-command.ts
|
|
2075
2099
|
function resolveSpawnCommand(command, args) {
|
|
2076
2100
|
if (SCRIPT_FILE_PATTERN.test(command)) {
|
|
@@ -9246,6 +9270,9 @@ function buildPromptArgs(input, tail) {
|
|
|
9246
9270
|
];
|
|
9247
9271
|
return appendAgentAndTail(prefix, input, tail);
|
|
9248
9272
|
}
|
|
9273
|
+
function buildQueueMessagePromptArgs(input, sessionName, text) {
|
|
9274
|
+
return buildPromptArgs(input, ["prompt", "-s", sessionName, "--no-wait", text]);
|
|
9275
|
+
}
|
|
9249
9276
|
function buildAgentQueryArgs(input, format, tail) {
|
|
9250
9277
|
const prefix = ["--format", format, "--cwd", input.cwd, ...buildPermissionArgs(input.permission)];
|
|
9251
9278
|
return appendAgentAndTail(prefix, input, tail);
|
|
@@ -9682,6 +9709,9 @@ class AcpxQueueOverflowError extends Error {
|
|
|
9682
9709
|
}
|
|
9683
9710
|
}
|
|
9684
9711
|
|
|
9712
|
+
// src/bridge/bridge-server.ts
|
|
9713
|
+
init_message_injection();
|
|
9714
|
+
|
|
9685
9715
|
// src/bridge/bridge-request-scheduler.ts
|
|
9686
9716
|
class BridgeRequestScheduler {
|
|
9687
9717
|
sessions = new Map;
|
|
@@ -9690,16 +9720,18 @@ class BridgeRequestScheduler {
|
|
|
9690
9720
|
return Promise.resolve().then(task);
|
|
9691
9721
|
}
|
|
9692
9722
|
const state = this.sessions.get(sessionName) ?? this.createSessionState(sessionName);
|
|
9693
|
-
|
|
9694
|
-
const
|
|
9695
|
-
state
|
|
9723
|
+
const tailName = lane === "message" ? "messageTail" : "normalTail";
|
|
9724
|
+
const pendingName = lane === "message" ? "pendingMessages" : "pendingNormals";
|
|
9725
|
+
state[pendingName] += 1;
|
|
9726
|
+
const result = state[tailName].then(() => task());
|
|
9727
|
+
state[tailName] = result.then(() => {
|
|
9696
9728
|
return;
|
|
9697
9729
|
}, () => {
|
|
9698
9730
|
return;
|
|
9699
9731
|
});
|
|
9700
9732
|
return result.finally(() => {
|
|
9701
|
-
state
|
|
9702
|
-
if (state.pendingNormals === 0 && this.sessions.get(sessionName) === state) {
|
|
9733
|
+
state[pendingName] -= 1;
|
|
9734
|
+
if (state.pendingNormals === 0 && state.pendingMessages === 0 && this.sessions.get(sessionName) === state) {
|
|
9703
9735
|
this.sessions.delete(sessionName);
|
|
9704
9736
|
}
|
|
9705
9737
|
});
|
|
@@ -9707,7 +9739,9 @@ class BridgeRequestScheduler {
|
|
|
9707
9739
|
createSessionState(sessionName) {
|
|
9708
9740
|
const state = {
|
|
9709
9741
|
pendingNormals: 0,
|
|
9710
|
-
|
|
9742
|
+
pendingMessages: 0,
|
|
9743
|
+
normalTail: Promise.resolve(),
|
|
9744
|
+
messageTail: Promise.resolve()
|
|
9711
9745
|
};
|
|
9712
9746
|
this.sessions.set(sessionName, state);
|
|
9713
9747
|
return state;
|
|
@@ -9753,6 +9787,7 @@ init_command_timeouts();
|
|
|
9753
9787
|
init_command_timeouts();
|
|
9754
9788
|
init_acpx_command_builder();
|
|
9755
9789
|
init_session_effort();
|
|
9790
|
+
init_message_injection();
|
|
9756
9791
|
class EnsureSessionFailedError extends Error {
|
|
9757
9792
|
kind;
|
|
9758
9793
|
data;
|
|
@@ -10037,6 +10072,35 @@ class BridgeRuntime {
|
|
|
10037
10072
|
} catch {}
|
|
10038
10073
|
}
|
|
10039
10074
|
}
|
|
10075
|
+
async injectMessage(input) {
|
|
10076
|
+
if (input.mode === "steer") {
|
|
10077
|
+
throw new MessageInjectionError("TARGET_NOT_STEERABLE", "The target does not support same-turn steering.");
|
|
10078
|
+
}
|
|
10079
|
+
if (input.mode === "interrupt") {
|
|
10080
|
+
throw new MessageInjectionError("TARGET_NOT_INTERRUPTIBLE", "The target does not support interrupt delivery.");
|
|
10081
|
+
}
|
|
10082
|
+
await this.syncPersistedSessionEffort(input);
|
|
10083
|
+
await this.launchMcpQueueOwnerIfNeeded(input);
|
|
10084
|
+
const spawnSpec = resolveSpawnCommand(this.command, buildQueueMessagePromptArgs({
|
|
10085
|
+
agent: input.agent,
|
|
10086
|
+
agentCommand: input.agentCommand,
|
|
10087
|
+
acpxAgent: input.acpxAgent,
|
|
10088
|
+
rawCommand: input.rawCommand,
|
|
10089
|
+
cwd: input.cwd,
|
|
10090
|
+
model: input.model,
|
|
10091
|
+
permission: this.permissionInput(),
|
|
10092
|
+
queueOwnerTtlSeconds: this.options.queueOwnerTtlSeconds
|
|
10093
|
+
}, input.name, input.text));
|
|
10094
|
+
const result = await this.run(spawnSpec.command, spawnSpec.args, this.withSpawnEnvironment(input, {
|
|
10095
|
+
timeoutMs: this.managementCommandTimeoutMs(),
|
|
10096
|
+
stage: "inject-message"
|
|
10097
|
+
}));
|
|
10098
|
+
if (result.code !== 0) {
|
|
10099
|
+
const detail = normalizeCommandError(result) ?? (result.stderr || result.stdout || `inject-message failed with exit code ${result.code}`);
|
|
10100
|
+
throw new Error(detail);
|
|
10101
|
+
}
|
|
10102
|
+
return { status: "queued", modeUsed: "queue" };
|
|
10103
|
+
}
|
|
10040
10104
|
async cleanupOverflowedOwner(input) {
|
|
10041
10105
|
const diagnostics = [];
|
|
10042
10106
|
let cancelSucceeded = false;
|
|
@@ -10596,6 +10660,7 @@ var BRIDGE_METHODS = new Set([
|
|
|
10596
10660
|
"listAgentSessions",
|
|
10597
10661
|
"resumeAgentSession",
|
|
10598
10662
|
"prompt",
|
|
10663
|
+
"injectMessage",
|
|
10599
10664
|
"setMode",
|
|
10600
10665
|
"setModel",
|
|
10601
10666
|
"getSessionModel",
|
|
@@ -10614,6 +10679,7 @@ var SESSION_SCOPED_METHODS = new Set([
|
|
|
10614
10679
|
"tailSessionHistory",
|
|
10615
10680
|
"resumeAgentSession",
|
|
10616
10681
|
"prompt",
|
|
10682
|
+
"injectMessage",
|
|
10617
10683
|
"setMode",
|
|
10618
10684
|
"setModel",
|
|
10619
10685
|
"getSessionModel",
|
|
@@ -10670,7 +10736,7 @@ class BridgeServer {
|
|
|
10670
10736
|
...error.stderrTail ? { stderrTail: error.stderrTail } : {}
|
|
10671
10737
|
}
|
|
10672
10738
|
} : {};
|
|
10673
|
-
const errorCode = error instanceof AcpxQueueOverflowError ? error.code : error instanceof BridgeInvalidRequestError ? "BRIDGE_INVALID_REQUEST" : "BRIDGE_INTERNAL_ERROR";
|
|
10739
|
+
const errorCode = error instanceof AcpxQueueOverflowError ? error.code : error instanceof MessageInjectionError ? error.code : error instanceof BridgeInvalidRequestError ? "BRIDGE_INVALID_REQUEST" : "BRIDGE_INTERNAL_ERROR";
|
|
10674
10740
|
return `${JSON.stringify({
|
|
10675
10741
|
id: requestId,
|
|
10676
10742
|
ok: false,
|
|
@@ -10763,7 +10829,7 @@ class BridgeServer {
|
|
|
10763
10829
|
if (!sessionKey) {
|
|
10764
10830
|
return await this.dispatch(requestId, method, params, writeLine);
|
|
10765
10831
|
}
|
|
10766
|
-
const lane = method === "cancel" || method === "isSessionWarm" ? "control" : "normal";
|
|
10832
|
+
const lane = method === "cancel" || method === "isSessionWarm" ? "control" : method === "injectMessage" ? "message" : "normal";
|
|
10767
10833
|
return await this.scheduler.run(sessionKey, lane, () => this.dispatch(requestId, method, params, writeLine));
|
|
10768
10834
|
}
|
|
10769
10835
|
async dispatch(requestId, method, params, writeLine) {
|
|
@@ -10897,6 +10963,23 @@ class BridgeServer {
|
|
|
10897
10963
|
}));
|
|
10898
10964
|
}
|
|
10899
10965
|
});
|
|
10966
|
+
case "injectMessage":
|
|
10967
|
+
return await this.runtime.injectMessage({
|
|
10968
|
+
agent: requireString(params, "agent"),
|
|
10969
|
+
...agentExecutionSettings(params),
|
|
10970
|
+
agentCommand: asOptionalString(params.agentCommand),
|
|
10971
|
+
...agentLaunchSelection(params),
|
|
10972
|
+
cwd: requireString(params, "cwd"),
|
|
10973
|
+
name: requireString(params, "name"),
|
|
10974
|
+
sessionKey: asOptionalString(params.sessionKey),
|
|
10975
|
+
model: asOptionalString(params.model),
|
|
10976
|
+
effort: asOptionalString(params.effort),
|
|
10977
|
+
mcpCoordinatorSession: asOptionalString(params.mcpCoordinatorSession),
|
|
10978
|
+
mcpSourceHandle: asOptionalString(params.mcpSourceHandle),
|
|
10979
|
+
text: requireString(params, "text"),
|
|
10980
|
+
mode: requireMessageMode(params, "mode"),
|
|
10981
|
+
messageId: requireString(params, "messageId")
|
|
10982
|
+
});
|
|
10900
10983
|
case "resumeAgentSession":
|
|
10901
10984
|
return await this.runtime.resumeAgentSession({
|
|
10902
10985
|
agent: requireString(params, "agent"),
|
|
@@ -11119,6 +11202,13 @@ function requirePromptText(params, media) {
|
|
|
11119
11202
|
}
|
|
11120
11203
|
return value;
|
|
11121
11204
|
}
|
|
11205
|
+
function requireMessageMode(params, key) {
|
|
11206
|
+
const value = params[key];
|
|
11207
|
+
if (value === "auto" || value === "steer" || value === "queue" || value === "interrupt") {
|
|
11208
|
+
return value;
|
|
11209
|
+
}
|
|
11210
|
+
throw new BridgeInvalidRequestError(key + " must be auto, steer, queue, or interrupt");
|
|
11211
|
+
}
|
|
11122
11212
|
function requirePermissionMode(params, key) {
|
|
11123
11213
|
const value = params[key];
|
|
11124
11214
|
if (value === "approve-all" || value === "approve-reads" || value === "deny-all") {
|
package/dist/channels/types.d.ts
CHANGED
|
@@ -157,6 +157,28 @@ export interface MessageChannelRuntime {
|
|
|
157
157
|
* treated as "table".
|
|
158
158
|
*/
|
|
159
159
|
nativeSessionListFormat?: "cards" | "table";
|
|
160
|
+
/** Relay-capable channels: route an Agent Message to a remote messaging node.
|
|
161
|
+
* Optional — absent channels make the router report ROUTE_UNAVAILABLE. */
|
|
162
|
+
sendAgentMessageRoute?(payload: {
|
|
163
|
+
sourceNodeId: string;
|
|
164
|
+
sourceEndpointId: string;
|
|
165
|
+
targetNodeId: string;
|
|
166
|
+
targetEndpointId: string;
|
|
167
|
+
messageId: string;
|
|
168
|
+
content: string;
|
|
169
|
+
requestedMode: string;
|
|
170
|
+
replyTo?: string;
|
|
171
|
+
}): Promise<{
|
|
172
|
+
messageId: string;
|
|
173
|
+
status: "injected" | "queued" | "failed";
|
|
174
|
+
modeUsed?: "steer" | "queue" | "interrupt" | "prompt";
|
|
175
|
+
targetState?: "idle" | "running";
|
|
176
|
+
errorCode?: string;
|
|
177
|
+
deduplicated?: boolean;
|
|
178
|
+
}>;
|
|
179
|
+
/** Relay-capable channels: publish this instance's agent endpoint directory to
|
|
180
|
+
* the hub. The FULL snapshot replaces the previous one (no delta protocol). */
|
|
181
|
+
syncAgentEndpoints?(endpoints: unknown[]): void;
|
|
160
182
|
}
|
|
161
183
|
export type ToolUseStatus = "running" | "success" | "error";
|
|
162
184
|
export type ToolUseKind = "read" | "search" | "execute" | "edit" | "think" | "other";
|