@love-moon/conductor-sdk 0.2.38 → 0.2.40
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/client.d.ts +23 -0
- package/dist/client.js +111 -1
- package/package.json +2 -2
package/dist/client.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ export interface ConductorClientConnectOptions {
|
|
|
26
26
|
onDisconnected?: (event: WebSocketDisconnectEvent) => void;
|
|
27
27
|
onPong?: (event: WebSocketPongEvent) => void;
|
|
28
28
|
onStopTask?: (event: StopTaskEvent) => Promise<void> | void;
|
|
29
|
+
onInterruptTurn?: (event: InterruptTurnEvent) => Promise<boolean | void> | boolean | void;
|
|
30
|
+
onRefreshSession?: (event: RefreshSessionEvent) => Promise<boolean | void> | boolean | void;
|
|
29
31
|
}
|
|
30
32
|
interface ConductorClientInit {
|
|
31
33
|
config: ConductorConfig;
|
|
@@ -41,12 +43,27 @@ interface ConductorClientInit {
|
|
|
41
43
|
downstreamCursorStore: DownstreamCursorStore;
|
|
42
44
|
agentHost: string;
|
|
43
45
|
onStopTask?: (event: StopTaskEvent) => Promise<void> | void;
|
|
46
|
+
onInterruptTurn?: (event: InterruptTurnEvent) => Promise<boolean | void> | boolean | void;
|
|
47
|
+
onRefreshSession?: (event: RefreshSessionEvent) => Promise<boolean | void> | boolean | void;
|
|
44
48
|
}
|
|
45
49
|
export interface StopTaskEvent {
|
|
46
50
|
taskId: string;
|
|
47
51
|
requestId?: string;
|
|
48
52
|
reason?: string;
|
|
49
53
|
}
|
|
54
|
+
export interface InterruptTurnEvent {
|
|
55
|
+
taskId: string;
|
|
56
|
+
requestId?: string;
|
|
57
|
+
reason?: string;
|
|
58
|
+
targetReplyTo: string;
|
|
59
|
+
}
|
|
60
|
+
export interface RefreshSessionEvent {
|
|
61
|
+
taskId: string;
|
|
62
|
+
requestId?: string;
|
|
63
|
+
reason?: string;
|
|
64
|
+
sessionId: string;
|
|
65
|
+
sessionFilePath?: string;
|
|
66
|
+
}
|
|
50
67
|
export interface FlushPendingUpstreamEventsOptions {
|
|
51
68
|
timeoutMs?: number;
|
|
52
69
|
retryIntervalMs?: number;
|
|
@@ -64,6 +81,8 @@ export declare class ConductorClient {
|
|
|
64
81
|
private downstreamCursorStore;
|
|
65
82
|
private readonly agentHost;
|
|
66
83
|
private readonly onStopTask?;
|
|
84
|
+
private readonly onInterruptTurn?;
|
|
85
|
+
private readonly onRefreshSession?;
|
|
67
86
|
private deliveryScopeId;
|
|
68
87
|
private closed;
|
|
69
88
|
private durableOutboxFlushPromise;
|
|
@@ -116,6 +135,10 @@ export declare class ConductorClient {
|
|
|
116
135
|
private extractDownstreamCommandContext;
|
|
117
136
|
private handleStopTaskCommand;
|
|
118
137
|
private invokeStopTaskHandler;
|
|
138
|
+
private handleInterruptTurnCommand;
|
|
139
|
+
private handleRefreshSessionCommand;
|
|
140
|
+
private invokeInterruptTurnHandler;
|
|
141
|
+
private invokeRefreshSessionHandler;
|
|
119
142
|
private persistAndCommitUpstreamEvent;
|
|
120
143
|
private requestDurableOutboxFlush;
|
|
121
144
|
private hasEarlierPendingSdkMessage;
|
package/dist/client.js
CHANGED
|
@@ -23,6 +23,8 @@ export class ConductorClient {
|
|
|
23
23
|
downstreamCursorStore;
|
|
24
24
|
agentHost;
|
|
25
25
|
onStopTask;
|
|
26
|
+
onInterruptTurn;
|
|
27
|
+
onRefreshSession;
|
|
26
28
|
deliveryScopeId;
|
|
27
29
|
closed = false;
|
|
28
30
|
durableOutboxFlushPromise = null;
|
|
@@ -41,6 +43,8 @@ export class ConductorClient {
|
|
|
41
43
|
this.downstreamCursorStore = init.downstreamCursorStore;
|
|
42
44
|
this.agentHost = init.agentHost;
|
|
43
45
|
this.onStopTask = init.onStopTask;
|
|
46
|
+
this.onInterruptTurn = init.onInterruptTurn;
|
|
47
|
+
this.onRefreshSession = init.onRefreshSession;
|
|
44
48
|
this.deliveryScopeId = init.deliveryScopeId;
|
|
45
49
|
this.wsClient.registerHandler(this.handleBackendEvent);
|
|
46
50
|
}
|
|
@@ -83,6 +87,8 @@ export class ConductorClient {
|
|
|
83
87
|
downstreamCursorStore,
|
|
84
88
|
agentHost,
|
|
85
89
|
onStopTask: options.onStopTask,
|
|
90
|
+
onInterruptTurn: options.onInterruptTurn,
|
|
91
|
+
onRefreshSession: options.onRefreshSession,
|
|
86
92
|
});
|
|
87
93
|
await client.wsClient.connect();
|
|
88
94
|
if (client.shouldAutoFlushDurableOutbox()) {
|
|
@@ -533,6 +539,21 @@ export class ConductorClient {
|
|
|
533
539
|
};
|
|
534
540
|
}
|
|
535
541
|
handleBackendEvent = async (payload) => {
|
|
542
|
+
if (typeof payload?.type === 'string' && payload.type === 'refresh_session') {
|
|
543
|
+
void this.handleRefreshSessionCommand(payload).catch((error) => {
|
|
544
|
+
const data = payload?.payload && typeof payload.payload === 'object'
|
|
545
|
+
? payload.payload
|
|
546
|
+
: null;
|
|
547
|
+
const taskId = typeof data?.task_id === 'string' ? data.task_id.trim() : '';
|
|
548
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
549
|
+
console.warn(`[sdk] refresh_session dispatch failed${taskId ? ` for task ${taskId}` : ''}: ${message}`);
|
|
550
|
+
});
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
if (typeof payload?.type === 'string' && payload.type === 'interrupt_turn') {
|
|
554
|
+
await this.handleInterruptTurnCommand(payload);
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
536
557
|
const command = this.extractDownstreamCommandContext(payload);
|
|
537
558
|
if (command?.eventType === 'stop_task') {
|
|
538
559
|
await this.handleStopTaskCommand(payload, command);
|
|
@@ -630,6 +651,92 @@ export class ConductorClient {
|
|
|
630
651
|
return false;
|
|
631
652
|
}
|
|
632
653
|
}
|
|
654
|
+
async handleInterruptTurnCommand(payload) {
|
|
655
|
+
const accepted = await this.invokeInterruptTurnHandler(payload);
|
|
656
|
+
await this.maybeAckInboundCommand(payload, { accepted });
|
|
657
|
+
}
|
|
658
|
+
async handleRefreshSessionCommand(payload) {
|
|
659
|
+
const accepted = await this.invokeRefreshSessionHandler(payload);
|
|
660
|
+
await this.maybeAckInboundCommand(payload, { accepted });
|
|
661
|
+
}
|
|
662
|
+
async invokeInterruptTurnHandler(payload) {
|
|
663
|
+
const data = payload?.payload && typeof payload.payload === 'object'
|
|
664
|
+
? payload.payload
|
|
665
|
+
: null;
|
|
666
|
+
if (!data) {
|
|
667
|
+
return false;
|
|
668
|
+
}
|
|
669
|
+
const taskId = typeof data.task_id === 'string' ? data.task_id.trim() : '';
|
|
670
|
+
const requestId = typeof data.request_id === 'string' ? data.request_id.trim() : '';
|
|
671
|
+
const reason = typeof data.reason === 'string' ? data.reason.trim() : '';
|
|
672
|
+
const targetReplyTo = typeof data.target_reply_to === 'string'
|
|
673
|
+
? data.target_reply_to.trim()
|
|
674
|
+
: typeof data.targetReplyTo === 'string'
|
|
675
|
+
? data.targetReplyTo.trim()
|
|
676
|
+
: '';
|
|
677
|
+
if (!taskId || !targetReplyTo) {
|
|
678
|
+
return false;
|
|
679
|
+
}
|
|
680
|
+
if (!this.onInterruptTurn) {
|
|
681
|
+
return false;
|
|
682
|
+
}
|
|
683
|
+
try {
|
|
684
|
+
const accepted = await this.onInterruptTurn({
|
|
685
|
+
taskId,
|
|
686
|
+
requestId: requestId || undefined,
|
|
687
|
+
reason: reason || undefined,
|
|
688
|
+
targetReplyTo,
|
|
689
|
+
});
|
|
690
|
+
return accepted !== false;
|
|
691
|
+
}
|
|
692
|
+
catch (error) {
|
|
693
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
694
|
+
console.warn(`[sdk] interrupt_turn callback failed for task ${taskId}: ${message}`);
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
async invokeRefreshSessionHandler(payload) {
|
|
699
|
+
const data = payload?.payload && typeof payload.payload === 'object'
|
|
700
|
+
? payload.payload
|
|
701
|
+
: null;
|
|
702
|
+
if (!data) {
|
|
703
|
+
return false;
|
|
704
|
+
}
|
|
705
|
+
const taskId = typeof data.task_id === 'string' ? data.task_id.trim() : '';
|
|
706
|
+
const requestId = typeof data.request_id === 'string' ? data.request_id.trim() : '';
|
|
707
|
+
const reason = typeof data.reason === 'string' ? data.reason.trim() : '';
|
|
708
|
+
const sessionId = typeof data.session_id === 'string'
|
|
709
|
+
? data.session_id.trim()
|
|
710
|
+
: typeof data.sessionId === 'string'
|
|
711
|
+
? data.sessionId.trim()
|
|
712
|
+
: '';
|
|
713
|
+
const sessionFilePath = typeof data.session_file_path === 'string'
|
|
714
|
+
? data.session_file_path.trim()
|
|
715
|
+
: typeof data.sessionFilePath === 'string'
|
|
716
|
+
? data.sessionFilePath.trim()
|
|
717
|
+
: '';
|
|
718
|
+
if (!taskId || !sessionId) {
|
|
719
|
+
return false;
|
|
720
|
+
}
|
|
721
|
+
if (!this.onRefreshSession) {
|
|
722
|
+
return false;
|
|
723
|
+
}
|
|
724
|
+
try {
|
|
725
|
+
const accepted = await this.onRefreshSession({
|
|
726
|
+
taskId,
|
|
727
|
+
requestId: requestId || undefined,
|
|
728
|
+
reason: reason || undefined,
|
|
729
|
+
sessionId,
|
|
730
|
+
sessionFilePath: sessionFilePath || undefined,
|
|
731
|
+
});
|
|
732
|
+
return accepted !== false;
|
|
733
|
+
}
|
|
734
|
+
catch (error) {
|
|
735
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
736
|
+
console.warn(`[sdk] refresh_session callback failed for task ${taskId}: ${message}`);
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
633
740
|
async persistAndCommitUpstreamEvent(entry) {
|
|
634
741
|
const stored = this.upstreamOutbox.upsert(entry);
|
|
635
742
|
if (stored.eventType === 'sdk_message' && this.hasEarlierPendingSdkMessage(stored.stableId)) {
|
|
@@ -796,7 +903,10 @@ export class ConductorClient {
|
|
|
796
903
|
}
|
|
797
904
|
async maybeAckInboundCommand(payload, options = {}) {
|
|
798
905
|
const eventType = typeof payload?.type === 'string' ? payload.type : '';
|
|
799
|
-
if (eventType !== 'task_user_message' &&
|
|
906
|
+
if (eventType !== 'task_user_message' &&
|
|
907
|
+
eventType !== 'task_action' &&
|
|
908
|
+
eventType !== 'interrupt_turn' &&
|
|
909
|
+
eventType !== 'refresh_session') {
|
|
800
910
|
return;
|
|
801
911
|
}
|
|
802
912
|
const data = payload?.payload && typeof payload.payload === 'object'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@love-moon/conductor-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.40",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"typescript": "^5.6.3",
|
|
28
28
|
"vitest": "^2.1.4"
|
|
29
29
|
},
|
|
30
|
-
"gitCommitId": "
|
|
30
|
+
"gitCommitId": "e08f8b6"
|
|
31
31
|
}
|