Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0f2e8f2
Initial plan
Copilot Sep 1, 2026
246403c
Fix shard-summary routing precedence for invalid summaries
Copilot Sep 1, 2026
6861cf7
Guard TBB backend build path when headers are unavailable
Copilot Sep 1, 2026
defb9c3
Respect explicit Vulkan disable in GPU auto-detect
Copilot Sep 1, 2026
84cc481
Respect explicit Vulkan disable in GPU auto-detect
Copilot Sep 1, 2026
6ddd2a3
Guard TBB usage in field encryption fallback path
Copilot Sep 1, 2026
55baf70
Add TBB-free concurrent cache fallback for missing headers
Copilot Sep 1, 2026
8783e21
Continue build blocker remediation without broadening scope
Copilot Sep 1, 2026
a7adbfd
Continue validating the pugixml CMake fix
Copilot Sep 2, 2026
447b9fe
Fix modular CMake link propagation for external deps
Copilot Sep 2, 2026
80b727f
Changes before error encountered
Copilot Sep 2, 2026
866c2da
Apply remaining changes
Copilot Sep 2, 2026
64bc942
Wire missing LLM and gRPC adapter sources into monolithic build
Copilot Sep 2, 2026
d64c7e1
Fix shard protobuf wiring for modular build
Copilot Sep 2, 2026
a0ee55a
Merge develop into PR branch to resolve conflicts
Copilot Sep 2, 2026
74be4e3
fix(ci): use valid ai-inference action ref in automation workflow
Copilot Sep 2, 2026
229719e
fix(ci): harden TruffleHog install in gate-pr-core
Copilot Sep 2, 2026
548f51a
fix: avoid false Doxygen declaration findings in scanner
Copilot Sep 2, 2026
3e63d70
fix(ci): pin ai-inference action in automation community workflow
Copilot Sep 2, 2026
14cef57
docs: satisfy doxygen governance requirements in changed headers
Copilot Sep 2, 2026
fbf8930
Fix RocksDB token blacklist DB open signature
Copilot Sep 2, 2026
735f34a
Fix RocksDB DB::Open call sites for DB** API
Copilot Sep 2, 2026
1a6437c
Merge remote-tracking branch 'origin/develop' into copilot/fix-chroni…
Copilot Sep 2, 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
2 changes: 1 addition & 1 deletion .github/actions/setup-cpp-build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ runs:
# Base packages required by every C++ CI job. Vulkan/GLSL tooling is
# required for ThemisDB's GPU backend checks in Linux CI and local
# validation runs that configure the Vulkan-capable build presets.
BASE_PKGS="cmake ninja-build ${{ inputs.cc }} ${{ inputs.cxx }} libgtest-dev pkg-config git libfmt-dev libboost-dev libboost-filesystem-dev libvulkan-dev glslc"
BASE_PKGS="cmake ninja-build ${{ inputs.cc }} ${{ inputs.cxx }} libgtest-dev pkg-config git libfmt-dev libboost-dev libboost-filesystem-dev libvulkan-dev glslc libcpp-httplib-dev"
# Append optional extra packages (guard against empty string)
EXTRA="${{ inputs.extra-packages }}"
# shellcheck disable=SC2086
Expand Down
18 changes: 16 additions & 2 deletions .github/workflows/gate-pr-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -955,10 +955,24 @@ jobs:

- name: Install TruffleHog
run: |
set -euo pipefail
echo " Installing TruffleHog from official install script..."
T0=$(date +%s)
curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
| sh -s -- -b /usr/local/bin
INSTALL_OK=0
for TAG in v3.97.2 v3.97.1; do
echo " Attempting TruffleHog install for ${TAG}..."
if curl -sSfL --retry 3 --retry-all-errors --retry-delay 2 \
https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
| sh -s -- -b /usr/local/bin "${TAG}"; then
INSTALL_OK=1
break
fi
echo "::warning::TruffleHog install failed for ${TAG}; trying fallback version."
done
if [ "${INSTALL_OK}" -ne 1 ]; then
echo "::error::Unable to install TruffleHog from pinned versions."
exit 1
fi
echo " ✅ TruffleHog installed in $(( $(date +%s) - T0 ))s"
echo " Version: $(trufflehog --version 2>&1 || echo 'N/A')"

Expand Down
247 changes: 153 additions & 94 deletions cmake/CMakeLists.txt

Large diffs are not rendered by default.

30 changes: 24 additions & 6 deletions cmake/Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -690,14 +690,32 @@ else()
endif()
endif()

# Boost: Try CONFIG first, fall back to MODULE if not found
## Prefer vcpkg-provided Boost CMake config to avoid ABI/version mismatches.
## Require a compatible Boost (>= 1.70) built and provided via vcpkg/toolchain.
find_package(Boost 1.70 CONFIG REQUIRED COMPONENTS system filesystem)
# Boost: try CONFIG first (vcpkg), then fall back to MODULE (system packages)
## Prefer vcpkg-provided Boost CMake config to avoid ABI/version mismatches,
## but allow system package installations that expose Boost via FindBoost.cmake.
if(POLICY CMP0167)
cmake_policy(SET CMP0167 NEW)
endif()

set(_themis_boost_mode "")
find_package(Boost 1.70 CONFIG QUIET COMPONENTS system filesystem)
if(Boost_FOUND)
message(STATUS "Boost found via CONFIG: ${Boost_VERSION} (Boost_DIR=${Boost_DIR})")
set(_themis_boost_mode "CONFIG")
else()
find_package(Boost 1.70 MODULE QUIET COMPONENTS system filesystem)
if(Boost_FOUND)
set(_themis_boost_mode "MODULE")
endif()
endif()

if(Boost_FOUND)
if(_themis_boost_mode STREQUAL "CONFIG")
message(STATUS "Boost found via CONFIG: ${Boost_VERSION} (Boost_DIR=${Boost_DIR})")
else()
message(STATUS "Boost found via MODULE: ${Boost_VERSION}")
endif()
else()
message(FATAL_ERROR "Boost (>=1.70) not found via CONFIG mode. Ensure vcpkg is installed and the triplet matches the build (VCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET}). Run: vcpkg install boost-filesystem boost-system --triplet ${VCPKG_TARGET_TRIPLET}")
message(FATAL_ERROR "Boost (>=1.70) not found. Ensure vcpkg is installed and the triplet matches the build (VCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET}), or install system packages such as libboost-filesystem-dev and libboost-system-dev")
endif()

find_package(Threads REQUIRED)
Expand Down
32 changes: 25 additions & 7 deletions cmake/ModularBuild.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2240,22 +2240,40 @@ function(themis_build_modular)
OpenSSL::SSL
OpenSSL::Crypto
)
# Ensure pugixml is found before checking for its targets
# (this module may be included before find_package(pugixml) is called in CMakeLists.txt)
if(NOT TARGET pugixml::shared AND NOT TARGET pugixml::pugixml AND NOT TARGET pugixml::static AND NOT TARGET pugixml)
find_package(pugixml CONFIG QUIET)
# Ensure pugixml is discovered even when the package is only available via
# pkg-config or a system library path. This keeps security builds resilient
# in CI/container environments that do not expose a CMake config package.
if(NOT TARGET pugixml::shared AND NOT TARGET pugixml::pugixml AND NOT TARGET pugixml::static AND NOT TARGET pugixml)
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
pkg_check_modules(PUGIXML QUIET pugixml)
endif()
if(pugixml_FOUND AND NOT TARGET pugixml::pugixml AND NOT TARGET pugixml::static AND NOT TARGET pugixml)
find_path(PUGIXML_INCLUDE_DIR NAMES pugixml.hpp PATH_SUFFIXES include)
find_library(PUGIXML_LIB NAMES pugixml libpugixml)

if(PUGIXML_FOUND AND NOT TARGET pugixml::pugixml AND NOT TARGET pugixml::static AND NOT TARGET pugixml)
find_path(PUGIXML_INCLUDE_DIR NAMES pugixml.hpp HINTS ${PUGIXML_INCLUDE_DIRS} PATH_SUFFIXES include)
find_library(PUGIXML_LIB NAMES pugixml libpugixml HINTS ${PUGIXML_LIBRARY_DIRS})
if(PUGIXML_INCLUDE_DIR AND PUGIXML_LIB)
add_library(pugixml UNKNOWN IMPORTED)
set_target_properties(pugixml PROPERTIES
IMPORTED_LOCATION "${PUGIXML_LIB}"
INTERFACE_INCLUDE_DIRECTORIES "${PUGIXML_INCLUDE_DIR}")
add_library(pugixml::pugixml ALIAS pugixml)
endif()
elseif(NOT TARGET pugixml::pugixml AND NOT TARGET pugixml::static AND NOT TARGET pugixml)
find_package(pugixml CONFIG QUIET)
if(pugixml_FOUND)
find_path(PUGIXML_INCLUDE_DIR NAMES pugixml.hpp PATH_SUFFIXES include)
find_library(PUGIXML_LIB NAMES pugixml libpugixml)
if(PUGIXML_INCLUDE_DIR AND PUGIXML_LIB)
add_library(pugixml UNKNOWN IMPORTED)
set_target_properties(pugixml PROPERTIES
IMPORTED_LOCATION "${PUGIXML_LIB}"
INTERFACE_INCLUDE_DIRECTORIES "${PUGIXML_INCLUDE_DIR}")
add_library(pugixml::pugixml ALIAS pugixml)
endif()
endif()
endif()
endif()
if(TARGET TBB::tbb)
list(APPEND _themis_security_deps TBB::tbb)
endif()
Expand Down
4 changes: 1 addition & 3 deletions include/auth/rocksdb_token_blacklist.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,7 @@ class RocksDBTokenBlacklist final : public ITokenBlacklist {
Config config_;

// RocksDB state
// RocksDB newer distributions install Open()/OpenForReadOnly() overloads
// that accept a `std::unique_ptr<rocksdb::DB>*` for ownership. Use
// unique_ptr here to match those APIs and ensure RAII cleanup.
// DB ownership is managed with unique_ptr for RAII cleanup.
std::unique_ptr<rocksdb::DB> db_{nullptr};
rocksdb::ColumnFamilyHandle* cf_{nullptr};

Expand Down
2 changes: 1 addition & 1 deletion include/cache/enhanced_query_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include <functional>
#include <optional>
#include <algorithm>
#include <tbb/concurrent_hash_map.h>
#include "utils/tbb_compat.h"

namespace themis {
namespace cache {
Expand Down
95 changes: 77 additions & 18 deletions include/llm/prompt_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include <vector>
#include <optional>
#include <mutex>
#include <tbb/concurrent_hash_map.h> // v1.1.0: TBB Concurrent Hash Map
#include "utils/tbb_compat.h" // Fallback for environments without Intel TBB
#include <nlohmann/json.hpp>
// Forward declaration
namespace rocksdb { class ColumnFamilyHandle; }
Expand All @@ -26,9 +26,16 @@ namespace themis {
class RocksDBWrapper;
class SchemaManager;

/** @brief Prompt manager component. */
/**
* @brief Manages prompt templates in-memory with optional RocksDB persistence.
*/

class PromptManager {
public:
/**
* @brief Persistent representation of a prompt template.
*/

struct PromptTemplate {
std::string id; // generated id
std::string name; // human readable name
Expand All @@ -38,6 +45,11 @@ class PromptManager {
nlohmann::json metadata; // arbitrary metadata (experiment flags etc.)
bool active = true;

/**
* @brief Serializes this prompt template into JSON.
* @return JSON object containing all prompt template fields.
*/

nlohmann::json toJson() const {
nlohmann::json j;
j["id"] = id;
Expand All @@ -51,46 +63,93 @@ class PromptManager {
}
};

// In-memory only manager
/**
* @brief Constructs an in-memory prompt manager.
*/
PromptManager();

// RocksDB-backed manager (does not take ownership of db or cf)
/**
* @brief Constructs a prompt manager backed by RocksDB handles.
* @param db Non-owning pointer to the RocksDB wrapper.
* @param cf Non-owning pointer to the column family used for prompt records.
*/
PromptManager(RocksDBWrapper* db, rocksdb::ColumnFamilyHandle* cf = nullptr);

/**
* @brief Destroys the prompt manager.
*/
~PromptManager() = default;

// Create a template; if template.id empty one is generated
/**
* @brief Creates a prompt template entry.
* @param t Template to store; an id is generated when empty.
* @return Stored prompt template including generated fields.
*/
PromptTemplate createTemplate(PromptTemplate t);

// Retrieve template by id
/**
* @brief Retrieves a template by id.
* @param id Template id to look up.
* @return Found template or std::nullopt when no template exists for id.
*/
std::optional<PromptTemplate> getTemplate(const std::string& id) const;

// List all templates
/**
* @brief Lists all known templates.
* @return Snapshot vector of all stored templates.
*/
std::vector<PromptTemplate> listTemplates() const;

// Update metadata/active flag of template; returns false if not found
/**
* @brief Updates metadata and active flag for an existing template.
* @param id Template id to update.
* @param metadata Metadata payload to store.
* @param active New active flag value.
* @return true when the template exists and was updated, otherwise false.
*/
bool updateTemplate(const std::string& id, const nlohmann::json& metadata, bool active);

// Assign an experiment id to a template (stores in metadata["experiment_id"])
/**
* @brief Assigns an experiment id to a template.
* @param id Template id to update.
* @param experiment_id Experiment identifier to store in metadata.
* @return true when the template exists and was updated, otherwise false.
*/
bool assignExperiment(const std::string& id, const std::string& experiment_id);

// Load prompts from YAML configuration file
// Returns number of prompts loaded successfully
/**
* @brief Loads prompt templates from a YAML configuration file.
* @param yaml_path Path to the YAML file.
* @return Number of templates loaded successfully.
*/
size_t loadFromYAML(const std::string& yaml_path);

// Inject context variables into a prompt template
// Replaces {variable} with values from context map
// Example: "{version}" -> "1.5.0", "{table_count}" -> "5"
/**
* @brief Injects context variables into a template string.
* @param template_str Template source text containing {variable} placeholders.
* @param context Mapping from placeholder key to replacement value.
* @return Prompt text with placeholder substitutions applied.
*/
std::string injectContext(const std::string& template_str,
const std::unordered_map<std::string, std::string>& context) const;

// Get a prompt with context injection
// Retrieves template by id and injects context variables
/**
* @brief Retrieves a template and returns context-injected prompt text.
* @param id Template id to render.
* @param context Mapping from placeholder key to replacement value.
* @return Rendered prompt text or std::nullopt when the template is absent.
*/
std::optional<std::string> getPromptWithContext(
const std::string& id,
const std::unordered_map<std::string, std::string>& context) const;

// Build context map from SchemaManager
// Creates standard context variables: {version}, {table_count}, {schema}, etc.
/**
* @brief Builds standard prompt context variables from schema metadata.
* @param schema_mgr Schema manager used to derive schema-dependent variables.
* @param edition Product edition label used in context fields.
* @param version Product version string used in context fields.
* @return Context map containing canonical keys such as version and schema data.
*/
static std::unordered_map<std::string, std::string> buildContextFromSchema(
SchemaManager* schema_mgr,
const std::string& edition = "Community",
Expand Down
Loading