@brief Returns a compact name+description list of every command, optionally * filtered by prefix and windowed by offset/limit (limit 0 = all). */
| 1942 | /** @brief Returns a compact name+description list of every command, optionally |
| 1943 | * filtered by prefix and windowed by offset/limit (limit 0 = all). */ |
| 1944 | QJsonObject AI::ToolDispatcher::listCommands(const QString& prefix, int offset, int limit) const |
| 1945 | { |
| 1946 | const auto& commands = API::CommandRegistry::instance().commands(); |
| 1947 | const auto& aiReg = AI::CommandRegistry::instance(); |
| 1948 | |
| 1949 | QJsonArray entries; |
| 1950 | auto appendVirtual = [&entries, &prefix](const QVector<detail::AssistantToolDef>& defs) { |
| 1951 | for (const auto& def : defs) { |
| 1952 | if (!prefix.isEmpty() && !def.name.startsWith(prefix)) |
| 1953 | continue; |
| 1954 | |
| 1955 | QJsonObject row; |
| 1956 | row[QStringLiteral("name")] = def.name; |
| 1957 | row[QStringLiteral("description")] = def.description; |
| 1958 | entries.append(row); |
| 1959 | } |
| 1960 | }; |
| 1961 | appendVirtual(assistantToolDefs()); |
| 1962 | appendVirtual(fsToolDefs()); |
| 1963 | appendVirtual(metaToolRoster()); |
| 1964 | |
| 1965 | for (auto it = commands.constBegin(); it != commands.constEnd(); ++it) { |
| 1966 | const auto& def = it.value(); |
| 1967 | if (aiReg.safetyOf(def.name) == Safety::Blocked) |
| 1968 | continue; |
| 1969 | |
| 1970 | if (!prefix.isEmpty() && !def.name.startsWith(prefix)) |
| 1971 | continue; |
| 1972 | |
| 1973 | QJsonObject row; |
| 1974 | row[QStringLiteral("name")] = def.name; |
| 1975 | row[QStringLiteral("description")] = def.description; |
| 1976 | entries.append(row); |
| 1977 | } |
| 1978 | |
| 1979 | const int total = entries.size(); |
| 1980 | const int start = qBound(0, offset, total); |
| 1981 | const int count = limit > 0 ? qMin(limit, total - start) : total - start; |
| 1982 | |
| 1983 | QJsonArray window; |
| 1984 | for (int i = start; i < start + count; ++i) |
| 1985 | window.append(entries.at(i)); |
| 1986 | |
| 1987 | QJsonObject reply; |
| 1988 | reply[QStringLiteral("ok")] = true; |
| 1989 | reply[QStringLiteral("total")] = total; |
| 1990 | reply[QStringLiteral("count")] = window.size(); |
| 1991 | reply[QStringLiteral("commands")] = window; |
| 1992 | if (start + count < total) |
| 1993 | reply[QStringLiteral("nextOffset")] = start + count; |
| 1994 | |
| 1995 | return reply; |
| 1996 | } |
| 1997 | |
| 1998 | /** |
| 1999 | * @brief Returns the curated one-line description for each top-level command scope. |
no test coverage detected