Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e2bf083
feat(#1001): AI agent harness — AIAgentManager state machine, capabil…
fernandotonon Sep 17, 2026
c78d76c
fix(#1021e): recommended GGUF list — verified single-file URLs, non-t…
fernandotonon Sep 17, 2026
6b81e16
fix(#1052): review round — always-on tool dispatcher, replan capacity…
fernandotonon Sep 17, 2026
ac10785
fix(#1052): review round 2 — cancel inside a tool call, idempotent fi…
fernandotonon Sep 17, 2026
be16f72
refactor(#1052): SonarCloud pass — split the complexity hotspots, fix…
fernandotonon Sep 17, 2026
a2e21cf
fix(#1052): review round 3 — integer range + array item validation; S…
fernandotonon Sep 17, 2026
650f51c
feat(#1052): conversation memory, select_entity tool, colour-name coe…
fernandotonon Sep 17, 2026
bbd6c29
fix(#1052): argument aliases before rejection; replan sees the failin…
fernandotonon Sep 17, 2026
1f84ed5
fix(#1052): review round 4 — colour names only on colour properties, …
fernandotonon Sep 17, 2026
c36f266
refactor(#1052): split alias normalisation and scene-info listing int…
fernandotonon Sep 17, 2026
12ead0d
refactor(#1052): extract checkRequired from validateArguments (Sonar …
fernandotonon Sep 17, 2026
7ed348a
fix(#1052): "Failed to decode prompt" — budget prompts against the mo…
fernandotonon Sep 17, 2026
e60002e
fix(#1052): model tip showed for every model (static Q_INVOKABLE unre…
fernandotonon Sep 17, 2026
3e6d35e
feat(#1052): meshes are not images (tool + validator); delete LLM fil…
fernandotonon Sep 17, 2026
0616c00
feat(#1052): Delete Selected / Remove All / Open Folder on the LLM Do…
fernandotonon Sep 17, 2026
599bfad
test: follow the 8192 default context size (LLMWorker default, manage…
fernandotonon Sep 17, 2026
aa33574
fix(#1052): chat input regains focus after the app was deactivated
fernandotonon Sep 17, 2026
83d197d
fix(#1052): a repeated need_capabilities for docs the model already h…
fernandotonon Sep 17, 2026
f35d349
fix(#1052): cloud_upload / cloud_login / cloud_logout ask for confirm…
fernandotonon Sep 17, 2026
b766bc9
fix(#1052): review round — deferred active-model deletion, .bin bulk …
fernandotonon Sep 17, 2026
148e7ad
fix(#1052): an invented image path becomes the text prompt instead of…
fernandotonon Sep 17, 2026
4500987
fix(#1052): heavy tools report progress and keep the UI painting inst…
fernandotonon Sep 17, 2026
22dcced
fix(#1052): Stop actually stops a running heavy tool; screenshot over…
fernandotonon Sep 17, 2026
7390db6
fix(#1052): the focus test asserted an event Qt only delivers in an a…
fernandotonon Sep 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ Split View|Skeleton Animation Controls
- **AI part segmentation & PartOps** — detect a character's parts (head/torso/arms/legs), then **split** into named submeshes, **explode** into separate scene nodes, **join** them back, or **solidify** thin-shell parts; GUI + `qtmesh segment --split-parts / --explode-parts` + MCP (`split_mesh_by_segments`, `explode_mesh_parts`, `join_mesh_parts`) — see [docs/PART_OPS.md](docs/PART_OPS.md)
- **Scene management** — duplicate (Ctrl+D), group (Ctrl+G), snap, pivot modes
- **Performance capture** — video/webcam → facial morph animation (ARKit blendshapes), head pose, and full-body skeletal capture onto humanoid rigs; live preview + record in the editor, `qtmesh mocap` on the CLI (`-DENABLE_MOCAP` builds)
- **AI chat** — natural language scene editing via local LLMs
- **AI agent** — describe a task in natural language; a local LLM plans it over the editor's tools, runs it step by step with structured observations and replanning, groups it into ONE undo step, and asks before deleting or overwriting (agent mode; the simple chat loop is one click away)
- **MCP server** — 57+ tools for AI agents (Claude, Cursor, etc.), including HDR/IBL (`set_hdr_environment`, `set_tonemap`, …) and QtMesh Cloud (`cloud_*`)
- **REST API** — opt-in HTTP interface for external automation (`--with-mcp --http-port 8080`). Bound to **localhost** by default; tools execute only via `POST /api/tools/<name>` (`GET /api/tools` lists them); set `QTMESH_HTTP_TOKEN` (or `--http-token-file <path>`; a secret on the command line is refused, since `ps` shows it to every local user) to require `Authorization: Bearer <token>` on every request, and `--http-bind 0.0.0.0` only when you mean to expose it

Expand Down
337 changes: 310 additions & 27 deletions qml/AIChatPanel.qml

Large diffs are not rendered by default.

71 changes: 66 additions & 5 deletions qml/AISettingsDialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Dialog {
property color buttonTextColor: palette.buttonText
property string pendingDeleteModelId: ""
property string pendingDeleteModelName: ""
property string pendingDeleteLlmFile: ""
property string pendingDeleteLlmName: ""

SystemPalette {
id: palette
Expand Down Expand Up @@ -224,11 +226,25 @@ Dialog {

Item { Layout.preferredHeight: 8 }

Text {
text: "Recommended Models"
font.pointSize: 12
font.bold: true
color: textColor
RowLayout {
Layout.fillWidth: true
spacing: 10
Text {
Layout.fillWidth: true
text: "Recommended Models"
font.pointSize: 12
font.bold: true
color: textColor
}
Local.ThemedButton {
text: "Remove All"
enabled: !ModelDownloader.isDownloading && LLMManager.availableModels.length > 0
onClicked: removeAllLlmModelsDialog.open()
}
Local.ThemedButton {
text: "Open Folder"
onClicked: Qt.openUrlExternally(LLMManager.modelsDirectoryUrl)
}
}

ListView {
Expand Down Expand Up @@ -279,6 +295,19 @@ Dialog {
color: modelData.isDownloaded ? "#4caf50" : Qt.darker(textColor, 1.5)
}
}

// Same affordance as the QtMeshEditor Models tab: free the disk
// space of a downloaded GGUF (unloads it first if it is active).
Local.ThemedButton {
text: "Delete"
visible: modelData.isDownloaded
enabled: !ModelDownloader.isDownloading
onClicked: {
aiSettingsDialog.pendingDeleteLlmFile = modelData.fileName
aiSettingsDialog.pendingDeleteLlmName = modelData.name
removeLlmModelDialog.open()
}
}
}
}

Expand Down Expand Up @@ -993,6 +1022,38 @@ Dialog {
}
}

Dialog {
id: removeLlmModelDialog
title: "Delete Model File"
modal: true
anchors.centerIn: parent
standardButtons: Dialog.Yes | Dialog.No
onAccepted: LLMManager.deleteModelFile(aiSettingsDialog.pendingDeleteLlmFile)

Text {
width: 360
text: "Delete " + aiSettingsDialog.pendingDeleteLlmName + " (" + aiSettingsDialog.pendingDeleteLlmFile + ") from the models folder? It is unloaded first if it is the active model."
color: textColor
wrapMode: Text.WordWrap
}
}

Dialog {
id: removeAllLlmModelsDialog
title: "Remove All LLM Files"
modal: true
anchors.centerIn: parent
standardButtons: Dialog.Yes | Dialog.No
onAccepted: LLMManager.deleteAllModelFiles()

Text {
width: 360
text: "Remove every downloaded GGUF model (" + LLMManager.availableModels.length + " file(s)) from the models folder? The active model is unloaded first."
color: textColor
wrapMode: Text.WordWrap
}
}

Dialog {
id: removeQtMeshModelDialog
title: "Delete Model Files"
Expand Down
Loading
Loading