@openacp/cli 2026.413.1 → 2026.414.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/dist/{channel-Dg1nGCYa.d.ts → channel-bWC2vDOv.d.ts} +21 -6
- package/dist/cli.js +210 -107
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +51 -10
- package/dist/index.js +146 -59
- package/dist/index.js.map +1 -1
- package/dist/testing.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as Attachment, O as OutgoingMessage, I as IChannelAdapter, T as TurnMeta, a as AgentEvent, S as StopReason, P as PermissionRequest, N as NotificationMessage, b as SessionStatus, U as UsageRecord, c as AgentCapabilities, d as AgentDefinition, M as McpServerConfig, e as SetConfigOptionValue, f as InstalledAgent, R as RegistryAgent, g as AgentListItem, h as AvailabilityResult, i as InstallProgress, j as InstallResult, k as TurnContext, C as ConfigOption, l as AgentSwitchEntry, m as AgentCommand, n as TurnRouting, o as SessionRecord, p as UsageRecordEvent, q as IncomingMessage, D as DisplayVerbosity,
|
|
2
|
-
export {
|
|
1
|
+
import { A as Attachment, O as OutgoingMessage, I as IChannelAdapter, T as TurnMeta, a as AgentEvent, S as StopReason, P as PermissionRequest, N as NotificationMessage, b as SessionStatus, U as UsageRecord, c as AgentCapabilities, d as AgentDefinition, M as McpServerConfig, e as SetConfigOptionValue, f as InstalledAgent, R as RegistryAgent, g as AgentListItem, h as AvailabilityResult, i as InstallProgress, j as InstallResult, k as TurnContext, C as ConfigOption, l as AgentSwitchEntry, m as AgentCommand, n as TurnRouting, o as SessionRecord, p as UsageRecordEvent, q as TurnSender, r as IncomingMessage, D as DisplayVerbosity, s as ChannelConfig, t as AdapterCapabilities, u as ToolCallMeta, V as ViewerLinks, v as OutputMode, w as PlanEntry } from './channel-bWC2vDOv.js';
|
|
2
|
+
export { x as AgentDistribution, y as AuthMethod, z as AuthenticateRequest, B as ChannelAdapter, E as ConfigSelectChoice, F as ConfigSelectGroup, G as ContentBlock, K as KIND_ICONS, H as ModelInfo, J as NewSessionResponse, L as PermissionOption, Q as PromptResponse, W as RegistryBinaryTarget, X as RegistryDistribution, Y as STATUS_ICONS, Z as SessionListItem, _ as SessionListResponse, $ as SessionMode, a0 as SessionModeState, a1 as SessionModelState, a2 as TelegramPlatformData, a3 as ToolUpdateMeta, a4 as createTurnContext, a5 as getEffectiveTarget, a6 as isSystemEvent } from './channel-bWC2vDOv.js';
|
|
3
3
|
import pino from 'pino';
|
|
4
4
|
import * as zod from 'zod';
|
|
5
5
|
import { ZodSchema, z } from 'zod';
|
|
@@ -559,6 +559,9 @@ interface MiddlewarePayloadMap {
|
|
|
559
559
|
promptNumber: number;
|
|
560
560
|
turnId: string;
|
|
561
561
|
meta?: TurnMeta;
|
|
562
|
+
userPrompt?: string;
|
|
563
|
+
sourceAdapterId?: string;
|
|
564
|
+
responseAdapterId?: string | null;
|
|
562
565
|
};
|
|
563
566
|
'turn:end': {
|
|
564
567
|
sessionId: string;
|
|
@@ -1868,6 +1871,11 @@ declare class Session extends TypedEmitter<SessionEvents> {
|
|
|
1868
1871
|
get queueDepth(): number;
|
|
1869
1872
|
/** Whether a prompt is currently being processed by the agent */
|
|
1870
1873
|
get promptRunning(): boolean;
|
|
1874
|
+
/** Snapshot of queued (not yet processing) items — for inspection by API consumers. */
|
|
1875
|
+
get queueItems(): {
|
|
1876
|
+
userPrompt: string;
|
|
1877
|
+
turnId?: string;
|
|
1878
|
+
}[];
|
|
1871
1879
|
/** Store context markdown to be prepended to the next prompt (used for session resume with history). */
|
|
1872
1880
|
setContext(markdown: string): void;
|
|
1873
1881
|
/** Set TTS mode: "off" = disabled, "next" = one-shot (auto-resets after prompt), "on" = persistent. */
|
|
@@ -1938,13 +1946,13 @@ declare class PromptQueue {
|
|
|
1938
1946
|
private abortController;
|
|
1939
1947
|
/** Set when abort is triggered; drainNext waits for the current processor to settle before starting the next item. */
|
|
1940
1948
|
private processorSettled;
|
|
1941
|
-
constructor(processor: (text: string, attachments?: Attachment[], routing?: TurnRouting, turnId?: string, meta?: TurnMeta) => Promise<void>, onError?: ((err: unknown) => void) | undefined);
|
|
1949
|
+
constructor(processor: (text: string, userPrompt: string, attachments?: Attachment[], routing?: TurnRouting, turnId?: string, meta?: TurnMeta) => Promise<void>, onError?: ((err: unknown) => void) | undefined);
|
|
1942
1950
|
/**
|
|
1943
1951
|
* Add a prompt to the queue. If no prompt is currently processing, it runs
|
|
1944
1952
|
* immediately. Otherwise, it's buffered and the returned promise resolves
|
|
1945
1953
|
* only after the prompt finishes processing.
|
|
1946
1954
|
*/
|
|
1947
|
-
enqueue(text: string, attachments?: Attachment[], routing?: TurnRouting, turnId?: string, meta?: TurnMeta): Promise<void>;
|
|
1955
|
+
enqueue(text: string, userPrompt: string, attachments?: Attachment[], routing?: TurnRouting, turnId?: string, meta?: TurnMeta): Promise<void>;
|
|
1948
1956
|
/** Run a single prompt through the processor, then drain the next queued item. */
|
|
1949
1957
|
private process;
|
|
1950
1958
|
/** Dequeue and process the next pending prompt, if any. Called after each prompt completes. */
|
|
@@ -1956,6 +1964,11 @@ declare class PromptQueue {
|
|
|
1956
1964
|
clear(): void;
|
|
1957
1965
|
get pending(): number;
|
|
1958
1966
|
get isProcessing(): boolean;
|
|
1967
|
+
/** Snapshot of queued (not yet processing) items — used for queue inspection by callers. */
|
|
1968
|
+
get pendingItems(): Array<{
|
|
1969
|
+
userPrompt: string;
|
|
1970
|
+
turnId?: string;
|
|
1971
|
+
}>;
|
|
1959
1972
|
}
|
|
1960
1973
|
|
|
1961
1974
|
/**
|
|
@@ -2036,6 +2049,7 @@ interface EventBusEvents {
|
|
|
2036
2049
|
}) => void;
|
|
2037
2050
|
"agent:event": (data: {
|
|
2038
2051
|
sessionId: string;
|
|
2052
|
+
turnId: string;
|
|
2039
2053
|
event: AgentEvent;
|
|
2040
2054
|
}) => void;
|
|
2041
2055
|
"permission:request": (data: {
|
|
@@ -2056,6 +2070,8 @@ interface EventBusEvents {
|
|
|
2056
2070
|
commands: Array<{
|
|
2057
2071
|
name: string;
|
|
2058
2072
|
description: string;
|
|
2073
|
+
category?: string;
|
|
2074
|
+
usage?: string;
|
|
2059
2075
|
}>;
|
|
2060
2076
|
}) => void;
|
|
2061
2077
|
"plugin:loaded": (data: {
|
|
@@ -2103,13 +2119,24 @@ interface EventBusEvents {
|
|
|
2103
2119
|
attachments?: unknown[];
|
|
2104
2120
|
timestamp: string;
|
|
2105
2121
|
queueDepth: number;
|
|
2122
|
+
sender?: TurnSender | null;
|
|
2106
2123
|
}) => void;
|
|
2107
2124
|
"message:processing": (data: {
|
|
2108
2125
|
sessionId: string;
|
|
2109
2126
|
turnId: string;
|
|
2110
2127
|
sourceAdapterId: string;
|
|
2128
|
+
userPrompt: string;
|
|
2129
|
+
finalPrompt: string;
|
|
2130
|
+
attachments?: unknown[];
|
|
2131
|
+
sender?: TurnSender | null;
|
|
2111
2132
|
timestamp: string;
|
|
2112
2133
|
}) => void;
|
|
2134
|
+
/** Fired when a queued message is rejected before processing (e.g. blocked by middleware). */
|
|
2135
|
+
"message:failed": (data: {
|
|
2136
|
+
sessionId: string;
|
|
2137
|
+
turnId: string;
|
|
2138
|
+
reason: string;
|
|
2139
|
+
}) => void;
|
|
2113
2140
|
"session:agentSwitch": (data: {
|
|
2114
2141
|
sessionId: string;
|
|
2115
2142
|
fromAgent: string;
|
|
@@ -3325,24 +3352,37 @@ declare class OpenACPCore {
|
|
|
3325
3352
|
* If no session is found, the user is told to start one with /new.
|
|
3326
3353
|
*/
|
|
3327
3354
|
handleMessage(message: IncomingMessage, initialMeta?: Record<string, unknown>): Promise<void>;
|
|
3355
|
+
/**
|
|
3356
|
+
* Shared dispatch path for sending a prompt to a session.
|
|
3357
|
+
* Called by both handleMessage (Telegram) and handleMessageInSession (SSE/API)
|
|
3358
|
+
* after their respective middleware/enrichment steps.
|
|
3359
|
+
*/
|
|
3360
|
+
private _dispatchToSession;
|
|
3328
3361
|
/**
|
|
3329
3362
|
* Send a message to a known session, running the full message:incoming → agent:beforePrompt
|
|
3330
3363
|
* middleware chain (same as handleMessage) but without the threadId-based session lookup.
|
|
3331
3364
|
*
|
|
3332
|
-
* Used by channels that already hold a direct session reference (e.g. SSE adapter),
|
|
3333
|
-
* looking up by channelId+threadId is unreliable (API sessions may have no threadId).
|
|
3365
|
+
* Used by channels that already hold a direct session reference (e.g. SSE adapter, api-server),
|
|
3366
|
+
* where looking up by channelId+threadId is unreliable (API sessions may have no threadId).
|
|
3334
3367
|
*
|
|
3335
3368
|
* @param session The target session — caller is responsible for validating its status.
|
|
3336
3369
|
* @param message Sender context and message content.
|
|
3337
3370
|
* @param initialMeta Optional adapter-specific context to seed the TurnMeta bag
|
|
3338
3371
|
* (e.g. channelUser with display name/username).
|
|
3372
|
+
* @param options Optional turnId override and response routing.
|
|
3339
3373
|
*/
|
|
3340
3374
|
handleMessageInSession(session: Session, message: {
|
|
3341
3375
|
channelId: string;
|
|
3342
3376
|
userId: string;
|
|
3343
3377
|
text: string;
|
|
3344
3378
|
attachments?: Attachment[];
|
|
3345
|
-
}, initialMeta?: Record<string, unknown
|
|
3379
|
+
}, initialMeta?: Record<string, unknown>, options?: {
|
|
3380
|
+
externalTurnId?: string;
|
|
3381
|
+
responseAdapterId?: string | null;
|
|
3382
|
+
}): Promise<{
|
|
3383
|
+
turnId: string;
|
|
3384
|
+
queueDepth: number;
|
|
3385
|
+
}>;
|
|
3346
3386
|
/**
|
|
3347
3387
|
* Create (or resume) a session with full wiring: agent, adapter thread, bridge, persistence.
|
|
3348
3388
|
*
|
|
@@ -4931,10 +4971,11 @@ declare class TelegramAdapter extends MessagingAdapter {
|
|
|
4931
4971
|
*/
|
|
4932
4972
|
private retryWithBackoff;
|
|
4933
4973
|
/**
|
|
4934
|
-
*
|
|
4935
|
-
*
|
|
4974
|
+
* Sync Telegram autocomplete commands after all plugins are ready.
|
|
4975
|
+
* Merges STATIC_COMMANDS (hardcoded system commands) with plugin commands
|
|
4976
|
+
* from the registry, deduplicating by command name. Non-critical.
|
|
4936
4977
|
*/
|
|
4937
|
-
private
|
|
4978
|
+
private syncCommandsWithRetry;
|
|
4938
4979
|
private initTopicDependentFeatures;
|
|
4939
4980
|
private startPrerequisiteWatcher;
|
|
4940
4981
|
/**
|
package/dist/index.js
CHANGED
|
@@ -852,6 +852,8 @@ var init_events = __esm({
|
|
|
852
852
|
MESSAGE_QUEUED: "message:queued",
|
|
853
853
|
/** Fired when a queued message starts processing. */
|
|
854
854
|
MESSAGE_PROCESSING: "message:processing",
|
|
855
|
+
/** Fired when a queued message is rejected (e.g. blocked by middleware). */
|
|
856
|
+
MESSAGE_FAILED: "message:failed",
|
|
855
857
|
// --- System lifecycle ---
|
|
856
858
|
/** Fired after kernel (core + plugin infrastructure) has booted. */
|
|
857
859
|
KERNEL_BOOTED: "kernel:booted",
|
|
@@ -3538,7 +3540,8 @@ var init_sse_manager = __esm({
|
|
|
3538
3540
|
BusEvent.PERMISSION_REQUEST,
|
|
3539
3541
|
BusEvent.PERMISSION_RESOLVED,
|
|
3540
3542
|
BusEvent.MESSAGE_QUEUED,
|
|
3541
|
-
BusEvent.MESSAGE_PROCESSING
|
|
3543
|
+
BusEvent.MESSAGE_PROCESSING,
|
|
3544
|
+
BusEvent.MESSAGE_FAILED
|
|
3542
3545
|
];
|
|
3543
3546
|
for (const eventName of events) {
|
|
3544
3547
|
const handler = (data) => {
|
|
@@ -3620,7 +3623,8 @@ data: ${JSON.stringify(data)}
|
|
|
3620
3623
|
BusEvent.PERMISSION_RESOLVED,
|
|
3621
3624
|
BusEvent.SESSION_UPDATED,
|
|
3622
3625
|
BusEvent.MESSAGE_QUEUED,
|
|
3623
|
-
BusEvent.MESSAGE_PROCESSING
|
|
3626
|
+
BusEvent.MESSAGE_PROCESSING,
|
|
3627
|
+
BusEvent.MESSAGE_FAILED
|
|
3624
3628
|
];
|
|
3625
3629
|
for (const res of this.sseConnections) {
|
|
3626
3630
|
const filter = res.sessionFilter;
|
|
@@ -10110,7 +10114,11 @@ var init_adapter = __esm({
|
|
|
10110
10114
|
}
|
|
10111
10115
|
return prev(method, payload, signal);
|
|
10112
10116
|
});
|
|
10113
|
-
|
|
10117
|
+
const onCommandsReady = ({ commands }) => {
|
|
10118
|
+
this.core.eventBus.off(BusEvent.SYSTEM_COMMANDS_READY, onCommandsReady);
|
|
10119
|
+
this.syncCommandsWithRetry(commands);
|
|
10120
|
+
};
|
|
10121
|
+
this.core.eventBus.on(BusEvent.SYSTEM_COMMANDS_READY, onCommandsReady);
|
|
10114
10122
|
this.bot.use((ctx, next) => {
|
|
10115
10123
|
const chatId = ctx.chat?.id ?? ctx.callbackQuery?.message?.chat?.id;
|
|
10116
10124
|
if (chatId !== this.telegramConfig.chatId) return;
|
|
@@ -10336,12 +10344,16 @@ ${p}` : p;
|
|
|
10336
10344
|
throw new Error("unreachable");
|
|
10337
10345
|
}
|
|
10338
10346
|
/**
|
|
10339
|
-
*
|
|
10340
|
-
*
|
|
10347
|
+
* Sync Telegram autocomplete commands after all plugins are ready.
|
|
10348
|
+
* Merges STATIC_COMMANDS (hardcoded system commands) with plugin commands
|
|
10349
|
+
* from the registry, deduplicating by command name. Non-critical.
|
|
10341
10350
|
*/
|
|
10342
|
-
|
|
10351
|
+
syncCommandsWithRetry(registryCommands) {
|
|
10352
|
+
const staticNames = new Set(STATIC_COMMANDS.map((c2) => c2.command));
|
|
10353
|
+
const pluginCommands = registryCommands.filter((c2) => c2.category === "plugin" && !staticNames.has(c2.name) && /^[a-z0-9_]+$/.test(c2.name)).map((c2) => ({ command: c2.name, description: c2.description.slice(0, 256) }));
|
|
10354
|
+
const allCommands = [...STATIC_COMMANDS, ...pluginCommands].slice(0, 100);
|
|
10343
10355
|
this.retryWithBackoff(
|
|
10344
|
-
() => this.bot.api.setMyCommands(
|
|
10356
|
+
() => this.bot.api.setMyCommands(allCommands, {
|
|
10345
10357
|
scope: { type: "chat", chat_id: this.telegramConfig.chatId }
|
|
10346
10358
|
}),
|
|
10347
10359
|
"setMyCommands"
|
|
@@ -12833,16 +12845,16 @@ var PromptQueue = class {
|
|
|
12833
12845
|
* immediately. Otherwise, it's buffered and the returned promise resolves
|
|
12834
12846
|
* only after the prompt finishes processing.
|
|
12835
12847
|
*/
|
|
12836
|
-
async enqueue(text3, attachments, routing, turnId, meta) {
|
|
12848
|
+
async enqueue(text3, userPrompt, attachments, routing, turnId, meta) {
|
|
12837
12849
|
if (this.processing) {
|
|
12838
12850
|
return new Promise((resolve7) => {
|
|
12839
|
-
this.queue.push({ text: text3, attachments, routing, turnId, meta, resolve: resolve7 });
|
|
12851
|
+
this.queue.push({ text: text3, userPrompt, attachments, routing, turnId, meta, resolve: resolve7 });
|
|
12840
12852
|
});
|
|
12841
12853
|
}
|
|
12842
|
-
await this.process(text3, attachments, routing, turnId, meta);
|
|
12854
|
+
await this.process(text3, userPrompt, attachments, routing, turnId, meta);
|
|
12843
12855
|
}
|
|
12844
12856
|
/** Run a single prompt through the processor, then drain the next queued item. */
|
|
12845
|
-
async process(text3, attachments, routing, turnId, meta) {
|
|
12857
|
+
async process(text3, userPrompt, attachments, routing, turnId, meta) {
|
|
12846
12858
|
this.processing = true;
|
|
12847
12859
|
this.abortController = new AbortController();
|
|
12848
12860
|
const { signal } = this.abortController;
|
|
@@ -12852,7 +12864,7 @@ var PromptQueue = class {
|
|
|
12852
12864
|
});
|
|
12853
12865
|
try {
|
|
12854
12866
|
await Promise.race([
|
|
12855
|
-
this.processor(text3, attachments, routing, turnId, meta),
|
|
12867
|
+
this.processor(text3, userPrompt, attachments, routing, turnId, meta),
|
|
12856
12868
|
new Promise((_, reject) => {
|
|
12857
12869
|
signal.addEventListener("abort", () => reject(new Error("Prompt aborted")), { once: true });
|
|
12858
12870
|
})
|
|
@@ -12873,7 +12885,7 @@ var PromptQueue = class {
|
|
|
12873
12885
|
drainNext() {
|
|
12874
12886
|
const next = this.queue.shift();
|
|
12875
12887
|
if (next) {
|
|
12876
|
-
this.process(next.text, next.attachments, next.routing, next.turnId, next.meta).then(next.resolve);
|
|
12888
|
+
this.process(next.text, next.userPrompt, next.attachments, next.routing, next.turnId, next.meta).then(next.resolve);
|
|
12877
12889
|
}
|
|
12878
12890
|
}
|
|
12879
12891
|
/**
|
|
@@ -12895,6 +12907,13 @@ var PromptQueue = class {
|
|
|
12895
12907
|
get isProcessing() {
|
|
12896
12908
|
return this.processing;
|
|
12897
12909
|
}
|
|
12910
|
+
/** Snapshot of queued (not yet processing) items — used for queue inspection by callers. */
|
|
12911
|
+
get pendingItems() {
|
|
12912
|
+
return this.queue.map((item) => ({
|
|
12913
|
+
userPrompt: item.userPrompt,
|
|
12914
|
+
turnId: item.turnId
|
|
12915
|
+
}));
|
|
12916
|
+
}
|
|
12898
12917
|
};
|
|
12899
12918
|
|
|
12900
12919
|
// src/core/sessions/permission-gate.ts
|
|
@@ -12976,17 +12995,31 @@ import * as fs8 from "fs";
|
|
|
12976
12995
|
|
|
12977
12996
|
// src/core/sessions/turn-context.ts
|
|
12978
12997
|
import { nanoid } from "nanoid";
|
|
12979
|
-
function
|
|
12998
|
+
function extractSender(meta) {
|
|
12999
|
+
const identity = meta?.identity;
|
|
13000
|
+
if (!identity || !identity.userId || !identity.identityId) return null;
|
|
12980
13001
|
return {
|
|
12981
|
-
|
|
12982
|
-
|
|
12983
|
-
|
|
13002
|
+
userId: identity.userId,
|
|
13003
|
+
identityId: identity.identityId,
|
|
13004
|
+
displayName: identity.displayName,
|
|
13005
|
+
username: identity.username
|
|
12984
13006
|
};
|
|
12985
13007
|
}
|
|
12986
13008
|
function getEffectiveTarget(ctx) {
|
|
12987
13009
|
if (ctx.responseAdapterId === null) return null;
|
|
12988
13010
|
return ctx.responseAdapterId ?? ctx.sourceAdapterId;
|
|
12989
13011
|
}
|
|
13012
|
+
function createTurnContext(sourceAdapterId, responseAdapterId, turnId, userPrompt, finalPrompt, attachments, meta) {
|
|
13013
|
+
return {
|
|
13014
|
+
turnId: turnId ?? nanoid(8),
|
|
13015
|
+
sourceAdapterId,
|
|
13016
|
+
responseAdapterId,
|
|
13017
|
+
userPrompt,
|
|
13018
|
+
finalPrompt,
|
|
13019
|
+
attachments,
|
|
13020
|
+
meta
|
|
13021
|
+
};
|
|
13022
|
+
}
|
|
12990
13023
|
var SYSTEM_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
12991
13024
|
"session_end",
|
|
12992
13025
|
"system_message",
|
|
@@ -13081,7 +13114,7 @@ var Session = class extends TypedEmitter {
|
|
|
13081
13114
|
this.log = createSessionLogger(this.id, moduleLog);
|
|
13082
13115
|
this.log.info({ agentName: this.agentName }, "Session created");
|
|
13083
13116
|
this.queue = new PromptQueue(
|
|
13084
|
-
(text3, attachments, routing, turnId, meta) => this.processPrompt(text3, attachments, routing, turnId, meta),
|
|
13117
|
+
(text3, userPrompt, attachments, routing, turnId, meta) => this.processPrompt(text3, userPrompt, attachments, routing, turnId, meta),
|
|
13085
13118
|
(err) => {
|
|
13086
13119
|
this.log.error({ err }, "Prompt execution failed");
|
|
13087
13120
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -13161,6 +13194,10 @@ var Session = class extends TypedEmitter {
|
|
|
13161
13194
|
get promptRunning() {
|
|
13162
13195
|
return this.queue.isProcessing;
|
|
13163
13196
|
}
|
|
13197
|
+
/** Snapshot of queued (not yet processing) items — for inspection by API consumers. */
|
|
13198
|
+
get queueItems() {
|
|
13199
|
+
return this.queue.pendingItems;
|
|
13200
|
+
}
|
|
13164
13201
|
// --- Context Injection ---
|
|
13165
13202
|
/** Store context markdown to be prepended to the next prompt (used for session resume with history). */
|
|
13166
13203
|
setContext(markdown) {
|
|
@@ -13183,22 +13220,28 @@ var Session = class extends TypedEmitter {
|
|
|
13183
13220
|
async enqueuePrompt(text3, attachments, routing, externalTurnId, meta) {
|
|
13184
13221
|
const turnId = externalTurnId ?? nanoid2(8);
|
|
13185
13222
|
const turnMeta = meta ?? { turnId };
|
|
13223
|
+
const userPrompt = text3;
|
|
13186
13224
|
if (this.middlewareChain) {
|
|
13187
13225
|
const payload = { text: text3, attachments, sessionId: this.id, sourceAdapterId: routing?.sourceAdapterId, meta: turnMeta };
|
|
13188
13226
|
const result = await this.middlewareChain.execute(Hook.AGENT_BEFORE_PROMPT, payload, async (p) => p);
|
|
13189
|
-
if (!result)
|
|
13227
|
+
if (!result) throw new Error("PROMPT_BLOCKED");
|
|
13190
13228
|
text3 = result.text;
|
|
13191
13229
|
attachments = result.attachments;
|
|
13192
13230
|
}
|
|
13193
|
-
await this.queue.enqueue(text3, attachments, routing, turnId, turnMeta);
|
|
13231
|
+
await this.queue.enqueue(text3, userPrompt, attachments, routing, turnId, turnMeta);
|
|
13194
13232
|
return turnId;
|
|
13195
13233
|
}
|
|
13196
|
-
async processPrompt(text3, attachments, routing, turnId, meta) {
|
|
13234
|
+
async processPrompt(text3, userPrompt, attachments, routing, turnId, meta) {
|
|
13197
13235
|
if (this._status === "finished") return;
|
|
13198
13236
|
this.activeTurnContext = createTurnContext(
|
|
13199
13237
|
routing?.sourceAdapterId ?? this.channelId,
|
|
13200
13238
|
routing?.responseAdapterId,
|
|
13201
|
-
turnId
|
|
13239
|
+
turnId,
|
|
13240
|
+
userPrompt,
|
|
13241
|
+
text3,
|
|
13242
|
+
// finalPrompt (after middleware transformations)
|
|
13243
|
+
attachments,
|
|
13244
|
+
meta
|
|
13202
13245
|
);
|
|
13203
13246
|
this.emit(SessionEv.TURN_STARTED, this.activeTurnContext);
|
|
13204
13247
|
this.promptCount++;
|
|
@@ -13249,7 +13292,16 @@ ${text3}`;
|
|
|
13249
13292
|
this.agentInstance.on(SessionEv.AGENT_EVENT, afterEventListener);
|
|
13250
13293
|
}
|
|
13251
13294
|
if (this.middlewareChain) {
|
|
13252
|
-
this.middlewareChain.execute(Hook.TURN_START, {
|
|
13295
|
+
this.middlewareChain.execute(Hook.TURN_START, {
|
|
13296
|
+
sessionId: this.id,
|
|
13297
|
+
promptText: processed.text,
|
|
13298
|
+
promptNumber: this.promptCount,
|
|
13299
|
+
turnId: this.activeTurnContext?.turnId ?? turnId ?? "",
|
|
13300
|
+
meta,
|
|
13301
|
+
userPrompt: this.activeTurnContext?.userPrompt,
|
|
13302
|
+
sourceAdapterId: this.activeTurnContext?.sourceAdapterId,
|
|
13303
|
+
responseAdapterId: this.activeTurnContext?.responseAdapterId
|
|
13304
|
+
}, async (p) => p).catch(() => {
|
|
13253
13305
|
});
|
|
13254
13306
|
}
|
|
13255
13307
|
let stopReason = "end_turn";
|
|
@@ -14418,7 +14470,7 @@ var SessionBridge = class {
|
|
|
14418
14470
|
if (this.shouldForward(event)) {
|
|
14419
14471
|
this.dispatchAgentEvent(event);
|
|
14420
14472
|
} else {
|
|
14421
|
-
this.deps.eventBus?.emit(BusEvent.AGENT_EVENT, { sessionId: this.session.id, event });
|
|
14473
|
+
this.deps.eventBus?.emit(BusEvent.AGENT_EVENT, { sessionId: this.session.id, turnId: "", event });
|
|
14422
14474
|
}
|
|
14423
14475
|
});
|
|
14424
14476
|
if (!this.session.agentInstance.onPermissionRequest || this.session.agentInstance.onPermissionRequest.__bridgeId === void 0) {
|
|
@@ -14471,14 +14523,16 @@ var SessionBridge = class {
|
|
|
14471
14523
|
this.deps.sessionManager.patchRecord(this.session.id, { currentPromptCount: count });
|
|
14472
14524
|
});
|
|
14473
14525
|
this.listen(this.session, SessionEv.TURN_STARTED, (ctx) => {
|
|
14474
|
-
|
|
14475
|
-
this.
|
|
14476
|
-
|
|
14477
|
-
|
|
14478
|
-
|
|
14479
|
-
|
|
14480
|
-
|
|
14481
|
-
|
|
14526
|
+
this.deps.eventBus?.emit(BusEvent.MESSAGE_PROCESSING, {
|
|
14527
|
+
sessionId: this.session.id,
|
|
14528
|
+
turnId: ctx.turnId,
|
|
14529
|
+
sourceAdapterId: ctx.sourceAdapterId,
|
|
14530
|
+
userPrompt: ctx.userPrompt,
|
|
14531
|
+
finalPrompt: ctx.finalPrompt,
|
|
14532
|
+
attachments: ctx.attachments,
|
|
14533
|
+
sender: extractSender(ctx.meta),
|
|
14534
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
14535
|
+
});
|
|
14482
14536
|
});
|
|
14483
14537
|
if (this.session.latestCommands !== null) {
|
|
14484
14538
|
this.session.emit(SessionEv.AGENT_EVENT, { type: "commands_update", commands: this.session.latestCommands });
|
|
@@ -14644,6 +14698,7 @@ var SessionBridge = class {
|
|
|
14644
14698
|
}
|
|
14645
14699
|
this.deps.eventBus?.emit(BusEvent.AGENT_EVENT, {
|
|
14646
14700
|
sessionId: this.session.id,
|
|
14701
|
+
turnId: this.session.activeTurnContext?.turnId ?? "",
|
|
14647
14702
|
event
|
|
14648
14703
|
});
|
|
14649
14704
|
return outgoing;
|
|
@@ -14844,6 +14899,7 @@ var SessionFactory = class {
|
|
|
14844
14899
|
const failedSessionId = createParams.existingSessionId ?? `failed-${Date.now()}`;
|
|
14845
14900
|
this.eventBus.emit(BusEvent.AGENT_EVENT, {
|
|
14846
14901
|
sessionId: failedSessionId,
|
|
14902
|
+
turnId: "",
|
|
14847
14903
|
event: guidance
|
|
14848
14904
|
});
|
|
14849
14905
|
throw err;
|
|
@@ -15393,7 +15449,7 @@ var AgentSwitchHandler = class {
|
|
|
15393
15449
|
message: `Switching from ${fromAgent} to ${toAgent}...`
|
|
15394
15450
|
};
|
|
15395
15451
|
session.emit(SessionEv.AGENT_EVENT, startEvent);
|
|
15396
|
-
eventBus.emit(BusEvent.AGENT_EVENT, { sessionId, event: startEvent });
|
|
15452
|
+
eventBus.emit(BusEvent.AGENT_EVENT, { sessionId, turnId: "", event: startEvent });
|
|
15397
15453
|
eventBus.emit(BusEvent.SESSION_AGENT_SWITCH, {
|
|
15398
15454
|
sessionId,
|
|
15399
15455
|
fromAgent,
|
|
@@ -15456,7 +15512,7 @@ var AgentSwitchHandler = class {
|
|
|
15456
15512
|
message: resumed ? `Switched to ${toAgent} (resumed previous session).` : `Switched to ${toAgent} (new session).`
|
|
15457
15513
|
};
|
|
15458
15514
|
session.emit(SessionEv.AGENT_EVENT, successEvent);
|
|
15459
|
-
eventBus.emit(BusEvent.AGENT_EVENT, { sessionId, event: successEvent });
|
|
15515
|
+
eventBus.emit(BusEvent.AGENT_EVENT, { sessionId, turnId: "", event: successEvent });
|
|
15460
15516
|
eventBus.emit(BusEvent.SESSION_AGENT_SWITCH, {
|
|
15461
15517
|
sessionId,
|
|
15462
15518
|
fromAgent,
|
|
@@ -15471,7 +15527,7 @@ var AgentSwitchHandler = class {
|
|
|
15471
15527
|
message: `Failed to switch to ${toAgent}: ${errorMessage}`
|
|
15472
15528
|
};
|
|
15473
15529
|
session.emit(SessionEv.AGENT_EVENT, failedEvent);
|
|
15474
|
-
eventBus.emit(BusEvent.AGENT_EVENT, { sessionId, event: failedEvent });
|
|
15530
|
+
eventBus.emit(BusEvent.AGENT_EVENT, { sessionId, turnId: "", event: failedEvent });
|
|
15475
15531
|
eventBus.emit(BusEvent.SESSION_AGENT_SWITCH, {
|
|
15476
15532
|
sessionId,
|
|
15477
15533
|
fromAgent,
|
|
@@ -17567,9 +17623,6 @@ var OpenACPCore = class {
|
|
|
17567
17623
|
}
|
|
17568
17624
|
return;
|
|
17569
17625
|
}
|
|
17570
|
-
this.sessionManager.patchRecord(session.id, {
|
|
17571
|
-
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17572
|
-
});
|
|
17573
17626
|
let text3 = message.text;
|
|
17574
17627
|
if (this.assistantManager?.isAssistant(session.id)) {
|
|
17575
17628
|
const pending = this.assistantManager.consumePendingSystemPrompt(message.channelId);
|
|
@@ -17582,38 +17635,56 @@ User message:
|
|
|
17582
17635
|
${text3}`;
|
|
17583
17636
|
}
|
|
17584
17637
|
}
|
|
17585
|
-
const sourceAdapterId = message.routing?.sourceAdapterId ?? message.channelId;
|
|
17586
|
-
const routing = sourceAdapterId !== message.routing?.sourceAdapterId ? { ...message.routing, sourceAdapterId } : message.routing;
|
|
17587
17638
|
const enrichedMeta = message.meta ?? meta;
|
|
17588
|
-
|
|
17589
|
-
|
|
17639
|
+
await this._dispatchToSession(session, text3, message.attachments, {
|
|
17640
|
+
sourceAdapterId: message.routing?.sourceAdapterId ?? message.channelId,
|
|
17641
|
+
responseAdapterId: message.routing?.responseAdapterId
|
|
17642
|
+
}, turnId, enrichedMeta);
|
|
17643
|
+
}
|
|
17644
|
+
/**
|
|
17645
|
+
* Shared dispatch path for sending a prompt to a session.
|
|
17646
|
+
* Called by both handleMessage (Telegram) and handleMessageInSession (SSE/API)
|
|
17647
|
+
* after their respective middleware/enrichment steps.
|
|
17648
|
+
*/
|
|
17649
|
+
async _dispatchToSession(session, text3, attachments, routing, turnId, meta) {
|
|
17650
|
+
this.sessionManager.patchRecord(session.id, {
|
|
17651
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17652
|
+
});
|
|
17653
|
+
this.eventBus.emit(BusEvent.MESSAGE_QUEUED, {
|
|
17654
|
+
sessionId: session.id,
|
|
17655
|
+
turnId,
|
|
17656
|
+
text: text3,
|
|
17657
|
+
sourceAdapterId: routing.sourceAdapterId,
|
|
17658
|
+
attachments,
|
|
17659
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17660
|
+
queueDepth: session.queueDepth + 1,
|
|
17661
|
+
sender: extractSender(meta)
|
|
17662
|
+
});
|
|
17663
|
+
session.enqueuePrompt(text3, attachments, routing, turnId, meta).catch((err) => {
|
|
17664
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
17665
|
+
log16.warn({ err, sessionId: session.id, turnId, reason }, "enqueuePrompt failed \u2014 emitting message:failed");
|
|
17666
|
+
this.eventBus.emit(BusEvent.MESSAGE_FAILED, {
|
|
17590
17667
|
sessionId: session.id,
|
|
17591
17668
|
turnId,
|
|
17592
|
-
|
|
17593
|
-
sourceAdapterId,
|
|
17594
|
-
attachments: message.attachments,
|
|
17595
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17596
|
-
queueDepth: session.queueDepth
|
|
17669
|
+
reason
|
|
17597
17670
|
});
|
|
17598
|
-
|
|
17599
|
-
} else {
|
|
17600
|
-
await session.enqueuePrompt(text3, message.attachments, routing, turnId, enrichedMeta);
|
|
17601
|
-
}
|
|
17671
|
+
});
|
|
17602
17672
|
}
|
|
17603
17673
|
/**
|
|
17604
17674
|
* Send a message to a known session, running the full message:incoming → agent:beforePrompt
|
|
17605
17675
|
* middleware chain (same as handleMessage) but without the threadId-based session lookup.
|
|
17606
17676
|
*
|
|
17607
|
-
* Used by channels that already hold a direct session reference (e.g. SSE adapter),
|
|
17608
|
-
* looking up by channelId+threadId is unreliable (API sessions may have no threadId).
|
|
17677
|
+
* Used by channels that already hold a direct session reference (e.g. SSE adapter, api-server),
|
|
17678
|
+
* where looking up by channelId+threadId is unreliable (API sessions may have no threadId).
|
|
17609
17679
|
*
|
|
17610
17680
|
* @param session The target session — caller is responsible for validating its status.
|
|
17611
17681
|
* @param message Sender context and message content.
|
|
17612
17682
|
* @param initialMeta Optional adapter-specific context to seed the TurnMeta bag
|
|
17613
17683
|
* (e.g. channelUser with display name/username).
|
|
17684
|
+
* @param options Optional turnId override and response routing.
|
|
17614
17685
|
*/
|
|
17615
|
-
async handleMessageInSession(session, message, initialMeta) {
|
|
17616
|
-
const turnId = nanoid3(8);
|
|
17686
|
+
async handleMessageInSession(session, message, initialMeta, options) {
|
|
17687
|
+
const turnId = options?.externalTurnId ?? nanoid3(8);
|
|
17617
17688
|
const meta = { turnId, ...initialMeta };
|
|
17618
17689
|
let text3 = message.text;
|
|
17619
17690
|
let { attachments } = message;
|
|
@@ -17632,13 +17703,17 @@ ${text3}`;
|
|
|
17632
17703
|
payload,
|
|
17633
17704
|
async (p) => p
|
|
17634
17705
|
);
|
|
17635
|
-
if (!result) return;
|
|
17706
|
+
if (!result) return { turnId, queueDepth: session.queueDepth };
|
|
17636
17707
|
text3 = result.text;
|
|
17637
17708
|
attachments = result.attachments;
|
|
17638
17709
|
enrichedMeta = result.meta ?? meta;
|
|
17639
17710
|
}
|
|
17640
|
-
const routing = {
|
|
17641
|
-
|
|
17711
|
+
const routing = {
|
|
17712
|
+
sourceAdapterId: message.channelId,
|
|
17713
|
+
responseAdapterId: options?.responseAdapterId
|
|
17714
|
+
};
|
|
17715
|
+
await this._dispatchToSession(session, text3, attachments, routing, turnId, enrichedMeta);
|
|
17716
|
+
return { turnId, queueDepth: session.queueDepth };
|
|
17642
17717
|
}
|
|
17643
17718
|
// --- Unified Session Creation Pipeline ---
|
|
17644
17719
|
/**
|
|
@@ -17750,7 +17825,7 @@ ${text3}`;
|
|
|
17750
17825
|
} else if (processedEvent.type === "error") {
|
|
17751
17826
|
session.fail(processedEvent.message);
|
|
17752
17827
|
}
|
|
17753
|
-
this.eventBus.emit(BusEvent.AGENT_EVENT, { sessionId: session.id, event: processedEvent });
|
|
17828
|
+
this.eventBus.emit(BusEvent.AGENT_EVENT, { sessionId: session.id, turnId: session.activeTurnContext?.turnId ?? "", event: processedEvent });
|
|
17754
17829
|
});
|
|
17755
17830
|
session.on(SessionEv.STATUS_CHANGE, (_from, to) => {
|
|
17756
17831
|
this.sessionManager.patchRecord(session.id, {
|
|
@@ -17762,6 +17837,18 @@ ${text3}`;
|
|
|
17762
17837
|
session.on(SessionEv.PROMPT_COUNT_CHANGED, (count) => {
|
|
17763
17838
|
this.sessionManager.patchRecord(session.id, { currentPromptCount: count });
|
|
17764
17839
|
});
|
|
17840
|
+
session.on(SessionEv.TURN_STARTED, (ctx) => {
|
|
17841
|
+
this.eventBus.emit(BusEvent.MESSAGE_PROCESSING, {
|
|
17842
|
+
sessionId: session.id,
|
|
17843
|
+
turnId: ctx.turnId,
|
|
17844
|
+
sourceAdapterId: ctx.sourceAdapterId,
|
|
17845
|
+
userPrompt: ctx.userPrompt,
|
|
17846
|
+
finalPrompt: ctx.finalPrompt,
|
|
17847
|
+
attachments: ctx.attachments,
|
|
17848
|
+
sender: extractSender(ctx.meta),
|
|
17849
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
17850
|
+
});
|
|
17851
|
+
});
|
|
17765
17852
|
}
|
|
17766
17853
|
this.sessionFactory.wireSideEffects(session, {
|
|
17767
17854
|
eventBus: this.eventBus,
|