@openacp/cli 2026.327.2 → 2026.327.5
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/{adapter-LC2QSDAS.js → adapter-JQFQ3JAO.js} +3 -3
- package/dist/{adapter-Y55NXX6I.js → adapter-UORRGHNH.js} +32 -8
- package/dist/adapter-UORRGHNH.js.map +1 -0
- package/dist/{chunk-TRXBJEZ5.js → chunk-32LVIEPW.js} +49 -19
- package/dist/chunk-32LVIEPW.js.map +1 -0
- package/dist/{chunk-UMT7RU77.js → chunk-HRKAXFWR.js} +2 -2
- package/dist/{chunk-36YQ44D7.js → chunk-P2G275VD.js} +2 -2
- package/dist/{chunk-HUWOFP2H.js → chunk-S3ZGPPXY.js} +3 -3
- package/dist/{chunk-LP45RCA4.js → chunk-XWDW3XBE.js} +338 -414
- package/dist/chunk-XWDW3XBE.js.map +1 -0
- package/dist/{chunk-3ASUU6WW.js → chunk-ZNSO2QVC.js} +2 -2
- package/dist/cli.js +60 -40
- package/dist/cli.js.map +1 -1
- package/dist/{config-editor-3IKBPZA7.js → config-editor-7PKW42GZ.js} +2 -2
- package/dist/{core-plugins-ROU4GPLT.js → core-plugins-Y5US6RED.js} +4 -4
- package/dist/index.d.ts +92 -93
- package/dist/index.js +35 -5
- package/dist/index.js.map +1 -1
- package/dist/{main-UVTZ46WP.js → main-3GF3EQTE.js} +8 -8
- package/dist/plugin-installer-QVJP6VKV.js +42 -0
- package/dist/plugin-installer-QVJP6VKV.js.map +1 -0
- package/dist/{setup-EYAFK2WI.js → setup-A7VPW46C.js} +8 -6
- package/dist/setup-A7VPW46C.js.map +1 -0
- package/dist/{slack-37ZWBDUI.js → slack-2XNWBOWH.js} +2 -2
- package/dist/{telegram-2ZCCCZIY.js → telegram-E65IWFBW.js} +2 -2
- package/package.json +1 -1
- package/dist/adapter-Y55NXX6I.js.map +0 -1
- package/dist/chunk-LP45RCA4.js.map +0 -1
- package/dist/chunk-TRXBJEZ5.js.map +0 -1
- package/dist/plugin-installer-GQ2P3Q3E.js +0 -23
- package/dist/plugin-installer-GQ2P3Q3E.js.map +0 -1
- package/dist/setup-EYAFK2WI.js.map +0 -1
- /package/dist/{adapter-LC2QSDAS.js.map → adapter-JQFQ3JAO.js.map} +0 -0
- /package/dist/{chunk-UMT7RU77.js.map → chunk-HRKAXFWR.js.map} +0 -0
- /package/dist/{chunk-36YQ44D7.js.map → chunk-P2G275VD.js.map} +0 -0
- /package/dist/{chunk-HUWOFP2H.js.map → chunk-S3ZGPPXY.js.map} +0 -0
- /package/dist/{chunk-3ASUU6WW.js.map → chunk-ZNSO2QVC.js.map} +0 -0
- /package/dist/{config-editor-3IKBPZA7.js.map → config-editor-7PKW42GZ.js.map} +0 -0
- /package/dist/{core-plugins-ROU4GPLT.js.map → core-plugins-Y5US6RED.js.map} +0 -0
- /package/dist/{main-UVTZ46WP.js.map → main-3GF3EQTE.js.map} +0 -0
- /package/dist/{slack-37ZWBDUI.js.map → slack-2XNWBOWH.js.map} +0 -0
- /package/dist/{telegram-2ZCCCZIY.js.map → telegram-E65IWFBW.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runConfigEditor
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HRKAXFWR.js";
|
|
4
4
|
import "./chunk-PPSMUECX.js";
|
|
5
5
|
import "./chunk-QVMEF6FB.js";
|
|
6
6
|
import "./chunk-XMMAGAT4.js";
|
|
@@ -8,4 +8,4 @@ import "./chunk-VUNV25KB.js";
|
|
|
8
8
|
export {
|
|
9
9
|
runConfigEditor
|
|
10
10
|
};
|
|
11
|
-
//# sourceMappingURL=config-editor-
|
|
11
|
+
//# sourceMappingURL=config-editor-7PKW42GZ.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
corePlugins
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-S3ZGPPXY.js";
|
|
4
|
+
import "./chunk-P2G275VD.js";
|
|
5
|
+
import "./chunk-ZNSO2QVC.js";
|
|
6
6
|
import "./chunk-SNPYTMPR.js";
|
|
7
7
|
import "./chunk-KMMEFXIE.js";
|
|
8
8
|
import "./chunk-4GMLGCF2.js";
|
|
@@ -20,4 +20,4 @@ import "./chunk-VUNV25KB.js";
|
|
|
20
20
|
export {
|
|
21
21
|
corePlugins
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=core-plugins-
|
|
23
|
+
//# sourceMappingURL=core-plugins-Y5US6RED.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -2410,6 +2410,94 @@ declare class OpenACPCore {
|
|
|
2410
2410
|
createBridge(session: Session, adapter: IChannelAdapter): SessionBridge;
|
|
2411
2411
|
}
|
|
2412
2412
|
|
|
2413
|
+
interface RegisteredCommand extends CommandDef {
|
|
2414
|
+
/** Scope extracted from pluginName, e.g. '@openacp/speech' → 'speech' */
|
|
2415
|
+
scope?: string;
|
|
2416
|
+
}
|
|
2417
|
+
/**
|
|
2418
|
+
* Central command registry with namespace resolution and adapter-specific overrides.
|
|
2419
|
+
*
|
|
2420
|
+
* Namespace rules:
|
|
2421
|
+
* - System commands always own the short name.
|
|
2422
|
+
* - Among plugins, the first to register wins the short name.
|
|
2423
|
+
* - Every plugin command also gets a qualified name: `scope:name`.
|
|
2424
|
+
* - Adapter plugins (@openacp/telegram, @openacp/discord, @openacp/slack)
|
|
2425
|
+
* registering a command that already exists → stored as an override
|
|
2426
|
+
* keyed by `channelId:commandName`, used when channelId matches.
|
|
2427
|
+
*/
|
|
2428
|
+
declare class CommandRegistry {
|
|
2429
|
+
/** Main registry: short names + qualified names → RegisteredCommand */
|
|
2430
|
+
private commands;
|
|
2431
|
+
/** Adapter-specific overrides: `channelId:commandName` → RegisteredCommand */
|
|
2432
|
+
private overrides;
|
|
2433
|
+
private static ADAPTER_SCOPES;
|
|
2434
|
+
/**
|
|
2435
|
+
* Register a command definition.
|
|
2436
|
+
* @param def - Command definition
|
|
2437
|
+
* @param pluginName - Plugin that owns the command (set automatically by PluginContext)
|
|
2438
|
+
*/
|
|
2439
|
+
register(def: CommandDef, pluginName?: string): void;
|
|
2440
|
+
/** Retrieve a command by name (short or qualified). */
|
|
2441
|
+
get(name: string): RegisteredCommand | undefined;
|
|
2442
|
+
/** Remove a command by short name. Also removes its qualified name entry. */
|
|
2443
|
+
unregister(name: string): void;
|
|
2444
|
+
/** Remove all commands registered by a given plugin. */
|
|
2445
|
+
unregisterByPlugin(pluginName: string): void;
|
|
2446
|
+
/** Return all unique commands (deduplicated — each command appears once). */
|
|
2447
|
+
getAll(): RegisteredCommand[];
|
|
2448
|
+
/** Filter commands by category. */
|
|
2449
|
+
getByCategory(category: 'system' | 'plugin'): RegisteredCommand[];
|
|
2450
|
+
/**
|
|
2451
|
+
* Parse and execute a command string.
|
|
2452
|
+
* @param commandString - Full command string, e.g. "/greet hello world"
|
|
2453
|
+
* @param baseArgs - Base arguments (channelId, userId, etc.)
|
|
2454
|
+
* @returns CommandResponse
|
|
2455
|
+
*/
|
|
2456
|
+
execute(commandString: string, baseArgs: CommandArgs): Promise<CommandResponse>;
|
|
2457
|
+
/** Extract scope from plugin name: '@openacp/speech' → 'speech', 'my-plugin' → 'my-plugin' */
|
|
2458
|
+
static extractScope(pluginName: string): string;
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
interface CheckResult {
|
|
2462
|
+
status: "pass" | "warn" | "fail";
|
|
2463
|
+
message: string;
|
|
2464
|
+
fixable?: boolean;
|
|
2465
|
+
fixRisk?: "safe" | "risky";
|
|
2466
|
+
fix?: () => Promise<FixResult>;
|
|
2467
|
+
}
|
|
2468
|
+
interface FixResult {
|
|
2469
|
+
success: boolean;
|
|
2470
|
+
message: string;
|
|
2471
|
+
}
|
|
2472
|
+
interface DoctorReport {
|
|
2473
|
+
categories: CategoryResult[];
|
|
2474
|
+
summary: {
|
|
2475
|
+
passed: number;
|
|
2476
|
+
warnings: number;
|
|
2477
|
+
failed: number;
|
|
2478
|
+
fixed: number;
|
|
2479
|
+
};
|
|
2480
|
+
pendingFixes: PendingFix[];
|
|
2481
|
+
}
|
|
2482
|
+
interface CategoryResult {
|
|
2483
|
+
name: string;
|
|
2484
|
+
results: CheckResult[];
|
|
2485
|
+
}
|
|
2486
|
+
interface PendingFix {
|
|
2487
|
+
category: string;
|
|
2488
|
+
message: string;
|
|
2489
|
+
fix: () => Promise<FixResult>;
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
declare class DoctorEngine {
|
|
2493
|
+
private dryRun;
|
|
2494
|
+
constructor(options?: {
|
|
2495
|
+
dryRun?: boolean;
|
|
2496
|
+
});
|
|
2497
|
+
runAll(): Promise<DoctorReport>;
|
|
2498
|
+
private buildContext;
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2413
2501
|
interface ConfigFieldDef {
|
|
2414
2502
|
path: string;
|
|
2415
2503
|
displayName: string;
|
|
@@ -2617,7 +2705,7 @@ interface ToolUpdateMeta extends ToolCallMeta {
|
|
|
2617
2705
|
|
|
2618
2706
|
interface RenderedMessage<TComponents = unknown> {
|
|
2619
2707
|
body: string;
|
|
2620
|
-
format:
|
|
2708
|
+
format: "html" | "markdown" | "plain" | "structured";
|
|
2621
2709
|
attachments?: RenderedAttachment[];
|
|
2622
2710
|
components?: TComponents;
|
|
2623
2711
|
}
|
|
@@ -2630,7 +2718,7 @@ interface RenderedAction {
|
|
|
2630
2718
|
isAllow?: boolean;
|
|
2631
2719
|
}
|
|
2632
2720
|
interface RenderedAttachment {
|
|
2633
|
-
type:
|
|
2721
|
+
type: "file" | "image" | "audio";
|
|
2634
2722
|
data: Buffer | string;
|
|
2635
2723
|
mimeType?: string;
|
|
2636
2724
|
filename?: string;
|
|
@@ -2639,7 +2727,7 @@ interface IRenderer {
|
|
|
2639
2727
|
renderText(content: OutgoingMessage, verbosity: DisplayVerbosity): RenderedMessage;
|
|
2640
2728
|
renderToolCall(content: OutgoingMessage, verbosity: DisplayVerbosity): RenderedMessage;
|
|
2641
2729
|
renderToolUpdate(content: OutgoingMessage, verbosity: DisplayVerbosity): RenderedMessage;
|
|
2642
|
-
renderPlan(content: OutgoingMessage
|
|
2730
|
+
renderPlan(content: OutgoingMessage): RenderedMessage;
|
|
2643
2731
|
renderUsage(content: OutgoingMessage, verbosity: DisplayVerbosity): RenderedMessage;
|
|
2644
2732
|
renderPermission(request: PermissionRequest): RenderedPermission;
|
|
2645
2733
|
renderError(content: OutgoingMessage): RenderedMessage;
|
|
@@ -2661,7 +2749,7 @@ declare class BaseRenderer implements IRenderer {
|
|
|
2661
2749
|
renderText(content: OutgoingMessage): RenderedMessage;
|
|
2662
2750
|
renderToolCall(content: OutgoingMessage, verbosity: DisplayVerbosity): RenderedMessage;
|
|
2663
2751
|
renderToolUpdate(content: OutgoingMessage, verbosity: DisplayVerbosity): RenderedMessage;
|
|
2664
|
-
renderPlan(content: OutgoingMessage
|
|
2752
|
+
renderPlan(content: OutgoingMessage): RenderedMessage;
|
|
2665
2753
|
renderUsage(content: OutgoingMessage, verbosity: DisplayVerbosity): RenderedMessage;
|
|
2666
2754
|
renderPermission(request: PermissionRequest): RenderedPermission;
|
|
2667
2755
|
renderError(content: OutgoingMessage): RenderedMessage;
|
|
@@ -2855,94 +2943,6 @@ declare function resolveToolIcon(tool: {
|
|
|
2855
2943
|
kind?: string;
|
|
2856
2944
|
}): string;
|
|
2857
2945
|
|
|
2858
|
-
interface RegisteredCommand extends CommandDef {
|
|
2859
|
-
/** Scope extracted from pluginName, e.g. '@openacp/speech' → 'speech' */
|
|
2860
|
-
scope?: string;
|
|
2861
|
-
}
|
|
2862
|
-
/**
|
|
2863
|
-
* Central command registry with namespace resolution and adapter-specific overrides.
|
|
2864
|
-
*
|
|
2865
|
-
* Namespace rules:
|
|
2866
|
-
* - System commands always own the short name.
|
|
2867
|
-
* - Among plugins, the first to register wins the short name.
|
|
2868
|
-
* - Every plugin command also gets a qualified name: `scope:name`.
|
|
2869
|
-
* - Adapter plugins (@openacp/telegram, @openacp/discord, @openacp/slack)
|
|
2870
|
-
* registering a command that already exists → stored as an override
|
|
2871
|
-
* keyed by `channelId:commandName`, used when channelId matches.
|
|
2872
|
-
*/
|
|
2873
|
-
declare class CommandRegistry {
|
|
2874
|
-
/** Main registry: short names + qualified names → RegisteredCommand */
|
|
2875
|
-
private commands;
|
|
2876
|
-
/** Adapter-specific overrides: `channelId:commandName` → RegisteredCommand */
|
|
2877
|
-
private overrides;
|
|
2878
|
-
private static ADAPTER_SCOPES;
|
|
2879
|
-
/**
|
|
2880
|
-
* Register a command definition.
|
|
2881
|
-
* @param def - Command definition
|
|
2882
|
-
* @param pluginName - Plugin that owns the command (set automatically by PluginContext)
|
|
2883
|
-
*/
|
|
2884
|
-
register(def: CommandDef, pluginName?: string): void;
|
|
2885
|
-
/** Retrieve a command by name (short or qualified). */
|
|
2886
|
-
get(name: string): RegisteredCommand | undefined;
|
|
2887
|
-
/** Remove a command by short name. Also removes its qualified name entry. */
|
|
2888
|
-
unregister(name: string): void;
|
|
2889
|
-
/** Remove all commands registered by a given plugin. */
|
|
2890
|
-
unregisterByPlugin(pluginName: string): void;
|
|
2891
|
-
/** Return all unique commands (deduplicated — each command appears once). */
|
|
2892
|
-
getAll(): RegisteredCommand[];
|
|
2893
|
-
/** Filter commands by category. */
|
|
2894
|
-
getByCategory(category: 'system' | 'plugin'): RegisteredCommand[];
|
|
2895
|
-
/**
|
|
2896
|
-
* Parse and execute a command string.
|
|
2897
|
-
* @param commandString - Full command string, e.g. "/greet hello world"
|
|
2898
|
-
* @param baseArgs - Base arguments (channelId, userId, etc.)
|
|
2899
|
-
* @returns CommandResponse
|
|
2900
|
-
*/
|
|
2901
|
-
execute(commandString: string, baseArgs: CommandArgs): Promise<CommandResponse>;
|
|
2902
|
-
/** Extract scope from plugin name: '@openacp/speech' → 'speech', 'my-plugin' → 'my-plugin' */
|
|
2903
|
-
static extractScope(pluginName: string): string;
|
|
2904
|
-
}
|
|
2905
|
-
|
|
2906
|
-
interface CheckResult {
|
|
2907
|
-
status: "pass" | "warn" | "fail";
|
|
2908
|
-
message: string;
|
|
2909
|
-
fixable?: boolean;
|
|
2910
|
-
fixRisk?: "safe" | "risky";
|
|
2911
|
-
fix?: () => Promise<FixResult>;
|
|
2912
|
-
}
|
|
2913
|
-
interface FixResult {
|
|
2914
|
-
success: boolean;
|
|
2915
|
-
message: string;
|
|
2916
|
-
}
|
|
2917
|
-
interface DoctorReport {
|
|
2918
|
-
categories: CategoryResult[];
|
|
2919
|
-
summary: {
|
|
2920
|
-
passed: number;
|
|
2921
|
-
warnings: number;
|
|
2922
|
-
failed: number;
|
|
2923
|
-
fixed: number;
|
|
2924
|
-
};
|
|
2925
|
-
pendingFixes: PendingFix[];
|
|
2926
|
-
}
|
|
2927
|
-
interface CategoryResult {
|
|
2928
|
-
name: string;
|
|
2929
|
-
results: CheckResult[];
|
|
2930
|
-
}
|
|
2931
|
-
interface PendingFix {
|
|
2932
|
-
category: string;
|
|
2933
|
-
message: string;
|
|
2934
|
-
fix: () => Promise<FixResult>;
|
|
2935
|
-
}
|
|
2936
|
-
|
|
2937
|
-
declare class DoctorEngine {
|
|
2938
|
-
private dryRun;
|
|
2939
|
-
constructor(options?: {
|
|
2940
|
-
dryRun?: boolean;
|
|
2941
|
-
});
|
|
2942
|
-
runAll(): Promise<DoctorReport>;
|
|
2943
|
-
private buildContext;
|
|
2944
|
-
}
|
|
2945
|
-
|
|
2946
2946
|
/**
|
|
2947
2947
|
* OpenACP Product Guide — comprehensive reference for the AI assistant.
|
|
2948
2948
|
* The assistant reads this at runtime to answer user questions about features.
|
|
@@ -2970,7 +2970,6 @@ declare class TelegramAdapter extends MessagingAdapter {
|
|
|
2970
2970
|
private assistantTopicId;
|
|
2971
2971
|
private sendQueue;
|
|
2972
2972
|
private _sessionThreadIds;
|
|
2973
|
-
private toolTracker;
|
|
2974
2973
|
private draftManager;
|
|
2975
2974
|
private skillManager;
|
|
2976
2975
|
private fileService;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runConfigEditor
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HRKAXFWR.js";
|
|
4
4
|
import {
|
|
5
5
|
AgentInstance,
|
|
6
6
|
AgentManager,
|
|
@@ -40,9 +40,8 @@ import {
|
|
|
40
40
|
import {
|
|
41
41
|
PRODUCT_GUIDE,
|
|
42
42
|
SendQueue,
|
|
43
|
-
TelegramAdapter
|
|
44
|
-
|
|
45
|
-
} from "./chunk-LP45RCA4.js";
|
|
43
|
+
TelegramAdapter
|
|
44
|
+
} from "./chunk-XWDW3XBE.js";
|
|
46
45
|
import "./chunk-AFKX424Q.js";
|
|
47
46
|
import {
|
|
48
47
|
DoctorEngine
|
|
@@ -61,7 +60,7 @@ import {
|
|
|
61
60
|
splitMessage,
|
|
62
61
|
stripCodeFences,
|
|
63
62
|
truncateContent
|
|
64
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-32LVIEPW.js";
|
|
65
64
|
import {
|
|
66
65
|
NotificationManager
|
|
67
66
|
} from "./chunk-WXVT3AOY.js";
|
|
@@ -370,6 +369,37 @@ var DraftManager = class {
|
|
|
370
369
|
}
|
|
371
370
|
};
|
|
372
371
|
|
|
372
|
+
// src/core/adapter-primitives/primitives/tool-call-tracker.ts
|
|
373
|
+
var ToolCallTracker = class {
|
|
374
|
+
sessions = /* @__PURE__ */ new Map();
|
|
375
|
+
track(sessionId, meta, messageId) {
|
|
376
|
+
if (!this.sessions.has(sessionId)) {
|
|
377
|
+
this.sessions.set(sessionId, /* @__PURE__ */ new Map());
|
|
378
|
+
}
|
|
379
|
+
this.sessions.get(sessionId).set(meta.id, { ...meta, messageId });
|
|
380
|
+
}
|
|
381
|
+
update(sessionId, toolId, status, patch) {
|
|
382
|
+
const tool = this.sessions.get(sessionId)?.get(toolId);
|
|
383
|
+
if (!tool) return null;
|
|
384
|
+
tool.status = status;
|
|
385
|
+
if (patch?.viewerLinks) tool.viewerLinks = patch.viewerLinks;
|
|
386
|
+
if (patch?.viewerFilePath) tool.viewerFilePath = patch.viewerFilePath;
|
|
387
|
+
if (patch?.name) tool.name = patch.name;
|
|
388
|
+
if (patch?.kind) tool.kind = patch.kind;
|
|
389
|
+
return tool;
|
|
390
|
+
}
|
|
391
|
+
getActive(sessionId) {
|
|
392
|
+
const session = this.sessions.get(sessionId);
|
|
393
|
+
return session ? [...session.values()] : [];
|
|
394
|
+
}
|
|
395
|
+
clear(sessionId) {
|
|
396
|
+
this.sessions.delete(sessionId);
|
|
397
|
+
}
|
|
398
|
+
clearAll() {
|
|
399
|
+
this.sessions.clear();
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
|
|
373
403
|
// src/core/adapter-primitives/primitives/activity-tracker.ts
|
|
374
404
|
var ActivityTracker = class {
|
|
375
405
|
constructor(config) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/channel.ts","../../src/plugins/telegram/topic-manager.ts","../../src/core/adapter-primitives/stream-adapter.ts","../../src/core/adapter-primitives/primitives/draft-manager.ts","../../src/core/adapter-primitives/primitives/activity-tracker.ts"],"sourcesContent":["import type { OutgoingMessage, PermissionRequest, NotificationMessage, AgentCommand } from './types.js'\n\nexport interface ChannelConfig {\n enabled: boolean\n [key: string]: unknown\n}\n\nexport interface AdapterCapabilities {\n streaming: boolean\n richFormatting: boolean\n threads: boolean\n reactions: boolean\n fileUpload: boolean\n voice: boolean\n}\n\nexport interface IChannelAdapter {\n readonly name: string\n readonly capabilities: AdapterCapabilities\n\n start(): Promise<void>\n stop(): Promise<void>\n\n // Outgoing: core → channel\n sendMessage(sessionId: string, content: OutgoingMessage): Promise<void>\n sendPermissionRequest(sessionId: string, request: PermissionRequest): Promise<void>\n sendNotification(notification: NotificationMessage): Promise<void>\n\n // Session lifecycle on channel side\n createSessionThread(sessionId: string, name: string): Promise<string> // returns threadId\n renameSessionThread(sessionId: string, newName: string): Promise<void>\n deleteSessionThread?(sessionId: string): Promise<void>\n archiveSessionTopic?(sessionId: string): Promise<void>\n\n // Skill commands — optional\n sendSkillCommands?(sessionId: string, commands: AgentCommand[]): Promise<void>\n cleanupSkillCommands?(sessionId: string): Promise<void>\n}\n\n/**\n * Base class providing default no-op implementations for optional methods.\n * Adapters can extend this or implement IChannelAdapter directly.\n * @deprecated Use MessagingAdapter or StreamAdapter instead. Kept for backward compat during migration.\n */\nexport abstract class ChannelAdapter<TCore = unknown> implements IChannelAdapter {\n abstract readonly name: string\n readonly capabilities: AdapterCapabilities = {\n streaming: false, richFormatting: false, threads: false,\n reactions: false, fileUpload: false, voice: false,\n }\n\n constructor(public readonly core: TCore, protected config: ChannelConfig) {}\n\n abstract start(): Promise<void>\n abstract stop(): Promise<void>\n\n abstract sendMessage(sessionId: string, content: OutgoingMessage): Promise<void>\n abstract sendPermissionRequest(sessionId: string, request: PermissionRequest): Promise<void>\n abstract sendNotification(notification: NotificationMessage): Promise<void>\n\n abstract createSessionThread(sessionId: string, name: string): Promise<string>\n abstract renameSessionThread(sessionId: string, newName: string): Promise<void>\n async deleteSessionThread(_sessionId: string): Promise<void> {}\n\n async sendSkillCommands(_sessionId: string, _commands: AgentCommand[]): Promise<void> {}\n async cleanupSkillCommands(_sessionId: string): Promise<void> {}\n async archiveSessionTopic(_sessionId: string): Promise<void> {}\n}\n","import type { SessionManager } from '../../core/sessions/session-manager.js'\nimport type { IChannelAdapter } from '../../core/channel.js'\nimport type { SessionRecord } from '../../core/types.js'\nimport { createChildLogger } from '../../core/utils/log.js'\n\nconst log = createChildLogger({ module: 'topic-manager' })\n\nexport interface TopicInfo {\n sessionId: string\n topicId: number | null\n name: string | null\n status: string\n agentName: string\n lastActiveAt: string\n}\n\nexport interface DeleteTopicResult {\n ok: boolean\n needsConfirmation?: boolean\n topicId?: number | null\n session?: { id: string; name: string | null; status: string }\n error?: string\n}\n\nexport interface CleanupResult {\n deleted: string[]\n failed: { sessionId: string; error: string }[]\n}\n\ninterface SystemTopicIds {\n notificationTopicId: number | null\n assistantTopicId: number | null\n}\n\nexport class TopicManager {\n constructor(\n private sessionManager: SessionManager,\n private adapter: IChannelAdapter | null,\n private systemTopicIds: SystemTopicIds,\n ) {}\n\n listTopics(filter?: { statuses?: string[] }): TopicInfo[] {\n const records = this.sessionManager.listRecords(filter)\n return records\n .filter(r => !this.isSystemTopic(r))\n .filter(r => !filter?.statuses?.length || filter.statuses.includes(r.status))\n .map(r => ({\n sessionId: r.sessionId,\n topicId: (r.platform as Record<string, unknown>)?.topicId as number ?? null,\n name: r.name ?? null,\n status: r.status,\n agentName: r.agentName,\n lastActiveAt: r.lastActiveAt,\n }))\n }\n\n async deleteTopic(sessionId: string, options?: { confirmed?: boolean }): Promise<DeleteTopicResult> {\n const records = this.sessionManager.listRecords()\n const record = records.find(r => r.sessionId === sessionId)\n if (!record) return { ok: false, error: 'Session not found' }\n\n if (this.isSystemTopic(record)) return { ok: false, error: 'Cannot delete system topic' }\n\n const isActive = record.status === 'active' || record.status === 'initializing'\n if (isActive && !options?.confirmed) {\n return {\n ok: false,\n needsConfirmation: true,\n session: { id: record.sessionId, name: record.name ?? null, status: record.status },\n }\n }\n\n if (isActive) {\n await this.sessionManager.cancelSession(sessionId)\n }\n\n const topicId = (record.platform as Record<string, unknown>)?.topicId as number ?? null\n if (this.adapter && topicId) {\n try {\n await this.adapter.deleteSessionThread?.(sessionId)\n } catch (err) {\n log.warn({ err, sessionId, topicId }, 'Failed to delete platform thread, removing record anyway')\n }\n }\n\n await this.sessionManager.removeRecord(sessionId)\n return { ok: true, topicId }\n }\n\n async cleanup(statuses?: string[]): Promise<CleanupResult> {\n const targetStatuses = statuses?.length ? statuses : ['finished', 'error', 'cancelled']\n const records = this.sessionManager.listRecords({ statuses: targetStatuses })\n const targets = records\n .filter(r => !this.isSystemTopic(r))\n .filter(r => targetStatuses.includes(r.status))\n\n const deleted: string[] = []\n const failed: { sessionId: string; error: string }[] = []\n\n for (const record of targets) {\n try {\n // Cancel active/initializing sessions to prevent orphaned agent processes\n const isActive = record.status === 'active' || record.status === 'initializing'\n if (isActive) {\n await this.sessionManager.cancelSession(record.sessionId)\n }\n\n const topicId = (record.platform as Record<string, unknown>)?.topicId as number | undefined\n if (this.adapter && topicId) {\n try {\n await this.adapter.deleteSessionThread?.(record.sessionId)\n } catch (err) {\n log.warn({ err, sessionId: record.sessionId }, 'Failed to delete platform thread during cleanup')\n }\n }\n await this.sessionManager.removeRecord(record.sessionId)\n deleted.push(record.sessionId)\n } catch (err) {\n failed.push({ sessionId: record.sessionId, error: err instanceof Error ? err.message : String(err) })\n }\n }\n\n return { deleted, failed }\n }\n\n private isSystemTopic(record: SessionRecord): boolean {\n const topicId = (record.platform as Record<string, unknown>)?.topicId as number | undefined\n if (!topicId) return false\n return topicId === this.systemTopicIds.notificationTopicId\n || topicId === this.systemTopicIds.assistantTopicId\n }\n}\n","import type {\n IChannelAdapter,\n AdapterCapabilities,\n} from '../channel.js'\nimport type {\n OutgoingMessage,\n PermissionRequest,\n NotificationMessage,\n} from '../types.js'\n\nexport interface StreamEvent {\n type: string\n sessionId?: string\n payload: unknown\n timestamp: number\n}\n\nexport abstract class StreamAdapter implements IChannelAdapter {\n abstract readonly name: string\n\n capabilities: AdapterCapabilities\n\n constructor(config?: Partial<AdapterCapabilities>) {\n this.capabilities = {\n streaming: true,\n richFormatting: false,\n threads: false,\n reactions: false,\n fileUpload: false,\n voice: false,\n ...config,\n }\n }\n\n async sendMessage(sessionId: string, content: OutgoingMessage): Promise<void> {\n await this.emit(sessionId, {\n type: content.type,\n sessionId,\n payload: content,\n timestamp: Date.now(),\n })\n }\n\n async sendPermissionRequest(sessionId: string, request: PermissionRequest): Promise<void> {\n await this.emit(sessionId, {\n type: 'permission_request',\n sessionId,\n payload: request,\n timestamp: Date.now(),\n })\n }\n\n async sendNotification(notification: NotificationMessage): Promise<void> {\n await this.broadcast({\n type: 'notification',\n payload: notification,\n timestamp: Date.now(),\n })\n }\n\n async createSessionThread(_sessionId: string, _name: string): Promise<string> {\n return ''\n }\n\n async renameSessionThread(sessionId: string, name: string): Promise<void> {\n await this.emit(sessionId, {\n type: 'session_rename',\n sessionId,\n payload: { name },\n timestamp: Date.now(),\n })\n }\n\n protected abstract emit(sessionId: string, event: StreamEvent): Promise<void>\n protected abstract broadcast(event: StreamEvent): Promise<void>\n abstract start(): Promise<void>\n abstract stop(): Promise<void>\n}\n","export interface DraftConfig {\n flushInterval: number\n maxLength: number\n onFlush: (sessionId: string, text: string, isEdit: boolean) => Promise<string | undefined>\n onError?: (sessionId: string, error: Error) => void\n}\n\nexport class Draft {\n private buffer = ''\n private _messageId?: string\n private firstFlushPending = false\n private flushTimer?: ReturnType<typeof setTimeout>\n private flushPromise: Promise<void> = Promise.resolve()\n\n constructor(\n private sessionId: string,\n private config: DraftConfig,\n ) {}\n\n get isEmpty(): boolean { return !this.buffer }\n get messageId(): string | undefined { return this._messageId }\n\n append(text: string): void {\n if (!text) return\n this.buffer += text\n this.scheduleFlush()\n }\n\n async finalize(): Promise<string | undefined> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer)\n this.flushTimer = undefined\n }\n await this.flushPromise\n if (this.buffer) {\n await this.flush()\n }\n return this._messageId\n }\n\n destroy(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer)\n this.flushTimer = undefined\n }\n this.buffer = ''\n }\n\n private scheduleFlush(): void {\n if (this.flushTimer) return\n this.flushTimer = setTimeout(() => {\n this.flushTimer = undefined\n this.flushPromise = this.flushPromise\n .then(() => this.flush())\n .catch(() => {})\n }, this.config.flushInterval)\n }\n\n private async flush(): Promise<void> {\n if (!this.buffer || this.firstFlushPending) return\n\n const snapshot = this.buffer\n const isEdit = !!this._messageId\n\n if (!this._messageId) {\n this.firstFlushPending = true\n }\n\n try {\n const result = await this.config.onFlush(this.sessionId, snapshot, isEdit)\n if (!isEdit && result) {\n this._messageId = result\n }\n } catch (err) {\n this.config.onError?.(this.sessionId, err instanceof Error ? err : new Error(String(err)))\n } finally {\n this.firstFlushPending = false\n }\n }\n}\n\nexport class DraftManager {\n private drafts = new Map<string, Draft>()\n\n constructor(private config: DraftConfig) {}\n\n getOrCreate(sessionId: string): Draft {\n let draft = this.drafts.get(sessionId)\n if (!draft) {\n draft = new Draft(sessionId, this.config)\n this.drafts.set(sessionId, draft)\n }\n return draft\n }\n\n async finalize(sessionId: string): Promise<void> {\n const draft = this.drafts.get(sessionId)\n if (!draft) return\n await draft.finalize()\n }\n\n async finalizeAll(): Promise<void> {\n await Promise.all([...this.drafts.values()].map(d => d.finalize()))\n }\n\n destroy(sessionId: string): void {\n const draft = this.drafts.get(sessionId)\n if (draft) {\n draft.destroy()\n this.drafts.delete(sessionId)\n }\n }\n\n destroyAll(): void {\n for (const draft of this.drafts.values()) {\n draft.destroy()\n }\n this.drafts.clear()\n }\n}\n","export interface ActivityConfig {\n thinkingRefreshInterval: number\n maxThinkingDuration: number\n}\n\nexport interface ActivityCallbacks {\n sendThinkingIndicator(): Promise<void>\n updateThinkingIndicator(): Promise<void>\n removeThinkingIndicator(): Promise<void>\n}\n\ninterface SessionState {\n callbacks: ActivityCallbacks\n refreshTimer?: ReturnType<typeof setInterval>\n startTime: number\n dismissed: boolean\n}\n\nexport class ActivityTracker {\n private sessions = new Map<string, SessionState>()\n\n constructor(private config: ActivityConfig) {}\n\n onThinkingStart(sessionId: string, callbacks: ActivityCallbacks): void {\n this.cleanup(sessionId)\n\n const state: SessionState = {\n callbacks,\n startTime: Date.now(),\n dismissed: false,\n }\n this.sessions.set(sessionId, state)\n\n setTimeout(() => {\n if (state.dismissed) return\n callbacks.sendThinkingIndicator().catch(() => {})\n this.startRefresh(sessionId, state)\n }, 0)\n }\n\n onTextStart(sessionId: string): void {\n const state = this.sessions.get(sessionId)\n if (!state || state.dismissed) return\n state.dismissed = true\n this.stopRefresh(state)\n state.callbacks.removeThinkingIndicator().catch(() => {})\n }\n\n onSessionEnd(sessionId: string): void {\n this.cleanup(sessionId)\n }\n\n destroy(): void {\n for (const [id] of this.sessions) {\n this.cleanup(id)\n }\n }\n\n private cleanup(sessionId: string): void {\n const state = this.sessions.get(sessionId)\n if (!state) return\n state.dismissed = true\n this.stopRefresh(state)\n this.sessions.delete(sessionId)\n }\n\n private startRefresh(sessionId: string, state: SessionState): void {\n state.refreshTimer = setInterval(() => {\n if (state.dismissed) {\n this.stopRefresh(state)\n return\n }\n if (Date.now() - state.startTime >= this.config.maxThinkingDuration) {\n this.stopRefresh(state)\n return\n }\n state.callbacks.updateThinkingIndicator().catch(() => {})\n }, this.config.thinkingRefreshInterval)\n }\n\n private stopRefresh(state: SessionState): void {\n if (state.refreshTimer) {\n clearInterval(state.refreshTimer)\n state.refreshTimer = undefined\n }\n }\n}\n"],"mappings":"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","names":["log"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/channel.ts","../../src/plugins/telegram/topic-manager.ts","../../src/core/adapter-primitives/stream-adapter.ts","../../src/core/adapter-primitives/primitives/draft-manager.ts","../../src/core/adapter-primitives/primitives/tool-call-tracker.ts","../../src/core/adapter-primitives/primitives/activity-tracker.ts"],"sourcesContent":["import type { OutgoingMessage, PermissionRequest, NotificationMessage, AgentCommand } from './types.js'\n\nexport interface ChannelConfig {\n enabled: boolean\n [key: string]: unknown\n}\n\nexport interface AdapterCapabilities {\n streaming: boolean\n richFormatting: boolean\n threads: boolean\n reactions: boolean\n fileUpload: boolean\n voice: boolean\n}\n\nexport interface IChannelAdapter {\n readonly name: string\n readonly capabilities: AdapterCapabilities\n\n start(): Promise<void>\n stop(): Promise<void>\n\n // Outgoing: core → channel\n sendMessage(sessionId: string, content: OutgoingMessage): Promise<void>\n sendPermissionRequest(sessionId: string, request: PermissionRequest): Promise<void>\n sendNotification(notification: NotificationMessage): Promise<void>\n\n // Session lifecycle on channel side\n createSessionThread(sessionId: string, name: string): Promise<string> // returns threadId\n renameSessionThread(sessionId: string, newName: string): Promise<void>\n deleteSessionThread?(sessionId: string): Promise<void>\n archiveSessionTopic?(sessionId: string): Promise<void>\n\n // Skill commands — optional\n sendSkillCommands?(sessionId: string, commands: AgentCommand[]): Promise<void>\n cleanupSkillCommands?(sessionId: string): Promise<void>\n}\n\n/**\n * Base class providing default no-op implementations for optional methods.\n * Adapters can extend this or implement IChannelAdapter directly.\n * @deprecated Use MessagingAdapter or StreamAdapter instead. Kept for backward compat during migration.\n */\nexport abstract class ChannelAdapter<TCore = unknown> implements IChannelAdapter {\n abstract readonly name: string\n readonly capabilities: AdapterCapabilities = {\n streaming: false, richFormatting: false, threads: false,\n reactions: false, fileUpload: false, voice: false,\n }\n\n constructor(public readonly core: TCore, protected config: ChannelConfig) {}\n\n abstract start(): Promise<void>\n abstract stop(): Promise<void>\n\n abstract sendMessage(sessionId: string, content: OutgoingMessage): Promise<void>\n abstract sendPermissionRequest(sessionId: string, request: PermissionRequest): Promise<void>\n abstract sendNotification(notification: NotificationMessage): Promise<void>\n\n abstract createSessionThread(sessionId: string, name: string): Promise<string>\n abstract renameSessionThread(sessionId: string, newName: string): Promise<void>\n async deleteSessionThread(_sessionId: string): Promise<void> {}\n\n async sendSkillCommands(_sessionId: string, _commands: AgentCommand[]): Promise<void> {}\n async cleanupSkillCommands(_sessionId: string): Promise<void> {}\n async archiveSessionTopic(_sessionId: string): Promise<void> {}\n}\n","import type { SessionManager } from '../../core/sessions/session-manager.js'\nimport type { IChannelAdapter } from '../../core/channel.js'\nimport type { SessionRecord } from '../../core/types.js'\nimport { createChildLogger } from '../../core/utils/log.js'\n\nconst log = createChildLogger({ module: 'topic-manager' })\n\nexport interface TopicInfo {\n sessionId: string\n topicId: number | null\n name: string | null\n status: string\n agentName: string\n lastActiveAt: string\n}\n\nexport interface DeleteTopicResult {\n ok: boolean\n needsConfirmation?: boolean\n topicId?: number | null\n session?: { id: string; name: string | null; status: string }\n error?: string\n}\n\nexport interface CleanupResult {\n deleted: string[]\n failed: { sessionId: string; error: string }[]\n}\n\ninterface SystemTopicIds {\n notificationTopicId: number | null\n assistantTopicId: number | null\n}\n\nexport class TopicManager {\n constructor(\n private sessionManager: SessionManager,\n private adapter: IChannelAdapter | null,\n private systemTopicIds: SystemTopicIds,\n ) {}\n\n listTopics(filter?: { statuses?: string[] }): TopicInfo[] {\n const records = this.sessionManager.listRecords(filter)\n return records\n .filter(r => !this.isSystemTopic(r))\n .filter(r => !filter?.statuses?.length || filter.statuses.includes(r.status))\n .map(r => ({\n sessionId: r.sessionId,\n topicId: (r.platform as Record<string, unknown>)?.topicId as number ?? null,\n name: r.name ?? null,\n status: r.status,\n agentName: r.agentName,\n lastActiveAt: r.lastActiveAt,\n }))\n }\n\n async deleteTopic(sessionId: string, options?: { confirmed?: boolean }): Promise<DeleteTopicResult> {\n const records = this.sessionManager.listRecords()\n const record = records.find(r => r.sessionId === sessionId)\n if (!record) return { ok: false, error: 'Session not found' }\n\n if (this.isSystemTopic(record)) return { ok: false, error: 'Cannot delete system topic' }\n\n const isActive = record.status === 'active' || record.status === 'initializing'\n if (isActive && !options?.confirmed) {\n return {\n ok: false,\n needsConfirmation: true,\n session: { id: record.sessionId, name: record.name ?? null, status: record.status },\n }\n }\n\n if (isActive) {\n await this.sessionManager.cancelSession(sessionId)\n }\n\n const topicId = (record.platform as Record<string, unknown>)?.topicId as number ?? null\n if (this.adapter && topicId) {\n try {\n await this.adapter.deleteSessionThread?.(sessionId)\n } catch (err) {\n log.warn({ err, sessionId, topicId }, 'Failed to delete platform thread, removing record anyway')\n }\n }\n\n await this.sessionManager.removeRecord(sessionId)\n return { ok: true, topicId }\n }\n\n async cleanup(statuses?: string[]): Promise<CleanupResult> {\n const targetStatuses = statuses?.length ? statuses : ['finished', 'error', 'cancelled']\n const records = this.sessionManager.listRecords({ statuses: targetStatuses })\n const targets = records\n .filter(r => !this.isSystemTopic(r))\n .filter(r => targetStatuses.includes(r.status))\n\n const deleted: string[] = []\n const failed: { sessionId: string; error: string }[] = []\n\n for (const record of targets) {\n try {\n // Cancel active/initializing sessions to prevent orphaned agent processes\n const isActive = record.status === 'active' || record.status === 'initializing'\n if (isActive) {\n await this.sessionManager.cancelSession(record.sessionId)\n }\n\n const topicId = (record.platform as Record<string, unknown>)?.topicId as number | undefined\n if (this.adapter && topicId) {\n try {\n await this.adapter.deleteSessionThread?.(record.sessionId)\n } catch (err) {\n log.warn({ err, sessionId: record.sessionId }, 'Failed to delete platform thread during cleanup')\n }\n }\n await this.sessionManager.removeRecord(record.sessionId)\n deleted.push(record.sessionId)\n } catch (err) {\n failed.push({ sessionId: record.sessionId, error: err instanceof Error ? err.message : String(err) })\n }\n }\n\n return { deleted, failed }\n }\n\n private isSystemTopic(record: SessionRecord): boolean {\n const topicId = (record.platform as Record<string, unknown>)?.topicId as number | undefined\n if (!topicId) return false\n return topicId === this.systemTopicIds.notificationTopicId\n || topicId === this.systemTopicIds.assistantTopicId\n }\n}\n","import type {\n IChannelAdapter,\n AdapterCapabilities,\n} from '../channel.js'\nimport type {\n OutgoingMessage,\n PermissionRequest,\n NotificationMessage,\n} from '../types.js'\n\nexport interface StreamEvent {\n type: string\n sessionId?: string\n payload: unknown\n timestamp: number\n}\n\nexport abstract class StreamAdapter implements IChannelAdapter {\n abstract readonly name: string\n\n capabilities: AdapterCapabilities\n\n constructor(config?: Partial<AdapterCapabilities>) {\n this.capabilities = {\n streaming: true,\n richFormatting: false,\n threads: false,\n reactions: false,\n fileUpload: false,\n voice: false,\n ...config,\n }\n }\n\n async sendMessage(sessionId: string, content: OutgoingMessage): Promise<void> {\n await this.emit(sessionId, {\n type: content.type,\n sessionId,\n payload: content,\n timestamp: Date.now(),\n })\n }\n\n async sendPermissionRequest(sessionId: string, request: PermissionRequest): Promise<void> {\n await this.emit(sessionId, {\n type: 'permission_request',\n sessionId,\n payload: request,\n timestamp: Date.now(),\n })\n }\n\n async sendNotification(notification: NotificationMessage): Promise<void> {\n await this.broadcast({\n type: 'notification',\n payload: notification,\n timestamp: Date.now(),\n })\n }\n\n async createSessionThread(_sessionId: string, _name: string): Promise<string> {\n return ''\n }\n\n async renameSessionThread(sessionId: string, name: string): Promise<void> {\n await this.emit(sessionId, {\n type: 'session_rename',\n sessionId,\n payload: { name },\n timestamp: Date.now(),\n })\n }\n\n protected abstract emit(sessionId: string, event: StreamEvent): Promise<void>\n protected abstract broadcast(event: StreamEvent): Promise<void>\n abstract start(): Promise<void>\n abstract stop(): Promise<void>\n}\n","export interface DraftConfig {\n flushInterval: number\n maxLength: number\n onFlush: (sessionId: string, text: string, isEdit: boolean) => Promise<string | undefined>\n onError?: (sessionId: string, error: Error) => void\n}\n\nexport class Draft {\n private buffer = ''\n private _messageId?: string\n private firstFlushPending = false\n private flushTimer?: ReturnType<typeof setTimeout>\n private flushPromise: Promise<void> = Promise.resolve()\n\n constructor(\n private sessionId: string,\n private config: DraftConfig,\n ) {}\n\n get isEmpty(): boolean { return !this.buffer }\n get messageId(): string | undefined { return this._messageId }\n\n append(text: string): void {\n if (!text) return\n this.buffer += text\n this.scheduleFlush()\n }\n\n async finalize(): Promise<string | undefined> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer)\n this.flushTimer = undefined\n }\n await this.flushPromise\n if (this.buffer) {\n await this.flush()\n }\n return this._messageId\n }\n\n destroy(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer)\n this.flushTimer = undefined\n }\n this.buffer = ''\n }\n\n private scheduleFlush(): void {\n if (this.flushTimer) return\n this.flushTimer = setTimeout(() => {\n this.flushTimer = undefined\n this.flushPromise = this.flushPromise\n .then(() => this.flush())\n .catch(() => {})\n }, this.config.flushInterval)\n }\n\n private async flush(): Promise<void> {\n if (!this.buffer || this.firstFlushPending) return\n\n const snapshot = this.buffer\n const isEdit = !!this._messageId\n\n if (!this._messageId) {\n this.firstFlushPending = true\n }\n\n try {\n const result = await this.config.onFlush(this.sessionId, snapshot, isEdit)\n if (!isEdit && result) {\n this._messageId = result\n }\n } catch (err) {\n this.config.onError?.(this.sessionId, err instanceof Error ? err : new Error(String(err)))\n } finally {\n this.firstFlushPending = false\n }\n }\n}\n\nexport class DraftManager {\n private drafts = new Map<string, Draft>()\n\n constructor(private config: DraftConfig) {}\n\n getOrCreate(sessionId: string): Draft {\n let draft = this.drafts.get(sessionId)\n if (!draft) {\n draft = new Draft(sessionId, this.config)\n this.drafts.set(sessionId, draft)\n }\n return draft\n }\n\n async finalize(sessionId: string): Promise<void> {\n const draft = this.drafts.get(sessionId)\n if (!draft) return\n await draft.finalize()\n }\n\n async finalizeAll(): Promise<void> {\n await Promise.all([...this.drafts.values()].map(d => d.finalize()))\n }\n\n destroy(sessionId: string): void {\n const draft = this.drafts.get(sessionId)\n if (draft) {\n draft.destroy()\n this.drafts.delete(sessionId)\n }\n }\n\n destroyAll(): void {\n for (const draft of this.drafts.values()) {\n draft.destroy()\n }\n this.drafts.clear()\n }\n}\n","import type { ToolCallMeta } from '../format-types.js'\n\nexport interface TrackedToolCall extends ToolCallMeta {\n messageId: string\n}\n\nexport class ToolCallTracker {\n private sessions = new Map<string, Map<string, TrackedToolCall>>()\n\n track(sessionId: string, meta: ToolCallMeta, messageId: string): void {\n if (!this.sessions.has(sessionId)) {\n this.sessions.set(sessionId, new Map())\n }\n this.sessions.get(sessionId)!.set(meta.id, { ...meta, messageId })\n }\n\n update(\n sessionId: string,\n toolId: string,\n status: string,\n patch?: Partial<Pick<ToolCallMeta, 'viewerLinks' | 'viewerFilePath' | 'name' | 'kind'>>,\n ): TrackedToolCall | null {\n const tool = this.sessions.get(sessionId)?.get(toolId)\n if (!tool) return null\n\n tool.status = status\n if (patch?.viewerLinks) tool.viewerLinks = patch.viewerLinks\n if (patch?.viewerFilePath) tool.viewerFilePath = patch.viewerFilePath\n if (patch?.name) tool.name = patch.name\n if (patch?.kind) tool.kind = patch.kind\n\n return tool\n }\n\n getActive(sessionId: string): TrackedToolCall[] {\n const session = this.sessions.get(sessionId)\n return session ? [...session.values()] : []\n }\n\n clear(sessionId: string): void {\n this.sessions.delete(sessionId)\n }\n\n clearAll(): void {\n this.sessions.clear()\n }\n}\n","export interface ActivityConfig {\n thinkingRefreshInterval: number\n maxThinkingDuration: number\n}\n\nexport interface ActivityCallbacks {\n sendThinkingIndicator(): Promise<void>\n updateThinkingIndicator(): Promise<void>\n removeThinkingIndicator(): Promise<void>\n}\n\ninterface SessionState {\n callbacks: ActivityCallbacks\n refreshTimer?: ReturnType<typeof setInterval>\n startTime: number\n dismissed: boolean\n}\n\nexport class ActivityTracker {\n private sessions = new Map<string, SessionState>()\n\n constructor(private config: ActivityConfig) {}\n\n onThinkingStart(sessionId: string, callbacks: ActivityCallbacks): void {\n this.cleanup(sessionId)\n\n const state: SessionState = {\n callbacks,\n startTime: Date.now(),\n dismissed: false,\n }\n this.sessions.set(sessionId, state)\n\n setTimeout(() => {\n if (state.dismissed) return\n callbacks.sendThinkingIndicator().catch(() => {})\n this.startRefresh(sessionId, state)\n }, 0)\n }\n\n onTextStart(sessionId: string): void {\n const state = this.sessions.get(sessionId)\n if (!state || state.dismissed) return\n state.dismissed = true\n this.stopRefresh(state)\n state.callbacks.removeThinkingIndicator().catch(() => {})\n }\n\n onSessionEnd(sessionId: string): void {\n this.cleanup(sessionId)\n }\n\n destroy(): void {\n for (const [id] of this.sessions) {\n this.cleanup(id)\n }\n }\n\n private cleanup(sessionId: string): void {\n const state = this.sessions.get(sessionId)\n if (!state) return\n state.dismissed = true\n this.stopRefresh(state)\n this.sessions.delete(sessionId)\n }\n\n private startRefresh(sessionId: string, state: SessionState): void {\n state.refreshTimer = setInterval(() => {\n if (state.dismissed) {\n this.stopRefresh(state)\n return\n }\n if (Date.now() - state.startTime >= this.config.maxThinkingDuration) {\n this.stopRefresh(state)\n return\n }\n state.callbacks.updateThinkingIndicator().catch(() => {})\n }, this.config.thinkingRefreshInterval)\n }\n\n private stopRefresh(state: SessionState): void {\n if (state.refreshTimer) {\n clearInterval(state.refreshTimer)\n state.refreshTimer = undefined\n }\n }\n}\n"],"mappings":"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","names":["log"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
corePlugins
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-S3ZGPPXY.js";
|
|
5
5
|
import {
|
|
6
6
|
SettingsManager
|
|
7
7
|
} from "./chunk-MLF4W5R6.js";
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-P2G275VD.js";
|
|
9
|
+
import "./chunk-ZNSO2QVC.js";
|
|
10
10
|
import "./chunk-SNPYTMPR.js";
|
|
11
11
|
import "./chunk-KMMEFXIE.js";
|
|
12
12
|
import "./chunk-4GMLGCF2.js";
|
|
@@ -300,7 +300,7 @@ async function startServer(opts) {
|
|
|
300
300
|
const configManager = new ConfigManager();
|
|
301
301
|
const configExists = await configManager.exists();
|
|
302
302
|
if (!configExists) {
|
|
303
|
-
const { runSetup } = await import("./setup-
|
|
303
|
+
const { runSetup } = await import("./setup-A7VPW46C.js");
|
|
304
304
|
const shouldStart = await runSetup(configManager, { settingsManager, pluginRegistry });
|
|
305
305
|
if (!shouldStart) process.exit(0);
|
|
306
306
|
}
|
|
@@ -313,7 +313,7 @@ async function startServer(opts) {
|
|
|
313
313
|
}
|
|
314
314
|
const isForegroundTTY = !!(process.stdout.isTTY && !process.env.NO_COLOR && config.runMode !== "daemon");
|
|
315
315
|
if (isForegroundTTY) {
|
|
316
|
-
const { printStartBanner } = await import("./setup-
|
|
316
|
+
const { printStartBanner } = await import("./setup-A7VPW46C.js");
|
|
317
317
|
await printStartBanner();
|
|
318
318
|
}
|
|
319
319
|
let spinner;
|
|
@@ -501,8 +501,8 @@ async function autoRegisterBuiltinPlugins(settingsManager, pluginRegistry, confi
|
|
|
501
501
|
import("./notifications-D5BRDNSU.js"),
|
|
502
502
|
import("./tunnel-45HA72MB.js"),
|
|
503
503
|
import("./api-server-7G3ZUZRM.js"),
|
|
504
|
-
import("./telegram-
|
|
505
|
-
import("./slack-
|
|
504
|
+
import("./telegram-E65IWFBW.js"),
|
|
505
|
+
import("./slack-2XNWBOWH.js")
|
|
506
506
|
]);
|
|
507
507
|
for (const result of pluginModules) {
|
|
508
508
|
if (result.status !== "fulfilled") continue;
|
|
@@ -566,4 +566,4 @@ export {
|
|
|
566
566
|
RESTART_EXIT_CODE,
|
|
567
567
|
startServer
|
|
568
568
|
};
|
|
569
|
-
//# sourceMappingURL=main-
|
|
569
|
+
//# sourceMappingURL=main-3GF3EQTE.js.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import "./chunk-VUNV25KB.js";
|
|
2
|
+
|
|
3
|
+
// src/core/plugin/plugin-installer.ts
|
|
4
|
+
import { exec } from "child_process";
|
|
5
|
+
import { promisify } from "util";
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
import * as os from "os";
|
|
8
|
+
import * as path from "path";
|
|
9
|
+
import { pathToFileURL } from "url";
|
|
10
|
+
var execAsync = promisify(exec);
|
|
11
|
+
async function importFromDir(packageName, dir) {
|
|
12
|
+
const pkgDir = path.join(dir, "node_modules", ...packageName.split("/"));
|
|
13
|
+
const pkgJsonPath = path.join(pkgDir, "package.json");
|
|
14
|
+
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
|
|
15
|
+
let entry;
|
|
16
|
+
const exportsMain = pkgJson.exports?.["."];
|
|
17
|
+
if (typeof exportsMain === "string") {
|
|
18
|
+
entry = exportsMain;
|
|
19
|
+
} else if (exportsMain?.import) {
|
|
20
|
+
entry = exportsMain.import;
|
|
21
|
+
} else {
|
|
22
|
+
entry = pkgJson.main ?? "index.js";
|
|
23
|
+
}
|
|
24
|
+
const entryPath = path.join(pkgDir, entry);
|
|
25
|
+
return import(pathToFileURL(entryPath).href);
|
|
26
|
+
}
|
|
27
|
+
async function installNpmPlugin(packageName, pluginsDir) {
|
|
28
|
+
const dir = pluginsDir ?? path.join(os.homedir(), ".openacp", "plugins");
|
|
29
|
+
try {
|
|
30
|
+
return await importFromDir(packageName, dir);
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
await execAsync(`npm install ${packageName} --prefix "${dir}" --save`, {
|
|
34
|
+
timeout: 6e4
|
|
35
|
+
});
|
|
36
|
+
return await importFromDir(packageName, dir);
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
importFromDir,
|
|
40
|
+
installNpmPlugin
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=plugin-installer-QVJP6VKV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/plugin/plugin-installer.ts"],"sourcesContent":["import { exec } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport * as fs from 'node:fs'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\nconst execAsync = promisify(exec)\n\n/**\n * Import a package resolved from a specific directory (not the project root).\n * Reads the package's package.json to find the ESM entry point, then imports by file path.\n */\nexport async function importFromDir(packageName: string, dir: string): Promise<any> {\n const pkgDir = path.join(dir, 'node_modules', ...packageName.split('/'))\n const pkgJsonPath = path.join(pkgDir, 'package.json')\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'))\n\n // Resolve entry: exports[\".\"].import > main > index.js\n let entry: string\n const exportsMain = pkgJson.exports?.['.']\n if (typeof exportsMain === 'string') {\n entry = exportsMain\n } else if (exportsMain?.import) {\n entry = exportsMain.import\n } else {\n entry = pkgJson.main ?? 'index.js'\n }\n\n const entryPath = path.join(pkgDir, entry)\n return import(pathToFileURL(entryPath).href)\n}\n\n/**\n * Install an npm package to the plugins directory and return the loaded module.\n * Tries to import first; if not installed, runs npm install asynchronously.\n */\nexport async function installNpmPlugin(packageName: string, pluginsDir?: string): Promise<any> {\n const dir = pluginsDir ?? path.join(os.homedir(), '.openacp', 'plugins')\n\n // Try import from plugins dir first — already installed\n try {\n return await importFromDir(packageName, dir)\n } catch {\n // Not installed, proceed with install\n }\n\n await execAsync(`npm install ${packageName} --prefix \"${dir}\" --save`, {\n timeout: 60000,\n })\n\n return await importFromDir(packageName, dir)\n}\n"],"mappings":";;;AAAA,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,SAAS,qBAAqB;AAE9B,IAAM,YAAY,UAAU,IAAI;AAMhC,eAAsB,cAAc,aAAqB,KAA2B;AAClF,QAAM,SAAc,UAAK,KAAK,gBAAgB,GAAG,YAAY,MAAM,GAAG,CAAC;AACvE,QAAM,cAAmB,UAAK,QAAQ,cAAc;AACpD,QAAM,UAAU,KAAK,MAAS,gBAAa,aAAa,OAAO,CAAC;AAGhE,MAAI;AACJ,QAAM,cAAc,QAAQ,UAAU,GAAG;AACzC,MAAI,OAAO,gBAAgB,UAAU;AACnC,YAAQ;AAAA,EACV,WAAW,aAAa,QAAQ;AAC9B,YAAQ,YAAY;AAAA,EACtB,OAAO;AACL,YAAQ,QAAQ,QAAQ;AAAA,EAC1B;AAEA,QAAM,YAAiB,UAAK,QAAQ,KAAK;AACzC,SAAO,OAAO,cAAc,SAAS,EAAE;AACzC;AAMA,eAAsB,iBAAiB,aAAqB,YAAmC;AAC7F,QAAM,MAAM,cAAmB,UAAQ,WAAQ,GAAG,YAAY,SAAS;AAGvE,MAAI;AACF,WAAO,MAAM,cAAc,aAAa,GAAG;AAAA,EAC7C,QAAQ;AAAA,EAER;AAEA,QAAM,UAAU,eAAe,WAAW,cAAc,GAAG,YAAY;AAAA,IACrE,SAAS;AAAA,EACX,CAAC;AAED,SAAO,MAAM,cAAc,aAAa,GAAG;AAC7C;","names":[]}
|
|
@@ -402,7 +402,7 @@ async function promptConfiguredAction(label) {
|
|
|
402
402
|
}
|
|
403
403
|
async function configureViaPlugin(channelId) {
|
|
404
404
|
const pluginImports = {
|
|
405
|
-
telegram: () => import("./telegram-
|
|
405
|
+
telegram: () => import("./telegram-E65IWFBW.js"),
|
|
406
406
|
discord: async () => {
|
|
407
407
|
const pkg = "@openacp/adapter-discord";
|
|
408
408
|
try {
|
|
@@ -521,7 +521,7 @@ async function runSetup(configManager, opts) {
|
|
|
521
521
|
for (const channelId of channelChoices) {
|
|
522
522
|
currentStep++;
|
|
523
523
|
if (channelId === "telegram") {
|
|
524
|
-
const telegramPlugin = (await import("./telegram-
|
|
524
|
+
const telegramPlugin = (await import("./telegram-E65IWFBW.js")).default;
|
|
525
525
|
const ctx = createInstallContext({
|
|
526
526
|
pluginName: telegramPlugin.name,
|
|
527
527
|
settingsManager,
|
|
@@ -627,14 +627,16 @@ async function runSetup(configManager, opts) {
|
|
|
627
627
|
async function installAndSetupDiscord(settingsManager, pluginRegistry) {
|
|
628
628
|
const packageName = "@openacp/adapter-discord";
|
|
629
629
|
let discordPlugin;
|
|
630
|
+
const pluginsDir = settingsManager.getBasePath();
|
|
630
631
|
try {
|
|
631
|
-
|
|
632
|
+
const { importFromDir } = await import("./plugin-installer-QVJP6VKV.js");
|
|
633
|
+
const mod = await importFromDir(packageName, pluginsDir);
|
|
634
|
+
discordPlugin = mod.default;
|
|
632
635
|
} catch {
|
|
633
636
|
const spinner3 = clack7.spinner();
|
|
634
637
|
spinner3.start(`Installing ${packageName}...`);
|
|
635
638
|
try {
|
|
636
|
-
const { installNpmPlugin } = await import("./plugin-installer-
|
|
637
|
-
const pluginsDir = settingsManager.getBasePath();
|
|
639
|
+
const { installNpmPlugin } = await import("./plugin-installer-QVJP6VKV.js");
|
|
638
640
|
const mod = await installNpmPlugin(packageName, pluginsDir);
|
|
639
641
|
discordPlugin = mod.default;
|
|
640
642
|
spinner3.stop(ok(`${packageName} installed`));
|
|
@@ -771,4 +773,4 @@ export {
|
|
|
771
773
|
validateBotToken,
|
|
772
774
|
validateChatId
|
|
773
775
|
};
|
|
774
|
-
//# sourceMappingURL=setup-
|
|
776
|
+
//# sourceMappingURL=setup-A7VPW46C.js.map
|