@agentdock/agent-runtime-core 0.0.97
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/acpTypes.d.ts +171 -0
- package/dist/acpTypes.js +1 -0
- package/dist/adapters/dingtalk.d.ts +11 -0
- package/dist/adapters/dingtalk.js +7 -0
- package/dist/adapters/feishu.d.ts +13 -0
- package/dist/adapters/feishu.js +1 -0
- package/dist/adapters/webhookClient.d.ts +8 -0
- package/dist/adapters/webhookClient.js +1 -0
- package/dist/agentSettings.d.ts +42 -0
- package/dist/agentSettings.js +1 -0
- package/dist/agentSpawnTypes.d.ts +76 -0
- package/dist/agentSpawnTypes.js +1 -0
- package/dist/agentStderrPolicy.d.ts +6 -0
- package/dist/agentStderrPolicy.js +1 -0
- package/dist/boundedSet.d.ts +12 -0
- package/dist/boundedSet.js +1 -0
- package/dist/brand.d.ts +27 -0
- package/dist/brand.js +1 -0
- package/dist/checkpointService.d.ts +40 -0
- package/dist/checkpointService.js +2 -0
- package/dist/cli-arg-access.d.ts +1 -0
- package/dist/cli-arg-access.js +1 -0
- package/dist/cli-args.d.ts +75 -0
- package/dist/cli-args.js +1 -0
- package/dist/cli-handoff-args.d.ts +22 -0
- package/dist/cli-handoff-args.js +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/containerEnvPrompt.d.ts +1 -0
- package/dist/containerEnvPrompt.js +1 -0
- package/dist/contextUsageQuery.d.ts +14 -0
- package/dist/contextUsageQuery.js +1 -0
- package/dist/conversationRollback.d.ts +12 -0
- package/dist/conversationRollback.js +4 -0
- package/dist/debugMode.d.ts +2 -0
- package/dist/debugMode.js +1 -0
- package/dist/decodeChildOutput.d.ts +12 -0
- package/dist/decodeChildOutput.js +1 -0
- package/dist/dekMethods.d.ts +9 -0
- package/dist/dekMethods.js +1 -0
- package/dist/deployment.d.ts +16 -0
- package/dist/deployment.js +1 -0
- package/dist/deploymentBinding.d.ts +15 -0
- package/dist/deploymentBinding.js +1 -0
- package/dist/directEnvelopeDelivery.d.ts +27 -0
- package/dist/directEnvelopeDelivery.js +1 -0
- package/dist/envSanitize.d.ts +14 -0
- package/dist/envSanitize.js +2 -0
- package/dist/envelopeOutbound.d.ts +8 -0
- package/dist/envelopeOutbound.js +1 -0
- package/dist/fetchRetry.d.ts +9 -0
- package/dist/fetchRetry.js +1 -0
- package/dist/fileReceiver.d.ts +32 -0
- package/dist/fileReceiver.js +1 -0
- package/dist/fileWatcher.d.ts +1 -0
- package/dist/fileWatcher.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/ingest/claudePaths.d.ts +11 -0
- package/dist/ingest/claudePaths.js +1 -0
- package/dist/ingest/claudeSessionScanner.d.ts +11 -0
- package/dist/ingest/claudeSessionScanner.js +1 -0
- package/dist/ingest/index.d.ts +3 -0
- package/dist/ingest/index.js +1 -0
- package/dist/ingest/types.d.ts +82 -0
- package/dist/ingest/types.js +1 -0
- package/dist/jsonFileUtils.d.ts +3 -0
- package/dist/jsonFileUtils.js +1 -0
- package/dist/jsonlIndexService.d.ts +26 -0
- package/dist/jsonlIndexService.js +1 -0
- package/dist/jsonrpc-stdio.d.ts +52 -0
- package/dist/jsonrpc-stdio.js +3 -0
- package/dist/keepAlive.d.ts +45 -0
- package/dist/keepAlive.js +1 -0
- package/dist/knownProjects.d.ts +3 -0
- package/dist/knownProjects.js +1 -0
- package/dist/languageSettingsFile.d.ts +3 -0
- package/dist/languageSettingsFile.js +1 -0
- package/dist/lock.d.ts +12 -0
- package/dist/lock.js +1 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.js +1 -0
- package/dist/messageQueue.d.ts +40 -0
- package/dist/messageQueue.js +1 -0
- package/dist/migration.d.ts +1 -0
- package/dist/migration.js +2 -0
- package/dist/modeLoop.d.ts +48 -0
- package/dist/modeLoop.js +1 -0
- package/dist/notificationChannels.d.ts +14 -0
- package/dist/notificationChannels.js +1 -0
- package/dist/notificationDispatcher.d.ts +11 -0
- package/dist/notificationDispatcher.js +1 -0
- package/dist/outbox.d.ts +49 -0
- package/dist/outbox.js +1 -0
- package/dist/paths.d.ts +24 -0
- package/dist/paths.js +1 -0
- package/dist/plaintextEnvelope.d.ts +5 -0
- package/dist/plaintextEnvelope.js +1 -0
- package/dist/processTree.d.ts +9 -0
- package/dist/processTree.js +5 -0
- package/dist/registerMachineOnConnect.d.ts +5 -0
- package/dist/registerMachineOnConnect.js +1 -0
- package/dist/responseLanguage.d.ts +5 -0
- package/dist/responseLanguage.js +5 -0
- package/dist/runtimeTargetGuard.d.ts +8 -0
- package/dist/runtimeTargetGuard.js +1 -0
- package/dist/sendClearedContextUsage.d.ts +4 -0
- package/dist/sendClearedContextUsage.js +1 -0
- package/dist/serverClient.d.ts +107 -0
- package/dist/serverClient.js +1 -0
- package/dist/serverClientEventHandlers.d.ts +6 -0
- package/dist/serverClientEventHandlers.js +1 -0
- package/dist/serverClientFactory.d.ts +3 -0
- package/dist/serverClientFactory.js +1 -0
- package/dist/serverClientTypes.d.ts +67 -0
- package/dist/serverClientTypes.js +1 -0
- package/dist/serverSettingsCache.d.ts +5 -0
- package/dist/serverSettingsCache.js +1 -0
- package/dist/session/backgroundTaskHandler.d.ts +29 -0
- package/dist/session/backgroundTaskHandler.js +1 -0
- package/dist/session/interactionDetector.d.ts +32 -0
- package/dist/session/interactionDetector.js +1 -0
- package/dist/session/modeHash.d.ts +6 -0
- package/dist/session/modeHash.js +1 -0
- package/dist/session/sessionBridge.d.ts +44 -0
- package/dist/session/sessionBridge.js +7 -0
- package/dist/session/sessionCompactBoundaryMapper.d.ts +17 -0
- package/dist/session/sessionCompactBoundaryMapper.js +1 -0
- package/dist/session/sessionMapper.d.ts +36 -0
- package/dist/session/sessionMapper.js +1 -0
- package/dist/session/sourceAgentRouting.d.ts +3 -0
- package/dist/session/sourceAgentRouting.js +1 -0
- package/dist/session/textAccumulator.d.ts +21 -0
- package/dist/session/textAccumulator.js +1 -0
- package/dist/session/turnTiming.d.ts +15 -0
- package/dist/session/turnTiming.js +1 -0
- package/dist/session/turnUsage.d.ts +17 -0
- package/dist/session/turnUsage.js +1 -0
- package/dist/session/workflowTracker.d.ts +63 -0
- package/dist/session/workflowTracker.js +1 -0
- package/dist/sessionBootstrap.d.ts +21 -0
- package/dist/sessionBootstrap.js +13 -0
- package/dist/sessionDeliveryDraft.d.ts +17 -0
- package/dist/sessionDeliveryDraft.js +1 -0
- package/dist/sessionDeliveryProtocol.d.ts +22 -0
- package/dist/sessionDeliveryProtocol.js +3 -0
- package/dist/sessionDeliverySubmit.d.ts +13 -0
- package/dist/sessionDeliverySubmit.js +1 -0
- package/dist/sessionDeliveryTool.d.ts +10 -0
- package/dist/sessionDeliveryTool.js +3 -0
- package/dist/sessionHandoffSystemPrompt.d.ts +10 -0
- package/dist/sessionHandoffSystemPrompt.js +3 -0
- package/dist/sessionMcpBootstrap.d.ts +13 -0
- package/dist/sessionMcpBootstrap.js +1 -0
- package/dist/sessionMcpInjection.d.ts +41 -0
- package/dist/sessionMcpInjection.js +1 -0
- package/dist/sessionMcpServer.d.ts +2 -0
- package/dist/sessionMcpServer.js +2 -0
- package/dist/sessionPrompt.d.ts +7 -0
- package/dist/sessionPrompt.js +3 -0
- package/dist/sessionRegistry.d.ts +42 -0
- package/dist/sessionRegistry.js +1 -0
- package/dist/sessionStatsCollector.d.ts +20 -0
- package/dist/sessionStatsCollector.js +1 -0
- package/dist/shellSanitizer.d.ts +1 -0
- package/dist/shellSanitizer.js +1 -0
- package/dist/shutdownHelper.d.ts +24 -0
- package/dist/shutdownHelper.js +1 -0
- package/dist/skillCache.d.ts +4 -0
- package/dist/skillCache.js +1 -0
- package/dist/skillParser.d.ts +20 -0
- package/dist/skillParser.js +6 -0
- package/dist/spawnConsole.d.ts +9 -0
- package/dist/spawnConsole.js +21 -0
- package/dist/startAbortHandler.d.ts +15 -0
- package/dist/startAbortHandler.js +1 -0
- package/dist/startAcpInitialPrompt.d.ts +51 -0
- package/dist/startAcpInitialPrompt.js +7 -0
- package/dist/startAcpPermission.d.ts +20 -0
- package/dist/startAcpPermission.js +1 -0
- package/dist/startAcpSwitchHelpers.d.ts +52 -0
- package/dist/startAcpSwitchHelpers.js +1 -0
- package/dist/startCancelTaskHandler.d.ts +17 -0
- package/dist/startCancelTaskHandler.js +1 -0
- package/dist/startCommandDaemonDebug.d.ts +8 -0
- package/dist/startCommandDaemonDebug.js +1 -0
- package/dist/startCommandRuntime.d.ts +162 -0
- package/dist/startCommandRuntime.js +5 -0
- package/dist/startCommandTypes.d.ts +33 -0
- package/dist/startCommandTypes.js +1 -0
- package/dist/startRpcHandler.d.ts +41 -0
- package/dist/startRpcHandler.js +1 -0
- package/dist/state.d.ts +29 -0
- package/dist/state.js +1 -0
- package/dist/statsAccumulator.d.ts +50 -0
- package/dist/statsAccumulator.js +1 -0
- package/dist/statsBuckets.d.ts +55 -0
- package/dist/statsBuckets.js +1 -0
- package/dist/subagentIds.d.ts +1 -0
- package/dist/subagentIds.js +1 -0
- package/dist/suggestedOptionsPrompt.d.ts +16 -0
- package/dist/suggestedOptionsPrompt.js +7 -0
- package/dist/taskTitle.d.ts +3 -0
- package/dist/taskTitle.js +1 -0
- package/dist/telemetryCollector.d.ts +15 -0
- package/dist/telemetryCollector.js +1 -0
- package/dist/terminalReset.d.ts +1 -0
- package/dist/terminalReset.js +1 -0
- package/dist/titleUpdater.d.ts +25 -0
- package/dist/titleUpdater.js +1 -0
- package/dist/tokenAuth.d.ts +6 -0
- package/dist/tokenAuth.js +1 -0
- package/dist/toolResultTruncation.d.ts +3 -0
- package/dist/toolResultTruncation.js +5 -0
- package/dist/transport.d.ts +13 -0
- package/dist/transport.js +1 -0
- package/dist/typeGuards.d.ts +7 -0
- package/dist/typeGuards.js +1 -0
- package/dist/userConfig.d.ts +5 -0
- package/dist/userConfig.js +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.g.d.ts +1 -0
- package/dist/version.g.js +1 -0
- package/dist/version.js +1 -0
- package/dist/waitForConnection.d.ts +2 -0
- package/dist/waitForConnection.js +1 -0
- package/dist/windowsCommandShim.d.ts +6 -0
- package/dist/windowsCommandShim.js +1 -0
- package/dist/zombieReaper.d.ts +34 -0
- package/dist/zombieReaper.js +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare const MODE_RESTART_SENTINEL = "\0mode-restart";
|
|
2
|
+
|
|
3
|
+
export interface QueuedImageAttachment {
|
|
4
|
+
readonly data: string;
|
|
5
|
+
readonly mediaType: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface QueuedMessage {
|
|
9
|
+
readonly text: string;
|
|
10
|
+
readonly images?: readonly QueuedImageAttachment[];
|
|
11
|
+
|
|
12
|
+
readonly echoToServer?: boolean;
|
|
13
|
+
|
|
14
|
+
readonly messageUuid?: string;
|
|
15
|
+
|
|
16
|
+
readonly settle?: (error?: Error) => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface MessageQueue {
|
|
20
|
+
|
|
21
|
+
push(text: string, images?: readonly QueuedImageAttachment[], opts?: {
|
|
22
|
+
readonly echoToServer?: boolean;
|
|
23
|
+
readonly messageUuid?: string;
|
|
24
|
+
}): void;
|
|
25
|
+
|
|
26
|
+
submit(text: string, images?: readonly QueuedImageAttachment[], opts?: {
|
|
27
|
+
readonly echoToServer?: boolean;
|
|
28
|
+
readonly messageUuid?: string;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
|
|
31
|
+
waitForMessage(abort: AbortSignal): Promise<QueuedMessage | null>;
|
|
32
|
+
|
|
33
|
+
clear(): void;
|
|
34
|
+
|
|
35
|
+
size(): number;
|
|
36
|
+
|
|
37
|
+
close(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export declare function createMessageQueue(): MessageQueue;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export const MODE_RESTART_SENTINEL="\0mode-restart";function d(s,r,n,l){const o=r&&r.length>0;return{text:s,...o?{images:r}:{},...n?.echoToServer?{echoToServer:!0}:{},...n?.messageUuid?{messageUuid:n.messageUuid}:{},...l?{settle:l}:{}}}export function createMessageQueue(){const s=[];let r=null,n=!1;function l(e){if(n)return!1;if(r){const t=r;r=null,e.settle?.(),t(e)}else s.push(e);return!0}function o(e){for(const t of s)t.settle?.(e);s.length=0}return{push(e,t,u){l(d(e,t,u))},submit(e,t,u){return new Promise((i,m)=>{let c=!1;const a=f=>{c||(c=!0,f?m(f):i())};l(d(e,t,u,a))||a(new Error("message queue is closed"))})},waitForMessage(e){if(n)return Promise.resolve(null);const t=s.shift();return t!==void 0?(t.settle?.(),Promise.resolve(t)):e.aborted?Promise.resolve(null):new Promise(u=>{r=u;const i=()=>{r===u&&(r=null,u(null))};e.addEventListener("abort",i,{once:!0})})},clear(){o(new Error("message queue was cleared"))},size(){return s.length},close(){if(n=!0,o(new Error("message queue is closed")),r){const e=r;r=null,e(null)}}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function migrateFromOldBrand(homeDir?: string): void;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";import s from"node:fs";import m from"node:os";import a from"node:path";import{getBrand as d,getDefaultBrand as l,isAltBrand as p}from"./brand.js";import{migrateDataDir as u}from"./paths.js";export function migrateFromOldBrand(e){if(!p())return;const t=e??m.homedir(),i=l(),o=d(),n=a.join(t,i.dataDir),r=a.join(t,o.dataDir);u(n,r),D(r,i.serverUrl,o.serverUrl)}function D(e,t,i){if(t===i)return;const o=a.join(e,"credentials.json");let n;try{n=s.readFileSync(o,"utf8")}catch{return}const r=JSON.parse(n);if(!r.profiles||!r.profiles[t])return;const{[t]:f,...c}=r.profiles;r.profiles={...c,[i]:f},s.writeFileSync(o,JSON.stringify(r,null,2)+`
|
|
2
|
+
`,"utf8")}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Logger } from './logger.js';
|
|
2
|
+
|
|
3
|
+
export type IterationResult = {
|
|
4
|
+
readonly type: 'switch';
|
|
5
|
+
readonly to: 'local' | 'remote';
|
|
6
|
+
} | {
|
|
7
|
+
readonly type: 'exit';
|
|
8
|
+
readonly code: number;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export interface LauncherContext {
|
|
12
|
+
readonly cwd: string;
|
|
13
|
+
readonly claudeSessionId: string | null;
|
|
14
|
+
readonly pendingMessage: string | null;
|
|
15
|
+
readonly abort: AbortSignal;
|
|
16
|
+
|
|
17
|
+
readonly getSwitchTarget: () => 'local' | 'remote' | null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type ModeLauncher = (ctx: LauncherContext) => Promise<IterationResult>;
|
|
21
|
+
|
|
22
|
+
export type ModeChangeCallback = (mode: 'local' | 'remote', isInitial: boolean) => void;
|
|
23
|
+
|
|
24
|
+
export interface ModeLoopOptions {
|
|
25
|
+
readonly cwd: string;
|
|
26
|
+
readonly claudeSessionId: string | null;
|
|
27
|
+
readonly localLauncher: ModeLauncher;
|
|
28
|
+
readonly remoteLauncher: ModeLauncher;
|
|
29
|
+
|
|
30
|
+
readonly onModeChange?: ModeChangeCallback;
|
|
31
|
+
|
|
32
|
+
readonly initialMode?: 'local' | 'remote';
|
|
33
|
+
readonly logger?: Logger;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ModeLoopController {
|
|
37
|
+
|
|
38
|
+
requestSwitch(to: 'local' | 'remote', message?: string): void;
|
|
39
|
+
|
|
40
|
+
getCurrentMode(): 'local' | 'remote';
|
|
41
|
+
|
|
42
|
+
requestExit(): void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export declare function modeLoop(opts: ModeLoopOptions): Promise<{
|
|
46
|
+
readonly controller: ModeLoopController;
|
|
47
|
+
readonly run: () => Promise<number>;
|
|
48
|
+
}>;
|
package/dist/modeLoop.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{createSilentLogger as h}from"./logger.js";export async function modeLoop(e){const r=e.logger??h();let t=e.initialMode??"local",n=null,a=null,i=!1,l=new AbortController;const u={requestSwitch(d,c){n=c??null,a=d,l.abort()},getCurrentMode(){return t},requestExit(){i=!0,l.abort()}};async function m(){let d=!0;for(;;){l=new AbortController,a=null;const c=t==="local"?e.localLauncher:e.remoteLauncher;e.onModeChange?.(t,d),d=!1,r.info({mode:t,hasPending:!!n,module:"daemon:modeLoop"},"mode loop iteration");const s={cwd:e.cwd,claudeSessionId:e.claudeSessionId,pendingMessage:n,abort:l.signal,getSwitchTarget:()=>a};n=null;let o;try{o=await c(s)}catch(g){r.error({err:g,mode:t,module:"daemon:modeLoop"},"launcher crashed"),o={type:"exit",code:1}}if(i)return r.info({module:"daemon:modeLoop"},"mode loop exit requested via controller"),0;if(o.type==="exit")return r.info({code:o.code,module:"daemon:modeLoop"},"mode loop exiting"),o.code;t=o.to,r.debug({to:o.to,module:"daemon:modeLoop"},"mode switch")}}return{controller:u,run:m}}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { NotificationEventType } from '@agentdock/wire';
|
|
2
|
+
export type NotificationProvider = 'feishu' | 'dingtalk' | 'wecom';
|
|
3
|
+
export type { NotificationEventType } from '@agentdock/wire';
|
|
4
|
+
export interface NotificationChannel {
|
|
5
|
+
readonly provider: NotificationProvider;
|
|
6
|
+
readonly webhook: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export declare function getNotificationBooleans(): {
|
|
10
|
+
feishu: boolean;
|
|
11
|
+
dingtalk: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export declare function getEnabledChannels(_eventType: NotificationEventType): NotificationChannel[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import i from"node:path";import{readJsonFile as s}from"./jsonFileUtils.js";import{getDaemonDir as r}from"./paths.js";function f(){return i.join(r(),"agent-settings.json")}function o(){return s(f(),{}).notification??{}}export function getNotificationBooleans(){const n=o();return{feishu:typeof n.feishu=="string"&&n.feishu.length>0,dingtalk:typeof n.dingtalk=="string"&&n.dingtalk.length>0}}export function getEnabledChannels(n){const t=o(),e=[];return t.feishu&&e.push({provider:"feishu",webhook:t.feishu}),t.dingtalk&&e.push({provider:"dingtalk",webhook:t.dingtalk}),t.wecom&&e.push({provider:"wecom",webhook:t.wecom}),e}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DispatchNotificationParams } from '@agentdock/wire';
|
|
2
|
+
export type NotificationEvent = DispatchNotificationParams;
|
|
3
|
+
export interface DispatchResult {
|
|
4
|
+
readonly provider: string;
|
|
5
|
+
readonly ok: boolean;
|
|
6
|
+
readonly error?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function dispatchNotification(event: NotificationEvent, log?: {
|
|
9
|
+
info?(msg: string, ...args: unknown[]): void;
|
|
10
|
+
error?(msg: string, ...args: unknown[]): void;
|
|
11
|
+
}): Promise<DispatchResult[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{sendFeishuCard as d}from"./adapters/feishu.js";import{sendDingtalkMarkdown as l}from"./adapters/dingtalk.js";import{getEnabledChannels as p}from"./notificationChannels.js";function h(e){switch(e){case"error":case"task_failed":case"daemon_disconnected":return"red";case"budget_warning":return"yellow";default:return"blue"}}export async function dispatchNotification(e,i){const n=p(e.type);if(n.length===0)return i?.info?.("notificationDispatcher: no enabled channels for event",e.type),[];const s=new Date(e.timestamp).toLocaleString("zh-CN",{timeZone:"Asia/Shanghai"}),c=e.machineHostname?`${e.machineHostname} | ${s}`:s,t=[];for(const a of n){const o={provider:a.provider};try{switch(a.provider){case"feishu":{const r=await d(a.webhook,{title:e.title,body:e.body,color:h(e.type),footer:c,url:e.data?.url});t.push(r.ok?{...o,ok:!0}:{...o,ok:!1,error:r.error});break}case"dingtalk":{const r=await l(a.webhook,{title:e.title,body:e.body,footer:c});t.push(r.ok?{...o,ok:!0}:{...o,ok:!1,error:r.error});break}case"wecom":i?.info?.("notificationDispatcher: wecom adapter not yet implemented, skipping"),t.push({...o,ok:!1,error:"wecom adapter not yet implemented"});break}}catch(r){i?.error?.("notificationDispatcher: dispatch failed",{provider:a.provider,error:String(r)}),t.push({...o,ok:!1,error:String(r)})}}return t}
|
package/dist/outbox.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { AgentdockClient } from '@agentdock/sdk';
|
|
2
|
+
import type { Logger } from './logger.js';
|
|
3
|
+
import type { EnvelopeContent } from '@agentdock/agent-runtime-contract/envelopeProtection';
|
|
4
|
+
|
|
5
|
+
export declare const MAX_OUTBOX = 2000;
|
|
6
|
+
export declare const MAX_PERSISTED_OUTBOX_BYTES: number;
|
|
7
|
+
|
|
8
|
+
export declare const MAX_OUTBOX_BYTES: number;
|
|
9
|
+
|
|
10
|
+
export declare const RATE_LIMIT_RETRY_MS = 1000;
|
|
11
|
+
|
|
12
|
+
export declare const EMIT_TIMEOUT_MS = 15000;
|
|
13
|
+
|
|
14
|
+
export declare const MAX_RETRIES = 5;
|
|
15
|
+
|
|
16
|
+
export declare function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T>;
|
|
17
|
+
|
|
18
|
+
export interface PendingMessage {
|
|
19
|
+
readonly sessionId: string;
|
|
20
|
+
readonly localId: string;
|
|
21
|
+
readonly content: EnvelopeContent;
|
|
22
|
+
readonly skipBroadcast?: boolean;
|
|
23
|
+
|
|
24
|
+
readonly ephemeral?: boolean;
|
|
25
|
+
retries: number;
|
|
26
|
+
}
|
|
27
|
+
export interface OutboxPersistence {
|
|
28
|
+
readonly filePath: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface OutboxStats {
|
|
32
|
+
readonly size: number;
|
|
33
|
+
readonly bytes: number;
|
|
34
|
+
readonly refusedCount: number;
|
|
35
|
+
readonly maxCount: number;
|
|
36
|
+
readonly maxBytes: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface EnqueueResult {
|
|
40
|
+
readonly ok: boolean;
|
|
41
|
+
readonly reason?: 'count' | 'bytes';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export declare function createOutbox(client: AgentdockClient, log?: Logger, onAcknowledged?: (msg: PendingMessage) => void, canSend?: (sessionId: string) => boolean, persistence?: OutboxPersistence): {
|
|
45
|
+
enqueue: (msg: PendingMessage) => EnqueueResult;
|
|
46
|
+
drain: () => Promise<void>;
|
|
47
|
+
getStats: () => OutboxStats;
|
|
48
|
+
hasPending: (sessionId: string) => boolean;
|
|
49
|
+
};
|
package/dist/outbox.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import h from"node:fs";import T from"node:path";import{errnoCode as b}from"./typeGuards.js";export const MAX_OUTBOX=2e3,MAX_PERSISTED_OUTBOX_BYTES=16*1024*1024,MAX_OUTBOX_BYTES=MAX_PERSISTED_OUTBOX_BYTES,RATE_LIMIT_RETRY_MS=1e3,EMIT_TIMEOUT_MS=15e3,MAX_RETRIES=5;export function withTimeout(n,o){let s;return Promise.race([n,new Promise((a,i)=>{s=setTimeout(()=>i(new Error("emitWithAck timeout")),o)})]).finally(()=>clearTimeout(s))}function y(n){return Buffer.byteLength(JSON.stringify(n.content),"utf8")}export function createOutbox(n,o,s,a,i){const r=w(i?.filePath,o);let c=r.reduce((e,t)=>e+y(t),0),g=0,f=0,u=null;function m(){if(i)try{h.mkdirSync(T.dirname(i.filePath),{recursive:!0});const e=`${i.filePath}.tmp`,t=JSON.stringify(r);if(Buffer.byteLength(t,"utf8")>MAX_PERSISTED_OUTBOX_BYTES){o?.warn({module:"daemon:server-client",maxBytes:MAX_PERSISTED_OUTBOX_BYTES},"outbox persistence reached byte limit; retaining in-memory queue only");return}h.writeFileSync(e,t,{mode:384}),h.renameSync(e,i.filePath)}catch{o?.warn({module:"daemon:server-client"},"outbox persistence failed")}}async function S(){for(;r.length>0&&n.getStatus()==="connected";){const e=r[0];if(!e||a&&!a(e.sessionId))break;try{const t=await withTimeout(n.emitWithAck("message",{sessionId:e.sessionId,localId:e.localId,content:e.content,...e.skipBroadcast?{skipBroadcast:!0}:{},...e.ephemeral?{ephemeral:!0}:{}}),EMIT_TIMEOUT_MS);t.ok?(r.shift(),c-=y(e),n.getStatus()!=="connected"&&m(),s?.(e),o?.info({localId:e.localId,seq:t.seq,module:"daemon:server-client"},"sendEnvelope: ok")):t.error?.includes("rate_limited")?(o?.warn({localId:e.localId,error:t.error,module:"daemon:server-client"},"sendEnvelope: rate limited, waiting"),await new Promise(d=>setTimeout(d,RATE_LIMIT_RETRY_MS))):(r.shift(),c-=y(e),n.getStatus()!=="connected"&&m(),o?.warn({localId:e.localId,error:t.error,module:"daemon:server-client"},"sendEnvelope: server rejected, skipping"))}catch(t){if(t instanceof Error&&t.message==="emitWithAck timeout")if(e.retries++,e.retries>=MAX_RETRIES){const p=r.shift();p&&(p.retries=0,r.push(p),n.getStatus()!=="connected"&&m()),o?.warn({localId:e.localId,outboxSize:r.length,module:"daemon:server-client"},"sendEnvelope: max retries reached, recycled to back of queue")}else{o?.warn({localId:e.localId,retries:e.retries,outboxSize:r.length,module:"daemon:server-client"},"sendEnvelope: ack timeout, will retry");break}else{o?.info({outboxSize:r.length,module:"daemon:server-client"},"sendEnvelope: disconnected, pausing drain");break}}}}function l(){return u||(u=S().finally(()=>{u=null,r.length>0&&n.getStatus()==="connected"&&setTimeout(()=>{l()},RATE_LIMIT_RETRY_MS)}),u)}function I(e){const t=y(e);if(r.length>=MAX_OUTBOX||c+t>MAX_OUTBOX_BYTES){const d=r.length>=MAX_OUTBOX?"count":"bytes";return g++,f++,(f===1||f%100===0)&&o?.warn({reason:d,size:r.length,bytes:c,refusedSinceLog:f,module:"daemon:server-client"},"outbox full, refusing new message"),{ok:!1,reason:d}}return r.push(e),c+=t,n.getStatus()!=="connected"&&m(),l(),{ok:!0}}n.onStatusChange(e=>{if(e==="connected"&&r.length>0){o?.info({outboxSize:r.length,module:"daemon:server-client"},"reconnected, draining outbox");const t=u;t?t.then(()=>l(),()=>l()):l()}});function x(){return{size:r.length,bytes:c,refusedCount:g,maxCount:MAX_OUTBOX,maxBytes:MAX_OUTBOX_BYTES}}function v(e){return r.some(t=>t.sessionId===e)}return{enqueue:I,drain:l,getStats:x,hasPending:v}}function w(n,o){if(!n)return[];try{const s=JSON.parse(h.readFileSync(n,"utf8"));return Array.isArray(s)?s.filter(a=>{if(!a||typeof a!="object")return!1;const i=a;return typeof i.sessionId=="string"&&typeof i.localId=="string"&&i.content!==void 0}):[]}catch(s){return b(s)==="ENOENT"?[]:(o?.warn({filePath:n,errno:b(s),module:"daemon:server-client"},"outbox persistence unreadable; queued messages were NOT restored"),[])}}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare function migrateFromLegacyDir(homeDir?: string): void;
|
|
2
|
+
|
|
3
|
+
export declare function migrateFromProfilesProd(homeDir?: string): void;
|
|
4
|
+
|
|
5
|
+
export declare function migrateCredentialsToBrand(homeDir?: string): void;
|
|
6
|
+
|
|
7
|
+
export declare function migrateDataDir(fromDir: string, toDir: string): void;
|
|
8
|
+
|
|
9
|
+
export declare function getDaemonDir(): string;
|
|
10
|
+
|
|
11
|
+
export declare function isProfileBasedPath(p: string): boolean;
|
|
12
|
+
|
|
13
|
+
export declare function getLockPath(): string;
|
|
14
|
+
|
|
15
|
+
export declare function getStatePath(): string;
|
|
16
|
+
|
|
17
|
+
export declare function getLogPath(): string;
|
|
18
|
+
|
|
19
|
+
export declare function getCliEntryPath(callerImportMetaUrl: string): string;
|
|
20
|
+
|
|
21
|
+
export declare function tryAutoCreateDir(cwd: string): Promise<{
|
|
22
|
+
exists: boolean;
|
|
23
|
+
isDirectory: boolean;
|
|
24
|
+
}>;
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import n from"node:fs";import t from"node:path";import d from"node:os";import{fileURLToPath as j}from"node:url";import{getBrand as l,getDefaultBrand as S}from"./brand.js";import{getDeployment as f}from"./deployment.js";const g=".agentbox";function p(){return`${l().dataDir}${f().dataDirSuffix}`}const x="daemon.pid",D="daemon.state.json",P=t.join("logs","daemon.log"),L=["credentials.json","daemon.pid","daemon.state.json","agent-settings.json","secret","stats-state.json"];export function migrateFromLegacyDir(c){const r=c??d.homedir(),e=t.join(r,g),o=t.join(r,l().dataDir);try{n.accessSync(e)}catch{return}try{n.accessSync(o);return}catch{}n.renameSync(e,o)}export function migrateFromProfilesProd(c){const r=c??d.homedir(),e=t.join(r,l().dataDir),o=t.join(e,"profiles","prod");try{n.accessSync(o)}catch{return}try{n.accessSync(t.join(e,"credentials.json"));return}catch{}for(const m of L){const h=t.join(o,m),u=t.join(e,m);try{n.accessSync(h);try{n.accessSync(u)}catch{n.renameSync(h,u)}}catch{}}const s=t.join(o,"tmp"),a=t.join(e,"tmp");try{n.accessSync(s);try{n.accessSync(a)}catch{n.renameSync(s,a)}}catch{}try{for(const m of n.readdirSync(o)){const h=t.join(o,m),u=t.join(e,m);try{n.accessSync(u)}catch{n.renameSync(h,u)}}}catch{}const y=t.join(e,"daemon.log"),i=t.join(e,"logs");try{n.accessSync(y),n.mkdirSync(i,{recursive:!0});try{n.accessSync(t.join(i,"daemon.log"))}catch{n.renameSync(y,t.join(i,"daemon.log"))}}catch{}try{n.rmdirSync(o)}catch{}try{n.rmdirSync(t.join(e,"profiles"))}catch{}}export function migrateCredentialsToBrand(c){const r=p(),e=S().dataDir;if(r===e)return;const o=c??d.homedir(),s=t.join(o,e),a=t.join(o,r),y=t.join(s,"credentials.json"),i=t.join(a,"credentials.json");try{n.accessSync(y)}catch{return}try{n.accessSync(i);return}catch{}n.mkdirSync(a,{recursive:!0}),n.copyFileSync(y,i)}export function migrateDataDir(c,r){try{n.accessSync(c)}catch{return}try{n.accessSync(t.join(r,"daemon.state.json"));return}catch{}try{n.accessSync(t.join(r,"credentials.json"));return}catch{}n.mkdirSync(r,{recursive:!0});for(const e of n.readdirSync(c)){const o=t.join(c,e),s=t.join(r,e);try{n.accessSync(s)}catch{n.cpSync(o,s,{recursive:!0})}}}export function getDaemonDir(){const c=p(),r=process.env.AGENTDOCK_PROFILE||f().defaultProfile;return r?t.join(d.homedir(),c,"profiles",r):t.join(d.homedir(),c)}export function isProfileBasedPath(c){const r=p();return c.includes(`${t.sep}${r}${t.sep}profiles${t.sep}`)}export function getLockPath(){return t.join(getDaemonDir(),x)}export function getStatePath(){return t.join(getDaemonDir(),D)}export function getLogPath(){return t.join(getDaemonDir(),P)}export function getCliEntryPath(c){const r=j(c),e=t.extname(r);return t.join(t.dirname(r),`cli${e}`)}export async function tryAutoCreateDir(c){const r=t.resolve(c),e=d.homedir(),o=process.cwd(),s=f().extraWorkspaceRoot;if(r.startsWith(e+t.sep)||r===e||r.startsWith(o+t.sep)||r===o||s!==null&&(r===s||r.startsWith(`${s}${t.sep}`)))try{return await n.promises.mkdir(r,{recursive:!0}),{exists:!0,isDirectory:!0}}catch{}return{exists:!1,isDirectory:!1}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{getSessionContextBoundary as n}from"@agentdock/wire";export function createPlaintextEnvelopeKeyManager(){return{kind:"plaintext",async serialize(i,t){const e=n(t);return{c:JSON.stringify(t),t:"plaintext",...t.messageUuid?{messageUuid:t.messageUuid}:{},...e?{contextBoundary:e}:{}}}}}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ChildProcess } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
export declare function killProcessTree(child: ChildProcess): void;
|
|
4
|
+
|
|
5
|
+
export declare function killProcessTreeByPid(pid: number): void;
|
|
6
|
+
|
|
7
|
+
export declare function killProcessTreeByPidAndWait(pid: number, timeoutMs?: number): Promise<void>;
|
|
8
|
+
|
|
9
|
+
export declare function killOwnChildProcessTrees(excludePids?: ReadonlySet<number>): void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";import{exec as t,execSync as f}from"node:child_process";const o=process.platform==="win32";export function killProcessTree(e){o&&e.pid?t(`taskkill /T /F /PID ${e.pid}`,{windowsHide:!0},i=>{i&&process.stderr.write(`taskkill failed for PID ${e.pid}: ${i.message}
|
|
2
|
+
`)}):e.kill("SIGTERM")}export function killProcessTreeByPid(e){o?t(`taskkill /T /F /PID ${e}`,{windowsHide:!0},i=>{i&&process.stderr.write(`taskkill failed for PID ${e}: ${i.message}
|
|
3
|
+
`)}):process.kill(e,"SIGTERM")}function l(e){try{return process.kill(e,0),!0}catch(i){return i.code==="EPERM"}}export async function killProcessTreeByPidAndWait(e,i=5e3){if(!l(e))return;if(o)await new Promise((s,r)=>{t(`taskkill /T /F /PID ${e}`,{windowsHide:!0},c=>{if(!c||!l(e)){s();return}r(c)})});else try{process.kill(e,"SIGTERM")}catch(s){if(s.code==="ESRCH")return;throw s}const n=Date.now()+i;for(;l(e);){if(Date.now()>=n)throw new Error(`process tree ${e} did not exit within ${i}ms`);await new Promise(s=>setTimeout(s,25))}}export function killOwnChildProcessTrees(e){if(o)try{const i=f(`wmic process where "ParentProcessId=${process.pid}" get ProcessId /format:csv`,{encoding:"utf8",timeout:3e3,windowsHide:!0});for(const n of i.split(`
|
|
4
|
+
`)){const s=n.trim().split(",").pop();if(s&&/^\d+$/.test(s)&&Number(s)!==process.pid){if(e?.has(Number(s)))continue;t(`taskkill /T /F /PID ${s}`,{windowsHide:!0},r=>{r&&process.stderr.write(`taskkill failed for PID ${s}: ${r.message}
|
|
5
|
+
`)})}}}catch{}}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RpcMethodType, LabsSettings, AccountLanguage } from '@agentdock/wire';
|
|
2
|
+
import type { ServerClient } from './serverClient.js';
|
|
3
|
+
import type { Logger } from './logger.js';
|
|
4
|
+
import type { TelemetryCollector } from './telemetryCollector.js';
|
|
5
|
+
export declare function registerMachineOnConnect(client: Pick<ServerClient, 'registerRpcMethods' | 'registerMachine'>, methods: readonly RpcMethodType[], machineInfo: Parameters<ServerClient['registerMachine']>[0], log: Logger, onLatestVersion?: (version: string) => void, telemetry?: TelemetryCollector, onLabsSettings?: (settings: LabsSettings) => void, onAccountId?: (accountId: string) => void, onPreferredLanguage?: (language: AccountLanguage) => void, onMachineUnpaired?: () => void): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{errorMessage as d}from"@agentdock/wire";export async function registerMachineOnConnect(t,l,c,r,a,i,n,o,s,m){try{await t.registerRpcMethods(l)}catch(e){r.error({err:e,module:"machine:connect"},"failed to register daemon RPC methods on connect"),i?.emit({type:"rpc.call_failed",code:"rpc.call_failed",message:"failed to register daemon RPC methods on connect",context:{method:"registerRpcMethods",error:d(e)}});return}try{r.info({module:"machine:connect",availableAgents:c.availableAgents??[]},"registering machine with server");const e=await t.registerMachine(c);if(!e.ok){r.warn({error:e.error,module:"machine:connect"},"machine registration rejected by server"),e.error==="machine-unpaired"&&m?.();return}e?.ok&&e.accountId&&o&&o(e.accountId),e?.latestVersion&&a&&a(e.latestVersion),e?.labsSettings&&n&&n(e.labsSettings),e?.preferredLanguage&&s&&s(e.preferredLanguage)}catch(e){r.error({err:e,module:"machine:connect"},"failed to register machine on connect"),i?.emit({type:"rpc.call_failed",code:"rpc.call_failed",message:"failed to register machine on connect",context:{method:"registerMachine",error:d(e)}})}}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AccountLanguage } from '@agentdock/wire';
|
|
2
|
+
export declare function resolveResponseLanguage(value?: AccountLanguage): AccountLanguage;
|
|
3
|
+
export declare function buildResponseLanguageInstruction(language: AccountLanguage): string;
|
|
4
|
+
|
|
5
|
+
export declare function toClaudeLanguageSetting(language: AccountLanguage): string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";import{getBrand as n}from"./brand.js";import{loadPreferredLanguage as s}from"./serverSettingsCache.js";export function resolveResponseLanguage(e){return e??s()??n().defaultAccountLanguage}export function buildResponseLanguageInstruction(e){return{en:`## Response language
|
|
2
|
+
|
|
3
|
+
Always respond in English, even if the user writes in another language. Respond to the user in English. This is a firm requirement that overrides matching the user's language \u2014 never switch to the user's language instead of English. Preserve code, commands, identifiers, paths, and quoted source text as-is.`,"zh-Hans":`## Response language
|
|
4
|
+
|
|
5
|
+
Always respond in Simplified Chinese, even if the user writes in another language. Respond to the user in Simplified Chinese. This is a firm requirement that overrides matching the user's language \u2014 never switch to the user's language instead of Simplified Chinese. Preserve code, commands, identifiers, paths, and quoted source text as-is.`}[e]}export function toClaudeLanguageSetting(e){return e==="zh-Hans"?"Chinese":"English"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BrandConfig } from './brand.js';
|
|
2
|
+
export interface RuntimeTarget {
|
|
3
|
+
readonly brand: BrandConfig;
|
|
4
|
+
readonly profile: string;
|
|
5
|
+
readonly sourceRun: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export declare function getRuntimeTargetError(target: RuntimeTarget): string | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export function getRuntimeTargetError(n){if(!(!(n.brand.npmPkg==="ccpark"||n.brand.npmPkg==="yarkai")||n.profile!=="dev"||!n.sourceRun))return[`Refusing to start ${n.brand.npmPkg} daemon in source/dev mode.`,"This would use the production brand with the development profile.","Use AGENTDOCK_PROFILE=dev AGENTDOCK_NPM_PACKAGE=agentdock for local development."].join(" ")}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Logger } from './logger.js';
|
|
2
|
+
import type { SessionSink } from '@agentdock/agent-runtime-contract/sessionSink';
|
|
3
|
+
|
|
4
|
+
export declare function sendClearedContextUsage(serverClient: SessionSink, sessionId: string, model: string | undefined, log: Logger): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{emptyContextUsageSnapshot as n}from"@agentdock/wire";export async function sendClearedContextUsage(e,t,a,o){try{await e.sendContextUsage(t,n(a??""))}catch(r){o.error({err:r,module:"daemon:remote"},"failed to send cleared context-usage snapshot after /clear")}}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { ConnectionStatus, StatusListener, Unsubscribe } from '@agentdock/sdk';
|
|
2
|
+
import type { SessionEnvelope, RpcResult, ActivityPreferences, AccountLanguage } from '@agentdock/wire';
|
|
3
|
+
import { type DirectEnvelopeAck } from './directEnvelopeDelivery.js';
|
|
4
|
+
import type { CreateSessionResult, MachineRegisterInfo, SessionAliveResult, SdkClientFactory, ServerClientConfig, ServerClientOptions } from './serverClientTypes.js';
|
|
5
|
+
export type { ServerClientConfig, CreateSessionResult, SessionAliveResult, MachineRegisterInfo, } from './serverClientTypes.js';
|
|
6
|
+
export type RpcRequestHandler = (method: string, params: Record<string, unknown>) => Promise<RpcResult>;
|
|
7
|
+
export type { MachineRegisterResult } from '@agentdock/wire';
|
|
8
|
+
import type { MachineRegisterResult } from '@agentdock/wire';
|
|
9
|
+
|
|
10
|
+
export interface ServerClient {
|
|
11
|
+
connect(): void;
|
|
12
|
+
disconnect(): void;
|
|
13
|
+
getStatus(): ConnectionStatus;
|
|
14
|
+
onStatusChange(listener: StatusListener): Unsubscribe;
|
|
15
|
+
sendEnvelope(sessionId: string, envelope: SessionEnvelope, opts?: {
|
|
16
|
+
readonly skipBroadcast?: boolean;
|
|
17
|
+
readonly ephemeral?: boolean;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
|
|
20
|
+
sendContextUsage(sessionId: string, data: Record<string, unknown>): Promise<void>;
|
|
21
|
+
createSession(tag: string, metadata?: string, dataEncryptionKey?: string, opts?: {
|
|
22
|
+
readonly source?: string;
|
|
23
|
+
readonly claudeSessionId?: string;
|
|
24
|
+
readonly projectPath?: string;
|
|
25
|
+
readonly handoffEnabled?: boolean;
|
|
26
|
+
readonly inheritedFrom?: readonly string[];
|
|
27
|
+
}): Promise<CreateSessionResult>;
|
|
28
|
+
sendSessionAlive(sessionId: string, opts?: {
|
|
29
|
+
readonly takeoverToken?: string;
|
|
30
|
+
}): Promise<SessionAliveResult | null>;
|
|
31
|
+
|
|
32
|
+
checkSessionResume(sessionId: string): Promise<{
|
|
33
|
+
ok: boolean;
|
|
34
|
+
error?: string;
|
|
35
|
+
} | null>;
|
|
36
|
+
|
|
37
|
+
prepareSessionResume(sessionId: string): Promise<{
|
|
38
|
+
ok: boolean;
|
|
39
|
+
takeoverToken?: string;
|
|
40
|
+
error?: string;
|
|
41
|
+
} | null>;
|
|
42
|
+
|
|
43
|
+
sendLivenessHeartbeat(sessionId: string): void;
|
|
44
|
+
sendSessionEnd(sessionId: string, summary?: string): Promise<void>;
|
|
45
|
+
|
|
46
|
+
drain(): Promise<void>;
|
|
47
|
+
|
|
48
|
+
waitForSessionDelivery(sessionId: string): Promise<boolean>;
|
|
49
|
+
|
|
50
|
+
sendSessionSummary(sessionId: string, summary: string): void;
|
|
51
|
+
|
|
52
|
+
registerRpcMethods(methods: readonly string[]): Promise<void>;
|
|
53
|
+
|
|
54
|
+
onRpcRequest(handler: RpcRequestHandler): Unsubscribe;
|
|
55
|
+
|
|
56
|
+
onActivityPreferencesChanged(handler: (prefs: ActivityPreferences) => void): Unsubscribe;
|
|
57
|
+
|
|
58
|
+
onImprovementPreferencesChanged(handler: (prefs: {
|
|
59
|
+
enabled: boolean;
|
|
60
|
+
}) => void): Unsubscribe;
|
|
61
|
+
|
|
62
|
+
onAccountLanguageChanged(handler: (language: AccountLanguage) => void): Unsubscribe;
|
|
63
|
+
|
|
64
|
+
onHistorySessionBlocked(handler: (payload: {
|
|
65
|
+
claudeSessionId: string;
|
|
66
|
+
}) => void): Unsubscribe;
|
|
67
|
+
|
|
68
|
+
registerMachine(info: MachineRegisterInfo): Promise<MachineRegisterResult>;
|
|
69
|
+
|
|
70
|
+
sendSessionStatus(sessionId: string, status: string): void;
|
|
71
|
+
|
|
72
|
+
sendPermissionResolved(sessionId: string, requestId: string): void;
|
|
73
|
+
|
|
74
|
+
emit(event: string, data: unknown): void;
|
|
75
|
+
|
|
76
|
+
updateMetadata(sessionId: string, metadata: string, expectedVersion: number): Promise<void>;
|
|
77
|
+
|
|
78
|
+
sendUsageReport(data: {
|
|
79
|
+
sessionId: string;
|
|
80
|
+
model: string;
|
|
81
|
+
tokens: {
|
|
82
|
+
inputTokens: number;
|
|
83
|
+
outputTokens: number;
|
|
84
|
+
cacheReadInputTokens: number;
|
|
85
|
+
cacheCreationInputTokens: number;
|
|
86
|
+
};
|
|
87
|
+
}): void;
|
|
88
|
+
|
|
89
|
+
sendEnvelopeDirect(sessionId: string, envelope: SessionEnvelope, opts?: {
|
|
90
|
+
readonly skipBroadcast?: boolean;
|
|
91
|
+
}): Promise<DirectEnvelopeAck>;
|
|
92
|
+
|
|
93
|
+
recoverSessionDek(sessionId: string, wrappedDekBase64: string): Promise<boolean>;
|
|
94
|
+
|
|
95
|
+
provisionSessionDek(sessionId: string): Promise<string | null>;
|
|
96
|
+
|
|
97
|
+
getSessionDek(sessionId: string): Uint8Array | null;
|
|
98
|
+
|
|
99
|
+
emitWithAck<T>(event: string, data: unknown, timeoutMs?: number): Promise<T>;
|
|
100
|
+
|
|
101
|
+
onFileRelayChunk(handler: (payload: Record<string, unknown>, ack: (result: Record<string, unknown>) => void) => void): Unsubscribe;
|
|
102
|
+
|
|
103
|
+
onFileRelayComplete(handler: (payload: Record<string, unknown>, ack: (result: Record<string, unknown>) => void) => void): Unsubscribe;
|
|
104
|
+
}
|
|
105
|
+
export type { SdkClientFactory, ServerClientOptions } from './serverClientTypes.js';
|
|
106
|
+
|
|
107
|
+
export declare function createServerClient(config: ServerClientConfig, factory?: SdkClientFactory, options?: ServerClientOptions): ServerClient;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{createEnvelope as T,errorMessage as D,SOCKET_EVENTS as a}from"@agentdock/wire";import{logSessionStatusSent as P,logSessionStatusSkipped as N}from"./logger.js";import{createEnvelopeOutbound as O}from"./envelopeOutbound.js";import{createOutbox as I,withTimeout as M}from"./outbox.js";import{getDaemonDir as U}from"./paths.js";import F from"node:path";import{createDirectEnvelopeDelivery as G}from"./directEnvelopeDelivery.js";import{isRecord as h}from"./typeGuards.js";import{recoverSessionDek as W,provisionSessionDek as K,getSessionDek as L}from"./dekMethods.js";import{createSdkClientFactory as b}from"./serverClientFactory.js";import{onAccountLanguageChanged as x,onPreferencesChanged as v}from"./serverClientEventHandlers.js";import{randomUUID as H}from"node:crypto";export function createServerClient(y,w,E){const r=w?.(y)??b(y,E?.onAuthError,E?.onUpgradeRequired),s=E?.logger,{keys:k,serializeEnvelope:p}=O(E?.envelope,s),A=new Map,R=H(),l=new Map,d=new Map,m=new Set,u=e=>!m.has(e),f=new Set,S=I(r,s,e=>{f.delete(`${e.sessionId}:${e.localId}`)},u,{filePath:F.join(U(),"offline-outbox.json")}),C=G({client:r,outbox:S,serialize:p,canWriteSession:u,log:s});return r.onStatusChange(e=>{if(!(e!=="disconnected"&&e!=="error"))for(const n of l.keys()){m.add(n);const t=d.get(n)??{};t.connectionGeneration=(BigInt(t.connectionGeneration??"0")+1n).toString(),d.set(n,t)}}),{connect(){r.connect()},disconnect(){r.disconnect()},getStatus(){return r.getStatus()},onStatusChange(e){return r.onStatusChange(e)},async sendEnvelope(e,n,t){const o=`${e}:${n.id}`;if(f.has(o))return;const i=await p(e,n);if(!i)return;f.add(o);const c=S.enqueue({sessionId:e,localId:n.id,content:i,skipBroadcast:t?.skipBroadcast,ephemeral:t?.ephemeral,retries:0});c.ok||(f.delete(o),s?.warn({sessionId:e,reason:c.reason,...S.getStats(),module:"daemon:server-client"},"sendEnvelope: outbox full, message refused (conversation content not queued)"))},async sendContextUsage(e,n){if(!u(e))return;const t=T("agent",{t:"context-usage",...n}),o=await p(e,t);if(!o)return;const i=await r.emitWithAck(a.CONTEXT_USAGE_UPDATE,{sessionId:e,contextUsage:o});i&&!i.ok&&s?.warn({sessionId:e,error:i.error,module:"daemon:serverClient"},"context-usage-update rejected by server")},async createSession(e,n,t,o){const i={tag:e,ownerInstanceId:R};n!==void 0&&(i.metadata=n),t!==void 0&&(i.dataEncryptionKey=t),o?.source&&(i.source=o.source),o?.claudeSessionId&&(i.claudeSessionId=o.claudeSessionId),o?.projectPath&&(i.projectPath=o.projectPath),o?.handoffEnabled!==void 0&&(i.handoffEnabled=o.handoffEnabled),o?.inheritedFrom&&(i.inheritedFrom=o.inheritedFrom);const c=await r.emitWithAck(a.SESSION_CREATE,i);return c.ok&&c.sessionId&&c.reconnectKey&&(l.set(c.sessionId,c.reconnectKey),d.set(c.sessionId,{ownerEpoch:c.ownerEpoch,connectionGeneration:c.connectionGeneration})),c},async sendSessionAlive(e,n){const t=A.get(e),o=l.get(e),i=await r.emitWithAck(a.SESSION_ALIVE,{sessionId:e,...t?{runtimeStatus:t}:{},ownerInstanceId:R,...o?{reconnectKey:o}:{},...d.get(e)??{},...n?.takeoverToken?{takeoverToken:n.takeoverToken}:{}});return i?.ok&&(i.reconnectKey&&l.set(e,i.reconnectKey),d.set(e,{ownerEpoch:i.ownerEpoch??d.get(e)?.ownerEpoch,connectionGeneration:i.connectionGeneration??d.get(e)?.connectionGeneration}),m.delete(e)&&S.drain()),i&&!i.ok&&s?.warn({sessionId:e,error:i.error,module:"daemon:serverClient"},"session-alive rejected by server"),i??null},async checkSessionResume(e){return await r.emitWithAck(a.SESSION_RESUME_CHECK,{sessionId:e})??null},async prepareSessionResume(e){return await r.emitWithAck(a.SESSION_RESUME_TAKEOVER,{sessionId:e})??null},sendLivenessHeartbeat(e){m.has(e)||r.emit(a.LIVENESS_HEARTBEAT,{sessionId:e})},async sendSessionEnd(e,n){if(!u(e))return;const t={sessionId:e};n&&(t.summary=n),await r.emitWithAck(a.SESSION_END,t)},async registerRpcMethods(e){for(const n of e)await r.emitWithAck(a.RPC_REGISTER,{method:n})},onRpcRequest(e){return r.on(a.RPC_REQUEST,async(...n)=>{const t=n[0],o=n[1];if(!h(t)){s?.warn({module:"daemon:serverClient"},"RPC request: invalid payload from server"),o?.({ok:!1,error:"invalid-request"});return}const i=typeof t.method=="string"?t.method:"",c=h(t.params)?t.params:{};try{const g=await e(i,c);o?.(g)}catch(g){const _=D(g);o?.({ok:!1,error:_})}})},onActivityPreferencesChanged(e){return v(r,a.ACTIVITY_PREFERENCES_CHANGED,e)},onImprovementPreferencesChanged(e){return v(r,a.IMPROVEMENT_PREFERENCES_CHANGED,e)},onAccountLanguageChanged(e){return x(r,e)},onHistorySessionBlocked(e){return r.on(a.HISTORY_SESSION_BLOCKED,(...n)=>{const t=n[0];t?.claudeSessionId&&e({claudeSessionId:t.claudeSessionId})})},async registerMachine(e){return r.emitWithAck(a.MACHINE_REGISTER,e)},sendSessionStatus(e,n){const t=n==="turn-completed"?"idle":n;if((t==="idle"||t==="thinking"||t==="tool_running"||t==="permission_required"||t==="disconnected")&&A.set(e,t),!u(e)){N(s,e,n);return}P(s,e,n,t),r.emit(a.SESSION_STATUS,{sessionId:e,status:n})},sendSessionSummary(e,n){u(e)&&r.emit(a.SESSION_SUMMARY,{sessionId:e,summary:n})},sendPermissionResolved(e,n){u(e)&&r.emit(a.PERMISSION_RESOLVED,{sessionId:e,requestId:n})},emit(e,n){r.emit(e,n)},async updateMetadata(e,n,t){if(!u(e))throw new Error("session reconnecting");const o=await r.emitWithAck(a.UPDATE_METADATA,{sessionId:e,metadata:n,expectedVersion:t});if(o&&!o.ok){const i=new Error(o.error??"update-metadata failed");throw i.serverVersion=o.serverVersion,i}},sendUsageReport(e){u(e.sessionId)&&r.emit(a.USAGE_REPORT,e)},async emitWithAck(e,n,t){return t?M(r.emitWithAck(e,n),t):r.emitWithAck(e,n)},onFileRelayChunk(e){return r.on(a.FILE_RELAY_CHUNK,(...n)=>{const t=n[0],o=n[1];h(t)&&e(t,o??(()=>{}))})},onFileRelayComplete(e){return r.on(a.FILE_RELAY_COMPLETE,(...n)=>{const t=n[0],o=n[1];h(t)&&e(t,o??(()=>{}))})},async recoverSessionDek(e,n){return W(k,e,n)},async provisionSessionDek(e){return K(r,k,s,e)},getSessionDek(e){return L(k,e)},async sendEnvelopeDirect(e,n,t){return C(e,n,t)},async drain(){await S.drain()},async waitForSessionDelivery(e){return await S.drain(),r.getStatus()==="connected"&&!S.hasPending(e)}}}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentdockClient, Unsubscribe } from '@agentdock/sdk';
|
|
2
|
+
import type { AccountLanguage } from '@agentdock/wire';
|
|
3
|
+
export declare function onPreferencesChanged(client: AgentdockClient, event: string, handler: (prefs: {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
}) => void): Unsubscribe;
|
|
6
|
+
export declare function onAccountLanguageChanged(client: AgentdockClient, handler: (language: AccountLanguage) => void): Unsubscribe;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{isAccountLanguage as t,SOCKET_EVENTS as a}from"@agentdock/wire";import{isRecord as c}from"./typeGuards.js";export function onPreferencesChanged(n,o,r){return n.on(o,e=>{if(c(e)&&c(e.preferences)){const f=e.preferences;typeof f.enabled=="boolean"&&r(f)}})}export function onAccountLanguageChanged(n,o){return n.on(a.ACCOUNT_LANGUAGE_CHANGED,(...r)=>{const e=r[0];c(e)&&t(e.language)&&o(e.language)})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{createClient as o}from"@agentdock/sdk";import{PROTOCOL_VERSION as r}from"@agentdock/wire";export function createSdkClientFactory(e,t,n){return o({endpoint:e.endpoint,token:e.token,clientType:"machine-scoped",machineId:e.machineId,protocolVersion:r,onAuthError:t,onUpgradeRequired:n})}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { AgentdockClient } from '@agentdock/sdk';
|
|
2
|
+
import type { EnvelopeKeyManager } from '@agentdock/agent-runtime-contract/envelopeProtection';
|
|
3
|
+
import type { Logger } from './logger.js';
|
|
4
|
+
|
|
5
|
+
export interface ServerClientOptions {
|
|
6
|
+
|
|
7
|
+
readonly envelope: EnvelopeKeyManager;
|
|
8
|
+
|
|
9
|
+
readonly logger?: Logger;
|
|
10
|
+
|
|
11
|
+
readonly onAuthError?: () => void;
|
|
12
|
+
|
|
13
|
+
readonly onUpgradeRequired?: () => void;
|
|
14
|
+
}
|
|
15
|
+
export interface ServerClientConfig {
|
|
16
|
+
readonly endpoint: string;
|
|
17
|
+
readonly token: string;
|
|
18
|
+
readonly machineId: string;
|
|
19
|
+
}
|
|
20
|
+
export type SdkClientFactory = (config: ServerClientConfig) => AgentdockClient;
|
|
21
|
+
export interface CreateSessionResult {
|
|
22
|
+
readonly ok: boolean;
|
|
23
|
+
readonly sessionId?: string;
|
|
24
|
+
readonly error?: string;
|
|
25
|
+
readonly reconnectKey?: string;
|
|
26
|
+
readonly ownerEpoch?: string;
|
|
27
|
+
readonly connectionGeneration?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface SessionAliveResult {
|
|
30
|
+
readonly ok: boolean;
|
|
31
|
+
readonly error?: string;
|
|
32
|
+
readonly reconnectKey?: string;
|
|
33
|
+
readonly ownerEpoch?: string;
|
|
34
|
+
readonly connectionGeneration?: string;
|
|
35
|
+
readonly metadata?: string;
|
|
36
|
+
readonly dataEncryptionKey?: string | null;
|
|
37
|
+
readonly handoffEnabled?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface MachineRegisterInfo {
|
|
40
|
+
readonly hostname: string;
|
|
41
|
+
readonly platform: string;
|
|
42
|
+
readonly arch?: string;
|
|
43
|
+
readonly displayName?: string;
|
|
44
|
+
readonly daemonVersion?: string;
|
|
45
|
+
readonly availableAgents?: readonly string[];
|
|
46
|
+
readonly agentVersions?: Readonly<Record<string, string>>;
|
|
47
|
+
readonly lastUpgradeError?: string;
|
|
48
|
+
readonly derivationVersion?: number;
|
|
49
|
+
|
|
50
|
+
readonly autoUpgradeDaemon?: boolean;
|
|
51
|
+
|
|
52
|
+
readonly notifyFeishu?: boolean;
|
|
53
|
+
|
|
54
|
+
readonly notifyDingtalk?: boolean;
|
|
55
|
+
readonly agentModels?: Readonly<Record<string, readonly {
|
|
56
|
+
id: string;
|
|
57
|
+
displayName: string;
|
|
58
|
+
isDefault: boolean;
|
|
59
|
+
hidden: boolean;
|
|
60
|
+
}[]>>;
|
|
61
|
+
readonly agentModes?: Readonly<Record<string, readonly {
|
|
62
|
+
id: string;
|
|
63
|
+
label: string;
|
|
64
|
+
}[]>>;
|
|
65
|
+
|
|
66
|
+
readonly capabilities?: readonly string[];
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export{};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type AccountLanguage, type LabsSettings } from '@agentdock/wire';
|
|
2
|
+
export declare function loadLabsSettings(): LabsSettings;
|
|
3
|
+
export declare function saveLabsSettings(labsSettings: LabsSettings): void;
|
|
4
|
+
export declare function loadPreferredLanguage(): AccountLanguage | undefined;
|
|
5
|
+
export declare function savePreferredLanguage(preferredLanguage: AccountLanguage): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import d from"node:fs";import i from"node:path";import{isAccountLanguage as u,LabsSettingsSchema as s}from"@agentdock/wire";import{getDaemonDir as f}from"./paths.js";import{readJsonFile as g,writeJsonFile as L}from"./jsonFileUtils.js";import{isRecord as p}from"./typeGuards.js";const m="server-settings-cache.json",b="labs-settings.json",a=1,l=s.parse({});function o(){return i.join(f(),m)}function h(){return i.join(f(),b)}function E(){const e=g(o(),null);if(!p(e))return null;const n=e;if(n.version!==a)return null;const c=s.safeParse(n.labsSettings);if(!c.success)return null;const t=n.preferredLanguage;return t!==void 0&&!u(t)?null:{version:a,labsSettings:c.data,...u(t)?{preferredLanguage:t}:{}}}function v(){const e=g(h(),null),n=s.safeParse(e);return n.success?n.data:l}function r(){const e=E();return e||{version:a,labsSettings:d.existsSync(o())?l:v()}}function S(e){L(o(),e)}export function loadLabsSettings(){return r().labsSettings}export function saveLabsSettings(e){const n=r();S({...n,labsSettings:e})}export function loadPreferredLanguage(){return r().preferredLanguage}export function savePreferredLanguage(e){const n=r();S({...n,preferredLanguage:e})}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AgentMessage } from '../acpTypes.js';
|
|
2
|
+
import type { SessionEnvelope } from '@agentdock/wire';
|
|
3
|
+
export interface BackgroundTaskHandlerDeps {
|
|
4
|
+
|
|
5
|
+
readonly activeSubagents: Map<string, string>;
|
|
6
|
+
|
|
7
|
+
readonly backgroundToolCalls: Set<string>;
|
|
8
|
+
|
|
9
|
+
readonly taskIdToToolCallId: Map<string, string>;
|
|
10
|
+
|
|
11
|
+
readonly envelopeOpts: () => {
|
|
12
|
+
turn?: string;
|
|
13
|
+
subagent?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
readonly buildStopEnvelope: (sessionSubagentId: string) => SessionEnvelope;
|
|
17
|
+
|
|
18
|
+
readonly maybeFlushDeferredTurnEnd: () => readonly SessionEnvelope[];
|
|
19
|
+
|
|
20
|
+
readonly onChildCompleted?: (toolUseId: string, usage?: {
|
|
21
|
+
totalTokens: number;
|
|
22
|
+
durationMs: number;
|
|
23
|
+
toolUses: number;
|
|
24
|
+
}) => readonly SessionEnvelope[];
|
|
25
|
+
}
|
|
26
|
+
export type TaskLifecycleHandler = (message: AgentMessage & {
|
|
27
|
+
type: 'task-lifecycle';
|
|
28
|
+
}) => readonly SessionEnvelope[];
|
|
29
|
+
export declare function createBackgroundTaskHandler(deps: BackgroundTaskHandlerDeps): TaskLifecycleHandler;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{createEnvelope as i,encodeBgTask as c}from"@agentdock/wire";function S(s,l,e){return s!==void 0&&(l.has(s)||e.has(s))}export function createBackgroundTaskHandler(s){const{activeSubagents:l,backgroundToolCalls:e,taskIdToToolCallId:k,envelopeOpts:d,buildStopEnvelope:U,maybeFlushDeferredTurnEnd:f}=s,r=new Set;return function(t){switch(t.subtype){case"task_started":return t.toolUseId&&(l.has(t.toolUseId)&&e.add(t.toolUseId),e.has(t.toolUseId)&&k.set(t.taskId,t.toolUseId)),S(t.toolUseId,e,l)?[i("agent",{t:"service",text:c({action:"started",taskId:t.taskId,desc:t.description??""})},d())]:[];case"task_progress":return[i("agent",{t:"service",text:c({action:"progress",taskId:t.taskId,summary:t.summary??""})},d())];case"task_notification":{const n=t.toolUseId??k.get(t.taskId),o=[],a=n?l.get(n):void 0;r.has(t.taskId)||(k.delete(t.taskId),n&&(e.delete(n),a&&(l.delete(n),o.push(U(a))),o.push(i("agent",{t:"tool-call-end",call:n},d())),s.onChildCompleted&&o.push(...s.onChildCompleted(n,{totalTokens:t.taskUsage?.totalTokens??0,durationMs:t.taskUsage?.durationMs??0,toolUses:t.taskUsage?.toolUses??0}))),r.add(t.taskId));{const u=t.taskStatus==="failed"?"failed":t.taskStatus==="stopped"?"stopped":"completed",p=t.taskUsage?.totalTokens??0,I=t.taskUsage?.durationMs??0,h=t.taskUsage?.toolUses??0,T=a?{...d(),subagent:a}:n?{...d(),toolCallId:n}:d();o.push(i("agent",{t:"service",text:c({action:u,taskId:t.taskId,totalTokens:p,durationMs:I,toolUses:h,summary:t.summary})},T))}return o.push(...f()),o}case"task_updated":{if(t.taskStatus==="killed"||t.taskStatus==="stopped"||t.taskStatus==="failed"||t.taskStatus==="completed"){const o=t.toolUseId??k.get(t.taskId);if(!o&&!r.has(t.taskId))return[];const a=[],u=o?l.get(o):void 0;r.has(t.taskId)||(k.delete(t.taskId),o&&(e.delete(o),u&&(l.delete(o),a.push(U(u))),a.push(i("agent",{t:"tool-call-end",call:o},d())),s.onChildCompleted&&a.push(...s.onChildCompleted(o,{totalTokens:t.taskUsage?.totalTokens??0,durationMs:t.taskUsage?.durationMs??0,toolUses:t.taskUsage?.toolUses??0}))),r.add(t.taskId));const p=t.taskStatus==="killed"?"stopped":t.taskStatus,I=u?{...d(),subagent:u}:o?{...d(),toolCallId:o}:d();return a.push(i("agent",{t:"service",text:c({action:p,taskId:t.taskId,totalTokens:t.taskUsage?.totalTokens??0,durationMs:t.taskUsage?.durationMs??0,toolUses:t.taskUsage?.toolUses??0,summary:t.summary})},I)),a.push(...f()),a}return t.isBackgrounded&&t.toolUseId&&e.add(t.toolUseId),[]}default:return[]}}}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AgentMessage } from '../acpTypes.js';
|
|
2
|
+
import type { PermissionModeValue } from '@agentdock/wire';
|
|
3
|
+
|
|
4
|
+
export type PermissionMode = PermissionModeValue;
|
|
5
|
+
|
|
6
|
+
export interface PendingRequest {
|
|
7
|
+
readonly requestId: string;
|
|
8
|
+
readonly toolCallId: string;
|
|
9
|
+
readonly toolName: string;
|
|
10
|
+
readonly createdAt: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface InteractionDetectorConfig {
|
|
14
|
+
readonly permissionMode: PermissionMode;
|
|
15
|
+
|
|
16
|
+
readonly nativePermissions?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface InteractionDetector {
|
|
20
|
+
|
|
21
|
+
processMessage(msg: AgentMessage): AgentMessage | null;
|
|
22
|
+
|
|
23
|
+
resolve(requestId: string): void;
|
|
24
|
+
|
|
25
|
+
getPending(requestId: string): PendingRequest | undefined;
|
|
26
|
+
|
|
27
|
+
getPendingCount(): number;
|
|
28
|
+
|
|
29
|
+
reset(): void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export declare function createInteractionDetector(config: InteractionDetectorConfig): InteractionDetector;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{createId as l}from"@agentdock/wire";const i=new Set(["bypassPermissions","yolo","full-auto"]);export function createInteractionDetector(n){const t=new Map;function r(){return!i.has(n.permissionMode)}return{processMessage(e){if(n.nativePermissions&&e.type==="tool-call"||e.type!=="tool-call"||!r())return null;const o=l();return t.set(o,{requestId:o,toolCallId:e.toolCallId,toolName:e.toolName,createdAt:Date.now()}),{type:"permission-request",requestId:o,toolCallId:e.toolCallId,toolName:e.toolName,input:e.input}},resolve(e){t.delete(e)},getPending(e){return t.get(e)},getPendingCount(){return t.size},reset(){t.clear()}}}
|