| 178 | } |
| 179 | |
| 180 | func (r *UiRuntime) RunSubmitMessage(ctx context.Context, userInput string, state *agent.AgentState, sessionID string) []agent.StreamEvent { |
| 181 | r.CurrentState = state |
| 182 | if refresher, ok := r.Engine.(interface{ RefreshRuntimeConfig() }); ok { |
| 183 | refresher.RefreshRuntimeConfig() |
| 184 | } |
| 185 | taskRuntime := r.taskRuntime() |
| 186 | if taskRuntime != nil { |
| 187 | taskRuntime.SetTaskEventSink(r.TaskSink) |
| 188 | defer taskRuntime.SetTaskEventSink(nil) |
| 189 | } |
| 190 | r.appendTranscriptEntry("user", userInput) |
| 191 | r.Frame.InputEnabled = false |
| 192 | r.Frame.InputMode = "normal" |
| 193 | r.Frame.InputPlaceholder = "Agent is responding..." |
| 194 | r.refreshContextWindowFrame() |
| 195 | if preparer, ok := r.UI.(RuntimePreparer); ok { |
| 196 | preparer.PrepareRuntime() |
| 197 | } |
| 198 | if r.UI != nil && !r.Mounted { |
| 199 | r.UI.Mount(r.Frame) |
| 200 | r.Mounted = true |
| 201 | } |
| 202 | r.markDirty() |
| 203 | r.Flush(true) |
| 204 | submitter, ok := r.Engine.(interface { |
| 205 | SubmitMessage(context.Context, string, *agent.AgentState, ...string) <-chan agent.StreamEvent |
| 206 | }) |
| 207 | if !ok { |
| 208 | if r.Dirty { |
| 209 | r.Flush(true) |
| 210 | } |
| 211 | return nil |
| 212 | } |
| 213 | var events []agent.StreamEvent |
| 214 | eventCh := submitter.SubmitMessage(ctx, userInput, state, sessionID) |
| 215 | ticker := time.NewTicker(uiAnimationInterval) |
| 216 | defer ticker.Stop() |
| 217 | for eventCh != nil { |
| 218 | select { |
| 219 | case event, open := <-eventCh: |
| 220 | if !open { |
| 221 | eventCh = nil |
| 222 | continue |
| 223 | } |
| 224 | uiEvent := r.ToUIEvent(event) |
| 225 | if uiEvent.Type == "permission_requested" { |
| 226 | r.HandlePermissionEvent(uiEvent) |
| 227 | } else { |
| 228 | r.ApplyUIEvent(uiEvent) |
| 229 | r.MaybeRenderEvent(event) |
| 230 | r.FlushIfDue() |
| 231 | } |
| 232 | r.DrainTaskEvents() |
| 233 | events = append(events, event) |
| 234 | case <-ticker.C: |
| 235 | r.advanceAnimationFrame() |
| 236 | r.DrainTaskEvents() |
| 237 | r.Flush(true) |