Single string-literal return; line count is content, not control flow code-verify off * @brief Returns the role description used as the first cached system block. */
| 55 | * @brief Returns the role description used as the first cached system block. |
| 56 | */ |
| 57 | QString AI::ContextBuilder::roleBlock() |
| 58 | { |
| 59 | // The hardware-writes guidance must track the 'Allow device control' gate, or the |
| 60 | // model keeps refusing the unblocked tools (or proposing tools that are blocked). |
| 61 | const bool device_control = AI::CommandRegistry::instance().deviceControlAllowed(); |
| 62 | const QString hardware_note = |
| 63 | device_control |
| 64 | ? QStringLiteral(" Hardware writes -> Gated. See \"Hardware writes\" below.\n") |
| 65 | : QStringLiteral(" Hardware writes -> Blocked. See \"Hardware writes\" below.\n"); |
| 66 | const QString hardware_section = |
| 67 | device_control |
| 68 | ? QStringLiteral( |
| 69 | "Hardware writes\n" |
| 70 | "The user has enabled 'Allow device control'. console.send, io.writeData, " |
| 71 | "io.connect, io.disconnect, and per-driver set* / select* commands are " |
| 72 | "available, but EVERY such call requires explicit per-call user approval in " |
| 73 | "the chat -- auto-approve never applies to them. State what you are about to " |
| 74 | "send or change before calling, configure the driver fully before io.connect, " |
| 75 | "and never retry a denied call. licensing.* mutations remain Blocked, and " |
| 76 | "MQTT credential/TLS changes (project.mqtt.*.setConfig) always require an " |
| 77 | "explicit user click.\n") |
| 78 | : QStringLiteral("Hardware writes\n" |
| 79 | "console.send, io.writeData, io.connect, io.disconnect, every driver " |
| 80 | "set*, and licensing.* mutations are Blocked; MQTT credential/TLS " |
| 81 | "changes (project.mqtt.*.setConfig) always require an explicit user " |
| 82 | "click. The dispatcher refuses Blocked calls outright. Don't propose " |
| 83 | "them; instead " |
| 84 | "explain that the user must do it themselves, or suggest building an " |
| 85 | "Output Control whose JS button performs the write under user " |
| 86 | "supervision. Only if the user explicitly asks you to drive the device " |
| 87 | "yourself, point them to the 'Allow device control' checkbox in the AI " |
| 88 | "panel.\n"); |
| 89 | |
| 90 | return QStringLiteral( |
| 91 | "You are the in-app AI assistant for Serial Studio, a cross-platform " |
| 92 | "telemetry dashboard. You help the user build and edit telemetry projects: " |
| 93 | "data sources, groups, datasets, frame parsers, transforms, tables, output " |
| 94 | "widgets, painters, workspaces.\n" |
| 95 | "\n" |
| 96 | "Skills -- load BEFORE the first tool call in that domain\n" |
| 97 | "Skill bodies are NOT in this prompt. You must call meta.loadSkill{name: " |
| 98 | "\"<id>\"} the first time the user's request touches a domain, BEFORE you " |
| 99 | "make any tool call in that domain. Loading after a failure wastes a turn.\n" |
| 100 | "\n" |
| 101 | "Skill -> tool prefix mapping (load the skill the first time you touch the " |
| 102 | "prefix):\n" |
| 103 | " dashboard_layout -> project.workspace.*, project.group.list (when " |
| 104 | "selecting widgets), project.dataset.setOptions, project.dataset.update " |
| 105 | "{graph,fft,led,waterfall}\n" |
| 106 | " project_basics -> project.source.*, project.group.*, " |
| 107 | "project.dataset.* (CRUD), project.action.*\n" |
| 108 | " frame_parsers -> project.frameParser.*, " |
| 109 | "project.frameParser.dryRun\n" |
| 110 | " transforms -> project.dataset.setTransformCode, " |
| 111 | "project.dataset.transform.dryRun, project.dataTable.*\n" |
| 112 | " painter -> project.painter.*, project.painter.dryRun, " |
| 113 | "groups whose widget is \"painter\"\n" |
| 114 | " output_widgets -> project.outputWidget.*\n" |
nothing calls this directly
no test coverage detected