Skip to content
Merged
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
14 changes: 8 additions & 6 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
Package: foundryR
Title: Tibble Workflows for 'Azure AI Foundry'
Version: 0.0.0.9000
Version: 0.1.0
Authors@R:
person("Alex", "Farach", , "alexfarach@microsoft.com", role = c("aut", "cre", "cph"))
Description: Work with 'Microsoft Azure AI Foundry' from dataframe-oriented
'R' workflows. Returns tibbles for Content Safety, Responses API calls,
strict structured extraction, embeddings, files, batch jobs, audio, media,
and chat completions. Supports research annotation, safety gates,
semantic search, and 'tidymodels' recipes for teams committed to Azure.
Description: Work with 'Microsoft Azure AI Foundry' from data-frame-oriented
'R' workflows. Provides tibble-returning helpers for 'Azure AI Content
Safety', 'Azure OpenAI' Responses API calls, strict structured extraction,
embeddings, files, batch jobs, audio, media, and chat completions. Supports
research annotation, safety gates, semantic search, and 'tidymodels'
recipes. Helps teams keep model workflows inside their 'Azure' environment
while preserving analyzable outputs.
License: MIT + file LICENSE
Depends:
R (>= 4.1.0)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
YEAR: 2025
YEAR: 2026
COPYRIGHT HOLDER: Alex Farach
4 changes: 2 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# foundryR 0.0.0.9000
# foundryR 0.1.0

Initial development release of foundryR, a tidy interface to Microsoft Azure AI Foundry.
Initial CRAN release of foundryR, a tidy interface to Microsoft Azure AI Foundry.

## New features

Expand Down
12 changes: 12 additions & 0 deletions R/batches.R
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,18 @@ foundry_extract_batch <- function(data,
#'
#' @return A one-row tibble with token totals and optional `cost`.
#' @export
#'
#' @examples
#' responses <- data.frame(
#' input_tokens = c(10, 20),
#' cached_input_tokens = c(0, 5),
#' output_tokens = c(3, 7)
#' )
#' foundry_usage(responses)
#' foundry_usage(
#' responses,
#' rates = c(input = 0.000001, cached_input = 0.0000001, output = 0.000004)
#' )
foundry_usage <- function(x, rates = NULL) {
if (!is.data.frame(x)) {
cli::cli_abort("{.arg x} must be a data frame.")
Expand Down
27 changes: 22 additions & 5 deletions R/codebook.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#' @export
#'
#' @examples
#' \dontrun{
#' codebook <- foundry_codebook(
#' name = "ai-applicability",
#' version = "1.0.0",
Expand All @@ -34,7 +33,6 @@
#' list(text = "Lift a heavy box", ai_applicable = FALSE)
#' )
#' )
#' }
foundry_codebook <- function(name,
version,
instructions,
Expand Down Expand Up @@ -76,6 +74,12 @@ foundry_codebook <- function(name,
#'
#' @return A JSON Schema fragment represented as an R list.
#' @name codebook_schema_helpers
#'
#' @examples
#' type_boolean("Whether AI could materially assist the task")
#' type_enum("Priority label", values = c("low", "medium", "high"))
#' type_number("Confidence score")
#' type_string("Short rationale")
NULL


Expand Down Expand Up @@ -119,9 +123,22 @@ type_string <- function(desc = NULL) {
#' @export
#'
#' @examples
#' \dontrun{
#' codebook_diff(old_codebook, new_codebook)
#' }
#' old <- foundry_codebook(
#' name = "support-sentiment",
#' version = "1.0.0",
#' instructions = "Label the sentiment of support tickets.",
#' schema = foundry_schema(sentiment = type_enum(values = c("pos", "neg")))
#' )
#' new <- foundry_codebook(
#' name = "support-sentiment",
#' version = "1.1.0",
#' instructions = "Label the sentiment and urgency of support tickets.",
#' schema = foundry_schema(
#' sentiment = type_enum(values = c("pos", "neg")),
#' urgent = type_boolean()
#' )
#' )
#' codebook_diff(old, new)
codebook_diff <- function(old, new) {
foundry_check_codebook(old, "old")
foundry_check_codebook(new, "new")
Expand Down
22 changes: 22 additions & 0 deletions R/content-safety-extra.R
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ foundry_moderate_image <- function(image,
#'
#' @return A tibble with one row per input text.
#' @export
#'
#' @examples
#' if (interactive() &&
#' nzchar(Sys.getenv("AZURE_CONTENT_SAFETY_ENDPOINT")) &&
#' nzchar(Sys.getenv("AZURE_CONTENT_SAFETY_KEY"))) {
#' foundry_protected_material("A short text sample.")
#' }
foundry_protected_material <- function(text,
endpoint = NULL,
api_key = NULL,
Expand Down Expand Up @@ -126,6 +133,21 @@ foundry_protected_material <- function(text,
#'
#' @return A tibble with blocklist or blocklist-item metadata.
#' @name foundry_blocklists
#'
#' @examples
#' if (interactive() &&
#' nzchar(Sys.getenv("AZURE_CONTENT_SAFETY_ENDPOINT")) &&
#' nzchar(Sys.getenv("AZURE_CONTENT_SAFETY_KEY"))) {
#' foundry_blocklists()
#' foundry_blocklist_create("example-blocklist", description = "Example")
#' foundry_blocklist_get("example-blocklist")
#' items <- foundry_blocklist_add_items("example-blocklist", "blocked phrase")
#' foundry_blocklist_items("example-blocklist")
#' if (nrow(items) > 0 && !is.na(items$item_id[[1]])) {
#' foundry_blocklist_remove_items("example-blocklist", items$item_id)
#' }
#' foundry_blocklist_delete("example-blocklist")
#' }
NULL


Expand Down
15 changes: 15 additions & 0 deletions R/conversations.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@
#'
#' @return A tibble with conversation metadata or conversation items.
#' @name foundry_conversations
#'
#' @examples
#' if (interactive() &&
#' nzchar(Sys.getenv("AZURE_FOUNDRY_ENDPOINT")) &&
#' nzchar(Sys.getenv("AZURE_FOUNDRY_KEY"))) {
#' conversation <- foundry_conversation_create(
#' metadata = list(example = "cran")
#' )
#' id <- conversation$conversation_id[[1]]
#' foundry_conversations(limit = 10)
#' foundry_conversation_get(id)
#' foundry_conversation_update(id, metadata = list(example = "updated"))
#' foundry_conversation_items(id)
#' foundry_conversation_delete(id)
#' }
NULL


Expand Down
12 changes: 12 additions & 0 deletions R/schema.R
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ foundry_schema <- function(...,
#'
#' @return A JSON Schema fragment represented as an R list.
#' @name schema_constructors
#'
#' @examples
#' schema_string("Free-text label")
#' schema_enum(c("positive", "negative", "neutral"))
#' schema_object(
#' sentiment = schema_enum(c("positive", "negative", "neutral")),
#' confidence = schema_number()
#' )
NULL


Expand Down Expand Up @@ -168,6 +176,10 @@ schema_object <- function(...,
#'
#' @return A JSON Schema represented as an R list.
#' @export
#'
#' @examples
#' schema <- foundry_schema(label = schema_string())
#' as_foundry_schema(schema)
as_foundry_schema <- function(x) {
if (inherits(x, "ellmer::Type")) {
return(foundry_preserve_schema_arrays(ellmer_type_to_schema(x)))
Expand Down
2 changes: 2 additions & 0 deletions R/utils-pipe.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@
#' @param lhs A value or the magrittr placeholder.
#' @param rhs A function call using the magrittr semantics.
#' @return The result of calling `rhs(lhs)`.
#' @examples
#' 1:3 %>% sum()
NULL
8 changes: 8 additions & 0 deletions R/validation.R
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ foundry_consistency <- function(text, schema, n = 3L, ...) {
#'
#' @return A one-row tibble.
#' @export
#'
#' @examples
#' schema <- foundry_schema(label = schema_string())
#' foundry_provenance(
#' model = "gpt-5-nano",
#' schema = schema,
#' metadata = list(run = "pilot")
#' )
foundry_provenance <- function(model, schema, metadata = NULL) {
foundry_check_character_scalar(model, "model")
schema <- as_foundry_schema(schema)
Expand Down
23 changes: 23 additions & 0 deletions R/vector-stores.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,26 @@
#'
#' @return A tibble with vector store, file, or search-result metadata.
#' @name foundry_vector_stores
#'
#' @examples
#' if (interactive() &&
#' nzchar(Sys.getenv("AZURE_FOUNDRY_ENDPOINT")) &&
#' nzchar(Sys.getenv("AZURE_FOUNDRY_KEY"))) {
#' store <- foundry_vector_store_create("example-store")
#' id <- store$vector_store_id[[1]]
#' foundry_vector_stores(limit = 10)
#' foundry_vector_store_get(id)
#' foundry_vector_store_modify(id, name = "renamed-example-store")
#' foundry_vector_store_files(id)
#' file_id <- Sys.getenv("AZURE_FOUNDRY_FILE_ID")
#' if (nzchar(file_id)) {
#' foundry_vector_store_file_add(id, file_id)
#' foundry_vector_store_file_remove(id, file_id)
#' foundry_vector_store_file_batch(id, file_id)
#' foundry_vector_search(id, "example query")
#' }
#' foundry_vector_store_delete(id)
#' }
NULL


Expand Down Expand Up @@ -260,6 +280,9 @@ foundry_vector_search <- function(vector_store_id,
#'
#' @return A Responses API tool definition list.
#' @export
#'
#' @examples
#' foundry_tool_file_search("vs_abc123", max_num_results = 3)
foundry_tool_file_search <- function(vector_store_ids, max_num_results = NULL) {
if (!is.character(vector_store_ids) || length(vector_store_ids) == 0L ||
any(is.na(vector_store_ids))) {
Expand Down
8 changes: 7 additions & 1 deletion README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ if (run_api) {
}
```

# foundryR <a href="https://farach.github.io/foundryR/"><img src="man/figures/logo.svg" align="right" height="138" alt="foundryR website" /></a>
# foundryR <a href="https://farach.github.io/foundryR/"><img src="https://raw.githubusercontent.com/farach/foundryR/main/man/figures/logo.svg" align="right" height="138" alt="foundryR website" /></a>

<!-- badges: start -->
[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental)
Expand All @@ -57,6 +57,12 @@ Its strongest path is dataframe in, dataframe out.

## Installation

Install the released version from CRAN:

```r
install.packages("foundryR")
```

Install the development version from GitHub:

```r
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- Executable chunks replay recorded, credential-free API fixtures. -->
<!-- Regenerate with: source("data-raw/record-doc-outputs.R") -->

# foundryR <a href="https://farach.github.io/foundryR/"><img src="man/figures/logo.svg" align="right" height="138" alt="foundryR website" /></a>
# foundryR <a href="https://farach.github.io/foundryR/"><img src="https://raw.githubusercontent.com/farach/foundryR/main/man/figures/logo.svg" align="right" height="138" alt="foundryR website" /></a>

<!-- badges: start -->

Expand Down Expand Up @@ -34,6 +34,12 @@ Its strongest path is dataframe in, dataframe out.

## Installation

Install the released version from CRAN:

``` r
install.packages("foundryR")
```

Install the development version from GitHub:

``` r
Expand Down
8 changes: 8 additions & 0 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## Submission

This is the first CRAN submission for foundryR.

## Test environments

- Local Windows 11 x64, R 4.5.2

## R CMD check results

0 errors | 0 warnings | 0 notes
Expand Down
11 changes: 11 additions & 0 deletions inst/extdata/samples/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
jfk.wav
=======

jfk.wav is a short excerpt from John F. Kennedy's January 20, 1961
inaugural address, included as a small speech-recognition example. The
address is a U.S. federal government work and is in the public domain in
the United States under 17 U.S.C. 105.

Source recording: John F. Kennedy Presidential Library and Museum,
"The Inaugural Address":
https://www.jfklibrary.org/learn/about-jfk/historic-speeches/the-inaugural-address
4 changes: 4 additions & 0 deletions man/as_foundry_schema.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 16 additions & 3 deletions man/codebook_diff.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions man/codebook_schema_helpers.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/foundryR-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions man/foundry_blocklists.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading