Stop showing the held tool call as running during a pause
This commit is contained in:
@@ -205,7 +205,7 @@ func (m *Manager) agyBeforeModel(l *live) hookcmd.Func {
|
|||||||
if in.InvocationNum == 0 || l.reviewID != "" {
|
if in.InvocationNum == 0 || l.reviewID != "" {
|
||||||
return map[string]any{}, nil
|
return map[string]any{}, nil
|
||||||
}
|
}
|
||||||
m.holdWhilePaused(ctx, l)
|
m.holdWhilePaused(ctx, l, "")
|
||||||
mt := m.deliverMidTurn(ctx, l)
|
mt := m.deliverMidTurn(ctx, l)
|
||||||
if mt.text == "" {
|
if mt.text == "" {
|
||||||
return map[string]any{}, nil
|
return map[string]any{}, nil
|
||||||
@@ -216,7 +216,7 @@ func (m *Manager) agyBeforeModel(l *live) hookcmd.Func {
|
|||||||
|
|
||||||
func (m *Manager) agyBeforeTool(l *live) hookcmd.Func {
|
func (m *Manager) agyBeforeTool(l *live) hookcmd.Func {
|
||||||
return func(ctx context.Context, input json.RawMessage) (map[string]any, error) {
|
return func(ctx context.Context, input json.RawMessage) (map[string]any, error) {
|
||||||
if !m.heldBeforeTool(ctx, l) || !m.midTurnWaiting(ctx, l) {
|
if !m.heldBeforeTool(ctx, l, "") || !m.midTurnWaiting(ctx, l) {
|
||||||
return map[string]any{"decision": "allow"}, nil
|
return map[string]any{"decision": "allow"}, nil
|
||||||
}
|
}
|
||||||
return map[string]any{"decision": "deny", "reason": pausedCallNotice}, nil
|
return map[string]any{"decision": "deny", "reason": pausedCallNotice}, nil
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ func (m *Manager) steerMidTurn(ctx context.Context, l *live, s *codex.Session) {
|
|||||||
|
|
||||||
func (m *Manager) codexAfterTool(l *live) hookcmd.Func {
|
func (m *Manager) codexAfterTool(l *live) hookcmd.Func {
|
||||||
return func(ctx context.Context, input json.RawMessage) (map[string]any, error) {
|
return func(ctx context.Context, input json.RawMessage) (map[string]any, error) {
|
||||||
if m.holdWhilePaused(ctx, l) && ctx.Err() == nil {
|
if m.holdWhilePaused(ctx, l, "") && ctx.Err() == nil {
|
||||||
m.steerMidTurn(context.WithoutCancel(ctx), l, l.sess.(codexProcess).s)
|
m.steerMidTurn(context.WithoutCancel(ctx), l, l.sess.(codexProcess).s)
|
||||||
}
|
}
|
||||||
return map[string]any{}, nil
|
return map[string]any{}, nil
|
||||||
|
|||||||
@@ -131,7 +131,15 @@ func (m *Manager) isPaused(sessionID string) bool {
|
|||||||
return m.paused[sessionID] != nil
|
return m.paused[sessionID] != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) holdWhilePaused(ctx context.Context, l *live) bool {
|
func hookToolUseID(input json.RawMessage) string {
|
||||||
|
in := struct {
|
||||||
|
ToolUseID string `json:"tool_use_id"`
|
||||||
|
}{}
|
||||||
|
json.Unmarshal(input, &in)
|
||||||
|
return in.ToolUseID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) holdWhilePaused(ctx context.Context, l *live, toolUseID string) bool {
|
||||||
held := false
|
held := false
|
||||||
for {
|
for {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
@@ -141,7 +149,13 @@ func (m *Manager) holdWhilePaused(ctx context.Context, l *live) bool {
|
|||||||
return held
|
return held
|
||||||
}
|
}
|
||||||
if !held {
|
if !held {
|
||||||
slog.Info("agent held by pause", "session", l.id)
|
slog.Info("agent held by pause", "session", l.id, "tool_use_id", toolUseID)
|
||||||
|
if toolUseID != "" {
|
||||||
|
err := m.emit(context.WithoutCancel(ctx), l, agentActor, "agent.held", map[string]any{"tool_use_id": toolUseID})
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("record held tool call", "session", l.id, "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
held = true
|
held = true
|
||||||
select {
|
select {
|
||||||
@@ -152,13 +166,13 @@ func (m *Manager) holdWhilePaused(ctx context.Context, l *live) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) heldBeforeTool(ctx context.Context, l *live) bool {
|
func (m *Manager) heldBeforeTool(ctx context.Context, l *live, toolUseID string) bool {
|
||||||
return m.holdWhilePaused(ctx, l) && ctx.Err() == nil
|
return m.holdWhilePaused(ctx, l, toolUseID) && ctx.Err() == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) beforeTool(l *live) hookcmd.Func {
|
func (m *Manager) beforeTool(l *live) hookcmd.Func {
|
||||||
return func(ctx context.Context, input json.RawMessage) (map[string]any, error) {
|
return func(ctx context.Context, input json.RawMessage) (map[string]any, error) {
|
||||||
if !m.heldBeforeTool(ctx, l) {
|
if !m.heldBeforeTool(ctx, l, hookToolUseID(input)) {
|
||||||
return map[string]any{}, nil
|
return map[string]any{}, nil
|
||||||
}
|
}
|
||||||
mt := m.deliverMidTurn(ctx, l)
|
mt := m.deliverMidTurn(ctx, l)
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ func (m *Manager) afterTool(l *live) hookcmd.Func {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
m.holdWhilePaused(ctx, l)
|
m.holdWhilePaused(ctx, l, hookToolUseID(input))
|
||||||
mt := m.deliverMidTurn(ctx, l)
|
mt := m.deliverMidTurn(ctx, l)
|
||||||
if mt.text == "" {
|
if mt.text == "" {
|
||||||
return map[string]any{}, nil
|
return map[string]any{}, nil
|
||||||
|
|||||||
@@ -1334,7 +1334,7 @@ struct RowView: View {
|
|||||||
} content: {
|
} content: {
|
||||||
VStack(alignment: .leading, spacing: 6) {
|
VStack(alignment: .leading, spacing: 6) {
|
||||||
PreBox(text: input)
|
PreBox(text: input)
|
||||||
ToolResult(result: row.result, unfinished: row.unfinished, started: row.started)
|
ToolResult(result: row.result, unfinished: row.unfinished, held: row.held, started: row.started)
|
||||||
}
|
}
|
||||||
.padding(.vertical, 6)
|
.padding(.vertical, 6)
|
||||||
}
|
}
|
||||||
@@ -1350,7 +1350,7 @@ struct RowView: View {
|
|||||||
ForEach(row.body!.rows) { child in
|
ForEach(row.body!.rows) { child in
|
||||||
RowView(row: child, model: model, nested: true)
|
RowView(row: child, model: model, nested: true)
|
||||||
}
|
}
|
||||||
ToolResult(result: row.result, unfinished: row.unfinished, started: row.started)
|
ToolResult(result: row.result, unfinished: row.unfinished, held: row.held, started: row.started)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1703,11 +1703,14 @@ private struct DiscussItem: View {
|
|||||||
private struct ToolResult: View {
|
private struct ToolResult: View {
|
||||||
let result: String?
|
let result: String?
|
||||||
let unfinished: Bool
|
let unfinished: Bool
|
||||||
|
let held: Bool
|
||||||
let started: Date?
|
let started: Date?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if let result {
|
if let result {
|
||||||
PreBox(text: result)
|
PreBox(text: result)
|
||||||
|
} else if held {
|
||||||
|
label("held by pause")
|
||||||
} else if unfinished || started == nil {
|
} else if unfinished || started == nil {
|
||||||
label(unfinished ? "no result" : "running…")
|
label(unfinished ? "no result" : "running…")
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ final class Row: Identifiable {
|
|||||||
var tag = false
|
var tag = false
|
||||||
var result: String?
|
var result: String?
|
||||||
var unfinished = false
|
var unfinished = false
|
||||||
|
var held = false
|
||||||
var started: Date?
|
var started: Date?
|
||||||
var status = "starting…"
|
var status = "starting…"
|
||||||
var statusState = SubagentState.running
|
var statusState = SubagentState.running
|
||||||
@@ -97,7 +98,7 @@ final class Row: Identifiable {
|
|||||||
var pending: Bool {
|
var pending: Bool {
|
||||||
switch kind {
|
switch kind {
|
||||||
case .tool, .subagent:
|
case .tool, .subagent:
|
||||||
return result == nil && !unfinished
|
return result == nil && !unfinished && !held
|
||||||
case .group:
|
case .group:
|
||||||
return body!.rows.contains { $0.pending }
|
return body!.rows.contains { $0.pending }
|
||||||
default:
|
default:
|
||||||
@@ -590,6 +591,18 @@ final class TranscriptBuilder {
|
|||||||
ctx.questions[item.id]?.question = item
|
ctx.questions[item.id]?.question = item
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if ev.kind == "agent.held" {
|
||||||
|
ctx.tools[jsString(p["tool_use_id"])]?.held = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ev.kind == "session.paused" {
|
||||||
|
if !bool(p, "paused") {
|
||||||
|
for tool in ctx.tools.values {
|
||||||
|
tool.held = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
let sub = ctx.subagents[parent]
|
let sub = ctx.subagents[parent]
|
||||||
if ev.kind == "agent.tool_call" && isSubagentCall(p) {
|
if ev.kind == "agent.tool_call" && isSubagentCall(p) {
|
||||||
let row = renderSubagent(p, parent)
|
let row = renderSubagent(p, parent)
|
||||||
|
|||||||
Reference in New Issue
Block a user