import QtQuick import QtQuick.Controls import QtQuick.Layouts Dialog { id: root objectName: "taskControlDialog" title: "Task control and jobs" modal: true standardButtons: Dialog.Close width: Math.min(760, parent ? parent.width - 24 : 760) height: Math.min(640, parent ? parent.height - 24 : 640) property var state: ({}) function refresh() { try { state = JSON.parse(agent.taskState()) } catch (e) { state = ({}) } } onOpened: { refresh(); config.text = agent.workerConfig() } Timer { interval: 500; repeat: true; running: root.visible; onTriggered: root.refresh() } ColumnLayout { anchors.fill: parent TabBar { id: tabs Layout.fillWidth: true TabButton { text: "Task / Jobs" } TabButton { text: "Models" } TabButton { text: "Integration" } } StackLayout { Layout.fillWidth: true Layout.fillHeight: true currentIndex: tabs.currentIndex ColumnLayout { Label { Layout.fillWidth: true; wrapMode: Text.Wrap; text: (root.state.goal || "No active goal") } Label { text: "Revision " + (root.state.revision || 0) + " · " + (root.state.status || "idle") + " · " + (root.state.cancel_source || "") } RowLayout { CheckBox { id: readonly objectName: "taskReadOnly" text: "Read only" checked: !!root.state.read_only onClicked: agent.taskControl(checked, !direct.checked, !!root.state.paused) } CheckBox { id: direct objectName: "taskMainOnly" text: "Main agent only" checked: root.state.delegation === false onClicked: agent.taskControl(readonly.checked, !checked, !!root.state.paused) } Button { text: root.state.paused ? "Resume" : "Pause"; onClicked: agent.taskControl(readonly.checked, !direct.checked, !root.state.paused) } } ScrollView { Layout.fillWidth: true Layout.fillHeight: true ColumnLayout { width: parent.width Repeater { model: root.state.jobs || [] Frame { required property var modelData Layout.fillWidth: true ColumnLayout { anchors.fill: parent Label { text: modelData.job_id + " · " + modelData.kind + " · " + modelData.status } Label { Layout.fillWidth: true; text: modelData.resource || ""; elide: Text.ElideMiddle } Label { Layout.fillWidth: true; wrapMode: Text.Wrap; text: (modelData.output || "").slice(-1000) } RowLayout { Button { text: "Cancel"; enabled: modelData.status === "running" || modelData.status === "queued"; onClicked: agent.cancelJob(modelData.job_id, false) } Button { text: "Force stop"; visible: modelData.status === "running_protected"; onClicked: agent.cancelJob(modelData.job_id, true) } Button { text: "Review delta"; visible: (modelData.resource || "").indexOf("/.agent/v2/wt-") >= 0; onClicked: { worktree.text = modelData.resource; tabs.currentIndex = 2 } } } } } } } } } ColumnLayout { Label { text: "Role model profiles and budgets (provider credentials stay separate)"; wrapMode: Text.Wrap; Layout.fillWidth: true } ScrollView { Layout.fillWidth: true; Layout.fillHeight: true; TextArea { id: config; wrapMode: TextEdit.Wrap; selectByMouse: true } } Label { id: configStatus; Layout.fillWidth: true; wrapMode: Text.Wrap } Button { text: "Save model configuration"; enabled: !agent.running; onClicked: { const e = agent.saveWorkerConfig(config.text); configStatus.text = e.length ? e : "Saved" } } } ColumnLayout { TextField { id: worktree; Layout.fillWidth: true; placeholderText: "Worker worktree path" } RowLayout { Button { text: "Preview"; enabled: !agent.running; onClicked: delta.text = agent.worktreeDiff(worktree.text, false) } Button { text: "Integrate reviewed delta"; enabled: !agent.running; onClicked: delta.text = agent.worktreeDiff(worktree.text, true) } } ScrollView { Layout.fillWidth: true; Layout.fillHeight: true; TextArea { id: delta; readOnly: true; wrapMode: TextEdit.Wrap; selectByMouse: true } } } } } }