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
3 changes: 3 additions & 0 deletions .github/workflows/samples-integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ on:
permissions:
contents: read

env:
ORT_TELEMETRY_DISABLED: '1'

jobs:
# ── Python Samples ──────────────────────────────────────────────────
python-samples:
Expand Down
3 changes: 3 additions & 0 deletions .pipelines/foundry-local-packaging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ parameters:

variables:
- group: FoundryLocal-ESRP-Signing
# Keep all CI jobs telemetry-free through the shared ORT/1DS runtime opt-out.
- name: ORT_TELEMETRY_DISABLED
value: '1'
# C++ SDK (sdk_v2/cpp) native dependency versions. Must match cmake defaults
# in sdk_v2/deps_versions.json.
- name: cppOrtVersion
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Foundry Local is an **end-to-end local AI solution** for building applications t

User data never leaves the device, responses start immediately with zero network latency, and your app works offline. No per-token costs, no API keys, no backend infrastructure to maintain, and no Azure subscription required.

Foundry Local may collect usage data and send it to Microsoft to help improve our products and services. See the [privacy statement](sdk_v2/cpp/docs/Privacy.md) for more details.

### Key Features

- **Lightweight runtime** — The runtime handles model acquisition, hardware acceleration, model management, and inference (via [ONNX Runtime](https://onnxruntime.ai/)).
Expand Down
67 changes: 66 additions & 1 deletion sdk_v2/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ endif()
if(NOT DEFINED FOUNDRY_LOCAL_BUILD_SERVICE OR FOUNDRY_LOCAL_BUILD_SERVICE)
list(APPEND VCPKG_MANIFEST_FEATURES "service")
endif()
# Telemetry must be selected before project() so vcpkg resolves the feature. Foundry Local Core always builds with
# telemetry; platforms that cannot link the 1DS transport are unsupported for this target.
if(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" OR VCPKG_TARGET_TRIPLET MATCHES "uwp")
message(FATAL_ERROR "Foundry Local Core always builds with telemetry; UWP/WindowsStore is not supported.")
endif()
list(APPEND VCPKG_MANIFEST_FEATURES "telemetry")

project(foundry_local VERSION 0.1.0 LANGUAGES CXX C)

Expand Down Expand Up @@ -45,6 +51,30 @@ option(FOUNDRY_LOCAL_BUILD_EXAMPLES "Build example programs" ON)
option(FOUNDRY_LOCAL_BUILD_SERVICE "Build web service support (requires oat++)" ON)
option(FOUNDRY_LOCAL_ENABLE_ASAN "Enable AddressSanitizer + UndefinedBehaviorSanitizer (Linux only)" OFF)

# Optional 1DS ingestion token override. Override only via environment so it does
# not appear in CMake cache files.
if(DEFINED CACHE{FOUNDRY_LOCAL_TELEMETRY_TOKEN}
AND NOT "$CACHE{FOUNDRY_LOCAL_TELEMETRY_TOKEN}" STREQUAL "")
message(FATAL_ERROR
"Do not pass FOUNDRY_LOCAL_TELEMETRY_TOKEN via -D or CMake cache. "
"Use the FOUNDRY_LOCAL_TELEMETRY_TOKEN environment variable for temporary test-tenant overrides.")
endif()
unset(FOUNDRY_LOCAL_TELEMETRY_TOKEN CACHE)

set(FOUNDRY_LOCAL_TELEMETRY_TOKEN "")
if(DEFINED ENV{FOUNDRY_LOCAL_TELEMETRY_TOKEN})
set(FOUNDRY_LOCAL_TELEMETRY_TOKEN "$ENV{FOUNDRY_LOCAL_TELEMETRY_TOKEN}")
endif()
if(FOUNDRY_LOCAL_TELEMETRY_TOKEN MATCHES "^\\$\\(")
set(FOUNDRY_LOCAL_TELEMETRY_TOKEN "")
endif()
if(FOUNDRY_LOCAL_TELEMETRY_TOKEN)
set(FOUNDRY_LOCAL_TELEMETRY_TOKEN_DEFINE
"#define FOUNDRY_LOCAL_TELEMETRY_TOKEN \"${FOUNDRY_LOCAL_TELEMETRY_TOKEN}\"")
else()
set(FOUNDRY_LOCAL_TELEMETRY_TOKEN_DEFINE "")
endif()

# Android: interactive examples and host tools don't run on device
if(ANDROID)
set(FOUNDRY_LOCAL_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
Expand Down Expand Up @@ -87,6 +117,13 @@ if(WIN32)
find_package(WinMLEpCatalog)
endif()

# 1DS C++ client telemetry — provided by the cpp-client-telemetry vcpkg port.
find_package(MSTelemetry CONFIG REQUIRED)
if(NOT WIN32)
find_package(OpenSSL REQUIRED)
endif()
message(STATUS "1DS telemetry: enabled (cpp-client-telemetry found)")

# --------------------------------------------------------------------------
# Library target
# --------------------------------------------------------------------------
Expand Down Expand Up @@ -196,7 +233,13 @@ set(FOUNDRY_LOCAL_SOURCES
src/service/web_service.cc
src/telemetry/telemetry.cc
src/telemetry/telemetry_action_tracker.cc
src/telemetry/device_id.cc
src/telemetry/invocation_context.cc
src/telemetry/telemetry_environment.cc
src/telemetry/telemetry_logger.cc
src/telemetry/telemetry_metadata.cc
src/telemetry/ep_download_tracker.cc
src/telemetry/download_tracker.cc
src/utils.cc
src/util/file_lock.cc
src/http/http_download.cc
Expand All @@ -208,6 +251,12 @@ set(FOUNDRY_LOCAL_SOURCES
${FOUNDRY_LOCAL_INTERNAL_HEADERS}
)

# 1DS bridge — always compiled for Foundry Local Core.
list(APPEND FOUNDRY_LOCAL_SOURCES src/telemetry/one_ds_telemetry.cc)
if(ANDROID)
list(APPEND FOUNDRY_LOCAL_SOURCES src/telemetry/android_telemetry_bridge.cc)
endif()

# Organize headers into filters matching the directory structure in Visual Studio
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "Source" FILES ${FOUNDRY_LOCAL_SOURCES})
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/include" PREFIX "Public Headers" FILES ${FOUNDRY_LOCAL_PUBLIC_HEADERS})
Expand Down Expand Up @@ -250,12 +299,18 @@ function(foundry_local_configure_target TARGET LINK_SCOPE)
endif()

if(WIN32)
target_link_libraries(${TARGET} ${LINK_SCOPE} dbghelp bcrypt)
target_link_libraries(${TARGET} ${LINK_SCOPE} dbghelp bcrypt version)
# UWP builds have CMAKE_SYSTEM_NAME = "WindowsStore"; desktop = "Windows".
# WinHTTP is not available in UWP, so only define this on desktop Windows.
if(NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
Comment on lines 301 to 305
target_compile_definitions(${TARGET} PRIVATE FOUNDRY_LOCAL_USE_WINHTTP_TRANSPORT=1)
endif()
else()
target_link_libraries(${TARGET} ${LINK_SCOPE} OpenSSL::Crypto)
endif()

if(APPLE)
target_link_libraries(${TARGET} ${LINK_SCOPE} "-framework CoreFoundation")
endif()

if(ANDROID)
Expand All @@ -273,6 +328,9 @@ function(foundry_local_configure_target TARGET LINK_SCOPE)
else()
target_compile_definitions(${TARGET} ${LINK_SCOPE} FOUNDRY_LOCAL_HAS_EP_CATALOG=0)
endif()

target_link_libraries(${TARGET} ${LINK_SCOPE} MSTelemetry::mat)

endfunction()

# --------------------------------------------------------------------------
Expand All @@ -291,6 +349,13 @@ configure_file(
@ONLY
)

# Generate the 1DS tenant-token header.
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/src/telemetry/one_ds_tenant_token.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/generated/one_ds_tenant_token.h"
@ONLY
)

# --------------------------------------------------------------------------
# Object library — compiles all sources once. Both the shared (DLL) and
# static library targets re-use these object files, avoiding a double build.
Expand Down
13 changes: 10 additions & 3 deletions sdk_v2/cpp/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ class HelpFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescript
help="Override the Microsoft.Windows.AI.MachineLearning NuGet version for the WinML EP "
"catalog (Windows only). Defaults to the version pinned in deps_versions.json.",
)

# Cross-compilation (mutually exclusive targets)
cross_group = parser.add_mutually_exclusive_group()
cross_group.add_argument(
Expand Down Expand Up @@ -439,6 +438,10 @@ def configure(args: argparse.Namespace) -> None:
if triplets_dir.is_dir():
command += [f"-DVCPKG_OVERLAY_TRIPLETS={triplets_dir}"]

ports_dir = SCRIPT_DIR / "ports"
if ports_dir.is_dir():
command += [f"-DVCPKG_OVERLAY_PORTS={ports_dir}"]

# Project options
build_tests = "ON"

Expand All @@ -451,9 +454,13 @@ def configure(args: argparse.Namespace) -> None:
f"-DFOUNDRY_LOCAL_BUILD_SERVICE={build_service}",
]

# Enable vcpkg manifest features for tests
# Enable vcpkg manifest features as needed. Multiple features are passed as a
# semicolon-separated list in a single -D flag.
manifest_features = []
if build_tests == "ON":
command += ["-DVCPKG_MANIFEST_FEATURES=tests"]
manifest_features.append("tests")
if manifest_features:
command += [f"-DVCPKG_MANIFEST_FEATURES={';'.join(manifest_features)}"]

# WinML EP catalog is enabled automatically on Windows by CMake. Allow an
# optional version override for the Microsoft.Windows.AI.MachineLearning NuGet.
Expand Down
24 changes: 24 additions & 0 deletions sdk_v2/cpp/docs/Privacy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Privacy

## Data Collection

The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may disable non-essential telemetry as described below. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft's privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.

***

Foundry Local collects a small number of trace events with the goal of improving product quality. Official packages on supported platforms include the cross-platform 1DS telemetry SDK. Collection is subject to user consent and handled following Microsoft's privacy practices.

Telemetry is turned **ON** by default.

#### Technical Details

Foundry Local uses the cross-platform 1DS SDK (cpp_client_telemetry) to send trace events to Microsoft's telemetry backend over HTTPS. Based on user consent, this data is handled following GDPR and privacy regulations for anonymity and data access controls.

Non-essential telemetry can be disabled as follows. Foundry Local may still send a minimal ProcessInfo event.

- **Disable via manager config.** Set the disable-nonessential-telemetry option before creating the manager:
- C++: `Configuration::SetDisableNonessentialTelemetry(true)`
- C#: `Configuration.DisableNonessentialTelemetry = true`
- JavaScript/TypeScript: `disableNonessentialTelemetry: true`
- Python: `disable_nonessential_telemetry=True`
- Native additional option: `DisableNonessentialTelemetry=true`
53 changes: 53 additions & 0 deletions sdk_v2/cpp/docs/telemetry/grafana/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Foundry Local Grafana dashboard

`foundry-local-telemetry-dashboard.json` is an importable Grafana dashboard for Foundry Local SDK v2 client
telemetry in Aria.

## Import

1. Install the Grafana Azure Data Explorer datasource plugin
(`grafana-azure-data-explorer-datasource`) version `7.2.8`. The dashboard targets Grafana `11.6.11`; newer
Grafana versions must also satisfy the plugin's compatibility requirements.
2. Configure a datasource that can query:
- Cluster: `https://kusto.aria.microsoft.com`
- Database: `9d5ddaec61e24567b788a20aea324631`
3. In Grafana, select **Dashboards > New > Import**, upload
`foundry-local-telemetry-dashboard.json`, and map **Aria Azure Data Explorer** to that datasource.

The dashboard defaults to UTC, the last seven days, and a five-minute refresh. Aria retention is approximately
12–14 days. Every query requires a populated `FoundryLocalVersion`, excluding legacy/unversioned telemetry from this
SDK v2 dashboard.

## Filters

All dashboard filters are time-aware and multi-select:

- App
- OS
- Foundry Local version
- User agent
- Action
- Status
- Model
- Execution provider

The filters use the ADX plugin's `$__contains` macro. Their **All** value must remain exactly `all`.

## Privacy

The dashboard does not project device identifiers, client IP addresses, or user identity fields. Device IDs are used
only inside an aggregate `count_distinct` calculation. Recent-error panels show the telemetry error text already
subject to Foundry Local's upload redaction rules.

## Regenerate

The JSON is generated from `generate-dashboard.py`:

```powershell
python sdk_v2\cpp\docs\telemetry\grafana\generate-dashboard.py
```

The queries were authored against the live Aria schemas for:

`action`, `audiomodel`, `catalogfetch`, `download`, `epdownloadandregister`, `epdownloadattempt`, `error`,
`hardwareinfo`, `model`, `modelid`, `processinfo`, and `session`.
Loading
Loading