// NewAgentDialog.qml — Dialog for creating a new agent in a session import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 Dialog { id: root title: editMode ? "Agent Settings" : "New Agent" width: 420 modal: false x: (parent ? (parent.width - width) / 2 : 0) y: (parent ? (parent.height - height) / 2 : 0) // Keep the non-modal dialog visually separate from the application behind it. background: Item { // A dark offset layer reads as a shadow instead of a bright outline. Rectangle { x: 4 y: 6 width: parent.width height: parent.height color: Qt.rgba(0, 0, 0, 0.28) radius: 4 } Rectangle { anchors.fill: parent color: theme.windowColor border.color: theme.dialogOutlineColor border.width: 3 radius: 4 Rectangle { anchors.fill: parent anchors.margins: 3 color: "transparent" border.color: theme.lightColor border.width: 1 radius: 3 } } } header: Rectangle { implicitHeight: 36 color: theme.buttonColor Text { anchors.centerIn: parent; text: root.title; color: theme.buttonTextColor } MouseArea { anchors.fill: parent cursorShape: Qt.SizeAllCursor property point pressPosition onPressed: pressPosition = Qt.point(mouse.x, mouse.y) onPositionChanged: if (pressed) { root.x += mouse.x - pressPosition.x root.y += mouse.y - pressPosition.y } } } // Session ID to create the agent in property string targetSessionId: "" // Mode: false = create, true = edit existing agent property bool editMode: false property string editAgentId: "" // Store original config when opened in edit mode for diffing on save. property var _originalConfig: ({}) // Inherited session working directory, shown as the Directory placeholder. property string _inheritedCwd: "" signal agentCreated() // Open in edit mode for an existing agent. function openForAgent(sessionId, agentId) { editMode = true targetSessionId = sessionId editAgentId = agentId open() } contentItem: ColumnLayout { spacing: 16 Layout.margins: 16 Label { text: root.editMode ? "Agent Settings" : "Agent" font.bold: true font.pointSize: theme.fontSize > 0 ? theme.fontSize + 1 : Qt.application.font.pointSize + 1 } Label { id: errorLabel Layout.fillWidth: true visible: text !== "" color: "red" wrapMode: Text.Wrap } RowLayout { Layout.fillWidth: true Label { text: "Backend:"; Layout.preferredWidth: 80 } ComboBox { id: backendCombo Layout.fillWidth: true enabled: ollie.rootBackendsLoaded model: ollie.availableBackends currentIndex: 0 editable: true onAccepted: backendCombo.editText = backendCombo.currentText } } ListModel { id: modelList } RowLayout { Layout.fillWidth: true Label { text: "Model:"; Layout.preferredWidth: 80 } ComboBox { id: modelCombo Layout.fillWidth: true enabled: backendCombo.currentIndex >= 0 && backendCombo.currentText.trim() !== "" && ollie.rootModelsLoaded model: modelList currentIndex: -1 editable: true onAccepted: modelCombo.editText = modelCombo.currentText } } RowLayout { Layout.fillWidth: true Label { text: "Profile:"; Layout.preferredWidth: 80 } ComboBox { id: agentCombo Layout.fillWidth: true enabled: ollie.rootAgentsLoaded model: ollie.availableAgents currentIndex: 0 } } RowLayout { Layout.fillWidth: true Label { text: "Name:"; Layout.preferredWidth: 80 } TextField { id: aliasField Layout.fillWidth: true placeholderText: "(auto-generated)" } } RowLayout { Layout.fillWidth: true visible: root.editMode Label { text: "Directory:"; Layout.preferredWidth: 80 } TextField { id: cwdField Layout.fillWidth: true // Empty = inherit the session working directory. The placeholder // shows the inherited path so it is clear what "empty" means. placeholderText: root._inheritedCwd !== "" ? ("(inherit: " + root._inheritedCwd + ")") : "(inherit session directory)" } Button { text: "Browse..." onClicked: { var start = cwdField.text || root._inheritedCwd || "" var folder = theme.chooseFolder("Select Agent Working Directory", start) if (folder !== "") cwdField.text = folder } } } RowLayout { Layout.fillWidth: true visible: root.editMode && cwdField.text.trim() !== "" Item { Layout.preferredWidth: 80 } Button { text: "Reset to session directory" onClicked: cwdField.text = "" } } Component.onCompleted: { if (!ollie.rootBackendsLoaded) ollie.loadRootBackends() if (!ollie.rootAgentsLoaded) ollie.loadRootAgents() } Connections { target: backendCombo function onCurrentTextChanged() { var be = backendCombo.currentText.trim() modelList.clear() if (be !== "" && ollie.rootModelsLoaded) { var models = ollie.getAvailableModels(be) for (var i = 0; i < models.length; ++i) { modelList.append({ modelData: models[i] }) } modelCombo.currentIndex = models.length > 0 ? 0 : -1 } else { modelCombo.currentIndex = -1 } } } } footer: RowLayout { Layout.fillWidth: true Item { Layout.fillWidth: true } Button { id: okButton text: root.editMode ? "Save" : "OK" onClicked: { errorLabel.text = "" var backend = backendCombo.currentText.trim() var model = modelCombo.currentIndex >= 0 ? modelCombo.currentText.trim() : modelCombo.editText.trim() var agent = agentCombo.currentText var agentAlias = aliasField.text.trim() if (root.editMode) { // Edit mode: write only the changed values back via ctl. // Profile is applied first because switching it can reset // backend/model; backend before model for the same reason. var cfg = root._originalConfig if (agent !== "" && agent !== cfg.profile) { var ep = ollie.updateAgentConfig(root.targetSessionId, root.editAgentId, "profile", agent) if (ep) { errorLabel.text = ep; return } } if (backend !== "" && backend !== cfg.backend) { var eb = ollie.updateAgentConfig(root.targetSessionId, root.editAgentId, "backend", backend) if (eb) { errorLabel.text = eb; return } } if (model !== "" && model !== cfg.model) { var em = ollie.updateAgentConfig(root.targetSessionId, root.editAgentId, "model", model) if (em) { errorLabel.text = em; return } } if (agentAlias !== "" && agentAlias !== cfg.displayName) { var en = ollie.updateAgentConfig(root.targetSessionId, root.editAgentId, "displayName", agentAlias) if (en) { errorLabel.text = en; return } } // Per-agent cwd override: empty value clears it (inherit). var cwd = cwdField.text.trim() if (cwd !== (cfg.cwdOverride || "")) { var ec = ollie.updateAgentConfig(root.targetSessionId, root.editAgentId, "cwd", cwd) if (ec) { errorLabel.text = ec; return } } ollie.refreshSessions() root.close() return } var newAgentId = ollie.createAgent(root.targetSessionId, backend, model, agent, "", agentAlias) var err = ollie.lastError() if (err === "") { // Success: refresh then switch to the newly created agent. ollie.refreshSessions() ollie.switchAgent(root.targetSessionId, newAgentId) root.agentCreated() root.close() } else { errorLabel.text = err } } } Button { text: "Cancel" onClicked: root.close() } } // Dialogs are display-only until the user clicks a field. focus: false onOpened: { errorLabel.text = "" if (!ollie.rootBackendsLoaded) ollie.loadRootBackends() if (!ollie.rootAgentsLoaded) ollie.loadRootAgents() if (editMode && targetSessionId !== "" && editAgentId !== "") { // Read current agent config and populate fields. var cfg = ollie.readAgentConfig(targetSessionId, editAgentId) _originalConfig = cfg // Backend: select or set as editable text. var beIdx = ollie.availableBackends.indexOf(cfg.backend || "") if (beIdx >= 0) backendCombo.currentIndex = beIdx backendCombo.editText = cfg.backend || "" // Rebuild the model list for this backend, then select the current model. modelList.clear() if (cfg.backend && ollie.rootModelsLoaded) { var models = ollie.getAvailableModels(cfg.backend) for (var i = 0; i < models.length; ++i) modelList.append({ modelData: models[i] }) var mIdx = models.indexOf(cfg.model || "") modelCombo.currentIndex = mIdx } else { modelCombo.currentIndex = -1 } modelCombo.editText = cfg.model || "" var prIdx = ollie.availableAgents.indexOf(cfg.profile || "") agentCombo.currentIndex = prIdx >= 0 ? prIdx : 0 aliasField.text = cfg.displayName || "" // cwd: show the override (if any) in the field; the inherited // session cwd is shown as the placeholder. _inheritedCwd = cfg.sessionCwd || "" cwdField.text = cfg.cwdOverride || "" } else { // Create mode: reset fields. aliasField.text = "" agentCombo.currentIndex = 0 modelCombo.currentIndex = -1 modelCombo.editText = "" cwdField.text = "" _inheritedCwd = "" _originalConfig = ({}) } } }