Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
47 changes: 47 additions & 0 deletions sdk/cpp/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
Language: Cpp
BasedOnStyle: Microsoft

# Match the existing project style
Standard: c++17
ColumnLimit: 120

# Indentation
IndentWidth: 4
TabWidth: 4
UseTab: Never
AccessModifierOffset: -4
IndentCaseLabels: false
NamespaceIndentation: All

# Braces
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterStruct: false
BeforeCatch: true
BeforeElse: true
IndentBraces: false

# Alignment
AlignAfterOpenBracket: Align
AlignOperands: Align
AlignTrailingComments: true

# Includes
SortIncludes: false
IncludeBlocks: Preserve

# Misc
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AllowShortBlocksOnASingleLine: Empty
PointerAlignment: Left
SpaceAfterCStyleCast: false
SpaceBeforeParens: ControlStatements
151 changes: 151 additions & 0 deletions sdk/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
cmake_minimum_required(VERSION 3.20)

# VS hot reload policy (safe-guarded)
if (POLICY CMP0141)
cmake_policy(SET CMP0141 NEW)
if (MSVC)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
"$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>")
endif()
endif()

project(CppSdk LANGUAGES CXX)

# -----------------------------
# Windows-only + compiler guard
# -----------------------------
if (NOT WIN32)
message(FATAL_ERROR "CppSdk is Windows-only for now (uses Win32/WIL headers).")
endif()

# Accept MSVC OR clang-cl (Clang in MSVC compatibility mode).
# VS CMake Open-Folder often uses clang-cl by default.
if (NOT (MSVC OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")))
message(STATUS "CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}")
message(STATUS "CMAKE_CXX_SIMULATE_ID = ${CMAKE_CXX_SIMULATE_ID}")
message(FATAL_ERROR "Need MSVC or clang-cl (MSVC-compatible toolchain).")
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Optional: target Windows 10+ APIs (adjust if you need older)
add_compile_definitions(_WIN32_WINNT=0x0A00 WINVER=0x0A00)

# -----------------------------
# Dependencies (installed via vcpkg)
# -----------------------------
find_package(nlohmann_json CONFIG REQUIRED)
find_package(wil CONFIG REQUIRED)
find_package(Microsoft.GSL CONFIG REQUIRED)
option(BUILD_TESTING "Build unit and end-to-end tests" ON)
if (BUILD_TESTING)
find_package(GTest CONFIG REQUIRED)
endif()

# -----------------------------
# SDK library (STATIC)
# List ONLY .cpp files here.
# -----------------------------
add_library(CppSdk STATIC
src/model.cpp
src/catalog.cpp
src/openai_chat_client.cpp
src/openai_audio_client.cpp
src/foundry_local_manager.cpp
)

target_include_directories(CppSdk
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)

target_link_libraries(CppSdk
PUBLIC
nlohmann_json::nlohmann_json
Microsoft.GSL::GSL
WIL::WIL
)

# -----------------------------
# Sample executable
# -----------------------------
add_executable(CppSdkSample
sample/main.cpp
)

target_link_libraries(CppSdkSample PRIVATE CppSdk)

# -----------------------------
# Unit tests
# -----------------------------
if (BUILD_TESTING)
enable_testing()

add_executable(CppSdkTests
test/parser_and_types_test.cpp
test/model_variant_test.cpp
test/catalog_test.cpp
test/client_test.cpp
)

target_include_directories(CppSdkTests
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test
${CMAKE_CURRENT_SOURCE_DIR}/src
)

target_compile_definitions(CppSdkTests PRIVATE FL_TESTS)

target_link_libraries(CppSdkTests
PRIVATE
CppSdk
GTest::gtest_main
)

# Copy testdata files next to the test executable so file-based tests can find them.
add_custom_command(TARGET CppSdkTests POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/test/testdata
$<TARGET_FILE_DIR:CppSdkTests>/testdata
)

include(GoogleTest)
gtest_discover_tests(CppSdkTests
WORKING_DIRECTORY $<TARGET_FILE_DIR:CppSdkTests>
)

# -----------------------------
# End-to-end tests (separate executable, requires Core DLL)
# Exercises the full public API against the real catalog.
# Tests that need model download are DISABLED by default;
# run with --gtest_also_run_disabled_tests locally.
# -----------------------------
add_executable(CppSdkE2ETests
test/e2e_test.cpp
)

target_include_directories(CppSdkE2ETests
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test
${CMAKE_CURRENT_SOURCE_DIR}/src
)

target_link_libraries(CppSdkE2ETests
PRIVATE
CppSdk
GTest::gtest_main
)

gtest_discover_tests(CppSdkE2ETests
WORKING_DIRECTORY $<TARGET_FILE_DIR:CppSdkE2ETests>
)
endif()

# Make Visual Studio start/debug this target by default
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
PROPERTY VS_STARTUP_PROJECT CppSdkSample)
109 changes: 109 additions & 0 deletions sdk/cpp/CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
{
"version": 6,
"configurePresets": [
{
"name": "windows-base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe",
"VCPKG_OVERLAY_TRIPLETS": "${sourceDir}/triplets"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "x64-debug",
"displayName": "MSVC x64 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"VCPKG_TARGET_TRIPLET": "x64-windows-static-md"
}
},
{
"name": "x64-release",
"displayName": "MSVC x64 Release",
"inherits": "windows-base",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"VCPKG_TARGET_TRIPLET": "x64-windows-static-md"
}
},
{
"name": "linux-debug",
"displayName": "Linux Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
}
},
{
"name": "macos-debug",
"displayName": "macOS Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
}
}
],
"buildPresets": [
{
"name": "x64-debug",
"configurePreset": "x64-debug",
"displayName": "MSVC x64 Debug Build"
},
{
"name": "x64-release",
"configurePreset": "x64-release",
"displayName": "MSVC x64 Release Build"
}
],
"testPresets": [
{
"name": "x64-debug",
"configurePreset": "x64-debug",
"displayName": "MSVC x64 Debug Tests",
"output": {
"outputOnFailure": true
}
},
{
"name": "x64-release",
"configurePreset": "x64-release",
"displayName": "MSVC x64 Release Tests",
"output": {
"outputOnFailure": true
}
}
]
}
75 changes: 75 additions & 0 deletions sdk/cpp/include/catalog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#pragma once
#include <string>
#include <string_view>
#include <vector>
#include <unordered_map>
#include <chrono>
#include <memory>
#include <mutex>

#include <gsl/pointers>
#include <gsl/span>

#include "model.h"

namespace foundry_local::Internal {
struct IFoundryLocalCore;
}

namespace foundry_local {
#ifdef FL_TESTS
namespace Testing {
struct MockObjectFactory;
}
#endif

class Catalog final {
public:
Catalog(const Catalog&) = delete;
Catalog& operator=(const Catalog&) = delete;
Catalog(Catalog&&) = delete;
Catalog& operator=(Catalog&&) = delete;

static std::unique_ptr<Catalog> Create(gsl::not_null<foundry_local::Internal::IFoundryLocalCore*> core,
gsl::not_null<ILogger*> logger) {
return std::unique_ptr<Catalog>(new Catalog(core, logger));
}

const std::string& GetName() const { return name_; }
std::vector<Model*> ListModels() const;
std::vector<ModelVariant*> GetLoadedModels() const;
std::vector<ModelVariant*> GetCachedModels() const;

Model* GetModel(std::string_view modelId) const;
ModelVariant* GetModelVariant(std::string_view modelVariantId) const;

private:
struct CatalogState {
std::unordered_map<std::string, Model> byAlias;
std::unordered_map<std::string, ModelVariant*> modelIdToModelVariant;
std::chrono::steady_clock::time_point lastFetch{};
};

void UpdateModels() const;
std::shared_ptr<const CatalogState> GetState() const;

mutable std::mutex mutex_;
mutable std::shared_ptr<const CatalogState> state_;

explicit Catalog(gsl::not_null<foundry_local::Internal::IFoundryLocalCore*> injected,
gsl::not_null<ILogger*> logger);

gsl::not_null<foundry_local::Internal::IFoundryLocalCore*> core_;
std::string name_;
gsl::not_null<ILogger*> logger_;

friend class FoundryLocalManager;
#ifdef FL_TESTS
friend struct Testing::MockObjectFactory;
#endif
};

} // namespace foundry_local
Loading
Loading