@@ -66,6 +66,10 @@ type daemonOptions struct {
6666 HeartbeatInterval time.Duration
6767}
6868
69+ type daemonTickOptions struct {
70+ SkipRemoteWhenWebSocket bool
71+ }
72+
6973type daemonControlOptions struct {
7074 StatePath string
7175 Status bool
@@ -690,6 +694,7 @@ func runDaemon(ctx context.Context, state *bootstrap.State, options daemonOption
690694 var tickMu sync.Mutex
691695 stopRequested := make (chan struct {})
692696 var stopOnce sync.Once
697+ remoteStreamMode := false
693698 writeHeartbeat := func (now time.Time ) error {
694699 return daemonpkg .WriteState (statePath , daemonpkg .BuildState (runner .SessionID , runner .WorkingDirectory , daemonpkg .RuntimeRunning , os .Getpid (), endpoint , now , nil ))
695700 }
@@ -699,7 +704,7 @@ func runDaemon(ctx context.Context, state *bootstrap.State, options daemonOption
699704 if err := writeHeartbeat (now ); err != nil {
700705 return contracts.ToolResult {}, err
701706 }
702- return runDaemonTick (ctx , runner , now )
707+ return runDaemonTickWithOptions (ctx , runner , now , daemonTickOptions { SkipRemoteWhenWebSocket : remoteStreamMode } )
703708 }
704709 if ! options .Once {
705710 daemonServer , err = daemonpkg .StartServer (daemonpkg.ServerOptions {
@@ -737,6 +742,7 @@ func runDaemon(ctx context.Context, state *bootstrap.State, options daemonOption
737742 fmt .Fprintf (stderr , "ccgo daemon: %v\n " , err )
738743 return 1
739744 }
745+ remoteStreamMode = true
740746 fmt .Fprintf (stdout , "ccgo daemon running\n session_id=%s\n state_path=%s\n " , runner .SessionID , statePath )
741747 if options .Once {
742748 return 0
@@ -921,11 +927,20 @@ func runDaemonDueSchedules(ctx context.Context, runner conversation.Runner, now
921927}
922928
923929func runDaemonTick (ctx context.Context , runner conversation.Runner , now time.Time ) (contracts.ToolResult , error ) {
930+ return runDaemonTickWithOptions (ctx , runner , now , daemonTickOptions {})
931+ }
932+
933+ func runDaemonTickWithOptions (ctx context.Context , runner conversation.Runner , now time.Time , options daemonTickOptions ) (contracts.ToolResult , error ) {
924934 scheduleResult , err := runDaemonDueSchedules (ctx , runner , now )
925935 if err != nil {
926936 return contracts.ToolResult {}, err
927937 }
928- remoteResult := runDaemonRemotePoll (ctx , runner , now )
938+ var remoteResult contracts.ToolResult
939+ if options .SkipRemoteWhenWebSocket {
940+ remoteResult = runDaemonRemotePollUnlessStream (ctx , runner , now )
941+ } else {
942+ remoteResult = runDaemonRemotePoll (ctx , runner , now )
943+ }
929944 schedule := scheduleResult .StructuredContent
930945 remotePoll := remoteResult .StructuredContent
931946 scheduleTriggered := intMapValue (schedule , "triggered_count" )
@@ -953,6 +968,32 @@ func runDaemonTick(ctx context.Context, runner conversation.Runner, now time.Tim
953968 }, nil
954969}
955970
971+ func runDaemonRemotePollUnlessStream (ctx context.Context , runner conversation.Runner , now time.Time ) contracts.ToolResult {
972+ registrationPath := remotepkg .SessionRegistrationPath (runner .SessionPath , runner .SessionID )
973+ if registrationPath == "" {
974+ return runDaemonRemotePoll (ctx , runner , now )
975+ }
976+ registration , err := remotepkg .LoadRegistrationState (registrationPath )
977+ if err != nil || registration .RuntimeState != remotepkg .RegistrationRegistered || strings .TrimSpace (registration .WebSocketURL ) == "" {
978+ return runDaemonRemotePoll (ctx , runner , now )
979+ }
980+ structured := map [string ]any {
981+ "type" : "remote_poll" ,
982+ "checked_at" : now .UTC ().Format (time .RFC3339Nano ),
983+ "runtime_state" : remotepkg .PumpRunning ,
984+ "transport" : "websocket_stream" ,
985+ "skipped" : true ,
986+ "event_count" : 0 ,
987+ "delivered_count" : 0 ,
988+ "duplicate_count" : 0 ,
989+ "error_count" : 0 ,
990+ }
991+ return contracts.ToolResult {
992+ Content : "Remote stream is handling websocket events." ,
993+ StructuredContent : structured ,
994+ }
995+ }
996+
956997func runDaemonRemotePoll (ctx context.Context , runner conversation.Runner , now time.Time ) contracts.ToolResult {
957998 structured := map [string ]any {
958999 "type" : "remote_poll" ,
0 commit comments