shennian 0.4.42 → 0.4.44
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/publish-build-manifest.json +130 -50
- package/dist/src/agents/adapter.d.ts +8 -0
- package/dist/src/agents/adapter.js +1 -1
- package/dist/src/agents/codex.d.ts +3 -1
- package/dist/src/agents/codex.js +10 -10
- package/dist/src/agents/pi-coding-agent.d.ts +3 -1
- package/dist/src/agents/pi-coding-agent.js +4 -4
- package/dist/src/commands/daemon-process.d.ts +2 -0
- package/dist/src/commands/daemon-process.js +1 -1
- package/dist/src/commands/daemon.d.ts +1 -1
- package/dist/src/commands/daemon.js +6 -6
- package/dist/src/commands/manager.js +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/manager/prompt.d.ts +1 -1
- package/dist/src/manager/prompt.js +4 -3
- package/dist/src/manager/registry.d.ts +9 -3
- package/dist/src/manager/registry.js +1 -1
- package/dist/src/manager/runtime.d.ts +9 -16
- package/dist/src/manager/runtime.js +8 -20
- package/dist/src/manager/worker-ipc.d.ts +17 -0
- package/dist/src/manager/worker-ipc.js +1 -0
- package/dist/src/manager/worker-markdown.d.ts +10 -0
- package/dist/src/manager/worker-markdown.js +6 -0
- package/dist/src/native-fusion/codex-message-parser.d.ts +9 -0
- package/dist/src/native-fusion/codex-message-parser.js +1 -0
- package/dist/src/native-fusion/codex-parser.js +3 -3
- package/dist/src/native-fusion/service.d.ts +3 -0
- package/dist/src/native-fusion/service.js +2 -2
- package/dist/src/native-fusion/state.js +2 -2
- package/dist/src/native-fusion/types.d.ts +2 -0
- package/dist/src/room/activation-service.js +5 -5
- package/dist/src/room/managed-room-binding.js +1 -1
- package/dist/src/room/mirror-sync-service.d.ts +2 -0
- package/dist/src/room/mirror-sync-service.js +1 -1
- package/dist/src/room/registration-authority.d.ts +4 -0
- package/dist/src/room/registration-authority.js +1 -0
- package/dist/src/room/room-action-client-types.d.ts +136 -0
- package/dist/src/room/room-action-client-types.js +1 -0
- package/dist/src/room/room-action-client.d.ts +3 -134
- package/dist/src/room/room-action-client.js +1 -1
- package/dist/src/room/session-registry.d.ts +5 -0
- package/dist/src/room/session-registry.js +2 -2
- package/dist/src/session/deletion-sync-validation.d.ts +2 -0
- package/dist/src/session/deletion-sync-validation.js +1 -0
- package/dist/src/session/handlers/agent-control.d.ts +4 -0
- package/dist/src/session/handlers/agent-control.js +1 -0
- package/dist/src/session/handlers/agent-workspace-validation.d.ts +1 -0
- package/dist/src/session/handlers/agent-workspace-validation.js +1 -1
- package/dist/src/session/handlers/chat-adapter-config.d.ts +11 -0
- package/dist/src/session/handlers/chat-adapter-config.js +1 -0
- package/dist/src/session/handlers/chat-events.d.ts +5 -0
- package/dist/src/session/handlers/chat-events.js +2 -0
- package/dist/src/session/handlers/chat-recovery.d.ts +4 -0
- package/dist/src/session/handlers/chat-recovery.js +1 -0
- package/dist/src/session/handlers/chat-session-lifecycle.d.ts +9 -0
- package/dist/src/session/handlers/chat-session-lifecycle.js +1 -0
- package/dist/src/session/handlers/chat.d.ts +1 -3
- package/dist/src/session/handlers/chat.js +1 -2
- package/dist/src/session/handlers/room-managed.d.ts +1 -0
- package/dist/src/session/handlers/room-managed.js +1 -1
- package/dist/src/session/manager.d.ts +3 -6
- package/dist/src/session/manager.js +2 -2
- package/dist/src/session/queue-helpers.d.ts +14 -0
- package/dist/src/session/queue-helpers.js +11 -0
- package/dist/src/session/queue-retry.d.ts +11 -0
- package/dist/src/session/queue-retry.js +1 -0
- package/dist/src/session/queue-storage.d.ts +7 -0
- package/dist/src/session/queue-storage.js +2 -0
- package/dist/src/session/queue.d.ts +25 -11
- package/dist/src/session/queue.js +1 -12
- package/dist/src/session/queued-chat-dispatch.d.ts +8 -0
- package/dist/src/session/queued-chat-dispatch.js +1 -0
- package/dist/src/session/run-recovery/schema.d.ts +3 -1
- package/dist/src/session/run-recovery/schema.js +1 -1
- package/dist/src/session/turn-trigger.d.ts +33 -0
- package/dist/src/session/turn-trigger.js +1 -0
- package/dist/src/session/types.d.ts +2 -1
- package/node_modules/@shennian/wire/dist/message-payload.js +1 -1
- package/node_modules/@shennian/wire/dist/methods.d.ts +1 -1
- package/node_modules/@shennian/wire/dist/session.d.ts +12 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"jsMinified": true,
|
|
4
4
|
"minifier": "esbuild",
|
|
5
|
-
"fileCount":
|
|
5
|
+
"fileCount": 200,
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"file": "bin/shennian.js",
|
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
},
|
|
92
92
|
{
|
|
93
93
|
"file": "src/agents/adapter.js",
|
|
94
|
-
"beforeBytes":
|
|
95
|
-
"afterBytes":
|
|
94
|
+
"beforeBytes": 3707,
|
|
95
|
+
"afterBytes": 1948
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
"file": "src/agents/claude-managed-permissions.js",
|
|
@@ -121,8 +121,8 @@
|
|
|
121
121
|
},
|
|
122
122
|
{
|
|
123
123
|
"file": "src/agents/codex.js",
|
|
124
|
-
"beforeBytes":
|
|
125
|
-
"afterBytes":
|
|
124
|
+
"beforeBytes": 67113,
|
|
125
|
+
"afterBytes": 34450
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
"file": "src/agents/command-spec.js",
|
|
@@ -241,8 +241,8 @@
|
|
|
241
241
|
},
|
|
242
242
|
{
|
|
243
243
|
"file": "src/agents/pi-coding-agent.js",
|
|
244
|
-
"beforeBytes":
|
|
245
|
-
"afterBytes":
|
|
244
|
+
"beforeBytes": 25531,
|
|
245
|
+
"afterBytes": 13883
|
|
246
246
|
},
|
|
247
247
|
{
|
|
248
248
|
"file": "src/agents/pi-managed-extension.js",
|
|
@@ -296,8 +296,8 @@
|
|
|
296
296
|
},
|
|
297
297
|
{
|
|
298
298
|
"file": "src/commands/daemon-process.js",
|
|
299
|
-
"beforeBytes":
|
|
300
|
-
"afterBytes":
|
|
299
|
+
"beforeBytes": 5337,
|
|
300
|
+
"afterBytes": 2995
|
|
301
301
|
},
|
|
302
302
|
{
|
|
303
303
|
"file": "src/commands/daemon-start-wait.js",
|
|
@@ -311,8 +311,8 @@
|
|
|
311
311
|
},
|
|
312
312
|
{
|
|
313
313
|
"file": "src/commands/daemon.js",
|
|
314
|
-
"beforeBytes":
|
|
315
|
-
"afterBytes":
|
|
314
|
+
"beforeBytes": 45807,
|
|
315
|
+
"afterBytes": 21994
|
|
316
316
|
},
|
|
317
317
|
{
|
|
318
318
|
"file": "src/commands/integration.js",
|
|
@@ -326,8 +326,8 @@
|
|
|
326
326
|
},
|
|
327
327
|
{
|
|
328
328
|
"file": "src/commands/manager.js",
|
|
329
|
-
"beforeBytes":
|
|
330
|
-
"afterBytes":
|
|
329
|
+
"beforeBytes": 10029,
|
|
330
|
+
"afterBytes": 6444
|
|
331
331
|
},
|
|
332
332
|
{
|
|
333
333
|
"file": "src/commands/pair-authorization.js",
|
|
@@ -441,8 +441,8 @@
|
|
|
441
441
|
},
|
|
442
442
|
{
|
|
443
443
|
"file": "src/index.js",
|
|
444
|
-
"beforeBytes":
|
|
445
|
-
"afterBytes":
|
|
444
|
+
"beforeBytes": 36726,
|
|
445
|
+
"afterBytes": 18286
|
|
446
446
|
},
|
|
447
447
|
{
|
|
448
448
|
"file": "src/log-redaction.js",
|
|
@@ -456,13 +456,13 @@
|
|
|
456
456
|
},
|
|
457
457
|
{
|
|
458
458
|
"file": "src/manager/prompt.js",
|
|
459
|
-
"beforeBytes":
|
|
460
|
-
"afterBytes":
|
|
459
|
+
"beforeBytes": 4582,
|
|
460
|
+
"afterBytes": 7519
|
|
461
461
|
},
|
|
462
462
|
{
|
|
463
463
|
"file": "src/manager/registry.js",
|
|
464
|
-
"beforeBytes":
|
|
465
|
-
"afterBytes":
|
|
464
|
+
"beforeBytes": 14080,
|
|
465
|
+
"afterBytes": 6882
|
|
466
466
|
},
|
|
467
467
|
{
|
|
468
468
|
"file": "src/manager/retired-external-channel-compat.js",
|
|
@@ -471,18 +471,33 @@
|
|
|
471
471
|
},
|
|
472
472
|
{
|
|
473
473
|
"file": "src/manager/runtime.js",
|
|
474
|
-
"beforeBytes":
|
|
475
|
-
"afterBytes":
|
|
474
|
+
"beforeBytes": 25164,
|
|
475
|
+
"afterBytes": 12805
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"file": "src/manager/worker-ipc.js",
|
|
479
|
+
"beforeBytes": 10872,
|
|
480
|
+
"afterBytes": 5983
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"file": "src/manager/worker-markdown.js",
|
|
484
|
+
"beforeBytes": 1327,
|
|
485
|
+
"afterBytes": 884
|
|
476
486
|
},
|
|
477
487
|
{
|
|
478
488
|
"file": "src/native-fusion/codex-files.js",
|
|
479
489
|
"beforeBytes": 4582,
|
|
480
490
|
"afterBytes": 2163
|
|
481
491
|
},
|
|
492
|
+
{
|
|
493
|
+
"file": "src/native-fusion/codex-message-parser.js",
|
|
494
|
+
"beforeBytes": 4048,
|
|
495
|
+
"afterBytes": 1955
|
|
496
|
+
},
|
|
482
497
|
{
|
|
483
498
|
"file": "src/native-fusion/codex-parser.js",
|
|
484
|
-
"beforeBytes":
|
|
485
|
-
"afterBytes":
|
|
499
|
+
"beforeBytes": 26689,
|
|
500
|
+
"afterBytes": 10912
|
|
486
501
|
},
|
|
487
502
|
{
|
|
488
503
|
"file": "src/native-fusion/codex-user-input.js",
|
|
@@ -526,8 +541,8 @@
|
|
|
526
541
|
},
|
|
527
542
|
{
|
|
528
543
|
"file": "src/native-fusion/service.js",
|
|
529
|
-
"beforeBytes":
|
|
530
|
-
"afterBytes":
|
|
544
|
+
"beforeBytes": 37567,
|
|
545
|
+
"afterBytes": 16892
|
|
531
546
|
},
|
|
532
547
|
{
|
|
533
548
|
"file": "src/native-fusion/session-header.js",
|
|
@@ -536,8 +551,8 @@
|
|
|
536
551
|
},
|
|
537
552
|
{
|
|
538
553
|
"file": "src/native-fusion/state.js",
|
|
539
|
-
"beforeBytes":
|
|
540
|
-
"afterBytes":
|
|
554
|
+
"beforeBytes": 4401,
|
|
555
|
+
"afterBytes": 2293
|
|
541
556
|
},
|
|
542
557
|
{
|
|
543
558
|
"file": "src/native-fusion/types.js",
|
|
@@ -591,8 +606,8 @@
|
|
|
591
606
|
},
|
|
592
607
|
{
|
|
593
608
|
"file": "src/room/activation-service.js",
|
|
594
|
-
"beforeBytes":
|
|
595
|
-
"afterBytes":
|
|
609
|
+
"beforeBytes": 24933,
|
|
610
|
+
"afterBytes": 12454
|
|
596
611
|
},
|
|
597
612
|
{
|
|
598
613
|
"file": "src/room/attachment-cache.js",
|
|
@@ -636,8 +651,8 @@
|
|
|
636
651
|
},
|
|
637
652
|
{
|
|
638
653
|
"file": "src/room/managed-room-binding.js",
|
|
639
|
-
"beforeBytes":
|
|
640
|
-
"afterBytes":
|
|
654
|
+
"beforeBytes": 6573,
|
|
655
|
+
"afterBytes": 3483
|
|
641
656
|
},
|
|
642
657
|
{
|
|
643
658
|
"file": "src/room/managed-room-ipc.js",
|
|
@@ -646,8 +661,8 @@
|
|
|
646
661
|
},
|
|
647
662
|
{
|
|
648
663
|
"file": "src/room/mirror-sync-service.js",
|
|
649
|
-
"beforeBytes":
|
|
650
|
-
"afterBytes":
|
|
664
|
+
"beforeBytes": 9331,
|
|
665
|
+
"afterBytes": 4258
|
|
651
666
|
},
|
|
652
667
|
{
|
|
653
668
|
"file": "src/room/public-attachment-cache.js",
|
|
@@ -659,10 +674,20 @@
|
|
|
659
674
|
"beforeBytes": 5858,
|
|
660
675
|
"afterBytes": 3219
|
|
661
676
|
},
|
|
677
|
+
{
|
|
678
|
+
"file": "src/room/registration-authority.js",
|
|
679
|
+
"beforeBytes": 1006,
|
|
680
|
+
"afterBytes": 462
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
"file": "src/room/room-action-client-types.js",
|
|
684
|
+
"beforeBytes": 329,
|
|
685
|
+
"afterBytes": 132
|
|
686
|
+
},
|
|
662
687
|
{
|
|
663
688
|
"file": "src/room/room-action-client.js",
|
|
664
|
-
"beforeBytes":
|
|
665
|
-
"afterBytes":
|
|
689
|
+
"beforeBytes": 29009,
|
|
690
|
+
"afterBytes": 14697
|
|
666
691
|
},
|
|
667
692
|
{
|
|
668
693
|
"file": "src/room/room-binding-client.js",
|
|
@@ -671,8 +696,8 @@
|
|
|
671
696
|
},
|
|
672
697
|
{
|
|
673
698
|
"file": "src/room/session-registry.js",
|
|
674
|
-
"beforeBytes":
|
|
675
|
-
"afterBytes":
|
|
699
|
+
"beforeBytes": 30575,
|
|
700
|
+
"afterBytes": 17164
|
|
676
701
|
},
|
|
677
702
|
{
|
|
678
703
|
"file": "src/security/managed-agent-credential-paths.js",
|
|
@@ -716,9 +741,14 @@
|
|
|
716
741
|
},
|
|
717
742
|
{
|
|
718
743
|
"file": "src/session/deletion-sync-state.js",
|
|
719
|
-
"beforeBytes":
|
|
744
|
+
"beforeBytes": 6026,
|
|
720
745
|
"afterBytes": 3190
|
|
721
746
|
},
|
|
747
|
+
{
|
|
748
|
+
"file": "src/session/deletion-sync-validation.js",
|
|
749
|
+
"beforeBytes": 1590,
|
|
750
|
+
"afterBytes": 919
|
|
751
|
+
},
|
|
722
752
|
{
|
|
723
753
|
"file": "src/session/handlers/agent-capabilities.js",
|
|
724
754
|
"beforeBytes": 767,
|
|
@@ -729,20 +759,45 @@
|
|
|
729
759
|
"beforeBytes": 5590,
|
|
730
760
|
"afterBytes": 2803
|
|
731
761
|
},
|
|
762
|
+
{
|
|
763
|
+
"file": "src/session/handlers/agent-control.js",
|
|
764
|
+
"beforeBytes": 6699,
|
|
765
|
+
"afterBytes": 3876
|
|
766
|
+
},
|
|
732
767
|
{
|
|
733
768
|
"file": "src/session/handlers/agent-workspace-validation.js",
|
|
734
|
-
"beforeBytes":
|
|
735
|
-
"afterBytes":
|
|
769
|
+
"beforeBytes": 9051,
|
|
770
|
+
"afterBytes": 4712
|
|
736
771
|
},
|
|
737
772
|
{
|
|
738
773
|
"file": "src/session/handlers/agents.js",
|
|
739
774
|
"beforeBytes": 2274,
|
|
740
775
|
"afterBytes": 1134
|
|
741
776
|
},
|
|
777
|
+
{
|
|
778
|
+
"file": "src/session/handlers/chat-adapter-config.js",
|
|
779
|
+
"beforeBytes": 2814,
|
|
780
|
+
"afterBytes": 1159
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
"file": "src/session/handlers/chat-events.js",
|
|
784
|
+
"beforeBytes": 15468,
|
|
785
|
+
"afterBytes": 6683
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
"file": "src/session/handlers/chat-recovery.js",
|
|
789
|
+
"beforeBytes": 6002,
|
|
790
|
+
"afterBytes": 3291
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
"file": "src/session/handlers/chat-session-lifecycle.js",
|
|
794
|
+
"beforeBytes": 3728,
|
|
795
|
+
"afterBytes": 1723
|
|
796
|
+
},
|
|
742
797
|
{
|
|
743
798
|
"file": "src/session/handlers/chat.js",
|
|
744
|
-
"beforeBytes":
|
|
745
|
-
"afterBytes":
|
|
799
|
+
"beforeBytes": 32547,
|
|
800
|
+
"afterBytes": 13978
|
|
746
801
|
},
|
|
747
802
|
{
|
|
748
803
|
"file": "src/session/handlers/control.js",
|
|
@@ -776,8 +831,8 @@
|
|
|
776
831
|
},
|
|
777
832
|
{
|
|
778
833
|
"file": "src/session/handlers/room-managed.js",
|
|
779
|
-
"beforeBytes":
|
|
780
|
-
"afterBytes":
|
|
834
|
+
"beforeBytes": 4928,
|
|
835
|
+
"afterBytes": 2628
|
|
781
836
|
},
|
|
782
837
|
{
|
|
783
838
|
"file": "src/session/handlers/session-refresh.js",
|
|
@@ -811,8 +866,8 @@
|
|
|
811
866
|
},
|
|
812
867
|
{
|
|
813
868
|
"file": "src/session/manager.js",
|
|
814
|
-
"beforeBytes":
|
|
815
|
-
"afterBytes":
|
|
869
|
+
"beforeBytes": 41802,
|
|
870
|
+
"afterBytes": 21965
|
|
816
871
|
},
|
|
817
872
|
{
|
|
818
873
|
"file": "src/session/native-cleanup-outbox.js",
|
|
@@ -834,10 +889,30 @@
|
|
|
834
889
|
"beforeBytes": 1991,
|
|
835
890
|
"afterBytes": 966
|
|
836
891
|
},
|
|
892
|
+
{
|
|
893
|
+
"file": "src/session/queue-helpers.js",
|
|
894
|
+
"beforeBytes": 7270,
|
|
895
|
+
"afterBytes": 3812
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
"file": "src/session/queue-retry.js",
|
|
899
|
+
"beforeBytes": 1253,
|
|
900
|
+
"afterBytes": 561
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
"file": "src/session/queue-storage.js",
|
|
904
|
+
"beforeBytes": 1663,
|
|
905
|
+
"afterBytes": 909
|
|
906
|
+
},
|
|
837
907
|
{
|
|
838
908
|
"file": "src/session/queue.js",
|
|
839
|
-
"beforeBytes":
|
|
840
|
-
"afterBytes":
|
|
909
|
+
"beforeBytes": 40646,
|
|
910
|
+
"afterBytes": 18459
|
|
911
|
+
},
|
|
912
|
+
{
|
|
913
|
+
"file": "src/session/queued-chat-dispatch.js",
|
|
914
|
+
"beforeBytes": 2356,
|
|
915
|
+
"afterBytes": 1264
|
|
841
916
|
},
|
|
842
917
|
{
|
|
843
918
|
"file": "src/session/run-recovery/barrier.js",
|
|
@@ -856,8 +931,8 @@
|
|
|
856
931
|
},
|
|
857
932
|
{
|
|
858
933
|
"file": "src/session/run-recovery/schema.js",
|
|
859
|
-
"beforeBytes":
|
|
860
|
-
"afterBytes":
|
|
934
|
+
"beforeBytes": 6647,
|
|
935
|
+
"afterBytes": 4272
|
|
861
936
|
},
|
|
862
937
|
{
|
|
863
938
|
"file": "src/session/store.js",
|
|
@@ -869,6 +944,11 @@
|
|
|
869
944
|
"beforeBytes": 2886,
|
|
870
945
|
"afterBytes": 1429
|
|
871
946
|
},
|
|
947
|
+
{
|
|
948
|
+
"file": "src/session/turn-trigger.js",
|
|
949
|
+
"beforeBytes": 106,
|
|
950
|
+
"afterBytes": 1
|
|
951
|
+
},
|
|
872
952
|
{
|
|
873
953
|
"file": "src/session/types.js",
|
|
874
954
|
"beforeBytes": 159,
|
|
@@ -52,6 +52,11 @@ export type AgentSendContext = {
|
|
|
52
52
|
/** Marks internal recovery input; it must never be persisted as user-authored text. */
|
|
53
53
|
recovery?: 'upgrade';
|
|
54
54
|
};
|
|
55
|
+
export type AgentActiveInput = {
|
|
56
|
+
text: string;
|
|
57
|
+
attachments?: ChatAttachmentMeta[];
|
|
58
|
+
clientMessageId?: string;
|
|
59
|
+
};
|
|
55
60
|
export type ImportedAgentMessage = {
|
|
56
61
|
/** Stable within repeated imports of the same provider session. */
|
|
57
62
|
sourceId: string;
|
|
@@ -122,6 +127,9 @@ export declare abstract class AgentAdapter extends EventEmitter<AgentAdapterEven
|
|
|
122
127
|
abstract readonly type: AgentType;
|
|
123
128
|
/** Explicit fail-closed default; resumable adapters must opt in. */
|
|
124
129
|
get recoveryCapabilities(): AgentRecoveryCapabilities;
|
|
130
|
+
/** Explicit fail-closed capability for adding input to the current provider turn. */
|
|
131
|
+
get supportsActiveInput(): boolean;
|
|
132
|
+
injectActiveInput?(input: AgentActiveInput): Promise<void>;
|
|
125
133
|
configure?(options: {
|
|
126
134
|
sessionId?: string;
|
|
127
135
|
externalChannel?: ExternalChannelSessionStatus | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EventEmitter as o}from"node:events";import{RECOVERY_CONTINUE_TEXT as u}from"../session/run-recovery/schema.js";class l extends o{get recoveryCapabilities(){return{inspectTerminal:!1,reattachRun:!1,resumeRun:!1,resumeSession:!1}}async inspectInterruptedRun(e){if(!this.getStatus)return{state:"interrupted",providerRunId:e.providerRunId};const r=await this.getStatus().catch(()=>null);return r?.active?{state:"active",providerRunId:r.runId??e.providerRunId,runPhase:r.runPhase}:{state:"interrupted",providerRunId:e.providerRunId}}async recoverInterruptedRun(e){const r=await this.inspectInterruptedRun(e);if(r.state==="terminal"&&this.recoveryCapabilities.inspectTerminal)return{result:"terminal_reconciled"};if(r.state==="active"&&this.recoveryCapabilities.reattachRun)return{result:"reattached"};if(!e.agentSessionId)return{result:"interrupted_by_upgrade",reason:"missing_agent_session"};if(!this.recoveryCapabilities.resumeSession)return{result:"interrupted_by_upgrade",reason:"resume_unsupported"};if(e.continueDispatchState!=="none")return{result:"recovery_failed",reason:"continue_dispatch_outcome_unknown"};try{return e.beforeContinueDispatch?.(),await this.send(u,e.modelId??void 0,e.reasoningEffort??void 0,void 0,e.systemPrompt,e.sendContext),{result:"continued"}}catch(i){const a=i instanceof Error?i.message:String(i),n=a.toLowerCase();return{result:"recovery_failed",reason:n.includes("auth")||n.includes("login")?"authentication_required":n.includes("permission")||n.includes("capability")?"permission_context_unavailable":n.includes("session")&&n.includes("not")?"provider_session_missing":"provider_error",message:a.slice(0,500)}}}}const s=new Map;function p(t,e){s.set(t,e)}function f(t){s.delete(t)}function g(t){const e=s.get(t);return e?e():null}function m(){return[...s.keys()]}export{l as AgentAdapter,g as createAgent,m as getRegisteredAgents,p as registerAgent,f as unregisterAgent};
|
|
1
|
+
import{EventEmitter as o}from"node:events";import{RECOVERY_CONTINUE_TEXT as u}from"../session/run-recovery/schema.js";class l extends o{get recoveryCapabilities(){return{inspectTerminal:!1,reattachRun:!1,resumeRun:!1,resumeSession:!1}}get supportsActiveInput(){return!1}async inspectInterruptedRun(e){if(!this.getStatus)return{state:"interrupted",providerRunId:e.providerRunId};const r=await this.getStatus().catch(()=>null);return r?.active?{state:"active",providerRunId:r.runId??e.providerRunId,runPhase:r.runPhase}:{state:"interrupted",providerRunId:e.providerRunId}}async recoverInterruptedRun(e){const r=await this.inspectInterruptedRun(e);if(r.state==="terminal"&&this.recoveryCapabilities.inspectTerminal)return{result:"terminal_reconciled"};if(r.state==="active"&&this.recoveryCapabilities.reattachRun)return{result:"reattached"};if(!e.agentSessionId)return{result:"interrupted_by_upgrade",reason:"missing_agent_session"};if(!this.recoveryCapabilities.resumeSession)return{result:"interrupted_by_upgrade",reason:"resume_unsupported"};if(e.continueDispatchState!=="none")return{result:"recovery_failed",reason:"continue_dispatch_outcome_unknown"};try{return e.beforeContinueDispatch?.(),await this.send(u,e.modelId??void 0,e.reasoningEffort??void 0,void 0,e.systemPrompt,e.sendContext),{result:"continued"}}catch(i){const a=i instanceof Error?i.message:String(i),n=a.toLowerCase();return{result:"recovery_failed",reason:n.includes("auth")||n.includes("login")?"authentication_required":n.includes("permission")||n.includes("capability")?"permission_context_unavailable":n.includes("session")&&n.includes("not")?"provider_session_missing":"provider_error",message:a.slice(0,500)}}}}const s=new Map;function p(t,e){s.set(t,e)}function f(t){s.delete(t)}function g(t){const e=s.get(t);return e?e():null}function m(){return[...s.keys()]}export{l as AgentAdapter,g as createAgent,m as getRegisteredAgents,p as registerAgent,f as unregisterAgent};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AgentAdapter, type AgentSendContext, type AgentSendResult, type AgentStartOptions } from './adapter.js';
|
|
1
|
+
import { AgentAdapter, type AgentActiveInput, type AgentSendContext, type AgentSendResult, type AgentStartOptions } from './adapter.js';
|
|
2
2
|
import { type ChatAttachmentMeta, type ExternalChannelSessionStatus } from '@shennian/wire';
|
|
3
3
|
import type { SessionRunPhase } from '@shennian/wire';
|
|
4
4
|
import { type CompiledManagedAgentPolicy } from '../security/managed-agent-policy.js';
|
|
@@ -19,6 +19,8 @@ export declare function buildCodexQueuedText(text: string, attachments?: ChatAtt
|
|
|
19
19
|
export declare function buildCodexQueueArgs(threadId: string, text: string, attachments?: ChatAttachmentMeta[]): string[];
|
|
20
20
|
export declare class CodexAdapter extends AgentAdapter {
|
|
21
21
|
private readonly options;
|
|
22
|
+
get supportsActiveInput(): boolean;
|
|
23
|
+
injectActiveInput(input: AgentActiveInput): Promise<void>;
|
|
22
24
|
readonly type: "codex";
|
|
23
25
|
get recoveryCapabilities(): {
|
|
24
26
|
inspectTerminal: boolean;
|
package/dist/src/agents/codex.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import{spawnSync as
|
|
2
|
-
`)}function ge(o,e){const t=e?.filter(s=>s.path&&!/^https?:\/\//i.test(s.path)&&!o.includes(s.path));if(!t?.length)return o;const r=t.map((s,i)=>{const n=
|
|
3
|
-
`)}function fe(o,e,t){return["queue","--thread",o,"--message",ge(e,t)]}function
|
|
4
|
-
${l}`.trim();if(u!==0){m(new Error(f||`codex queue exited with code ${u??"unknown"}`));return}const b=f.match(/Queued message\s+([^\s]+)\s+for thread/i)?.[1];m(void 0,b)})})}async resume(e){await this.killProcess(),this.agentSessionId=e,this.resetTextState()}async setTitle(e,t,r){const s=e.trim(),i=t.replace(/\s+/g," ").trim();!s||!i||(this.agentSessionId=s,r?.trim()&&(this.workDir=r),await this.ensureAppServer(),await this.sendRpc("thread/name/set",{threadId:s,name:i}))}async stop(){this.managedRoomTools.deactivateTurn(),await this.interruptActiveTurn().catch(()=>{}),await this.killProcess()}async getStatus(){const e=this.agentSessionId,t=this.activeTurnId;if(!e||!this.process)return{active:!1,runId:t,runPhase:null,canStop:!1};let r=null;try{r=(await this.sendRpc("thread/read",{threadId:e,includeTurns:!1},5e3)).thread?.status??null}catch{}const s=r?.type==="active"||!!t;return{active:s,runId:t,runPhase:s?this.mapThreadStatusToRunPhase(r):null,canStop:!!(s&&t&&this.process)}}spawnCodex(e){const t=T("codex");if(!t){this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?'));return}const r=x(t,e,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:this.buildProcessEnv()});this.process=r,S({input:r.stdout}).on("line",n=>{if(n.trim())try{const a=JSON.parse(n);this.handleStreamEvent(a)}catch{this.emitEvent({state:"delta",text:n})}});let i="";r.stderr?.on("data",n=>{i+=n.toString()}),r.on("close",n=>{this.process===r&&(this.process=null,this.clearForceCloseTimer(),this.handleProcessClose(n,i))}),r.on("error",n=>{this.process===r&&(this.process=null,n.code==="ENOENT"?this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?')):this.emit("error",n))})}spawnAppServer(){const e=T("codex");if(!e){this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?'));return}const t=["app-server","--listen","stdio://"],r=this.options.modelInstructionsFile??U(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,this.agentSystemPrompt);r&&t.push("-c",`model_instructions_file=${JSON.stringify(r)}`);const s=x(e,t,{cwd:this.workDir??void 0,stdio:["pipe","pipe","pipe"],env:this.buildProcessEnv({NO_COLOR:"1"})});this.process=s,this.stderrBuf="",this.appServerStartupError=null,S({input:s.stdout}).on("line",n=>{if(!n.trim())return;let a;try{a=JSON.parse(n)}catch{this.handleAppServerNonJsonStdout(n);return}this.handleAppServerMessage(a)}),s.stderr?.on("data",n=>{this.stderrBuf+=n.toString()}),s.on("close",n=>{if(this.process!==s)return;const a=this.activeTurnId!=null;this.process=null,this.appServerReady=null,this.activeTurnId=null,this.managedRoomTools.reset(),this.clearConfiguredManagedRoomContext(),this.rejectAllPending(new Error(k(this.stderrBuf)||`codex app-server exited with code ${n}`)),this.terminalState==="open"&&a&&this.handleProcessClose(n,this.stderrBuf)}),s.on("error",n=>{this.process===s&&(this.process=null,this.managedRoomTools.reset(),this.clearConfiguredManagedRoomContext(),this.rejectAllPending(n),n.code==="ENOENT"?this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?')):this.emit("error",n))})}async ensureAppServer(e){return this.appServerReady?this.appServerReady:(this.spawnAppServer(),this.appServerReady=this.initializeAppServer(e).catch(async t=>{throw this.appServerReady=null,await this.killProcess(),t}),this.appServerReady)}async initializeAppServer(e){const t=I(e);await this.sendRpc("initialize",{clientInfo:K,capabilities:{experimentalApi:!0}}),this.managedPermissionConfig=this.managedAgentPolicy&&!R(this.managedAgentPolicy)?await this.buildManagedPermissionConfig():null;const r=!!(this.configuredManagedRoomContextToken||this.configuredManagedRoomExecutor);if(this.managedAgentPolicy&&r&&!this.managedRoomTools.isConfigured()&&(this.managedRoomTools.configure(this.configuredManagedRoomContextToken,this.configuredManagedRoomExecutor),!this.managedRoomTools.isConfigured()))throw new Error("codex_managed_room_tool_context_unavailable");if(this.agentSessionId&&this.managedAgentPolicy&&r&&this.agentSessionId!==this.managedRoomToolThreadId){if(!this.managedRoomTools.isConfigured())throw new Error("codex_managed_room_tool_context_unavailable");this.agentSessionId=null}if(this.agentSessionId){const c={threadId:this.agentSessionId,cwd:this.workDir,approvalPolicy:"never",...this.managedPermissionConfig?{config:this.managedPermissionConfig.threadConfig}:{sandbox:"danger-full-access"},persistExtendedHistory:!0,...t?{model:t}:{}};let l;try{l=await this.sendRpc("thread/resume",{...c,excludeTurns:!0})}catch(p){if(!de(p))throw p;l=await this.sendRpc("thread/resume",c)}this.agentSessionId=l.thread?.id??this.agentSessionId,this.managedPermissionConfig&&E(l,this.managedPermissionConfig.profileId),this.managedAgentPolicy&&r&&(this.managedRoomTools.bindThread(this.agentSessionId),this.managedRoomToolThreadId=this.agentSessionId);return}const s=this.options.hidden||this.nativeSessionVisibility==="internal"||!this.persistNativeSession,i=s?void 0:await this.resolveCodexProjectId(),n={cwd:this.workDir,approvalPolicy:"never",...this.managedPermissionConfig?{config:this.managedPermissionConfig.threadConfig}:{sandbox:"danger-full-access"},serviceName:"Shennian",...s?{}:{threadSource:"user"},experimentalRawEvents:!1,persistExtendedHistory:!0,...this.managedAgentPolicy&&r?{dynamicTools:G}:{},...i?{projectId:i}:{},...t?{model:t}:{}};let a;if(s&&!this.managedPermissionConfig)a=await this.sendRpc("thread/start",n);else try{a=await this.sendRpc("thread/start",{...n,historyMode:"paginated"})}catch(c){throw ae(c)?new Error("\u5F53\u524D Codex CLI \u4E0D\u652F\u6301\u521B\u5EFA\u53EF\u5728 Codex Desktop \u4E2D\u7EE7\u7EED\u7684\u65B0\u4F1A\u8BDD\uFF0C\u8BF7\u624B\u52A8\u5347\u7EA7 Codex CLI \u540E\u91CD\u8BD5\u3002\u795E\u5FF5\u4E0D\u4F1A\u81EA\u52A8\u5347\u7EA7\uFF0C\u4E5F\u4E0D\u4F1A\u964D\u7EA7\u521B\u5EFA\u4E0D\u53EF\u89C1\u7684 legacy \u4F1A\u8BDD\u3002",{cause:c}):c}const d=a.thread?.id;if(!d)throw new Error("codex app-server thread/start returned no thread id");this.managedPermissionConfig&&E(a,this.managedPermissionConfig.profileId),this.managedAgentPolicy&&r&&(this.managedRoomTools.bindThread(d),this.managedRoomToolThreadId=d),this.agentSessionId=d}async buildManagedPermissionConfig(){const e=this.managedAgentPolicy;if(!e)throw new Error("managed_agent_policy_missing");const t=e.adapterPolicy.externalCapabilities.mcp?[]:X(await this.sendRpc("config/read",{cwd:e.adapterPolicy.workDir}));return H(z(e),e.adapterPolicy.workDir,{configuredMcpServerNames:t,shellSubprocessPolicy:e.environmentPolicy.shellSubprocess})}async resolveCodexProjectId(){const e=this.workDir?.trim();if(e)try{const t=[];let r;do{const c=await this.sendRpc("project/list",{limit:100,...r?{cursor:r}:{}});t.push(...c.data??[]),r=c.nextCursor}while(r);const s=ce(t,e);if(s)return s;const i=g.resolve(e),n=`shennian-project-${w("sha256").update(i).digest("hex")}`,d=(await this.sendRpc("project/create",{idempotencyKey:n,name:g.basename(i)||i,roots:[{path:i}],metadata:{createdBy:"Shennian"}})).project?.id;if(!d)throw new Error("codex app-server project/create returned no project id");return d}catch(t){throw le(t)?new Error("\u5F53\u524D Codex CLI \u4E0D\u652F\u6301\u521B\u5EFA\u53EF\u5F52\u5C5E\u5230 Codex Desktop \u9879\u76EE\u7684\u65B0\u4F1A\u8BDD\uFF0C\u8BF7\u624B\u52A8\u5347\u7EA7 Codex CLI \u540E\u91CD\u8BD5\u3002\u795E\u5FF5\u4E0D\u4F1A\u81EA\u52A8\u5347\u7EA7\uFF0C\u4E5F\u4E0D\u4F1A\u76F4\u63A5\u4FEE\u6539 Codex Desktop \u7684\u79C1\u6709\u4FA7\u680F\u7D22\u5F15\u3002",{cause:t}):t}}async startTurnWithRecovery(e,t,r,s,i){try{return await this.startTurn(e,t,r,s,i)}catch(n){if(!v(n))throw n;if(this.managedAgentPolicy||this.managedPermissionConfig){this.logManagedThreadLifecycle("rollout.missing",{threadId:e,recovery:"recreate"}),await this.killProcess(!0),this.agentSessionId=null,this.managedRoomToolThreadId=null,await this.ensureAppServer(r);const a=this.agentSessionId;if(!a)throw new Error("codex app-server did not recreate the managed thread",{cause:n});return this.logManagedThreadLifecycle("thread.recreated",{previousThreadId:e,threadId:a}),this.emitEvent({state:"start",agentSessionId:a}),await this.startFreshManagedTurnWithReadinessRetry(a,t,r,s,i)}return await this.killProcess(),await this.ensureAppServer(r),await this.startTurn(e,t,r,s,i)}}async startFreshManagedTurnWithReadinessRetry(e,t,r,s,i){const n=[0,100,300,1e3];let a;for(let d=0;d<n.length;d+=1){const c=n[d];c>0&&await new Promise(l=>setTimeout(l,c));try{const l=await this.startTurn(e,t,r,s,i);return d>0&&this.logManagedThreadLifecycle("rollout.ready",{threadId:e,attempt:d+1}),l}catch(l){if(a=l,!v(l)||d===n.length-1)throw l;this.logManagedThreadLifecycle("rollout.retry",{threadId:e,attempt:d+2,delayMs:n[d+1]})}}throw a}logManagedThreadLifecycle(e,t){console.error(`[codex.managed] ${JSON.stringify({event:e,...t})}`)}async startTurn(e,t,r,s,i){try{return await this.sendRpc("turn/start",{threadId:e,input:[ue(t,i)],approvalPolicy:"never",...this.managedPermissionConfig?{}:{sandboxPolicy:{type:"dangerFullAccess"}},...r?{model:r}:{},...s?{effort:s}:{}})}catch(n){throw s&&ee(n)?new Error(`Codex app-server does not accept reasoning effort "${s}" for this turn. Refresh models or upgrade Codex CLI, then retry.`,{cause:n}):n}}async interruptActiveTurn(){const e=this.agentSessionId,t=this.activeTurnId;this.activeTurnId=null,this.managedRoomTools.deactivateTurn(),!(!e||!t||!this.process)&&await this.sendRpc("turn/interrupt",{threadId:e,turnId:t},5e3)}sendRpc(e,t,r=6e4){if(this.appServerStartupError)return Promise.reject(this.appServerStartupError);const s=this.process;if(!s?.stdin)return Promise.reject(new Error("codex app-server is not running"));const i=this.rpcSeq++,n=JSON.stringify({id:i,method:e,params:t});return new Promise((a,d)=>{const c=setTimeout(()=>{this.pendingRequests.delete(i),d(new Error(`codex app-server request timed out: ${e}`))},r);this.pendingRequests.set(i,{resolve:a,reject:d,timer:c}),s.stdin.write(`${n}
|
|
5
|
-
`,l=>{l&&(clearTimeout(c),this.pendingRequests.delete(i),d(l))})})}handleAppServerMessage(e){if(e.method==="item/tool/call"&&e.id!=null){this.handleManagedRoomToolCall(e.id,e.params??{});return}if(e.id!=null){const r=typeof e.id=="number"?this.pendingRequests.get(e.id):void 0;r&&(clearTimeout(r.timer),this.pendingRequests.delete(e.id),e.error?r.reject(new Error(e.error.message||`codex app-server error ${e.error.code??""}`.trim())):r.resolve(e.result))}if(!e.method)return;const t=e.params??{};switch(e.method){case"turn/started":{const r=typeof t.turn=="object"&&t.turn!==null?t.turn:null,s=typeof r?.id=="string"?r.id:null,i=typeof t.threadId=="string"?t.threadId:"";s&&(this.activeTurnId=s,this.managedRoomToolThreadId===i&&!this.managedRoomTools.bindTurn(i,s)&&this.emitErrorIfOpen("codex_managed_room_turn_binding_failed"));break}case"thread/status/changed":{const r=typeof t.threadId=="string"?t.threadId:"";if(r&&this.agentSessionId&&r!==this.agentSessionId)break;const s=typeof t.status=="object"&&t.status!==null?t.status:null;s?.type==="active"&&this.emitEvent({state:"heartbeat",runPhase:this.mapThreadStatusToRunPhase(s)});break}case"item/agentMessage/delta":{const r=typeof t.itemId=="string"?t.itemId:"";r&&this.deltaItemIds.add(r),typeof t.delta=="string"&&this.emitText(t.delta);break}case"item/completed":this.handleAppServerCompletedItem(t);break;case"thread/tokenUsage/updated":this.handleAppServerUsage(t);break;case"turn/completed":{const r=typeof t.turn=="object"&&t.turn!==null?t.turn:null,s=typeof r?.id=="string"?r.id:null;(!this.activeTurnId||s===this.activeTurnId)&&(this.activeTurnId=null,this.managedRoomTools.deactivateTurn(),this.emitFinalIfOpen());break}case"turn/failed":{const r=_(t);if(this.scheduleManagedAsyncRolloutRecovery(r))return;this.emitErrorIfOpen(r||"turn failed");break}case"error":{const r=_(t);if(
|
|
6
|
-
`)}mapThreadStatusToRunPhase(e){const t=e?.type==="active"&&Array.isArray(e.activeFlags)?e.activeFlags:[];return t.includes("waitingOnApproval")?"waiting_approval":t.includes("waitingOnUserInput")?"waiting_user_input":"thinking"}handleAppServerNonJsonStdout(e){const t=
|
|
7
|
-
(exit ${t.exitCode})`:""].join("").trim()});break}case"mcpToolCall":case"dynamicToolCall":{const r=typeof t.tool=="string"?t.tool:t.type;if(y(r))return;const s=typeof t.arguments=="object"&&t.arguments!==null?t.arguments:{};this.emitEvent({state:"tool-call",name:r,args:s}),this.emitEvent({state:"tool-result",name:r,result:A(t.error??t.result??t.contentItems??"")});break}case"fileChange":break;case"approvalRequest":case"approval_request":case"permissionRequest":case"permission_request":case"userInputRequired":case"user_input_required":{this.emitApprovalPending(t);break}}}handleAppServerUsage(e){const t=typeof e.tokenUsage=="object"&&e.tokenUsage!==null?e.tokenUsage:null,r=typeof t?.last=="object"&&t.last!==null?t.last:null,s=typeof t?.total=="object"&&t.total!==null?t.total:null,i=r??s;if(!i)return;const n=typeof i.inputTokens=="number"?i.inputTokens:void 0,a=typeof i.outputTokens=="number"?i.outputTokens:void 0;(n!=null||a!=null)&&(this.pendingUsage={inputTokens:n??0,outputTokens:a??0})}handleCodexItemLine(e){const t=e.item;if(t?.type&&!
|
|
1
|
+
import{spawnSync as q}from"node:child_process";import{createInterface as w}from"node:readline";import{createHash as S,randomUUID as N}from"node:crypto";import g from"node:path";import{AgentAdapter as D,registerAgent as L}from"./adapter.js";import{resolveBuiltinCommand as T,spawnAgentCommand as x}from"./command-spec.js";import{buildAgentProcessEnv as F,buildManagedAgentProcessEnv as $,buildManagedNativeFullProcessEnv as U}from"../agent-env.js";import{ensurePlatformInstructionsFile as W}from"./platform-instructions.js";import{CODEX_DESKTOP_SEND_UNAVAILABLE as C}from"@shennian/wire";import{isCodexThreadTailInterrupted as z}from"../native-fusion/codex-files.js";import{resolveManagedAgentAdapterEnforcement as B,isManagedAgentNativeFull as R}from"../security/managed-agent-policy.js";import{registerManagedAgentRuntimeSecurity as G}from"../security/managed-agent-runtime.js";import{CODEX_MANAGED_ROOM_DYNAMIC_TOOLS as J,CodexManagedRoomToolBinding as V}from"./codex-managed-room-tools.js";import{assertCodexManagedPermissionProfile as E,CODEX_MANAGED_RUNTIME_SECURITY as H,compileCodexManagedPermissions as X,extractCodexMcpServerNames as K}from"./codex-managed-permissions.js";import{CODEX_APP_SERVER_CLIENT_INFO as Q,extractAppServerErrorMessage as _,formatCodexErrorMessage as j,formatTransientCodexStatus as Y,isCodexCollabAgentItem as Z,isCodexCollabAgentToolName as y,isCodexLegacyCollabAgentItem as ee,isCodexUnsupportedEffortError as te,isMissingCodexRolloutError as v,isTransientCodexErrorMessage as re,looksLikeCodexInteractiveAuthPrompt as se,looksLikeFatalCodexStderr as ne,normalizeCodexModelId as I,normalizeCodexReasoningEffort as ie,normalizeCodexStderr as k,normalizeTerminalText as oe,safeStringify as A,stripGitDirectiveArtifacts as ae}from"./codex-utils.js";import{isCodexUnsupportedEffortError as Ne,isMissingCodexRolloutError as De,normalizeCodexModelId as Le,normalizeCodexReasoningEffort as Fe}from"./codex-utils.js";G("codex",H);function P(o){const e=o instanceof Error?o.message:String(o);return/already has an active writer|thread-store conflict/i.test(e)}function de(o){const e=o instanceof Error?o.message:String(o);return/paginated(?:_threads|\s+(?:thread\s+)?history)?.*(?:not supported|unsupported|unavailable)/i.test(e)||/(?:not supported|unsupported|unavailable).*paginated(?:_threads|\s+(?:thread\s+)?history)?/i.test(e)}function le(o){const e=o instanceof Error?o.message:String(o);return/unknown field [`'"]?excludeTurns/i.test(e)||/excludeTurns.*(?:not supported|unsupported|unavailable)/i.test(e)}function ce(o){const e=o instanceof Error?o.message:String(o);return/(?:method not found|unknown method).*(?:project\/list|project\/create)/i.test(e)||/(?:project\/list|project\/create).*(?:not supported|unsupported|unavailable)/i.test(e)}function ue(o,e){const t=g.resolve(e);let r;for(const s of o)if(s.id)for(const i of s.roots??[]){if(!i.path)continue;const n=g.resolve(i.path),a=g.relative(n,t);!(a===""||!a.startsWith("..")&&!g.isAbsolute(a))||n.length<=(r?.rootLength??-1)||(r={id:s.id,rootLength:n.length})}return r?.id}function M(o,e){const t=e?.flatMap(s=>he(s)).filter(s=>!/^https?:\/\//i.test(s.path)).filter(s=>s.path);return{type:"text",text:me(o,e),text_elements:[],...t?.length?{local_images:t}:{}}}function he(o){if(o.kind==="image")return o.previewData?[{path:o.path,data:o.previewData,mimeType:o.mimeType}]:[{path:o.path}];if(o.mimeType.startsWith("video/")){const e=pe(o.path);return e?[{path:e}]:[]}return[]}function pe(o){if(!o||/^https?:\/\//i.test(o))return null;const e=g.extname(o),r=`${e?o.slice(0,-e.length):o}.preview.png`;return q("ffmpeg",["-y","-ss","0","-i",o,"-frames:v","1","-vf","scale=320:-1",r],{stdio:"ignore",timeout:15e3}).status===0?r:null}function me(o,e){const t=e?.filter(i=>i.kind!=="image").filter(i=>i.path&&!/^https?:\/\//i.test(i.path));if(!t?.length||t.every(i=>o.includes(i.path)))return o;const s=t.map((i,n)=>{const a=i.name||`attachment-${n+1}`,d=i.mimeType?` (${i.mimeType})`:"";return`[${b(a)}${d}](<${i.path}>)`});return[o,"",...s].join(`
|
|
2
|
+
`)}function ge(o,e){const t=e?.filter(s=>s.path&&!/^https?:\/\//i.test(s.path)&&!o.includes(s.path));if(!t?.length)return o;const r=t.map((s,i)=>{const n=b(s.name||`attachment-${i+1}`);return s.kind==="image"?``:`[${n}](<${s.path}>)`});return[o,"",...r].join(`
|
|
3
|
+
`)}function fe(o,e,t){return["queue","--thread",o,"--message",ge(e,t)]}function b(o){return o.replace(/[[\]\\]/g,"\\$&")}class ye extends D{options;get supportsActiveInput(){return!0}async injectActiveInput(e){const t=this.agentSessionId,r=this.activeTurnId;if(!t||!r||!this.process)throw new Error("codex_active_turn_unavailable");const s=await this.sendRpc("turn/steer",{threadId:t,expectedTurnId:r,input:[M(e.text,e.attachments)],...e.clientMessageId?{clientUserMessageId:e.clientMessageId}:{}});if(s.turnId&&s.turnId!==r)throw new Error("codex_active_turn_changed")}type="codex";get recoveryCapabilities(){return{inspectTerminal:!1,reattachRun:!1,resumeRun:!1,resumeSession:!0}}process=null;workDir=null;seq=0;runId="";pendingUsage;agentSessionId=null;hasEmittedText=!1;textTail="";terminalState="open";forceCloseTimer=null;stderrBuf="";rpcSeq=1;pendingRequests=new Map;appServerReady=null;appServerStartupError=null;activeTurnId=null;deltaItemIds=new Set;lastTransientStatus="";agentSystemPrompt="";managedAgentPolicy=null;managedPermissionConfig=null;configurationRestartRequired=!1;managedRoomTools=new V;configuredManagedRoomContextToken=null;configuredManagedRoomExecutor=null;managedRoomToolThreadId=null;preparedExternalOwnerThreadId=null;managedTurnReplay=null;managedAsyncRecovery=null;persistNativeSession=!0;nativeSessionVisibility="user";constructor(e={}){super(),this.options=e}externalChannel=null;shennianSessionId=null;extraEnv={};configure(e){const t=this.configurationFingerprint();this.shennianSessionId=e.sessionId??null,this.externalChannel=e.externalChannel??null,this.extraEnv=e.env??{},"managedAgentPolicy"in e&&(this.managedAgentPolicy=e.managedAgentPolicy??null),("managedRoomContextToken"in e||"managedRoomExecutor"in e)&&(this.managedRoomTools.deactivateTurn(),this.configuredManagedRoomContextToken=e.managedRoomContextToken?.trim()||null,this.configuredManagedRoomExecutor=e.managedRoomExecutor??null),this.managedAgentPolicy&&(this.workDir=this.managedAgentPolicy.adapterPolicy.workDir);const r=this.configurationFingerprint();t!==r&&this.process&&(this.configurationRestartRequired=!0)}configurationFingerprint(){const e=Object.keys(this.extraEnv).sort().map(t=>[t,this.extraEnv[t]??null]);return S("sha256").update(JSON.stringify({sessionId:this.shennianSessionId,externalChannel:this.externalChannel,env:e,managedAgentPolicy:this.managedAgentPolicy})).digest("hex")}buildProcessEnv(e={}){if(!this.managedAgentPolicy)return F({...e,...this.extraEnv});if(R(this.managedAgentPolicy))return U({...e,...this.extraEnv});const t=Object.fromEntries(Object.entries(this.extraEnv).filter(([r])=>r!=="SHENNIAN_MANAGED_ROOM_CONTEXT"&&r!=="SHENNIAN_MANAGED_ROOM_IPC_ROOT"));return $({agentType:"codex",providerEnv:t,sessionEnv:t,runtimeEnv:e})}async start(e,t,r,s){this.workDir=this.managedAgentPolicy?.adapterPolicy.workDir??t,this.seq=0,this.persistNativeSession=s?.persistNativeSession!==!1,this.nativeSessionVisibility=s?.nativeSessionVisibility??"user",r&&(this.agentSessionId=r)}async prepareSend(e,t,r,s,i,n){const a=i?.trim()??"";if(a!==this.agentSystemPrompt&&(this.agentSystemPrompt=a,this.process&&await this.killProcess(!0)),!(!this.agentSessionId||this.activeTurnId)){this.preparedExternalOwnerThreadId=null;try{await this.ensureAppServer(I(t))}catch(d){if(!P(d))throw d;if(n?.source==="room_activation")throw new Error("codex_managed_thread_owned_externally",{cause:d});if(this.isThreadTailInterrupted(this.agentSessionId))throw new Error(C,{cause:d});this.preparedExternalOwnerThreadId=this.agentSessionId}}}async send(e,t,r,s,i,n){if(n?.source==="room_activation"&&!this.managedAgentPolicy)throw new Error("managed_agent_policy_missing");if(n?.source==="room_activation"&&(!this.configuredManagedRoomContextToken||!this.configuredManagedRoomExecutor))throw new Error("codex_managed_room_tool_context_unavailable");this.activeTurnId&&(await this.interruptActiveTurn().catch(()=>{}),await this.killProcess(!0)),this.configurationRestartRequired&&this.process&&await this.killProcess(!0),this.configurationRestartRequired=!1;const a=I(t),d=ie(r),c=i?.trim()??"";if(c!==this.agentSystemPrompt&&(this.agentSystemPrompt=c,this.process&&await this.killProcess(!0)),n?.source==="room_activation"&&this.managedRoomTools.configure(this.configuredManagedRoomContextToken,this.configuredManagedRoomExecutor),this.runId=N(),this.seq=0,this.resetRunState(),this.agentSessionId&&this.preparedExternalOwnerThreadId===this.agentSessionId)return this.preparedExternalOwnerThreadId=null,{deliveryMode:"external_owner_queue",queuedSubmissionId:await this.enqueueForExternalOwner(this.agentSessionId,e,s)};try{await this.ensureAppServer(a)}catch(h){if(!this.agentSessionId||!P(h))throw h;if(n?.source==="room_activation")throw new Error("codex_managed_thread_owned_externally",{cause:h});if(this.isThreadTailInterrupted(this.agentSessionId))throw new Error(C,{cause:h});return{deliveryMode:"external_owner_queue",queuedSubmissionId:await this.enqueueForExternalOwner(this.agentSessionId,e,s)}}const l=this.agentSessionId;if(!l)throw new Error("codex app-server did not create a thread");this.emitEvent({state:"start",agentSessionId:l}),this.managedTurnReplay=this.managedPermissionConfig?{text:e,modelId:a,reasoningEffort:d,attachments:s,recoveryCount:0}:null;const p=await this.startTurnWithRecovery(l,e,a,d,s),m=this.agentSessionId??l;if(this.activeTurnId=p.turn?.id??null,this.managedRoomToolThreadId===m&&this.activeTurnId&&!this.managedRoomTools.bindTurn(m,this.activeTurnId))throw await this.killProcess(),new Error("codex_managed_room_turn_binding_failed");return{deliveryMode:"direct"}}isThreadTailInterrupted(e){return this.options.isThreadTailInterrupted?.(e)??z(e)}async enqueueForExternalOwner(e,t,r){const s=T("codex");if(!s)throw new Error('Command "codex" not found. Is OpenAI Codex CLI installed?');const i=fe(e,t,r),n=x(s,i,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:this.buildProcessEnv({NO_COLOR:"1"})});return await new Promise((a,d)=>{let c="",l="",p=!1;const m=(u,f)=>{p||(p=!0,clearTimeout(h),u?d(u):a(f))},h=setTimeout(()=>{n.kill("SIGTERM"),m(new Error("Codex Desktop message queue timed out"))},6e4);h.unref?.(),n.stdout?.on("data",u=>{c+=u.toString()}),n.stderr?.on("data",u=>{l+=u.toString()}),n.once("error",u=>m(u)),n.once("close",u=>{const f=`${c}
|
|
4
|
+
${l}`.trim();if(u!==0){m(new Error(f||`codex queue exited with code ${u??"unknown"}`));return}const O=f.match(/Queued message\s+([^\s]+)\s+for thread/i)?.[1];m(void 0,O)})})}async resume(e){await this.killProcess(),this.agentSessionId=e,this.resetTextState()}async setTitle(e,t,r){const s=e.trim(),i=t.replace(/\s+/g," ").trim();!s||!i||(this.agentSessionId=s,r?.trim()&&(this.workDir=r),await this.ensureAppServer(),await this.sendRpc("thread/name/set",{threadId:s,name:i}))}async stop(){this.managedRoomTools.deactivateTurn(),await this.interruptActiveTurn().catch(()=>{}),await this.killProcess()}async getStatus(){const e=this.agentSessionId,t=this.activeTurnId;if(!e||!this.process)return{active:!1,runId:t,runPhase:null,canStop:!1};let r=null;try{r=(await this.sendRpc("thread/read",{threadId:e,includeTurns:!1},5e3)).thread?.status??null}catch{}const s=r?.type==="active"||!!t;return{active:s,runId:t,runPhase:s?this.mapThreadStatusToRunPhase(r):null,canStop:!!(s&&t&&this.process)}}spawnCodex(e){const t=T("codex");if(!t){this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?'));return}const r=x(t,e,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:this.buildProcessEnv()});this.process=r,w({input:r.stdout}).on("line",n=>{if(n.trim())try{const a=JSON.parse(n);this.handleStreamEvent(a)}catch{this.emitEvent({state:"delta",text:n})}});let i="";r.stderr?.on("data",n=>{i+=n.toString()}),r.on("close",n=>{this.process===r&&(this.process=null,this.clearForceCloseTimer(),this.handleProcessClose(n,i))}),r.on("error",n=>{this.process===r&&(this.process=null,n.code==="ENOENT"?this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?')):this.emit("error",n))})}spawnAppServer(){const e=T("codex");if(!e){this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?'));return}const t=["app-server","--listen","stdio://"],r=this.options.modelInstructionsFile??W(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,this.agentSystemPrompt);r&&t.push("-c",`model_instructions_file=${JSON.stringify(r)}`);const s=x(e,t,{cwd:this.workDir??void 0,stdio:["pipe","pipe","pipe"],env:this.buildProcessEnv({NO_COLOR:"1"})});this.process=s,this.stderrBuf="",this.appServerStartupError=null,w({input:s.stdout}).on("line",n=>{if(!n.trim())return;let a;try{a=JSON.parse(n)}catch{this.handleAppServerNonJsonStdout(n);return}this.handleAppServerMessage(a)}),s.stderr?.on("data",n=>{this.stderrBuf+=n.toString()}),s.on("close",n=>{if(this.process!==s)return;const a=this.activeTurnId!=null;this.process=null,this.appServerReady=null,this.activeTurnId=null,this.managedRoomTools.reset(),this.clearConfiguredManagedRoomContext(),this.rejectAllPending(new Error(k(this.stderrBuf)||`codex app-server exited with code ${n}`)),this.terminalState==="open"&&a&&this.handleProcessClose(n,this.stderrBuf)}),s.on("error",n=>{this.process===s&&(this.process=null,this.managedRoomTools.reset(),this.clearConfiguredManagedRoomContext(),this.rejectAllPending(n),n.code==="ENOENT"?this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?')):this.emit("error",n))})}async ensureAppServer(e){return this.appServerReady?this.appServerReady:(this.spawnAppServer(),this.appServerReady=this.initializeAppServer(e).catch(async t=>{throw this.appServerReady=null,await this.killProcess(),t}),this.appServerReady)}async initializeAppServer(e){const t=I(e);await this.sendRpc("initialize",{clientInfo:Q,capabilities:{experimentalApi:!0}}),this.managedPermissionConfig=this.managedAgentPolicy&&!R(this.managedAgentPolicy)?await this.buildManagedPermissionConfig():null;const r=!!(this.configuredManagedRoomContextToken||this.configuredManagedRoomExecutor);if(this.managedAgentPolicy&&r&&!this.managedRoomTools.isConfigured()&&(this.managedRoomTools.configure(this.configuredManagedRoomContextToken,this.configuredManagedRoomExecutor),!this.managedRoomTools.isConfigured()))throw new Error("codex_managed_room_tool_context_unavailable");if(this.agentSessionId&&this.managedAgentPolicy&&r&&this.agentSessionId!==this.managedRoomToolThreadId){if(!this.managedRoomTools.isConfigured())throw new Error("codex_managed_room_tool_context_unavailable");this.agentSessionId=null}if(this.agentSessionId){const c={threadId:this.agentSessionId,cwd:this.workDir,approvalPolicy:"never",...this.managedPermissionConfig?{config:this.managedPermissionConfig.threadConfig}:{sandbox:"danger-full-access"},persistExtendedHistory:!0,...t?{model:t}:{}};let l;try{l=await this.sendRpc("thread/resume",{...c,excludeTurns:!0})}catch(p){if(!le(p))throw p;l=await this.sendRpc("thread/resume",c)}this.agentSessionId=l.thread?.id??this.agentSessionId,this.managedPermissionConfig&&E(l,this.managedPermissionConfig.profileId),this.managedAgentPolicy&&r&&(this.managedRoomTools.bindThread(this.agentSessionId),this.managedRoomToolThreadId=this.agentSessionId);return}const s=this.options.hidden||this.nativeSessionVisibility==="internal"||!this.persistNativeSession,i=s?void 0:await this.resolveCodexProjectId(),n={cwd:this.workDir,approvalPolicy:"never",...this.managedPermissionConfig?{config:this.managedPermissionConfig.threadConfig}:{sandbox:"danger-full-access"},serviceName:"Shennian",...s?{}:{threadSource:"user"},experimentalRawEvents:!1,persistExtendedHistory:!0,...this.managedAgentPolicy&&r?{dynamicTools:J}:{},...i?{projectId:i}:{},...t?{model:t}:{}};let a;if(s&&!this.managedPermissionConfig)a=await this.sendRpc("thread/start",n);else try{a=await this.sendRpc("thread/start",{...n,historyMode:"paginated"})}catch(c){throw de(c)?new Error("\u5F53\u524D Codex CLI \u4E0D\u652F\u6301\u521B\u5EFA\u53EF\u5728 Codex Desktop \u4E2D\u7EE7\u7EED\u7684\u65B0\u4F1A\u8BDD\uFF0C\u8BF7\u624B\u52A8\u5347\u7EA7 Codex CLI \u540E\u91CD\u8BD5\u3002\u795E\u5FF5\u4E0D\u4F1A\u81EA\u52A8\u5347\u7EA7\uFF0C\u4E5F\u4E0D\u4F1A\u964D\u7EA7\u521B\u5EFA\u4E0D\u53EF\u89C1\u7684 legacy \u4F1A\u8BDD\u3002",{cause:c}):c}const d=a.thread?.id;if(!d)throw new Error("codex app-server thread/start returned no thread id");this.managedPermissionConfig&&E(a,this.managedPermissionConfig.profileId),this.managedAgentPolicy&&r&&(this.managedRoomTools.bindThread(d),this.managedRoomToolThreadId=d),this.agentSessionId=d}async buildManagedPermissionConfig(){const e=this.managedAgentPolicy;if(!e)throw new Error("managed_agent_policy_missing");const t=e.adapterPolicy.externalCapabilities.mcp?[]:K(await this.sendRpc("config/read",{cwd:e.adapterPolicy.workDir}));return X(B(e),e.adapterPolicy.workDir,{configuredMcpServerNames:t,shellSubprocessPolicy:e.environmentPolicy.shellSubprocess})}async resolveCodexProjectId(){const e=this.workDir?.trim();if(e)try{const t=[];let r;do{const c=await this.sendRpc("project/list",{limit:100,...r?{cursor:r}:{}});t.push(...c.data??[]),r=c.nextCursor}while(r);const s=ue(t,e);if(s)return s;const i=g.resolve(e),n=`shennian-project-${S("sha256").update(i).digest("hex")}`,d=(await this.sendRpc("project/create",{idempotencyKey:n,name:g.basename(i)||i,roots:[{path:i}],metadata:{createdBy:"Shennian"}})).project?.id;if(!d)throw new Error("codex app-server project/create returned no project id");return d}catch(t){throw ce(t)?new Error("\u5F53\u524D Codex CLI \u4E0D\u652F\u6301\u521B\u5EFA\u53EF\u5F52\u5C5E\u5230 Codex Desktop \u9879\u76EE\u7684\u65B0\u4F1A\u8BDD\uFF0C\u8BF7\u624B\u52A8\u5347\u7EA7 Codex CLI \u540E\u91CD\u8BD5\u3002\u795E\u5FF5\u4E0D\u4F1A\u81EA\u52A8\u5347\u7EA7\uFF0C\u4E5F\u4E0D\u4F1A\u76F4\u63A5\u4FEE\u6539 Codex Desktop \u7684\u79C1\u6709\u4FA7\u680F\u7D22\u5F15\u3002",{cause:t}):t}}async startTurnWithRecovery(e,t,r,s,i){try{return await this.startTurn(e,t,r,s,i)}catch(n){if(!v(n))throw n;if(this.managedAgentPolicy||this.managedPermissionConfig){this.logManagedThreadLifecycle("rollout.missing",{threadId:e,recovery:"recreate"}),await this.killProcess(!0),this.agentSessionId=null,this.managedRoomToolThreadId=null,await this.ensureAppServer(r);const a=this.agentSessionId;if(!a)throw new Error("codex app-server did not recreate the managed thread",{cause:n});return this.logManagedThreadLifecycle("thread.recreated",{previousThreadId:e,threadId:a}),this.emitEvent({state:"start",agentSessionId:a}),await this.startFreshManagedTurnWithReadinessRetry(a,t,r,s,i)}return await this.killProcess(),await this.ensureAppServer(r),await this.startTurn(e,t,r,s,i)}}async startFreshManagedTurnWithReadinessRetry(e,t,r,s,i){const n=[0,100,300,1e3];let a;for(let d=0;d<n.length;d+=1){const c=n[d];c>0&&await new Promise(l=>setTimeout(l,c));try{const l=await this.startTurn(e,t,r,s,i);return d>0&&this.logManagedThreadLifecycle("rollout.ready",{threadId:e,attempt:d+1}),l}catch(l){if(a=l,!v(l)||d===n.length-1)throw l;this.logManagedThreadLifecycle("rollout.retry",{threadId:e,attempt:d+2,delayMs:n[d+1]})}}throw a}logManagedThreadLifecycle(e,t){console.error(`[codex.managed] ${JSON.stringify({event:e,...t})}`)}async startTurn(e,t,r,s,i){try{return await this.sendRpc("turn/start",{threadId:e,input:[M(t,i)],approvalPolicy:"never",...this.managedPermissionConfig?{}:{sandboxPolicy:{type:"dangerFullAccess"}},...r?{model:r}:{},...s?{effort:s}:{}})}catch(n){throw s&&te(n)?new Error(`Codex app-server does not accept reasoning effort "${s}" for this turn. Refresh models or upgrade Codex CLI, then retry.`,{cause:n}):n}}async interruptActiveTurn(){const e=this.agentSessionId,t=this.activeTurnId;this.activeTurnId=null,this.managedRoomTools.deactivateTurn(),!(!e||!t||!this.process)&&await this.sendRpc("turn/interrupt",{threadId:e,turnId:t},5e3)}sendRpc(e,t,r=6e4){if(this.appServerStartupError)return Promise.reject(this.appServerStartupError);const s=this.process;if(!s?.stdin)return Promise.reject(new Error("codex app-server is not running"));const i=this.rpcSeq++,n=JSON.stringify({id:i,method:e,params:t});return new Promise((a,d)=>{const c=setTimeout(()=>{this.pendingRequests.delete(i),d(new Error(`codex app-server request timed out: ${e}`))},r);this.pendingRequests.set(i,{resolve:a,reject:d,timer:c}),s.stdin.write(`${n}
|
|
5
|
+
`,l=>{l&&(clearTimeout(c),this.pendingRequests.delete(i),d(l))})})}handleAppServerMessage(e){if(e.method==="item/tool/call"&&e.id!=null){this.handleManagedRoomToolCall(e.id,e.params??{});return}if(e.id!=null){const r=typeof e.id=="number"?this.pendingRequests.get(e.id):void 0;r&&(clearTimeout(r.timer),this.pendingRequests.delete(e.id),e.error?r.reject(new Error(e.error.message||`codex app-server error ${e.error.code??""}`.trim())):r.resolve(e.result))}if(!e.method)return;const t=e.params??{};switch(e.method){case"turn/started":{const r=typeof t.turn=="object"&&t.turn!==null?t.turn:null,s=typeof r?.id=="string"?r.id:null,i=typeof t.threadId=="string"?t.threadId:"";s&&(this.activeTurnId=s,this.managedRoomToolThreadId===i&&!this.managedRoomTools.bindTurn(i,s)&&this.emitErrorIfOpen("codex_managed_room_turn_binding_failed"));break}case"thread/status/changed":{const r=typeof t.threadId=="string"?t.threadId:"";if(r&&this.agentSessionId&&r!==this.agentSessionId)break;const s=typeof t.status=="object"&&t.status!==null?t.status:null;s?.type==="active"&&this.emitEvent({state:"heartbeat",runPhase:this.mapThreadStatusToRunPhase(s)});break}case"item/agentMessage/delta":{const r=typeof t.itemId=="string"?t.itemId:"";r&&this.deltaItemIds.add(r),typeof t.delta=="string"&&this.emitText(t.delta);break}case"item/completed":this.handleAppServerCompletedItem(t);break;case"thread/tokenUsage/updated":this.handleAppServerUsage(t);break;case"turn/completed":{const r=typeof t.turn=="object"&&t.turn!==null?t.turn:null,s=typeof r?.id=="string"?r.id:null;(!this.activeTurnId||s===this.activeTurnId)&&(this.activeTurnId=null,this.managedRoomTools.deactivateTurn(),this.emitFinalIfOpen());break}case"turn/failed":{const r=_(t);if(this.scheduleManagedAsyncRolloutRecovery(r))return;this.emitErrorIfOpen(r||"turn failed");break}case"error":{const r=_(t);if(re(r)){this.emitTransientStatus(r);return}if(this.scheduleManagedAsyncRolloutRecovery(r))return;this.emitErrorIfOpen(r);break}}}scheduleManagedAsyncRolloutRecovery(e){if(!this.managedAgentPolicy&&!this.managedPermissionConfig||!this.managedTurnReplay||!v(new Error(e)))return!1;if(this.managedAsyncRecovery)return!0;if(this.managedTurnReplay.recoveryCount>=2)return!1;this.managedTurnReplay.recoveryCount+=1;const t=this.managedTurnReplay.recoveryCount;return this.logManagedThreadLifecycle("rollout.failed-async",{threadId:this.agentSessionId,recoveryCount:t}),this.managedAsyncRecovery=this.recoverManagedTurnAfterAsyncRolloutFailure().catch(r=>{const s=v(r)?"no rollout found after managed thread recovery":r instanceof Error?r.message:"managed thread recovery failed";this.emitErrorIfOpen(s)}).finally(()=>{this.managedAsyncRecovery=null}),!0}async recoverManagedTurnAfterAsyncRolloutFailure(){const e=this.managedTurnReplay,t=this.agentSessionId;if(!e||!t||this.terminalState!=="open")return;this.activeTurnId=null,this.managedRoomTools.deactivateTurn(),await this.killProcess(!0),this.agentSessionId=null,this.managedRoomToolThreadId=null,await this.ensureAppServer(e.modelId);const r=this.agentSessionId;if(!r)throw new Error("codex app-server did not recreate the managed thread");this.logManagedThreadLifecycle("thread.recreated-async",{previousThreadId:t,threadId:r,recoveryCount:e.recoveryCount}),this.emitEvent({state:"start",agentSessionId:r});const s=await this.startFreshManagedTurnWithReadinessRetry(r,e.text,e.modelId,e.reasoningEffort,e.attachments);if(this.activeTurnId=s.turn?.id??null,this.managedRoomToolThreadId===r&&this.activeTurnId&&!this.managedRoomTools.bindTurn(r,this.activeTurnId))throw new Error("codex_managed_room_turn_binding_failed")}async handleManagedRoomToolCall(e,t){const r=await this.managedRoomTools.execute(t);if(this.writeAppServerResponse(e,r),r.success&&t.tool==="shennian_room_send"){const s=typeof t.arguments=="object"&&t.arguments!==null?t.arguments:null,i=typeof s?.text=="string"?s.text.trim():"";i&&this.emitText(i,"block")}}writeAppServerResponse(e,t){const r=this.process;r?.stdin&&r.stdin.write(`${JSON.stringify({id:e,result:t})}
|
|
6
|
+
`)}mapThreadStatusToRunPhase(e){const t=e?.type==="active"&&Array.isArray(e.activeFlags)?e.activeFlags:[];return t.includes("waitingOnApproval")?"waiting_approval":t.includes("waitingOnUserInput")?"waiting_user_input":"thinking"}handleAppServerNonJsonStdout(e){const t=oe(e);se(t)&&this.failAppServerStartup(new Error("Codex \u672A\u767B\u5F55\u3002\u8BF7\u5148\u5728\u8FD9\u53F0\u7535\u8111\u7684\u7EC8\u7AEF\u8FD0\u884C `codex`\uFF0C\u6309\u63D0\u793A\u5B8C\u6210 ChatGPT \u767B\u5F55\u6216\u914D\u7F6E API key\uFF0C\u7136\u540E\u518D\u56DE\u5230\u795E\u5FF5\u53D1\u9001\u6D88\u606F\u3002"))}failAppServerStartup(e){this.appServerStartupError||(this.appServerStartupError=e,this.rejectAllPending(e),this.process?.kill("SIGTERM"))}handleAppServerCompletedItem(e){const t=typeof e.item=="object"&&e.item!==null?e.item:null;if(!(!t||typeof t.type!="string")&&!Z(t))switch(t.type){case"agentMessage":{const r=typeof t.id=="string"?t.id:"";if(r&&this.deltaItemIds.has(r))return;typeof t.text=="string"&&this.emitText(t.text,"block");break}case"commandExecution":{const r=typeof t.command=="string"?t.command:"",s=typeof t.aggregatedOutput=="string"?t.aggregatedOutput:"";r&&this.emitEvent({state:"tool-call",name:"command_execution",args:{command:r}}),this.emitEvent({state:"tool-result",name:"command_execution",result:[s,t.exitCode!=null?`
|
|
7
|
+
(exit ${t.exitCode})`:""].join("").trim()});break}case"mcpToolCall":case"dynamicToolCall":{const r=typeof t.tool=="string"?t.tool:t.type;if(y(r))return;const s=typeof t.arguments=="object"&&t.arguments!==null?t.arguments:{};this.emitEvent({state:"tool-call",name:r,args:s}),this.emitEvent({state:"tool-result",name:r,result:A(t.error??t.result??t.contentItems??"")});break}case"fileChange":break;case"approvalRequest":case"approval_request":case"permissionRequest":case"permission_request":case"userInputRequired":case"user_input_required":{this.emitApprovalPending(t);break}}}handleAppServerUsage(e){const t=typeof e.tokenUsage=="object"&&e.tokenUsage!==null?e.tokenUsage:null,r=typeof t?.last=="object"&&t.last!==null?t.last:null,s=typeof t?.total=="object"&&t.total!==null?t.total:null,i=r??s;if(!i)return;const n=typeof i.inputTokens=="number"?i.inputTokens:void 0,a=typeof i.outputTokens=="number"?i.outputTokens:void 0;(n!=null||a!=null)&&(this.pendingUsage={inputTokens:n??0,outputTokens:a??0})}handleCodexItemLine(e){const t=e.item;if(t?.type&&!ee(t))switch(t.type){case"agent_message":case"reasoning":{e.type==="item.completed"&&t.text&&this.emitText(t.text,"block");break}case"command_execution":{if(e.type==="item.started"&&t.command&&this.emitEvent({state:"tool-call",name:"command_execution",args:{command:t.command}}),e.type==="item.completed"){const r=[t.aggregated_output??"",t.exit_code!=null?`
|
|
8
8
|
(exit ${t.exit_code})`:""];this.emitEvent({state:"tool-result",name:"command_execution",result:r.join("").trim()||String(t.status??"")})}break}case"mcp_tool_call":{if(t.tool&&y(t.tool))return;if(e.type==="item.started"&&this.emitEvent({state:"tool-call",name:t.tool??"mcp_tool",args:{server:t.server,...t.arguments&&typeof t.arguments=="object"?t.arguments:{}}}),e.type==="item.completed"){const r=t.error&&typeof t.error=="object"?t.error.message:void 0;this.emitEvent({state:"tool-result",name:t.tool??"mcp_tool",result:r??A(t.result)})}break}case"file_change":break;case"web_search":{e.type==="item.completed"&&t.query&&this.emitText(`[web_search] ${t.query}`,"block");break}case"todo_list":{if(e.type==="item.completed"&&t.items?.length){const r=t.items.map(s=>`- [${s.completed?"x":" "}] ${s.text}`).join(`
|
|
9
|
-
`);this.emitText(r,"block")}break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{(e.type==="item.started"||e.type==="item.completed")&&this.emitApprovalPending(t);break}case"error":{e.type==="item.completed"&&t.message&&this.emitEvent({state:"error",message:t.message});break}default:break}}handleStreamEvent(e){const t=e.type??e.event;switch(t?.startsWith("item.")&&this.handleCodexItemLine(e),t){case"turn.completed":{const s=e.usage;if(s){const i=s.input_tokens??s.prompt_tokens,n=s.output_tokens??s.completion_tokens;(i!=null||n!=null)&&(this.pendingUsage={inputTokens:i??0,outputTokens:n??0})}this.emitFinalIfOpen();return}case"turn.failed":{const s=typeof e.error=="object"&&e.error?.message?e.error.message:typeof e.error=="string"?e.error:"turn failed";this.emitErrorIfOpen(s);return}case"error":{const s=typeof e.message=="string"?e.message:"";if(s.includes("Reconnecting"))return;this.emitErrorIfOpen(s||(typeof e.error=="string"?e.error:"stream error"));return}case"thread.started":{const s=e.thread_id??e.session_id??e.id;typeof s=="string"&&s&&(this.agentSessionId=s,this.emitEvent({state:"start",agentSessionId:this.agentSessionId}));return}case"turn.started":return}if(t?.startsWith("item."))return;switch(e.type??e.event){case"message":case"text":case"content":{const s=e.content??e.text;s&&this.emitText(s);break}case"function_call":case"tool_call":{if(this.isApprovalLikeName(e.name)){this.emitApprovalPending(e);break}if(e.name&&y(e.name))return;this.emitEvent({state:"tool-call",name:e.name,args:e.arguments??e.input});break}case"function_call_output":case"tool_result":{if(e.name&&y(e.name))return;this.emitEvent({state:"tool-result",name:e.name,result:e.output??e.result});break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{this.emitApprovalPending(e);break}case"error":break;case"done":case"completed":{e.usage&&(this.pendingUsage={inputTokens:e.usage.prompt_tokens??e.usage.input_tokens??0,outputTokens:e.usage.completion_tokens??e.usage.output_tokens??0}),this.emitFinalIfOpen();break}}}emitEvent(e){if(this.terminalState!=="open"&&e.state!=="final"&&e.state!=="error"&&e.state!=="aborted")return;const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}isApprovalLikeName(e){return typeof e!="string"?!1:/approval|permission|confirm|user[_-]?input|request[_-]?user/i.test(e)}emitApprovalPending(e){const t=typeof e.command=="string"?e.command:"",r=typeof e.title=="string"&&e.title.trim()?e.title:"\u9700\u8981\u7528\u6237\u786E\u8BA4",s=typeof e.prompt=="string"?e.prompt:typeof e.reason=="string"?e.reason:typeof e.message=="string"?e.message:t?`Codex \u8BF7\u6C42\u6267\u884C\u547D\u4EE4\uFF1A${t}`:"Codex \u6B63\u5728\u7B49\u5F85\u7528\u6237\u786E\u8BA4\u540E\u7EE7\u7EED\u3002";this.emitEvent({state:"approval-pending",approval:{title:r,content:s,source:"codex",actionHint:"\u5F53\u524D\u795E\u5FF5\u6682\u4E0D\u652F\u6301\u8FDC\u7A0B\u786E\u8BA4\uFF0C\u8BF7\u56DE\u5230\u8FD0\u884C Codex \u7684\u7535\u8111/\u7EC8\u7AEF\u5B8C\u6210\u786E\u8BA4\u3002"}})}async killProcess(e=!1){const t=this.process;if(this.appServerReady=null,this.activeTurnId=null,this.managedRoomTools.reset(),e||this.clearConfiguredManagedRoomContext(),!t){this.rejectAllPending(new Error("codex app-server stopped"));return}this.process=null,this.clearForceCloseTimer(),t.kill("SIGTERM"),await new Promise(r=>{t.on("close",r),setTimeout(()=>{t.kill("SIGKILL"),r()},3e3)}),this.rejectAllPending(new Error("codex app-server stopped"))}rejectAllPending(e){for(const[t,r]of this.pendingRequests.entries())clearTimeout(r.timer),r.reject(e),this.pendingRequests.delete(t)}handleProcessClose(e,t){const r=k(t);if(e!==0&&e!==null){const s=r||`codex exited with code ${e}`;this.emitErrorIfOpen(s)}else
|
|
10
|
-
`,thinking:!0}))}resetTextState(){this.hasEmittedText=!1,this.textTail=""}emitText(e,t="delta"){if(!e)return;let r=
|
|
9
|
+
`);this.emitText(r,"block")}break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{(e.type==="item.started"||e.type==="item.completed")&&this.emitApprovalPending(t);break}case"error":{e.type==="item.completed"&&t.message&&this.emitEvent({state:"error",message:t.message});break}default:break}}handleStreamEvent(e){const t=e.type??e.event;switch(t?.startsWith("item.")&&this.handleCodexItemLine(e),t){case"turn.completed":{const s=e.usage;if(s){const i=s.input_tokens??s.prompt_tokens,n=s.output_tokens??s.completion_tokens;(i!=null||n!=null)&&(this.pendingUsage={inputTokens:i??0,outputTokens:n??0})}this.emitFinalIfOpen();return}case"turn.failed":{const s=typeof e.error=="object"&&e.error?.message?e.error.message:typeof e.error=="string"?e.error:"turn failed";this.emitErrorIfOpen(s);return}case"error":{const s=typeof e.message=="string"?e.message:"";if(s.includes("Reconnecting"))return;this.emitErrorIfOpen(s||(typeof e.error=="string"?e.error:"stream error"));return}case"thread.started":{const s=e.thread_id??e.session_id??e.id;typeof s=="string"&&s&&(this.agentSessionId=s,this.emitEvent({state:"start",agentSessionId:this.agentSessionId}));return}case"turn.started":return}if(t?.startsWith("item."))return;switch(e.type??e.event){case"message":case"text":case"content":{const s=e.content??e.text;s&&this.emitText(s);break}case"function_call":case"tool_call":{if(this.isApprovalLikeName(e.name)){this.emitApprovalPending(e);break}if(e.name&&y(e.name))return;this.emitEvent({state:"tool-call",name:e.name,args:e.arguments??e.input});break}case"function_call_output":case"tool_result":{if(e.name&&y(e.name))return;this.emitEvent({state:"tool-result",name:e.name,result:e.output??e.result});break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{this.emitApprovalPending(e);break}case"error":break;case"done":case"completed":{e.usage&&(this.pendingUsage={inputTokens:e.usage.prompt_tokens??e.usage.input_tokens??0,outputTokens:e.usage.completion_tokens??e.usage.output_tokens??0}),this.emitFinalIfOpen();break}}}emitEvent(e){if(this.terminalState!=="open"&&e.state!=="final"&&e.state!=="error"&&e.state!=="aborted")return;const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}isApprovalLikeName(e){return typeof e!="string"?!1:/approval|permission|confirm|user[_-]?input|request[_-]?user/i.test(e)}emitApprovalPending(e){const t=typeof e.command=="string"?e.command:"",r=typeof e.title=="string"&&e.title.trim()?e.title:"\u9700\u8981\u7528\u6237\u786E\u8BA4",s=typeof e.prompt=="string"?e.prompt:typeof e.reason=="string"?e.reason:typeof e.message=="string"?e.message:t?`Codex \u8BF7\u6C42\u6267\u884C\u547D\u4EE4\uFF1A${t}`:"Codex \u6B63\u5728\u7B49\u5F85\u7528\u6237\u786E\u8BA4\u540E\u7EE7\u7EED\u3002";this.emitEvent({state:"approval-pending",approval:{title:r,content:s,source:"codex",actionHint:"\u5F53\u524D\u795E\u5FF5\u6682\u4E0D\u652F\u6301\u8FDC\u7A0B\u786E\u8BA4\uFF0C\u8BF7\u56DE\u5230\u8FD0\u884C Codex \u7684\u7535\u8111/\u7EC8\u7AEF\u5B8C\u6210\u786E\u8BA4\u3002"}})}async killProcess(e=!1){const t=this.process;if(this.appServerReady=null,this.activeTurnId=null,this.managedRoomTools.reset(),e||this.clearConfiguredManagedRoomContext(),!t){this.rejectAllPending(new Error("codex app-server stopped"));return}this.process=null,this.clearForceCloseTimer(),t.kill("SIGTERM"),await new Promise(r=>{t.on("close",r),setTimeout(()=>{t.kill("SIGKILL"),r()},3e3)}),this.rejectAllPending(new Error("codex app-server stopped"))}rejectAllPending(e){for(const[t,r]of this.pendingRequests.entries())clearTimeout(r.timer),r.reject(e),this.pendingRequests.delete(t)}handleProcessClose(e,t){const r=k(t);if(e!==0&&e!==null){const s=r||`codex exited with code ${e}`;this.emitErrorIfOpen(s)}else ne(r)?this.emitErrorIfOpen(r):this.emitFinalIfOpen();this.pendingUsage=void 0}emitFinalIfOpen(){this.terminalState==="open"&&(this.terminalState="final",this.managedTurnReplay=null,this.managedRoomTools.deactivateTurn(),this.clearConfiguredManagedRoomContext(),this.emitEvent({state:"final",usage:this.pendingUsage,agentSessionId:this.agentSessionId??void 0}),this.killProcess().catch(()=>{}))}emitErrorIfOpen(e){this.terminalState==="open"&&(this.terminalState="error",this.managedTurnReplay=null,this.managedRoomTools.deactivateTurn(),this.clearConfiguredManagedRoomContext(),this.emitEvent({state:"error",message:j(e)}),this.scheduleProcessClose())}resetRunState(){this.pendingUsage=void 0,this.terminalState="open",this.deltaItemIds.clear(),this.lastTransientStatus="",this.clearForceCloseTimer(),this.resetTextState()}clearConfiguredManagedRoomContext(){this.configuredManagedRoomContextToken=null,this.configuredManagedRoomExecutor=null}emitTransientStatus(e){const t=Y(e);!t||t===this.lastTransientStatus||this.terminalState!=="open"||(this.lastTransientStatus=t,this.emitEvent({state:"delta",text:`${t}
|
|
10
|
+
`,thinking:!0}))}resetTextState(){this.hasEmittedText=!1,this.textTail=""}emitText(e,t="delta"){if(!e)return;let r=ae(e);r&&(t==="block"&&this.hasEmittedText&&!r.startsWith(`
|
|
11
11
|
`)&&(this.textTail.endsWith(`
|
|
12
12
|
`)?r=`
|
|
13
13
|
${r}`:this.textTail.endsWith(`
|
|
14
14
|
|
|
15
15
|
`)||(r=`
|
|
16
16
|
|
|
17
|
-
${r}`)),this.hasEmittedText=!0,this.textTail=(this.textTail+r).slice(-4),this.emitEvent({state:"delta",text:r}))}scheduleProcessClose(){const e=this.process;!e||this.forceCloseTimer||(this.forceCloseTimer=setTimeout(()=>{this.forceCloseTimer=null,this.process===e&&(e.kill("SIGTERM"),setTimeout(()=>{this.process===e&&e.kill("SIGKILL")},1e3))},250))}clearForceCloseTimer(){this.forceCloseTimer&&(clearTimeout(this.forceCloseTimer),this.forceCloseTimer=null)}}
|
|
17
|
+
${r}`)),this.hasEmittedText=!0,this.textTail=(this.textTail+r).slice(-4),this.emitEvent({state:"delta",text:r}))}scheduleProcessClose(){const e=this.process;!e||this.forceCloseTimer||(this.forceCloseTimer=setTimeout(()=>{this.forceCloseTimer=null,this.process===e&&(e.kill("SIGTERM"),setTimeout(()=>{this.process===e&&e.kill("SIGKILL")},1e3))},250))}clearForceCloseTimer(){this.forceCloseTimer&&(clearTimeout(this.forceCloseTimer),this.forceCloseTimer=null)}}L("codex",()=>new ye);export{ye as CodexAdapter,fe as buildCodexQueueArgs,ge as buildCodexQueuedText,P as isCodexActiveWriterError,le as isCodexExcludeTurnsUnsupportedError,de as isCodexPaginatedHistoryUnsupportedError,ce as isCodexProjectApiUnsupportedError,Ne as isCodexUnsupportedEffortError,De as isMissingCodexRolloutError,Le as normalizeCodexModelId,Fe as normalizeCodexReasoningEffort,ue as selectCodexProjectIdForWorkDir};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ChatAttachmentMeta, ExternalChannelSessionStatus } from '@shennian/wire';
|
|
2
|
-
import { AgentAdapter, type AgentSendContext } from './adapter.js';
|
|
2
|
+
import { AgentAdapter, type AgentActiveInput, type AgentSendContext } from './adapter.js';
|
|
3
3
|
import { type CompiledManagedAgentPolicy } from '../security/managed-agent-policy.js';
|
|
4
4
|
export declare class PiCodingAgentAdapter extends AgentAdapter {
|
|
5
5
|
readonly type: "pi-coding-agent";
|
|
6
|
+
get supportsActiveInput(): boolean;
|
|
7
|
+
injectActiveInput(input: AgentActiveInput): Promise<void>;
|
|
6
8
|
get recoveryCapabilities(): {
|
|
7
9
|
inspectTerminal: boolean;
|
|
8
10
|
reattachRun: boolean;
|