@yushaw/sanqian-chat 0.2.23 → 0.2.25
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/core/index.d.mts +5 -2
- package/dist/core/index.d.ts +5 -2
- package/dist/core/index.js +4 -2
- package/dist/core/index.mjs +4 -2
- package/dist/main/index.d.mts +5 -0
- package/dist/main/index.d.ts +5 -0
- package/dist/main/index.js +77 -12
- package/dist/main/index.mjs +77 -12
- package/dist/preload/factories.d.mts +1 -0
- package/dist/preload/factories.d.ts +1 -0
- package/dist/renderer/index.d.mts +5 -2
- package/dist/renderer/index.d.ts +5 -2
- package/dist/renderer/index.js +174 -36
- package/dist/renderer/index.mjs +174 -36
- package/package.json +1 -1
package/dist/core/index.d.mts
CHANGED
|
@@ -496,6 +496,9 @@ interface LinkHandlerConfig {
|
|
|
496
496
|
|
|
497
497
|
/** Stream event callback */
|
|
498
498
|
type StreamEvent = {
|
|
499
|
+
/** Internal stream identifier (set by IPC adapter for precise routing) */
|
|
500
|
+
stream_id?: string;
|
|
501
|
+
} & ({
|
|
499
502
|
type: 'start';
|
|
500
503
|
run_id: string;
|
|
501
504
|
conversationId?: string;
|
|
@@ -543,7 +546,7 @@ type StreamEvent = {
|
|
|
543
546
|
} | {
|
|
544
547
|
type: 'cancelled';
|
|
545
548
|
run_id?: string;
|
|
546
|
-
};
|
|
549
|
+
});
|
|
547
550
|
/** Message to send */
|
|
548
551
|
interface SendMessage {
|
|
549
552
|
role: 'user' | 'assistant';
|
|
@@ -578,7 +581,7 @@ interface ChatAdapter {
|
|
|
578
581
|
}): Promise<{
|
|
579
582
|
cancel: () => void;
|
|
580
583
|
}>;
|
|
581
|
-
sendHitlResponse?(response: HitlResponse, runId?: string): void;
|
|
584
|
+
sendHitlResponse?(response: HitlResponse, runId?: string, streamId?: string): void;
|
|
582
585
|
/** List available context providers */
|
|
583
586
|
listResourceProviders?(): Promise<ContextProviderInfo[]>;
|
|
584
587
|
/** Get resource list from a provider with search/pagination */
|
package/dist/core/index.d.ts
CHANGED
|
@@ -496,6 +496,9 @@ interface LinkHandlerConfig {
|
|
|
496
496
|
|
|
497
497
|
/** Stream event callback */
|
|
498
498
|
type StreamEvent = {
|
|
499
|
+
/** Internal stream identifier (set by IPC adapter for precise routing) */
|
|
500
|
+
stream_id?: string;
|
|
501
|
+
} & ({
|
|
499
502
|
type: 'start';
|
|
500
503
|
run_id: string;
|
|
501
504
|
conversationId?: string;
|
|
@@ -543,7 +546,7 @@ type StreamEvent = {
|
|
|
543
546
|
} | {
|
|
544
547
|
type: 'cancelled';
|
|
545
548
|
run_id?: string;
|
|
546
|
-
};
|
|
549
|
+
});
|
|
547
550
|
/** Message to send */
|
|
548
551
|
interface SendMessage {
|
|
549
552
|
role: 'user' | 'assistant';
|
|
@@ -578,7 +581,7 @@ interface ChatAdapter {
|
|
|
578
581
|
}): Promise<{
|
|
579
582
|
cancel: () => void;
|
|
580
583
|
}>;
|
|
581
|
-
sendHitlResponse?(response: HitlResponse, runId?: string): void;
|
|
584
|
+
sendHitlResponse?(response: HitlResponse, runId?: string, streamId?: string): void;
|
|
582
585
|
/** List available context providers */
|
|
583
586
|
listResourceProviders?(): Promise<ContextProviderInfo[]>;
|
|
584
587
|
/** Get resource list from a provider with search/pagination */
|
package/dist/core/index.js
CHANGED
|
@@ -581,8 +581,10 @@ function processStreamEvents(stream, onEvent, sdk, setCurrentRunId) {
|
|
|
581
581
|
default: {
|
|
582
582
|
const evt = event;
|
|
583
583
|
if (evt.type === "interrupt") {
|
|
584
|
-
|
|
585
|
-
|
|
584
|
+
if (evt.run_id) {
|
|
585
|
+
currentRunId = evt.run_id;
|
|
586
|
+
setCurrentRunId(evt.run_id);
|
|
587
|
+
}
|
|
586
588
|
onEvent({
|
|
587
589
|
type: "interrupt",
|
|
588
590
|
interrupt_type: evt.interrupt_type || "",
|
package/dist/core/index.mjs
CHANGED
|
@@ -542,8 +542,10 @@ function processStreamEvents(stream, onEvent, sdk, setCurrentRunId) {
|
|
|
542
542
|
default: {
|
|
543
543
|
const evt = event;
|
|
544
544
|
if (evt.type === "interrupt") {
|
|
545
|
-
|
|
546
|
-
|
|
545
|
+
if (evt.run_id) {
|
|
546
|
+
currentRunId = evt.run_id;
|
|
547
|
+
setCurrentRunId(evt.run_id);
|
|
548
|
+
}
|
|
547
549
|
onEvent({
|
|
548
550
|
type: "interrupt",
|
|
549
551
|
interrupt_type: evt.interrupt_type || "",
|
package/dist/main/index.d.mts
CHANGED
|
@@ -715,6 +715,7 @@ declare class FloatingWindow {
|
|
|
715
715
|
private stateSaveTimer;
|
|
716
716
|
private activeStreams;
|
|
717
717
|
private reconnectAcquired;
|
|
718
|
+
private resolveHitlRunId;
|
|
718
719
|
/**
|
|
719
720
|
* Get SDK instance from either getClient or getSdk
|
|
720
721
|
*/
|
|
@@ -920,6 +921,10 @@ declare class ChatPanel {
|
|
|
920
921
|
private scheduleSaveState;
|
|
921
922
|
private saveState;
|
|
922
923
|
private getSdk;
|
|
924
|
+
/**
|
|
925
|
+
* Resolve HITL runId. Prefer explicit runId from renderer; fallback to latest active stream runId.
|
|
926
|
+
*/
|
|
927
|
+
private resolveHitlRunId;
|
|
923
928
|
/**
|
|
924
929
|
* Setup session resource event forwarding from SDK to renderer
|
|
925
930
|
* Called when SDK becomes available (on connect)
|
package/dist/main/index.d.ts
CHANGED
|
@@ -715,6 +715,7 @@ declare class FloatingWindow {
|
|
|
715
715
|
private stateSaveTimer;
|
|
716
716
|
private activeStreams;
|
|
717
717
|
private reconnectAcquired;
|
|
718
|
+
private resolveHitlRunId;
|
|
718
719
|
/**
|
|
719
720
|
* Get SDK instance from either getClient or getSdk
|
|
720
721
|
*/
|
|
@@ -920,6 +921,10 @@ declare class ChatPanel {
|
|
|
920
921
|
private scheduleSaveState;
|
|
921
922
|
private saveState;
|
|
922
923
|
private getSdk;
|
|
924
|
+
/**
|
|
925
|
+
* Resolve HITL runId. Prefer explicit runId from renderer; fallback to latest active stream runId.
|
|
926
|
+
*/
|
|
927
|
+
private resolveHitlRunId;
|
|
923
928
|
/**
|
|
924
929
|
* Setup session resource event forwarding from SDK to renderer
|
|
925
930
|
* Called when SDK becomes available (on connect)
|
package/dist/main/index.js
CHANGED
|
@@ -399,6 +399,17 @@ var FloatingWindow = class _FloatingWindow {
|
|
|
399
399
|
import_electron.app.whenReady().then(() => this.registerShortcut());
|
|
400
400
|
}
|
|
401
401
|
}
|
|
402
|
+
resolveHitlRunId(runId) {
|
|
403
|
+
if (runId) return runId;
|
|
404
|
+
const streams = Array.from(this.activeStreams.values());
|
|
405
|
+
for (let i = streams.length - 1; i >= 0; i -= 1) {
|
|
406
|
+
const stream = streams[i];
|
|
407
|
+
if (stream && stream.runId && !stream.cancelled) {
|
|
408
|
+
return stream.runId;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
402
413
|
/**
|
|
403
414
|
* Get SDK instance from either getClient or getSdk
|
|
404
415
|
*/
|
|
@@ -639,7 +650,7 @@ var FloatingWindow = class _FloatingWindow {
|
|
|
639
650
|
webContents.send("sanqian-chat:streamEvent", { streamId, event: { type: "error", error: "SDK or agent not ready" } });
|
|
640
651
|
return;
|
|
641
652
|
}
|
|
642
|
-
const streamState = { cancelled: false, runId: null };
|
|
653
|
+
const streamState = { cancelled: false, runId: null, cancelSignalSent: false };
|
|
643
654
|
activeInstance?.activeStreams.set(streamId, streamState);
|
|
644
655
|
try {
|
|
645
656
|
await sdk.ensureReady();
|
|
@@ -650,7 +661,24 @@ var FloatingWindow = class _FloatingWindow {
|
|
|
650
661
|
{ conversationId, persistHistory: true }
|
|
651
662
|
);
|
|
652
663
|
for await (const evt of stream) {
|
|
653
|
-
|
|
664
|
+
const evtWithRunId = evt;
|
|
665
|
+
if (evtWithRunId.run_id && !streamState.runId) {
|
|
666
|
+
streamState.runId = evtWithRunId.run_id;
|
|
667
|
+
}
|
|
668
|
+
if (streamState.cancelled && streamState.runId && !streamState.cancelSignalSent) {
|
|
669
|
+
try {
|
|
670
|
+
sdk.cancelRun(streamState.runId);
|
|
671
|
+
streamState.cancelSignalSent = true;
|
|
672
|
+
} catch (e) {
|
|
673
|
+
console.warn("[FloatingWindow] Failed to cancel run:", e);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
if (streamState.cancelled) {
|
|
677
|
+
if (streamState.cancelSignalSent) {
|
|
678
|
+
break;
|
|
679
|
+
}
|
|
680
|
+
continue;
|
|
681
|
+
}
|
|
654
682
|
if (activeInstance?.options.devMode) {
|
|
655
683
|
console.log("[FloatingWindow] SDK event:", evt.type, JSON.stringify(evt).slice(0, 200));
|
|
656
684
|
}
|
|
@@ -702,24 +730,27 @@ var FloatingWindow = class _FloatingWindow {
|
|
|
702
730
|
const stream = activeInstance?.activeStreams.get(params.streamId);
|
|
703
731
|
if (stream) {
|
|
704
732
|
stream.cancelled = true;
|
|
705
|
-
if (stream.runId) {
|
|
733
|
+
if (stream.runId && !stream.cancelSignalSent) {
|
|
706
734
|
const sdk = activeInstance ? _FloatingWindow.getSdkFromOptions(activeInstance.options) : null;
|
|
707
735
|
if (sdk) {
|
|
708
736
|
try {
|
|
709
737
|
sdk.cancelRun(stream.runId);
|
|
738
|
+
stream.cancelSignalSent = true;
|
|
710
739
|
} catch (e) {
|
|
711
740
|
console.warn("[FloatingWindow] Failed to cancel run:", e);
|
|
712
741
|
}
|
|
713
742
|
}
|
|
714
743
|
}
|
|
715
|
-
activeInstance?.activeStreams.delete(params.streamId);
|
|
716
744
|
}
|
|
717
745
|
return { success: true };
|
|
718
746
|
});
|
|
719
747
|
import_electron.ipcMain.handle("sanqian-chat:hitlResponse", (_, params) => {
|
|
720
748
|
const sdk = activeInstance ? _FloatingWindow.getSdkFromOptions(activeInstance.options) : null;
|
|
721
|
-
|
|
722
|
-
|
|
749
|
+
const runId = activeInstance?.resolveHitlRunId(params.runId) ?? null;
|
|
750
|
+
if (sdk && runId) {
|
|
751
|
+
sdk.sendHitlResponse(runId, params.response);
|
|
752
|
+
} else if (activeInstance?.options.devMode) {
|
|
753
|
+
console.warn("[FloatingWindow] HITL response dropped: missing runId");
|
|
723
754
|
}
|
|
724
755
|
return { success: true };
|
|
725
756
|
});
|
|
@@ -1668,6 +1699,20 @@ var ChatPanel = class {
|
|
|
1668
1699
|
const client = this.config.getClient();
|
|
1669
1700
|
return client;
|
|
1670
1701
|
}
|
|
1702
|
+
/**
|
|
1703
|
+
* Resolve HITL runId. Prefer explicit runId from renderer; fallback to latest active stream runId.
|
|
1704
|
+
*/
|
|
1705
|
+
resolveHitlRunId(runId) {
|
|
1706
|
+
if (runId) return runId;
|
|
1707
|
+
const streams = Array.from(this.activeStreams.values());
|
|
1708
|
+
for (let i = streams.length - 1; i >= 0; i -= 1) {
|
|
1709
|
+
const stream = streams[i];
|
|
1710
|
+
if (stream && stream.runId && !stream.cancelled) {
|
|
1711
|
+
return stream.runId;
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
return null;
|
|
1715
|
+
}
|
|
1671
1716
|
/**
|
|
1672
1717
|
* Setup session resource event forwarding from SDK to renderer
|
|
1673
1718
|
* Called when SDK becomes available (on connect)
|
|
@@ -1729,7 +1774,7 @@ var ChatPanel = class {
|
|
|
1729
1774
|
webContents.send("sanqian-chat:streamEvent", { streamId, event: { type: "error", error: "SDK or agent not ready" } });
|
|
1730
1775
|
return;
|
|
1731
1776
|
}
|
|
1732
|
-
const streamState = { cancelled: false, runId: null };
|
|
1777
|
+
const streamState = { cancelled: false, runId: null, cancelSignalSent: false };
|
|
1733
1778
|
activeInstance2?.activeStreams.set(streamId, streamState);
|
|
1734
1779
|
try {
|
|
1735
1780
|
await sdk.ensureReady();
|
|
@@ -1745,7 +1790,24 @@ var ChatPanel = class {
|
|
|
1745
1790
|
sessionResources: sessionResources?.length ? sessionResources : void 0
|
|
1746
1791
|
});
|
|
1747
1792
|
for await (const evt of stream) {
|
|
1748
|
-
|
|
1793
|
+
const evtWithRunId = evt;
|
|
1794
|
+
if (evtWithRunId.run_id && !streamState.runId) {
|
|
1795
|
+
streamState.runId = evtWithRunId.run_id;
|
|
1796
|
+
}
|
|
1797
|
+
if (streamState.cancelled && streamState.runId && !streamState.cancelSignalSent) {
|
|
1798
|
+
try {
|
|
1799
|
+
sdk.cancelRun(streamState.runId);
|
|
1800
|
+
streamState.cancelSignalSent = true;
|
|
1801
|
+
} catch (e) {
|
|
1802
|
+
console.warn("[ChatPanel] Failed to cancel run:", e);
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
if (streamState.cancelled) {
|
|
1806
|
+
if (streamState.cancelSignalSent) {
|
|
1807
|
+
break;
|
|
1808
|
+
}
|
|
1809
|
+
continue;
|
|
1810
|
+
}
|
|
1749
1811
|
if (activeInstance2?.config.devMode) {
|
|
1750
1812
|
console.log("[ChatPanel] SDK event:", evt.type, JSON.stringify(evt).slice(0, 200));
|
|
1751
1813
|
}
|
|
@@ -1797,24 +1859,27 @@ var ChatPanel = class {
|
|
|
1797
1859
|
const stream = activeInstance2?.activeStreams.get(params.streamId);
|
|
1798
1860
|
if (stream) {
|
|
1799
1861
|
stream.cancelled = true;
|
|
1800
|
-
if (stream.runId) {
|
|
1862
|
+
if (stream.runId && !stream.cancelSignalSent) {
|
|
1801
1863
|
const sdk = activeInstance2?.getSdk();
|
|
1802
1864
|
if (sdk) {
|
|
1803
1865
|
try {
|
|
1804
1866
|
sdk.cancelRun(stream.runId);
|
|
1867
|
+
stream.cancelSignalSent = true;
|
|
1805
1868
|
} catch (e) {
|
|
1806
1869
|
console.warn("[ChatPanel] Failed to cancel run:", e);
|
|
1807
1870
|
}
|
|
1808
1871
|
}
|
|
1809
1872
|
}
|
|
1810
|
-
activeInstance2?.activeStreams.delete(params.streamId);
|
|
1811
1873
|
}
|
|
1812
1874
|
return { success: true };
|
|
1813
1875
|
});
|
|
1814
1876
|
import_electron2.ipcMain.handle("sanqian-chat:hitlResponse", (_, params) => {
|
|
1815
1877
|
const sdk = activeInstance2?.getSdk();
|
|
1816
|
-
|
|
1817
|
-
|
|
1878
|
+
const runId = activeInstance2?.resolveHitlRunId(params.runId) ?? null;
|
|
1879
|
+
if (sdk && runId) {
|
|
1880
|
+
sdk.sendHitlResponse(runId, params.response);
|
|
1881
|
+
} else if (activeInstance2?.config.devMode) {
|
|
1882
|
+
console.warn("[ChatPanel] HITL response dropped: missing runId");
|
|
1818
1883
|
}
|
|
1819
1884
|
return { success: true };
|
|
1820
1885
|
});
|
package/dist/main/index.mjs
CHANGED
|
@@ -368,6 +368,17 @@ var FloatingWindow = class _FloatingWindow {
|
|
|
368
368
|
app.whenReady().then(() => this.registerShortcut());
|
|
369
369
|
}
|
|
370
370
|
}
|
|
371
|
+
resolveHitlRunId(runId) {
|
|
372
|
+
if (runId) return runId;
|
|
373
|
+
const streams = Array.from(this.activeStreams.values());
|
|
374
|
+
for (let i = streams.length - 1; i >= 0; i -= 1) {
|
|
375
|
+
const stream = streams[i];
|
|
376
|
+
if (stream && stream.runId && !stream.cancelled) {
|
|
377
|
+
return stream.runId;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
371
382
|
/**
|
|
372
383
|
* Get SDK instance from either getClient or getSdk
|
|
373
384
|
*/
|
|
@@ -608,7 +619,7 @@ var FloatingWindow = class _FloatingWindow {
|
|
|
608
619
|
webContents.send("sanqian-chat:streamEvent", { streamId, event: { type: "error", error: "SDK or agent not ready" } });
|
|
609
620
|
return;
|
|
610
621
|
}
|
|
611
|
-
const streamState = { cancelled: false, runId: null };
|
|
622
|
+
const streamState = { cancelled: false, runId: null, cancelSignalSent: false };
|
|
612
623
|
activeInstance?.activeStreams.set(streamId, streamState);
|
|
613
624
|
try {
|
|
614
625
|
await sdk.ensureReady();
|
|
@@ -619,7 +630,24 @@ var FloatingWindow = class _FloatingWindow {
|
|
|
619
630
|
{ conversationId, persistHistory: true }
|
|
620
631
|
);
|
|
621
632
|
for await (const evt of stream) {
|
|
622
|
-
|
|
633
|
+
const evtWithRunId = evt;
|
|
634
|
+
if (evtWithRunId.run_id && !streamState.runId) {
|
|
635
|
+
streamState.runId = evtWithRunId.run_id;
|
|
636
|
+
}
|
|
637
|
+
if (streamState.cancelled && streamState.runId && !streamState.cancelSignalSent) {
|
|
638
|
+
try {
|
|
639
|
+
sdk.cancelRun(streamState.runId);
|
|
640
|
+
streamState.cancelSignalSent = true;
|
|
641
|
+
} catch (e) {
|
|
642
|
+
console.warn("[FloatingWindow] Failed to cancel run:", e);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
if (streamState.cancelled) {
|
|
646
|
+
if (streamState.cancelSignalSent) {
|
|
647
|
+
break;
|
|
648
|
+
}
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
623
651
|
if (activeInstance?.options.devMode) {
|
|
624
652
|
console.log("[FloatingWindow] SDK event:", evt.type, JSON.stringify(evt).slice(0, 200));
|
|
625
653
|
}
|
|
@@ -671,24 +699,27 @@ var FloatingWindow = class _FloatingWindow {
|
|
|
671
699
|
const stream = activeInstance?.activeStreams.get(params.streamId);
|
|
672
700
|
if (stream) {
|
|
673
701
|
stream.cancelled = true;
|
|
674
|
-
if (stream.runId) {
|
|
702
|
+
if (stream.runId && !stream.cancelSignalSent) {
|
|
675
703
|
const sdk = activeInstance ? _FloatingWindow.getSdkFromOptions(activeInstance.options) : null;
|
|
676
704
|
if (sdk) {
|
|
677
705
|
try {
|
|
678
706
|
sdk.cancelRun(stream.runId);
|
|
707
|
+
stream.cancelSignalSent = true;
|
|
679
708
|
} catch (e) {
|
|
680
709
|
console.warn("[FloatingWindow] Failed to cancel run:", e);
|
|
681
710
|
}
|
|
682
711
|
}
|
|
683
712
|
}
|
|
684
|
-
activeInstance?.activeStreams.delete(params.streamId);
|
|
685
713
|
}
|
|
686
714
|
return { success: true };
|
|
687
715
|
});
|
|
688
716
|
ipcMain.handle("sanqian-chat:hitlResponse", (_, params) => {
|
|
689
717
|
const sdk = activeInstance ? _FloatingWindow.getSdkFromOptions(activeInstance.options) : null;
|
|
690
|
-
|
|
691
|
-
|
|
718
|
+
const runId = activeInstance?.resolveHitlRunId(params.runId) ?? null;
|
|
719
|
+
if (sdk && runId) {
|
|
720
|
+
sdk.sendHitlResponse(runId, params.response);
|
|
721
|
+
} else if (activeInstance?.options.devMode) {
|
|
722
|
+
console.warn("[FloatingWindow] HITL response dropped: missing runId");
|
|
692
723
|
}
|
|
693
724
|
return { success: true };
|
|
694
725
|
});
|
|
@@ -1643,6 +1674,20 @@ var ChatPanel = class {
|
|
|
1643
1674
|
const client = this.config.getClient();
|
|
1644
1675
|
return client;
|
|
1645
1676
|
}
|
|
1677
|
+
/**
|
|
1678
|
+
* Resolve HITL runId. Prefer explicit runId from renderer; fallback to latest active stream runId.
|
|
1679
|
+
*/
|
|
1680
|
+
resolveHitlRunId(runId) {
|
|
1681
|
+
if (runId) return runId;
|
|
1682
|
+
const streams = Array.from(this.activeStreams.values());
|
|
1683
|
+
for (let i = streams.length - 1; i >= 0; i -= 1) {
|
|
1684
|
+
const stream = streams[i];
|
|
1685
|
+
if (stream && stream.runId && !stream.cancelled) {
|
|
1686
|
+
return stream.runId;
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
return null;
|
|
1690
|
+
}
|
|
1646
1691
|
/**
|
|
1647
1692
|
* Setup session resource event forwarding from SDK to renderer
|
|
1648
1693
|
* Called when SDK becomes available (on connect)
|
|
@@ -1704,7 +1749,7 @@ var ChatPanel = class {
|
|
|
1704
1749
|
webContents.send("sanqian-chat:streamEvent", { streamId, event: { type: "error", error: "SDK or agent not ready" } });
|
|
1705
1750
|
return;
|
|
1706
1751
|
}
|
|
1707
|
-
const streamState = { cancelled: false, runId: null };
|
|
1752
|
+
const streamState = { cancelled: false, runId: null, cancelSignalSent: false };
|
|
1708
1753
|
activeInstance2?.activeStreams.set(streamId, streamState);
|
|
1709
1754
|
try {
|
|
1710
1755
|
await sdk.ensureReady();
|
|
@@ -1720,7 +1765,24 @@ var ChatPanel = class {
|
|
|
1720
1765
|
sessionResources: sessionResources?.length ? sessionResources : void 0
|
|
1721
1766
|
});
|
|
1722
1767
|
for await (const evt of stream) {
|
|
1723
|
-
|
|
1768
|
+
const evtWithRunId = evt;
|
|
1769
|
+
if (evtWithRunId.run_id && !streamState.runId) {
|
|
1770
|
+
streamState.runId = evtWithRunId.run_id;
|
|
1771
|
+
}
|
|
1772
|
+
if (streamState.cancelled && streamState.runId && !streamState.cancelSignalSent) {
|
|
1773
|
+
try {
|
|
1774
|
+
sdk.cancelRun(streamState.runId);
|
|
1775
|
+
streamState.cancelSignalSent = true;
|
|
1776
|
+
} catch (e) {
|
|
1777
|
+
console.warn("[ChatPanel] Failed to cancel run:", e);
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
if (streamState.cancelled) {
|
|
1781
|
+
if (streamState.cancelSignalSent) {
|
|
1782
|
+
break;
|
|
1783
|
+
}
|
|
1784
|
+
continue;
|
|
1785
|
+
}
|
|
1724
1786
|
if (activeInstance2?.config.devMode) {
|
|
1725
1787
|
console.log("[ChatPanel] SDK event:", evt.type, JSON.stringify(evt).slice(0, 200));
|
|
1726
1788
|
}
|
|
@@ -1772,24 +1834,27 @@ var ChatPanel = class {
|
|
|
1772
1834
|
const stream = activeInstance2?.activeStreams.get(params.streamId);
|
|
1773
1835
|
if (stream) {
|
|
1774
1836
|
stream.cancelled = true;
|
|
1775
|
-
if (stream.runId) {
|
|
1837
|
+
if (stream.runId && !stream.cancelSignalSent) {
|
|
1776
1838
|
const sdk = activeInstance2?.getSdk();
|
|
1777
1839
|
if (sdk) {
|
|
1778
1840
|
try {
|
|
1779
1841
|
sdk.cancelRun(stream.runId);
|
|
1842
|
+
stream.cancelSignalSent = true;
|
|
1780
1843
|
} catch (e) {
|
|
1781
1844
|
console.warn("[ChatPanel] Failed to cancel run:", e);
|
|
1782
1845
|
}
|
|
1783
1846
|
}
|
|
1784
1847
|
}
|
|
1785
|
-
activeInstance2?.activeStreams.delete(params.streamId);
|
|
1786
1848
|
}
|
|
1787
1849
|
return { success: true };
|
|
1788
1850
|
});
|
|
1789
1851
|
ipcMain2.handle("sanqian-chat:hitlResponse", (_, params) => {
|
|
1790
1852
|
const sdk = activeInstance2?.getSdk();
|
|
1791
|
-
|
|
1792
|
-
|
|
1853
|
+
const runId = activeInstance2?.resolveHitlRunId(params.runId) ?? null;
|
|
1854
|
+
if (sdk && runId) {
|
|
1855
|
+
sdk.sendHitlResponse(runId, params.response);
|
|
1856
|
+
} else if (activeInstance2?.config.devMode) {
|
|
1857
|
+
console.warn("[ChatPanel] HITL response dropped: missing runId");
|
|
1793
1858
|
}
|
|
1794
1859
|
return { success: true };
|
|
1795
1860
|
});
|
|
@@ -499,6 +499,9 @@ interface LinkHandlerConfig {
|
|
|
499
499
|
|
|
500
500
|
/** Stream event callback */
|
|
501
501
|
type StreamEvent = {
|
|
502
|
+
/** Internal stream identifier (set by IPC adapter for precise routing) */
|
|
503
|
+
stream_id?: string;
|
|
504
|
+
} & ({
|
|
502
505
|
type: 'start';
|
|
503
506
|
run_id: string;
|
|
504
507
|
conversationId?: string;
|
|
@@ -546,7 +549,7 @@ type StreamEvent = {
|
|
|
546
549
|
} | {
|
|
547
550
|
type: 'cancelled';
|
|
548
551
|
run_id?: string;
|
|
549
|
-
};
|
|
552
|
+
});
|
|
550
553
|
/** Message to send */
|
|
551
554
|
interface SendMessage {
|
|
552
555
|
role: 'user' | 'assistant';
|
|
@@ -581,7 +584,7 @@ interface ChatAdapter {
|
|
|
581
584
|
}): Promise<{
|
|
582
585
|
cancel: () => void;
|
|
583
586
|
}>;
|
|
584
|
-
sendHitlResponse?(response: HitlResponse, runId?: string): void;
|
|
587
|
+
sendHitlResponse?(response: HitlResponse, runId?: string, streamId?: string): void;
|
|
585
588
|
/** List available context providers */
|
|
586
589
|
listResourceProviders?(): Promise<ContextProviderInfo[]>;
|
|
587
590
|
/** Get resource list from a provider with search/pagination */
|
package/dist/renderer/index.d.ts
CHANGED
|
@@ -499,6 +499,9 @@ interface LinkHandlerConfig {
|
|
|
499
499
|
|
|
500
500
|
/** Stream event callback */
|
|
501
501
|
type StreamEvent = {
|
|
502
|
+
/** Internal stream identifier (set by IPC adapter for precise routing) */
|
|
503
|
+
stream_id?: string;
|
|
504
|
+
} & ({
|
|
502
505
|
type: 'start';
|
|
503
506
|
run_id: string;
|
|
504
507
|
conversationId?: string;
|
|
@@ -546,7 +549,7 @@ type StreamEvent = {
|
|
|
546
549
|
} | {
|
|
547
550
|
type: 'cancelled';
|
|
548
551
|
run_id?: string;
|
|
549
|
-
};
|
|
552
|
+
});
|
|
550
553
|
/** Message to send */
|
|
551
554
|
interface SendMessage {
|
|
552
555
|
role: 'user' | 'assistant';
|
|
@@ -581,7 +584,7 @@ interface ChatAdapter {
|
|
|
581
584
|
}): Promise<{
|
|
582
585
|
cancel: () => void;
|
|
583
586
|
}>;
|
|
584
|
-
sendHitlResponse?(response: HitlResponse, runId?: string): void;
|
|
587
|
+
sendHitlResponse?(response: HitlResponse, runId?: string, streamId?: string): void;
|
|
585
588
|
/** List available context providers */
|
|
586
589
|
listResourceProviders?(): Promise<ContextProviderInfo[]>;
|
|
587
590
|
/** Get resource list from a provider with search/pagination */
|
package/dist/renderer/index.js
CHANGED
|
@@ -122,6 +122,7 @@ function useChat(options) {
|
|
|
122
122
|
const messagesRef = (0, import_react.useRef)(messages);
|
|
123
123
|
const conversationIdRef = (0, import_react.useRef)(conversationId);
|
|
124
124
|
const currentRunIdRef = (0, import_react.useRef)(null);
|
|
125
|
+
const pendingInterruptStreamIdRef = (0, import_react.useRef)(null);
|
|
125
126
|
const currentAgentIdRef = (0, import_react.useRef)(null);
|
|
126
127
|
const pendingCancelRef = (0, import_react.useRef)(false);
|
|
127
128
|
const pendingCancelTimeoutRef = (0, import_react.useRef)(null);
|
|
@@ -573,6 +574,7 @@ function useChat(options) {
|
|
|
573
574
|
setIsStreaming(false);
|
|
574
575
|
setIsLoading(false);
|
|
575
576
|
currentRunIdRef.current = null;
|
|
577
|
+
pendingInterruptStreamIdRef.current = null;
|
|
576
578
|
suppressStreamRef.current = false;
|
|
577
579
|
clearPendingCancel();
|
|
578
580
|
break;
|
|
@@ -609,6 +611,7 @@ function useChat(options) {
|
|
|
609
611
|
setIsLoading(false);
|
|
610
612
|
setPendingInterrupt(null);
|
|
611
613
|
currentRunIdRef.current = null;
|
|
614
|
+
pendingInterruptStreamIdRef.current = null;
|
|
612
615
|
suppressStreamRef.current = false;
|
|
613
616
|
clearPendingCancel();
|
|
614
617
|
break;
|
|
@@ -636,13 +639,19 @@ function useChat(options) {
|
|
|
636
639
|
setIsStreaming(false);
|
|
637
640
|
setIsLoading(false);
|
|
638
641
|
currentRunIdRef.current = null;
|
|
642
|
+
pendingInterruptStreamIdRef.current = null;
|
|
639
643
|
suppressStreamRef.current = false;
|
|
640
644
|
clearPendingCancel();
|
|
641
645
|
break;
|
|
642
646
|
}
|
|
643
647
|
case "interrupt": {
|
|
644
648
|
flushTypewriter();
|
|
645
|
-
|
|
649
|
+
if (event.run_id) {
|
|
650
|
+
currentRunIdRef.current = event.run_id;
|
|
651
|
+
}
|
|
652
|
+
if (event.stream_id) {
|
|
653
|
+
pendingInterruptStreamIdRef.current = event.stream_id;
|
|
654
|
+
}
|
|
646
655
|
const payload = event.interrupt_payload;
|
|
647
656
|
if (payload) {
|
|
648
657
|
setPendingInterrupt(payload);
|
|
@@ -665,6 +674,7 @@ function useChat(options) {
|
|
|
665
674
|
}
|
|
666
675
|
resetStreamBuffers();
|
|
667
676
|
currentRunIdRef.current = null;
|
|
677
|
+
pendingInterruptStreamIdRef.current = null;
|
|
668
678
|
const userMessage = {
|
|
669
679
|
id: crypto.randomUUID(),
|
|
670
680
|
role: "user",
|
|
@@ -784,6 +794,7 @@ function useChat(options) {
|
|
|
784
794
|
});
|
|
785
795
|
resetStreamBuffers();
|
|
786
796
|
currentRunIdRef.current = null;
|
|
797
|
+
pendingInterruptStreamIdRef.current = null;
|
|
787
798
|
if (!shouldDelayCancel) {
|
|
788
799
|
clearPendingCancel();
|
|
789
800
|
suppressStreamRef.current = false;
|
|
@@ -800,6 +811,7 @@ function useChat(options) {
|
|
|
800
811
|
setIsStreaming(false);
|
|
801
812
|
resetStreamBuffers();
|
|
802
813
|
currentRunIdRef.current = null;
|
|
814
|
+
pendingInterruptStreamIdRef.current = null;
|
|
803
815
|
clearPendingCancel();
|
|
804
816
|
suppressStreamRef.current = false;
|
|
805
817
|
}, [clearPendingCancel, resetStreamBuffers]);
|
|
@@ -837,23 +849,31 @@ function useChat(options) {
|
|
|
837
849
|
setPendingInterrupt(null);
|
|
838
850
|
resetStreamBuffers();
|
|
839
851
|
currentRunIdRef.current = null;
|
|
852
|
+
pendingInterruptStreamIdRef.current = null;
|
|
840
853
|
clearPendingCancel();
|
|
841
854
|
}, [clearPendingCancel, resetStreamBuffers]);
|
|
842
855
|
const sendHitlResponse = (0, import_react.useCallback)((response) => {
|
|
843
|
-
adapter.sendHitlResponse?.(
|
|
856
|
+
adapter.sendHitlResponse?.(
|
|
857
|
+
response,
|
|
858
|
+
currentRunIdRef.current ?? void 0,
|
|
859
|
+
pendingInterruptStreamIdRef.current ?? void 0
|
|
860
|
+
);
|
|
844
861
|
}, [adapter]);
|
|
845
862
|
const approveHitl = (0, import_react.useCallback)((remember = false) => {
|
|
846
863
|
sendHitlResponse({ approved: true, remember });
|
|
847
864
|
setPendingInterrupt(null);
|
|
865
|
+
pendingInterruptStreamIdRef.current = null;
|
|
848
866
|
}, [sendHitlResponse]);
|
|
849
867
|
const rejectHitl = (0, import_react.useCallback)((remember = false) => {
|
|
850
868
|
sendHitlResponse({ approved: false, remember });
|
|
851
869
|
setPendingInterrupt(null);
|
|
870
|
+
pendingInterruptStreamIdRef.current = null;
|
|
852
871
|
setIsLoading(false);
|
|
853
872
|
}, [sendHitlResponse]);
|
|
854
873
|
const submitHitlInput = (0, import_react.useCallback)((response) => {
|
|
855
874
|
sendHitlResponse(response);
|
|
856
875
|
setPendingInterrupt(null);
|
|
876
|
+
pendingInterruptStreamIdRef.current = null;
|
|
857
877
|
if (response.cancelled || response.timed_out) setIsLoading(false);
|
|
858
878
|
}, [sendHitlResponse]);
|
|
859
879
|
const removeSessionResource = (0, import_react.useCallback)((fullId) => {
|
|
@@ -5963,13 +5983,19 @@ function createIpcAdapter() {
|
|
|
5963
5983
|
async chatStream(messages, conversationId, onEvent, options) {
|
|
5964
5984
|
const streamId = crypto.randomUUID();
|
|
5965
5985
|
streamCallbacks.set(streamId, (event) => {
|
|
5966
|
-
if (event.type === "start"
|
|
5986
|
+
if (event.type === "start") {
|
|
5967
5987
|
currentRunId = event.run_id || null;
|
|
5968
5988
|
}
|
|
5989
|
+
if (event.type === "interrupt") {
|
|
5990
|
+
const interruptRunId = event.run_id;
|
|
5991
|
+
if (interruptRunId) {
|
|
5992
|
+
currentRunId = interruptRunId;
|
|
5993
|
+
}
|
|
5994
|
+
}
|
|
5969
5995
|
if (event.type === "done" || event.type === "cancelled" || event.type === "error") {
|
|
5970
5996
|
currentRunId = null;
|
|
5971
5997
|
}
|
|
5972
|
-
onEvent(event);
|
|
5998
|
+
onEvent({ ...event, stream_id: streamId });
|
|
5973
5999
|
});
|
|
5974
6000
|
try {
|
|
5975
6001
|
await api.stream({
|
|
@@ -5991,8 +6017,12 @@ function createIpcAdapter() {
|
|
|
5991
6017
|
throw e;
|
|
5992
6018
|
}
|
|
5993
6019
|
},
|
|
5994
|
-
sendHitlResponse(response, runId) {
|
|
5995
|
-
api.sendHitlResponse({
|
|
6020
|
+
sendHitlResponse(response, runId, streamId) {
|
|
6021
|
+
api.sendHitlResponse({
|
|
6022
|
+
response,
|
|
6023
|
+
runId: runId || currentRunId || void 0,
|
|
6024
|
+
streamId: streamId || void 0
|
|
6025
|
+
});
|
|
5996
6026
|
},
|
|
5997
6027
|
cleanup() {
|
|
5998
6028
|
streamEventCleanup?.();
|
|
@@ -6366,8 +6396,10 @@ function processStreamEvents(stream, onEvent, sdk, setCurrentRunId) {
|
|
|
6366
6396
|
default: {
|
|
6367
6397
|
const evt = event;
|
|
6368
6398
|
if (evt.type === "interrupt") {
|
|
6369
|
-
|
|
6370
|
-
|
|
6399
|
+
if (evt.run_id) {
|
|
6400
|
+
currentRunId = evt.run_id;
|
|
6401
|
+
setCurrentRunId(evt.run_id);
|
|
6402
|
+
}
|
|
6371
6403
|
onEvent({
|
|
6372
6404
|
type: "interrupt",
|
|
6373
6405
|
interrupt_type: evt.interrupt_type || "",
|
|
@@ -8018,6 +8050,23 @@ var defaultStrings = {
|
|
|
8018
8050
|
approvalRequest: "Approval Request",
|
|
8019
8051
|
inputRequest: "Input Request"
|
|
8020
8052
|
};
|
|
8053
|
+
var defaultZhStrings = {
|
|
8054
|
+
approve: "\u6279\u51C6",
|
|
8055
|
+
reject: "\u62D2\u7EDD",
|
|
8056
|
+
submit: "\u63D0\u4EA4",
|
|
8057
|
+
cancel: "\u53D6\u6D88",
|
|
8058
|
+
rememberChoice: "\u8BB0\u4F4F\u672C\u6B21\u9009\u62E9",
|
|
8059
|
+
requiredField: "\u6B64\u9879\u5FC5\u586B",
|
|
8060
|
+
timeoutIn: "\u8D85\u65F6\u5269\u4F59",
|
|
8061
|
+
seconds: "\u79D2",
|
|
8062
|
+
executeTool: "\u6267\u884C",
|
|
8063
|
+
toolLabel: "\u5DE5\u5177",
|
|
8064
|
+
argsLabel: "\u53C2\u6570",
|
|
8065
|
+
defaultPrefix: "\u9ED8\u8BA4",
|
|
8066
|
+
enterResponse: "\u8BF7\u8F93\u5165\u4F60\u7684\u56DE\u590D...",
|
|
8067
|
+
approvalRequest: "\u9700\u8981\u5BA1\u6279",
|
|
8068
|
+
inputRequest: "\u9700\u8981\u8F93\u5165"
|
|
8069
|
+
};
|
|
8021
8070
|
var riskColors = {
|
|
8022
8071
|
low: {
|
|
8023
8072
|
bg: "bg-blue-500/10",
|
|
@@ -8047,9 +8096,37 @@ var HitlCard = (0, import_react24.memo)(function HitlCard2({
|
|
|
8047
8096
|
isDarkMode = false,
|
|
8048
8097
|
strings = {}
|
|
8049
8098
|
}) {
|
|
8050
|
-
const
|
|
8099
|
+
const mergedStrings = { ...defaultStrings, ...strings };
|
|
8051
8100
|
const isApproval = interrupt.type === "approval_request";
|
|
8052
8101
|
const isUserInput = interrupt.type === "user_input_request";
|
|
8102
|
+
const cjkRegex = /[\u3400-\u9fff]/;
|
|
8103
|
+
const hasCjkContent = cjkRegex.test(
|
|
8104
|
+
[
|
|
8105
|
+
interrupt.question || "",
|
|
8106
|
+
interrupt.context || "",
|
|
8107
|
+
interrupt.reason || "",
|
|
8108
|
+
interrupt.tool || "",
|
|
8109
|
+
...interrupt.options || []
|
|
8110
|
+
].join(" ")
|
|
8111
|
+
);
|
|
8112
|
+
const t = hasCjkContent ? {
|
|
8113
|
+
...mergedStrings,
|
|
8114
|
+
approve: mergedStrings.approve === defaultStrings.approve ? defaultZhStrings.approve : mergedStrings.approve,
|
|
8115
|
+
reject: mergedStrings.reject === defaultStrings.reject ? defaultZhStrings.reject : mergedStrings.reject,
|
|
8116
|
+
submit: mergedStrings.submit === defaultStrings.submit ? defaultZhStrings.submit : mergedStrings.submit,
|
|
8117
|
+
cancel: mergedStrings.cancel === defaultStrings.cancel ? defaultZhStrings.cancel : mergedStrings.cancel,
|
|
8118
|
+
rememberChoice: mergedStrings.rememberChoice === defaultStrings.rememberChoice ? defaultZhStrings.rememberChoice : mergedStrings.rememberChoice,
|
|
8119
|
+
requiredField: mergedStrings.requiredField === defaultStrings.requiredField ? defaultZhStrings.requiredField : mergedStrings.requiredField,
|
|
8120
|
+
timeoutIn: mergedStrings.timeoutIn === defaultStrings.timeoutIn ? defaultZhStrings.timeoutIn : mergedStrings.timeoutIn,
|
|
8121
|
+
seconds: mergedStrings.seconds === defaultStrings.seconds ? defaultZhStrings.seconds : mergedStrings.seconds,
|
|
8122
|
+
executeTool: mergedStrings.executeTool === defaultStrings.executeTool ? defaultZhStrings.executeTool : mergedStrings.executeTool,
|
|
8123
|
+
toolLabel: mergedStrings.toolLabel === defaultStrings.toolLabel ? defaultZhStrings.toolLabel : mergedStrings.toolLabel,
|
|
8124
|
+
argsLabel: mergedStrings.argsLabel === defaultStrings.argsLabel ? defaultZhStrings.argsLabel : mergedStrings.argsLabel,
|
|
8125
|
+
defaultPrefix: mergedStrings.defaultPrefix === defaultStrings.defaultPrefix ? defaultZhStrings.defaultPrefix : mergedStrings.defaultPrefix,
|
|
8126
|
+
enterResponse: mergedStrings.enterResponse === defaultStrings.enterResponse ? defaultZhStrings.enterResponse : mergedStrings.enterResponse,
|
|
8127
|
+
approvalRequest: mergedStrings.approvalRequest === defaultStrings.approvalRequest ? defaultZhStrings.approvalRequest : mergedStrings.approvalRequest,
|
|
8128
|
+
inputRequest: mergedStrings.inputRequest === defaultStrings.inputRequest ? defaultZhStrings.inputRequest : mergedStrings.inputRequest
|
|
8129
|
+
} : mergedStrings;
|
|
8053
8130
|
const [answer, setAnswer] = (0, import_react24.useState)(interrupt.default || "");
|
|
8054
8131
|
const [selectedIndices, setSelectedIndices] = (0, import_react24.useState)([]);
|
|
8055
8132
|
const [isComposing, setIsComposing] = (0, import_react24.useState)(false);
|
|
@@ -8130,15 +8207,70 @@ var HitlCard = (0, import_react24.memo)(function HitlCard2({
|
|
|
8130
8207
|
}
|
|
8131
8208
|
};
|
|
8132
8209
|
const cardBg = isDarkMode ? "bg-zinc-800" : "bg-white";
|
|
8133
|
-
const cardBorder = isDarkMode ? "border-zinc-
|
|
8210
|
+
const cardBorder = isDarkMode ? "border-zinc-600" : "border-zinc-300";
|
|
8134
8211
|
const textPrimary = isDarkMode ? "text-zinc-100" : "text-zinc-900";
|
|
8135
8212
|
const textSecondary = isDarkMode ? "text-zinc-400" : "text-zinc-500";
|
|
8136
8213
|
const inputBg = isDarkMode ? "bg-zinc-900" : "bg-zinc-50";
|
|
8137
8214
|
const inputBorder = isDarkMode ? "border-zinc-600" : "border-zinc-300";
|
|
8215
|
+
const optionControlStyle = {
|
|
8216
|
+
accentColor: "var(--chat-accent, #2563eb)",
|
|
8217
|
+
width: "1.125rem",
|
|
8218
|
+
height: "1.125rem",
|
|
8219
|
+
margin: 0,
|
|
8220
|
+
flexShrink: 0
|
|
8221
|
+
};
|
|
8222
|
+
const cardStyle = {
|
|
8223
|
+
background: isDarkMode ? "rgba(24, 24, 27, 0.98)" : "#ffffff",
|
|
8224
|
+
borderColor: isDarkMode ? "rgba(212, 212, 216, 0.2)" : "rgba(63, 63, 70, 0.22)",
|
|
8225
|
+
boxShadow: isDarkMode ? "0 12px 30px rgba(0, 0, 0, 0.4)" : "0 10px 24px rgba(15, 23, 42, 0.14)"
|
|
8226
|
+
};
|
|
8227
|
+
const questionStyle = {
|
|
8228
|
+
fontSize: "1rem",
|
|
8229
|
+
lineHeight: 1.55,
|
|
8230
|
+
letterSpacing: "0.01em"
|
|
8231
|
+
};
|
|
8232
|
+
const questionIconStyle = {
|
|
8233
|
+
background: isDarkMode ? "rgba(59, 130, 246, 0.26)" : "rgba(59, 130, 246, 0.16)",
|
|
8234
|
+
color: isDarkMode ? "#dbeafe" : "#1d4ed8"
|
|
8235
|
+
};
|
|
8236
|
+
const cancelButtonClass = isDarkMode ? "flex-1 rounded-lg border border-zinc-500 bg-zinc-700/80 px-3 py-2 text-sm font-semibold text-zinc-100 transition-colors hover:bg-zinc-600" : "flex-1 rounded-lg border border-zinc-300 bg-zinc-100 px-3 py-2 text-sm font-semibold text-zinc-900 transition-colors hover:bg-zinc-200";
|
|
8237
|
+
const isSubmitDisabled = isUserInput && interrupt.required && !answer.trim() && (!interrupt.options || selectedIndices.length === 0);
|
|
8238
|
+
const submitButtonClass = `flex-1 rounded-lg border px-3 py-2 text-sm font-semibold transition-colors ${isSubmitDisabled ? "cursor-not-allowed" : "hover:brightness-105"}`;
|
|
8239
|
+
const cancelButtonStyle = isDarkMode ? {
|
|
8240
|
+
background: "rgba(63, 63, 70, 0.82)",
|
|
8241
|
+
color: "#f4f4f5",
|
|
8242
|
+
borderColor: "rgba(161, 161, 170, 0.6)"
|
|
8243
|
+
} : {
|
|
8244
|
+
background: "#f4f4f5",
|
|
8245
|
+
color: "#18181b",
|
|
8246
|
+
borderColor: "rgba(113, 113, 122, 0.45)"
|
|
8247
|
+
};
|
|
8248
|
+
const submitButtonStyle = isSubmitDisabled ? isDarkMode ? {
|
|
8249
|
+
background: "rgba(82, 82, 91, 0.72)",
|
|
8250
|
+
color: "#d4d4d8",
|
|
8251
|
+
borderColor: "rgba(161, 161, 170, 0.35)",
|
|
8252
|
+
boxShadow: "none"
|
|
8253
|
+
} : {
|
|
8254
|
+
background: "rgba(228, 228, 231, 0.98)",
|
|
8255
|
+
color: "#52525b",
|
|
8256
|
+
borderColor: "rgba(161, 161, 170, 0.42)",
|
|
8257
|
+
boxShadow: "none"
|
|
8258
|
+
} : isApproval && riskLevel === "high" ? {
|
|
8259
|
+
background: "#dc2626",
|
|
8260
|
+
color: "#ffffff",
|
|
8261
|
+
borderColor: "rgba(220, 38, 38, 0.9)",
|
|
8262
|
+
boxShadow: "0 2px 8px rgba(220, 38, 38, 0.35)"
|
|
8263
|
+
} : {
|
|
8264
|
+
background: "var(--chat-accent, #2563eb)",
|
|
8265
|
+
color: "#ffffff",
|
|
8266
|
+
borderColor: "transparent",
|
|
8267
|
+
boxShadow: "0 2px 10px rgba(37, 99, 235, 0.3)"
|
|
8268
|
+
};
|
|
8138
8269
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
8139
8270
|
"div",
|
|
8140
8271
|
{
|
|
8141
8272
|
className: `rounded-xl border ${cardBorder} ${cardBg} p-3 shadow-sm`,
|
|
8273
|
+
style: cardStyle,
|
|
8142
8274
|
role: "dialog",
|
|
8143
8275
|
"aria-modal": "true",
|
|
8144
8276
|
"aria-label": isApproval ? t.approvalRequest : t.inputRequest,
|
|
@@ -8153,7 +8285,7 @@ var HitlCard = (0, import_react24.memo)(function HitlCard2({
|
|
|
8153
8285
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "capitalize", children: riskLevel })
|
|
8154
8286
|
]
|
|
8155
8287
|
}
|
|
8156
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "text-
|
|
8288
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "inline-flex h-7 w-7 items-center justify-center rounded-full text-base font-semibold", style: questionIconStyle, children: "?" }) }),
|
|
8157
8289
|
timeLeft !== null && timeLeft > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: `text-xs ${textSecondary} whitespace-nowrap`, children: [
|
|
8158
8290
|
t.timeoutIn,
|
|
8159
8291
|
" ",
|
|
@@ -8162,7 +8294,7 @@ var HitlCard = (0, import_react24.memo)(function HitlCard2({
|
|
|
8162
8294
|
] })
|
|
8163
8295
|
] }),
|
|
8164
8296
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-2", children: [
|
|
8165
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: `text-sm font-
|
|
8297
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: `text-sm font-semibold ${textPrimary} break-words`, style: questionStyle, children: isApproval ? interrupt.reason || `${t.executeTool} ${interrupt.tool}?` : interrupt.question }),
|
|
8166
8298
|
isUserInput && interrupt.context && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: `text-xs ${textSecondary} rounded p-2 ${inputBg} break-words`, children: interrupt.context }),
|
|
8167
8299
|
isApproval && interrupt.tool && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `text-xs ${textSecondary} rounded p-2 ${inputBg} space-y-1`, children: [
|
|
8168
8300
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
@@ -8182,26 +8314,31 @@ var HitlCard = (0, import_react24.memo)(function HitlCard2({
|
|
|
8182
8314
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("code", { className: "text-[10px]", children: JSON.stringify(interrupt.args, null, 0) })
|
|
8183
8315
|
] })
|
|
8184
8316
|
] }),
|
|
8185
|
-
isUserInput && interrupt.options && interrupt.options.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-1.5", children: interrupt.options.map((option, index) =>
|
|
8186
|
-
|
|
8187
|
-
{
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8317
|
+
isUserInput && interrupt.options && interrupt.options.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-1.5", children: interrupt.options.map((option, index) => {
|
|
8318
|
+
const isSelected = selectedIndices.includes(index);
|
|
8319
|
+
const optionStyle = isSelected ? isDarkMode ? { borderColor: "rgba(96, 165, 250, 0.75)", background: "rgba(59, 130, 246, 0.24)" } : { borderColor: "rgba(37, 99, 235, 0.36)", background: "rgba(239, 246, 255, 0.98)" } : isDarkMode ? { borderColor: "rgba(113, 113, 122, 0.6)", background: "rgba(9, 9, 11, 0.84)" } : { borderColor: "rgba(113, 113, 122, 0.34)", background: "rgba(250, 250, 250, 0.96)" };
|
|
8320
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
8321
|
+
"label",
|
|
8322
|
+
{
|
|
8323
|
+
className: `flex cursor-pointer items-center gap-2 rounded p-2 transition-colors ${isSelected ? isDarkMode ? "border-blue-500/50 bg-blue-500/20" : "border-blue-200 bg-blue-50" : `${inputBg} border-transparent hover:border-zinc-300`} border`,
|
|
8324
|
+
style: optionStyle,
|
|
8325
|
+
children: [
|
|
8326
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
8327
|
+
"input",
|
|
8328
|
+
{
|
|
8329
|
+
type: interrupt.multi_select ? "checkbox" : "radio",
|
|
8330
|
+
name: "hitl-options",
|
|
8331
|
+
checked: isSelected,
|
|
8332
|
+
onChange: () => handleOptionToggle(index),
|
|
8333
|
+
style: optionControlStyle
|
|
8334
|
+
}
|
|
8335
|
+
),
|
|
8336
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `text-sm ${textPrimary} break-words ${isSelected ? "font-semibold" : "font-medium"}`, children: option })
|
|
8337
|
+
]
|
|
8338
|
+
},
|
|
8339
|
+
index
|
|
8340
|
+
);
|
|
8341
|
+
}) }),
|
|
8205
8342
|
isUserInput && (!interrupt.options || interrupt.options.length === 0) && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
8206
8343
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
8207
8344
|
"input",
|
|
@@ -8244,8 +8381,8 @@ var HitlCard = (0, import_react24.memo)(function HitlCard2({
|
|
|
8244
8381
|
"button",
|
|
8245
8382
|
{
|
|
8246
8383
|
onClick: handleCancel,
|
|
8247
|
-
|
|
8248
|
-
|
|
8384
|
+
className: cancelButtonClass,
|
|
8385
|
+
style: cancelButtonStyle,
|
|
8249
8386
|
children: isApproval ? t.reject : t.cancel
|
|
8250
8387
|
}
|
|
8251
8388
|
),
|
|
@@ -8253,8 +8390,9 @@ var HitlCard = (0, import_react24.memo)(function HitlCard2({
|
|
|
8253
8390
|
"button",
|
|
8254
8391
|
{
|
|
8255
8392
|
onClick: handleSubmit,
|
|
8256
|
-
disabled:
|
|
8257
|
-
className:
|
|
8393
|
+
disabled: isSubmitDisabled,
|
|
8394
|
+
className: submitButtonClass,
|
|
8395
|
+
style: submitButtonStyle,
|
|
8258
8396
|
children: isApproval ? t.approve : t.submit
|
|
8259
8397
|
}
|
|
8260
8398
|
)
|
package/dist/renderer/index.mjs
CHANGED
|
@@ -34,6 +34,7 @@ function useChat(options) {
|
|
|
34
34
|
const messagesRef = useRef(messages);
|
|
35
35
|
const conversationIdRef = useRef(conversationId);
|
|
36
36
|
const currentRunIdRef = useRef(null);
|
|
37
|
+
const pendingInterruptStreamIdRef = useRef(null);
|
|
37
38
|
const currentAgentIdRef = useRef(null);
|
|
38
39
|
const pendingCancelRef = useRef(false);
|
|
39
40
|
const pendingCancelTimeoutRef = useRef(null);
|
|
@@ -485,6 +486,7 @@ function useChat(options) {
|
|
|
485
486
|
setIsStreaming(false);
|
|
486
487
|
setIsLoading(false);
|
|
487
488
|
currentRunIdRef.current = null;
|
|
489
|
+
pendingInterruptStreamIdRef.current = null;
|
|
488
490
|
suppressStreamRef.current = false;
|
|
489
491
|
clearPendingCancel();
|
|
490
492
|
break;
|
|
@@ -521,6 +523,7 @@ function useChat(options) {
|
|
|
521
523
|
setIsLoading(false);
|
|
522
524
|
setPendingInterrupt(null);
|
|
523
525
|
currentRunIdRef.current = null;
|
|
526
|
+
pendingInterruptStreamIdRef.current = null;
|
|
524
527
|
suppressStreamRef.current = false;
|
|
525
528
|
clearPendingCancel();
|
|
526
529
|
break;
|
|
@@ -548,13 +551,19 @@ function useChat(options) {
|
|
|
548
551
|
setIsStreaming(false);
|
|
549
552
|
setIsLoading(false);
|
|
550
553
|
currentRunIdRef.current = null;
|
|
554
|
+
pendingInterruptStreamIdRef.current = null;
|
|
551
555
|
suppressStreamRef.current = false;
|
|
552
556
|
clearPendingCancel();
|
|
553
557
|
break;
|
|
554
558
|
}
|
|
555
559
|
case "interrupt": {
|
|
556
560
|
flushTypewriter();
|
|
557
|
-
|
|
561
|
+
if (event.run_id) {
|
|
562
|
+
currentRunIdRef.current = event.run_id;
|
|
563
|
+
}
|
|
564
|
+
if (event.stream_id) {
|
|
565
|
+
pendingInterruptStreamIdRef.current = event.stream_id;
|
|
566
|
+
}
|
|
558
567
|
const payload = event.interrupt_payload;
|
|
559
568
|
if (payload) {
|
|
560
569
|
setPendingInterrupt(payload);
|
|
@@ -577,6 +586,7 @@ function useChat(options) {
|
|
|
577
586
|
}
|
|
578
587
|
resetStreamBuffers();
|
|
579
588
|
currentRunIdRef.current = null;
|
|
589
|
+
pendingInterruptStreamIdRef.current = null;
|
|
580
590
|
const userMessage = {
|
|
581
591
|
id: crypto.randomUUID(),
|
|
582
592
|
role: "user",
|
|
@@ -696,6 +706,7 @@ function useChat(options) {
|
|
|
696
706
|
});
|
|
697
707
|
resetStreamBuffers();
|
|
698
708
|
currentRunIdRef.current = null;
|
|
709
|
+
pendingInterruptStreamIdRef.current = null;
|
|
699
710
|
if (!shouldDelayCancel) {
|
|
700
711
|
clearPendingCancel();
|
|
701
712
|
suppressStreamRef.current = false;
|
|
@@ -712,6 +723,7 @@ function useChat(options) {
|
|
|
712
723
|
setIsStreaming(false);
|
|
713
724
|
resetStreamBuffers();
|
|
714
725
|
currentRunIdRef.current = null;
|
|
726
|
+
pendingInterruptStreamIdRef.current = null;
|
|
715
727
|
clearPendingCancel();
|
|
716
728
|
suppressStreamRef.current = false;
|
|
717
729
|
}, [clearPendingCancel, resetStreamBuffers]);
|
|
@@ -749,23 +761,31 @@ function useChat(options) {
|
|
|
749
761
|
setPendingInterrupt(null);
|
|
750
762
|
resetStreamBuffers();
|
|
751
763
|
currentRunIdRef.current = null;
|
|
764
|
+
pendingInterruptStreamIdRef.current = null;
|
|
752
765
|
clearPendingCancel();
|
|
753
766
|
}, [clearPendingCancel, resetStreamBuffers]);
|
|
754
767
|
const sendHitlResponse = useCallback((response) => {
|
|
755
|
-
adapter.sendHitlResponse?.(
|
|
768
|
+
adapter.sendHitlResponse?.(
|
|
769
|
+
response,
|
|
770
|
+
currentRunIdRef.current ?? void 0,
|
|
771
|
+
pendingInterruptStreamIdRef.current ?? void 0
|
|
772
|
+
);
|
|
756
773
|
}, [adapter]);
|
|
757
774
|
const approveHitl = useCallback((remember = false) => {
|
|
758
775
|
sendHitlResponse({ approved: true, remember });
|
|
759
776
|
setPendingInterrupt(null);
|
|
777
|
+
pendingInterruptStreamIdRef.current = null;
|
|
760
778
|
}, [sendHitlResponse]);
|
|
761
779
|
const rejectHitl = useCallback((remember = false) => {
|
|
762
780
|
sendHitlResponse({ approved: false, remember });
|
|
763
781
|
setPendingInterrupt(null);
|
|
782
|
+
pendingInterruptStreamIdRef.current = null;
|
|
764
783
|
setIsLoading(false);
|
|
765
784
|
}, [sendHitlResponse]);
|
|
766
785
|
const submitHitlInput = useCallback((response) => {
|
|
767
786
|
sendHitlResponse(response);
|
|
768
787
|
setPendingInterrupt(null);
|
|
788
|
+
pendingInterruptStreamIdRef.current = null;
|
|
769
789
|
if (response.cancelled || response.timed_out) setIsLoading(false);
|
|
770
790
|
}, [sendHitlResponse]);
|
|
771
791
|
const removeSessionResource = useCallback((fullId) => {
|
|
@@ -5875,13 +5895,19 @@ function createIpcAdapter() {
|
|
|
5875
5895
|
async chatStream(messages, conversationId, onEvent, options) {
|
|
5876
5896
|
const streamId = crypto.randomUUID();
|
|
5877
5897
|
streamCallbacks.set(streamId, (event) => {
|
|
5878
|
-
if (event.type === "start"
|
|
5898
|
+
if (event.type === "start") {
|
|
5879
5899
|
currentRunId = event.run_id || null;
|
|
5880
5900
|
}
|
|
5901
|
+
if (event.type === "interrupt") {
|
|
5902
|
+
const interruptRunId = event.run_id;
|
|
5903
|
+
if (interruptRunId) {
|
|
5904
|
+
currentRunId = interruptRunId;
|
|
5905
|
+
}
|
|
5906
|
+
}
|
|
5881
5907
|
if (event.type === "done" || event.type === "cancelled" || event.type === "error") {
|
|
5882
5908
|
currentRunId = null;
|
|
5883
5909
|
}
|
|
5884
|
-
onEvent(event);
|
|
5910
|
+
onEvent({ ...event, stream_id: streamId });
|
|
5885
5911
|
});
|
|
5886
5912
|
try {
|
|
5887
5913
|
await api.stream({
|
|
@@ -5903,8 +5929,12 @@ function createIpcAdapter() {
|
|
|
5903
5929
|
throw e;
|
|
5904
5930
|
}
|
|
5905
5931
|
},
|
|
5906
|
-
sendHitlResponse(response, runId) {
|
|
5907
|
-
api.sendHitlResponse({
|
|
5932
|
+
sendHitlResponse(response, runId, streamId) {
|
|
5933
|
+
api.sendHitlResponse({
|
|
5934
|
+
response,
|
|
5935
|
+
runId: runId || currentRunId || void 0,
|
|
5936
|
+
streamId: streamId || void 0
|
|
5937
|
+
});
|
|
5908
5938
|
},
|
|
5909
5939
|
cleanup() {
|
|
5910
5940
|
streamEventCleanup?.();
|
|
@@ -6278,8 +6308,10 @@ function processStreamEvents(stream, onEvent, sdk, setCurrentRunId) {
|
|
|
6278
6308
|
default: {
|
|
6279
6309
|
const evt = event;
|
|
6280
6310
|
if (evt.type === "interrupt") {
|
|
6281
|
-
|
|
6282
|
-
|
|
6311
|
+
if (evt.run_id) {
|
|
6312
|
+
currentRunId = evt.run_id;
|
|
6313
|
+
setCurrentRunId(evt.run_id);
|
|
6314
|
+
}
|
|
6283
6315
|
onEvent({
|
|
6284
6316
|
type: "interrupt",
|
|
6285
6317
|
interrupt_type: evt.interrupt_type || "",
|
|
@@ -7946,6 +7978,23 @@ var defaultStrings = {
|
|
|
7946
7978
|
approvalRequest: "Approval Request",
|
|
7947
7979
|
inputRequest: "Input Request"
|
|
7948
7980
|
};
|
|
7981
|
+
var defaultZhStrings = {
|
|
7982
|
+
approve: "\u6279\u51C6",
|
|
7983
|
+
reject: "\u62D2\u7EDD",
|
|
7984
|
+
submit: "\u63D0\u4EA4",
|
|
7985
|
+
cancel: "\u53D6\u6D88",
|
|
7986
|
+
rememberChoice: "\u8BB0\u4F4F\u672C\u6B21\u9009\u62E9",
|
|
7987
|
+
requiredField: "\u6B64\u9879\u5FC5\u586B",
|
|
7988
|
+
timeoutIn: "\u8D85\u65F6\u5269\u4F59",
|
|
7989
|
+
seconds: "\u79D2",
|
|
7990
|
+
executeTool: "\u6267\u884C",
|
|
7991
|
+
toolLabel: "\u5DE5\u5177",
|
|
7992
|
+
argsLabel: "\u53C2\u6570",
|
|
7993
|
+
defaultPrefix: "\u9ED8\u8BA4",
|
|
7994
|
+
enterResponse: "\u8BF7\u8F93\u5165\u4F60\u7684\u56DE\u590D...",
|
|
7995
|
+
approvalRequest: "\u9700\u8981\u5BA1\u6279",
|
|
7996
|
+
inputRequest: "\u9700\u8981\u8F93\u5165"
|
|
7997
|
+
};
|
|
7949
7998
|
var riskColors = {
|
|
7950
7999
|
low: {
|
|
7951
8000
|
bg: "bg-blue-500/10",
|
|
@@ -7975,9 +8024,37 @@ var HitlCard = memo8(function HitlCard2({
|
|
|
7975
8024
|
isDarkMode = false,
|
|
7976
8025
|
strings = {}
|
|
7977
8026
|
}) {
|
|
7978
|
-
const
|
|
8027
|
+
const mergedStrings = { ...defaultStrings, ...strings };
|
|
7979
8028
|
const isApproval = interrupt.type === "approval_request";
|
|
7980
8029
|
const isUserInput = interrupt.type === "user_input_request";
|
|
8030
|
+
const cjkRegex = /[\u3400-\u9fff]/;
|
|
8031
|
+
const hasCjkContent = cjkRegex.test(
|
|
8032
|
+
[
|
|
8033
|
+
interrupt.question || "",
|
|
8034
|
+
interrupt.context || "",
|
|
8035
|
+
interrupt.reason || "",
|
|
8036
|
+
interrupt.tool || "",
|
|
8037
|
+
...interrupt.options || []
|
|
8038
|
+
].join(" ")
|
|
8039
|
+
);
|
|
8040
|
+
const t = hasCjkContent ? {
|
|
8041
|
+
...mergedStrings,
|
|
8042
|
+
approve: mergedStrings.approve === defaultStrings.approve ? defaultZhStrings.approve : mergedStrings.approve,
|
|
8043
|
+
reject: mergedStrings.reject === defaultStrings.reject ? defaultZhStrings.reject : mergedStrings.reject,
|
|
8044
|
+
submit: mergedStrings.submit === defaultStrings.submit ? defaultZhStrings.submit : mergedStrings.submit,
|
|
8045
|
+
cancel: mergedStrings.cancel === defaultStrings.cancel ? defaultZhStrings.cancel : mergedStrings.cancel,
|
|
8046
|
+
rememberChoice: mergedStrings.rememberChoice === defaultStrings.rememberChoice ? defaultZhStrings.rememberChoice : mergedStrings.rememberChoice,
|
|
8047
|
+
requiredField: mergedStrings.requiredField === defaultStrings.requiredField ? defaultZhStrings.requiredField : mergedStrings.requiredField,
|
|
8048
|
+
timeoutIn: mergedStrings.timeoutIn === defaultStrings.timeoutIn ? defaultZhStrings.timeoutIn : mergedStrings.timeoutIn,
|
|
8049
|
+
seconds: mergedStrings.seconds === defaultStrings.seconds ? defaultZhStrings.seconds : mergedStrings.seconds,
|
|
8050
|
+
executeTool: mergedStrings.executeTool === defaultStrings.executeTool ? defaultZhStrings.executeTool : mergedStrings.executeTool,
|
|
8051
|
+
toolLabel: mergedStrings.toolLabel === defaultStrings.toolLabel ? defaultZhStrings.toolLabel : mergedStrings.toolLabel,
|
|
8052
|
+
argsLabel: mergedStrings.argsLabel === defaultStrings.argsLabel ? defaultZhStrings.argsLabel : mergedStrings.argsLabel,
|
|
8053
|
+
defaultPrefix: mergedStrings.defaultPrefix === defaultStrings.defaultPrefix ? defaultZhStrings.defaultPrefix : mergedStrings.defaultPrefix,
|
|
8054
|
+
enterResponse: mergedStrings.enterResponse === defaultStrings.enterResponse ? defaultZhStrings.enterResponse : mergedStrings.enterResponse,
|
|
8055
|
+
approvalRequest: mergedStrings.approvalRequest === defaultStrings.approvalRequest ? defaultZhStrings.approvalRequest : mergedStrings.approvalRequest,
|
|
8056
|
+
inputRequest: mergedStrings.inputRequest === defaultStrings.inputRequest ? defaultZhStrings.inputRequest : mergedStrings.inputRequest
|
|
8057
|
+
} : mergedStrings;
|
|
7981
8058
|
const [answer, setAnswer] = useState15(interrupt.default || "");
|
|
7982
8059
|
const [selectedIndices, setSelectedIndices] = useState15([]);
|
|
7983
8060
|
const [isComposing, setIsComposing] = useState15(false);
|
|
@@ -8058,15 +8135,70 @@ var HitlCard = memo8(function HitlCard2({
|
|
|
8058
8135
|
}
|
|
8059
8136
|
};
|
|
8060
8137
|
const cardBg = isDarkMode ? "bg-zinc-800" : "bg-white";
|
|
8061
|
-
const cardBorder = isDarkMode ? "border-zinc-
|
|
8138
|
+
const cardBorder = isDarkMode ? "border-zinc-600" : "border-zinc-300";
|
|
8062
8139
|
const textPrimary = isDarkMode ? "text-zinc-100" : "text-zinc-900";
|
|
8063
8140
|
const textSecondary = isDarkMode ? "text-zinc-400" : "text-zinc-500";
|
|
8064
8141
|
const inputBg = isDarkMode ? "bg-zinc-900" : "bg-zinc-50";
|
|
8065
8142
|
const inputBorder = isDarkMode ? "border-zinc-600" : "border-zinc-300";
|
|
8143
|
+
const optionControlStyle = {
|
|
8144
|
+
accentColor: "var(--chat-accent, #2563eb)",
|
|
8145
|
+
width: "1.125rem",
|
|
8146
|
+
height: "1.125rem",
|
|
8147
|
+
margin: 0,
|
|
8148
|
+
flexShrink: 0
|
|
8149
|
+
};
|
|
8150
|
+
const cardStyle = {
|
|
8151
|
+
background: isDarkMode ? "rgba(24, 24, 27, 0.98)" : "#ffffff",
|
|
8152
|
+
borderColor: isDarkMode ? "rgba(212, 212, 216, 0.2)" : "rgba(63, 63, 70, 0.22)",
|
|
8153
|
+
boxShadow: isDarkMode ? "0 12px 30px rgba(0, 0, 0, 0.4)" : "0 10px 24px rgba(15, 23, 42, 0.14)"
|
|
8154
|
+
};
|
|
8155
|
+
const questionStyle = {
|
|
8156
|
+
fontSize: "1rem",
|
|
8157
|
+
lineHeight: 1.55,
|
|
8158
|
+
letterSpacing: "0.01em"
|
|
8159
|
+
};
|
|
8160
|
+
const questionIconStyle = {
|
|
8161
|
+
background: isDarkMode ? "rgba(59, 130, 246, 0.26)" : "rgba(59, 130, 246, 0.16)",
|
|
8162
|
+
color: isDarkMode ? "#dbeafe" : "#1d4ed8"
|
|
8163
|
+
};
|
|
8164
|
+
const cancelButtonClass = isDarkMode ? "flex-1 rounded-lg border border-zinc-500 bg-zinc-700/80 px-3 py-2 text-sm font-semibold text-zinc-100 transition-colors hover:bg-zinc-600" : "flex-1 rounded-lg border border-zinc-300 bg-zinc-100 px-3 py-2 text-sm font-semibold text-zinc-900 transition-colors hover:bg-zinc-200";
|
|
8165
|
+
const isSubmitDisabled = isUserInput && interrupt.required && !answer.trim() && (!interrupt.options || selectedIndices.length === 0);
|
|
8166
|
+
const submitButtonClass = `flex-1 rounded-lg border px-3 py-2 text-sm font-semibold transition-colors ${isSubmitDisabled ? "cursor-not-allowed" : "hover:brightness-105"}`;
|
|
8167
|
+
const cancelButtonStyle = isDarkMode ? {
|
|
8168
|
+
background: "rgba(63, 63, 70, 0.82)",
|
|
8169
|
+
color: "#f4f4f5",
|
|
8170
|
+
borderColor: "rgba(161, 161, 170, 0.6)"
|
|
8171
|
+
} : {
|
|
8172
|
+
background: "#f4f4f5",
|
|
8173
|
+
color: "#18181b",
|
|
8174
|
+
borderColor: "rgba(113, 113, 122, 0.45)"
|
|
8175
|
+
};
|
|
8176
|
+
const submitButtonStyle = isSubmitDisabled ? isDarkMode ? {
|
|
8177
|
+
background: "rgba(82, 82, 91, 0.72)",
|
|
8178
|
+
color: "#d4d4d8",
|
|
8179
|
+
borderColor: "rgba(161, 161, 170, 0.35)",
|
|
8180
|
+
boxShadow: "none"
|
|
8181
|
+
} : {
|
|
8182
|
+
background: "rgba(228, 228, 231, 0.98)",
|
|
8183
|
+
color: "#52525b",
|
|
8184
|
+
borderColor: "rgba(161, 161, 170, 0.42)",
|
|
8185
|
+
boxShadow: "none"
|
|
8186
|
+
} : isApproval && riskLevel === "high" ? {
|
|
8187
|
+
background: "#dc2626",
|
|
8188
|
+
color: "#ffffff",
|
|
8189
|
+
borderColor: "rgba(220, 38, 38, 0.9)",
|
|
8190
|
+
boxShadow: "0 2px 8px rgba(220, 38, 38, 0.35)"
|
|
8191
|
+
} : {
|
|
8192
|
+
background: "var(--chat-accent, #2563eb)",
|
|
8193
|
+
color: "#ffffff",
|
|
8194
|
+
borderColor: "transparent",
|
|
8195
|
+
boxShadow: "0 2px 10px rgba(37, 99, 235, 0.3)"
|
|
8196
|
+
};
|
|
8066
8197
|
return /* @__PURE__ */ jsxs6(
|
|
8067
8198
|
"div",
|
|
8068
8199
|
{
|
|
8069
8200
|
className: `rounded-xl border ${cardBorder} ${cardBg} p-3 shadow-sm`,
|
|
8201
|
+
style: cardStyle,
|
|
8070
8202
|
role: "dialog",
|
|
8071
8203
|
"aria-modal": "true",
|
|
8072
8204
|
"aria-label": isApproval ? t.approvalRequest : t.inputRequest,
|
|
@@ -8081,7 +8213,7 @@ var HitlCard = memo8(function HitlCard2({
|
|
|
8081
8213
|
/* @__PURE__ */ jsx12("span", { className: "capitalize", children: riskLevel })
|
|
8082
8214
|
]
|
|
8083
8215
|
}
|
|
8084
|
-
) : /* @__PURE__ */ jsx12("span", { className: "text-
|
|
8216
|
+
) : /* @__PURE__ */ jsx12("span", { className: "inline-flex h-7 w-7 items-center justify-center rounded-full text-base font-semibold", style: questionIconStyle, children: "?" }) }),
|
|
8085
8217
|
timeLeft !== null && timeLeft > 0 && /* @__PURE__ */ jsxs6("span", { className: `text-xs ${textSecondary} whitespace-nowrap`, children: [
|
|
8086
8218
|
t.timeoutIn,
|
|
8087
8219
|
" ",
|
|
@@ -8090,7 +8222,7 @@ var HitlCard = memo8(function HitlCard2({
|
|
|
8090
8222
|
] })
|
|
8091
8223
|
] }),
|
|
8092
8224
|
/* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
|
|
8093
|
-
/* @__PURE__ */ jsx12("p", { className: `text-sm font-
|
|
8225
|
+
/* @__PURE__ */ jsx12("p", { className: `text-sm font-semibold ${textPrimary} break-words`, style: questionStyle, children: isApproval ? interrupt.reason || `${t.executeTool} ${interrupt.tool}?` : interrupt.question }),
|
|
8094
8226
|
isUserInput && interrupt.context && /* @__PURE__ */ jsx12("div", { className: `text-xs ${textSecondary} rounded p-2 ${inputBg} break-words`, children: interrupt.context }),
|
|
8095
8227
|
isApproval && interrupt.tool && /* @__PURE__ */ jsxs6("div", { className: `text-xs ${textSecondary} rounded p-2 ${inputBg} space-y-1`, children: [
|
|
8096
8228
|
/* @__PURE__ */ jsxs6("div", { children: [
|
|
@@ -8110,26 +8242,31 @@ var HitlCard = memo8(function HitlCard2({
|
|
|
8110
8242
|
/* @__PURE__ */ jsx12("code", { className: "text-[10px]", children: JSON.stringify(interrupt.args, null, 0) })
|
|
8111
8243
|
] })
|
|
8112
8244
|
] }),
|
|
8113
|
-
isUserInput && interrupt.options && interrupt.options.length > 0 && /* @__PURE__ */ jsx12("div", { className: "space-y-1.5", children: interrupt.options.map((option, index) =>
|
|
8114
|
-
|
|
8115
|
-
{
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8245
|
+
isUserInput && interrupt.options && interrupt.options.length > 0 && /* @__PURE__ */ jsx12("div", { className: "space-y-1.5", children: interrupt.options.map((option, index) => {
|
|
8246
|
+
const isSelected = selectedIndices.includes(index);
|
|
8247
|
+
const optionStyle = isSelected ? isDarkMode ? { borderColor: "rgba(96, 165, 250, 0.75)", background: "rgba(59, 130, 246, 0.24)" } : { borderColor: "rgba(37, 99, 235, 0.36)", background: "rgba(239, 246, 255, 0.98)" } : isDarkMode ? { borderColor: "rgba(113, 113, 122, 0.6)", background: "rgba(9, 9, 11, 0.84)" } : { borderColor: "rgba(113, 113, 122, 0.34)", background: "rgba(250, 250, 250, 0.96)" };
|
|
8248
|
+
return /* @__PURE__ */ jsxs6(
|
|
8249
|
+
"label",
|
|
8250
|
+
{
|
|
8251
|
+
className: `flex cursor-pointer items-center gap-2 rounded p-2 transition-colors ${isSelected ? isDarkMode ? "border-blue-500/50 bg-blue-500/20" : "border-blue-200 bg-blue-50" : `${inputBg} border-transparent hover:border-zinc-300`} border`,
|
|
8252
|
+
style: optionStyle,
|
|
8253
|
+
children: [
|
|
8254
|
+
/* @__PURE__ */ jsx12(
|
|
8255
|
+
"input",
|
|
8256
|
+
{
|
|
8257
|
+
type: interrupt.multi_select ? "checkbox" : "radio",
|
|
8258
|
+
name: "hitl-options",
|
|
8259
|
+
checked: isSelected,
|
|
8260
|
+
onChange: () => handleOptionToggle(index),
|
|
8261
|
+
style: optionControlStyle
|
|
8262
|
+
}
|
|
8263
|
+
),
|
|
8264
|
+
/* @__PURE__ */ jsx12("span", { className: `text-sm ${textPrimary} break-words ${isSelected ? "font-semibold" : "font-medium"}`, children: option })
|
|
8265
|
+
]
|
|
8266
|
+
},
|
|
8267
|
+
index
|
|
8268
|
+
);
|
|
8269
|
+
}) }),
|
|
8133
8270
|
isUserInput && (!interrupt.options || interrupt.options.length === 0) && /* @__PURE__ */ jsxs6("div", { children: [
|
|
8134
8271
|
/* @__PURE__ */ jsx12(
|
|
8135
8272
|
"input",
|
|
@@ -8172,8 +8309,8 @@ var HitlCard = memo8(function HitlCard2({
|
|
|
8172
8309
|
"button",
|
|
8173
8310
|
{
|
|
8174
8311
|
onClick: handleCancel,
|
|
8175
|
-
|
|
8176
|
-
|
|
8312
|
+
className: cancelButtonClass,
|
|
8313
|
+
style: cancelButtonStyle,
|
|
8177
8314
|
children: isApproval ? t.reject : t.cancel
|
|
8178
8315
|
}
|
|
8179
8316
|
),
|
|
@@ -8181,8 +8318,9 @@ var HitlCard = memo8(function HitlCard2({
|
|
|
8181
8318
|
"button",
|
|
8182
8319
|
{
|
|
8183
8320
|
onClick: handleSubmit,
|
|
8184
|
-
disabled:
|
|
8185
|
-
className:
|
|
8321
|
+
disabled: isSubmitDisabled,
|
|
8322
|
+
className: submitButtonClass,
|
|
8323
|
+
style: submitButtonStyle,
|
|
8186
8324
|
children: isApproval ? t.approve : t.submit
|
|
8187
8325
|
}
|
|
8188
8326
|
)
|