diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 82ca0b271c71..0d5dfb61dc5b 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -202,6 +202,8 @@ "bdist", "Beddall", "bstr", + "byom", + "byos", "byref", "cdll", "certprg", @@ -243,6 +245,7 @@ "dpkg", "dtlk", "dtlksd", + "dtmf", "duckdb", "DWORD", "eastus", @@ -327,6 +330,7 @@ "Lucene", "Mazuel", "mbps", + "mcphttp", "mday", "mibps", "mgmt", @@ -376,6 +380,8 @@ "owasp", "ownerid", "PBYTE", + "pcma", + "pcmu", "PCREDENTIAL", "pepy", "perfmon", @@ -393,6 +399,7 @@ "prompty", "pschema", "PSECRET", + "pstn", "pydantic", "pyfetch", "pyfuncitem", @@ -415,6 +422,7 @@ "rohitganguly", "reauthenticated", "reimage", + "retriable", "revascularization", "riscv", "rollup", diff --git a/sdk/ai/azure-ai-projects/.env.template b/sdk/ai/azure-ai-projects/.env.template index 14effd0c4418..8e60ee147e0c 100644 --- a/sdk/ai/azure-ai-projects/.env.template +++ b/sdk/ai/azure-ai-projects/.env.template @@ -103,6 +103,13 @@ GITHUB_USERNAME= TEAMS_CONNECTION_NAME= TEAMS_CHANNEL_URL= +# Read by the samples under samples/agents/voice/ (model deployment name, agent name, model type, +# and a conversation ID for the read-conversation samples). Distinct from FOUNDRY_VOICE_MODEL_NAME below. +FOUNDRY_VOICE_MODEL= +FOUNDRY_VOICE_MODEL_TYPE= +FOUNDRY_VOICE_AGENT_NAME= +FOUNDRY_VOICE_CONVERSATION_ID= + ####################################################################### # # Used in tests @@ -116,6 +123,10 @@ AZURE_SKIP_LIVE_RECORDING=true #Used by hosted agent FOUNDRY_HOSTED_AGENT_NAME= +# Read by the recorded voice-agent CRUD, conversation, realtime-live, and telephony tests +# (tests/test_base.py and friends), not by any sample. +FOUNDRY_VOICE_MODEL_NAME= + # Used in Fine-tuning tests COMPLETED_OAI_MODEL_SFT_FINE_TUNING_JOB_ID= COMPLETED_OAI_MODEL_RFT_FINE_TUNING_JOB_ID= diff --git a/sdk/ai/azure-ai-projects/.github/skills/README.md b/sdk/ai/azure-ai-projects/.github/skills/README.md index bb04532d03c8..b48751648bf2 100644 --- a/sdk/ai/azure-ai-projects/.github/skills/README.md +++ b/sdk/ai/azure-ai-projects/.github/skills/README.md @@ -56,3 +56,7 @@ This skill compares a newly emitted or merged public API surface with its select ### azure-ai-projects-author-tests This skill updates existing pytest coverage and authors complete sync/async Test Proxy tests for new behavior. New recorded service tests remain enabled so missing-recording errors surface in PR validation and authors can contact the SDK maintainer for help. + +### azure-ai-projects-model-reference-graph + +This skill generates structured and readable graphs that trace every generated model through direct references, inheritance, runtime ownership, and public operation methods. It supports model-usage investigation and TypeSpec removal analysis without treating static reachability as proof that a model is safe to remove. diff --git a/sdk/ai/azure-ai-projects/.github/skills/azure-ai-projects-model-reference-graph/SKILL.md b/sdk/ai/azure-ai-projects/.github/skills/azure-ai-projects-model-reference-graph/SKILL.md new file mode 100644 index 000000000000..8e2b7f3ca6c1 --- /dev/null +++ b/sdk/ai/azure-ai-projects/.github/skills/azure-ai-projects-model-reference-graph/SKILL.md @@ -0,0 +1,123 @@ +--- +name: azure-ai-projects-model-reference-graph +description: 'Generate and analyze the azure-ai-projects model reference graph from models/_models.py through model references, inheritance, runtime ownership, and public operation methods. WHEN: find which operations use a model; trace model dependencies; generate model-reference-graph.json; generate model-reference-trees.txt; investigate unused or orphaned generated models; assess whether a TypeSpec model may be removable. DO NOT USE FOR: deleting generated models automatically; packages other than azure-ai-projects. INVOKES: GenerateModelReferenceGraph.ps1, Python JSON validation, git diff checks.' +argument-hint: 'Optionally provide a model name to inspect after generating the graph' +--- + +# Generate the azure-ai-projects model reference graph + +Run this workflow from `sdk\ai\azure-ai-projects`. + +## 1. Check prerequisites + +Confirm the package root and required files: + +```powershell +git rev-parse --show-prefix +Test-Path .\.github\skills\azure-ai-projects-model-reference-graph\scripts\GenerateModelReferenceGraph.ps1 +Test-Path .\azure\ai\projects\models\_models.py +``` + +The Git prefix must be `sdk/ai/azure-ai-projects/`. Stop and report the missing prerequisite if either file does not exist. + +Prefer the active virtual environment's Python. Use `.\.venv\Scripts\python.exe` when it exists; otherwise use `python`. + +## 2. Generate the graph + +```powershell +.\.github\skills\azure-ai-projects-model-reference-graph\scripts\GenerateModelReferenceGraph.ps1 ` + -PythonExecutable .\.venv\Scripts\python.exe +``` + +The script produces: + +- `model-reference-graph.json`: structured data keyed by every class in `_models.py`. +- `model-reference-trees.txt`: readable reverse-reference trees rooted at every model. + +Do not edit generated artifacts manually. Rerun the script after SDK emission or model changes. + +## 3. Interpret the graph + +For each model, follow children toward public operations: + +```text +ChildModel + `- BaseModel [base class] + `- RequestOrResponseModel + `- SomeOperations.method [operation] +``` + +Edge and marker meanings: + +- An unmarked model child directly references its parent through a field, annotation, decorator, or other model declaration. +- `[base class]` traverses from a derived model to its base type. +- `[derived class]` traverses from a base model to a derived type. +- `[operation]` is a public sync/async-deduplicated operation method. +- `[cycle]` stops a circular model relationship. +- `[already expanded]` identifies a shared branch already rendered under the same root. + +The JSON entry additionally contains direct and indirect model referrers, bases, derived models, operation references, paths, public-export status, and non-operation references. + +Some runtime ownership is not expressible through Python method annotations. The generator maintains an explicit, reviewed ownership table for WebSocket protocol messages, custom polling results, and flattened request bodies. Do not add a mapping based only on similar names. Verify the owning endpoint, handwritten patch, protocol documentation, or generated method implementation first. + +## 4. Inspect a requested model + +When the user supplies a model name, report: + +1. Its base and derived models. +2. Models that reference it directly and indirectly. +3. Every public operation it reaches, distinguishing direct references from inherited or transitive paths. +4. At least one representative path from the operation to the requested model. +5. Non-operation references from patches, tests, or samples. + +Use PowerShell for a focused JSON lookup: + +```powershell +$graph = Get-Content .\model-reference-graph.json -Raw | ConvertFrom-Json -AsHashtable +$graph.models[''] | ConvertTo-Json -Depth 10 +``` + +## 5. Validate generated artifacts + +Run all checks after generation: + +```powershell +$tokens = $null +$errors = $null +[System.Management.Automation.Language.Parser]::ParseFile( + (Resolve-Path '.\.github\skills\azure-ai-projects-model-reference-graph\scripts\GenerateModelReferenceGraph.ps1'), + [ref]$tokens, + [ref]$errors +) | Out-Null +if ($errors.Count) { throw ($errors.Message -join [Environment]::NewLine) } + +python -m json.tool .\model-reference-graph.json > $null +git diff --check -- .\.github\skills\azure-ai-projects-model-reference-graph\scripts\GenerateModelReferenceGraph.ps1 .\model-reference-graph.json .\model-reference-trees.txt +``` + +Also verify the summary against the structured graph: + +```powershell +$graph = Get-Content .\model-reference-graph.json -Raw | ConvertFrom-Json -AsHashtable +$withoutOperations = @($graph.models.GetEnumerator() | Where-Object { $_.Value.pathsToOperations.Count -eq 0 }) +if ($withoutOperations.Count -ne $graph.metadata.modelsWithoutOperationPaths) { + throw 'The tree summary does not match the structured graph.' +} +``` + +## 6. Apply removal safeguards + +Operation reachability is not proof that a model is safe or unsafe to remove. Before proposing removal, verify all of the following: + +- Public export status in `models/__init__.py`. +- References from `_patch.py`, `_unions.py`, samples, and tests. +- Base classes, derived classes, and discriminator registration. +- Runtime protocol roles such as WebSocket events and LRO polling bodies. +- The corresponding TypeSpec declaration and all TypeSpec references. +- API review impact after regenerating the SDK. + +Never delete generated classes directly from `_models.py`. Remove or correct the TypeSpec source, regenerate the SDK, rerun this skill, and run package validation. + +## 7. Report results + +Report the model count, models with and without operation paths, requested model paths, explicit runtime ownership mappings used, and validation results. Clearly label static-analysis limitations and any model requiring TypeSpec or runtime review. \ No newline at end of file diff --git a/sdk/ai/azure-ai-projects/.github/skills/azure-ai-projects-model-reference-graph/scripts/GenerateModelReferenceGraph.ps1 b/sdk/ai/azure-ai-projects/.github/skills/azure-ai-projects-model-reference-graph/scripts/GenerateModelReferenceGraph.ps1 new file mode 100644 index 000000000000..b85eb2427c6c --- /dev/null +++ b/sdk/ai/azure-ai-projects/.github/skills/azure-ai-projects-model-reference-graph/scripts/GenerateModelReferenceGraph.ps1 @@ -0,0 +1,457 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +[CmdletBinding()] +param( + [string]$PythonExecutable = "python", + [string]$ModelsPath, + [string]$OutputPath, + [string]$TreeOutputPath +) + +$ErrorActionPreference = "Stop" +$packageRoot = (Resolve-Path (Join-Path $PSScriptRoot "..\..\..\..")).Path +if (-not $ModelsPath) { + $ModelsPath = Join-Path $packageRoot "azure\ai\projects\models\_models.py" +} +if (-not $OutputPath) { + $OutputPath = Join-Path $packageRoot "model-reference-graph.json" +} +if (-not $TreeOutputPath) { + $TreeOutputPath = Join-Path $packageRoot "model-reference-trees.txt" +} +$temporaryScript = Join-Path ([System.IO.Path]::GetTempPath()) ("generate-model-reference-graph-{0}.py" -f [guid]::NewGuid()) + +$pythonScript = @' +from __future__ import annotations + +import ast +from collections import defaultdict, deque +import json +from pathlib import Path +import re +import sys +from typing import Iterable + + +package_root = Path(sys.argv[1]).resolve() +models_path = Path(sys.argv[2]).resolve() +output_path = Path(sys.argv[3]).resolve() +tree_output_path = Path(sys.argv[4]).resolve() + +excluded_directories = { + ".git", + ".mypy_cache", + ".pytest_cache", + ".tox", + ".venv", + "__pycache__", + "build", + "dist", + "node_modules", +} + + +def parse_python(path: Path) -> ast.Module: + try: + return ast.parse(path.read_text(encoding="utf-8-sig"), filename=str(path)) + except (OSError, UnicodeError, SyntaxError) as error: + raise RuntimeError(f"Unable to parse {path}: {error}") from error + + +def body_without_docstring(body: list[ast.stmt]) -> list[ast.stmt]: + if body and isinstance(body[0], ast.Expr): + value = body[0].value + if isinstance(value, ast.Constant) and isinstance(value.value, str): + return body[1:] + return body + + +class ReferenceCollector(ast.NodeVisitor): + def __init__(self, known_symbols: set[str]) -> None: + self.known_symbols = known_symbols + self.references: set[str] = set() + + def visit_Name(self, node: ast.Name) -> None: + if node.id in self.known_symbols: + self.references.add(node.id) + + def visit_Attribute(self, node: ast.Attribute) -> None: + if node.attr in self.known_symbols: + self.references.add(node.attr) + self.visit(node.value) + + def visit_Constant(self, node: ast.Constant) -> None: + if isinstance(node.value, str): + for name in re.findall(r"\b[A-Za-z_][A-Za-z0-9_]*\b", node.value): + if name in self.known_symbols: + self.references.add(name) + + def visit_Module(self, node: ast.Module) -> None: + for statement in body_without_docstring(node.body): + self.visit(statement) + + def visit_ClassDef(self, node: ast.ClassDef) -> None: + for child in [*node.decorator_list, *node.bases, *node.keywords]: + self.visit(child) + for statement in body_without_docstring(node.body): + self.visit(statement) + + def visit_FunctionDef(self, node: ast.FunctionDef) -> None: + for child in [*node.decorator_list, node.args]: + self.visit(child) + if node.returns: + self.visit(node.returns) + for statement in body_without_docstring(node.body): + self.visit(statement) + + visit_AsyncFunctionDef = visit_FunctionDef + + +def collect_references(node: ast.AST, known_symbols: set[str]) -> set[str]: + collector = ReferenceCollector(known_symbols) + collector.visit(node) + return collector.references + + +def python_files(root: Path) -> Iterable[Path]: + for path in root.rglob("*.py"): + if not any(part in excluded_directories or part.startswith(".venv") for part in path.parts): + yield path + + +def find_public_exports(init_path: Path, known_models: set[str]) -> set[str]: + exports: set[str] = set() + for node in parse_python(init_path).body: + if isinstance(node, ast.ImportFrom) and node.module == "_models": + exports.update(alias.name for alias in node.names if alias.name in known_models) + return exports + + +def assignment_nodes(tree: ast.Module) -> dict[str, ast.AST]: + assignments: dict[str, ast.AST] = {} + for node in tree.body: + if ( + isinstance(node, ast.Assign) + and len(node.targets) == 1 + and isinstance(node.targets[0], ast.Name) + ): + assignments[node.targets[0].id] = node.value + return assignments + + +def scoped_references(tree: ast.Module, known_symbols: set[str]) -> dict[str, set[str]]: + scopes: dict[str, set[str]] = defaultdict(set) + module_nodes: list[ast.AST] = [] + for node in body_without_docstring(tree.body): + if isinstance(node, ast.ClassDef): + class_nodes: list[ast.AST] = [*node.decorator_list, *node.bases, *node.keywords] + for statement in body_without_docstring(node.body): + if isinstance(statement, (ast.FunctionDef, ast.AsyncFunctionDef)): + scopes[f"{node.name}.{statement.name}"].update( + collect_references(statement, known_symbols) + ) + else: + class_nodes.append(statement) + for class_node in class_nodes: + scopes[node.name].update(collect_references(class_node, known_symbols)) + elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): + scopes[node.name].update(collect_references(node, known_symbols)) + else: + module_nodes.append(node) + for module_node in module_nodes: + scopes[""].update(collect_references(module_node, known_symbols)) + return {name: references for name, references in scopes.items() if references} + + +models_tree = parse_python(models_path) +model_nodes = { + node.name: node + for node in models_tree.body + if isinstance(node, ast.ClassDef) +} +known_models = set(model_nodes) + +unions_path = models_path.parent.parent / "_unions.py" +union_nodes = assignment_nodes(parse_python(unions_path)) +known_unions = set(union_nodes) +known_symbols = known_models | known_unions + +union_references = { + name: collect_references(node, known_symbols) - {name} + for name, node in union_nodes.items() +} +resolved_union_models: dict[str, set[str]] = {} + + +def models_for_union(name: str, resolving: set[str] | None = None) -> set[str]: + if name in resolved_union_models: + return resolved_union_models[name] + resolving = set() if resolving is None else resolving + if name in resolving: + return set() + resolving.add(name) + symbols = union_references.get(name, set()) + models = set(symbols & known_models) + for referenced_union in symbols & known_unions: + models.update(models_for_union(referenced_union, resolving)) + resolving.remove(name) + resolved_union_models[name] = models + return models + + +def expand_models(symbols: set[str]) -> set[str]: + models = set(symbols & known_models) + for union_name in symbols & known_unions: + models.update(models_for_union(union_name)) + return models + + +model_bases: dict[str, set[str]] = {} +model_dependencies: dict[str, set[str]] = {} +for name, node in model_nodes.items(): + base_symbols: set[str] = set() + for base in node.bases: + base_symbols.update(collect_references(base, known_symbols)) + model_bases[name] = expand_models(base_symbols) - {name} + model_dependencies[name] = expand_models(collect_references(node, known_symbols)) - {name} - model_bases[name] + +direct_model_referrers: dict[str, set[str]] = defaultdict(set) +for referring_model, referenced_models in model_dependencies.items(): + for referenced_model in referenced_models: + direct_model_referrers[referenced_model].add(referring_model) + +model_subclasses: dict[str, set[str]] = defaultdict(set) +for child_model, base_models in model_bases.items(): + for base_model in base_models: + model_subclasses[base_model].add(child_model) + +def outward_models(name: str) -> set[str]: + return direct_model_referrers[name] | model_bases[name] | model_subclasses[name] + +models_init_path = models_path.parent / "__init__.py" +public_exports = find_public_exports(models_init_path, known_models) +operation_references: dict[str, set[str]] = defaultdict(set) +other_references: dict[str, set[str]] = defaultdict(set) + +for path in python_files(package_root): + resolved_path = path.resolve() + if resolved_path in {models_path, models_init_path, unions_path}: + continue + relative_path = path.relative_to(package_root) + is_operation = "operations" in relative_path.parts + references_by_scope = scoped_references(parse_python(path), known_symbols) + for scope, symbols in references_by_scope.items(): + if is_operation and ("." not in scope or scope.rsplit(".", maxsplit=1)[-1].startswith("_")): + continue + location = f"{relative_path.as_posix()}::{scope}" + target = operation_references if is_operation else other_references + for model_name in expand_models(symbols): + target[model_name].add(location) + +# These protocol/runtime models are owned by public operations but are intentionally +# absent from their Python signatures: WebSocket messages flow over the upgraded +# connection, and the memory update result is consumed by a custom polling method. +runtime_operation_owners = { + "RealtimeClientEvent": "azure/ai/projects/operations/_operations.py::BetaVoiceAgentsRealtimeOperations._connect_voice_agent", + "RealtimeServerEvent": "azure/ai/projects/operations/_operations.py::BetaVoiceAgentsRealtimeOperations._connect_voice_agent", + "RealtimeServerEventError": "azure/ai/projects/operations/_operations.py::BetaVoiceAgentsRealtimeOperations._connect_voice_agent", + "VoiceAgentClientEventSessionUpdate": "azure/ai/projects/operations/_operations.py::BetaVoiceAgentsRealtimeOperations._connect_voice_agent", + "VoiceAgentSessionResponseConfig": "azure/ai/projects/operations/_operations.py::BetaVoiceAgentsRealtimeOperations._connect_voice_agent", + "VoiceAgentSessionUpdateConfig": "azure/ai/projects/operations/_operations.py::BetaVoiceAgentsRealtimeOperations._connect_voice_agent", + "MemoryStoreUpdateResult": "azure/ai/projects/operations/_patch_memories.py::BetaMemoryStoresOperations.begin_update_memories", + "UpdateToolboxRequest": "azure/ai/projects/operations/_operations.py::ToolboxesOperations.update", +} +for model_name, operation in runtime_operation_owners.items(): + operation_references[model_name].add(operation) + + +def reverse_reachability(start: str) -> tuple[set[str], dict[str, tuple[str, ...]]]: + reached: set[str] = set() + shortest_paths: dict[str, tuple[str, ...]] = {start: (start,)} + pending: deque[str] = deque([start]) + while pending: + current = pending.popleft() + for referrer in sorted(outward_models(current)): + if referrer in shortest_paths: + continue + reached.add(referrer) + shortest_paths[referrer] = (*shortest_paths[current], referrer) + pending.append(referrer) + return reached, shortest_paths + + +graph: dict[str, object] = {} +models_with_operation_paths = 0 +for name in sorted(known_models): + indirect_referrers, shortest_paths = reverse_reachability(name) + direct_referrers = direct_model_referrers[name] + indirect_only = indirect_referrers - direct_referrers - model_bases[name] + + direct_operations = set(operation_references[name]) + indirect_operations: set[str] = set() + paths_to_operations: list[dict[str, object]] = [] + for referring_model, model_path in sorted(shortest_paths.items()): + for operation in sorted(operation_references[referring_model]): + if referring_model != name: + indirect_operations.add(operation) + paths_to_operations.append( + { + "operation": operation, + "modelPath": list(reversed(model_path)), + } + ) + + all_operations = direct_operations | indirect_operations + if all_operations: + models_with_operation_paths += 1 + + all_other_references: set[str] = set(other_references[name]) + for referring_model in indirect_referrers: + all_other_references.update(other_references[referring_model]) + + graph[name] = { + "definedLine": model_nodes[name].lineno, + "publiclyExported": name in public_exports, + "baseModels": sorted(model_bases[name]), + "derivedModels": sorted(model_subclasses[name]), + "referencesModels": sorted(model_dependencies[name]), + "directModelReferrers": sorted(direct_referrers), + "indirectModelReferrers": sorted(indirect_only), + "directOperationReferences": sorted(direct_operations), + "indirectOperationReferences": sorted(indirect_operations - direct_operations), + "pathsToOperations": paths_to_operations, + "otherReferences": sorted(all_other_references), + } + +models_without_operation_paths = [ + name for name in sorted(known_models) if not graph[name]["pathsToOperations"] +] + +document = { + "metadata": { + "modelsPath": models_path.relative_to(package_root).as_posix(), + "modelCount": len(known_models), + "modelsWithOperationPaths": models_with_operation_paths, + "modelsWithoutOperationPaths": len(models_without_operation_paths), + "modelsWithoutOperationPathNames": models_without_operation_paths, + "explicitRuntimeOperationOwners": runtime_operation_owners, + "pathSemantics": "Each path is operation -> referring models -> keyed model. One shortest model path is emitted for each reachable operation reference.", + }, + "models": graph, +} + + +def operation_scope(location: str) -> str: + return location.split("::", maxsplit=1)[-1] + + +def render_tree(root: str) -> list[str]: + lines = [root] + expanded = {root} + + def append_children(current: str, prefix: str, ancestors: set[str]) -> None: + base_children = [("base", name) for name in sorted(model_bases[current])] + derived_children = [ + ("derived", name) + for name in sorted(model_subclasses[current] - ancestors) + ] + model_children = [ + ("model", name) + for name in sorted(direct_model_referrers[current] - ancestors) + ] + operation_children = [ + ("operation", name) + for name in sorted({operation_scope(location) for location in operation_references[current]}) + ] + children = base_children + derived_children + model_children + operation_children + if not children: + lines.append(f"{prefix}`- [no model or operation referrer]") + return + + for index, (kind, name) in enumerate(children): + is_last = index == len(children) - 1 + connector = "`-" if is_last else "+-" + child_prefix = f"{prefix}{' ' if is_last else '| '}" + if kind == "operation": + lines.append(f"{prefix}{connector} {name} [operation]") + continue + + if kind == "base": + label = f"{name} [base class]" + elif kind == "derived": + label = f"{name} [derived class]" + else: + label = name + + if name in ancestors: + lines.append(f"{prefix}{connector} {label} [cycle]") + continue + if name in expanded: + lines.append(f"{prefix}{connector} {label} [already expanded]") + continue + + lines.append(f"{prefix}{connector} {label}") + expanded.add(name) + append_children(name, child_prefix, ancestors | {name}) + + append_children(root, " ", {root}) + return lines + + +output_path.parent.mkdir(parents=True, exist_ok=True) +output_path.write_text( + json.dumps(document, indent=2, sort_keys=False) + "\n", + encoding="utf-8", + newline="\n", +) + +tree_lines = [ + "Model reference trees", + "=====================", + "", + "Each root is a model from _models.py. Child models directly reference their parent.", + "[base class] marks traversal from a derived model to a base type accepted by other models or operations.", + "[derived class] marks traversal from a base model to a derived model used by other models or operations.", + "Operation leaves are deduplicated across sync and async files by class and method name.", + "[already expanded] marks a shared branch rendered elsewhere under the same root.", + "[cycle] marks a reference cycle.", + "", + "Summary", + "-------", + "", + f"Models: {len(known_models)}", + f"Models with a path to a public operation: {models_with_operation_paths}", + f"Models with no path to a public operation: {len(models_without_operation_paths)}", + "", + "Models with no path to a public operation:", + *([f"- {name}" for name in models_without_operation_paths] if models_without_operation_paths else ["- None"]), + "", + "Trees", + "-----", + "", +] +for model_name in sorted(known_models): + tree_lines.extend(render_tree(model_name)) + tree_lines.append("") + +tree_output_path.parent.mkdir(parents=True, exist_ok=True) +tree_output_path.write_text("\n".join(tree_lines), encoding="utf-8", newline="\n") +print( + f"Generated graph for {len(known_models)} models; " + f"{models_with_operation_paths} have a path to an operation." +) +print(f"Graph: {output_path}") +print(f"Trees: {tree_output_path}") +'@ + +try { + [System.IO.File]::WriteAllText($temporaryScript, $pythonScript, [System.Text.UTF8Encoding]::new($false)) + & $PythonExecutable $temporaryScript $packageRoot $ModelsPath $OutputPath $TreeOutputPath + if ($LASTEXITCODE -ne 0) { + throw "Model reference graph generation failed with exit code $LASTEXITCODE." + } +} +finally { + Remove-Item $temporaryScript -Force -ErrorAction SilentlyContinue +} \ No newline at end of file diff --git a/sdk/ai/azure-ai-projects/.github/skills/azure-ai-projects-update-changelog/SKILL.md b/sdk/ai/azure-ai-projects/.github/skills/azure-ai-projects-update-changelog/SKILL.md index 297c15893e93..cc40b0977f76 100644 --- a/sdk/ai/azure-ai-projects/.github/skills/azure-ai-projects-update-changelog/SKILL.md +++ b/sdk/ai/azure-ai-projects/.github/skills/azure-ai-projects-update-changelog/SKILL.md @@ -133,7 +133,7 @@ For each new sample, provide a one-line description of what it demonstrates. Rea Organize detected changes into these categories: ### Features Added -- New sub-clients (e.g., "New `.beta.routines` sub-client with routine operations: `create_or_update`, `get`, `enable`, ...") +- New sub-clients (e.g., "New `.beta.routines` sub-client for creating, scheduling, and managing routines.") - New methods on existing sub-clients (e.g., "New methods on `.beta.agents` for optimization jobs: `create_optimization_job`, `get_optimization_job`, ...") - New model classes that represent significant features (e.g., "Support integration of external Agents. See new `ExternalAgentDefinition` class.") - New properties on existing classes (e.g., "New optional `force` parameter on `agents.delete` method.") @@ -201,7 +201,7 @@ Breaking changes in beta classes: **Guidelines for writing entries:** - For new methods: mention the sub-client and method name, briefly describe what it does. Only report the sync version — do not list both sync and async versions separately. -- For new sub-clients: list all the methods it provides (sync versions only) +- For new sub-clients: summarize the capability the sub-client provides; do not enumerate all of its methods. - For new tools: just mention the class name - For property changes: mention the class name and the affected property - For renames: show "X renamed to Y" format @@ -282,9 +282,9 @@ Here's an example of a well-formatted changelog entry: * Optimization jobs: `create_optimization_job`, `get_optimization_job`, `list_optimization_jobs`, `cancel_optimization_job`, `list_optimization_candidates`. * Optimization candidate management: `list_optimization_candidates`, `get_optimization_candidate`, `get_optimization_candidate_config`, `get_optimization_candidate_results`, `get_candidate_file`, `promote_candidate`. * `stop_session` to stop a running agent session. -* New `.beta.datasets` sub-client with data generation job operations: `create_generation_job`, `get_generation_job`, `list_generation_jobs`, `cancel_generation_job`, `delete_generation_job`. -* New `.beta.models` sub-client to handle AI model weights: `create`, `list_versions`, `list`, `get`, `delete`, `update`, `pending_create_version`, `pending_upload`, `get_credentials`. -* New `.beta.routines` sub-client with routine operations: `create_or_update`, `get`, `enable`, `disable`, `list`, `delete`, `list_runs`, `dispatch`. +* New `.beta.datasets` sub-client for creating, monitoring, and managing data generation jobs. +* New `.beta.models` sub-client for registering, versioning, and managing AI model weights. +* New `.beta.routines` sub-client for creating, scheduling, and managing routines and their runs. * New methods on `.beta.evaluators` for evaluator generation jobs: `create_generation_job`, `get_generation_job`, `list_generation_jobs`, `cancel_generation_job`, `delete_generation_job`. * New methods on `.beta.memory_stores` to handle individual memory items: `create_memory`, `update_memory`, `list_memories`, `get_memory`, `delete_memory`. * New methods on `.beta.skills` for versioned skill management: `create`, `list_versions`, `get_version`, `download_version`, `delete_version`. diff --git a/sdk/ai/azure-ai-projects/CHANGELOG.md b/sdk/ai/azure-ai-projects/CHANGELOG.md index a7ecc1685348..7cbbb7221081 100644 --- a/sdk/ai/azure-ai-projects/CHANGELOG.md +++ b/sdk/ai/azure-ai-projects/CHANGELOG.md @@ -1,5 +1,45 @@ # Release History +## 2.7.0 (2026-09-18) + +### Features Added + +* Added preview Voice Agent support, including voice agent definitions, realtime sessions and events, conversations, audio, and telephony models. +* Added `.beta.agents.create_from_prompt()` to generate and create a Voice Agent from high-level inputs. +* Added the `.beta.voice_agents.conversations` sub-client for managing voice conversations and retrieving their responses, conversation items, and audio. +* Added `.beta.voice_agents.realtime.connect()` for sync and async realtime Voice Agent sessions with typed client and server events. +* Added the `.beta.voice_agents.telephony` sub-client for managing calls, bindings, transfer targets, and durable outbound call jobs. +* Added optional `harness` and `skills` properties to `PromptAgentDefinition`, with new GitHub Copilot harness, toolset, and skill-reference models. +* Added invocation moderation through `RaiConfig.invocations_moderation` and `RaiInvocationModeration`. +* Added `ToolboxesOperations.invoke_latest_toolbox_mcp()` and toolbox version metadata through `ToolboxObject.updated_at` and `ToolboxObject.versions`. +* Added `DataGenerationJobOutputOptions.write_mode` for controlling dataset output writes and `TracesDataGenerationJobSource.trace_ids` for selecting explicit traces. +* Made `TracesDataGenerationJobOptions.max_samples` optional. +* Added read-only agent lifecycle properties `AgentDetails.configuration_state` and `AgentSessionResource.stopped_at`. + +### Breaking Changes + +Breaking changes in beta classes: + +* Removed the `max_samples` constructor argument and property from `DataGenerationJobOptions` and `SimulationSeedDataGenerationJobOptions`. +* The `ToolboxObject` constructor now requires `updated_at` and `versions`. + +### Dependency update + +* Added the optional `voice` dependency group, which installs `websockets` for sync realtime Voice Agent sessions and `aiohttp` for async sessions. + +### Sample updates + +* Added `sample_voice_agent_basic.py` under `samples/agents/voice/`, demonstrating the Voice Agent management lifecycle. +* Added `sample_voice_agent_generate.py`, demonstrating guided Voice Agent authoring with `.beta.agents.create_from_prompt()`. +* Added `sample_voice_agent_live_text_conversation.py`, demonstrating a persisted, typed realtime Voice Agent conversation. +* Added `sample_voice_agent_live_audio_conversation_async.py`, demonstrating a hands-free realtime audio conversation with barge-in. +* Added `sample_voice_agent_live_function_tool.py`, demonstrating client-side function execution during a realtime Voice Agent session. +* Added `sample_voice_agent_read_conversation.py`, demonstrating how to read a persisted Voice Agent conversation and transcript. +* Added `sample_voice_agent_read_conversation_audio.py`, demonstrating how to retrieve merged conversation audio and individual audio segments. +* Added `sample_voice_agent_versions.py`, demonstrating Voice Agent version and draft management. +* Added `sample_voice_agent_with_tools.py`, demonstrating audio configuration, tools, and self-deployed models. +* Updated `sample_synthetic_multiturn_evaluation.py` to set the service-required simulation seed `max_samples` field through the model's mapping interface because `SimulationSeedDataGenerationJobOptions` no longer exposes it as a constructor argument. + ## 2.6.1 (2026-09-14) ### Sample updates diff --git a/sdk/ai/azure-ai-projects/PostEmitter.ps1 b/sdk/ai/azure-ai-projects/PostEmitter.ps1 index 129b8b4bbd12..ffbc1a0d5779 100644 --- a/sdk/ai/azure-ai-projects/PostEmitter.ps1 +++ b/sdk/ai/azure-ai-projects/PostEmitter.ps1 @@ -73,6 +73,63 @@ foreach ($line in $lines) { } Set-Content $f $out +# Normalize generated reStructuredText bullet lists in model and enum docstrings. +# Join incorrectly indented continuations, then reflow long bullets with valid continuation indentation. +$files = 'azure\ai\projects\models\_models.py', 'azure\ai\projects\models\_enums.py' +foreach ($f in $files) { + $lines = Get-Content $f + $out = @() + $inDocstring = $false + $inBulletList = $false + for ($i = 0; $i -lt $lines.Length; $i++) { + $line = $lines[$i] + $trimmed = $line.TrimStart() + $quoteCount = ([regex]::Matches($line, '"""')).Count + $isClosingQuote = $trimmed -eq '"""' + $isContinuation = $trimmed -match '^[a-z0-9`(]' + if ($inDocstring -and $inBulletList -and $isContinuation -and $line -match '^\s{4}\S') { + while ($out.Count -gt 0 -and -not $out[-1].Trim()) { $out = $out[0..($out.Count - 2)] } + if ($out.Count -gt 0) { + $out[-1] = $out[-1].TrimEnd() + ' ' + $trimmed + continue + } + } + if ($inDocstring -and $inBulletList -and $trimmed -match '^\:') { + if ($out.Count -gt 0 -and $out[-1].Trim()) { $out += '' } + $inBulletList = $false + } + $out += $line + if ($trimmed -match '^\*\s') { $inBulletList = $true } + if ($quoteCount % 2 -eq 1 -and -not $isClosingQuote) { $inDocstring = -not $inDocstring } + if ($isClosingQuote) { $inDocstring = $false; $inBulletList = $false } + } + $wrapped = @() + foreach ($line in $out) { + if ($line.Length -le 120 -or $line -notmatch '^(\s*)\*\s+(.+)$') { + $wrapped += $line + continue + } + + $firstPrefix = $Matches[1] + '* ' + $continuationPrefix = $Matches[1] + ' ' + $prefix = $firstPrefix + $currentLine = $prefix + foreach ($word in $Matches[2] -split '\s+') { + if ($currentLine.Length -gt $prefix.Length -and $currentLine.Length + 1 + $word.Length -gt 120) { + $wrapped += $currentLine + $prefix = $continuationPrefix + $currentLine = $prefix + $word + } + else { + $separator = if ($currentLine.Length -eq $prefix.Length) { '' } else { ' ' } + $currentLine += $separator + $word + } + } + $wrapped += $currentLine + } + Set-Content $f $wrapped +} + # Fix Sphinx docutils warnings in get_session_log_stream docstrings (sync + async). # The emitter wraps bullet/code-block lines with insufficient indentation. $files = 'azure\ai\projects\operations\_operations.py', 'azure\ai\projects\aio\operations\_operations.py' @@ -86,14 +143,49 @@ foreach ($f in $files) { Set-Content $f $c -NoNewline } -# Finishing by running 'black' tool to format code. -pip install black +# Wrap forward-reference-only aliases in Union so they are valid runtime type aliases. +$f = 'azure\ai\projects\_unions.py' +$c = Get-Content $f -Raw +$c = $c -replace '(?m)^([A-Za-z_][A-Za-z0-9_]*\s*=\s*)"([^"\r\n]+)"\s*$', '$1Union["$2"]' +# Remove the duplicate VoiceAgentToolChoice alias emitted by some TypeSpec versions. +$duplicateVoiceAgentToolChoice = '(?ms)\r?\nVoiceAgentToolChoice = Union\[\r?\n Literal\["none"\], Literal\["auto"\], Literal\["required"\], "_models\.ToolChoiceFunction", "_models\.ToolChoiceMCP"\r?\n\]' +$firstVoiceAgentToolChoice = [regex]::Match($c, $duplicateVoiceAgentToolChoice) +if ($firstVoiceAgentToolChoice.Success) { + $secondStart = $firstVoiceAgentToolChoice.Index + $firstVoiceAgentToolChoice.Length + $second = [regex]::Match($c.Substring($secondStart), $duplicateVoiceAgentToolChoice) + if ($second.Success) { + $removeStart = $secondStart + $second.Index + $c = $c.Remove($removeStart, $second.Length) + } +} +Set-Content $f $c -NoNewline + +# Remove invalid single overload stubs for BetaAgentsOperations.generate/create_from_prompt. +$files = 'azure\ai\projects\operations\_operations.py', 'azure\ai\projects\aio\operations\_operations.py' +foreach ($f in $files) { + $c = Get-Content $f -Raw + $c = $c -replace '(?ms)\r?\n @overload\r?\n (?:async )?def (?:generate|create_from_prompt)\(\r?\n self, body: _models\.GenerateVoiceAgentRequest, \*, content_type: str = "application/json", \*\*kwargs: Any\r?\n \) -> _models\.AgentDetails:\r?\n """Generate an agent\..*? """\r?\n\r?\n(?= @distributed_trace)', "`r`n" + $c = $c -replace '(?ms)\r?\n @overload\r?\n async def (?:generate|create_from_prompt)\(\r?\n self, body: _models\.GenerateVoiceAgentRequest, \*, content_type: str = "application/json", \*\*kwargs: Any\r?\n \) -> _models\.AgentDetails:\r?\n """Generate an agent\..*? """\r?\n\r?\n(?= @distributed_trace_async)', "`r`n" + Set-Content $f $c -NoNewline +} + +# Complete generated MatchConditions support for TypeSpec Azure.Core.eTag parameters. +# The emitter generates prep_if_match(etag, match_condition), but omits the helper, +# imports, match_condition parameters, and arguments that the generated call path needs. +& (Join-Path $PSScriptRoot 'scripts\FixMatchConditions.ps1') -PackageRoot $PSScriptRoot + +# Finishing by running 'black' tool to format code. black --config ../../../eng/black-pyproject.toml . # Regenerate API review artifacts and the public method inventory. +$pythonExecutable = (Get-Command python -ErrorAction Stop).Source +& $pythonExecutable -m pip install --no-deps --editable . +if ($LASTEXITCODE -ne 0) { + throw "Editable package installation failed with exit code $LASTEXITCODE." +} azpysdk apistub . $apiStubExitCode = $LASTEXITCODE -.\GeneratePublicMethods.ps1 +.\docs\GeneratePublicMethodsDoc.ps1 -PythonExecutable $pythonExecutable if ($apiStubExitCode -ne 0) { throw "API stub generation failed with exit code $apiStubExitCode." } diff --git a/sdk/ai/azure-ai-projects/README.md b/sdk/ai/azure-ai-projects/README.md index 891d029765fd..a8c65f8735ca 100644 --- a/sdk/ai/azure-ai-projects/README.md +++ b/sdk/ai/azure-ai-projects/README.md @@ -4,6 +4,7 @@ The AI Projects client library is part of the Microsoft Foundry SDK, and provide resources in your [Microsoft Foundry](https://ai.azure.com/) Project. Use it to: * **Create and run Agents** using methods on the `.agents` client property. This includes **Hosted Agents**, which let you run your own containerized agent runtime while using Microsoft Foundry for managed hosting and scaling. +* **Build and run Voice Agents (preview)** for real-time, speech-to-speech conversational AI, reachable over a WebSocket (`.beta.voice_agents.realtime`) or telephony (`.beta.voice_agents.telephony`), with persisted conversation transcripts and audio through `.beta.voice_agents.conversations`. * **Enhance Agents with specialized tools and toolbox tools** such as: * Agent-to-Agent (A2A) * Azure AI Search @@ -192,6 +193,7 @@ The table below lists the operation groups supported by the client library, with | Sessions | [Manage hosted sessions](https://learn.microsoft.com/azure/foundry/agents/how-to/manage-hosted-sessions?pivots=python) | `samples/hosted_agents/` | | Skills (preview) | | `samples/skills/` | | Toolboxes | [Curate intent-based toolbox in Foundry](https://learn.microsoft.com/azure/foundry/agents/how-to/tools/toolbox?pivots=python) | `samples/hosted_agents/`, `samples/toolboxes/` | +| Voice agents (preview) | | `samples/agents/voice/` | ## Client-side tracing diff --git a/sdk/ai/azure-ai-projects/api.md b/sdk/ai/azure-ai-projects/api.md index c45fbcf28b86..23cf22b76295 100644 --- a/sdk/ai/azure-ai-projects/api.md +++ b/sdk/ai/azure-ai-projects/api.md @@ -517,6 +517,75 @@ namespace azure.ai.projects.aio.operations ) -> SessionFileWriteResult: ... + class azure.ai.projects.aio.operations.AsyncBetaRealtime: + + def __init__( + self, + *args: Any, + **kwargs: Any + ) -> None: ... + + def connect( + self, + *, + agent_name: str, + agent_session_id: Optional[str] = ..., + api_version: Optional[str] = ..., + connection_url: Optional[str] = ..., + credential_scopes: Optional[List[str]] = ..., + extra_headers: Optional[Mapping[str, str]] = ..., + extra_query: Optional[Mapping[str, str]] = ..., + structured_inputs: Optional[Mapping[str, Any]] = ..., + **kwargs: Any + ) -> AsyncBetaRealtimeConnectionManager: ... + + + class azure.ai.projects.aio.operations.AsyncBetaRealtimeConnection: implements AsyncContextManager + property closed: bool # Read-only + + def __aiter__(self) -> AsyncIterator[ServerEvent]: ... + + def __init__( + self, + connection: ClientWebSocketResponse, + session: ClientSession + ) -> None: ... + + def __repr__(self) -> str: ... + + async def close( + self, + *, + code: int = 1000, + reason: str = "" + ) -> None: ... + + async def recv(self) -> ServerEvent: ... + + async def send(self, event: ClientEvent) -> None: ... + + + class azure.ai.projects.aio.operations.AsyncBetaRealtimeConnectionManager: implements AsyncContextManager + + def __init__( + self, + *, + agent_name: str, + agent_session_id: Optional[str] = ..., + api_version: str, + connection_url: Optional[str] = ..., + credential: AsyncTokenCredential, + credential_scopes: List[str], + endpoint: str, + extra_headers: Optional[Mapping[str, str]] = ..., + extra_query: Optional[Mapping[str, str]] = ..., + structured_inputs: Optional[Mapping[str, Any]] = ..., + **kwargs: Any + ) -> None: ... + + async def enter(self) -> AsyncBetaRealtimeConnection: ... + + class azure.ai.projects.aio.operations.BetaAgentInsightMonitorsOperations(BetaAgentInsightMonitorsOperationsGenerated): def __init__( @@ -780,6 +849,13 @@ namespace azure.ai.projects.aio.operations **kwargs: Any ) -> AgentOptimizationJob: ... + @distributed_trace_async + async def create_from_prompt( + self, + body: GenerateAgentRequest, + **kwargs: Any + ) -> AgentDetails: ... + @distributed_trace_async async def delete_optimization_job( self, @@ -1787,6 +1863,7 @@ namespace azure.ai.projects.aio.operations routines: BetaRoutinesOperations schedules: BetaSchedulesOperations skills: BetaSkillsOperations + voice_agents: BetaVoiceAgentsOperations def __init__( self, @@ -2196,7 +2273,7 @@ namespace azure.ai.projects.aio.operations ) -> SkillDetails: ... - class azure.ai.projects.aio.operations.ConnectionsOperations(ConnectionsOperationsGenerated): + class azure.ai.projects.aio.operations.BetaVoiceAgentsConversationsOperations: def __init__( self, @@ -2205,166 +2282,153 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @distributed_trace_async - async def get( + async def delete( self, - name: str, - *, - include_credentials: Optional[bool] = False, + agent_name: str, + conversation_id: str, **kwargs: Any - ) -> Connection: ... + ) -> None: ... @distributed_trace_async - async def get_default( + async def download_audio( self, - connection_type: Union[str, ConnectionType], - *, - include_credentials: Optional[bool] = False, + agent_name: str, + conversation_id: str, **kwargs: Any - ) -> Connection: ... + ) -> AsyncIterator[bytes]: ... - @distributed_trace - def list( + @distributed_trace_async + async def download_audio_item( self, - *, - connection_type: Optional[Union[str, ConnectionType]] = ..., - default_connection: Optional[bool] = ..., + agent_name: str, + conversation_id: str, + item_id: str, **kwargs: Any - ) -> AsyncItemPaged[Connection]: ... - - - class azure.ai.projects.aio.operations.DatasetsOperations(DatasetsOperationsGenerated): - - def __init__( - self, - *args, - **kwargs - ) -> None: ... + ) -> AsyncIterator[bytes]: ... - @overload - async def create_or_update( + @distributed_trace_async + async def download_generated_audio_item( self, - name: str, - version: str, - dataset_version: DatasetVersion, - *, - content_type: str = "application/merge-patch+json", + agent_name: str, + conversation_id: str, + item_id: str, **kwargs: Any - ) -> DatasetVersion: ... + ) -> AsyncIterator[bytes]: ... - @overload - async def create_or_update( + @distributed_trace_async + async def get( self, - name: str, - version: str, - dataset_version: JSON, - *, - content_type: str = "application/merge-patch+json", + agent_name: str, + conversation_id: str, **kwargs: Any - ) -> DatasetVersion: ... + ) -> VoiceConversation: ... - @overload - async def create_or_update( + @distributed_trace_async + async def get_audio( self, - name: str, - version: str, - dataset_version: IO[bytes], - *, - content_type: str = "application/merge-patch+json", + agent_name: str, + conversation_id: str, **kwargs: Any - ) -> DatasetVersion: ... + ) -> VoiceRecording: ... @distributed_trace_async - async def delete( + async def get_audio_item( self, - name: str, - version: str, + agent_name: str, + conversation_id: str, + item_id: str, **kwargs: Any - ) -> None: ... + ) -> VoiceAudioItem: ... @distributed_trace_async - async def get( + async def get_generated_audio_item( self, - name: str, - version: str, + agent_name: str, + conversation_id: str, + item_id: str, **kwargs: Any - ) -> DatasetVersion: ... + ) -> VoiceGeneratedAudioItem: ... @distributed_trace_async - async def get_credentials( + async def get_item( self, - name: str, - version: str, + agent_name: str, + conversation_id: str, + item_id: str, **kwargs: Any - ) -> DatasetCredential: ... - - @distributed_trace - def list(self, **kwargs: Any) -> AsyncItemPaged[DatasetVersion]: ... + ) -> RealtimeConversationItem: ... - @distributed_trace - def list_versions( + @distributed_trace_async + async def get_response( self, - name: str, + agent_name: str, + conversation_id: str, + response_id: str, **kwargs: Any - ) -> AsyncItemPaged[DatasetVersion]: ... + ) -> VoiceResponse: ... - @overload - async def pending_upload( + @distributed_trace + def list( self, - name: str, - version: str, - pending_upload_request: PendingUploadRequest, + agent_name: str, *, - content_type: str = "application/json", + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> PendingUploadResponse: ... + ) -> AsyncItemPaged[VoiceConversation]: ... - @overload - async def pending_upload( + @distributed_trace + def list_items( self, - name: str, - version: str, - pending_upload_request: JSON, + agent_name: str, + conversation_id: str, *, - content_type: str = "application/json", + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> PendingUploadResponse: ... + ) -> AsyncItemPaged[RealtimeConversationItem]: ... - @overload - async def pending_upload( + @distributed_trace + def list_response_items( self, - name: str, - version: str, - pending_upload_request: IO[bytes], + agent_name: str, + conversation_id: str, + response_id: str, *, - content_type: str = "application/json", + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> PendingUploadResponse: ... + ) -> AsyncItemPaged[RealtimeConversationItem]: ... - @distributed_trace_async - async def upload_file( + @distributed_trace + def list_responses( self, + agent_name: str, + conversation_id: str, *, - connection_name: Optional[str] = ..., - file_path: str, - name: str, - version: str, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> FileDatasetVersion: ... + ) -> AsyncItemPaged[VoiceResponse]: ... - @distributed_trace_async - async def upload_folder( + + class azure.ai.projects.aio.operations.BetaVoiceAgentsOperations(GeneratedBetaVoiceAgentsOperations): + conversations: BetaVoiceAgentsConversationsOperations + realtime: AsyncBetaRealtime + telephony: BetaVoiceAgentsTelephonyOperations + + def __init__( self, - *, - connection_name: Optional[str] = ..., - file_pattern: Optional[Pattern] = ..., - folder: str, - name: str, - version: str, + *args: Any, **kwargs: Any - ) -> FolderDatasetVersion: ... + ) -> None: ... - class azure.ai.projects.aio.operations.DeploymentsOperations: + class azure.ai.projects.aio.operations.BetaVoiceAgentsTelephonyOperations: def __init__( self, @@ -2373,163 +2437,303 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @distributed_trace_async - async def get( + async def cancel_call_job( self, - name: str, + agent_name: str, + call_job_id: str, + *, + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> Deployment: ... + ) -> TelephonyCallJob: ... - @distributed_trace - def list( + @overload + async def create_binding( self, + agent_name: str, + telephony_binding: CreateTelephonyBindingRequest, *, - deployment_type: Optional[Union[str, DeploymentType]] = ..., - model_name: Optional[str] = ..., - model_publisher: Optional[str] = ..., + content_type: str = "application/json", **kwargs: Any - ) -> AsyncItemPaged[Deployment]: ... + ) -> TelephonyBinding: ... + @overload + async def create_binding( + self, + agent_name: str, + telephony_binding: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyBinding: ... - class azure.ai.projects.aio.operations.EvaluationRulesOperations(GeneratedEvaluationRulesOperations): - - def __init__( + @overload + async def create_binding( self, - *args, - **kwargs - ) -> None: ... + agent_name: str, + telephony_binding: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyBinding: ... @overload - async def create_or_update( + async def create_call_job( self, - id: str, - evaluation_rule: EvaluationRule, + agent_name: str, + body: CreateTelephonyCallJobRequest, *, content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> EvaluationRule: ... + ) -> TelephonyCallJob: ... @overload - async def create_or_update( + async def create_call_job( self, - id: str, - evaluation_rule: JSON, + agent_name: str, + body: JSON, *, content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> EvaluationRule: ... + ) -> TelephonyCallJob: ... @overload - async def create_or_update( + async def create_call_job( self, - id: str, - evaluation_rule: IO[bytes], + agent_name: str, + body: IO[bytes], *, content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> EvaluationRule: ... + ) -> TelephonyCallJob: ... @distributed_trace_async - async def delete( + async def delete_binding( self, - id: str, + agent_name: str, + binding_id: str, + *, + etag: str, + match_condition: MatchConditions, **kwargs: Any ) -> None: ... @distributed_trace_async - async def get( + async def end_call( self, - id: str, + agent_name: str, + call_id: str, **kwargs: Any - ) -> EvaluationRule: ... + ) -> TelephonyCallRecord: ... + + @distributed_trace_async + async def get_binding( + self, + agent_name: str, + binding_id: str, + **kwargs: Any + ) -> TelephonyBinding: ... + + @distributed_trace_async + async def get_call( + self, + agent_name: str, + call_id: str, + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @distributed_trace_async + async def get_call_job( + self, + agent_name: str, + call_job_id: str, + **kwargs: Any + ) -> TelephonyCallJob: ... + + @distributed_trace_async + async def get_transfer_targets( + self, + agent_name: str, + **kwargs: Any + ) -> TelephonyTransferTargets: ... @distributed_trace - def list( + def list_bindings( self, + agent_name: str, *, - action_type: Optional[Union[str, EvaluationRuleActionType]] = ..., - agent_name: Optional[str] = ..., - enabled: Optional[bool] = ..., + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + provider: Optional[Union[str, TelephonyProvider]] = ..., + status: Optional[Union[str, TelephonyBindingStatus]] = ..., **kwargs: Any - ) -> AsyncItemPaged[EvaluationRule]: ... + ) -> AsyncItemPaged[TelephonyBindingListItem]: ... + @distributed_trace + def list_calls( + self, + agent_name: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + provider: Optional[Union[str, TelephonyProvider]] = ..., + started_after_time: Optional[datetime] = ..., + started_before_time: Optional[datetime] = ..., + status: Optional[Union[str, TelephonyCallStatus]] = ..., + **kwargs: Any + ) -> AsyncItemPaged[TelephonyCallSummary]: ... - class azure.ai.projects.aio.operations.IndexesOperations: + @overload + async def replace_transfer_targets( + self, + agent_name: str, + *, + content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, + transfer_targets: List[TelephonyTransferTarget], + **kwargs: Any + ) -> TelephonyTransferTargets: ... - def __init__( + @overload + async def replace_transfer_targets( self, - *args, - **kwargs - ) -> None: ... + agent_name: str, + body: JSON, + *, + content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyTransferTargets: ... @overload - async def create_or_update( + async def replace_transfer_targets( self, - name: str, - version: str, - index: Index, + agent_name: str, + body: IO[bytes], *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> Index: ... + ) -> TelephonyTransferTargets: ... @overload - async def create_or_update( + async def transfer_call( self, - name: str, - version: str, - index: JSON, + agent_name: str, + call_id: str, + *, + content_type: str = "application/json", + target: str, + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @overload + async def transfer_call( + self, + agent_name: str, + call_id: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @overload + async def transfer_call( + self, + agent_name: str, + call_id: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @overload + async def update_binding( + self, + agent_name: str, + binding_id: str, + body: UpdateTelephonyBindingRequest, *, content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> Index: ... + ) -> TelephonyBinding: ... @overload - async def create_or_update( + async def update_binding( self, - name: str, - version: str, - index: IO[bytes], + agent_name: str, + binding_id: str, + body: JSON, *, content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> Index: ... + ) -> TelephonyBinding: ... - @distributed_trace_async - async def delete( + @overload + async def update_binding( self, - name: str, - version: str, + agent_name: str, + binding_id: str, + body: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, **kwargs: Any + ) -> TelephonyBinding: ... + + + class azure.ai.projects.aio.operations.ConnectionsOperations(ConnectionsOperationsGenerated): + + def __init__( + self, + *args, + **kwargs ) -> None: ... @distributed_trace_async async def get( self, name: str, - version: str, + *, + include_credentials: Optional[bool] = False, **kwargs: Any - ) -> Index: ... + ) -> Connection: ... - @distributed_trace - def list(self, **kwargs: Any) -> AsyncItemPaged[Index]: ... + @distributed_trace_async + async def get_default( + self, + connection_type: Union[str, ConnectionType], + *, + include_credentials: Optional[bool] = False, + **kwargs: Any + ) -> Connection: ... @distributed_trace - def list_versions( + def list( self, - name: str, + *, + connection_type: Optional[Union[str, ConnectionType]] = ..., + default_connection: Optional[bool] = ..., **kwargs: Any - ) -> AsyncItemPaged[Index]: ... - - - class azure.ai.projects.aio.operations.TelemetryOperations: - - def __init__(self, outer_instance: AIProjectClient) -> None: ... - - @distributed_trace_async - async def get_application_insights_connection_string(self) -> str: ... + ) -> AsyncItemPaged[Connection]: ... - class azure.ai.projects.aio.operations.ToolboxesOperations: + class azure.ai.projects.aio.operations.DatasetsOperations(DatasetsOperationsGenerated): def __init__( self, @@ -2538,48 +2742,40 @@ namespace azure.ai.projects.aio.operations ) -> None: ... @overload - async def create_version( + async def create_or_update( self, name: str, + version: str, + dataset_version: DatasetVersion, *, - content_type: str = "application/json", - description: Optional[str] = ..., - metadata: Optional[dict[str, str]] = ..., - policies: Optional[ToolboxPolicies] = ..., - skills: Optional[List[ToolboxSkill]] = ..., - tools: List[ToolboxTool], + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> ToolboxVersionObject: ... + ) -> DatasetVersion: ... @overload - async def create_version( + async def create_or_update( self, name: str, - body: JSON, + version: str, + dataset_version: JSON, *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> ToolboxVersionObject: ... + ) -> DatasetVersion: ... @overload - async def create_version( + async def create_or_update( self, name: str, - body: IO[bytes], + version: str, + dataset_version: IO[bytes], *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> ToolboxVersionObject: ... + ) -> DatasetVersion: ... @distributed_trace_async async def delete( - self, - name: str, - **kwargs: Any - ) -> None: ... - - @distributed_trace_async - async def delete_version( self, name: str, version: str, @@ -2590,239 +2786,4565 @@ namespace azure.ai.projects.aio.operations async def get( self, name: str, + version: str, **kwargs: Any - ) -> ToolboxObject: ... + ) -> DatasetVersion: ... @distributed_trace_async - async def get_version( + async def get_credentials( self, name: str, version: str, **kwargs: Any - ) -> ToolboxVersionObject: ... + ) -> DatasetCredential: ... @distributed_trace - def list( - self, - *, - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., - **kwargs: Any - ) -> AsyncItemPaged[ToolboxObject]: ... + def list(self, **kwargs: Any) -> AsyncItemPaged[DatasetVersion]: ... @distributed_trace def list_versions( self, name: str, - *, - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> AsyncItemPaged[ToolboxVersionObject]: ... + ) -> AsyncItemPaged[DatasetVersion]: ... @overload - async def update( + async def pending_upload( self, name: str, + version: str, + pending_upload_request: PendingUploadRequest, *, content_type: str = "application/json", - default_version: str, **kwargs: Any - ) -> ToolboxObject: ... + ) -> PendingUploadResponse: ... @overload - async def update( + async def pending_upload( self, name: str, - body: JSON, + version: str, + pending_upload_request: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> ToolboxObject: ... + ) -> PendingUploadResponse: ... @overload - async def update( + async def pending_upload( self, name: str, - body: IO[bytes], + version: str, + pending_upload_request: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> ToolboxObject: ... - - -namespace azure.ai.projects.models - - class azure.ai.projects.models.A2APreviewTool(Tool, discriminator='a2a_preview'): - agent_card_path: Optional[str] - base_url: Optional[str] - project_connection_id: Optional[str] - send_credentials_for_agent_card: Optional[bool] - type: Literal[ToolType.A2A_PREVIEW] + ) -> PendingUploadResponse: ... - @overload - def __init__( + @distributed_trace_async + async def upload_file( self, *, - agent_card_path: Optional[str] = ..., - base_url: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - send_credentials_for_agent_card: Optional[bool] = ... - ) -> None: ... + connection_name: Optional[str] = ..., + file_path: str, + name: str, + version: str, + **kwargs: Any + ) -> FileDatasetVersion: ... - @overload + @distributed_trace_async + async def upload_folder( + self, + *, + connection_name: Optional[str] = ..., + file_pattern: Optional[Pattern] = ..., + folder: str, + name: str, + version: str, + **kwargs: Any + ) -> FolderDatasetVersion: ... + + + class azure.ai.projects.aio.operations.DeploymentsOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace_async + async def get( + self, + name: str, + **kwargs: Any + ) -> Deployment: ... + + @distributed_trace + def list( + self, + *, + deployment_type: Optional[Union[str, DeploymentType]] = ..., + model_name: Optional[str] = ..., + model_publisher: Optional[str] = ..., + **kwargs: Any + ) -> AsyncItemPaged[Deployment]: ... + + + class azure.ai.projects.aio.operations.EvaluationRulesOperations(GeneratedEvaluationRulesOperations): + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def create_or_update( + self, + id: str, + evaluation_rule: EvaluationRule, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> EvaluationRule: ... + + @overload + async def create_or_update( + self, + id: str, + evaluation_rule: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> EvaluationRule: ... + + @overload + async def create_or_update( + self, + id: str, + evaluation_rule: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> EvaluationRule: ... + + @distributed_trace_async + async def delete( + self, + id: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def get( + self, + id: str, + **kwargs: Any + ) -> EvaluationRule: ... + + @distributed_trace + def list( + self, + *, + action_type: Optional[Union[str, EvaluationRuleActionType]] = ..., + agent_name: Optional[str] = ..., + enabled: Optional[bool] = ..., + **kwargs: Any + ) -> AsyncItemPaged[EvaluationRule]: ... + + + class azure.ai.projects.aio.operations.IndexesOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def create_or_update( + self, + name: str, + version: str, + index: Index, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> Index: ... + + @overload + async def create_or_update( + self, + name: str, + version: str, + index: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> Index: ... + + @overload + async def create_or_update( + self, + name: str, + version: str, + index: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> Index: ... + + @distributed_trace_async + async def delete( + self, + name: str, + version: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def get( + self, + name: str, + version: str, + **kwargs: Any + ) -> Index: ... + + @distributed_trace + def list(self, **kwargs: Any) -> AsyncItemPaged[Index]: ... + + @distributed_trace + def list_versions( + self, + name: str, + **kwargs: Any + ) -> AsyncItemPaged[Index]: ... + + + class azure.ai.projects.aio.operations.TelemetryOperations: + + def __init__(self, outer_instance: AIProjectClient) -> None: ... + + @distributed_trace_async + async def get_application_insights_connection_string(self) -> str: ... + + + class azure.ai.projects.aio.operations.ToolboxesOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def create_version( + self, + name: str, + *, + content_type: str = "application/json", + description: Optional[str] = ..., + metadata: Optional[dict[str, str]] = ..., + policies: Optional[ToolboxPolicies] = ..., + skills: Optional[List[ToolboxSkill]] = ..., + tools: List[ToolboxTool], + **kwargs: Any + ) -> ToolboxVersionObject: ... + + @overload + async def create_version( + self, + name: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> ToolboxVersionObject: ... + + @overload + async def create_version( + self, + name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> ToolboxVersionObject: ... + + @distributed_trace_async + async def delete( + self, + name: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def delete_version( + self, + name: str, + version: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace_async + async def get( + self, + name: str, + **kwargs: Any + ) -> ToolboxObject: ... + + @distributed_trace_async + async def get_version( + self, + name: str, + version: str, + **kwargs: Any + ) -> ToolboxVersionObject: ... + + @distributed_trace_async + async def invoke_latest_toolbox_mcp( + self, + name: str, + request: dict[str, Any], + **kwargs: Any + ) -> Any: ... + + @distributed_trace + def list( + self, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> AsyncItemPaged[ToolboxObject]: ... + + @distributed_trace + def list_versions( + self, + name: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> AsyncItemPaged[ToolboxVersionObject]: ... + + @overload + async def update( + self, + name: str, + *, + content_type: str = "application/json", + default_version: str, + **kwargs: Any + ) -> ToolboxObject: ... + + @overload + async def update( + self, + name: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> ToolboxObject: ... + + @overload + async def update( + self, + name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> ToolboxObject: ... + + +namespace azure.ai.projects.models + + class azure.ai.projects.models.A2APreviewTool(Tool, discriminator='a2a_preview'): + agent_card_path: Optional[str] + base_url: Optional[str] + project_connection_id: Optional[str] + send_credentials_for_agent_card: Optional[bool] + type: Literal[ToolType.A2A_PREVIEW] + + @overload + def __init__( + self, + *, + agent_card_path: Optional[str] = ..., + base_url: Optional[str] = ..., + project_connection_id: Optional[str] = ..., + send_credentials_for_agent_card: Optional[bool] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.A2APreviewToolboxTool(ToolboxTool, discriminator='a2a_preview'): + agent_card_path: Optional[str] + base_url: Optional[str] + description: str + name: str + project_connection_id: Optional[str] + send_credentials_for_agent_card: Optional[bool] + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.A2A_PREVIEW] + + @overload + def __init__( + self, + *, + agent_card_path: Optional[str] = ..., + base_url: Optional[str] = ..., + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: Optional[str] = ..., + send_credentials_for_agent_card: Optional[bool] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.A2AProtocolConfiguration(_Model): + + + class azure.ai.projects.models.A2AProtocolVersion(str, Enum, metaclass=CaseInsensitiveEnumMeta): + V1_0 = "1.0" + + + class azure.ai.projects.models.A2ATool(Tool, discriminator='a2a'): + a2a_version: Union[str, A2AProtocolVersion] + agent_card_path: Optional[str] + base_url: Optional[str] + project_connection_id: Optional[str] + send_credentials_for_agent_card: Optional[bool] + type: Literal[ToolType.A2_A] + + @overload + def __init__( + self, + *, + a2a_version: Union[str, A2AProtocolVersion], + agent_card_path: Optional[str] = ..., + base_url: Optional[str] = ..., + project_connection_id: Optional[str] = ..., + send_credentials_for_agent_card: Optional[bool] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.A2AToolboxTool(ToolboxTool, discriminator='a2a'): + a2a_version: Union[str, A2AProtocolVersion] + agent_card_path: Optional[str] + base_url: Optional[str] + description: str + name: str + project_connection_id: Optional[str] + send_credentials_for_agent_card: Optional[bool] + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.A2_A] + + @overload + def __init__( + self, + *, + a2a_version: Union[str, A2AProtocolVersion], + agent_card_path: Optional[str] = ..., + base_url: Optional[str] = ..., + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: Optional[str] = ..., + send_credentials_for_agent_card: Optional[bool] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AISearchIndexResource(_Model): + filter: Optional[str] + index_asset_id: Optional[str] + index_name: Optional[str] + project_connection_id: Optional[str] + query_type: Optional[Union[str, AzureAISearchQueryType]] + top_k: Optional[int] + + @overload + def __init__( + self, + *, + filter: Optional[str] = ..., + index_asset_id: Optional[str] = ..., + index_name: Optional[str] = ..., + project_connection_id: Optional[str] = ..., + query_type: Optional[Union[str, AzureAISearchQueryType]] = ..., + top_k: Optional[int] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ActivityProtocolAccessBoundary(str, Enum, metaclass=CaseInsensitiveEnumMeta): + READ1_ON1_ALLOWLISTED = "read.1on1.allowlisted" + READ1_ON1_DEVELOPERS = "read.1on1.developers" + READ1_ON1_MANAGER = "read.1on1.manager" + READ1_ON1_TENANT = "read.1on1.tenant" + READ_GROUP_ALLOWLISTED = "read.group.allowlisted" + READ_GROUP_DEVELOPERS = "read.group.developers" + READ_GROUP_MANAGER_INVITED = "read.group.manager-invited" + READ_GROUP_MANAGER_PRESENT = "read.group.manager-present" + READ_GROUP_TENANT = "read.group.tenant" + WRITE1_ON1_ALLOWLISTED = "write.1on1.allowlisted" + WRITE1_ON1_DEVELOPERS = "write.1on1.developers" + WRITE1_ON1_MANAGER = "write.1on1.manager" + WRITE1_ON1_TENANT = "write.1on1.tenant" + WRITE_GROUP_ALLOWLISTED = "write.group.allowlisted" + WRITE_GROUP_DEVELOPERS = "write.group.developers" + WRITE_GROUP_MANAGER_INVITED = "write.group.manager-invited" + WRITE_GROUP_MANAGER_PRESENT = "write.group.manager-present" + WRITE_GROUP_TENANT = "write.group.tenant" + + + class azure.ai.projects.models.ActivityProtocolConfiguration(_Model): + access_boundaries: Optional[list[Union[str, ActivityProtocolAccessBoundary]]] + enable_m365_public_endpoint: Optional[bool] + + @overload + def __init__( + self, + *, + enable_m365_public_endpoint: Optional[bool] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentBlueprintReference(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentBlueprintReferenceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MANAGED_AGENT_IDENTITY_BLUEPRINT = "ManagedAgentIdentityBlueprint" + + + class azure.ai.projects.models.AgentCard(_Model): + description: Optional[str] + skills: list[AgentCardSkill] + version: str + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + skills: list[AgentCardSkill], + version: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentCardSkill(_Model): + description: Optional[str] + examples: Optional[list[str]] + id: str + name: str + tags: Optional[list[str]] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + examples: Optional[list[str]] = ..., + id: str, + name: str, + tags: Optional[list[str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentClusterInsightRequest(InsightRequest, discriminator='AgentClusterInsight'): + agent_name: str + model_configuration: Optional[InsightModelConfiguration] + type: Literal[InsightType.AGENT_CLUSTER_INSIGHT] + + @overload + def __init__( + self, + *, + agent_name: str, + model_configuration: Optional[InsightModelConfiguration] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentClusterInsightResult(InsightResult, discriminator='AgentClusterInsight'): + cluster_insight: ClusterInsightResult + type: Literal[InsightType.AGENT_CLUSTER_INSIGHT] + + @overload + def __init__( + self, + *, + cluster_insight: ClusterInsightResult + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentDataGenerationJobSource(DataGenerationJobSource, discriminator='agent'): + agent_name: str + agent_version: Optional[str] + description: str + type: Literal[DataGenerationJobSourceType.AGENT] + + @overload + def __init__( + self, + *, + agent_name: str, + agent_version: Optional[str] = ..., + description: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentDefinition(_Model): + kind: str + rai_config: Optional[RaiConfig] + + @overload + def __init__( + self, + *, + kind: str, + rai_config: Optional[RaiConfig] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentDetails(_Model): + agent_card: Optional[AgentCard] + agent_endpoint: Optional[AgentEndpointConfig] + blueprint: Optional[AgentIdentity] + blueprint_reference: Optional[AgentBlueprintReference] + configuration_state: Union[str, AgentState] + digital_worker_type: Optional[Union[str, DigitalWorkerType]] + id: str + instance_identity: Optional[AgentIdentity] + name: str + object: Literal[AgentObjectType.AGENT] + state: Union[str, AgentState] + state_source: Optional[Union[str, AgentStateSource]] + versions: AgentObjectVersions + + @overload + def __init__( + self, + *, + agent_card: Optional[AgentCard] = ..., + agent_endpoint: Optional[AgentEndpointConfig] = ..., + digital_worker_type: Optional[Union[str, DigitalWorkerType]] = ..., + id: str, + name: str, + object: Literal[AgentObjectType.AGENT], + versions: AgentObjectVersions + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentEndpointAuthorizationScheme(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentEndpointAuthorizationSchemeType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BOT_SERVICE = "BotService" + BOT_SERVICE_RBAC = "BotServiceRbac" + BOT_SERVICE_TENANT = "BotServiceTenant" + ENTRA = "Entra" + + + class azure.ai.projects.models.AgentEndpointConfig(_Model): + authorization_schemes: Optional[list[AgentEndpointAuthorizationScheme]] + protocol_configuration: Optional[ProtocolConfiguration] + publish_approval_status: Optional[Union[str, PublishApprovalStatus]] + version_selector: Optional[VersionSelector] + + @overload + def __init__( + self, + *, + authorization_schemes: Optional[list[AgentEndpointAuthorizationScheme]] = ..., + protocol_configuration: Optional[ProtocolConfiguration] = ..., + version_selector: Optional[VersionSelector] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentEndpointProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): + A2A = "a2a" + ACTIVITY = "activity" + INVOCATIONS = "invocations" + INVOCATIONS_WS = "invocations_ws" + MCP = "mcp" + RESPONSES = "responses" + VOICE = "voice" + + + class azure.ai.projects.models.AgentEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='agent'): + agent_name: str + agent_version: Optional[str] + description: Optional[str] + type: Literal[EvaluatorGenerationJobSourceType.AGENT] + + @overload + def __init__( + self, + *, + agent_name: str, + agent_version: Optional[str] = ..., + description: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentHarness(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentIdentity(_Model): + client_id: str + principal_id: str + status: Optional[Union[str, AgentIdentityStatus]] + + @overload + def __init__( + self, + *, + client_id: str, + principal_id: str, + status: Optional[Union[str, AgentIdentityStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentIdentityStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACTIVE = "active" + DISABLED = "disabled" + + + class azure.ai.projects.models.AgentInsight(_Model): + agent_name: str + agent_version: str + category: str + created_at: datetime + description: str + details: Optional[AgentInsightDetails] + id: str + monitor_id: str + severity: Union[str, AgentInsightSeverity] + status: Union[str, AgentInsightStatus] + title: str + trace_count: int + updated_at: datetime + + + class azure.ai.projects.models.AgentInsightDetails(_Model): + highlighted_traces: list[AgentInsightHighlightedTrace] + linked_traces: list[AgentInsightLinkedTrace] + recommended_actions: AgentInsightRecommendedAction + + @overload + def __init__( + self, + *, + highlighted_traces: list[AgentInsightHighlightedTrace], + linked_traces: list[AgentInsightLinkedTrace], + recommended_actions: AgentInsightRecommendedAction + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightEstimatedCost(_Model): + amount: float + currency: Literal["USD"] + + @overload + def __init__( + self, + *, + amount: float + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightHighlightedTrace(_Model): + duration_ms: timedelta + summary: str + timestamp: datetime + total_tokens: Optional[int] + trace_id: str + + @overload + def __init__( + self, + *, + duration_ms: timedelta, + summary: str, + timestamp: datetime, + total_tokens: Optional[int] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightLinkedTrace(_Model): + timestamp: datetime + trace_id: str + + + class azure.ai.projects.models.AgentInsightMonitor(_Model): + agent_name: str + enabled: bool + estimated_cost: Optional[AgentInsightEstimatedCost] + id: str + model_deployment_name: str + next_scheduled_run_at: Optional[datetime] + overview: AgentInsightsOverview + run_interval_hours: float + suspension: AgentInsightSuspension + updated_at: datetime + + + class azure.ai.projects.models.AgentInsightMonitorCreate(_Model): + agent_name: str + enabled: Optional[bool] + model_deployment_name: str + run_interval_hours: Optional[float] + + @overload + def __init__( + self, + *, + agent_name: str, + enabled: Optional[bool] = ..., + model_deployment_name: str, + run_interval_hours: Optional[float] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightMonitorListItem(_Model): + agent_name: str + enabled: bool + estimated_cost: Optional[AgentInsightEstimatedCost] + id: str + model_deployment_name: str + next_scheduled_run_at: Optional[datetime] + run_interval_hours: float + suspension: AgentInsightSuspension + updated_at: datetime + + + class azure.ai.projects.models.AgentInsightMonitorUpdate(_Model): + enabled: Optional[bool] + model_deployment_name: Optional[str] + overview_override: Optional[AgentInsightsOverviewOverride] + run_interval_hours: Optional[float] + + @overload + def __init__( + self, + *, + enabled: Optional[bool] = ..., + model_deployment_name: Optional[str] = ..., + overview_override: Optional[AgentInsightsOverviewOverride] = ..., + run_interval_hours: Optional[float] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightOverviewSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + GENERATED = "generated" + USER_OVERRIDE = "user_override" + + + class azure.ai.projects.models.AgentInsightPromptSurface(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INSTRUCTIONS = "instructions" + TOOL = "tool" + + + class azure.ai.projects.models.AgentInsightProposedFix(_Model): + changes: Optional[list[AgentInsightProposedFixChange]] + kind: Union[str, AgentInsightProposedFixKind] + text: str + + @overload + def __init__( + self, + *, + changes: Optional[list[AgentInsightProposedFixChange]] = ..., + kind: Union[str, AgentInsightProposedFixKind], + text: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightProposedFixChange(_Model): + diff: Optional[str] + language: Optional[str] + new_value: Optional[Any] + old_value: Optional[Any] + path: Optional[str] + surface: Optional[Union[str, AgentInsightPromptSurface]] + target: Optional[str] + + @overload + def __init__( + self, + *, + diff: Optional[str] = ..., + language: Optional[str] = ..., + new_value: Optional[Any] = ..., + old_value: Optional[Any] = ..., + path: Optional[str] = ..., + surface: Optional[Union[str, AgentInsightPromptSurface]] = ..., + target: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightProposedFixKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CODE_CHANGE = "code_change" + PROMPT_CHANGE = "prompt_change" + PROSE = "prose" + + + class azure.ai.projects.models.AgentInsightRecommendedAction(_Model): + proposed_fix: AgentInsightProposedFix + + @overload + def __init__( + self, + *, + proposed_fix: AgentInsightProposedFix + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightRun(_Model): + agent_name: str + completed_at: Optional[datetime] + created_at: datetime + error: Optional[ApiError] + id: str + inputs: Optional[AgentInsightRunCreate] + model_deployment_name: str + monitor_id: str + result: Optional[AgentInsightRunResult] + started_at: Optional[datetime] + status: Union[str, JobStatus] + trigger: Union[str, AgentInsightRunTrigger] + updated_at: datetime + window_end: datetime + window_start: datetime + + @overload + def __init__( + self, + *, + inputs: Optional[AgentInsightRunCreate] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightRunCreate(_Model): + lookback_hours: Optional[float] + + @overload + def __init__( + self, + *, + lookback_hours: Optional[float] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightRunLROPoller(LROPoller[AgentInsightRunResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: PollingMethod[AgentInsightRunResult], + continuation_token: str, + **kwargs: Any + ) -> AgentInsightRunLROPoller: ... + + def status(self) -> str: ... + + + class azure.ai.projects.models.AgentInsightRunResult(_Model): + insights_created: int + insights_reopened: int + insights_updated: int + token_usage: AgentInsightTokenUsage + traces_analyzed: int + traces_in_window: int + + @overload + def __init__( + self, + *, + insights_created: int, + insights_reopened: int, + insights_updated: int, + token_usage: AgentInsightTokenUsage, + traces_analyzed: int, + traces_in_window: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightRunTrigger(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ON_DEMAND = "on_demand" + SCHEDULED = "scheduled" + + + class azure.ai.projects.models.AgentInsightSeverity(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + MEDIUM = "medium" + + + class azure.ai.projects.models.AgentInsightStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACTIVE = "active" + IGNORED = "ignored" + RESOLVED = "resolved" + + + class azure.ai.projects.models.AgentInsightSuspension(_Model): + code: str + details: Optional[dict[str, Any]] + message: str + occurred_at: datetime + + @overload + def __init__( + self, + *, + code: str, + details: Optional[dict[str, Any]] = ..., + message: str, + occurred_at: datetime + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightTokenUsage(_Model): + cached_tokens: Optional[int] + input_tokens: int + output_tokens: int + total_tokens: int + + @overload + def __init__( + self, + *, + cached_tokens: Optional[int] = ..., + input_tokens: int, + output_tokens: int, + total_tokens: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightUpdate(_Model): + status: Optional[Union[str, AgentInsightStatus]] + + @overload + def __init__( + self, + *, + status: Optional[Union[str, AgentInsightStatus]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightsOverview(_Model): + content: str + source: Union[str, AgentInsightOverviewSource] + updated_at: datetime + + @overload + def __init__( + self, + *, + content: str, + source: Union[str, AgentInsightOverviewSource], + updated_at: datetime + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentInsightsOverviewOverride(_Model): + content: str + + @overload + def __init__( + self, + *, + content: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EXTERNAL = "external" + HOSTED = "hosted" + PROMPT = "prompt" + VOICE = "voice" + WORKFLOW = "workflow" + + + class azure.ai.projects.models.AgentObjectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + AGENT_CONTAINER = "agent.container" + AGENT_DELETED = "agent.deleted" + AGENT_VERSION = "agent.version" + AGENT_VERSION_DELETED = "agent.version.deleted" + + + class azure.ai.projects.models.AgentObjectVersions(_Model): + latest: AgentVersionDetails + + @overload + def __init__( + self, + *, + latest: AgentVersionDetails + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationCandidate(_Model): + avg_score: float + avg_tokens: float + candidate_id: Optional[str] + eval_id: Optional[str] + eval_run_id: Optional[str] + mutations: Optional[dict[str, Any]] + name: str + promotion: Optional[PromotionInfo] + + @overload + def __init__( + self, + *, + avg_score: float, + avg_tokens: float, + candidate_id: Optional[str] = ..., + eval_id: Optional[str] = ..., + eval_run_id: Optional[str] = ..., + mutations: Optional[dict[str, Any]] = ..., + name: str, + promotion: Optional[PromotionInfo] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationDatasetCriterion(_Model): + instruction: str + name: str + + @overload + def __init__( + self, + *, + instruction: str, + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationDatasetInput(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationDatasetInputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INLINE = "inline" + REFERENCE = "reference" + + + class azure.ai.projects.models.AgentOptimizationDatasetItem(_Model): + criteria: Optional[list[AgentOptimizationDatasetCriterion]] + desired_num_turns: Optional[int] + ground_truth: Optional[str] + query: Optional[str] + + @overload + def __init__( + self, + *, + criteria: Optional[list[AgentOptimizationDatasetCriterion]] = ..., + desired_num_turns: Optional[int] = ..., + ground_truth: Optional[str] = ..., + query: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationEvaluatorRef(_Model): + name: str + version: Optional[str] + + @overload + def __init__( + self, + *, + name: str, + version: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationInlineDatasetInput(AgentOptimizationDatasetInput, discriminator='inline'): + dataset_items: list[AgentOptimizationDatasetItem] + type: Literal[AgentOptimizationDatasetInputType.INLINE] + + @overload + def __init__( + self, + *, + dataset_items: list[AgentOptimizationDatasetItem] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationJob(_Model): + created_at: datetime + error: Optional[ApiError] + id: str + inputs: Optional[AgentOptimizationJobInputs] + progress: Optional[AgentOptimizationJobProgress] + result: Optional[AgentOptimizationJobResult] + status: Union[str, JobStatus] + updated_at: datetime + warnings: Optional[list[str]] + + @overload + def __init__( + self, + *, + inputs: Optional[AgentOptimizationJobInputs] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationJobInputs(_Model): + agent: OptimizedAgentIdentifier + evaluators: list[AgentOptimizationEvaluatorRef] + options: Optional[AgentOptimizationOptions] + train_dataset: AgentOptimizationDatasetInput + validation_dataset: Optional[AgentOptimizationDatasetInput] + + @overload + def __init__( + self, + *, + agent: OptimizedAgentIdentifier, + evaluators: list[AgentOptimizationEvaluatorRef], + options: Optional[AgentOptimizationOptions] = ..., + train_dataset: AgentOptimizationDatasetInput, + validation_dataset: Optional[AgentOptimizationDatasetInput] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationJobListItem(_Model): + agent: Optional[OptimizedAgentIdentifier] + created_at: datetime + error: Optional[ApiError] + id: str + progress: Optional[AgentOptimizationJobProgress] + status: Union[str, JobStatus] + updated_at: datetime + + + class azure.ai.projects.models.AgentOptimizationJobProgress(_Model): + best_score: float + candidates_completed: int + elapsed_seconds: float + + @overload + def __init__( + self, + *, + best_score: float, + candidates_completed: int, + elapsed_seconds: float + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationJobResult(_Model): + baseline: Optional[str] + best: Optional[str] + candidates: Optional[list[AgentOptimizationCandidate]] + + @overload + def __init__( + self, + *, + baseline: Optional[str] = ..., + best: Optional[str] = ..., + candidates: Optional[list[AgentOptimizationCandidate]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationLROPoller(LROPoller[AgentOptimizationJobResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: PollingMethod[AgentOptimizationJobResult], + continuation_token: str, + **kwargs: Any + ) -> AgentOptimizationLROPoller: ... + + + class azure.ai.projects.models.AgentOptimizationOptions(_Model): + eval_model: Optional[str] + evaluation_level: Optional[Union[str, EvaluationLevel]] + max_candidates: Optional[int] + max_stalls: Optional[int] + optimization_config: Optional[dict[str, Any]] + optimization_model: Optional[str] + + @overload + def __init__( + self, + *, + eval_model: Optional[str] = ..., + evaluation_level: Optional[Union[str, EvaluationLevel]] = ..., + max_candidates: Optional[int] = ..., + max_stalls: Optional[int] = ..., + optimization_config: Optional[dict[str, Any]] = ..., + optimization_model: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentOptimizationReferenceDatasetInput(AgentOptimizationDatasetInput, discriminator='reference'): + name: str + type: Literal[AgentOptimizationDatasetInputType.REFERENCE] + version: Optional[str] + + @overload + def __init__( + self, + *, + name: str, + version: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentSessionResource(_Model): + agent_session_id: str + created_at: datetime + expires_at: datetime + last_accessed_at: datetime + status: Union[str, AgentSessionStatus] + stopped_at: Optional[datetime] + version_indicator: VersionIndicator + + @overload + def __init__( + self, + *, + agent_session_id: str, + status: Union[str, AgentSessionStatus], + version_indicator: VersionIndicator + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentSessionStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACTIVE = "active" + CREATING = "creating" + DELETED = "deleted" + DELETING = "deleting" + EXPIRED = "expired" + FAILED = "failed" + IDLE = "idle" + UPDATING = "updating" + + + class azure.ai.projects.models.AgentState(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DISABLED = "disabled" + ENABLED = "enabled" + + + class azure.ai.projects.models.AgentStateSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT_BLUEPRINT = "agent_blueprint" + AGENT_INSTANCE_IDENTITY = "agent_instance_identity" + + + class azure.ai.projects.models.AgentTaxonomyInput(EvaluationTaxonomyInput, discriminator='agent'): + risk_categories: list[Union[str, RiskCategory]] + target: EvaluationTarget + type: Literal[EvaluationTaxonomyInputType.AGENT] + + @overload + def __init__( + self, + *, + risk_categories: list[Union[str, RiskCategory]], + target: EvaluationTarget + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentVersionDetails(_Model): + agent_guid: Optional[str] + blueprint: Optional[AgentIdentity] + blueprint_reference: Optional[AgentBlueprintReference] + created_at: datetime + definition: AgentDefinition + description: Optional[str] + draft: Optional[bool] + id: str + instance_identity: Optional[AgentIdentity] + metadata: dict[str, str] + name: str + object: Literal[AgentObjectType.AGENT_VERSION] + status: Optional[Union[str, AgentVersionStatus]] + version: str + + @overload + def __init__( + self, + *, + created_at: datetime, + definition: AgentDefinition, + description: Optional[str] = ..., + draft: Optional[bool] = ..., + id: str, + metadata: dict[str, str], + name: str, + object: Literal[AgentObjectType.AGENT_VERSION], + status: Optional[Union[str, AgentVersionStatus]] = ..., + version: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AgentVersionStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACTIVE = "active" + CREATING = "creating" + DELETED = "deleted" + DELETING = "deleting" + FAILED = "failed" + + + class azure.ai.projects.models.AgenticIdentityPreviewCredentials(BaseCredentials, discriminator='AgenticIdentityToken_Preview'): + type: Literal[CredentialType.AGENTIC_IDENTITY_PREVIEW] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ApiError(_Model): + additional_info: Optional[dict[str, Any]] + code: str + debug_info: Optional[dict[str, Any]] + details: Optional[list[ApiError]] + message: str + param: Optional[str] + type: Optional[str] + + @overload + def __init__( + self, + *, + additional_info: Optional[dict[str, Any]] = ..., + code: str, + debug_info: Optional[dict[str, Any]] = ..., + details: Optional[list[ApiError]] = ..., + message: str, + param: Optional[str] = ..., + type: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ApiErrorResponse(_Model): + error: ApiError + + @overload + def __init__( + self, + *, + error: ApiError + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ApiKeyCredentials(BaseCredentials, discriminator='ApiKey'): + api_key: Optional[str] + type: Literal[CredentialType.API_KEY] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ApplyPatchToolParam(Tool, discriminator='apply_patch'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + type: Literal[ToolType.APPLY_PATCH] + + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ApproximateLocation(_Model): + city: Optional[str] + country: Optional[str] + region: Optional[str] + timezone: Optional[str] + type: Literal["approximate"] + + @overload + def __init__( + self, + *, + city: Optional[str] = ..., + country: Optional[str] = ..., + region: Optional[str] = ..., + timezone: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ArtifactProfile(_Model): + category: Union[str, FoundryModelArtifactProfileCategory] + signals: Optional[list[Union[str, FoundryModelArtifactProfileSignal]]] + + @overload + def __init__( + self, + *, + category: Union[str, FoundryModelArtifactProfileCategory], + signals: Optional[list[Union[str, FoundryModelArtifactProfileSignal]]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AsyncAgentInsightRunLROPoller(AsyncLROPoller[AgentInsightRunResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: AsyncPollingMethod[AgentInsightRunResult], + continuation_token: str, + **kwargs: Any + ) -> AsyncAgentInsightRunLROPoller: ... + + def status(self) -> str: ... + + + class azure.ai.projects.models.AsyncAgentOptimizationLROPoller(AsyncLROPoller[AgentOptimizationJobResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: AsyncPollingMethod[AgentOptimizationJobResult], + continuation_token: str, + **kwargs: Any + ) -> AsyncAgentOptimizationLROPoller: ... + + + class azure.ai.projects.models.AsyncDatasetGenerationLROPoller(AsyncLROPoller[DataGenerationJobResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: AsyncPollingMethod[DataGenerationJobResult], + continuation_token: str, + **kwargs: Any + ) -> AsyncDatasetGenerationLROPoller: ... + + + class azure.ai.projects.models.AsyncEvaluatorGenerationLROPoller(AsyncLROPoller[EvaluatorVersion]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: AsyncPollingMethod[EvaluatorVersion], + continuation_token: str, + **kwargs: Any + ) -> AsyncEvaluatorGenerationLROPoller: ... + + + class azure.ai.projects.models.AsyncUpdateMemoriesLROPoller(AsyncLROPoller[MemoryStoreUpdateCompletedResult]): + property superseded_by: Optional[str] # Read-only + property update_id: str # Read-only + + @classmethod + def from_continuation_token( + cls, + polling_method: AsyncPollingMethod[MemoryStoreUpdateCompletedResult], + continuation_token: str, + **kwargs: Any + ) -> AsyncUpdateMemoriesLROPoller: ... + + + class azure.ai.projects.models.AttackStrategy(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ANSI_ATTACK = "ansi_attack" + ASCII_ART = "ascii_art" + ASCII_SMUGGLER = "ascii_smuggler" + ATBASH = "atbash" + BASE64 = "base64" + BASELINE = "baseline" + BINARY = "binary" + CAESAR = "caesar" + CHARACTER_SPACE = "character_space" + CHARACTER_SWAP = "character_swap" + CRESCENDO = "crescendo" + DIACRITIC = "diacritic" + DIFFICULT = "difficult" + EASY = "easy" + FLIP = "flip" + INDIRECT_JAILBREAK = "indirect_jailbreak" + JAILBREAK = "jailbreak" + LEETSPEAK = "leetspeak" + MODERATE = "moderate" + MORSE = "morse" + MULTI_TURN = "multi_turn" + ROT13 = "rot13" + STRING_JOIN = "string_join" + SUFFIX_APPEND = "suffix_append" + TENSE = "tense" + UNICODE_CONFUSABLE = "unicode_confusable" + UNICODE_SUBSTITUTION = "unicode_substitution" + URL = "url" + + + class azure.ai.projects.models.AutoCodeInterpreterToolParam(_Model): + file_ids: Optional[list[str]] + memory_limit: Optional[Union[str, ContainerMemoryLimit]] + network_policy: Optional[ContainerNetworkPolicyParam] + type: Literal["auto"] + + @overload + def __init__( + self, + *, + file_ids: Optional[list[str]] = ..., + memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., + network_policy: Optional[ContainerNetworkPolicyParam] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureAIAgentTarget(EvaluationTarget, discriminator='azure_ai_agent'): + name: str + tool_descriptions: Optional[list[ToolDescription]] + tools: Optional[list[Tool]] + type: Literal["azure_ai_agent"] + version: Optional[str] + + @overload + def __init__( + self, + *, + name: str, + tool_descriptions: Optional[list[ToolDescription]] = ..., + tools: Optional[list[Tool]] = ..., + version: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureAIAgentTargetParam(TypedDict, total=False): + key "name": Required[str] + key "tool_descriptions": List[ToolDescriptionParam] + key "type": Required[Literal["azure_ai_agent"]] + key "version": str + + + class azure.ai.projects.models.AzureAIBenchmarkPreviewEvalRunDataSource(TypedDict, total=False): + key "input_messages": InputMessagesItemReference + key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] + key "type": Required[Literal["azure_ai_benchmark_preview"]] + + + class azure.ai.projects.models.AzureAIDataSourceConfig(TypedDict, total=False): + key "scenario": Required[str] + key "type": Required[Literal["azure_ai_source"]] + + + class azure.ai.projects.models.AzureAIModelTarget(EvaluationTarget, discriminator='azure_ai_model'): + model: Optional[str] + sampling_params: Optional[ModelSamplingParams] + type: Literal["azure_ai_model"] + + @overload + def __init__( + self, + *, + model: Optional[str] = ..., + sampling_params: Optional[ModelSamplingParams] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureAIModelTargetParam(TypedDict, total=False): + key "model": str + key "sampling_params": ModelSamplingConfigParam + key "type": Required[Literal["azure_ai_model"]] + + + class azure.ai.projects.models.AzureAIResponsesEvalRunDataSource(TypedDict, total=False): + key "event_configuration_id": str + key "item_generation_params": Required[ResponseRetrievalItemGenerationParams] + key "max_runs_hourly": int + key "type": Required[Literal["azure_ai_responses"]] + + + class azure.ai.projects.models.AzureAISearchIndex(Index, discriminator='AzureSearch'): + connection_name: str + description: str + field_mapping: Optional[FieldMapping] + id: str + index_name: str + name: str + tags: dict[str, str] + type: Literal[IndexType.AZURE_SEARCH] + version: str + + @overload + def __init__( + self, + *, + connection_name: str, + description: Optional[str] = ..., + field_mapping: Optional[FieldMapping] = ..., + index_name: str, + tags: Optional[dict[str, str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureAISearchQueryType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + SEMANTIC = "semantic" + SIMPLE = "simple" + VECTOR = "vector" + VECTOR_SEMANTIC_HYBRID = "vector_semantic_hybrid" + VECTOR_SIMPLE_HYBRID = "vector_simple_hybrid" + + + class azure.ai.projects.models.AzureAISearchTool(Tool, discriminator='azure_ai_search'): + azure_ai_search: AzureAISearchToolResource + description: Optional[str] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.AZURE_AI_SEARCH] + + @overload + def __init__( + self, + *, + azure_ai_search: AzureAISearchToolResource, + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureAISearchToolResource(_Model): + indexes: list[AISearchIndexResource] + + @overload + def __init__( + self, + *, + indexes: list[AISearchIndexResource] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureAISearchToolboxTool(ToolboxTool, discriminator='azure_ai_search'): + azure_ai_search: AzureAISearchToolResource + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.AZURE_AI_SEARCH] + + @overload + def __init__( + self, + *, + azure_ai_search: AzureAISearchToolResource, + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureFunctionBinding(_Model): + storage_queue: AzureFunctionStorageQueue + type: Literal["storage_queue"] + + @overload + def __init__( + self, + *, + storage_queue: AzureFunctionStorageQueue + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureFunctionDefinition(_Model): + function: AzureFunctionDefinitionFunction + input_binding: AzureFunctionBinding + output_binding: AzureFunctionBinding + + @overload + def __init__( + self, + *, + function: AzureFunctionDefinitionFunction, + input_binding: AzureFunctionBinding, + output_binding: AzureFunctionBinding + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureFunctionDefinitionFunction(_Model): + description: Optional[str] + name: str + parameters: dict[str, Any] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: str, + parameters: dict[str, Any] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureFunctionStorageQueue(_Model): + queue_name: str + queue_service_endpoint: str + + @overload + def __init__( + self, + *, + queue_name: str, + queue_service_endpoint: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureFunctionTool(Tool, discriminator='azure_function'): + azure_function: AzureFunctionDefinition + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.AZURE_FUNCTION] + + @overload + def __init__( + self, + *, + azure_function: AzureFunctionDefinition, + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.AzureOpenAIModelConfiguration(RedTeamTargetConfig, discriminator='AzureOpenAIModel'): + model_deployment_name: str + type: Literal["AzureOpenAIModel"] + + @overload + def __init__( + self, + *, + model_deployment_name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BaseCredentials(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingCustomSearchConfiguration(_Model): + count: Optional[int] + freshness: Optional[str] + instance_name: str + market: Optional[str] + project_connection_id: str + set_lang: Optional[str] + + @overload + def __init__( + self, + *, + count: Optional[int] = ..., + freshness: Optional[str] = ..., + instance_name: str, + market: Optional[str] = ..., + project_connection_id: str, + set_lang: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingCustomSearchPreviewTool(Tool, discriminator='bing_custom_search_preview'): + bing_custom_search_preview: BingCustomSearchToolParameters + type: Literal[ToolType.BING_CUSTOM_SEARCH_PREVIEW] + + @overload + def __init__( + self, + *, + bing_custom_search_preview: BingCustomSearchToolParameters + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingCustomSearchToolParameters(_Model): + search_configurations: list[BingCustomSearchConfiguration] + + @overload + def __init__( + self, + *, + search_configurations: list[BingCustomSearchConfiguration] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingGroundingSearchConfiguration(_Model): + count: Optional[int] + freshness: Optional[str] + market: Optional[str] + project_connection_id: str + set_lang: Optional[str] + + @overload + def __init__( + self, + *, + count: Optional[int] = ..., + freshness: Optional[str] = ..., + market: Optional[str] = ..., + project_connection_id: str, + set_lang: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingGroundingSearchToolParameters(_Model): + search_configurations: list[BingGroundingSearchConfiguration] + + @overload + def __init__( + self, + *, + search_configurations: list[BingGroundingSearchConfiguration] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BingGroundingTool(Tool, discriminator='bing_grounding'): + bing_grounding: BingGroundingSearchToolParameters + description: Optional[str] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.BING_GROUNDING] + + @overload + def __init__( + self, + *, + bing_grounding: BingGroundingSearchToolParameters, + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BlobReference(_Model): + blob_uri: str + credential: BlobReferenceSasCredential + storage_account_arm_id: str + + @overload + def __init__( + self, + *, + blob_uri: str, + credential: BlobReferenceSasCredential, + storage_account_arm_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BlobReferenceSasCredential(_Model): + sas_uri: str + type: Literal["SAS"] + + def __init__( + self, + *args: Any, + **kwargs: Any + ) -> None: ... + + + class azure.ai.projects.models.BotServiceAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotService'): + type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BotServiceRbacAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotServiceRbac'): + type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE_RBAC] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BotServiceTenantAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotServiceTenant'): + type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE_TENANT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BrowserAutomationPreviewTool(Tool, discriminator='browser_automation_preview'): + browser_automation_preview: BrowserAutomationToolParameters + type: Literal[ToolType.BROWSER_AUTOMATION_PREVIEW] + + @overload + def __init__( + self, + *, + browser_automation_preview: BrowserAutomationToolParameters + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BrowserAutomationPreviewToolboxTool(ToolboxTool, discriminator='browser_automation_preview'): + browser_automation_preview: BrowserAutomationToolParameters + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.BROWSER_AUTOMATION_PREVIEW] + + @overload + def __init__( + self, + *, + browser_automation_preview: BrowserAutomationToolParameters, + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BrowserAutomationToolConnectionParameters(_Model): + project_connection_id: str + + @overload + def __init__( + self, + *, + project_connection_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.BrowserAutomationToolParameters(_Model): + connection: BrowserAutomationToolConnectionParameters + + @overload + def __init__( + self, + *, + connection: BrowserAutomationToolConnectionParameters + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CallableToolAllowedCaller(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DIRECT = "direct" + PROGRAMMATIC = "programmatic" + + + class azure.ai.projects.models.CaptureStructuredOutputsTool(Tool, discriminator='capture_structured_outputs'): + description: Optional[str] + name: Optional[str] + outputs: StructuredOutputDefinition + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.CAPTURE_STRUCTURED_OUTPUTS] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + outputs: StructuredOutputDefinition, + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ChartCoordinate(_Model): + size: int + x: int + y: int + + @overload + def __init__( + self, + *, + size: int, + x: int, + y: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ChatSummaryMemoryItem(MemoryItem, discriminator='chat_summary'): + content: str + kind: Literal[MemoryItemKind.CHAT_SUMMARY] + memory_id: str + scope: str + updated_at: datetime + + @overload + def __init__( + self, + *, + content: str, + memory_id: str, + scope: str, + updated_at: datetime + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ClusterInsightResult(_Model): + clusters: list[InsightCluster] + coordinates: Optional[dict[str, ChartCoordinate]] + summary: InsightSummary + + @overload + def __init__( + self, + *, + clusters: list[InsightCluster], + coordinates: Optional[dict[str, ChartCoordinate]] = ..., + summary: InsightSummary + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ClusterTokenUsage(_Model): + input_token_usage: int + output_token_usage: int + total_token_usage: int + + @overload + def __init__( + self, + *, + input_token_usage: int, + output_token_usage: int, + total_token_usage: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CodeBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='code'): + blob_uri: Optional[str] + code_text: Optional[str] + data_schema: dict[str, any] + entry_point: Optional[str] + image_tag: Optional[str] + init_parameters: dict[str, any] + metrics: dict[str, EvaluatorMetric] + type: Literal[EvaluatorDefinitionType.CODE] + + @overload + def __init__( + self, + *, + blob_uri: Optional[str] = ..., + code_text: Optional[str] = ..., + data_schema: Optional[dict[str, Any]] = ..., + entry_point: Optional[str] = ..., + image_tag: Optional[str] = ..., + init_parameters: Optional[dict[str, Any]] = ..., + metrics: Optional[dict[str, EvaluatorMetric]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CodeConfiguration(_Model): + content_hash: Optional[str] + dependency_resolution: Union[str, CodeDependencyResolution] + entry_point: list[str] + runtime: str + + @overload + def __init__( + self, + *, + dependency_resolution: Union[str, CodeDependencyResolution], + entry_point: list[str], + runtime: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CodeDependencyResolution(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BUNDLED = "bundled" + REMOTE_BUILD = "remote_build" + + + class azure.ai.projects.models.CodeInterpreterTool(Tool, discriminator='code_interpreter'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + container: Optional[Union[str, AutoCodeInterpreterToolParam]] + description: Optional[str] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.CODE_INTERPRETER] + + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + container: Optional[Union[str, AutoCodeInterpreterToolParam]] = ..., + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CodeInterpreterToolboxTool(ToolboxTool, discriminator='code_interpreter'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + container: Optional[Union[str, AutoCodeInterpreterToolParam]] + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.CODE_INTERPRETER] + + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + container: Optional[Union[str, AutoCodeInterpreterToolParam]] = ..., + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ComparisonFilter(_Model): + key: str + type: Literal["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"] + value: Union[str, float, bool, list[Union[str, float]]] + + @overload + def __init__( + self, + *, + key: str, + type: Literal["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"], + value: Union[str, float, bool, list[Union[str, float]]] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CompoundFilter(_Model): + filters: list[Union[ComparisonFilter, Any]] + type: Literal["and", "or"] + + @overload + def __init__( + self, + *, + filters: list[Union[ComparisonFilter, Any]], + type: Literal["and", "or"] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ComputerEnvironment(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BROWSER = "browser" + LINUX = "linux" + MAC = "mac" + UBUNTU = "ubuntu" + WINDOWS = "windows" + + + class azure.ai.projects.models.ComputerTool(Tool, discriminator='computer'): + type: Literal[ToolType.COMPUTER] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ComputerUsePreviewTool(Tool, discriminator='computer_use_preview'): + display_height: int + display_width: int + environment: Union[str, ComputerEnvironment] + type: Literal[ToolType.COMPUTER_USE_PREVIEW] + + @overload + def __init__( + self, + *, + display_height: int, + display_width: int, + environment: Union[str, ComputerEnvironment] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.Connection(_Model): + credentials: BaseCredentials + id: str + is_default: bool + metadata: dict[str, str] + name: str + target: str + type: Union[str, ConnectionType] + + + class azure.ai.projects.models.ConnectionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + API_KEY = "ApiKey" + APPLICATION_CONFIGURATION = "AppConfig" + APPLICATION_INSIGHTS = "AppInsights" + AZURE_AI_SEARCH = "CognitiveSearch" + AZURE_BLOB_STORAGE = "AzureBlob" + AZURE_OPEN_AI = "AzureOpenAI" + AZURE_STORAGE_ACCOUNT = "AzureStorageAccount" + COSMOS_DB = "CosmosDB" + CUSTOM = "CustomKeys" + REMOTE_TOOL = "RemoteTool_Preview" + + + class azure.ai.projects.models.ContainerAutoParam(FunctionShellToolParamEnvironment, discriminator='container_auto'): + file_ids: Optional[list[str]] + memory_limit: Optional[Union[str, ContainerMemoryLimit]] + network_policy: Optional[ContainerNetworkPolicyParam] + skills: Optional[list[ContainerSkill]] + type: Literal[FunctionShellToolParamEnvironmentType.CONTAINER_AUTO] + + @overload + def __init__( + self, + *, + file_ids: Optional[list[str]] = ..., + memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., + network_policy: Optional[ContainerNetworkPolicyParam] = ..., + skills: Optional[list[ContainerSkill]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ContainerConfiguration(_Model): + image: str + registry_connection_id: Optional[str] + + @overload + def __init__( + self, + *, + image: str, + registry_connection_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ContainerMemoryLimit(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MEMORY_16GB = "16g" + MEMORY_1GB = "1g" + MEMORY_4GB = "4g" + MEMORY_64GB = "64g" + + + class azure.ai.projects.models.ContainerNetworkPolicyAllowlistParam(ContainerNetworkPolicyParam, discriminator='allowlist'): + allowed_domains: list[str] + domain_secrets: Optional[list[ContainerNetworkPolicyDomainSecretParam]] + type: Literal[ContainerNetworkPolicyParamType.ALLOWLIST] + + @overload + def __init__( + self, + *, + allowed_domains: list[str], + domain_secrets: Optional[list[ContainerNetworkPolicyDomainSecretParam]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ContainerNetworkPolicyDisabledParam(ContainerNetworkPolicyParam, discriminator='disabled'): + type: Literal[ContainerNetworkPolicyParamType.DISABLED] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ContainerNetworkPolicyDomainSecretParam(_Model): + domain: str + name: str + value: str + + @overload + def __init__( + self, + *, + domain: str, + name: str, + value: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ContainerNetworkPolicyParam(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ContainerNetworkPolicyParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ALLOWLIST = "allowlist" + DISABLED = "disabled" + + + class azure.ai.projects.models.ContainerSkill(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ContainerSkillType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INLINE = "inline" + SKILL_REFERENCE = "skill_reference" + + + class azure.ai.projects.models.ContinuousEvaluationRuleAction(EvaluationRuleAction, discriminator='continuousEvaluation'): + eval_id: str + max_hourly_runs: Optional[int] + sampling_rate: Optional[float] + type: Literal[EvaluationRuleActionType.CONTINUOUS_EVALUATION] + + @overload + def __init__( + self, + *, + eval_id: str, + max_hourly_runs: Optional[int] = ..., + sampling_rate: Optional[float] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CosmosDBIndex(Index, discriminator='CosmosDBNoSqlVectorStore'): + connection_name: str + container_name: str + database_name: str + description: str + embedding_configuration: EmbeddingConfiguration + field_mapping: FieldMapping + id: str + name: str + tags: dict[str, str] + type: Literal[IndexType.COSMOS_DB] + version: str + + @overload + def __init__( + self, + *, + connection_name: str, + container_name: str, + database_name: str, + description: Optional[str] = ..., + embedding_configuration: EmbeddingConfiguration, + field_mapping: FieldMapping, + tags: Optional[dict[str, str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateAsyncResponse(_Model): + location: Optional[str] + operation_result: Optional[str] + + @overload + def __init__( + self, + *, + location: Optional[str] = ..., + operation_result: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateSkillVersionFromFilesBody(_Model): + default: Optional[bool] + files: list[Union[str, bytes, IO[str], IO[bytes], tuple[Optional[str], Union[str, bytes, IO[str], IO[bytes]]], tuple[Optional[str], Union[str, bytes, IO[str], IO[bytes]], Optional[str]]]] + + @overload + def __init__( + self, + *, + default: Optional[bool] = ..., + files: list[FileType] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTeamsPhoneExtensionTelephonyBindingRequest(CreateTelephonyBindingRequest, discriminator='teams_phone_extension'): + connection_name: str + label: str + phone_number: Optional[str] + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] + resource_account_object_id: str + + @overload + def __init__( + self, + *, + connection_name: str, + label: Optional[str] = ..., + phone_number: Optional[str] = ..., + resource_account_object_id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTelephonyBindingRequest(_Model): + connection_name: str + label: Optional[str] + provider: str + + @overload + def __init__( + self, + *, + connection_name: str, + label: Optional[str] = ..., + provider: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTelephonyCallJobRequest(_Model): + connection_name: str + destination: TelephonyOutboundDestination + purpose: Optional[str] + retry_policy: Optional[TelephonyOutboundRetryPolicy] + schedule: Optional[TelephonyCallJobSchedule] + source: str + structured_inputs: Optional[dict[str, Any]] + + @overload + def __init__( + self, + *, + connection_name: str, + destination: TelephonyOutboundDestination, + purpose: Optional[str] = ..., + retry_policy: Optional[TelephonyOutboundRetryPolicy] = ..., + schedule: Optional[TelephonyCallJobSchedule] = ..., + source: str, + structured_inputs: Optional[dict[str, Any]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTranscriptionResponseJsonUsage(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CreateTranscriptionResponseJsonUsageType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DURATION = "duration" + TOKENS = "tokens" + + + class azure.ai.projects.models.CreateTwilioTelephonyBindingRequest(CreateTelephonyBindingRequest, discriminator='twilio'): + connection_name: str + label: str + phone_number: str + provider: Literal[TelephonyProvider.TWILIO] + + @overload + def __init__( + self, + *, + connection_name: str, + label: Optional[str] = ..., + phone_number: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CredentialType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENTIC_IDENTITY_PREVIEW = "AgenticIdentityToken_Preview" + API_KEY = "ApiKey" + CUSTOM = "CustomKeys" + ENTRA_ID = "AAD" + NONE = "None" + SAS = "SAS" + + + class azure.ai.projects.models.CronTrigger(Trigger, discriminator='Cron'): + end_time: Optional[datetime] + expression: str + start_time: Optional[datetime] + time_zone: Optional[str] + type: Literal[TriggerType.CRON] + + @overload + def __init__( + self, + *, + end_time: Optional[datetime] = ..., + expression: str, + start_time: Optional[datetime] = ..., + time_zone: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CustomCredential(CustomCredentialGenerated, discriminator='CustomKeys'): + credential_keys: Dict[str, str] + type: Union[str, CredentialType] + + def __init__( + self, + *args: Any, + **kwargs: Any + ) -> None: ... + + + class azure.ai.projects.models.CustomGrammarFormatParam(CustomToolParamFormat, discriminator='grammar'): + definition: str + syntax: Union[str, GrammarSyntax1] + type: Literal[CustomToolParamFormatType.GRAMMAR] + + @overload + def __init__( + self, + *, + definition: str, + syntax: Union[str, GrammarSyntax1] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CustomRoutineTrigger(RoutineTrigger, discriminator='custom'): + event_name: Optional[str] + parameters: dict[str, Any] + provider: str + type: Literal[RoutineTriggerType.CUSTOM] + + @overload + def __init__( + self, + *, + event_name: Optional[str] = ..., + parameters: dict[str, Any], + provider: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CustomTextFormatParam(CustomToolParamFormat, discriminator='text'): + type: Literal[CustomToolParamFormatType.TEXT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CustomToolParam(Tool, discriminator='custom'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + defer_loading: Optional[bool] + description: Optional[str] + format: Optional[CustomToolParamFormat] + name: str + type: Literal[ToolType.CUSTOM] + + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + defer_loading: Optional[bool] = ..., + description: Optional[str] = ..., + format: Optional[CustomToolParamFormat] = ..., + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CustomToolParamFormat(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.CustomToolParamFormatType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + GRAMMAR = "grammar" + TEXT = "text" + + + class azure.ai.projects.models.DailyRecurrenceSchedule(RecurrenceSchedule, discriminator='Daily'): + hours: list[int] + type: Literal[RecurrenceType.DAILY] + + @overload + def __init__( + self, + *, + hours: list[int] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJob(_Model): + created_at: datetime + error: Optional[ApiError] + finished_at: Optional[datetime] + id: str + inputs: Optional[DataGenerationJobInputs] + result: Optional[DataGenerationJobResult] + status: Union[str, JobStatus] + + @overload + def __init__( + self, + *, + inputs: Optional[DataGenerationJobInputs] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobInputs(_Model): + name: str + options: DataGenerationJobOptions + output_options: Optional[DataGenerationJobOutputOptions] + scenario: Union[str, DataGenerationJobScenario] + sources: list[DataGenerationJobSource] + + @overload + def __init__( + self, + *, + name: str, + options: DataGenerationJobOptions, + output_options: Optional[DataGenerationJobOutputOptions] = ..., + scenario: Union[str, DataGenerationJobScenario], + sources: list[DataGenerationJobSource] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobOptions(_Model): + model_options: Optional[DataGenerationModelOptions] + train_split: Optional[float] + type: str + + @overload + def __init__( + self, + *, + model_options: Optional[DataGenerationModelOptions] = ..., + train_split: Optional[float] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobOutput(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobOutputOptions(_Model): + description: Optional[str] + name: Optional[str] + tags: Optional[dict[str, str]] + write_mode: Optional[Union[str, DataGenerationJobOutputWriteMode]] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + tags: Optional[dict[str, str]] = ..., + write_mode: Optional[Union[str, DataGenerationJobOutputWriteMode]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobOutputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DATASET = "dataset" + FILE = "file" + + + class azure.ai.projects.models.DataGenerationJobOutputWriteMode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MERGE = "merge" + OVERWRITE = "overwrite" + + + class azure.ai.projects.models.DataGenerationJobResult(_Model): + generated_samples: int + outputs: Optional[list[DataGenerationJobOutput]] + token_usage: Optional[DataGenerationTokenUsage] + + @overload + def __init__( + self, + *, + generated_samples: int, + outputs: Optional[list[DataGenerationJobOutput]] = ..., + token_usage: Optional[DataGenerationTokenUsage] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobScenario(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EVALUATION = "evaluation" + REINFORCEMENT_FINETUNING = "reinforcement_finetuning" + SUPERVISED_FINETUNING = "supervised_finetuning" + + + class azure.ai.projects.models.DataGenerationJobSource(_Model): + description: Optional[str] + type: str + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationJobSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + FILE = "file" + PROMPT = "prompt" + TRACES = "traces" + + + class azure.ai.projects.models.DataGenerationJobType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + SIMPLE_QNA = "simple_qna" + SIMULATION_SEED = "simulation_seed" + TOOL_USE = "tool_use" + TRACES = "traces" + + + class azure.ai.projects.models.DataGenerationModelOptions(_Model): + model: str + + @overload + def __init__( + self, + *, + model: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DataGenerationTokenUsage(_Model): + completion_tokens: int + prompt_tokens: int + total_tokens: int + + + class azure.ai.projects.models.DatasetCredential(_Model): + blob_reference: BlobReference + + @overload + def __init__( + self, + *, + blob_reference: BlobReference + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DatasetDataGenerationJobOutput(DataGenerationJobOutput, discriminator='dataset'): + description: Optional[str] + id: Optional[str] + name: Optional[str] + tags: Optional[dict[str, str]] + type: Literal[DataGenerationJobOutputType.DATASET] + version: Optional[str] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DatasetEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='dataset'): + description: Optional[str] + name: str + type: Literal[EvaluatorGenerationJobSourceType.DATASET] + version: Optional[str] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: str, + version: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DatasetGenerationLROPoller(LROPoller[DataGenerationJobResult]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: PollingMethod[DataGenerationJobResult], + continuation_token: str, + **kwargs: Any + ) -> DatasetGenerationLROPoller: ... + + + class azure.ai.projects.models.DatasetReference(_Model): + name: str + version: str + + @overload + def __init__( + self, + *, + name: str, + version: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DatasetType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + URI_FILE = "uri_file" + URI_FOLDER = "uri_folder" + + + class azure.ai.projects.models.DatasetVersion(_Model): + connection_name: Optional[str] + data_uri: str + description: Optional[str] + id: Optional[str] + is_reference: Optional[bool] + name: str + tags: Optional[dict[str, str]] + type: str + version: str + + @overload + def __init__( + self, + *, + connection_name: Optional[str] = ..., + data_uri: str, + description: Optional[str] = ..., + tags: Optional[dict[str, str]] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DayOfWeek(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FRIDAY = "Friday" + MONDAY = "Monday" + SATURDAY = "Saturday" + SUNDAY = "Sunday" + THURSDAY = "Thursday" + TUESDAY = "Tuesday" + WEDNESDAY = "Wednesday" + + + class azure.ai.projects.models.DeleteAgentResponse(_Model): + deleted: bool + name: str + object: Literal[AgentObjectType.AGENT_DELETED] + + @overload + def __init__( + self, + *, + deleted: bool, + name: str, + object: Literal[AgentObjectType.AGENT_DELETED] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeleteAgentVersionResponse(_Model): + deleted: bool + name: str + object: Literal[AgentObjectType.AGENT_VERSION_DELETED] + version: str + + @overload + def __init__( + self, + *, + deleted: bool, + name: str, + object: Literal[AgentObjectType.AGENT_VERSION_DELETED], + version: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeleteMemoryResult(_Model): + deleted: bool + memory_id: str + object: Literal[MemoryStoreObjectType.MEMORY_DELETED] + + @overload + def __init__( + self, + *, + deleted: bool, + memory_id: str, + object: Literal[MemoryStoreObjectType.MEMORY_DELETED] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeleteMemoryStoreResult(_Model): + deleted: bool + name: str + object: Literal[MemoryStoreObjectType.MEMORY_STORE_DELETED] + + @overload + def __init__( + self, + *, + deleted: bool, + name: str, + object: Literal[MemoryStoreObjectType.MEMORY_STORE_DELETED] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeleteSkillResult(_Model): + deleted: bool + id: str + name: str + + @overload + def __init__( + self, + *, + deleted: bool, + id: str, + name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeleteSkillVersionResult(_Model): + deleted: bool + id: str + name: str + version: str + + @overload + def __init__( + self, + *, + deleted: bool, + id: str, + name: str, + version: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.Deployment(_Model): + name: str + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DeploymentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MODEL_DEPLOYMENT = "ModelDeployment" + + + class azure.ai.projects.models.DigitalWorkerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + M365 = "m365" + + + class azure.ai.projects.models.Dimension(_Model): + always_applicable: Optional[bool] + description: str + id: str + weight: int + + @overload + def __init__( + self, + *, + always_applicable: Optional[bool] = ..., + description: str, + id: str, + weight: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.DispatchRoutineResult(_Model): + action_correlation_id: Optional[str] + dispatch_id: Optional[str] + task_id: Optional[str] + + @overload + def __init__( + self, + *, + action_correlation_id: Optional[str] = ..., + dispatch_id: Optional[str] = ..., + task_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EmbeddingConfiguration(_Model): + embedding_field: str + model_deployment_name: str + + @overload + def __init__( + self, + *, + embedding_field: str, + model_deployment_name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EmptyModelParam(_Model): + + + class azure.ai.projects.models.EndpointBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='endpoint'): + connection_name: str + data_schema: dict[str, any] + init_parameters: dict[str, any] + metrics: dict[str, EvaluatorMetric] + type: Literal[EvaluatorDefinitionType.ENDPOINT] + + @overload + def __init__( + self, + *, + connection_name: str, + data_schema: Optional[dict[str, Any]] = ..., + init_parameters: Optional[dict[str, Any]] = ..., + metrics: Optional[dict[str, EvaluatorMetric]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EntraAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='Entra'): + type: Literal[AgentEndpointAuthorizationSchemeType.ENTRA] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EntraIDCredentials(BaseCredentials, discriminator='AAD'): + type: Literal[CredentialType.ENTRA_ID] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvalCsvFileIdSource(TypedDict, total=False): + key "id": Required[str] + key "type": Required[Literal["file_id"]] + + + class azure.ai.projects.models.EvalCsvRunDataSource(TypedDict, total=False): + key "source": Required[EvalCsvFileIdSource] + key "type": Required[Literal["csv"]] + + + class azure.ai.projects.models.EvalResult(_Model): + name: str + passed: bool + score: float + type: str + + @overload + def __init__( + self, + *, + name: str, + passed: bool, + score: float, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvalRunResultCompareItem(_Model): + delta_estimate: float + p_value: float + treatment_effect: Union[str, TreatmentEffectType] + treatment_run_id: str + treatment_run_summary: EvalRunResultSummary + + @overload + def __init__( + self, + *, + delta_estimate: float, + p_value: float, + treatment_effect: Union[str, TreatmentEffectType], + treatment_run_id: str, + treatment_run_summary: EvalRunResultSummary + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvalRunResultComparison(_Model): + baseline_run_summary: EvalRunResultSummary + compare_items: list[EvalRunResultCompareItem] + evaluator: str + metric: str + testing_criteria: str + + @overload + def __init__( + self, + *, + baseline_run_summary: EvalRunResultSummary, + compare_items: list[EvalRunResultCompareItem], + evaluator: str, + metric: str, + testing_criteria: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvalRunResultSummary(_Model): + average: float + run_id: str + sample_count: int + standard_deviation: float + + @overload + def __init__( + self, + *, + average: float, + run_id: str, + sample_count: int, + standard_deviation: float + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationComparisonInsightRequest(InsightRequest, discriminator='EvaluationComparison'): + baseline_run_id: str + eval_id: str + treatment_run_ids: list[str] + type: Literal[InsightType.EVALUATION_COMPARISON] + + @overload + def __init__( + self, + *, + baseline_run_id: str, + eval_id: str, + treatment_run_ids: list[str] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationComparisonInsightResult(InsightResult, discriminator='EvaluationComparison'): + comparisons: list[EvalRunResultComparison] + method: str + type: Literal[InsightType.EVALUATION_COMPARISON] + + @overload + def __init__( + self, + *, + comparisons: list[EvalRunResultComparison], + method: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationLevel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONVERSATION = "conversation" + TURN = "turn" + + + class azure.ai.projects.models.EvaluationResultSample(InsightSample, discriminator='EvaluationResultSample'): + correlation_info: dict[str, any] + evaluation_result: EvalResult + features: dict[str, any] + id: str + type: Literal[SampleType.EVALUATION_RESULT_SAMPLE] + + @overload + def __init__( + self, + *, + correlation_info: dict[str, Any], + evaluation_result: EvalResult, + features: dict[str, Any], + id: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationRule(_Model): + action: EvaluationRuleAction + description: Optional[str] + display_name: Optional[str] + enabled: bool + event_type: Union[str, EvaluationRuleEventType] + filter: Optional[EvaluationRuleFilter] + id: str + system_data: dict[str, str] + + @overload + def __init__( + self, + *, + action: EvaluationRuleAction, + description: Optional[str] = ..., + display_name: Optional[str] = ..., + enabled: bool, + event_type: Union[str, EvaluationRuleEventType], + filter: Optional[EvaluationRuleFilter] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationRuleAction(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationRuleActionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTINUOUS_EVALUATION = "continuousEvaluation" + HUMAN_EVALUATION_PREVIEW = "humanEvaluationPreview" + + + class azure.ai.projects.models.EvaluationRuleEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MANUAL = "manual" + RESPONSE_COMPLETED = "responseCompleted" + + + class azure.ai.projects.models.EvaluationRuleFilter(_Model): + agent_name: str + + @overload + def __init__( + self, + *, + agent_name: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationRunClusterInsightRequest(InsightRequest, discriminator='EvaluationRunClusterInsight'): + eval_id: str + model_configuration: Optional[InsightModelConfiguration] + run_ids: list[str] + type: Literal[InsightType.EVALUATION_RUN_CLUSTER_INSIGHT] + + @overload + def __init__( + self, + *, + eval_id: str, + model_configuration: Optional[InsightModelConfiguration] = ..., + run_ids: list[str] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationRunClusterInsightResult(InsightResult, discriminator='EvaluationRunClusterInsight'): + cluster_insight: ClusterInsightResult + type: Literal[InsightType.EVALUATION_RUN_CLUSTER_INSIGHT] + + @overload + def __init__( + self, + *, + cluster_insight: ClusterInsightResult + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationScheduleTask(ScheduleTask, discriminator='Evaluation'): + configuration: dict[str, str] + eval_id: str + eval_run: dict[str, Any] + type: Literal[ScheduleTaskType.EVALUATION] + + @overload + def __init__( + self, + *, + configuration: Optional[dict[str, str]] = ..., + eval_id: str, + eval_run: dict[str, Any] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationTarget(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationTaxonomy(_Model): + description: Optional[str] + id: Optional[str] + name: str + properties: Optional[dict[str, str]] + tags: Optional[dict[str, str]] + taxonomy_categories: Optional[list[TaxonomyCategory]] + taxonomy_input: EvaluationTaxonomyInput + version: str + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + properties: Optional[dict[str, str]] = ..., + tags: Optional[dict[str, str]] = ..., + taxonomy_categories: Optional[list[TaxonomyCategory]] = ..., + taxonomy_input: EvaluationTaxonomyInput + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationTaxonomyInput(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluationTaxonomyInputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + POLICY = "policy" + + + class azure.ai.projects.models.EvaluatorCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENTS = "agents" + QUALITY = "quality" + SAFETY = "safety" + + + class azure.ai.projects.models.EvaluatorCredentialRequest(_Model): + blob_uri: str + + @overload + def __init__( + self, + *, + blob_uri: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorDefinition(_Model): + data_schema: Optional[dict[str, Any]] + init_parameters: Optional[dict[str, Any]] + metrics: Optional[dict[str, EvaluatorMetric]] + type: str + + @overload + def __init__( + self, + *, + data_schema: Optional[dict[str, Any]] = ..., + init_parameters: Optional[dict[str, Any]] = ..., + metrics: Optional[dict[str, EvaluatorMetric]] = ..., + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorDefinitionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CODE = "code" + ENDPOINT = "endpoint" + OPENAI_GRADERS = "openai_graders" + PROMPT = "prompt" + PROMPT_AND_CODE = "prompt_and_code" + RUBRIC = "rubric" + SERVICE = "service" + + + class azure.ai.projects.models.EvaluatorGenerationArtifacts(_Model): + dataset: DatasetReference + kinds: list[str] + + @overload + def __init__( + self, + *, + dataset: DatasetReference, + kinds: list[str] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorGenerationInputs(_Model): + evaluator_description: Optional[str] + evaluator_display_name: Optional[str] + evaluator_name: str + model: str + sources: list[EvaluatorGenerationJobSource] + + @overload + def __init__( + self, + *, + evaluator_description: Optional[str] = ..., + evaluator_display_name: Optional[str] = ..., + evaluator_name: str, + model: str, + sources: list[EvaluatorGenerationJobSource] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorGenerationJob(_Model): + created_at: datetime + error: Optional[ApiError] + finished_at: Optional[datetime] + id: str + input_quality_warnings: Optional[list[RubricGenerationInputQualityWarning]] + inputs: Optional[EvaluatorGenerationInputs] + result: Optional[EvaluatorVersion] + status: Union[str, JobStatus] + usage: Optional[EvaluatorGenerationTokenUsage] + + @overload + def __init__( + self, + *, + inputs: Optional[EvaluatorGenerationInputs] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorGenerationJobSource(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorGenerationJobSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + DATASET = "dataset" + PROMPT = "prompt" + TRACES = "traces" + + + class azure.ai.projects.models.EvaluatorGenerationLROPoller(LROPoller[EvaluatorVersion]): + property details: Mapping[str, Any] # Read-only + + def __init__( + self, + client: Any, + initial_response: Any, + deserialization_callback: Any, + polling_method: Any + ) -> None: ... + + @classmethod + def from_continuation_token( + cls, + polling_method: PollingMethod[EvaluatorVersion], + continuation_token: str, + **kwargs: Any + ) -> EvaluatorGenerationLROPoller: ... + + + class azure.ai.projects.models.EvaluatorGenerationTokenUsage(_Model): + input_tokens: int + output_tokens: int + total_tokens: int + + @overload + def __init__( + self, + *, + input_tokens: int, + output_tokens: int, + total_tokens: int + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorMetric(_Model): + desirable_direction: Optional[Union[str, EvaluatorMetricDirection]] + is_primary: Optional[bool] + max_value: Optional[float] + min_value: Optional[float] + threshold: Optional[float] + type: Optional[Union[str, EvaluatorMetricType]] + + @overload + def __init__( + self, + *, + desirable_direction: Optional[Union[str, EvaluatorMetricDirection]] = ..., + is_primary: Optional[bool] = ..., + max_value: Optional[float] = ..., + min_value: Optional[float] = ..., + threshold: Optional[float] = ..., + type: Optional[Union[str, EvaluatorMetricType]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.EvaluatorMetricDirection(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DECREASE = "decrease" + INCREASE = "increase" + NEUTRAL = "neutral" + + + class azure.ai.projects.models.EvaluatorMetricType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BOOLEAN = "boolean" + CONTINUOUS = "continuous" + ORDINAL = "ordinal" + + + class azure.ai.projects.models.EvaluatorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BUILT_IN = "builtin" + CUSTOM = "custom" + + + class azure.ai.projects.models.EvaluatorVersion(_Model): + categories: list[Union[str, EvaluatorCategory]] + created_at: datetime + created_by: str + definition: EvaluatorDefinition + description: Optional[str] + display_name: Optional[str] + evaluator_type: Union[str, EvaluatorType] + generation_artifacts: Optional[EvaluatorGenerationArtifacts] + generation_job_id: Optional[str] + id: Optional[str] + metadata: Optional[dict[str, str]] + modified_at: datetime + name: str + supported_evaluation_levels: Optional[list[Union[str, EvaluationLevel]]] + tags: Optional[dict[str, str]] + version: str + warnings: Optional[list[Union[str, GenerationWarningType]]] + + @overload + def __init__( + self, + *, + categories: list[Union[str, EvaluatorCategory]], + definition: EvaluatorDefinition, + description: Optional[str] = ..., + display_name: Optional[str] = ..., + evaluator_type: Union[str, EvaluatorType], + metadata: Optional[dict[str, str]] = ..., + supported_evaluation_levels: Optional[list[Union[str, EvaluationLevel]]] = ..., + tags: Optional[dict[str, str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ExternalAgentDefinition(AgentDefinition, discriminator='external'): + kind: Literal[AgentKind.EXTERNAL] + otel_agent_id: Optional[str] + rai_config: RaiConfig + + @overload + def __init__( + self, + *, + otel_agent_id: Optional[str] = ..., + rai_config: Optional[RaiConfig] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FabricDataAgentToolParameters(_Model): + project_connections: Optional[list[ToolProjectConnection]] + + @overload + def __init__( + self, + *, + project_connections: Optional[list[ToolProjectConnection]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FabricIQPreviewTool(Tool, discriminator='fabric_iq_preview'): + project_connection_id: str + require_approval: Optional[Union[MCPToolRequireApproval, str]] + server_label: Optional[str] + server_url: Optional[str] + type: Literal[ToolType.FABRIC_IQ_PREVIEW] + + @overload + def __init__( + self, + *, + project_connection_id: str, + require_approval: Optional[Union[MCPToolRequireApproval, str]] = ..., + server_label: Optional[str] = ..., + server_url: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FabricIQPreviewToolboxTool(ToolboxTool, discriminator='fabric_iq_preview'): + description: str + name: str + project_connection_id: str + require_approval: Optional[Union[MCPToolRequireApproval, str]] + server_label: Optional[str] + server_url: Optional[str] + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.FABRIC_IQ_PREVIEW] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + project_connection_id: str, + require_approval: Optional[Union[MCPToolRequireApproval, str]] = ..., + server_label: Optional[str] = ..., + server_url: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FieldMapping(_Model): + content_fields: list[str] + filepath_field: Optional[str] + metadata_fields: Optional[list[str]] + title_field: Optional[str] + url_field: Optional[str] + vector_fields: Optional[list[str]] + + @overload + def __init__( + self, + *, + content_fields: list[str], + filepath_field: Optional[str] = ..., + metadata_fields: Optional[list[str]] = ..., + title_field: Optional[str] = ..., + url_field: Optional[str] = ..., + vector_fields: Optional[list[str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FileDataGenerationJobOutput(DataGenerationJobOutput, discriminator='file'): + filename: str + id: str + type: Literal[DataGenerationJobOutputType.FILE] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FileDataGenerationJobSource(DataGenerationJobSource, discriminator='file'): + description: str + id: str + type: Literal[DataGenerationJobSourceType.FILE] + + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + id: str + ) -> None: ... + + @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.A2APreviewToolboxTool(ToolboxTool, discriminator='a2a_preview'): - agent_card_path: Optional[str] - base_url: Optional[str] + class azure.ai.projects.models.FileDatasetVersion(DatasetVersion, discriminator='uri_file'): + connection_name: str + data_uri: str description: str + id: str + is_reference: bool name: str - project_connection_id: Optional[str] - send_credentials_for_agent_card: Optional[bool] - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.A2A_PREVIEW] + tags: dict[str, str] + type: Literal[DatasetType.URI_FILE] + version: str + + @overload + def __init__( + self, + *, + connection_name: Optional[str] = ..., + data_uri: str, + description: Optional[str] = ..., + tags: Optional[dict[str, str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FileSearchTool(Tool, discriminator='file_search'): + description: Optional[str] + filters: Optional[Filters] + max_num_results: Optional[int] + name: Optional[str] + ranking_options: Optional[RankingOptions] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.FILE_SEARCH] + vector_store_ids: list[str] @overload def __init__( self, *, - agent_card_path: Optional[str] = ..., - base_url: Optional[str] = ..., description: Optional[str] = ..., + filters: Optional[Filters] = ..., + max_num_results: Optional[int] = ..., name: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - send_credentials_for_agent_card: Optional[bool] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + ranking_options: Optional[RankingOptions] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ..., + vector_store_ids: list[str] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.A2AProtocolConfiguration(_Model): + class azure.ai.projects.models.FileSearchToolboxTool(ToolboxTool, discriminator='file_search'): + description: str + filters: Optional[Filters] + max_num_results: Optional[int] + name: str + ranking_options: Optional[RankingOptions] + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.FILE_SEARCH] + vector_store_ids: Optional[list[str]] + @overload + def __init__( + self, + *, + description: Optional[str] = ..., + filters: Optional[Filters] = ..., + max_num_results: Optional[int] = ..., + name: Optional[str] = ..., + ranking_options: Optional[RankingOptions] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ..., + vector_store_ids: Optional[list[str]] = ... + ) -> None: ... - class azure.ai.projects.models.A2AProtocolVersion(str, Enum, metaclass=CaseInsensitiveEnumMeta): - V1_0 = "1.0" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.A2ATool(Tool, discriminator='a2a'): - a2a_version: Union[str, A2AProtocolVersion] - agent_card_path: Optional[str] - base_url: Optional[str] - project_connection_id: Optional[str] - send_credentials_for_agent_card: Optional[bool] - type: Literal[ToolType.A2_A] + class azure.ai.projects.models.FixedRatioVersionSelectionRule(VersionSelectionRule, discriminator='FixedRatio'): + agent_version: str + traffic_percentage: int + type: Literal[VersionSelectorType.FIXED_RATIO] @overload def __init__( self, *, - a2a_version: Union[str, A2AProtocolVersion], - agent_card_path: Optional[str] = ..., - base_url: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - send_credentials_for_agent_card: Optional[bool] = ... + agent_version: str, + traffic_percentage: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.A2AToolboxTool(ToolboxTool, discriminator='a2a'): - a2a_version: Union[str, A2AProtocolVersion] - agent_card_path: Optional[str] - base_url: Optional[str] + class azure.ai.projects.models.FolderDatasetVersion(DatasetVersion, discriminator='uri_folder'): + connection_name: str + data_uri: str description: str + id: str + is_reference: bool name: str - project_connection_id: Optional[str] - send_credentials_for_agent_card: Optional[bool] - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.A2_A] + tags: dict[str, str] + type: Literal[DatasetType.URI_FOLDER] + version: str @overload def __init__( self, *, - a2a_version: Union[str, A2AProtocolVersion], - agent_card_path: Optional[str] = ..., - base_url: Optional[str] = ..., + connection_name: Optional[str] = ..., + data_uri: str, description: Optional[str] = ..., - name: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - send_credentials_for_agent_card: Optional[bool] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + tags: Optional[dict[str, str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AISearchIndexResource(_Model): - filter: Optional[str] - index_asset_id: Optional[str] - index_name: Optional[str] - project_connection_id: Optional[str] - query_type: Optional[Union[str, AzureAISearchQueryType]] - top_k: Optional[int] + class azure.ai.projects.models.FoundryModelArtifactProfileCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DATA_ONLY = "DataOnly" + RUNTIME_DEPENDENT = "RuntimeDependent" + UNKNOWN = "Unknown" + + + class azure.ai.projects.models.FoundryModelArtifactProfileSignal(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CUSTOM_PYTHON_CODE = "CustomPythonCode" + DYNAMIC_OPS = "DynamicOps" + NATIVE_BINARY = "NativeBinary" + PICKLE_DESERIALIZATION = "PickleDeserialization" + UNKNOWN_FORMAT = "UnknownFormat" + + + class azure.ai.projects.models.FoundryModelSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LOCAL_UPLOAD = "LocalUpload" + TRAINING_JOB = "TrainingJob" + + + class azure.ai.projects.models.FoundryModelWarning(_Model): + code: Optional[Union[str, FoundryModelWarningCode]] + message: Optional[str] @overload def __init__( self, *, - filter: Optional[str] = ..., - index_asset_id: Optional[str] = ..., - index_name: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - query_type: Optional[Union[str, AzureAISearchQueryType]] = ..., - top_k: Optional[int] = ... + code: Optional[Union[str, FoundryModelWarningCode]] = ..., + message: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ActivityProtocolAccessBoundary(str, Enum, metaclass=CaseInsensitiveEnumMeta): - READ1_ON1_ALLOWLISTED = "read.1on1.allowlisted" - READ1_ON1_DEVELOPERS = "read.1on1.developers" - READ1_ON1_MANAGER = "read.1on1.manager" - READ1_ON1_TENANT = "read.1on1.tenant" - READ_GROUP_ALLOWLISTED = "read.group.allowlisted" - READ_GROUP_DEVELOPERS = "read.group.developers" - READ_GROUP_MANAGER_INVITED = "read.group.manager-invited" - READ_GROUP_MANAGER_PRESENT = "read.group.manager-present" - READ_GROUP_TENANT = "read.group.tenant" - WRITE1_ON1_ALLOWLISTED = "write.1on1.allowlisted" - WRITE1_ON1_DEVELOPERS = "write.1on1.developers" - WRITE1_ON1_MANAGER = "write.1on1.manager" - WRITE1_ON1_TENANT = "write.1on1.tenant" - WRITE_GROUP_ALLOWLISTED = "write.group.allowlisted" - WRITE_GROUP_DEVELOPERS = "write.group.developers" - WRITE_GROUP_MANAGER_INVITED = "write.group.manager-invited" - WRITE_GROUP_MANAGER_PRESENT = "write.group.manager-present" - WRITE_GROUP_TENANT = "write.group.tenant" + class azure.ai.projects.models.FoundryModelWarningCode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + RUNTIME_DEPENDENT_ARTIFACT = "RuntimeDependentArtifact" + UNCLASSIFIED_ARTIFACT = "UnclassifiedArtifact" - class azure.ai.projects.models.ActivityProtocolConfiguration(_Model): - access_boundaries: Optional[list[Union[str, ActivityProtocolAccessBoundary]]] - enable_m365_public_endpoint: Optional[bool] + class azure.ai.projects.models.FoundryModelWeightType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DRAFT_MODEL = "DraftModel" + FULL_WEIGHT = "FullWeight" + LO_RA = "LoRA" + + + class azure.ai.projects.models.FunctionShellToolParam(Tool, discriminator='shell'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + description: Optional[str] + environment: Optional[FunctionShellToolParamEnvironment] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.SHELL] @overload def __init__( self, *, - enable_m365_public_endpoint: Optional[bool] = ... + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + description: Optional[str] = ..., + environment: Optional[FunctionShellToolParamEnvironment] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentBlueprintReference(_Model): + class azure.ai.projects.models.FunctionShellToolParamEnvironment(_Model): type: str @overload @@ -2836,1558 +7358,1595 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentBlueprintReferenceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - MANAGED_AGENT_IDENTITY_BLUEPRINT = "ManagedAgentIdentityBlueprint" + class azure.ai.projects.models.FunctionShellToolParamEnvironmentContainerReferenceParam(FunctionShellToolParamEnvironment, discriminator='container_reference'): + container_id: str + type: Literal[FunctionShellToolParamEnvironmentType.CONTAINER_REFERENCE] + @overload + def __init__( + self, + *, + container_id: str + ) -> None: ... - class azure.ai.projects.models.AgentCard(_Model): + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FunctionShellToolParamEnvironmentLocalEnvironmentParam(FunctionShellToolParamEnvironment, discriminator='local'): + skills: Optional[list[LocalSkillParam]] + type: Literal[FunctionShellToolParamEnvironmentType.LOCAL] + + @overload + def __init__( + self, + *, + skills: Optional[list[LocalSkillParam]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.FunctionShellToolParamEnvironmentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTAINER_AUTO = "container_auto" + CONTAINER_REFERENCE = "container_reference" + LOCAL = "local" + + + class azure.ai.projects.models.FunctionTool(Tool, discriminator='function'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + defer_loading: Optional[bool] description: Optional[str] - skills: list[AgentCardSkill] - version: str + name: str + output_schema: Optional[dict[str, Any]] + parameters: dict[str, Any] + strict: bool + type: Literal[ToolType.FUNCTION] @overload def __init__( self, *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + defer_loading: Optional[bool] = ..., description: Optional[str] = ..., - skills: list[AgentCardSkill], - version: str + name: str, + output_schema: Optional[dict[str, Any]] = ..., + parameters: dict[str, Any], + strict: bool ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentCardSkill(_Model): + class azure.ai.projects.models.FunctionToolParam(_Model): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + defer_loading: Optional[bool] description: Optional[str] - examples: Optional[list[str]] - id: str name: str - tags: Optional[list[str]] + output_schema: Optional[dict[str, Any]] + parameters: Optional[EmptyModelParam] + strict: Optional[bool] + type: Literal["function"] @overload def __init__( self, *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + defer_loading: Optional[bool] = ..., description: Optional[str] = ..., - examples: Optional[list[str]] = ..., - id: str, name: str, - tags: Optional[list[str]] = ... + output_schema: Optional[dict[str, Any]] = ..., + parameters: Optional[EmptyModelParam] = ..., + strict: Optional[bool] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentClusterInsightRequest(InsightRequest, discriminator='AgentClusterInsight'): - agent_name: str - model_configuration: Optional[InsightModelConfiguration] - type: Literal[InsightType.AGENT_CLUSTER_INSIGHT] + class azure.ai.projects.models.GenerateVoiceAgentRequest(_Model): + description: Optional[str] + draft: Optional[bool] + goal: Optional[str] + kind: Literal[AgentKind.VOICE] + model: Optional[str] + model_type: Optional[Union[str, VoiceModelType]] + name: str + tools: Optional[list[VoiceAgentTool]] + use_case: Optional[str] @overload def __init__( self, *, - agent_name: str, - model_configuration: Optional[InsightModelConfiguration] = ... + description: Optional[str] = ..., + draft: Optional[bool] = ..., + goal: Optional[str] = ..., + kind: Literal[AgentKind.VOICE], + model: Optional[str] = ..., + model_type: Optional[Union[str, VoiceModelType]] = ..., + name: str, + tools: Optional[list[VoiceAgentTool]] = ..., + use_case: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentClusterInsightResult(InsightResult, discriminator='AgentClusterInsight'): - cluster_insight: ClusterInsightResult - type: Literal[InsightType.AGENT_CLUSTER_INSIGHT] + class azure.ai.projects.models.GenerationWarningType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INPUT_QUALITY = "input_quality" - @overload - def __init__( - self, - *, - cluster_insight: ClusterInsightResult - ) -> None: ... - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... + class azure.ai.projects.models.GitHubCopilotBuiltInTool(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FILESYSTEM_READ = "filesystem_read" + FILESYSTEM_WRITE = "filesystem_write" + SHELL = "shell" + SUBAGENTS = "subagents" + WEB = "web" - class azure.ai.projects.models.AgentDataGenerationJobSource(DataGenerationJobSource, discriminator='agent'): - agent_name: str - agent_version: Optional[str] - description: str - type: Literal[DataGenerationJobSourceType.AGENT] + class azure.ai.projects.models.GitHubCopilotHarness(AgentHarness, discriminator='github_copilot_preview'): + type: Literal["github_copilot_preview"] @overload - def __init__( - self, - *, - agent_name: str, - agent_version: Optional[str] = ..., - description: Optional[str] = ... - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentDefinition(_Model): - kind: str - rai_config: Optional[RaiConfig] + class azure.ai.projects.models.GitHubCopilotToolsetConfig(_Model): + enabled: Optional[bool] + name: Union[str, GitHubCopilotBuiltInTool] @overload def __init__( self, *, - kind: str, - rai_config: Optional[RaiConfig] = ... + enabled: Optional[bool] = ..., + name: Union[str, GitHubCopilotBuiltInTool] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentDetails(_Model): - agent_card: Optional[AgentCard] - agent_endpoint: Optional[AgentEndpointConfig] - blueprint: Optional[AgentIdentity] - blueprint_reference: Optional[AgentBlueprintReference] - digital_worker_type: Optional[Union[str, DigitalWorkerType]] - id: str - instance_identity: Optional[AgentIdentity] - name: str - object: Literal[AgentObjectType.AGENT] - state: Union[str, AgentState] - state_source: Optional[Union[str, AgentStateSource]] - versions: AgentObjectVersions + class azure.ai.projects.models.GitHubCopilotToolsetDefaultConfig(_Model): + enabled: Optional[bool] @overload def __init__( self, *, - agent_card: Optional[AgentCard] = ..., - agent_endpoint: Optional[AgentEndpointConfig] = ..., - digital_worker_type: Optional[Union[str, DigitalWorkerType]] = ..., - id: str, - name: str, - object: Literal[AgentObjectType.AGENT], - versions: AgentObjectVersions + enabled: Optional[bool] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentEndpointAuthorizationScheme(_Model): - type: str + class azure.ai.projects.models.GitHubCopilotToolsetPreview(Tool, discriminator='github_copilot_toolset_preview'): + configs: Optional[list[GitHubCopilotToolsetConfig]] + default_config: Optional[GitHubCopilotToolsetDefaultConfig] + type: Literal[ToolType.GITHUB_COPILOT_TOOLSET_PREVIEW] @overload def __init__( self, *, - type: str + configs: Optional[list[GitHubCopilotToolsetConfig]] = ..., + default_config: Optional[GitHubCopilotToolsetDefaultConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentEndpointAuthorizationSchemeType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BOT_SERVICE = "BotService" - BOT_SERVICE_RBAC = "BotServiceRbac" - BOT_SERVICE_TENANT = "BotServiceTenant" - ENTRA = "Entra" + class azure.ai.projects.models.GitHubIssueEvent(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CLOSED = "closed" + OPENED = "opened" - class azure.ai.projects.models.AgentEndpointConfig(_Model): - authorization_schemes: Optional[list[AgentEndpointAuthorizationScheme]] - protocol_configuration: Optional[ProtocolConfiguration] - publish_approval_status: Optional[Union[str, PublishApprovalStatus]] - version_selector: Optional[VersionSelector] + class azure.ai.projects.models.GitHubIssueRoutineTrigger(RoutineTrigger, discriminator='github_issue'): + connection_id: str + issue_event: Union[str, GitHubIssueEvent] + owner: str + repository: str + type: Literal[RoutineTriggerType.GITHUB_ISSUE] @overload def __init__( self, *, - authorization_schemes: Optional[list[AgentEndpointAuthorizationScheme]] = ..., - protocol_configuration: Optional[ProtocolConfiguration] = ..., - version_selector: Optional[VersionSelector] = ... + connection_id: str, + issue_event: Union[str, GitHubIssueEvent], + owner: str, + repository: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentEndpointProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): - A2A = "a2a" - ACTIVITY = "activity" - INVOCATIONS = "invocations" - INVOCATIONS_WS = "invocations_ws" - MCP = "mcp" - RESPONSES = "responses" + class azure.ai.projects.models.GrammarSyntax1(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LARK = "lark" + REGEX = "regex" - class azure.ai.projects.models.AgentEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='agent'): - agent_name: str - agent_version: Optional[str] - description: Optional[str] - type: Literal[EvaluatorGenerationJobSourceType.AGENT] + class azure.ai.projects.models.HeaderTelemetryEndpointAuth(TelemetryEndpointAuth, discriminator='header'): + header_name: str + secret_id: str + secret_key: str + type: Literal[TelemetryEndpointAuthType.HEADER] @overload def __init__( self, *, - agent_name: str, - agent_version: Optional[str] = ..., - description: Optional[str] = ... + header_name: str, + secret_id: str, + secret_key: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentIdentity(_Model): - client_id: str - principal_id: str - status: Optional[Union[str, AgentIdentityStatus]] + class azure.ai.projects.models.HostedAgentDefinition(AgentDefinition, discriminator='hosted'): + code_configuration: Optional[CodeConfiguration] + container_configuration: Optional[ContainerConfiguration] + cpu: str + environment_variables: Optional[dict[str, str]] + kind: Literal[AgentKind.HOSTED] + memory: str + protocol_versions: Optional[list[ProtocolVersionRecord]] + rai_config: RaiConfig + session_configuration: Optional[SessionConfiguration] + telemetry_config: Optional[TelemetryConfig] @overload def __init__( self, *, - client_id: str, - principal_id: str, - status: Optional[Union[str, AgentIdentityStatus]] = ... + code_configuration: Optional[CodeConfiguration] = ..., + container_configuration: Optional[ContainerConfiguration] = ..., + cpu: str, + environment_variables: Optional[dict[str, str]] = ..., + memory: str, + protocol_versions: Optional[list[ProtocolVersionRecord]] = ..., + rai_config: Optional[RaiConfig] = ..., + session_configuration: Optional[SessionConfiguration] = ..., + telemetry_config: Optional[TelemetryConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentIdentityStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ACTIVE = "active" - DISABLED = "disabled" + class azure.ai.projects.models.HourlyRecurrenceSchedule(RecurrenceSchedule, discriminator='Hourly'): + type: Literal[RecurrenceType.HOURLY] + @overload + def __init__(self) -> None: ... - class azure.ai.projects.models.AgentInsight(_Model): - agent_name: str - agent_version: str - category: str - created_at: datetime - description: str - details: Optional[AgentInsightDetails] - id: str - monitor_id: str - severity: Union[str, AgentInsightSeverity] - status: Union[str, AgentInsightStatus] - title: str - trace_count: int - updated_at: datetime + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightDetails(_Model): - highlighted_traces: list[AgentInsightHighlightedTrace] - linked_traces: list[AgentInsightLinkedTrace] - recommended_actions: AgentInsightRecommendedAction + class azure.ai.projects.models.HumanEvaluationPreviewRuleAction(EvaluationRuleAction, discriminator='humanEvaluationPreview'): + template_id: str + type: Literal[EvaluationRuleActionType.HUMAN_EVALUATION_PREVIEW] @overload def __init__( self, *, - highlighted_traces: list[AgentInsightHighlightedTrace], - linked_traces: list[AgentInsightLinkedTrace], - recommended_actions: AgentInsightRecommendedAction + template_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightEstimatedCost(_Model): - amount: float - currency: Literal["USD"] + class azure.ai.projects.models.HybridSearchOptions(_Model): + embedding_weight: float + text_weight: float @overload def __init__( self, *, - amount: float + embedding_weight: float, + text_weight: float ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightHighlightedTrace(_Model): - duration_ms: timedelta - summary: str - timestamp: datetime - total_tokens: Optional[int] - trace_id: str + class azure.ai.projects.models.ImageGenAction(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + EDIT = "edit" + GENERATE = "generate" + + + class azure.ai.projects.models.ImageGenTool(Tool, discriminator='image_generation'): + action: Optional[Union[str, ImageGenAction]] + background: Optional[Literal["transparent", "opaque", "auto"]] + description: Optional[str] + input_fidelity: Optional[Union[str, InputFidelity]] + input_image_mask: Optional[ImageGenToolInputImageMask] + model: Optional[Union[Literal["gpt-image-1"], Literal["gpt-image-1-mini"], Literal["gpt-image-5"], str]] + moderation: Optional[Literal["auto", "low"]] + name: Optional[str] + output_compression: Optional[int] + output_format: Optional[Literal["png", "webp", "jpeg"]] + partial_images: Optional[int] + quality: Optional[Literal["low", "medium", "high", "auto"]] + size: Optional[Union[Literal["1024x1024"], Literal["1024x1536"], Literal["1536x1024"], Literal["auto"], str]] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.IMAGE_GENERATION] @overload def __init__( self, *, - duration_ms: timedelta, - summary: str, - timestamp: datetime, - total_tokens: Optional[int] = ... + action: Optional[Union[str, ImageGenAction]] = ..., + background: Optional[Literal[transparent, opaque, auto]] = ..., + description: Optional[str] = ..., + input_fidelity: Optional[Union[str, InputFidelity]] = ..., + input_image_mask: Optional[ImageGenToolInputImageMask] = ..., + model: Optional[Union[Literal[gpt-image-1], Literal[gpt-image-1-mini], Literal[gpt-image-5], str]] = ..., + moderation: Optional[Literal[auto, low]] = ..., + name: Optional[str] = ..., + output_compression: Optional[int] = ..., + output_format: Optional[Literal[png, webp, jpeg]] = ..., + partial_images: Optional[int] = ..., + quality: Optional[Literal[low, medium, high, auto]] = ..., + size: Optional[Union[Literal[1024x1024], Literal[1024x1536], Literal[1536x1024], Literal[auto], str]] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightLinkedTrace(_Model): - timestamp: datetime - trace_id: str - - - class azure.ai.projects.models.AgentInsightMonitor(_Model): - agent_name: str - enabled: bool - estimated_cost: Optional[AgentInsightEstimatedCost] - id: str - model_deployment_name: str - next_scheduled_run_at: Optional[datetime] - overview: AgentInsightsOverview - run_interval_hours: float - suspension: AgentInsightSuspension - updated_at: datetime - - - class azure.ai.projects.models.AgentInsightMonitorCreate(_Model): - agent_name: str - enabled: Optional[bool] - model_deployment_name: str - run_interval_hours: Optional[float] + class azure.ai.projects.models.ImageGenToolInputImageMask(_Model): + file_id: Optional[str] + image_url: Optional[str] @overload def __init__( self, *, - agent_name: str, - enabled: Optional[bool] = ..., - model_deployment_name: str, - run_interval_hours: Optional[float] = ... + file_id: Optional[str] = ..., + image_url: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightMonitorListItem(_Model): - agent_name: str - enabled: bool - estimated_cost: Optional[AgentInsightEstimatedCost] - id: str - model_deployment_name: str - next_scheduled_run_at: Optional[datetime] - run_interval_hours: float - suspension: AgentInsightSuspension - updated_at: datetime - - - class azure.ai.projects.models.AgentInsightMonitorUpdate(_Model): - enabled: Optional[bool] - model_deployment_name: Optional[str] - overview_override: Optional[AgentInsightsOverviewOverride] - run_interval_hours: Optional[float] + class azure.ai.projects.models.Index(_Model): + description: Optional[str] + id: Optional[str] + name: str + tags: Optional[dict[str, str]] + type: str + version: str @overload def __init__( self, *, - enabled: Optional[bool] = ..., - model_deployment_name: Optional[str] = ..., - overview_override: Optional[AgentInsightsOverviewOverride] = ..., - run_interval_hours: Optional[float] = ... + description: Optional[str] = ..., + tags: Optional[dict[str, str]] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightOverviewSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): - GENERATED = "generated" - USER_OVERRIDE = "user_override" - - - class azure.ai.projects.models.AgentInsightPromptSurface(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INSTRUCTIONS = "instructions" - TOOL = "tool" + class azure.ai.projects.models.IndexType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AZURE_SEARCH = "AzureSearch" + COSMOS_DB = "CosmosDBNoSqlVectorStore" + MANAGED_AZURE_SEARCH = "ManagedAzureSearch" - class azure.ai.projects.models.AgentInsightProposedFix(_Model): - changes: Optional[list[AgentInsightProposedFixChange]] - kind: Union[str, AgentInsightProposedFixKind] - text: str + class azure.ai.projects.models.InlineSkillParam(ContainerSkill, discriminator='inline'): + description: str + name: str + source: InlineSkillSourceParam + type: Literal[ContainerSkillType.INLINE] @overload def __init__( self, *, - changes: Optional[list[AgentInsightProposedFixChange]] = ..., - kind: Union[str, AgentInsightProposedFixKind], - text: str + description: str, + name: str, + source: InlineSkillSourceParam ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightProposedFixChange(_Model): - diff: Optional[str] - language: Optional[str] - new_value: Optional[Any] - old_value: Optional[Any] - path: Optional[str] - surface: Optional[Union[str, AgentInsightPromptSurface]] - target: Optional[str] + class azure.ai.projects.models.InlineSkillSourceParam(_Model): + data: str + media_type: Literal["application/zip"] + type: Literal["base64"] @overload def __init__( self, *, - diff: Optional[str] = ..., - language: Optional[str] = ..., - new_value: Optional[Any] = ..., - old_value: Optional[Any] = ..., - path: Optional[str] = ..., - surface: Optional[Union[str, AgentInsightPromptSurface]] = ..., - target: Optional[str] = ... + data: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightProposedFixKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CODE_CHANGE = "code_change" - PROMPT_CHANGE = "prompt_change" - PROSE = "prose" + class azure.ai.projects.models.InputFidelity(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" - class azure.ai.projects.models.AgentInsightRecommendedAction(_Model): - proposed_fix: AgentInsightProposedFix + class azure.ai.projects.models.Insight(_Model): + display_name: str + insight_id: str + metadata: InsightsMetadata + request: InsightRequest + result: Optional[InsightResult] + state: Union[str, OperationState] @overload def __init__( self, *, - proposed_fix: AgentInsightProposedFix + display_name: str, + request: InsightRequest ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightRun(_Model): - agent_name: str - completed_at: Optional[datetime] - created_at: datetime - error: Optional[ApiError] + class azure.ai.projects.models.InsightCluster(_Model): + description: str id: str - inputs: Optional[AgentInsightRunCreate] - model_deployment_name: str - monitor_id: str - result: Optional[AgentInsightRunResult] - started_at: Optional[datetime] - status: Union[str, JobStatus] - trigger: Union[str, AgentInsightRunTrigger] - updated_at: datetime - window_end: datetime - window_start: datetime + label: str + samples: Optional[list[InsightSample]] + sub_clusters: Optional[list[InsightCluster]] + suggestion: str + suggestion_title: str + weight: int @overload def __init__( self, *, - inputs: Optional[AgentInsightRunCreate] = ... + description: str, + id: str, + label: str, + samples: Optional[list[InsightSample]] = ..., + sub_clusters: Optional[list[InsightCluster]] = ..., + suggestion: str, + suggestion_title: str, + weight: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightRunCreate(_Model): - lookback_hours: Optional[float] + class azure.ai.projects.models.InsightModelConfiguration(_Model): + model_deployment_name: str @overload def __init__( self, *, - lookback_hours: Optional[float] = ... + model_deployment_name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightRunLROPoller(LROPoller[AgentInsightRunResult]): - property details: Mapping[str, Any] # Read-only - - def __init__( - self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any - ) -> None: ... - - @classmethod - def from_continuation_token( - cls, - polling_method: PollingMethod[AgentInsightRunResult], - continuation_token: str, - **kwargs: Any - ) -> AgentInsightRunLROPoller: ... - - def status(self) -> str: ... - - - class azure.ai.projects.models.AgentInsightRunResult(_Model): - insights_created: int - insights_reopened: int - insights_updated: int - token_usage: AgentInsightTokenUsage - traces_analyzed: int - traces_in_window: int + class azure.ai.projects.models.InsightRequest(_Model): + type: str @overload def __init__( self, *, - insights_created: int, - insights_reopened: int, - insights_updated: int, - token_usage: AgentInsightTokenUsage, - traces_analyzed: int, - traces_in_window: int + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightRunTrigger(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ON_DEMAND = "on_demand" - SCHEDULED = "scheduled" - - - class azure.ai.projects.models.AgentInsightSeverity(str, Enum, metaclass=CaseInsensitiveEnumMeta): - HIGH = "high" - LOW = "low" - MEDIUM = "medium" - - - class azure.ai.projects.models.AgentInsightStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ACTIVE = "active" - IGNORED = "ignored" - RESOLVED = "resolved" - - - class azure.ai.projects.models.AgentInsightSuspension(_Model): - code: str - details: Optional[dict[str, Any]] - message: str - occurred_at: datetime + class azure.ai.projects.models.InsightResult(_Model): + type: str @overload def __init__( self, *, - code: str, - details: Optional[dict[str, Any]] = ..., - message: str, - occurred_at: datetime + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightTokenUsage(_Model): - cached_tokens: Optional[int] - input_tokens: int - output_tokens: int - total_tokens: int + class azure.ai.projects.models.InsightSample(_Model): + correlation_info: dict[str, Any] + features: dict[str, Any] + id: str + type: str @overload - def __init__( - self, - *, - cached_tokens: Optional[int] = ..., - input_tokens: int, - output_tokens: int, - total_tokens: int + def __init__( + self, + *, + correlation_info: dict[str, Any], + features: dict[str, Any], + id: str, + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightUpdate(_Model): - status: Optional[Union[str, AgentInsightStatus]] + class azure.ai.projects.models.InsightScheduleTask(ScheduleTask, discriminator='Insight'): + configuration: dict[str, str] + insight: Insight + type: Literal[ScheduleTaskType.INSIGHT] @overload def __init__( self, *, - status: Optional[Union[str, AgentInsightStatus]] = ... + configuration: Optional[dict[str, str]] = ..., + insight: Insight ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightsOverview(_Model): - content: str - source: Union[str, AgentInsightOverviewSource] - updated_at: datetime + class azure.ai.projects.models.InsightSummary(_Model): + method: str + sample_count: int + unique_cluster_count: int + unique_subcluster_count: int + usage: ClusterTokenUsage @overload def __init__( self, *, - content: str, - source: Union[str, AgentInsightOverviewSource], - updated_at: datetime + method: str, + sample_count: int, + unique_cluster_count: int, + unique_subcluster_count: int, + usage: ClusterTokenUsage ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentInsightsOverviewOverride(_Model): - content: str + class azure.ai.projects.models.InsightType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT_CLUSTER_INSIGHT = "AgentClusterInsight" + EVALUATION_COMPARISON = "EvaluationComparison" + EVALUATION_RUN_CLUSTER_INSIGHT = "EvaluationRunClusterInsight" + + + class azure.ai.projects.models.InsightsMetadata(_Model): + completed_at: Optional[datetime] + created_at: datetime @overload def __init__( self, *, - content: str + completed_at: Optional[datetime] = ..., + created_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EXTERNAL = "external" - HOSTED = "hosted" - PROMPT = "prompt" - WORKFLOW = "workflow" + class azure.ai.projects.models.InvocationsProtocolConfiguration(_Model): - class azure.ai.projects.models.AgentObjectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - AGENT_CONTAINER = "agent.container" - AGENT_DELETED = "agent.deleted" - AGENT_VERSION = "agent.version" - AGENT_VERSION_DELETED = "agent.version.deleted" + class azure.ai.projects.models.InvocationsWsProtocolConfiguration(_Model): - class azure.ai.projects.models.AgentObjectVersions(_Model): - latest: AgentVersionDetails + class azure.ai.projects.models.InvokeAgentInvocationsApiDispatchPayload(RoutineDispatchPayload, discriminator='invoke_agent_invocations_api'): + input: Any + type: Literal[RoutineDispatchPayloadType.INVOKE_AGENT_INVOCATIONS_API] @overload def __init__( self, *, - latest: AgentVersionDetails + input: Any ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationCandidate(_Model): - avg_score: float - avg_tokens: float - candidate_id: Optional[str] - eval_id: Optional[str] - eval_run_id: Optional[str] - mutations: Optional[dict[str, Any]] - name: str - promotion: Optional[PromotionInfo] + class azure.ai.projects.models.InvokeAgentInvocationsApiRoutineAction(RoutineAction, discriminator='invoke_agent_invocations_api'): + agent_endpoint_id: Optional[str] + agent_name: Optional[str] + input: Optional[Any] + session_id: Optional[str] + type: Literal[RoutineActionType.INVOKE_AGENT_INVOCATIONS_API] @overload def __init__( self, *, - avg_score: float, - avg_tokens: float, - candidate_id: Optional[str] = ..., - eval_id: Optional[str] = ..., - eval_run_id: Optional[str] = ..., - mutations: Optional[dict[str, Any]] = ..., - name: str, - promotion: Optional[PromotionInfo] = ... + agent_endpoint_id: Optional[str] = ..., + agent_name: Optional[str] = ..., + input: Optional[Any] = ..., + session_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationDatasetCriterion(_Model): - instruction: str - name: str + class azure.ai.projects.models.InvokeAgentResponsesApiDispatchPayload(RoutineDispatchPayload, discriminator='invoke_agent_responses_api'): + input: Any + type: Literal[RoutineDispatchPayloadType.INVOKE_AGENT_RESPONSES_API] @overload def __init__( self, *, - instruction: str, - name: str + input: Any ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationDatasetInput(_Model): - type: str + class azure.ai.projects.models.InvokeAgentResponsesApiRoutineAction(RoutineAction, discriminator='invoke_agent_responses_api'): + agent_endpoint_id: Optional[str] + agent_name: Optional[str] + conversation: Optional[str] + input: Optional[Any] + type: Literal[RoutineActionType.INVOKE_AGENT_RESPONSES_API] @overload def __init__( self, *, - type: str + agent_endpoint_id: Optional[str] = ..., + agent_name: Optional[str] = ..., + conversation: Optional[str] = ..., + input: Optional[Any] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationDatasetInputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INLINE = "inline" - REFERENCE = "reference" + class azure.ai.projects.models.JobStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CANCELLED = "cancelled" + FAILED = "failed" + IN_PROGRESS = "in_progress" + QUEUED = "queued" + SUCCEEDED = "succeeded" - class azure.ai.projects.models.AgentOptimizationDatasetItem(_Model): - criteria: Optional[list[AgentOptimizationDatasetCriterion]] - desired_num_turns: Optional[int] - ground_truth: Optional[str] - query: Optional[str] + class azure.ai.projects.models.LocalShellToolParam(Tool, discriminator='local_shell'): + description: Optional[str] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.LOCAL_SHELL] @overload def __init__( self, *, - criteria: Optional[list[AgentOptimizationDatasetCriterion]] = ..., - desired_num_turns: Optional[int] = ..., - ground_truth: Optional[str] = ..., - query: Optional[str] = ... + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationEvaluatorRef(_Model): + class azure.ai.projects.models.LocalSkillParam(_Model): + description: str name: str - version: Optional[str] + path: str @overload def __init__( self, *, + description: str, name: str, - version: Optional[str] = ... + path: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationInlineDatasetInput(AgentOptimizationDatasetInput, discriminator='inline'): - dataset_items: list[AgentOptimizationDatasetItem] - type: Literal[AgentOptimizationDatasetInputType.INLINE] + class azure.ai.projects.models.LogProbProperties(_Model): + bytes: list[int] + logprob: float + token: str @overload def __init__( self, *, - dataset_items: list[AgentOptimizationDatasetItem] + bytes: list[int], + logprob: float, + token: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationJob(_Model): - created_at: datetime - error: Optional[ApiError] - id: str - inputs: Optional[AgentOptimizationJobInputs] - progress: Optional[AgentOptimizationJobProgress] - result: Optional[AgentOptimizationJobResult] - status: Union[str, JobStatus] - updated_at: datetime - warnings: Optional[list[str]] + class azure.ai.projects.models.LoraConfig(_Model): + alpha: Optional[int] + dropout: Optional[float] + rank: Optional[int] + target_modules: Optional[list[str]] @overload def __init__( self, *, - inputs: Optional[AgentOptimizationJobInputs] = ... + alpha: Optional[int] = ..., + dropout: Optional[float] = ..., + rank: Optional[int] = ..., + target_modules: Optional[list[str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationJobInputs(_Model): - agent: OptimizedAgentIdentifier - evaluators: list[AgentOptimizationEvaluatorRef] - options: Optional[AgentOptimizationOptions] - train_dataset: AgentOptimizationDatasetInput - validation_dataset: Optional[AgentOptimizationDatasetInput] + class azure.ai.projects.models.MCPListToolsTool(_Model): + annotations: Optional[MCPListToolsToolAnnotations] + description: Optional[str] + input_schema: MCPListToolsToolInputSchema + name: str @overload def __init__( self, *, - agent: OptimizedAgentIdentifier, - evaluators: list[AgentOptimizationEvaluatorRef], - options: Optional[AgentOptimizationOptions] = ..., - train_dataset: AgentOptimizationDatasetInput, - validation_dataset: Optional[AgentOptimizationDatasetInput] = ... + annotations: Optional[MCPListToolsToolAnnotations] = ..., + description: Optional[str] = ..., + input_schema: MCPListToolsToolInputSchema, + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationJobListItem(_Model): - agent: Optional[OptimizedAgentIdentifier] - created_at: datetime - error: Optional[ApiError] - id: str - progress: Optional[AgentOptimizationJobProgress] - status: Union[str, JobStatus] - updated_at: datetime + class azure.ai.projects.models.MCPListToolsToolAnnotations(_Model): - class azure.ai.projects.models.AgentOptimizationJobProgress(_Model): - best_score: float - candidates_completed: int - elapsed_seconds: float + class azure.ai.projects.models.MCPListToolsToolInputSchema(_Model): + + + class azure.ai.projects.models.MCPTool(Tool, discriminator='mcp'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + allowed_tools: Optional[Union[list[str], MCPToolFilter]] + authorization: Optional[str] + connector_id: Optional[Literal["connector_dropbox", "connector_gmail", "connector_googlecalendar", "connector_googledrive", "connector_microsoftteams", "connector_outlookcalendar", "connector_outlookemail", "connector_sharepoint"]] + defer_loading: Optional[bool] + headers: Optional[dict[str, str]] + project_connection_id: Optional[str] + require_approval: Optional[Union[MCPToolRequireApproval, Literal["always"], Literal["never"]]] + server_description: Optional[str] + server_label: str + server_url: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + tunnel_id: Optional[str] + type: Literal[ToolType.MCP] + + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + allowed_tools: Optional[Union[list[str], MCPToolFilter]] = ..., + authorization: Optional[str] = ..., + connector_id: Optional[Literal[connector_dropbox, connector_gmail, connector_googlecalendar, connector_googledrive, connector_microsoftteams, connector_outlookcalendar, connector_outlookemail, connector_sharepoint]] = ..., + defer_loading: Optional[bool] = ..., + headers: Optional[dict[str, str]] = ..., + project_connection_id: Optional[str] = ..., + require_approval: Optional[Union[MCPToolRequireApproval, Literal[always], Literal[never]]] = ..., + server_description: Optional[str] = ..., + server_label: str, + server_url: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ..., + tunnel_id: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.MCPToolFilter(_Model): + read_only: Optional[bool] + tool_names: Optional[list[str]] + + @overload + def __init__( + self, + *, + read_only: Optional[bool] = ..., + tool_names: Optional[list[str]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.MCPToolRequireApproval(_Model): + always: Optional[MCPToolFilter] + never: Optional[MCPToolFilter] @overload def __init__( self, *, - best_score: float, - candidates_completed: int, - elapsed_seconds: float + always: Optional[MCPToolFilter] = ..., + never: Optional[MCPToolFilter] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationJobResult(_Model): - baseline: Optional[str] - best: Optional[str] - candidates: Optional[list[AgentOptimizationCandidate]] + class azure.ai.projects.models.MCPToolboxTool(ToolboxTool, discriminator='mcp'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + allowed_tools: Optional[Union[list[str], MCPToolFilter]] + authorization: Optional[str] + connector_id: Optional[Literal["connector_dropbox", "connector_gmail", "connector_googlecalendar", "connector_googledrive", "connector_microsoftteams", "connector_outlookcalendar", "connector_outlookemail", "connector_sharepoint"]] + defer_loading: Optional[bool] + description: str + headers: Optional[dict[str, str]] + name: str + project_connection_id: Optional[str] + require_approval: Optional[Union[MCPToolRequireApproval, Literal["always"], Literal["never"]]] + server_description: Optional[str] + server_label: str + server_url: Optional[str] + tool_configs: dict[str, ToolConfig] + tunnel_id: Optional[str] + type: Literal[ToolboxToolType.MCP] @overload def __init__( self, *, - baseline: Optional[str] = ..., - best: Optional[str] = ..., - candidates: Optional[list[AgentOptimizationCandidate]] = ... + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + allowed_tools: Optional[Union[list[str], MCPToolFilter]] = ..., + authorization: Optional[str] = ..., + connector_id: Optional[Literal[connector_dropbox, connector_gmail, connector_googlecalendar, connector_googledrive, connector_microsoftteams, connector_outlookcalendar, connector_outlookemail, connector_sharepoint]] = ..., + defer_loading: Optional[bool] = ..., + description: Optional[str] = ..., + headers: Optional[dict[str, str]] = ..., + name: Optional[str] = ..., + project_connection_id: Optional[str] = ..., + require_approval: Optional[Union[MCPToolRequireApproval, Literal[always], Literal[never]]] = ..., + server_description: Optional[str] = ..., + server_label: str, + server_url: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ..., + tunnel_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationLROPoller(LROPoller[AgentOptimizationJobResult]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.ManagedAgentIdentityBlueprintReference(AgentBlueprintReference, discriminator='ManagedAgentIdentityBlueprint'): + blueprint_id: str + type: Literal[AgentBlueprintReferenceType.MANAGED_AGENT_IDENTITY_BLUEPRINT] + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + blueprint_id: str ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: PollingMethod[AgentOptimizationJobResult], - continuation_token: str, - **kwargs: Any - ) -> AgentOptimizationLROPoller: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationOptions(_Model): - eval_model: Optional[str] - evaluation_level: Optional[Union[str, EvaluationLevel]] - max_candidates: Optional[int] - max_stalls: Optional[int] - optimization_config: Optional[dict[str, Any]] - optimization_model: Optional[str] + class azure.ai.projects.models.ManagedAzureAISearchIndex(Index, discriminator='ManagedAzureSearch'): + description: str + id: str + name: str + tags: dict[str, str] + type: Literal[IndexType.MANAGED_AZURE_SEARCH] + vector_store_id: str + version: str @overload def __init__( self, *, - eval_model: Optional[str] = ..., - evaluation_level: Optional[Union[str, EvaluationLevel]] = ..., - max_candidates: Optional[int] = ..., - max_stalls: Optional[int] = ..., - optimization_config: Optional[dict[str, Any]] = ..., - optimization_model: Optional[str] = ... + description: Optional[str] = ..., + tags: Optional[dict[str, str]] = ..., + vector_store_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentOptimizationReferenceDatasetInput(AgentOptimizationDatasetInput, discriminator='reference'): - name: str - type: Literal[AgentOptimizationDatasetInputType.REFERENCE] - version: Optional[str] + class azure.ai.projects.models.McpProtocolConfiguration(_Model): + + + class azure.ai.projects.models.MemoryItem(_Model): + content: str + kind: str + memory_id: str + scope: str + updated_at: datetime @overload def __init__( self, *, - name: str, - version: Optional[str] = ... + content: str, + kind: str, + memory_id: str, + scope: str, + updated_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentSessionResource(_Model): - agent_session_id: str - created_at: datetime - expires_at: datetime - last_accessed_at: datetime - status: Union[str, AgentSessionStatus] - version_indicator: VersionIndicator + class azure.ai.projects.models.MemoryItemKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CHAT_SUMMARY = "chat_summary" + PROCEDURAL = "procedural" + USER_PROFILE = "user_profile" + + + class azure.ai.projects.models.MemoryOperation(_Model): + kind: Union[str, MemoryOperationKind] + memory_item: MemoryItem @overload def __init__( self, *, - agent_session_id: str, - status: Union[str, AgentSessionStatus], - version_indicator: VersionIndicator + kind: Union[str, MemoryOperationKind], + memory_item: MemoryItem ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentSessionStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ACTIVE = "active" - CREATING = "creating" - DELETED = "deleted" - DELETING = "deleting" - EXPIRED = "expired" - FAILED = "failed" - IDLE = "idle" - UPDATING = "updating" + class azure.ai.projects.models.MemoryOperationKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CREATE = "create" + DELETE = "delete" + UPDATE = "update" - class azure.ai.projects.models.AgentState(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DISABLED = "disabled" - ENABLED = "enabled" + class azure.ai.projects.models.MemorySearchItem(_Model): + memory_item: MemoryItem + @overload + def __init__( + self, + *, + memory_item: MemoryItem + ) -> None: ... - class azure.ai.projects.models.AgentStateSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT_BLUEPRINT = "agent_blueprint" - AGENT_INSTANCE_IDENTITY = "agent_instance_identity" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentTaxonomyInput(EvaluationTaxonomyInput, discriminator='agent'): - risk_categories: list[Union[str, RiskCategory]] - target: EvaluationTarget - type: Literal[EvaluationTaxonomyInputType.AGENT] + class azure.ai.projects.models.MemorySearchOptions(_Model): + max_memories: Optional[int] @overload def __init__( self, *, - risk_categories: list[Union[str, RiskCategory]], - target: EvaluationTarget + max_memories: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentVersionDetails(_Model): - agent_guid: Optional[str] - blueprint: Optional[AgentIdentity] - blueprint_reference: Optional[AgentBlueprintReference] - created_at: datetime - definition: AgentDefinition - description: Optional[str] - draft: Optional[bool] - id: str - instance_identity: Optional[AgentIdentity] - metadata: dict[str, str] - name: str - object: Literal[AgentObjectType.AGENT_VERSION] - status: Optional[Union[str, AgentVersionStatus]] - version: str + class azure.ai.projects.models.MemorySearchPreviewTool(Tool, discriminator='memory_search_preview'): + memory_store_name: str + scope: str + search_options: Optional[MemorySearchOptions] + type: Literal[ToolType.MEMORY_SEARCH_PREVIEW] + update_delay: Optional[int] @overload def __init__( self, *, - created_at: datetime, - definition: AgentDefinition, - description: Optional[str] = ..., - draft: Optional[bool] = ..., - id: str, - metadata: dict[str, str], - name: str, - object: Literal[AgentObjectType.AGENT_VERSION], - status: Optional[Union[str, AgentVersionStatus]] = ..., - version: str + memory_store_name: str, + scope: str, + search_options: Optional[MemorySearchOptions] = ..., + update_delay: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AgentVersionStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ACTIVE = "active" - CREATING = "creating" - DELETED = "deleted" - DELETING = "deleting" - FAILED = "failed" - - - class azure.ai.projects.models.AgenticIdentityPreviewCredentials(BaseCredentials, discriminator='AgenticIdentityToken_Preview'): - type: Literal[CredentialType.AGENTIC_IDENTITY_PREVIEW] + class azure.ai.projects.models.MemoryStoreDefaultDefinition(MemoryStoreDefinition, discriminator='default'): + chat_model: str + embedding_model: str + kind: Literal[MemoryStoreKind.DEFAULT] + options: Optional[MemoryStoreDefaultOptions] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + chat_model: str, + embedding_model: str, + options: Optional[MemoryStoreDefaultOptions] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ApiError(_Model): - additional_info: Optional[dict[str, Any]] - code: str - debug_info: Optional[dict[str, Any]] - details: Optional[list[ApiError]] - message: str - param: Optional[str] - type: Optional[str] + class azure.ai.projects.models.MemoryStoreDefaultOptions(_Model): + chat_summary_enabled: bool + default_ttl_seconds: Optional[timedelta] + procedural_memory_enabled: Optional[bool] + user_profile_details: Optional[str] + user_profile_enabled: bool @overload - def __init__( - self, - *, - additional_info: Optional[dict[str, Any]] = ..., - code: str, - debug_info: Optional[dict[str, Any]] = ..., - details: Optional[list[ApiError]] = ..., - message: str, - param: Optional[str] = ..., - type: Optional[str] = ... + def __init__( + self, + *, + chat_summary_enabled: bool, + default_ttl_seconds: Optional[timedelta] = ..., + procedural_memory_enabled: Optional[bool] = ..., + user_profile_details: Optional[str] = ..., + user_profile_enabled: bool ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ApiErrorResponse(_Model): - error: ApiError + class azure.ai.projects.models.MemoryStoreDefinition(_Model): + kind: str @overload def __init__( self, *, - error: ApiError + kind: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ApiKeyCredentials(BaseCredentials, discriminator='ApiKey'): - api_key: Optional[str] - type: Literal[CredentialType.API_KEY] + class azure.ai.projects.models.MemoryStoreDeleteScopeResult(_Model): + deleted: bool + name: str + object: Literal[MemoryStoreObjectType.MEMORY_STORE_SCOPE_DELETED] + scope: str @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + deleted: bool, + name: str, + object: Literal[MemoryStoreObjectType.MEMORY_STORE_SCOPE_DELETED], + scope: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ApplyPatchToolParam(Tool, discriminator='apply_patch'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - type: Literal[ToolType.APPLY_PATCH] + class azure.ai.projects.models.MemoryStoreDetails(_Model): + created_at: datetime + definition: MemoryStoreDefinition + description: Optional[str] + id: str + metadata: Optional[dict[str, str]] + name: str + object: Literal[MemoryStoreObjectType.MEMORY_STORE] + updated_at: datetime @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ... + created_at: datetime, + definition: MemoryStoreDefinition, + description: Optional[str] = ..., + id: str, + metadata: Optional[dict[str, str]] = ..., + name: str, + object: Literal[MemoryStoreObjectType.MEMORY_STORE], + updated_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ApproximateLocation(_Model): - city: Optional[str] - country: Optional[str] - region: Optional[str] - timezone: Optional[str] - type: Literal["approximate"] + class azure.ai.projects.models.MemoryStoreKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DEFAULT = "default" + + + class azure.ai.projects.models.MemoryStoreObjectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MEMORY_DELETED = "memory_store.item.deleted" + MEMORY_STORE = "memory_store" + MEMORY_STORE_DELETED = "memory_store.deleted" + MEMORY_STORE_SCOPE_DELETED = "memory_store.scope.deleted" + + + class azure.ai.projects.models.MemoryStoreOperationUsage(_Model): + embedding_tokens: int + input_tokens: int + input_tokens_details: ResponseUsageInputTokensDetails + output_tokens: int + output_tokens_details: ResponseUsageOutputTokensDetails + total_tokens: int @overload def __init__( self, *, - city: Optional[str] = ..., - country: Optional[str] = ..., - region: Optional[str] = ..., - timezone: Optional[str] = ... + embedding_tokens: int, + input_tokens: int, + input_tokens_details: ResponseUsageInputTokensDetails, + output_tokens: int, + output_tokens_details: ResponseUsageOutputTokensDetails, + total_tokens: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ArtifactProfile(_Model): - category: Union[str, FoundryModelArtifactProfileCategory] - signals: Optional[list[Union[str, FoundryModelArtifactProfileSignal]]] + class azure.ai.projects.models.MemoryStoreSearchResult(_Model): + memories: list[MemorySearchItem] + search_id: str + usage: MemoryStoreOperationUsage @overload def __init__( self, *, - category: Union[str, FoundryModelArtifactProfileCategory], - signals: Optional[list[Union[str, FoundryModelArtifactProfileSignal]]] = ... + memories: list[MemorySearchItem], + search_id: str, + usage: MemoryStoreOperationUsage ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AsyncAgentInsightRunLROPoller(AsyncLROPoller[AgentInsightRunResult]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.MemoryStoreUpdateCompletedResult(_Model): + memory_operations: list[MemoryOperation] + usage: MemoryStoreOperationUsage + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + memory_operations: list[MemoryOperation], + usage: MemoryStoreOperationUsage ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: AsyncPollingMethod[AgentInsightRunResult], - continuation_token: str, - **kwargs: Any - ) -> AsyncAgentInsightRunLROPoller: ... - - def status(self) -> str: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AsyncAgentOptimizationLROPoller(AsyncLROPoller[AgentOptimizationJobResult]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.MemoryStoreUpdateResult(_Model): + error: Optional[ApiError] + result: Optional[MemoryStoreUpdateCompletedResult] + status: Union[str, MemoryStoreUpdateStatus] + superseded_by: Optional[str] + update_id: str + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + error: Optional[ApiError] = ..., + result: Optional[MemoryStoreUpdateCompletedResult] = ..., + status: Union[str, MemoryStoreUpdateStatus], + superseded_by: Optional[str] = ..., + update_id: str ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: AsyncPollingMethod[AgentOptimizationJobResult], - continuation_token: str, - **kwargs: Any - ) -> AsyncAgentOptimizationLROPoller: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AsyncDatasetGenerationLROPoller(AsyncLROPoller[DataGenerationJobResult]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.MemoryStoreUpdateStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + FAILED = "failed" + IN_PROGRESS = "in_progress" + QUEUED = "queued" + SUPERSEDED = "superseded" - def __init__( - self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any - ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: AsyncPollingMethod[DataGenerationJobResult], - continuation_token: str, - **kwargs: Any - ) -> AsyncDatasetGenerationLROPoller: ... + class azure.ai.projects.models.Metadata(_Model): - class azure.ai.projects.models.AsyncEvaluatorGenerationLROPoller(AsyncLROPoller[EvaluatorVersion]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.Microsoft365PermissionScopes(_Model): + resource_app_id: str + scopes: list[str] + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + resource_app_id: str, + scopes: list[str] ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: AsyncPollingMethod[EvaluatorVersion], - continuation_token: str, - **kwargs: Any - ) -> AsyncEvaluatorGenerationLROPoller: ... - - - class azure.ai.projects.models.AsyncUpdateMemoriesLROPoller(AsyncLROPoller[MemoryStoreUpdateCompletedResult]): - property superseded_by: Optional[str] # Read-only - property update_id: str # Read-only - - @classmethod - def from_continuation_token( - cls, - polling_method: AsyncPollingMethod[MemoryStoreUpdateCompletedResult], - continuation_token: str, - **kwargs: Any - ) -> AsyncUpdateMemoriesLROPoller: ... - - - class azure.ai.projects.models.AttackStrategy(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ANSI_ATTACK = "ansi_attack" - ASCII_ART = "ascii_art" - ASCII_SMUGGLER = "ascii_smuggler" - ATBASH = "atbash" - BASE64 = "base64" - BASELINE = "baseline" - BINARY = "binary" - CAESAR = "caesar" - CHARACTER_SPACE = "character_space" - CHARACTER_SWAP = "character_swap" - CRESCENDO = "crescendo" - DIACRITIC = "diacritic" - DIFFICULT = "difficult" - EASY = "easy" - FLIP = "flip" - INDIRECT_JAILBREAK = "indirect_jailbreak" - JAILBREAK = "jailbreak" - LEETSPEAK = "leetspeak" - MODERATE = "moderate" - MORSE = "morse" - MULTI_TURN = "multi_turn" - ROT13 = "rot13" - STRING_JOIN = "string_join" - SUFFIX_APPEND = "suffix_append" - TENSE = "tense" - UNICODE_CONFUSABLE = "unicode_confusable" - UNICODE_SUBSTITUTION = "unicode_substitution" - URL = "url" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AutoCodeInterpreterToolParam(_Model): - file_ids: Optional[list[str]] - memory_limit: Optional[Union[str, ContainerMemoryLimit]] - network_policy: Optional[ContainerNetworkPolicyParam] - type: Literal["auto"] + class azure.ai.projects.models.Microsoft365PublishDefaults(_Model): + agent_display_name: Optional[str] + agent_name: Optional[str] + app_publish_scope: Optional[Union[str, Microsoft365PublishScope]] + app_registration_client_id: Optional[str] + app_version: Optional[str] + bot_service_arm_id: Optional[str] + developer_name: Optional[str] + developer_website_url: Optional[str] + full_description: Optional[str] + privacy_url: Optional[str] + recommended_next_app_version: Optional[str] + short_description: Optional[str] + teams_app_id: Optional[str] + terms_of_use_url: Optional[str] + title_id: Optional[str] @overload def __init__( self, *, - file_ids: Optional[list[str]] = ..., - memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., - network_policy: Optional[ContainerNetworkPolicyParam] = ... + agent_display_name: Optional[str] = ..., + agent_name: Optional[str] = ..., + app_publish_scope: Optional[Union[str, Microsoft365PublishScope]] = ..., + app_registration_client_id: Optional[str] = ..., + app_version: Optional[str] = ..., + bot_service_arm_id: Optional[str] = ..., + developer_name: Optional[str] = ..., + developer_website_url: Optional[str] = ..., + full_description: Optional[str] = ..., + privacy_url: Optional[str] = ..., + recommended_next_app_version: Optional[str] = ..., + short_description: Optional[str] = ..., + teams_app_id: Optional[str] = ..., + terms_of_use_url: Optional[str] = ..., + title_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAIAgentTarget(EvaluationTarget, discriminator='azure_ai_agent'): - name: str - tool_descriptions: Optional[list[ToolDescription]] - tools: Optional[list[Tool]] - type: Literal["azure_ai_agent"] - version: Optional[str] + class azure.ai.projects.models.Microsoft365PublishResult(_Model): + teams_app_id: Optional[str] + title_id: Optional[str] @overload def __init__( self, *, - name: str, - tool_descriptions: Optional[list[ToolDescription]] = ..., - tools: Optional[list[Tool]] = ..., - version: Optional[str] = ... + teams_app_id: Optional[str] = ..., + title_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAIAgentTargetParam(TypedDict, total=False): - key "name": Required[str] - key "tool_descriptions": List[ToolDescriptionParam] - key "type": Required[Literal["azure_ai_agent"]] - key "version": str + class azure.ai.projects.models.Microsoft365PublishScope(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PERSONAL = "Personal" + SHARED = "Shared" + TENANT = "Tenant" - class azure.ai.projects.models.AzureAIBenchmarkPreviewEvalRunDataSource(TypedDict, total=False): - key "input_messages": InputMessagesItemReference - key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] - key "type": Required[Literal["azure_ai_benchmark_preview"]] + class azure.ai.projects.models.MicrosoftFabricPreviewTool(Tool, discriminator='fabric_dataagent_preview'): + fabric_dataagent_preview: FabricDataAgentToolParameters + type: Literal[ToolType.FABRIC_DATAAGENT_PREVIEW] + @overload + def __init__( + self, + *, + fabric_dataagent_preview: FabricDataAgentToolParameters + ) -> None: ... - class azure.ai.projects.models.AzureAIDataSourceConfig(TypedDict, total=False): - key "scenario": Required[str] - key "type": Required[Literal["azure_ai_source"]] + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAIModelTarget(EvaluationTarget, discriminator='azure_ai_model'): - model: Optional[str] - sampling_params: Optional[ModelSamplingParams] - type: Literal["azure_ai_model"] + class azure.ai.projects.models.ModelCredentialRequest(_Model): + blob_uri: str @overload def __init__( self, *, - model: Optional[str] = ..., - sampling_params: Optional[ModelSamplingParams] = ... + blob_uri: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAIModelTargetParam(TypedDict, total=False): - key "model": str - key "sampling_params": ModelSamplingConfigParam - key "type": Required[Literal["azure_ai_model"]] + class azure.ai.projects.models.ModelDeployment(Deployment, discriminator='ModelDeployment'): + capabilities: dict[str, str] + connection_name: Optional[str] + model_name: str + model_publisher: str + model_version: str + name: str + sku: ModelDeploymentSku + type: Literal[DeploymentType.MODEL_DEPLOYMENT] + @overload + def __init__(self) -> None: ... - class azure.ai.projects.models.AzureAIResponsesEvalRunDataSource(TypedDict, total=False): - key "event_configuration_id": str - key "item_generation_params": Required[ResponseRetrievalItemGenerationParams] - key "max_runs_hourly": int - key "type": Required[Literal["azure_ai_responses"]] + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAISearchIndex(Index, discriminator='AzureSearch'): - connection_name: str - description: str - field_mapping: Optional[FieldMapping] - id: str - index_name: str + class azure.ai.projects.models.ModelDeploymentSku(_Model): + capacity: int + family: str name: str - tags: dict[str, str] - type: Literal[IndexType.AZURE_SEARCH] - version: str + size: str + tier: str @overload def __init__( self, *, - connection_name: str, - description: Optional[str] = ..., - field_mapping: Optional[FieldMapping] = ..., - index_name: str, - tags: Optional[dict[str, str]] = ... + capacity: int, + family: str, + name: str, + size: str, + tier: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAISearchQueryType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - SEMANTIC = "semantic" - SIMPLE = "simple" - VECTOR = "vector" - VECTOR_SEMANTIC_HYBRID = "vector_semantic_hybrid" - VECTOR_SIMPLE_HYBRID = "vector_simple_hybrid" - - - class azure.ai.projects.models.AzureAISearchTool(Tool, discriminator='azure_ai_search'): - azure_ai_search: AzureAISearchToolResource - description: Optional[str] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.AZURE_AI_SEARCH] + class azure.ai.projects.models.ModelPendingUploadRequest(_Model): + connection_name: Optional[str] + pending_upload_id: Optional[str] + pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] @overload def __init__( self, *, - azure_ai_search: AzureAISearchToolResource, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + connection_name: Optional[str] = ..., + pending_upload_id: Optional[str] = ..., + pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAISearchToolResource(_Model): - indexes: list[AISearchIndexResource] + class azure.ai.projects.models.ModelPendingUploadResponse(_Model): + blob_reference: BlobReference + pending_upload_id: str + pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] + version: Optional[str] @overload def __init__( self, *, - indexes: list[AISearchIndexResource] + blob_reference: BlobReference, + pending_upload_id: str, + pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE], + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureAISearchToolboxTool(ToolboxTool, discriminator='azure_ai_search'): - azure_ai_search: AzureAISearchToolResource - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.AZURE_AI_SEARCH] + class azure.ai.projects.models.ModelSamplingConfigParam(TypedDict, total=False): + key "max_completion_tokens": int + key "seed": int + key "temperature": float + key "top_p": float + + + class azure.ai.projects.models.ModelSamplingParams(_Model): + max_completion_tokens: Optional[int] + seed: Optional[int] + temperature: Optional[float] + top_p: Optional[float] @overload def __init__( self, *, - azure_ai_search: AzureAISearchToolResource, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + max_completion_tokens: Optional[int] = ..., + seed: Optional[int] = ..., + temperature: Optional[float] = ..., + top_p: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureFunctionBinding(_Model): - storage_queue: AzureFunctionStorageQueue - type: Literal["storage_queue"] + class azure.ai.projects.models.ModelSourceData(_Model): + job_id: Optional[str] + source_type: Optional[Union[str, FoundryModelSourceType]] @overload def __init__( self, *, - storage_queue: AzureFunctionStorageQueue + job_id: Optional[str] = ..., + source_type: Optional[Union[str, FoundryModelSourceType]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureFunctionDefinition(_Model): - function: AzureFunctionDefinitionFunction - input_binding: AzureFunctionBinding - output_binding: AzureFunctionBinding + class azure.ai.projects.models.ModelVersion(_Model): + artifact_profile: Optional[ArtifactProfile] + base_model: Optional[str] + blob_uri: str + description: Optional[str] + id: Optional[str] + lora_config: Optional[LoraConfig] + name: str + source: Optional[ModelSourceData] + tags: Optional[dict[str, str]] + version: str + warnings: Optional[list[FoundryModelWarning]] + weight_type: Optional[Union[str, FoundryModelWeightType]] @overload def __init__( self, *, - function: AzureFunctionDefinitionFunction, - input_binding: AzureFunctionBinding, - output_binding: AzureFunctionBinding + base_model: Optional[str] = ..., + blob_uri: str, + description: Optional[str] = ..., + lora_config: Optional[LoraConfig] = ..., + source: Optional[ModelSourceData] = ..., + tags: Optional[dict[str, str]] = ..., + weight_type: Optional[Union[str, FoundryModelWeightType]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureFunctionDefinitionFunction(_Model): - description: Optional[str] - name: str - parameters: dict[str, Any] + class azure.ai.projects.models.MonthlyRecurrenceSchedule(RecurrenceSchedule, discriminator='Monthly'): + days_of_month: list[int] + type: Literal[RecurrenceType.MONTHLY] @overload def __init__( self, *, - description: Optional[str] = ..., - name: str, - parameters: dict[str, Any] + days_of_month: list[int] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureFunctionStorageQueue(_Model): - queue_name: str - queue_service_endpoint: str + class azure.ai.projects.models.NamespaceToolParam(Tool, discriminator='namespace'): + description: str + name: str + tools: list[Union[FunctionToolParam, CustomToolParam]] + type: Literal[ToolType.NAMESPACE] @overload def __init__( self, *, - queue_name: str, - queue_service_endpoint: str + description: str, + name: str, + tools: list[Union[FunctionToolParam, CustomToolParam]] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureFunctionTool(Tool, discriminator='azure_function'): - azure_function: AzureFunctionDefinition - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.AZURE_FUNCTION] + class azure.ai.projects.models.NoAuthenticationCredentials(BaseCredentials, discriminator='None'): + type: Literal[CredentialType.NONE] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.OneTimeTrigger(Trigger, discriminator='OneTime'): + time_zone: Optional[str] + trigger_at: datetime + type: Literal[TriggerType.ONE_TIME] @overload def __init__( self, *, - azure_function: AzureFunctionDefinition, - tool_configs: Optional[dict[str, ToolConfig]] = ... + time_zone: Optional[str] = ..., + trigger_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.AzureOpenAIModelConfiguration(RedTeamTargetConfig, discriminator='AzureOpenAIModel'): - model_deployment_name: str - type: Literal["AzureOpenAIModel"] + class azure.ai.projects.models.OpenApiAnonymousAuthDetails(OpenApiAuthDetails, discriminator='anonymous'): + type: Literal[OpenApiAuthType.ANONYMOUS] @overload - def __init__( - self, - *, - model_deployment_name: str - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BaseCredentials(_Model): + class azure.ai.projects.models.OpenApiAuthDetails(_Model): type: str @overload @@ -4401,594 +8960,606 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingCustomSearchConfiguration(_Model): - count: Optional[int] - freshness: Optional[str] - instance_name: str - market: Optional[str] - project_connection_id: str - set_lang: Optional[str] + class azure.ai.projects.models.OpenApiAuthType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ANONYMOUS = "anonymous" + MANAGED_IDENTITY = "managed_identity" + PROJECT_CONNECTION = "project_connection" + + + class azure.ai.projects.models.OpenApiFunctionDefinition(_Model): + auth: OpenApiAuthDetails + default_params: Optional[list[str]] + description: Optional[str] + functions: Optional[list[OpenApiFunctionDefinitionFunction]] + name: str + spec: dict[str, Any] @overload def __init__( self, *, - count: Optional[int] = ..., - freshness: Optional[str] = ..., - instance_name: str, - market: Optional[str] = ..., - project_connection_id: str, - set_lang: Optional[str] = ... + auth: OpenApiAuthDetails, + default_params: Optional[list[str]] = ..., + description: Optional[str] = ..., + name: str, + spec: dict[str, Any] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingCustomSearchPreviewTool(Tool, discriminator='bing_custom_search_preview'): - bing_custom_search_preview: BingCustomSearchToolParameters - type: Literal[ToolType.BING_CUSTOM_SEARCH_PREVIEW] + class azure.ai.projects.models.OpenApiFunctionDefinitionFunction(_Model): + description: Optional[str] + name: str + parameters: dict[str, Any] @overload def __init__( self, *, - bing_custom_search_preview: BingCustomSearchToolParameters + description: Optional[str] = ..., + name: str, + parameters: dict[str, Any] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingCustomSearchToolParameters(_Model): - search_configurations: list[BingCustomSearchConfiguration] + class azure.ai.projects.models.OpenApiManagedAuthDetails(OpenApiAuthDetails, discriminator='managed_identity'): + security_scheme: OpenApiManagedSecurityScheme + type: Literal[OpenApiAuthType.MANAGED_IDENTITY] @overload def __init__( self, *, - search_configurations: list[BingCustomSearchConfiguration] + security_scheme: OpenApiManagedSecurityScheme ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingGroundingSearchConfiguration(_Model): - count: Optional[int] - freshness: Optional[str] - market: Optional[str] - project_connection_id: str - set_lang: Optional[str] + class azure.ai.projects.models.OpenApiManagedSecurityScheme(_Model): + audience: str @overload def __init__( self, *, - count: Optional[int] = ..., - freshness: Optional[str] = ..., - market: Optional[str] = ..., - project_connection_id: str, - set_lang: Optional[str] = ... + audience: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingGroundingSearchToolParameters(_Model): - search_configurations: list[BingGroundingSearchConfiguration] + class azure.ai.projects.models.OpenApiProjectConnectionAuthDetails(OpenApiAuthDetails, discriminator='project_connection'): + security_scheme: OpenApiProjectConnectionSecurityScheme + type: Literal[OpenApiAuthType.PROJECT_CONNECTION] @overload def __init__( self, *, - search_configurations: list[BingGroundingSearchConfiguration] + security_scheme: OpenApiProjectConnectionSecurityScheme ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BingGroundingTool(Tool, discriminator='bing_grounding'): - bing_grounding: BingGroundingSearchToolParameters - description: Optional[str] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.BING_GROUNDING] + class azure.ai.projects.models.OpenApiProjectConnectionSecurityScheme(_Model): + project_connection_id: str @overload def __init__( self, *, - bing_grounding: BingGroundingSearchToolParameters, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + project_connection_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BlobReference(_Model): - blob_uri: str - credential: BlobReferenceSasCredential - storage_account_arm_id: str + class azure.ai.projects.models.OpenApiTool(Tool, discriminator='openapi'): + openapi: OpenApiFunctionDefinition + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal[ToolType.OPENAPI] @overload def __init__( self, *, - blob_uri: str, - credential: BlobReferenceSasCredential, - storage_account_arm_id: str + openapi: OpenApiFunctionDefinition, + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BlobReferenceSasCredential(_Model): - sas_uri: str - type: Literal["SAS"] + class azure.ai.projects.models.OpenApiToolboxTool(ToolboxTool, discriminator='openapi'): + description: str + name: str + openapi: OpenApiFunctionDefinition + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.OPENAPI] + @overload def __init__( self, - *args: Any, - **kwargs: Any + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + openapi: OpenApiFunctionDefinition, + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... - - class azure.ai.projects.models.BotServiceAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotService'): - type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE] - - @overload - def __init__(self) -> None: ... - @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BotServiceRbacAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotServiceRbac'): - type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE_RBAC] + class azure.ai.projects.models.OperationState(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CANCELED = "Canceled" + FAILED = "Failed" + NOT_STARTED = "NotStarted" + RUNNING = "Running" + SUCCEEDED = "Succeeded" + + + class azure.ai.projects.models.OptimizedAgentIdentifier(_Model): + agent_name: str + agent_version: Optional[str] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + agent_name: str, + agent_version: Optional[str] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BotServiceTenantAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='BotServiceTenant'): - type: Literal[AgentEndpointAuthorizationSchemeType.BOT_SERVICE_TENANT] + class azure.ai.projects.models.OtlpTelemetryEndpoint(TelemetryEndpoint, discriminator='OTLP'): + auth: TelemetryEndpointAuth + data: Union[list[str, TelemetryDataKind]] + endpoint: str + kind: Literal[TelemetryEndpointKind.OTLP] + protocol: Union[str, TelemetryTransportProtocol] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + auth: Optional[TelemetryEndpointAuth] = ..., + data: list[Union[str, TelemetryDataKind]], + endpoint: str, + protocol: Union[str, TelemetryTransportProtocol] + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BrowserAutomationPreviewTool(Tool, discriminator='browser_automation_preview'): - browser_automation_preview: BrowserAutomationToolParameters - type: Literal[ToolType.BROWSER_AUTOMATION_PREVIEW] + class azure.ai.projects.models.PSTNTelephonyTransferDestination(TelephonyTransferDestination, discriminator='pstn'): + kind: Literal[TelephonyTransferDestinationKind.PSTN] + value: str @overload def __init__( self, *, - browser_automation_preview: BrowserAutomationToolParameters + value: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BrowserAutomationPreviewToolboxTool(ToolboxTool, discriminator='browser_automation_preview'): - browser_automation_preview: BrowserAutomationToolParameters - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.BROWSER_AUTOMATION_PREVIEW] + class azure.ai.projects.models.PageOrder(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ASC = "asc" + DESC = "desc" + + + class azure.ai.projects.models.PendingUploadRequest(_Model): + connection_name: Optional[str] + pending_upload_id: Optional[str] + pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] @overload def __init__( self, *, - browser_automation_preview: BrowserAutomationToolParameters, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + connection_name: Optional[str] = ..., + pending_upload_id: Optional[str] = ..., + pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BrowserAutomationToolConnectionParameters(_Model): - project_connection_id: str + class azure.ai.projects.models.PendingUploadResponse(_Model): + blob_reference: BlobReference + pending_upload_id: str + pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] + version: Optional[str] @overload def __init__( self, *, - project_connection_id: str + blob_reference: BlobReference, + pending_upload_id: str, + pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE], + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.BrowserAutomationToolParameters(_Model): - connection: BrowserAutomationToolConnectionParameters + class azure.ai.projects.models.PendingUploadType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BLOB_REFERENCE = "BlobReference" + NONE = "None" + TEMPORARY_BLOB_REFERENCE = "TemporaryBlobReference" + + + class azure.ai.projects.models.PickPropertiesVoiceAgentAudioConfig(_Model): + output: Optional[VoiceAgentAudioOutputConfig] @overload def __init__( self, *, - connection: BrowserAutomationToolConnectionParameters + output: Optional[VoiceAgentAudioOutputConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CallableToolAllowedCaller(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DIRECT = "direct" - PROGRAMMATIC = "programmatic" - - - class azure.ai.projects.models.CaptureStructuredOutputsTool(Tool, discriminator='capture_structured_outputs'): - description: Optional[str] - name: Optional[str] - outputs: StructuredOutputDefinition - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.CAPTURE_STRUCTURED_OUTPUTS] + class azure.ai.projects.models.ProceduralMemoryItem(MemoryItem, discriminator='procedural'): + content: str + kind: Literal[MemoryItemKind.PROCEDURAL] + memory_id: str + scope: str + updated_at: datetime @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - outputs: StructuredOutputDefinition, - tool_configs: Optional[dict[str, ToolConfig]] = ... + content: str, + memory_id: str, + scope: str, + updated_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ChartCoordinate(_Model): - size: int - x: int - y: int + class azure.ai.projects.models.ProgrammaticToolCallingParam(Tool, discriminator='programmatic_tool_calling'): + type: Literal[ToolType.PROGRAMMATIC_TOOL_CALLING] @overload - def __init__( - self, - *, - size: int, - x: int, - y: int - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ChatSummaryMemoryItem(MemoryItem, discriminator='chat_summary'): - content: str - kind: Literal[MemoryItemKind.CHAT_SUMMARY] - memory_id: str - scope: str - updated_at: datetime + class azure.ai.projects.models.PromotionInfo(_Model): + agent_name: str + agent_version: str + promoted_at: datetime @overload def __init__( self, *, - content: str, - memory_id: str, - scope: str, - updated_at: datetime + agent_name: str, + agent_version: str, + promoted_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ClusterInsightResult(_Model): - clusters: list[InsightCluster] - coordinates: Optional[dict[str, ChartCoordinate]] - summary: InsightSummary + class azure.ai.projects.models.PromptAgentDefinition(AgentDefinition, discriminator='prompt'): + harness: Optional[AgentHarness] + instructions: Optional[str] + kind: Literal[AgentKind.PROMPT] + model: str + rai_config: RaiConfig + reasoning: Optional[Reasoning] + skills: Optional[list[SkillReference]] + structured_inputs: Optional[dict[str, StructuredInputDefinition]] + temperature: Optional[float] + text: Optional[PromptAgentDefinitionTextOptions] + tool_choice: Optional[Union[str, ToolChoiceParam]] + tools: Optional[list[Tool]] + top_p: Optional[float] @overload def __init__( self, *, - clusters: list[InsightCluster], - coordinates: Optional[dict[str, ChartCoordinate]] = ..., - summary: InsightSummary + harness: Optional[AgentHarness] = ..., + instructions: Optional[str] = ..., + model: str, + rai_config: Optional[RaiConfig] = ..., + reasoning: Optional[Reasoning] = ..., + skills: Optional[list[SkillReference]] = ..., + structured_inputs: Optional[dict[str, StructuredInputDefinition]] = ..., + temperature: Optional[float] = ..., + text: Optional[PromptAgentDefinitionTextOptions] = ..., + tool_choice: Optional[Union[str, ToolChoiceParam]] = ..., + tools: Optional[list[Tool]] = ..., + top_p: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ClusterTokenUsage(_Model): - input_token_usage: int - output_token_usage: int - total_token_usage: int + class azure.ai.projects.models.PromptAgentDefinitionTextOptions(_Model): + format: Optional[TextResponseFormat] @overload def __init__( self, *, - input_token_usage: int, - output_token_usage: int, - total_token_usage: int + format: Optional[TextResponseFormat] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CodeBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='code'): - blob_uri: Optional[str] - code_text: Optional[str] + class azure.ai.projects.models.PromptBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='prompt'): data_schema: dict[str, any] - entry_point: Optional[str] - image_tag: Optional[str] init_parameters: dict[str, any] metrics: dict[str, EvaluatorMetric] - type: Literal[EvaluatorDefinitionType.CODE] + prompt_text: str + type: Literal[EvaluatorDefinitionType.PROMPT] @overload def __init__( self, *, - blob_uri: Optional[str] = ..., - code_text: Optional[str] = ..., data_schema: Optional[dict[str, Any]] = ..., - entry_point: Optional[str] = ..., - image_tag: Optional[str] = ..., init_parameters: Optional[dict[str, Any]] = ..., - metrics: Optional[dict[str, EvaluatorMetric]] = ... + metrics: Optional[dict[str, EvaluatorMetric]] = ..., + prompt_text: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CodeConfiguration(_Model): - content_hash: Optional[str] - dependency_resolution: Union[str, CodeDependencyResolution] - entry_point: list[str] - runtime: str + class azure.ai.projects.models.PromptDataGenerationJobSource(DataGenerationJobSource, discriminator='prompt'): + description: str + prompt: str + type: Literal[DataGenerationJobSourceType.PROMPT] @overload def __init__( self, *, - dependency_resolution: Union[str, CodeDependencyResolution], - entry_point: list[str], - runtime: str + description: Optional[str] = ..., + prompt: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CodeDependencyResolution(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BUNDLED = "bundled" - REMOTE_BUILD = "remote_build" - - - class azure.ai.projects.models.CodeInterpreterTool(Tool, discriminator='code_interpreter'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - container: Optional[Union[str, AutoCodeInterpreterToolParam]] + class azure.ai.projects.models.PromptEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='prompt'): description: Optional[str] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.CODE_INTERPRETER] + prompt: str + type: Literal[EvaluatorGenerationJobSourceType.PROMPT] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - container: Optional[Union[str, AutoCodeInterpreterToolParam]] = ..., description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + prompt: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CodeInterpreterToolboxTool(ToolboxTool, discriminator='code_interpreter'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - container: Optional[Union[str, AutoCodeInterpreterToolParam]] - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.CODE_INTERPRETER] + class azure.ai.projects.models.ProtocolConfiguration(_Model): + a2a: Optional[A2AProtocolConfiguration] + activity: Optional[ActivityProtocolConfiguration] + invocations: Optional[InvocationsProtocolConfiguration] + invocations_ws: Optional[InvocationsWsProtocolConfiguration] + mcp: Optional[McpProtocolConfiguration] + responses: Optional[ResponsesProtocolConfiguration] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - container: Optional[Union[str, AutoCodeInterpreterToolParam]] = ..., - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + a2a: Optional[A2AProtocolConfiguration] = ..., + activity: Optional[ActivityProtocolConfiguration] = ..., + invocations: Optional[InvocationsProtocolConfiguration] = ..., + invocations_ws: Optional[InvocationsWsProtocolConfiguration] = ..., + mcp: Optional[McpProtocolConfiguration] = ..., + responses: Optional[ResponsesProtocolConfiguration] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ComparisonFilter(_Model): - key: str - type: Literal["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"] - value: Union[str, float, bool, list[Union[str, float]]] + class azure.ai.projects.models.ProtocolVersionRecord(_Model): + protocol: Union[str, AgentEndpointProtocol] + version: str @overload def __init__( self, *, - key: str, - type: Literal["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin"], - value: Union[str, float, bool, list[Union[str, float]]] + protocol: Union[str, AgentEndpointProtocol], + version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CompoundFilter(_Model): - filters: list[Union[ComparisonFilter, Any]] - type: Literal["and", "or"] + class azure.ai.projects.models.PublishApprovalStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + APPROVED = "approved" + NOT_PUBLISHED = "not_published" + NO_APPROVAL_NEEDED = "no_approval_needed" + PENDING = "pending" + REJECTED = "rejected" + + + class azure.ai.projects.models.RaiConfig(_Model): + invocations_moderation: Optional[RaiInvocationModeration] + rai_policy_name: str @overload def __init__( self, *, - filters: list[Union[ComparisonFilter, Any]], - type: Literal["and", "or"] + invocations_moderation: Optional[RaiInvocationModeration] = ..., + rai_policy_name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ComputerEnvironment(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BROWSER = "browser" - LINUX = "linux" - MAC = "mac" - UBUNTU = "ubuntu" - WINDOWS = "windows" + class azure.ai.projects.models.RaiInvocationContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + JSON = "json" + TEXT = "text" - class azure.ai.projects.models.ComputerTool(Tool, discriminator='computer'): - type: Literal[ToolType.COMPUTER] + class azure.ai.projects.models.RaiInvocationMode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BOTH = "both" + NON_STREAMING = "non_streaming" + STREAMING = "streaming" + + + class azure.ai.projects.models.RaiInvocationModeration(_Model): + input_content_type: Optional[Union[str, RaiInvocationContentType]] + input_paths: Optional[list[str]] + output_content_type: Optional[Union[str, RaiInvocationContentType]] + output_paths: Optional[list[str]] + response_mode: Union[str, RaiInvocationMode] + stream_selectors: Optional[list[RaiSseTextSelector]] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + input_content_type: Optional[Union[str, RaiInvocationContentType]] = ..., + input_paths: Optional[list[str]] = ..., + output_content_type: Optional[Union[str, RaiInvocationContentType]] = ..., + output_paths: Optional[list[str]] = ..., + response_mode: Union[str, RaiInvocationMode], + stream_selectors: Optional[list[RaiSseTextSelector]] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ComputerUsePreviewTool(Tool, discriminator='computer_use_preview'): - display_height: int - display_width: int - environment: Union[str, ComputerEnvironment] - type: Literal[ToolType.COMPUTER_USE_PREVIEW] + class azure.ai.projects.models.RaiSseTextSelector(_Model): + event_type: str + text_field: Optional[str] @overload def __init__( self, *, - display_height: int, - display_width: int, - environment: Union[str, ComputerEnvironment] + event_type: str, + text_field: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Connection(_Model): - credentials: BaseCredentials - id: str - is_default: bool - metadata: dict[str, str] - name: str - target: str - type: Union[str, ConnectionType] - - - class azure.ai.projects.models.ConnectionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - API_KEY = "ApiKey" - APPLICATION_CONFIGURATION = "AppConfig" - APPLICATION_INSIGHTS = "AppInsights" - AZURE_AI_SEARCH = "CognitiveSearch" - AZURE_BLOB_STORAGE = "AzureBlob" - AZURE_OPEN_AI = "AzureOpenAI" - AZURE_STORAGE_ACCOUNT = "AzureStorageAccount" - COSMOS_DB = "CosmosDB" - CUSTOM = "CustomKeys" - REMOTE_TOOL = "RemoteTool_Preview" + class azure.ai.projects.models.RankerVersionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + DEFAULT_2024_11_15 = "default-2024-11-15" - class azure.ai.projects.models.ContainerAutoParam(FunctionShellToolParamEnvironment, discriminator='container_auto'): - file_ids: Optional[list[str]] - memory_limit: Optional[Union[str, ContainerMemoryLimit]] - network_policy: Optional[ContainerNetworkPolicyParam] - skills: Optional[list[ContainerSkill]] - type: Literal[FunctionShellToolParamEnvironmentType.CONTAINER_AUTO] + class azure.ai.projects.models.RankingOptions(_Model): + hybrid_search: Optional[HybridSearchOptions] + ranker: Optional[Union[str, RankerVersionType]] + score_threshold: Optional[float] @overload def __init__( self, *, - file_ids: Optional[list[str]] = ..., - memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., - network_policy: Optional[ContainerNetworkPolicyParam] = ..., - skills: Optional[list[ContainerSkill]] = ... + hybrid_search: Optional[HybridSearchOptions] = ..., + ranker: Optional[Union[str, RankerVersionType]] = ..., + score_threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerConfiguration(_Model): - image: str - registry_connection_id: Optional[str] + class azure.ai.projects.models.RealtimeAudioFormats(_Model): + type: str @overload def __init__( self, *, - image: str, - registry_connection_id: Optional[str] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerMemoryLimit(str, Enum, metaclass=CaseInsensitiveEnumMeta): - MEMORY_16GB = "16g" - MEMORY_1GB = "1g" - MEMORY_4GB = "4g" - MEMORY_64GB = "64g" - - - class azure.ai.projects.models.ContainerNetworkPolicyAllowlistParam(ContainerNetworkPolicyParam, discriminator='allowlist'): - allowed_domains: list[str] - domain_secrets: Optional[list[ContainerNetworkPolicyDomainSecretParam]] - type: Literal[ContainerNetworkPolicyParamType.ALLOWLIST] + class azure.ai.projects.models.RealtimeAudioFormatsAudioPcm(RealtimeAudioFormats, discriminator='audio/pcm'): + rate: Optional[Literal[24000]] + type: Literal[RealtimeAudioFormatsType.AUDIO_PCM] @overload def __init__( self, *, - allowed_domains: list[str], - domain_secrets: Optional[list[ContainerNetworkPolicyDomainSecretParam]] = ... + rate: Optional[Literal[24000]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerNetworkPolicyDisabledParam(ContainerNetworkPolicyParam, discriminator='disabled'): - type: Literal[ContainerNetworkPolicyParamType.DISABLED] + class azure.ai.projects.models.RealtimeAudioFormatsAudioPcma(RealtimeAudioFormats, discriminator='audio/pcma'): + type: Literal[RealtimeAudioFormatsType.AUDIO_PCMA] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.RealtimeAudioFormatsAudioPcmu(RealtimeAudioFormats, discriminator='audio/pcmu'): + type: Literal[RealtimeAudioFormatsType.AUDIO_PCMU] @overload def __init__(self) -> None: ... @@ -4997,699 +9568,769 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerNetworkPolicyDomainSecretParam(_Model): - domain: str - name: str - value: str + class azure.ai.projects.models.RealtimeAudioFormatsType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUDIO_PCM = "audio/pcm" + AUDIO_PCMA = "audio/pcma" + AUDIO_PCMU = "audio/pcmu" + + + class azure.ai.projects.models.RealtimeClientEvent(_Model): + type: str @overload def __init__( self, *, - domain: str, - name: str, - value: str + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerNetworkPolicyParam(_Model): - type: str + class azure.ai.projects.models.RealtimeClientEventConversationItemCreate(RealtimeClientEvent, discriminator='conversation.item.create'): + event_id: Optional[str] + item: RealtimeConversationItem + previous_item_id: Optional[str] + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_CREATE] @overload def __init__( self, *, - type: str + event_id: Optional[str] = ..., + item: RealtimeConversationItem, + previous_item_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerNetworkPolicyParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ALLOWLIST = "allowlist" - DISABLED = "disabled" - - - class azure.ai.projects.models.ContainerSkill(_Model): - type: str + class azure.ai.projects.models.RealtimeClientEventConversationItemDelete(RealtimeClientEvent, discriminator='conversation.item.delete'): + event_id: Optional[str] + item_id: str + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_DELETE] @overload def __init__( self, *, - type: str + event_id: Optional[str] = ..., + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ContainerSkillType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INLINE = "inline" - SKILL_REFERENCE = "skill_reference" - - - class azure.ai.projects.models.ContinuousEvaluationRuleAction(EvaluationRuleAction, discriminator='continuousEvaluation'): - eval_id: str - max_hourly_runs: Optional[int] - sampling_rate: Optional[float] - type: Literal[EvaluationRuleActionType.CONTINUOUS_EVALUATION] + class azure.ai.projects.models.RealtimeClientEventConversationItemRetrieve(RealtimeClientEvent, discriminator='conversation.item.retrieve'): + event_id: Optional[str] + item_id: str + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_RETRIEVE] @overload def __init__( self, *, - eval_id: str, - max_hourly_runs: Optional[int] = ..., - sampling_rate: Optional[float] = ... + event_id: Optional[str] = ..., + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CosmosDBIndex(Index, discriminator='CosmosDBNoSqlVectorStore'): - connection_name: str - container_name: str - database_name: str - description: str - embedding_configuration: EmbeddingConfiguration - field_mapping: FieldMapping - id: str - name: str - tags: dict[str, str] - type: Literal[IndexType.COSMOS_DB] - version: str + class azure.ai.projects.models.RealtimeClientEventConversationItemTruncate(RealtimeClientEvent, discriminator='conversation.item.truncate'): + audio_end_ms: int + content_index: int + event_id: Optional[str] + item_id: str + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_TRUNCATE] @overload def __init__( self, *, - connection_name: str, - container_name: str, - database_name: str, - description: Optional[str] = ..., - embedding_configuration: EmbeddingConfiguration, - field_mapping: FieldMapping, - tags: Optional[dict[str, str]] = ... + audio_end_ms: int, + content_index: int, + event_id: Optional[str] = ..., + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CreateAsyncResponse(_Model): - location: Optional[str] - operation_result: Optional[str] + class azure.ai.projects.models.RealtimeClientEventInputAudioBufferAppend(RealtimeClientEvent, discriminator='input_audio_buffer.append'): + audio: str + event_id: Optional[str] + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_APPEND] @overload def __init__( self, *, - location: Optional[str] = ..., - operation_result: Optional[str] = ... + audio: str, + event_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CreateSkillVersionFromFilesBody(_Model): - default: Optional[bool] - files: list[Union[str, bytes, IO[str], IO[bytes], tuple[Optional[str], Union[str, bytes, IO[str], IO[bytes]]], tuple[Optional[str], Union[str, bytes, IO[str], IO[bytes]], Optional[str]]]] + class azure.ai.projects.models.RealtimeClientEventInputAudioBufferClear(RealtimeClientEvent, discriminator='input_audio_buffer.clear'): + event_id: Optional[str] + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_CLEAR] @overload def __init__( self, *, - default: Optional[bool] = ..., - files: list[FileType] + event_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CredentialType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENTIC_IDENTITY_PREVIEW = "AgenticIdentityToken_Preview" - API_KEY = "ApiKey" - CUSTOM = "CustomKeys" - ENTRA_ID = "AAD" - NONE = "None" - SAS = "SAS" - - - class azure.ai.projects.models.CronTrigger(Trigger, discriminator='Cron'): - end_time: Optional[datetime] - expression: str - start_time: Optional[datetime] - time_zone: Optional[str] - type: Literal[TriggerType.CRON] + class azure.ai.projects.models.RealtimeClientEventInputAudioBufferCommit(RealtimeClientEvent, discriminator='input_audio_buffer.commit'): + event_id: Optional[str] + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_COMMIT] @overload def __init__( self, *, - end_time: Optional[datetime] = ..., - expression: str, - start_time: Optional[datetime] = ..., - time_zone: Optional[str] = ... + event_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomCredential(CustomCredentialGenerated, discriminator='CustomKeys'): - credential_keys: Dict[str, str] - type: Union[str, CredentialType] + class azure.ai.projects.models.RealtimeClientEventOutputAudioBufferClear(RealtimeClientEvent, discriminator='output_audio_buffer.clear'): + event_id: Optional[str] + type: Literal[RealtimeClientEventType.OUTPUT_AUDIO_BUFFER_CLEAR] + @overload def __init__( self, - *args: Any, - **kwargs: Any + *, + event_id: Optional[str] = ... ) -> None: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomGrammarFormatParam(CustomToolParamFormat, discriminator='grammar'): - definition: str - syntax: Union[str, GrammarSyntax1] - type: Literal[CustomToolParamFormatType.GRAMMAR] + + class azure.ai.projects.models.RealtimeClientEventResponseCancel(RealtimeClientEvent, discriminator='response.cancel'): + event_id: Optional[str] + response_id: Optional[str] + type: Literal[RealtimeClientEventType.RESPONSE_CANCEL] @overload def __init__( self, *, - definition: str, - syntax: Union[str, GrammarSyntax1] + event_id: Optional[str] = ..., + response_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomRoutineTrigger(RoutineTrigger, discriminator='custom'): - event_name: Optional[str] - parameters: dict[str, Any] - provider: str - type: Literal[RoutineTriggerType.CUSTOM] + class azure.ai.projects.models.RealtimeClientEventResponseCreate(RealtimeClientEvent, discriminator='response.create'): + event_id: Optional[str] + response: Optional[VoiceAgentResponseCreateParams] + type: Literal[RealtimeClientEventType.RESPONSE_CREATE] @overload def __init__( self, *, - event_name: Optional[str] = ..., - parameters: dict[str, Any], - provider: str + event_id: Optional[str] = ..., + response: Optional[VoiceAgentResponseCreateParams] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomTextFormatParam(CustomToolParamFormat, discriminator='text'): - type: Literal[CustomToolParamFormatType.TEXT] + class azure.ai.projects.models.RealtimeClientEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONVERSATION_ITEM_CREATE = "conversation.item.create" + CONVERSATION_ITEM_DELETE = "conversation.item.delete" + CONVERSATION_ITEM_RETRIEVE = "conversation.item.retrieve" + CONVERSATION_ITEM_TRUNCATE = "conversation.item.truncate" + INPUT_AUDIO_BUFFER_APPEND = "input_audio_buffer.append" + INPUT_AUDIO_BUFFER_CLEAR = "input_audio_buffer.clear" + INPUT_AUDIO_BUFFER_COMMIT = "input_audio_buffer.commit" + OUTPUT_AUDIO_BUFFER_CLEAR = "output_audio_buffer.clear" + RESPONSE_CANCEL = "response.cancel" + RESPONSE_CREATE = "response.create" + RTC_CALL_SDP_CREATE = "rtc.call.sdp.create" + SESSION_AVATAR_CONNECT = "session.avatar.connect" + SESSION_UPDATE = "session.update" + + + class azure.ai.projects.models.RealtimeConversationItem(_Model): + type: str @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + type: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomToolParam(Tool, discriminator='custom'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - defer_loading: Optional[bool] - description: Optional[str] - format: Optional[CustomToolParamFormat] + class azure.ai.projects.models.RealtimeConversationItemFunctionCall(RealtimeConversationItem, discriminator='function_call'): + arguments: str + call_id: Optional[str] + created_at: Optional[datetime] + id: Optional[str] name: str - type: Literal[ToolType.CUSTOM] + object: Optional[Literal["item"]] + response_id: Optional[str] + status: Optional[Literal["completed", "incomplete", "in_progress"]] + type: Literal[RealtimeConversationItemType.FUNCTION_CALL] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - defer_loading: Optional[bool] = ..., - description: Optional[str] = ..., - format: Optional[CustomToolParamFormat] = ..., - name: str + arguments: str, + call_id: Optional[str] = ..., + id: Optional[str] = ..., + name: str, + object: Optional[Literal[item]] = ..., + status: Optional[Literal[completed, incomplete, in_progress]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomToolParamFormat(_Model): - type: str + class azure.ai.projects.models.RealtimeConversationItemFunctionCallOutput(RealtimeConversationItem, discriminator='function_call_output'): + call_id: str + created_at: Optional[datetime] + id: Optional[str] + name: Optional[str] + object: Optional[Literal["item"]] + output: str + response_id: Optional[str] + status: Optional[Literal["completed", "incomplete", "in_progress"]] + type: Literal[RealtimeConversationItemType.FUNCTION_CALL_OUTPUT] @overload def __init__( self, *, - type: str + call_id: str, + id: Optional[str] = ..., + name: Optional[str] = ..., + object: Optional[Literal[item]] = ..., + output: str, + status: Optional[Literal[completed, incomplete, in_progress]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.CustomToolParamFormatType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - GRAMMAR = "grammar" - TEXT = "text" - - - class azure.ai.projects.models.DailyRecurrenceSchedule(RecurrenceSchedule, discriminator='Daily'): - hours: list[int] - type: Literal[RecurrenceType.DAILY] + class azure.ai.projects.models.RealtimeConversationItemMessage(RealtimeConversationItem, discriminator='message'): + role: str + type: Literal[RealtimeConversationItemType.MESSAGE] @overload def __init__( self, *, - hours: list[int] + role: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJob(_Model): - created_at: datetime - error: Optional[ApiError] - finished_at: Optional[datetime] - id: str - inputs: Optional[DataGenerationJobInputs] - result: Optional[DataGenerationJobResult] - status: Union[str, JobStatus] + class azure.ai.projects.models.RealtimeConversationItemMessageAssistant(RealtimeConversationItemMessage, discriminator='assistant'): + content: list[RealtimeConversationItemMessageAssistantContent] + created_at: Optional[datetime] + id: Optional[str] + object: Optional[Literal["item"]] + response_id: Optional[str] + role: Literal[RealtimeConversationItemMessageType.ASSISTANT] + status: Optional[Literal["completed", "incomplete", "in_progress"]] + type: Union[str, azure.ai.projects.models.MESSAGE] @overload def __init__( self, *, - inputs: Optional[DataGenerationJobInputs] = ... + content: list[RealtimeConversationItemMessageAssistantContent], + id: Optional[str] = ..., + object: Optional[Literal[item]] = ..., + status: Optional[Literal[completed, incomplete, in_progress]] = ..., + type: Literal[RealtimeConversationItemType.MESSAGE] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobInputs(_Model): - name: str - options: DataGenerationJobOptions - output_options: Optional[DataGenerationJobOutputOptions] - scenario: Union[str, DataGenerationJobScenario] - sources: list[DataGenerationJobSource] + class azure.ai.projects.models.RealtimeConversationItemMessageAssistantContent(_Model): + audio: Optional[str] + text: Optional[str] + transcript: Optional[str] + type: Optional[Literal["output_text", "output_audio"]] @overload def __init__( self, *, - name: str, - options: DataGenerationJobOptions, - output_options: Optional[DataGenerationJobOutputOptions] = ..., - scenario: Union[str, DataGenerationJobScenario], - sources: list[DataGenerationJobSource] + audio: Optional[str] = ..., + text: Optional[str] = ..., + transcript: Optional[str] = ..., + type: Optional[Literal[output_text, output_audio]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobOptions(_Model): - max_samples: int - model_options: Optional[DataGenerationModelOptions] - train_split: Optional[float] - type: str + class azure.ai.projects.models.RealtimeConversationItemMessageSystem(RealtimeConversationItemMessage, discriminator='system'): + content: list[RealtimeConversationItemMessageSystemContent] + created_at: Optional[datetime] + id: Optional[str] + object: Optional[Literal["item"]] + response_id: Optional[str] + role: Literal[RealtimeConversationItemMessageType.SYSTEM] + status: Optional[Literal["completed", "incomplete", "in_progress"]] + type: Union[str, azure.ai.projects.models.MESSAGE] @overload def __init__( self, *, - max_samples: int, - model_options: Optional[DataGenerationModelOptions] = ..., - train_split: Optional[float] = ..., - type: str + content: list[RealtimeConversationItemMessageSystemContent], + id: Optional[str] = ..., + object: Optional[Literal[item]] = ..., + status: Optional[Literal[completed, incomplete, in_progress]] = ..., + type: Literal[RealtimeConversationItemType.MESSAGE] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobOutput(_Model): - type: str + class azure.ai.projects.models.RealtimeConversationItemMessageSystemContent(_Model): + text: Optional[str] + type: Optional[Literal["input_text"]] @overload def __init__( self, *, - type: str + text: Optional[str] = ..., + type: Optional[Literal[input_text]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobOutputOptions(_Model): - description: Optional[str] - name: Optional[str] - tags: Optional[dict[str, str]] + class azure.ai.projects.models.RealtimeConversationItemMessageType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ASSISTANT = "assistant" + SYSTEM = "system" + USER = "user" + + + class azure.ai.projects.models.RealtimeConversationItemMessageUser(RealtimeConversationItemMessage, discriminator='user'): + content: list[RealtimeConversationItemMessageUserContent] + created_at: Optional[datetime] + id: Optional[str] + object: Optional[Literal["item"]] + response_id: Optional[str] + role: Literal[RealtimeConversationItemMessageType.USER] + status: Optional[Literal["completed", "incomplete", "in_progress"]] + type: Union[str, azure.ai.projects.models.MESSAGE] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tags: Optional[dict[str, str]] = ... + content: list[RealtimeConversationItemMessageUserContent], + id: Optional[str] = ..., + object: Optional[Literal[item]] = ..., + status: Optional[Literal[completed, incomplete, in_progress]] = ..., + type: Literal[RealtimeConversationItemType.MESSAGE] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobOutputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DATASET = "dataset" - FILE = "file" - - - class azure.ai.projects.models.DataGenerationJobResult(_Model): - generated_samples: int - outputs: Optional[list[DataGenerationJobOutput]] - token_usage: Optional[DataGenerationTokenUsage] + class azure.ai.projects.models.RealtimeConversationItemMessageUserContent(_Model): + audio: Optional[str] + detail: Optional[Literal["auto", "low", "high"]] + image_url: Optional[str] + text: Optional[str] + transcript: Optional[str] + type: Optional[Literal["input_text", "input_audio", "input_image"]] @overload def __init__( self, *, - generated_samples: int, - outputs: Optional[list[DataGenerationJobOutput]] = ..., - token_usage: Optional[DataGenerationTokenUsage] = ... + audio: Optional[str] = ..., + detail: Optional[Literal[auto, low, high]] = ..., + image_url: Optional[str] = ..., + text: Optional[str] = ..., + transcript: Optional[str] = ..., + type: Optional[Literal[input_text, input_audio, input_image]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobScenario(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EVALUATION = "evaluation" - REINFORCEMENT_FINETUNING = "reinforcement_finetuning" - SUPERVISED_FINETUNING = "supervised_finetuning" + class azure.ai.projects.models.RealtimeConversationItemType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FUNCTION_CALL = "function_call" + FUNCTION_CALL_OUTPUT = "function_call_output" + MCP_APPROVAL_REQUEST = "mcp_approval_request" + MCP_APPROVAL_RESPONSE = "mcp_approval_response" + MCP_CALL = "mcp_call" + MCP_LIST_TOOLS = "mcp_list_tools" + MESSAGE = "message" - class azure.ai.projects.models.DataGenerationJobSource(_Model): + class azure.ai.projects.models.RealtimeFunctionTool(_Model): description: Optional[str] - type: str + name: Optional[str] + parameters: Optional[RealtimeFunctionToolParameters] + type: Optional[Literal["function"]] @overload def __init__( self, *, description: Optional[str] = ..., - type: str + name: Optional[str] = ..., + parameters: Optional[RealtimeFunctionToolParameters] = ..., + type: Optional[Literal[function]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationJobSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - FILE = "file" - PROMPT = "prompt" - TRACES = "traces" + class azure.ai.projects.models.RealtimeFunctionToolParameters(_Model): - class azure.ai.projects.models.DataGenerationJobType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - SIMPLE_QNA = "simple_qna" - SIMULATION_SEED = "simulation_seed" - TOOL_USE = "tool_use" - TRACES = "traces" + class azure.ai.projects.models.RealtimeMCPApprovalRequest(RealtimeConversationItem, discriminator='mcp_approval_request'): + arguments: str + created_at: Optional[datetime] + id: str + name: str + response_id: Optional[str] + server_label: str + type: Literal[RealtimeConversationItemType.MCP_APPROVAL_REQUEST] + + @overload + def __init__( + self, + *, + arguments: str, + id: str, + name: str, + server_label: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationModelOptions(_Model): - model: str + class azure.ai.projects.models.RealtimeMCPApprovalResponse(RealtimeConversationItem, discriminator='mcp_approval_response'): + approval_request_id: str + approve: bool + created_at: Optional[datetime] + id: str + reason: Optional[str] + response_id: Optional[str] + type: Literal[RealtimeConversationItemType.MCP_APPROVAL_RESPONSE] @overload def __init__( self, *, - model: str + approval_request_id: str, + approve: bool, + id: str, + reason: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DataGenerationTokenUsage(_Model): - completion_tokens: int - prompt_tokens: int - total_tokens: int + class azure.ai.projects.models.RealtimeMCPError(_Model): + type: str + + @overload + def __init__( + self, + *, + type: str + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetCredential(_Model): - blob_reference: BlobReference + class azure.ai.projects.models.RealtimeMCPHTTPError(RealtimeMCPError, discriminator='http_error'): + code: int + message: str + type: Literal[RealtimeMcpErrorType.HTTP_ERROR] @overload def __init__( self, *, - blob_reference: BlobReference + code: int, + message: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetDataGenerationJobOutput(DataGenerationJobOutput, discriminator='dataset'): - description: Optional[str] + class azure.ai.projects.models.RealtimeMCPListTools(RealtimeConversationItem, discriminator='mcp_list_tools'): + created_at: Optional[datetime] id: Optional[str] - name: Optional[str] - tags: Optional[dict[str, str]] - type: Literal[DataGenerationJobOutputType.DATASET] - version: Optional[str] + response_id: Optional[str] + server_label: str + tools: list[MCPListToolsTool] + type: Literal[RealtimeConversationItemType.MCP_LIST_TOOLS] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + id: Optional[str] = ..., + server_label: str, + tools: list[MCPListToolsTool] + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='dataset'): - description: Optional[str] - name: str - type: Literal[EvaluatorGenerationJobSourceType.DATASET] - version: Optional[str] + class azure.ai.projects.models.RealtimeMCPProtocolError(RealtimeMCPError, discriminator='protocol_error'): + code: int + message: str + type: Literal[RealtimeMcpErrorType.PROTOCOL_ERROR] @overload def __init__( self, *, - description: Optional[str] = ..., - name: str, - version: Optional[str] = ... + code: int, + message: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetGenerationLROPoller(LROPoller[DataGenerationJobResult]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.RealtimeMCPToolCall(RealtimeConversationItem, discriminator='mcp_call'): + approval_request_id: Optional[str] + arguments: str + created_at: Optional[datetime] + error: Optional[RealtimeMCPError] + id: str + name: str + output: Optional[str] + response_id: Optional[str] + server_label: str + type: Literal[RealtimeConversationItemType.MCP_CALL] + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + approval_request_id: Optional[str] = ..., + arguments: str, + error: Optional[RealtimeMCPError] = ..., + id: str, + name: str, + output: Optional[str] = ..., + server_label: str ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: PollingMethod[DataGenerationJobResult], - continuation_token: str, - **kwargs: Any - ) -> DatasetGenerationLROPoller: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetReference(_Model): - name: str - version: str + class azure.ai.projects.models.RealtimeMCPToolExecutionError(RealtimeMCPError, discriminator='tool_execution_error'): + message: str + type: Literal[RealtimeMcpErrorType.TOOL_EXECUTION_ERROR] @overload def __init__( self, *, - name: str, - version: str + message: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DatasetType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - URI_FILE = "uri_file" - URI_FOLDER = "uri_folder" + class azure.ai.projects.models.RealtimeMcpErrorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HTTP_ERROR = "http_error" + PROTOCOL_ERROR = "protocol_error" + TOOL_EXECUTION_ERROR = "tool_execution_error" - class azure.ai.projects.models.DatasetVersion(_Model): - connection_name: Optional[str] - data_uri: str - description: Optional[str] - id: Optional[str] - is_reference: Optional[bool] - name: str - tags: Optional[dict[str, str]] - type: str - version: str + class azure.ai.projects.models.RealtimeReasoning(_Model): + effort: Optional[Union[str, RealtimeReasoningEffort]] @overload def __init__( self, *, - connection_name: Optional[str] = ..., - data_uri: str, - description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ..., - type: str + effort: Optional[Union[str, RealtimeReasoningEffort]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DayOfWeek(str, Enum, metaclass=CaseInsensitiveEnumMeta): - FRIDAY = "Friday" - MONDAY = "Monday" - SATURDAY = "Saturday" - SUNDAY = "Sunday" - THURSDAY = "Thursday" - TUESDAY = "Tuesday" - WEDNESDAY = "Wednesday" + class azure.ai.projects.models.RealtimeReasoningEffort(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + MEDIUM = "medium" + MINIMAL = "minimal" + XHIGH = "xhigh" - class azure.ai.projects.models.DeleteAgentResponse(_Model): - deleted: bool - name: str - object: Literal[AgentObjectType.AGENT_DELETED] + class azure.ai.projects.models.RealtimeResponseStatusDetails(_Model): + error: Optional[RealtimeResponseStatusDetailsError] + reason: Optional[Literal["turn_detected", "client_cancelled", "max_output_tokens", "content_filter"]] + type: Optional[Literal["completed", "cancelled", "failed", "incomplete"]] @overload def __init__( self, *, - deleted: bool, - name: str, - object: Literal[AgentObjectType.AGENT_DELETED] + error: Optional[RealtimeResponseStatusDetailsError] = ..., + reason: Optional[Literal[turn_detected, client_cancelled, max_output_tokens, content_filter]] = ..., + type: Optional[Literal[completed, cancelled, failed, incomplete]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeleteAgentVersionResponse(_Model): - deleted: bool - name: str - object: Literal[AgentObjectType.AGENT_VERSION_DELETED] - version: str + class azure.ai.projects.models.RealtimeResponseStatusDetailsError(_Model): + code: Optional[str] + type: Optional[str] @overload def __init__( self, *, - deleted: bool, - name: str, - object: Literal[AgentObjectType.AGENT_VERSION_DELETED], - version: str + code: Optional[str] = ..., + type: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeleteMemoryResult(_Model): - deleted: bool - memory_id: str - object: Literal[MemoryStoreObjectType.MEMORY_DELETED] + class azure.ai.projects.models.RealtimeResponseUsage(_Model): + input_token_details: Optional[RealtimeResponseUsageInputTokenDetails] + input_tokens: Optional[int] + output_token_details: Optional[RealtimeResponseUsageOutputTokenDetails] + output_tokens: Optional[int] + total_tokens: Optional[int] @overload def __init__( self, *, - deleted: bool, - memory_id: str, - object: Literal[MemoryStoreObjectType.MEMORY_DELETED] + input_token_details: Optional[RealtimeResponseUsageInputTokenDetails] = ..., + input_tokens: Optional[int] = ..., + output_token_details: Optional[RealtimeResponseUsageOutputTokenDetails] = ..., + output_tokens: Optional[int] = ..., + total_tokens: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeleteMemoryStoreResult(_Model): - deleted: bool - name: str - object: Literal[MemoryStoreObjectType.MEMORY_STORE_DELETED] + class azure.ai.projects.models.RealtimeResponseUsageInputTokenDetails(_Model): + audio_tokens: Optional[int] + cached_tokens: Optional[int] + cached_tokens_details: Optional[RealtimeResponseUsageInputTokenDetailsCachedTokensDetails] + image_tokens: Optional[int] + text_tokens: Optional[int] @overload def __init__( self, *, - deleted: bool, - name: str, - object: Literal[MemoryStoreObjectType.MEMORY_STORE_DELETED] + audio_tokens: Optional[int] = ..., + cached_tokens: Optional[int] = ..., + cached_tokens_details: Optional[RealtimeResponseUsageInputTokenDetailsCachedTokensDetails] = ..., + image_tokens: Optional[int] = ..., + text_tokens: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeleteSkillResult(_Model): - deleted: bool - id: str - name: str + class azure.ai.projects.models.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails(_Model): + audio_tokens: Optional[int] + image_tokens: Optional[int] + text_tokens: Optional[int] @overload def __init__( self, *, - deleted: bool, - id: str, - name: str + audio_tokens: Optional[int] = ..., + image_tokens: Optional[int] = ..., + text_tokens: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeleteSkillVersionResult(_Model): - deleted: bool - id: str - name: str - version: str + class azure.ai.projects.models.RealtimeResponseUsageOutputTokenDetails(_Model): + audio_tokens: Optional[int] + text_tokens: Optional[int] @overload def __init__( self, *, - deleted: bool, - id: str, - name: str, - version: str + audio_tokens: Optional[int] = ..., + text_tokens: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Deployment(_Model): - name: str + class azure.ai.projects.models.RealtimeServerEvent(_Model): type: str @overload @@ -5703,2035 +10344,2297 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DeploymentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - MODEL_DEPLOYMENT = "ModelDeployment" - - - class azure.ai.projects.models.DigitalWorkerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - M365 = "m365" - - - class azure.ai.projects.models.Dimension(_Model): - always_applicable: Optional[bool] - description: str - id: str - weight: int + class azure.ai.projects.models.RealtimeServerEventConversationItemAdded(RealtimeServerEvent, discriminator='conversation.item.added'): + event_id: str + item: RealtimeConversationItem + previous_item_id: Optional[str] + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_ADDED] @overload def __init__( self, *, - always_applicable: Optional[bool] = ..., - description: str, - id: str, - weight: int + event_id: str, + item: RealtimeConversationItem, + previous_item_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.DispatchRoutineResult(_Model): - action_correlation_id: Optional[str] - dispatch_id: Optional[str] - task_id: Optional[str] + class azure.ai.projects.models.RealtimeServerEventConversationItemCreated(RealtimeServerEvent, discriminator='conversation.item.created'): + event_id: str + item: RealtimeConversationItem + previous_item_id: Optional[str] + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_CREATED] @overload def __init__( self, *, - action_correlation_id: Optional[str] = ..., - dispatch_id: Optional[str] = ..., - task_id: Optional[str] = ... + event_id: str, + item: RealtimeConversationItem, + previous_item_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EmbeddingConfiguration(_Model): - embedding_field: str - model_deployment_name: str + class azure.ai.projects.models.RealtimeServerEventConversationItemDeleted(RealtimeServerEvent, discriminator='conversation.item.deleted'): + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_DELETED] @overload def __init__( self, *, - embedding_field: str, - model_deployment_name: str + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EmptyModelParam(_Model): - - - class azure.ai.projects.models.EndpointBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='endpoint'): - connection_name: str - data_schema: dict[str, any] - init_parameters: dict[str, any] - metrics: dict[str, EvaluatorMetric] - type: Literal[EvaluatorDefinitionType.ENDPOINT] + class azure.ai.projects.models.RealtimeServerEventConversationItemDone(RealtimeServerEvent, discriminator='conversation.item.done'): + event_id: str + item: RealtimeConversationItem + previous_item_id: Optional[str] + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_DONE] @overload def __init__( self, *, - connection_name: str, - data_schema: Optional[dict[str, Any]] = ..., - init_parameters: Optional[dict[str, Any]] = ..., - metrics: Optional[dict[str, EvaluatorMetric]] = ... + event_id: str, + item: RealtimeConversationItem, + previous_item_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EntraAuthorizationScheme(AgentEndpointAuthorizationScheme, discriminator='Entra'): - type: Literal[AgentEndpointAuthorizationSchemeType.ENTRA] + class azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted(RealtimeServerEvent, discriminator='conversation.item.input_audio_transcription.completed'): + content_index: int + event_id: str + item_id: str + languages: Optional[list[TranscriptionLanguage]] + logprobs: Optional[list[LogProbProperties]] + phrases: Optional[list[VoiceAgentTranscriptionPhrase]] + transcript: str + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED] + usage: Union[TranscriptTextUsageTokens, TranscriptTextUsageDuration] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + content_index: int, + event_id: str, + item_id: str, + languages: Optional[list[TranscriptionLanguage]] = ..., + logprobs: Optional[list[LogProbProperties]] = ..., + phrases: Optional[list[VoiceAgentTranscriptionPhrase]] = ..., + transcript: str, + usage: Union[TranscriptTextUsageTokens, TranscriptTextUsageDuration] + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EntraIDCredentials(BaseCredentials, discriminator='AAD'): - type: Literal[CredentialType.ENTRA_ID] + class azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta(RealtimeServerEvent, discriminator='conversation.item.input_audio_transcription.delta'): + content_index: Optional[int] + delta: Optional[str] + event_id: str + item_id: str + logprobs: Optional[list[LogProbProperties]] + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + content_index: Optional[int] = ..., + delta: Optional[str] = ..., + event_id: str, + item_id: str, + logprobs: Optional[list[LogProbProperties]] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvalCsvFileIdSource(TypedDict, total=False): - key "id": Required[str] - key "type": Required[Literal["file_id"]] + class azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed(RealtimeServerEvent, discriminator='conversation.item.input_audio_transcription.failed'): + content_index: int + error: RealtimeServerEventConversationItemInputAudioTranscriptionFailedError + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED] + @overload + def __init__( + self, + *, + content_index: int, + error: RealtimeServerEventConversationItemInputAudioTranscriptionFailedError, + event_id: str, + item_id: str + ) -> None: ... - class azure.ai.projects.models.EvalCsvRunDataSource(TypedDict, total=False): - key "source": Required[EvalCsvFileIdSource] - key "type": Required[Literal["csv"]] + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvalResult(_Model): - name: str - passed: bool - score: float - type: str + class azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError(_Model): + code: Optional[str] + message: Optional[str] + param: Optional[str] + type: Optional[str] @overload def __init__( self, *, - name: str, - passed: bool, - score: float, - type: str + code: Optional[str] = ..., + message: Optional[str] = ..., + param: Optional[str] = ..., + type: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvalRunResultCompareItem(_Model): - delta_estimate: float - p_value: float - treatment_effect: Union[str, TreatmentEffectType] - treatment_run_id: str - treatment_run_summary: EvalRunResultSummary + class azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment(RealtimeServerEvent, discriminator='conversation.item.input_audio_transcription.segment'): + content_index: int + end: float + event_id: str + id: str + item_id: str + speaker: str + start: float + text: str + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT] @overload def __init__( self, *, - delta_estimate: float, - p_value: float, - treatment_effect: Union[str, TreatmentEffectType], - treatment_run_id: str, - treatment_run_summary: EvalRunResultSummary + content_index: int, + end: float, + event_id: str, + id: str, + item_id: str, + speaker: str, + start: float, + text: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvalRunResultComparison(_Model): - baseline_run_summary: EvalRunResultSummary - compare_items: list[EvalRunResultCompareItem] - evaluator: str - metric: str - testing_criteria: str + class azure.ai.projects.models.RealtimeServerEventConversationItemRetrieved(RealtimeServerEvent, discriminator='conversation.item.retrieved'): + event_id: str + item: RealtimeConversationItem + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_RETRIEVED] @overload def __init__( self, *, - baseline_run_summary: EvalRunResultSummary, - compare_items: list[EvalRunResultCompareItem], - evaluator: str, - metric: str, - testing_criteria: str + event_id: str, + item: RealtimeConversationItem ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvalRunResultSummary(_Model): - average: float - run_id: str - sample_count: int - standard_deviation: float + class azure.ai.projects.models.RealtimeServerEventConversationItemTruncated(RealtimeServerEvent, discriminator='conversation.item.truncated'): + audio_end_ms: int + content_index: int + event_id: str + item: Optional[RealtimeConversationItem] + item_id: str + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_TRUNCATED] @overload def __init__( self, *, - average: float, - run_id: str, - sample_count: int, - standard_deviation: float + audio_end_ms: int, + content_index: int, + event_id: str, + item: Optional[RealtimeConversationItem] = ..., + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationComparisonInsightRequest(InsightRequest, discriminator='EvaluationComparison'): - baseline_run_id: str - eval_id: str - treatment_run_ids: list[str] - type: Literal[InsightType.EVALUATION_COMPARISON] + class azure.ai.projects.models.RealtimeServerEventError(_Model): + error: RealtimeServerEventErrorError + event_id: str + type: Literal["error"] @overload def __init__( self, *, - baseline_run_id: str, - eval_id: str, - treatment_run_ids: list[str] + error: RealtimeServerEventErrorError, + event_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationComparisonInsightResult(InsightResult, discriminator='EvaluationComparison'): - comparisons: list[EvalRunResultComparison] - method: str - type: Literal[InsightType.EVALUATION_COMPARISON] + class azure.ai.projects.models.RealtimeServerEventErrorError(_Model): + code: Optional[str] + event_id: Optional[str] + message: str + param: Optional[str] + type: str @overload def __init__( self, *, - comparisons: list[EvalRunResultComparison], - method: str + code: Optional[str] = ..., + event_id: Optional[str] = ..., + message: str, + param: Optional[str] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationLevel(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CONVERSATION = "conversation" - TURN = "turn" - - - class azure.ai.projects.models.EvaluationResultSample(InsightSample, discriminator='EvaluationResultSample'): - correlation_info: dict[str, any] - evaluation_result: EvalResult - features: dict[str, any] - id: str - type: Literal[SampleType.EVALUATION_RESULT_SAMPLE] + class azure.ai.projects.models.RealtimeServerEventInputAudioBufferCleared(RealtimeServerEvent, discriminator='input_audio_buffer.cleared'): + event_id: str + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_CLEARED] @overload def __init__( self, *, - correlation_info: dict[str, Any], - evaluation_result: EvalResult, - features: dict[str, Any], - id: str + event_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRule(_Model): - action: EvaluationRuleAction - description: Optional[str] - display_name: Optional[str] - enabled: bool - event_type: Union[str, EvaluationRuleEventType] - filter: Optional[EvaluationRuleFilter] - id: str - system_data: dict[str, str] + class azure.ai.projects.models.RealtimeServerEventInputAudioBufferCommitted(RealtimeServerEvent, discriminator='input_audio_buffer.committed'): + event_id: str + item_id: str + previous_item_id: Optional[str] + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_COMMITTED] @overload def __init__( self, *, - action: EvaluationRuleAction, - description: Optional[str] = ..., - display_name: Optional[str] = ..., - enabled: bool, - event_type: Union[str, EvaluationRuleEventType], - filter: Optional[EvaluationRuleFilter] = ... + event_id: str, + item_id: str, + previous_item_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRuleAction(_Model): - type: str + class azure.ai.projects.models.RealtimeServerEventInputAudioBufferSpeechStarted(RealtimeServerEvent, discriminator='input_audio_buffer.speech_started'): + audio_start_ms: int + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STARTED] @overload def __init__( self, *, - type: str + audio_start_ms: int, + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRuleActionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CONTINUOUS_EVALUATION = "continuousEvaluation" - HUMAN_EVALUATION_PREVIEW = "humanEvaluationPreview" - - - class azure.ai.projects.models.EvaluationRuleEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - MANUAL = "manual" - RESPONSE_COMPLETED = "responseCompleted" - - - class azure.ai.projects.models.EvaluationRuleFilter(_Model): - agent_name: str + class azure.ai.projects.models.RealtimeServerEventInputAudioBufferSpeechStopped(RealtimeServerEvent, discriminator='input_audio_buffer.speech_stopped'): + audio_end_ms: int + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STOPPED] @overload def __init__( self, *, - agent_name: str + audio_end_ms: int, + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRunClusterInsightRequest(InsightRequest, discriminator='EvaluationRunClusterInsight'): - eval_id: str - model_configuration: Optional[InsightModelConfiguration] - run_ids: list[str] - type: Literal[InsightType.EVALUATION_RUN_CLUSTER_INSIGHT] + class azure.ai.projects.models.RealtimeServerEventInputAudioBufferTimeoutTriggered(RealtimeServerEvent, discriminator='input_audio_buffer.timeout_triggered'): + audio_end_ms: int + audio_start_ms: int + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED] @overload def __init__( self, *, - eval_id: str, - model_configuration: Optional[InsightModelConfiguration] = ..., - run_ids: list[str] + audio_end_ms: int, + audio_start_ms: int, + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationRunClusterInsightResult(InsightResult, discriminator='EvaluationRunClusterInsight'): - cluster_insight: ClusterInsightResult - type: Literal[InsightType.EVALUATION_RUN_CLUSTER_INSIGHT] + class azure.ai.projects.models.RealtimeServerEventMCPListToolsCompleted(RealtimeServerEvent, discriminator='mcp_list_tools.completed'): + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_COMPLETED] @overload def __init__( self, *, - cluster_insight: ClusterInsightResult + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationScheduleTask(ScheduleTask, discriminator='Evaluation'): - configuration: dict[str, str] - eval_id: str - eval_run: dict[str, Any] - type: Literal[ScheduleTaskType.EVALUATION] + class azure.ai.projects.models.RealtimeServerEventMCPListToolsFailed(RealtimeServerEvent, discriminator='mcp_list_tools.failed'): + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_FAILED] @overload def __init__( self, *, - configuration: Optional[dict[str, str]] = ..., - eval_id: str, - eval_run: dict[str, Any] + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationTarget(_Model): - type: str + class azure.ai.projects.models.RealtimeServerEventMCPListToolsInProgress(RealtimeServerEvent, discriminator='mcp_list_tools.in_progress'): + event_id: str + item_id: str + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_IN_PROGRESS] @overload def __init__( self, *, - type: str + event_id: str, + item_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationTaxonomy(_Model): - description: Optional[str] - id: Optional[str] - name: str - properties: Optional[dict[str, str]] - tags: Optional[dict[str, str]] - taxonomy_categories: Optional[list[TaxonomyCategory]] - taxonomy_input: EvaluationTaxonomyInput - version: str + class azure.ai.projects.models.RealtimeServerEventOutputAudioBufferCleared(RealtimeServerEvent, discriminator='output_audio_buffer.cleared'): + event_id: str + response_id: str + type: Literal[RealtimeServerEventType.OUTPUT_AUDIO_BUFFER_CLEARED] @overload def __init__( self, *, - description: Optional[str] = ..., - properties: Optional[dict[str, str]] = ..., - tags: Optional[dict[str, str]] = ..., - taxonomy_categories: Optional[list[TaxonomyCategory]] = ..., - taxonomy_input: EvaluationTaxonomyInput + event_id: str, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationTaxonomyInput(_Model): - type: str + class azure.ai.projects.models.RealtimeServerEventRateLimitsUpdated(RealtimeServerEvent, discriminator='rate_limits.updated'): + event_id: str + rate_limits: list[RealtimeServerEventRateLimitsUpdatedRateLimits] + type: Literal[RealtimeServerEventType.RATE_LIMITS_UPDATED] @overload def __init__( self, *, - type: str + event_id: str, + rate_limits: list[RealtimeServerEventRateLimitsUpdatedRateLimits] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluationTaxonomyInputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - POLICY = "policy" - - - class azure.ai.projects.models.EvaluatorCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENTS = "agents" - QUALITY = "quality" - SAFETY = "safety" - - - class azure.ai.projects.models.EvaluatorCredentialRequest(_Model): - blob_uri: str + class azure.ai.projects.models.RealtimeServerEventRateLimitsUpdatedRateLimits(_Model): + limit: Optional[int] + name: Optional[Literal["requests", "tokens"]] + remaining: Optional[int] + reset_seconds: Optional[float] @overload def __init__( self, *, - blob_uri: str + limit: Optional[int] = ..., + name: Optional[Literal[requests, tokens]] = ..., + remaining: Optional[int] = ..., + reset_seconds: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorDefinition(_Model): - data_schema: Optional[dict[str, Any]] - init_parameters: Optional[dict[str, Any]] - metrics: Optional[dict[str, EvaluatorMetric]] - type: str + class azure.ai.projects.models.RealtimeServerEventResponseAudioDelta(RealtimeServerEvent, discriminator='response.output_audio.delta'): + content_index: int + delta: bytes + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DELTA] @overload def __init__( self, *, - data_schema: Optional[dict[str, Any]] = ..., - init_parameters: Optional[dict[str, Any]] = ..., - metrics: Optional[dict[str, EvaluatorMetric]] = ..., - type: str + content_index: int, + delta: bytes, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorDefinitionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CODE = "code" - ENDPOINT = "endpoint" - OPENAI_GRADERS = "openai_graders" - PROMPT = "prompt" - PROMPT_AND_CODE = "prompt_and_code" - RUBRIC = "rubric" - SERVICE = "service" - - - class azure.ai.projects.models.EvaluatorGenerationArtifacts(_Model): - dataset: DatasetReference - kinds: list[str] + class azure.ai.projects.models.RealtimeServerEventResponseAudioDone(RealtimeServerEvent, discriminator='response.output_audio.done'): + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DONE] @overload def __init__( self, *, - dataset: DatasetReference, - kinds: list[str] + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorGenerationInputs(_Model): - evaluator_description: Optional[str] - evaluator_display_name: Optional[str] - evaluator_name: str - model: str - sources: list[EvaluatorGenerationJobSource] + class azure.ai.projects.models.RealtimeServerEventResponseAudioTranscriptDelta(RealtimeServerEvent, discriminator='response.output_audio_transcript.delta'): + content_index: int + delta: str + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA] @overload def __init__( self, *, - evaluator_description: Optional[str] = ..., - evaluator_display_name: Optional[str] = ..., - evaluator_name: str, - model: str, - sources: list[EvaluatorGenerationJobSource] + content_index: int, + delta: str, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorGenerationJob(_Model): - created_at: datetime - error: Optional[ApiError] - finished_at: Optional[datetime] - id: str - input_quality_warnings: Optional[list[RubricGenerationInputQualityWarning]] - inputs: Optional[EvaluatorGenerationInputs] - result: Optional[EvaluatorVersion] - status: Union[str, JobStatus] - usage: Optional[EvaluatorGenerationTokenUsage] + class azure.ai.projects.models.RealtimeServerEventResponseAudioTranscriptDone(RealtimeServerEvent, discriminator='response.output_audio_transcript.done'): + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + transcript: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE] @overload def __init__( self, *, - inputs: Optional[EvaluatorGenerationInputs] = ... + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str, + transcript: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorGenerationJobSource(_Model): - type: str + class azure.ai.projects.models.RealtimeServerEventResponseContentPartAdded(RealtimeServerEvent, discriminator='response.content_part.added'): + content_index: int + event_id: str + item_id: str + output_index: int + part: RealtimeServerEventResponseContentPartAddedPart + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_CONTENT_PART_ADDED] @overload def __init__( self, *, - type: str + content_index: int, + event_id: str, + item_id: str, + output_index: int, + part: RealtimeServerEventResponseContentPartAddedPart, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorGenerationJobSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - DATASET = "dataset" - PROMPT = "prompt" - TRACES = "traces" - - - class azure.ai.projects.models.EvaluatorGenerationLROPoller(LROPoller[EvaluatorVersion]): - property details: Mapping[str, Any] # Read-only + class azure.ai.projects.models.RealtimeServerEventResponseContentPartAddedPart(_Model): + audio: Optional[str] + text: Optional[str] + transcript: Optional[str] + type: Optional[Literal["audio", "text"]] + @overload def __init__( self, - client: Any, - initial_response: Any, - deserialization_callback: Any, - polling_method: Any + *, + audio: Optional[str] = ..., + text: Optional[str] = ..., + transcript: Optional[str] = ..., + type: Optional[Literal[audio, text]] = ... ) -> None: ... - @classmethod - def from_continuation_token( - cls, - polling_method: PollingMethod[EvaluatorVersion], - continuation_token: str, - **kwargs: Any - ) -> EvaluatorGenerationLROPoller: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorGenerationTokenUsage(_Model): - input_tokens: int - output_tokens: int - total_tokens: int + class azure.ai.projects.models.RealtimeServerEventResponseContentPartDone(RealtimeServerEvent, discriminator='response.content_part.done'): + content_index: int + event_id: str + item_id: str + output_index: int + part: RealtimeServerEventResponseContentPartDonePart + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_CONTENT_PART_DONE] @overload def __init__( self, *, - input_tokens: int, - output_tokens: int, - total_tokens: int + content_index: int, + event_id: str, + item_id: str, + output_index: int, + part: RealtimeServerEventResponseContentPartDonePart, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorMetric(_Model): - desirable_direction: Optional[Union[str, EvaluatorMetricDirection]] - is_primary: Optional[bool] - max_value: Optional[float] - min_value: Optional[float] - threshold: Optional[float] - type: Optional[Union[str, EvaluatorMetricType]] + class azure.ai.projects.models.RealtimeServerEventResponseContentPartDonePart(_Model): + audio: Optional[str] + format: Optional[RealtimeAudioFormats] + text: Optional[str] + transcript: Optional[str] + type: Optional[Literal["audio", "text"]] @overload def __init__( self, *, - desirable_direction: Optional[Union[str, EvaluatorMetricDirection]] = ..., - is_primary: Optional[bool] = ..., - max_value: Optional[float] = ..., - min_value: Optional[float] = ..., - threshold: Optional[float] = ..., - type: Optional[Union[str, EvaluatorMetricType]] = ... + audio: Optional[str] = ..., + format: Optional[RealtimeAudioFormats] = ..., + text: Optional[str] = ..., + transcript: Optional[str] = ..., + type: Optional[Literal[audio, text]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorMetricDirection(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DECREASE = "decrease" - INCREASE = "increase" - NEUTRAL = "neutral" + class azure.ai.projects.models.RealtimeServerEventResponseCreated(RealtimeServerEvent, discriminator='response.created'): + event_id: str + response: VoiceAgentRealtimeResponse + type: Literal[RealtimeServerEventType.RESPONSE_CREATED] + @overload + def __init__( + self, + *, + event_id: str, + response: VoiceAgentRealtimeResponse + ) -> None: ... - class azure.ai.projects.models.EvaluatorMetricType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BOOLEAN = "boolean" - CONTINUOUS = "continuous" - ORDINAL = "ordinal" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BUILT_IN = "builtin" - CUSTOM = "custom" + class azure.ai.projects.models.RealtimeServerEventResponseDone(RealtimeServerEvent, discriminator='response.done'): + event_id: str + response: VoiceAgentRealtimeResponse + type: Literal[RealtimeServerEventType.RESPONSE_DONE] + @overload + def __init__( + self, + *, + event_id: str, + response: VoiceAgentRealtimeResponse + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.EvaluatorVersion(_Model): - categories: list[Union[str, EvaluatorCategory]] - created_at: datetime - created_by: str - definition: EvaluatorDefinition - description: Optional[str] - display_name: Optional[str] - evaluator_type: Union[str, EvaluatorType] - generation_artifacts: Optional[EvaluatorGenerationArtifacts] - generation_job_id: Optional[str] - id: Optional[str] - metadata: Optional[dict[str, str]] - modified_at: datetime - name: str - supported_evaluation_levels: Optional[list[Union[str, EvaluationLevel]]] - tags: Optional[dict[str, str]] - version: str - warnings: Optional[list[Union[str, GenerationWarningType]]] + + class azure.ai.projects.models.RealtimeServerEventResponseFunctionCallArgumentsDelta(RealtimeServerEvent, discriminator='response.function_call_arguments.delta'): + call_id: str + delta: str + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA] @overload def __init__( self, *, - categories: list[Union[str, EvaluatorCategory]], - definition: EvaluatorDefinition, - description: Optional[str] = ..., - display_name: Optional[str] = ..., - evaluator_type: Union[str, EvaluatorType], - metadata: Optional[dict[str, str]] = ..., - supported_evaluation_levels: Optional[list[Union[str, EvaluationLevel]]] = ..., - tags: Optional[dict[str, str]] = ... + call_id: str, + delta: str, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ExternalAgentDefinition(AgentDefinition, discriminator='external'): - kind: Literal[AgentKind.EXTERNAL] - otel_agent_id: Optional[str] - rai_config: RaiConfig + class azure.ai.projects.models.RealtimeServerEventResponseFunctionCallArgumentsDone(RealtimeServerEvent, discriminator='response.function_call_arguments.done'): + arguments: str + call_id: str + event_id: str + item_id: str + name: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE] @overload def __init__( self, *, - otel_agent_id: Optional[str] = ..., - rai_config: Optional[RaiConfig] = ... + arguments: str, + call_id: str, + event_id: str, + item_id: str, + name: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FabricDataAgentToolParameters(_Model): - project_connections: Optional[list[ToolProjectConnection]] + class azure.ai.projects.models.RealtimeServerEventResponseMCPCallArgumentsDelta(RealtimeServerEvent, discriminator='response.mcp_call_arguments.delta'): + delta: str + event_id: str + item_id: str + obfuscation: Optional[str] + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DELTA] @overload def __init__( self, *, - project_connections: Optional[list[ToolProjectConnection]] = ... + delta: str, + event_id: str, + item_id: str, + obfuscation: Optional[str] = ..., + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FabricIQPreviewTool(Tool, discriminator='fabric_iq_preview'): - project_connection_id: str - require_approval: Optional[Union[MCPToolRequireApproval, str]] - server_label: Optional[str] - server_url: Optional[str] - type: Literal[ToolType.FABRIC_IQ_PREVIEW] + class azure.ai.projects.models.RealtimeServerEventResponseMCPCallArgumentsDone(RealtimeServerEvent, discriminator='response.mcp_call_arguments.done'): + arguments: str + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DONE] @overload def __init__( self, *, - project_connection_id: str, - require_approval: Optional[Union[MCPToolRequireApproval, str]] = ..., - server_label: Optional[str] = ..., - server_url: Optional[str] = ... + arguments: str, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FabricIQPreviewToolboxTool(ToolboxTool, discriminator='fabric_iq_preview'): - description: str - name: str - project_connection_id: str - require_approval: Optional[Union[MCPToolRequireApproval, str]] - server_label: Optional[str] - server_url: Optional[str] - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.FABRIC_IQ_PREVIEW] + class azure.ai.projects.models.RealtimeServerEventResponseMCPCallCompleted(RealtimeServerEvent, discriminator='response.mcp_call.completed'): + event_id: str + item_id: str + output_index: int + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_COMPLETED] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - project_connection_id: str, - require_approval: Optional[Union[MCPToolRequireApproval, str]] = ..., - server_label: Optional[str] = ..., - server_url: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + event_id: str, + item_id: str, + output_index: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FieldMapping(_Model): - content_fields: list[str] - filepath_field: Optional[str] - metadata_fields: Optional[list[str]] - title_field: Optional[str] - url_field: Optional[str] - vector_fields: Optional[list[str]] + class azure.ai.projects.models.RealtimeServerEventResponseMCPCallFailed(RealtimeServerEvent, discriminator='response.mcp_call.failed'): + event_id: str + item_id: str + output_index: int + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_FAILED] @overload def __init__( self, *, - content_fields: list[str], - filepath_field: Optional[str] = ..., - metadata_fields: Optional[list[str]] = ..., - title_field: Optional[str] = ..., - url_field: Optional[str] = ..., - vector_fields: Optional[list[str]] = ... + event_id: str, + item_id: str, + output_index: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FileDataGenerationJobOutput(DataGenerationJobOutput, discriminator='file'): - filename: str - id: str - type: Literal[DataGenerationJobOutputType.FILE] + class azure.ai.projects.models.RealtimeServerEventResponseMCPCallInProgress(RealtimeServerEvent, discriminator='response.mcp_call.in_progress'): + event_id: str + item_id: str + output_index: int + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_IN_PROGRESS] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + event_id: str, + item_id: str, + output_index: int + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FileDataGenerationJobSource(DataGenerationJobSource, discriminator='file'): - description: str - id: str - type: Literal[DataGenerationJobSourceType.FILE] + class azure.ai.projects.models.RealtimeServerEventResponseOutputItemAdded(RealtimeServerEvent, discriminator='response.output_item.added'): + event_id: str + item: RealtimeConversationItem + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_ADDED] @overload def __init__( self, *, - description: Optional[str] = ..., - id: str + event_id: str, + item: RealtimeConversationItem, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FileDatasetVersion(DatasetVersion, discriminator='uri_file'): - connection_name: str - data_uri: str - description: str - id: str - is_reference: bool - name: str - tags: dict[str, str] - type: Literal[DatasetType.URI_FILE] - version: str + class azure.ai.projects.models.RealtimeServerEventResponseOutputItemDone(RealtimeServerEvent, discriminator='response.output_item.done'): + event_id: str + item: RealtimeConversationItem + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_DONE] @overload def __init__( self, *, - connection_name: Optional[str] = ..., - data_uri: str, - description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ... + event_id: str, + item: RealtimeConversationItem, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FileSearchTool(Tool, discriminator='file_search'): - description: Optional[str] - filters: Optional[Filters] - max_num_results: Optional[int] - name: Optional[str] - ranking_options: Optional[RankingOptions] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.FILE_SEARCH] - vector_store_ids: list[str] + class azure.ai.projects.models.RealtimeServerEventResponseTextDelta(RealtimeServerEvent, discriminator='response.output_text.delta'): + content_index: int + delta: str + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DELTA] @overload def __init__( self, *, - description: Optional[str] = ..., - filters: Optional[Filters] = ..., - max_num_results: Optional[int] = ..., - name: Optional[str] = ..., - ranking_options: Optional[RankingOptions] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ..., - vector_store_ids: list[str] + content_index: int, + delta: str, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FileSearchToolboxTool(ToolboxTool, discriminator='file_search'): - description: str - filters: Optional[Filters] - max_num_results: Optional[int] - name: str - ranking_options: Optional[RankingOptions] - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.FILE_SEARCH] - vector_store_ids: Optional[list[str]] + class azure.ai.projects.models.RealtimeServerEventResponseTextDone(RealtimeServerEvent, discriminator='response.output_text.done'): + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + text: str + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DONE] @overload def __init__( self, *, - description: Optional[str] = ..., - filters: Optional[Filters] = ..., - max_num_results: Optional[int] = ..., - name: Optional[str] = ..., - ranking_options: Optional[RankingOptions] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ..., - vector_store_ids: Optional[list[str]] = ... + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str, + text: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FixedRatioVersionSelectionRule(VersionSelectionRule, discriminator='FixedRatio'): - agent_version: str - traffic_percentage: int - type: Literal[VersionSelectorType.FIXED_RATIO] + class azure.ai.projects.models.RealtimeServerEventSessionCreated(RealtimeServerEvent, discriminator='session.created'): + conversation_id: Optional[str] + event_id: str + session: VoiceAgentSessionResponse + type: Literal[RealtimeServerEventType.SESSION_CREATED] @overload def __init__( self, *, - agent_version: str, - traffic_percentage: int + conversation_id: Optional[str] = ..., + event_id: str, + session: VoiceAgentSessionResponse + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.RealtimeServerEventSessionUpdated(RealtimeServerEvent, discriminator='session.updated'): + event_id: str + session: VoiceAgentSessionResponse + type: Literal[RealtimeServerEventType.SESSION_UPDATED] + + @overload + def __init__( + self, + *, + event_id: str, + session: VoiceAgentSessionResponse + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.RealtimeServerEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONVERSATION_CREATED = "conversation.created" + CONVERSATION_ITEM_ADDED = "conversation.item.added" + CONVERSATION_ITEM_CREATED = "conversation.item.created" + CONVERSATION_ITEM_DELETED = "conversation.item.deleted" + CONVERSATION_ITEM_DONE = "conversation.item.done" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED = "conversation.item.input_audio_transcription.completed" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA = "conversation.item.input_audio_transcription.delta" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED = "conversation.item.input_audio_transcription.failed" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT = "conversation.item.input_audio_transcription.segment" + CONVERSATION_ITEM_RETRIEVED = "conversation.item.retrieved" + CONVERSATION_ITEM_TRUNCATED = "conversation.item.truncated" + ERROR = "error" + INPUT_AUDIO_BUFFER_CLEARED = "input_audio_buffer.cleared" + INPUT_AUDIO_BUFFER_COMMITTED = "input_audio_buffer.committed" + INPUT_AUDIO_BUFFER_DTMF_EVENT_RECEIVED = "input_audio_buffer.dtmf_event_received" + INPUT_AUDIO_BUFFER_SPEECH_STARTED = "input_audio_buffer.speech_started" + INPUT_AUDIO_BUFFER_SPEECH_STOPPED = "input_audio_buffer.speech_stopped" + INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED = "input_audio_buffer.timeout_triggered" + MCP_LIST_TOOLS_COMPLETED = "mcp_list_tools.completed" + MCP_LIST_TOOLS_FAILED = "mcp_list_tools.failed" + MCP_LIST_TOOLS_IN_PROGRESS = "mcp_list_tools.in_progress" + OUTPUT_AUDIO_BUFFER_CLEARED = "output_audio_buffer.cleared" + OUTPUT_AUDIO_BUFFER_STARTED = "output_audio_buffer.started" + OUTPUT_AUDIO_BUFFER_STOPPED = "output_audio_buffer.stopped" + RATE_LIMITS_UPDATED = "rate_limits.updated" + RESPONSE_ANIMATION_BLENDSHAPES_DELTA = "response.animation_blendshapes.delta" + RESPONSE_ANIMATION_BLENDSHAPES_DONE = "response.animation_blendshapes.done" + RESPONSE_ANIMATION_VISEME_DELTA = "response.animation_viseme.delta" + RESPONSE_ANIMATION_VISEME_DONE = "response.animation_viseme.done" + RESPONSE_AUDIO_TIMESTAMP_DELTA = "response.audio_timestamp.delta" + RESPONSE_AUDIO_TIMESTAMP_DONE = "response.audio_timestamp.done" + RESPONSE_CONTENT_PART_ADDED = "response.content_part.added" + RESPONSE_CONTENT_PART_DONE = "response.content_part.done" + RESPONSE_CREATED = "response.created" + RESPONSE_DONE = "response.done" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA = "response.function_call_arguments.delta" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE = "response.function_call_arguments.done" + RESPONSE_MCP_CALL_ARGUMENTS_DELTA = "response.mcp_call_arguments.delta" + RESPONSE_MCP_CALL_ARGUMENTS_DONE = "response.mcp_call_arguments.done" + RESPONSE_MCP_CALL_COMPLETED = "response.mcp_call.completed" + RESPONSE_MCP_CALL_FAILED = "response.mcp_call.failed" + RESPONSE_MCP_CALL_IN_PROGRESS = "response.mcp_call.in_progress" + RESPONSE_OUTPUT_AUDIO_DELTA = "response.output_audio.delta" + RESPONSE_OUTPUT_AUDIO_DONE = "response.output_audio.done" + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA = "response.output_audio_transcript.delta" + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE = "response.output_audio_transcript.done" + RESPONSE_OUTPUT_ITEM_ADDED = "response.output_item.added" + RESPONSE_OUTPUT_ITEM_DONE = "response.output_item.done" + RESPONSE_OUTPUT_TEXT_DELTA = "response.output_text.delta" + RESPONSE_OUTPUT_TEXT_DONE = "response.output_text.done" + RESPONSE_VIDEO_DELTA = "response.video.delta" + RTC_CALL_ERROR = "rtc.call.error" + RTC_CALL_SDP_CREATED = "rtc.call.sdp.created" + SESSION_AVATAR_CONNECTING = "session.avatar.connecting" + SESSION_AVATAR_SWITCH_TO_IDLE = "session.avatar.switch_to_idle" + SESSION_AVATAR_SWITCH_TO_SPEAKING = "session.avatar.switch_to_speaking" + SESSION_CREATED = "session.created" + SESSION_SUBAGENT_ABORTED = "session.subagent.aborted" + SESSION_SUBAGENT_COMPLETED = "session.subagent.completed" + SESSION_SUBAGENT_STARTED = "session.subagent.started" + SESSION_UPDATED = "session.updated" + WARNING = "warning" + + + class azure.ai.projects.models.Reasoning(_Model): + context: Optional[Literal["auto", "current_turn", "all_turns"]] + effort: Optional[Union[str, ReasoningEffort]] + generate_summary: Optional[Literal["auto", "concise", "detailed"]] + mode: Optional[Union[str, ReasoningModeEnum]] + summary: Optional[Literal["auto", "concise", "detailed"]] + + @overload + def __init__( + self, + *, + context: Optional[Literal[auto, current_turn, all_turns]] = ..., + effort: Optional[Union[str, ReasoningEffort]] = ..., + generate_summary: Optional[Literal[auto, concise, detailed]] = ..., + mode: Optional[Union[str, ReasoningModeEnum]] = ..., + summary: Optional[Literal[auto, concise, detailed]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FolderDatasetVersion(DatasetVersion, discriminator='uri_folder'): - connection_name: str - data_uri: str - description: str - id: str - is_reference: bool - name: str - tags: dict[str, str] - type: Literal[DatasetType.URI_FOLDER] - version: str + class azure.ai.projects.models.ReasoningEffort(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + MAX = "max" + MEDIUM = "medium" + MINIMAL = "minimal" + NONE = "none" + XHIGH = "xhigh" + + + class azure.ai.projects.models.ReasoningModeEnum(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PRO = "pro" + STANDARD = "standard" + + + class azure.ai.projects.models.RecurrenceSchedule(_Model): + type: str @overload def __init__( self, *, - connection_name: Optional[str] = ..., - data_uri: str, - description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FoundryModelArtifactProfileCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DATA_ONLY = "DataOnly" - RUNTIME_DEPENDENT = "RuntimeDependent" - UNKNOWN = "Unknown" + class azure.ai.projects.models.RecurrenceTrigger(Trigger, discriminator='Recurrence'): + end_time: Optional[datetime] + interval: int + schedule: RecurrenceSchedule + start_time: Optional[datetime] + time_zone: Optional[str] + type: Literal[TriggerType.RECURRENCE] + @overload + def __init__( + self, + *, + end_time: Optional[datetime] = ..., + interval: int, + schedule: RecurrenceSchedule, + start_time: Optional[datetime] = ..., + time_zone: Optional[str] = ... + ) -> None: ... - class azure.ai.projects.models.FoundryModelArtifactProfileSignal(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CUSTOM_PYTHON_CODE = "CustomPythonCode" - DYNAMIC_OPS = "DynamicOps" - NATIVE_BINARY = "NativeBinary" - PICKLE_DESERIALIZATION = "PickleDeserialization" - UNKNOWN_FORMAT = "UnknownFormat" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FoundryModelSourceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - LOCAL_UPLOAD = "LocalUpload" - TRAINING_JOB = "TrainingJob" + class azure.ai.projects.models.RecurrenceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DAILY = "Daily" + HOURLY = "Hourly" + MONTHLY = "Monthly" + WEEKLY = "Weekly" - class azure.ai.projects.models.FoundryModelWarning(_Model): - code: Optional[Union[str, FoundryModelWarningCode]] - message: Optional[str] + class azure.ai.projects.models.RedTeam(_Model): + application_scenario: Optional[str] + attack_strategies: Optional[list[Union[str, AttackStrategy]]] + display_name: Optional[str] + name: str + num_turns: Optional[int] + properties: Optional[dict[str, str]] + risk_categories: Optional[list[Union[str, RiskCategory]]] + simulation_only: Optional[bool] + status: Optional[str] + tags: Optional[dict[str, str]] + target: RedTeamTargetConfig @overload def __init__( self, *, - code: Optional[Union[str, FoundryModelWarningCode]] = ..., - message: Optional[str] = ... + application_scenario: Optional[str] = ..., + attack_strategies: Optional[list[Union[str, AttackStrategy]]] = ..., + display_name: Optional[str] = ..., + num_turns: Optional[int] = ..., + properties: Optional[dict[str, str]] = ..., + risk_categories: Optional[list[Union[str, RiskCategory]]] = ..., + simulation_only: Optional[bool] = ..., + tags: Optional[dict[str, str]] = ..., + target: RedTeamTargetConfig ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FoundryModelWarningCode(str, Enum, metaclass=CaseInsensitiveEnumMeta): - RUNTIME_DEPENDENT_ARTIFACT = "RuntimeDependentArtifact" - UNCLASSIFIED_ARTIFACT = "UnclassifiedArtifact" - - - class azure.ai.projects.models.FoundryModelWeightType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DRAFT_MODEL = "DraftModel" - FULL_WEIGHT = "FullWeight" - LO_RA = "LoRA" + class azure.ai.projects.models.RedTeamEvalRunDataSource(TypedDict, total=False): + key "item_generation_params": Required[Any] + key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] + key "type": Required[Literal["azure_ai_red_team"]] - class azure.ai.projects.models.FunctionShellToolParam(Tool, discriminator='shell'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - description: Optional[str] - environment: Optional[FunctionShellToolParamEnvironment] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.SHELL] + class azure.ai.projects.models.RedTeamTargetConfig(_Model): + type: str @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - description: Optional[str] = ..., - environment: Optional[FunctionShellToolParamEnvironment] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FunctionShellToolParamEnvironment(_Model): - type: str + class azure.ai.projects.models.ReminderPreviewToolboxTool(ToolboxTool, discriminator='reminder_preview'): + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.REMINDER_PREVIEW] @overload def __init__( self, *, - type: str + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FunctionShellToolParamEnvironmentContainerReferenceParam(FunctionShellToolParamEnvironment, discriminator='container_reference'): - container_id: str - type: Literal[FunctionShellToolParamEnvironmentType.CONTAINER_REFERENCE] + class azure.ai.projects.models.ResponseRetrievalItemGenerationParams(TypedDict, total=False): + key "data_mapping": Required[Dict[str, str]] + key "max_num_turns": int + key "source": Required[Union[SourceFileContent, SourceFileID]] + key "type": Required[Literal["response_retrieval"]] + + + class azure.ai.projects.models.ResponseUsageInputTokensDetails(_Model): + cache_write_tokens: int + cached_tokens: int @overload def __init__( self, *, - container_id: str + cache_write_tokens: int, + cached_tokens: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FunctionShellToolParamEnvironmentLocalEnvironmentParam(FunctionShellToolParamEnvironment, discriminator='local'): - skills: Optional[list[LocalSkillParam]] - type: Literal[FunctionShellToolParamEnvironmentType.LOCAL] + class azure.ai.projects.models.ResponseUsageOutputTokensDetails(_Model): + reasoning_tokens: int @overload def __init__( self, *, - skills: Optional[list[LocalSkillParam]] = ... + reasoning_tokens: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FunctionShellToolParamEnvironmentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CONTAINER_AUTO = "container_auto" - CONTAINER_REFERENCE = "container_reference" - LOCAL = "local" + class azure.ai.projects.models.ResponsesProtocolConfiguration(_Model): - class azure.ai.projects.models.FunctionTool(Tool, discriminator='function'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - defer_loading: Optional[bool] + class azure.ai.projects.models.RiskCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CODE_VULNERABILITY = "CodeVulnerability" + HATE_UNFAIRNESS = "HateUnfairness" + PROHIBITED_ACTIONS = "ProhibitedActions" + PROTECTED_MATERIAL = "ProtectedMaterial" + SELF_HARM = "SelfHarm" + SENSITIVE_DATA_LEAKAGE = "SensitiveDataLeakage" + SEXUAL = "Sexual" + TASK_ADHERENCE = "TaskAdherence" + UNGROUNDED_ATTRIBUTES = "UngroundedAttributes" + VIOLENCE = "Violence" + + + class azure.ai.projects.models.Routine(_Model): + action: Optional[RoutineAction] + created_at: Optional[datetime] description: Optional[str] - name: str - output_schema: Optional[dict[str, Any]] - parameters: dict[str, Any] - strict: bool - type: Literal[ToolType.FUNCTION] + enabled: bool + name: Optional[str] + triggers: Optional[dict[str, RoutineTrigger]] + updated_at: Optional[datetime] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - defer_loading: Optional[bool] = ..., + action: Optional[RoutineAction] = ..., + created_at: Optional[datetime] = ..., description: Optional[str] = ..., - name: str, - output_schema: Optional[dict[str, Any]] = ..., - parameters: dict[str, Any], - strict: bool + enabled: bool, + name: Optional[str] = ..., + triggers: Optional[dict[str, RoutineTrigger]] = ..., + updated_at: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.FunctionToolParam(_Model): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - defer_loading: Optional[bool] - description: Optional[str] - name: str - output_schema: Optional[dict[str, Any]] - parameters: Optional[EmptyModelParam] - strict: Optional[bool] - type: Literal["function"] + class azure.ai.projects.models.RoutineAction(_Model): + type: str @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - defer_loading: Optional[bool] = ..., - description: Optional[str] = ..., - name: str, - output_schema: Optional[dict[str, Any]] = ..., - parameters: Optional[EmptyModelParam] = ..., - strict: Optional[bool] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.GenerationWarningType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INPUT_QUALITY = "input_quality" + class azure.ai.projects.models.RoutineActionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INVOKE_AGENT_INVOCATIONS_API = "invoke_agent_invocations_api" + INVOKE_AGENT_RESPONSES_API = "invoke_agent_responses_api" - class azure.ai.projects.models.GitHubIssueEvent(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CLOSED = "closed" - OPENED = "opened" + class azure.ai.projects.models.RoutineAttemptSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EVENT_FIRE = "event_fire" + MANUAL_DISPATCH = "manual_dispatch" + QUEUED_DISPATCH = "queued_dispatch" + SCHEDULE_DELIVERY = "schedule_delivery" + TIMER_DELIVERY = "timer_delivery" - class azure.ai.projects.models.GitHubIssueRoutineTrigger(RoutineTrigger, discriminator='github_issue'): - connection_id: str - issue_event: Union[str, GitHubIssueEvent] - owner: str - repository: str - type: Literal[RoutineTriggerType.GITHUB_ISSUE] + class azure.ai.projects.models.RoutineAuthorization(_Model): + identity: Optional[Union[str, RoutineDispatchIdentity]] @overload def __init__( self, *, - connection_id: str, - issue_event: Union[str, GitHubIssueEvent], - owner: str, - repository: str + identity: Optional[Union[str, RoutineDispatchIdentity]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.GrammarSyntax1(str, Enum, metaclass=CaseInsensitiveEnumMeta): - LARK = "lark" - REGEX = "regex" + class azure.ai.projects.models.RoutineDispatchIdentity(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + CREATOR = "creator" - class azure.ai.projects.models.HeaderTelemetryEndpointAuth(TelemetryEndpointAuth, discriminator='header'): - header_name: str - secret_id: str - secret_key: str - type: Literal[TelemetryEndpointAuthType.HEADER] + class azure.ai.projects.models.RoutineDispatchPayload(_Model): + type: str @overload def __init__( self, *, - header_name: str, - secret_id: str, - secret_key: str + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.HostedAgentDefinition(AgentDefinition, discriminator='hosted'): - code_configuration: Optional[CodeConfiguration] - container_configuration: Optional[ContainerConfiguration] - cpu: str - environment_variables: Optional[dict[str, str]] - kind: Literal[AgentKind.HOSTED] - memory: str - protocol_versions: Optional[list[ProtocolVersionRecord]] - rai_config: RaiConfig - session_configuration: Optional[SessionConfiguration] - telemetry_config: Optional[TelemetryConfig] + class azure.ai.projects.models.RoutineDispatchPayloadType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INVOKE_AGENT_INVOCATIONS_API = "invoke_agent_invocations_api" + INVOKE_AGENT_RESPONSES_API = "invoke_agent_responses_api" + + + class azure.ai.projects.models.RoutineRun(_Model): + action_correlation_id: Optional[str] + action_type: Optional[Union[str, RoutineActionType]] + agent_endpoint_id: Optional[str] + agent_id: Optional[str] + attempt_source: Optional[Union[str, RoutineAttemptSource]] + conversation_id: Optional[str] + dispatch_id: Optional[str] + ended_at: Optional[datetime] + error_message: Optional[str] + error_status_code: Optional[int] + error_type: Optional[str] + id: str + phase: Optional[Union[str, RoutineRunPhase]] + response_id: Optional[str] + scheduled_fire_at: Optional[datetime] + session_id: Optional[str] + started_at: Optional[datetime] + status: Optional[RoutineRunStatus] + task_id: Optional[str] + trigger_event_payload: Optional[dict[str, Any]] + trigger_name: Optional[str] + trigger_type: Optional[Union[str, RoutineTriggerType]] + triggered_at: Optional[datetime] @overload def __init__( self, *, - code_configuration: Optional[CodeConfiguration] = ..., - container_configuration: Optional[ContainerConfiguration] = ..., - cpu: str, - environment_variables: Optional[dict[str, str]] = ..., - memory: str, - protocol_versions: Optional[list[ProtocolVersionRecord]] = ..., - rai_config: Optional[RaiConfig] = ..., - session_configuration: Optional[SessionConfiguration] = ..., - telemetry_config: Optional[TelemetryConfig] = ... + action_correlation_id: Optional[str] = ..., + action_type: Optional[Union[str, RoutineActionType]] = ..., + agent_endpoint_id: Optional[str] = ..., + agent_id: Optional[str] = ..., + attempt_source: Optional[Union[str, RoutineAttemptSource]] = ..., + conversation_id: Optional[str] = ..., + dispatch_id: Optional[str] = ..., + ended_at: Optional[datetime] = ..., + error_message: Optional[str] = ..., + error_status_code: Optional[int] = ..., + error_type: Optional[str] = ..., + phase: Optional[Union[str, RoutineRunPhase]] = ..., + response_id: Optional[str] = ..., + scheduled_fire_at: Optional[datetime] = ..., + session_id: Optional[str] = ..., + started_at: Optional[datetime] = ..., + status: Optional[RoutineRunStatus] = ..., + task_id: Optional[str] = ..., + trigger_event_payload: Optional[dict[str, Any]] = ..., + trigger_name: Optional[str] = ..., + trigger_type: Optional[Union[str, RoutineTriggerType]] = ..., + triggered_at: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.HourlyRecurrenceSchedule(RecurrenceSchedule, discriminator='Hourly'): - type: Literal[RecurrenceType.HOURLY] - - @overload - def __init__(self) -> None: ... - - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... + class azure.ai.projects.models.RoutineRunPhase(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + DISPATCHING = "dispatching" + FAILED = "failed" + QUEUED = "queued" - class azure.ai.projects.models.HumanEvaluationPreviewRuleAction(EvaluationRuleAction, discriminator='humanEvaluationPreview'): - template_id: str - type: Literal[EvaluationRuleActionType.HUMAN_EVALUATION_PREVIEW] + class azure.ai.projects.models.RoutineTrigger(_Model): + type: str @overload def __init__( self, *, - template_id: str + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.HybridSearchOptions(_Model): - embedding_weight: float - text_weight: float + class azure.ai.projects.models.RoutineTriggerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CUSTOM = "custom" + GITHUB_ISSUE = "github_issue" + SCHEDULE = "schedule" + TIMER = "timer" + + + class azure.ai.projects.models.RubricBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='rubric'): + data_schema: dict[str, any] + dimensions: list[Dimension] + init_parameters: dict[str, any] + metrics: dict[str, EvaluatorMetric] + pass_threshold: Optional[float] + type: Literal[EvaluatorDefinitionType.RUBRIC] @overload def __init__( self, *, - embedding_weight: float, - text_weight: float + data_schema: Optional[dict[str, Any]] = ..., + dimensions: list[Dimension], + init_parameters: Optional[dict[str, Any]] = ..., + metrics: Optional[dict[str, EvaluatorMetric]] = ..., + pass_threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ImageGenAction(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AUTO = "auto" - EDIT = "edit" - GENERATE = "generate" - - - class azure.ai.projects.models.ImageGenTool(Tool, discriminator='image_generation'): - action: Optional[Union[str, ImageGenAction]] - background: Optional[Literal["transparent", "opaque", "auto"]] - description: Optional[str] - input_fidelity: Optional[Union[str, InputFidelity]] - input_image_mask: Optional[ImageGenToolInputImageMask] - model: Optional[Union[Literal["gpt-image-1"], Literal["gpt-image-1-mini"], Literal["gpt-image-5"], str]] - moderation: Optional[Literal["auto", "low"]] - name: Optional[str] - output_compression: Optional[int] - output_format: Optional[Literal["png", "webp", "jpeg"]] - partial_images: Optional[int] - quality: Optional[Literal["low", "medium", "high", "auto"]] - size: Optional[Union[Literal["1024x1024"], Literal["1024x1536"], Literal["1536x1024"], Literal["auto"], str]] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.IMAGE_GENERATION] + class azure.ai.projects.models.RubricGenerationInputQualityWarning(_Model): + code: Union[str, RubricGenerationInputQualityWarningCode] + message: str + severity: Union[str, RubricGenerationInputQualityWarningSeverity] + source: Union[str, RubricGenerationInputQualityWarningSource] + source_index: Optional[int] @overload def __init__( self, *, - action: Optional[Union[str, ImageGenAction]] = ..., - background: Optional[Literal[transparent, opaque, auto]] = ..., - description: Optional[str] = ..., - input_fidelity: Optional[Union[str, InputFidelity]] = ..., - input_image_mask: Optional[ImageGenToolInputImageMask] = ..., - model: Optional[Union[Literal[gpt-image-1], Literal[gpt-image-1-mini], Literal[gpt-image-5], str]] = ..., - moderation: Optional[Literal[auto, low]] = ..., - name: Optional[str] = ..., - output_compression: Optional[int] = ..., - output_format: Optional[Literal[png, webp, jpeg]] = ..., - partial_images: Optional[int] = ..., - quality: Optional[Literal[low, medium, high, auto]] = ..., - size: Optional[Union[Literal[1024x1024], Literal[1024x1536], Literal[1536x1024], Literal[auto], str]] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + code: Union[str, RubricGenerationInputQualityWarningCode], + message: str, + severity: Union[str, RubricGenerationInputQualityWarningSeverity], + source: Union[str, RubricGenerationInputQualityWarningSource], + source_index: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ImageGenToolInputImageMask(_Model): - file_id: Optional[str] - image_url: Optional[str] + class azure.ai.projects.models.RubricGenerationInputQualityWarningCode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EMPTY_AGENT_INSTRUCTIONS = "empty_agent_instructions" + EMPTY_DATASET_CONTENT = "empty_dataset_content" + EMPTY_PROMPT = "empty_prompt" + INSUFFICIENT_TOTAL_INPUT = "insufficient_total_input" + LOW_TRACE_COUNT = "low_trace_count" + SHORT_AGENT_INSTRUCTIONS = "short_agent_instructions" + SHORT_DATASET_CONTENT = "short_dataset_content" + SHORT_PROMPT = "short_prompt" + + + class azure.ai.projects.models.RubricGenerationInputQualityWarningSeverity(str, Enum, metaclass=CaseInsensitiveEnumMeta): + WARNING = "warning" + + + class azure.ai.projects.models.RubricGenerationInputQualityWarningSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + AGGREGATE = "aggregate" + DATASET = "dataset" + PROMPT = "prompt" + + + class azure.ai.projects.models.SASCredentials(BaseCredentials, discriminator='SAS'): + sas_token: Optional[str] + type: Literal[CredentialType.SAS] @overload - def __init__( - self, - *, - file_id: Optional[str] = ..., - image_url: Optional[str] = ... - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Index(_Model): + class azure.ai.projects.models.SampleType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EVALUATION_RESULT_SAMPLE = "EvaluationResultSample" + + + class azure.ai.projects.models.Schedule(_Model): description: Optional[str] - id: Optional[str] - name: str + display_name: Optional[str] + enabled: bool + properties: Optional[dict[str, str]] + provisioning_status: Optional[Union[str, ScheduleProvisioningStatus]] + schedule_id: str + system_data: dict[str, str] tags: Optional[dict[str, str]] - type: str - version: str + task: ScheduleTask + trigger: Trigger @overload def __init__( self, *, description: Optional[str] = ..., + display_name: Optional[str] = ..., + enabled: bool, + properties: Optional[dict[str, str]] = ..., tags: Optional[dict[str, str]] = ..., - type: str + task: ScheduleTask, + trigger: Trigger ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.IndexType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AZURE_SEARCH = "AzureSearch" - COSMOS_DB = "CosmosDBNoSqlVectorStore" - MANAGED_AZURE_SEARCH = "ManagedAzureSearch" + class azure.ai.projects.models.ScheduleProvisioningStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CREATING = "Creating" + DELETING = "Deleting" + FAILED = "Failed" + SUCCEEDED = "Succeeded" + UPDATING = "Updating" - class azure.ai.projects.models.InlineSkillParam(ContainerSkill, discriminator='inline'): - description: str - name: str - source: InlineSkillSourceParam - type: Literal[ContainerSkillType.INLINE] + class azure.ai.projects.models.ScheduleRoutineTrigger(RoutineTrigger, discriminator='schedule'): + cron_expression: str + time_zone: str + type: Literal[RoutineTriggerType.SCHEDULE] @overload def __init__( self, *, - description: str, - name: str, - source: InlineSkillSourceParam + cron_expression: str, + time_zone: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InlineSkillSourceParam(_Model): - data: str - media_type: Literal["application/zip"] - type: Literal["base64"] + class azure.ai.projects.models.ScheduleRun(_Model): + error: Optional[str] + properties: dict[str, str] + run_id: str + schedule_id: str + success: bool + trigger_time: Optional[datetime] @overload def __init__( self, *, - data: str + schedule_id: str, + trigger_time: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InputFidelity(str, Enum, metaclass=CaseInsensitiveEnumMeta): - HIGH = "high" - LOW = "low" - - - class azure.ai.projects.models.Insight(_Model): - display_name: str - insight_id: str - metadata: InsightsMetadata - request: InsightRequest - result: Optional[InsightResult] - state: Union[str, OperationState] + class azure.ai.projects.models.ScheduleTask(_Model): + configuration: Optional[dict[str, str]] + type: str @overload def __init__( self, *, - display_name: str, - request: InsightRequest + configuration: Optional[dict[str, str]] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightCluster(_Model): - description: str - id: str - label: str - samples: Optional[list[InsightSample]] - sub_clusters: Optional[list[InsightCluster]] - suggestion: str - suggestion_title: str - weight: int + class azure.ai.projects.models.ScheduleTaskType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + EVALUATION = "Evaluation" + INSIGHT = "Insight" + + + class azure.ai.projects.models.SearchContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + IMAGE = "image" + TEXT = "text" + + + class azure.ai.projects.models.SearchContextSize(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HIGH = "high" + LOW = "low" + MEDIUM = "medium" + + + class azure.ai.projects.models.SessionConfiguration(_Model): + idle_timeout_seconds: Optional[timedelta] @overload def __init__( self, *, - description: str, - id: str, - label: str, - samples: Optional[list[InsightSample]] = ..., - sub_clusters: Optional[list[InsightCluster]] = ..., - suggestion: str, - suggestion_title: str, - weight: int + idle_timeout_seconds: Optional[timedelta] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.SessionDirectoryEntry(_Model): + is_directory: bool + modified_time: datetime + name: str + size: int + + @overload + def __init__( + self, + *, + is_directory: bool, + modified_time: datetime, + name: str, + size: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightModelConfiguration(_Model): - model_deployment_name: str + class azure.ai.projects.models.SessionFileWriteResult(_Model): + bytes_written: int + path: str @overload def __init__( self, *, - model_deployment_name: str + bytes_written: int, + path: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightRequest(_Model): - type: str + class azure.ai.projects.models.SessionLogEvent(_Model): + data: str + event: Union[str, SessionLogEventType] @overload def __init__( self, *, - type: str + data: str, + event: Union[str, SessionLogEventType] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightResult(_Model): - type: str + class azure.ai.projects.models.SessionLogEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LOG = "log" + + + class azure.ai.projects.models.SharepointGroundingToolParameters(_Model): + project_connections: Optional[list[ToolProjectConnection]] @overload def __init__( self, *, - type: str + project_connections: Optional[list[ToolProjectConnection]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightSample(_Model): - correlation_info: dict[str, Any] - features: dict[str, Any] - id: str - type: str + class azure.ai.projects.models.SharepointPreviewTool(Tool, discriminator='sharepoint_grounding_preview'): + sharepoint_grounding_preview: SharepointGroundingToolParameters + type: Literal[ToolType.SHAREPOINT_GROUNDING_PREVIEW] @overload def __init__( self, *, - correlation_info: dict[str, Any], - features: dict[str, Any], - id: str, - type: str + sharepoint_grounding_preview: SharepointGroundingToolParameters ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightScheduleTask(ScheduleTask, discriminator='Insight'): - configuration: dict[str, str] - insight: Insight - type: Literal[ScheduleTaskType.INSIGHT] + class azure.ai.projects.models.ShellToolboxTool(ToolboxTool, discriminator='shell'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + description: str + environment: ToolboxShellEnvironment + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.SHELL] @overload def __init__( self, *, - configuration: Optional[dict[str, str]] = ..., - insight: Insight + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + description: Optional[str] = ..., + environment: ToolboxShellEnvironment, + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightSummary(_Model): - method: str - sample_count: int - unique_cluster_count: int - unique_subcluster_count: int - usage: ClusterTokenUsage + class azure.ai.projects.models.SimpleQnADataGenerationJobOptions(DataGenerationJobOptions, discriminator='simple_qna'): + max_samples: int + model_options: DataGenerationModelOptions + question_types: Optional[list[Union[str, SimpleQnAFineTuningQuestionType]]] + train_split: float + type: Literal[DataGenerationJobType.SIMPLE_QNA] @overload def __init__( self, *, - method: str, - sample_count: int, - unique_cluster_count: int, - unique_subcluster_count: int, - usage: ClusterTokenUsage + max_samples: int, + model_options: Optional[DataGenerationModelOptions] = ..., + question_types: Optional[list[Union[str, SimpleQnAFineTuningQuestionType]]] = ..., + train_split: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InsightType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT_CLUSTER_INSIGHT = "AgentClusterInsight" - EVALUATION_COMPARISON = "EvaluationComparison" - EVALUATION_RUN_CLUSTER_INSIGHT = "EvaluationRunClusterInsight" + class azure.ai.projects.models.SimpleQnAFineTuningQuestionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LONG_ANSWER = "long_answer" + SHORT_ANSWER = "short_answer" - class azure.ai.projects.models.InsightsMetadata(_Model): - completed_at: Optional[datetime] - created_at: datetime + class azure.ai.projects.models.SimulationSeedDataGenerationJobOptions(DataGenerationJobOptions, discriminator='simulation_seed'): + model_options: DataGenerationModelOptions + train_split: float + type: Literal[DataGenerationJobType.SIMULATION_SEED] @overload def __init__( self, *, - completed_at: Optional[datetime] = ..., - created_at: datetime + model_options: Optional[DataGenerationModelOptions] = ..., + train_split: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InvocationsProtocolConfiguration(_Model): - - - class azure.ai.projects.models.InvocationsWsProtocolConfiguration(_Model): - - - class azure.ai.projects.models.InvokeAgentInvocationsApiDispatchPayload(RoutineDispatchPayload, discriminator='invoke_agent_invocations_api'): - input: Any - type: Literal[RoutineDispatchPayloadType.INVOKE_AGENT_INVOCATIONS_API] + class azure.ai.projects.models.SipTelephonyTransferDestination(TelephonyTransferDestination, discriminator='sip'): + kind: Literal[TelephonyTransferDestinationKind.SIP] + value: str @overload def __init__( self, *, - input: Any + value: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InvokeAgentInvocationsApiRoutineAction(RoutineAction, discriminator='invoke_agent_invocations_api'): - agent_endpoint_id: Optional[str] - agent_name: Optional[str] - input: Optional[Any] - session_id: Optional[str] - type: Literal[RoutineActionType.INVOKE_AGENT_INVOCATIONS_API] + class azure.ai.projects.models.SkillDetails(_Model): + created_at: datetime + default_version: str + description: str + id: str + latest_version: str + name: str @overload def __init__( self, *, - agent_endpoint_id: Optional[str] = ..., - agent_name: Optional[str] = ..., - input: Optional[Any] = ..., - session_id: Optional[str] = ... + created_at: datetime, + default_version: str, + description: str, + id: str, + latest_version: str, + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InvokeAgentResponsesApiDispatchPayload(RoutineDispatchPayload, discriminator='invoke_agent_responses_api'): - input: Any - type: Literal[RoutineDispatchPayloadType.INVOKE_AGENT_RESPONSES_API] + class azure.ai.projects.models.SkillInlineContent(_Model): + allowed_tools: Optional[list[str]] + compatibility: Optional[str] + description: str + instructions: str + license: Optional[str] + metadata: Optional[dict[str, str]] @overload def __init__( self, *, - input: Any + allowed_tools: Optional[list[str]] = ..., + compatibility: Optional[str] = ..., + description: str, + instructions: str, + license: Optional[str] = ..., + metadata: Optional[dict[str, str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.InvokeAgentResponsesApiRoutineAction(RoutineAction, discriminator='invoke_agent_responses_api'): - agent_endpoint_id: Optional[str] - agent_name: Optional[str] - conversation: Optional[str] - input: Optional[Any] - type: Literal[RoutineActionType.INVOKE_AGENT_RESPONSES_API] + class azure.ai.projects.models.SkillReference(_Model): + name: str + version: Optional[str] @overload def __init__( self, *, - agent_endpoint_id: Optional[str] = ..., - agent_name: Optional[str] = ..., - conversation: Optional[str] = ..., - input: Optional[Any] = ... + name: str, + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.JobStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CANCELLED = "cancelled" - FAILED = "failed" - IN_PROGRESS = "in_progress" - QUEUED = "queued" - SUCCEEDED = "succeeded" - - - class azure.ai.projects.models.LocalShellToolParam(Tool, discriminator='local_shell'): - description: Optional[str] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.LOCAL_SHELL] + class azure.ai.projects.models.SkillReferenceParam(ContainerSkill, discriminator='skill_reference'): + skill_id: str + type: Literal[ContainerSkillType.SKILL_REFERENCE] + version: Optional[str] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + skill_id: str, + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.LocalSkillParam(_Model): + class azure.ai.projects.models.SkillVersion(_Model): + created_at: datetime description: str + id: str name: str - path: str + skill_id: str + version: str @overload def __init__( self, *, + created_at: datetime, description: str, + id: str, name: str, - path: str + skill_id: str, + version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.LoraConfig(_Model): - alpha: Optional[int] - dropout: Optional[float] - rank: Optional[int] - target_modules: Optional[list[str]] + class azure.ai.projects.models.SpecificApplyPatchParam(ToolChoiceParam, discriminator='apply_patch'): + type: Literal[ToolChoiceParamType.APPLY_PATCH] @overload - def __init__( - self, - *, - alpha: Optional[int] = ..., - dropout: Optional[float] = ..., - rank: Optional[int] = ..., - target_modules: Optional[list[str]] = ... - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MCPTool(Tool, discriminator='mcp'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - allowed_tools: Optional[Union[list[str], MCPToolFilter]] - authorization: Optional[str] - connector_id: Optional[Literal["connector_dropbox", "connector_gmail", "connector_googlecalendar", "connector_googledrive", "connector_microsoftteams", "connector_outlookcalendar", "connector_outlookemail", "connector_sharepoint"]] - defer_loading: Optional[bool] - headers: Optional[dict[str, str]] - project_connection_id: Optional[str] - require_approval: Optional[Union[MCPToolRequireApproval, Literal["always"], Literal["never"]]] - server_description: Optional[str] - server_label: str - server_url: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - tunnel_id: Optional[str] - type: Literal[ToolType.MCP] + class azure.ai.projects.models.SpecificFunctionShellParam(ToolChoiceParam, discriminator='shell'): + type: Literal[ToolChoiceParamType.SHELL] @overload - def __init__( - self, - *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - allowed_tools: Optional[Union[list[str], MCPToolFilter]] = ..., - authorization: Optional[str] = ..., - connector_id: Optional[Literal[connector_dropbox, connector_gmail, connector_googlecalendar, connector_googledrive, connector_microsoftteams, connector_outlookcalendar, connector_outlookemail, connector_sharepoint]] = ..., - defer_loading: Optional[bool] = ..., - headers: Optional[dict[str, str]] = ..., - project_connection_id: Optional[str] = ..., - require_approval: Optional[Union[MCPToolRequireApproval, Literal[always], Literal[never]]] = ..., - server_description: Optional[str] = ..., - server_label: str, - server_url: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ..., - tunnel_id: Optional[str] = ... - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MCPToolFilter(_Model): - read_only: Optional[bool] - tool_names: Optional[list[str]] + class azure.ai.projects.models.SpecificProgrammaticToolCallingParam(ToolChoiceParam, discriminator='programmatic_tool_calling'): + type: Literal[ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING] @overload - def __init__( - self, - *, - read_only: Optional[bool] = ..., - tool_names: Optional[list[str]] = ... - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MCPToolRequireApproval(_Model): - always: Optional[MCPToolFilter] - never: Optional[MCPToolFilter] + class azure.ai.projects.models.StructuredInputDefinition(_Model): + default_value: Optional[Any] + description: Optional[str] + required: Optional[bool] + schema: Optional[dict[str, Any]] @overload def __init__( self, *, - always: Optional[MCPToolFilter] = ..., - never: Optional[MCPToolFilter] = ... + default_value: Optional[Any] = ..., + description: Optional[str] = ..., + required: Optional[bool] = ..., + schema: Optional[dict[str, Any]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MCPToolboxTool(ToolboxTool, discriminator='mcp'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - allowed_tools: Optional[Union[list[str], MCPToolFilter]] - authorization: Optional[str] - connector_id: Optional[Literal["connector_dropbox", "connector_gmail", "connector_googlecalendar", "connector_googledrive", "connector_microsoftteams", "connector_outlookcalendar", "connector_outlookemail", "connector_sharepoint"]] - defer_loading: Optional[bool] + class azure.ai.projects.models.StructuredOutputDefinition(_Model): description: str - headers: Optional[dict[str, str]] name: str - project_connection_id: Optional[str] - require_approval: Optional[Union[MCPToolRequireApproval, Literal["always"], Literal["never"]]] - server_description: Optional[str] - server_label: str - server_url: Optional[str] - tool_configs: dict[str, ToolConfig] - tunnel_id: Optional[str] - type: Literal[ToolboxToolType.MCP] + schema: dict[str, Any] + strict: bool @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - allowed_tools: Optional[Union[list[str], MCPToolFilter]] = ..., - authorization: Optional[str] = ..., - connector_id: Optional[Literal[connector_dropbox, connector_gmail, connector_googlecalendar, connector_googledrive, connector_microsoftteams, connector_outlookcalendar, connector_outlookemail, connector_sharepoint]] = ..., - defer_loading: Optional[bool] = ..., - description: Optional[str] = ..., - headers: Optional[dict[str, str]] = ..., - name: Optional[str] = ..., - project_connection_id: Optional[str] = ..., - require_approval: Optional[Union[MCPToolRequireApproval, Literal[always], Literal[never]]] = ..., - server_description: Optional[str] = ..., - server_label: str, - server_url: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ..., - tunnel_id: Optional[str] = ... + description: str, + name: str, + schema: dict[str, Any], + strict: bool ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ManagedAgentIdentityBlueprintReference(AgentBlueprintReference, discriminator='ManagedAgentIdentityBlueprint'): - blueprint_id: str - type: Literal[AgentBlueprintReferenceType.MANAGED_AGENT_IDENTITY_BLUEPRINT] + class azure.ai.projects.models.TargetCompletionEvalRunDataSource(TypedDict, total=False): + key "input_messages": Required[InputMessagesItemReference] + key "source": Required[Union[SourceFileContent, SourceFileID]] + key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] + key "type": Required[Literal["azure_ai_target_completions"]] + + + class azure.ai.projects.models.TaxonomyCategory(_Model): + description: Optional[str] + id: str + name: str + properties: Optional[dict[str, str]] + risk_category: Union[str, RiskCategory] + sub_categories: list[TaxonomySubCategory] @overload def __init__( self, *, - blueprint_id: str + description: Optional[str] = ..., + id: str, + name: str, + properties: Optional[dict[str, str]] = ..., + risk_category: Union[str, RiskCategory], + sub_categories: list[TaxonomySubCategory] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ManagedAzureAISearchIndex(Index, discriminator='ManagedAzureSearch'): - description: str + class azure.ai.projects.models.TaxonomySubCategory(_Model): + description: Optional[str] + enabled: bool id: str name: str - tags: dict[str, str] - type: Literal[IndexType.MANAGED_AZURE_SEARCH] - vector_store_id: str - version: str + properties: Optional[dict[str, str]] @overload def __init__( self, *, description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ..., - vector_store_id: str + enabled: bool, + id: str, + name: str, + properties: Optional[dict[str, str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.McpProtocolConfiguration(_Model): - - - class azure.ai.projects.models.MemoryItem(_Model): - content: str - kind: str - memory_id: str - scope: str - updated_at: datetime + class azure.ai.projects.models.TeamsPhoneExtensionTelephonyBinding(TelephonyBinding, discriminator='teams_phone_extension'): + connection_name: str + id: str + incoming_call_url: str + label: str + phone_number: Optional[str] + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] + resource_account_object_id: str + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - content: str, - kind: str, - memory_id: str, - scope: str, - updated_at: datetime + connection_name: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + phone_number: Optional[str] = ..., + resource_account_object_id: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryItemKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CHAT_SUMMARY = "chat_summary" - PROCEDURAL = "procedural" - USER_PROFILE = "user_profile" - - - class azure.ai.projects.models.MemoryOperation(_Model): - kind: Union[str, MemoryOperationKind] - memory_item: MemoryItem + class azure.ai.projects.models.TeamsPhoneExtensionTelephonyBindingListItem(TelephonyBindingListItem, discriminator='teams_phone_extension'): + connection_name: str + etag: str + id: str + incoming_call_url: str + label: str + phone_number: Optional[str] + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] + resource_account_object_id: str + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - kind: Union[str, MemoryOperationKind], - memory_item: MemoryItem + connection_name: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + phone_number: Optional[str] = ..., + resource_account_object_id: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryOperationKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CREATE = "create" - DELETE = "delete" - UPDATE = "update" - - - class azure.ai.projects.models.MemorySearchItem(_Model): - memory_item: MemoryItem + class azure.ai.projects.models.TeamsTelephonyTransferDestination(TelephonyTransferDestination, discriminator='teams'): + kind: Literal[TelephonyTransferDestinationKind.TEAMS] + value: str @overload def __init__( self, *, - memory_item: MemoryItem + value: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemorySearchOptions(_Model): - max_memories: Optional[int] + class azure.ai.projects.models.TelemetryConfig(_Model): + endpoints: list[TelemetryEndpoint] @overload def __init__( self, *, - max_memories: Optional[int] = ... + endpoints: list[TelemetryEndpoint] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemorySearchPreviewTool(Tool, discriminator='memory_search_preview'): - memory_store_name: str - scope: str - search_options: Optional[MemorySearchOptions] - type: Literal[ToolType.MEMORY_SEARCH_PREVIEW] - update_delay: Optional[int] + class azure.ai.projects.models.TelemetryDataKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CONTAINER_OTEL = "ContainerOtel" + CONTAINER_STDOUT_STDERR = "ContainerStdoutStderr" + METRICS = "Metrics" + + + class azure.ai.projects.models.TelemetryEndpoint(_Model): + auth: Optional[TelemetryEndpointAuth] + data: list[Union[str, TelemetryDataKind]] + kind: str @overload def __init__( self, *, - memory_store_name: str, - scope: str, - search_options: Optional[MemorySearchOptions] = ..., - update_delay: Optional[int] = ... + auth: Optional[TelemetryEndpointAuth] = ..., + data: list[Union[str, TelemetryDataKind]], + kind: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreDefaultDefinition(MemoryStoreDefinition, discriminator='default'): - chat_model: str - embedding_model: str - kind: Literal[MemoryStoreKind.DEFAULT] - options: Optional[MemoryStoreDefaultOptions] + class azure.ai.projects.models.TelemetryEndpointAuth(_Model): + type: str @overload def __init__( self, *, - chat_model: str, - embedding_model: str, - options: Optional[MemoryStoreDefaultOptions] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreDefaultOptions(_Model): - chat_summary_enabled: bool - default_ttl_seconds: Optional[timedelta] - procedural_memory_enabled: Optional[bool] - user_profile_details: Optional[str] - user_profile_enabled: bool + class azure.ai.projects.models.TelemetryEndpointAuthType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + HEADER = "header" - @overload - def __init__( - self, - *, - chat_summary_enabled: bool, - default_ttl_seconds: Optional[timedelta] = ..., - procedural_memory_enabled: Optional[bool] = ..., - user_profile_details: Optional[str] = ..., - user_profile_enabled: bool - ) -> None: ... - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... + class azure.ai.projects.models.TelemetryEndpointKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + OTLP = "OTLP" - class azure.ai.projects.models.MemoryStoreDefinition(_Model): - kind: str + class azure.ai.projects.models.TelemetryTransportProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): + GRPC = "Grpc" + HTTP = "Http" + + + class azure.ai.projects.models.TelephonyBinding(_Model): + connection_name: str + id: str + incoming_call_url: str + label: Optional[str] + provider: str + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - kind: str + connection_name: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + provider: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreDeleteScopeResult(_Model): - deleted: bool - name: str - object: Literal[MemoryStoreObjectType.MEMORY_STORE_SCOPE_DELETED] - scope: str + class azure.ai.projects.models.TelephonyBindingListItem(_Model): + connection_name: str + etag: str + id: str + incoming_call_url: str + label: Optional[str] + provider: str + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - deleted: bool, - name: str, - object: Literal[MemoryStoreObjectType.MEMORY_STORE_SCOPE_DELETED], - scope: str + connection_name: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + provider: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreDetails(_Model): + class azure.ai.projects.models.TelephonyBindingStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACTIVE = "active" + SUSPENDED = "suspended" + + + class azure.ai.projects.models.TelephonyCallDurationBasis(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ANSWERED = "answered" + RECEIVED = "received" + + + class azure.ai.projects.models.TelephonyCallEndReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ADMISSION_CHECK_FAILED = "admission_check_failed" + ADMISSION_REJECTED = "admission_rejected" + AGENT_SESSION_CONNECT_FAILED = "agent_session_connect_failed" + ANSWER_FAILED = "answer_failed" + BINDING_NOT_FOUND = "binding_not_found" + BINDING_SUSPENDED = "binding_suspended" + BRIDGE_CANCELLED = "bridge_cancelled" + BRIDGE_FAILED = "bridge_failed" + CREDENTIAL_RESOLUTION_FAILED = "credential_resolution_failed" + ENDPOINT_RESOLUTION_FAILED = "endpoint_resolution_failed" + INGRESS_SETUP_FAILED = "ingress_setup_failed" + INVALID_BINDING_CONFIGURATION = "invalid_binding_configuration" + INVALID_WEBHOOK_PAYLOAD = "invalid_webhook_payload" + LIVE_CALL_CONFLICT = "live_call_conflict" + LIVE_CALL_PERSISTENCE_FAILED = "live_call_persistence_failed" + MANAGED_HANGUP = "managed_hangup" + MANAGED_TRANSFER = "managed_transfer" + MANAGE_HANGUP_FAILED = "manage_hangup_failed" + MANAGE_TRANSFER_FAILED = "manage_transfer_failed" + MEDIA_STREAM_ENDED = "media_stream_ended" + PROVIDER_BUSY = "provider_busy" + PROVIDER_CANCELLED = "provider_cancelled" + PROVIDER_DISCONNECTED = "provider_disconnected" + PROVIDER_FAILED = "provider_failed" + PROVIDER_NO_ANSWER = "provider_no_answer" + PROVIDER_RESOURCE_MISMATCH = "provider_resource_mismatch" + PROVIDER_STREAM_ERROR = "provider_stream_error" + PROVIDER_STREAM_STOPPED = "provider_stream_stopped" + ROUTE_AGENT_MISMATCH = "route_agent_mismatch" + WEBHOOK_VALIDATION_FAILED = "webhook_validation_failed" + + + class azure.ai.projects.models.TelephonyCallJob(_Model): + agent_name: str + attempt_count: int + cancellation: Optional[TelephonyCallJobCancellation] + connection_name: str created_at: datetime - definition: MemoryStoreDefinition - description: Optional[str] + destination: TelephonyOutboundDestination id: str - metadata: Optional[dict[str, str]] - name: str - object: Literal[MemoryStoreObjectType.MEMORY_STORE] + next_attempt_at: Optional[datetime] + object: Literal["call_job"] + purpose: Optional[str] + retry_policy: TelephonyOutboundRetryPolicy + revision: int + schedule: Optional[TelephonyCallJobSchedule] + source: str + status: Union[str, TelephonyCallJobStatus] + structured_inputs: Optional[dict[str, Any]] + terminal_reason: Optional[Union[str, TelephonyCallJobTerminalReason]] updated_at: datetime @overload def __init__( self, *, + agent_name: str, + attempt_count: int, + cancellation: Optional[TelephonyCallJobCancellation] = ..., + connection_name: str, created_at: datetime, - definition: MemoryStoreDefinition, - description: Optional[str] = ..., - id: str, - metadata: Optional[dict[str, str]] = ..., - name: str, - object: Literal[MemoryStoreObjectType.MEMORY_STORE], + destination: TelephonyOutboundDestination, + id: str, + next_attempt_at: Optional[datetime] = ..., + purpose: Optional[str] = ..., + retry_policy: TelephonyOutboundRetryPolicy, + revision: int, + schedule: Optional[TelephonyCallJobSchedule] = ..., + source: str, + status: Union[str, TelephonyCallJobStatus], + structured_inputs: Optional[dict[str, Any]] = ..., + terminal_reason: Optional[Union[str, TelephonyCallJobTerminalReason]] = ..., updated_at: datetime ) -> None: ... @@ -7739,401 +12642,620 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DEFAULT = "default" - - - class azure.ai.projects.models.MemoryStoreObjectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - MEMORY_DELETED = "memory_store.item.deleted" - MEMORY_STORE = "memory_store" - MEMORY_STORE_DELETED = "memory_store.deleted" - MEMORY_STORE_SCOPE_DELETED = "memory_store.scope.deleted" - - - class azure.ai.projects.models.MemoryStoreOperationUsage(_Model): - embedding_tokens: int - input_tokens: int - input_tokens_details: ResponseUsageInputTokensDetails - output_tokens: int - output_tokens_details: ResponseUsageOutputTokensDetails - total_tokens: int + class azure.ai.projects.models.TelephonyCallJobCancellation(_Model): + mode: str + requested_at: datetime + requested_by: str + revision: int @overload def __init__( self, *, - embedding_tokens: int, - input_tokens: int, - input_tokens_details: ResponseUsageInputTokensDetails, - output_tokens: int, - output_tokens_details: ResponseUsageOutputTokensDetails, - total_tokens: int + mode: str, + requested_at: datetime, + requested_by: str, + revision: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreSearchResult(_Model): - memories: list[MemorySearchItem] - search_id: str - usage: MemoryStoreOperationUsage + class azure.ai.projects.models.TelephonyCallJobSchedule(_Model): + expires_at: Optional[datetime] + not_before: Optional[datetime] @overload def __init__( self, *, - memories: list[MemorySearchItem], - search_id: str, - usage: MemoryStoreOperationUsage + expires_at: Optional[datetime] = ..., + not_before: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreUpdateCompletedResult(_Model): - memory_operations: list[MemoryOperation] - usage: MemoryStoreOperationUsage + class azure.ai.projects.models.TelephonyCallJobStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACCEPTED = "accepted" + BLOCKED = "blocked" + CANCELLATION_REQUESTED = "cancellation_requested" + CANCELLED = "cancelled" + COMPLETED = "completed" + DISPATCHING = "dispatching" + EXPIRED = "expired" + FAILED = "failed" + IN_PROGRESS = "in_progress" + QUEUED = "queued" + WAITING_FOR_RETRY = "waiting_for_retry" + WAITING_FOR_SCHEDULE = "waiting_for_schedule" + + + class azure.ai.projects.models.TelephonyCallJobTerminalReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ANSWER_FAILED = "answer_failed" + BRIDGE_CANCELLED = "bridge_cancelled" + BRIDGE_FAILED = "bridge_failed" + CAMPAIGN_CANCELLED = "campaign_cancelled" + CAMPAIGN_COMPLETED = "campaign_completed" + CAMPAIGN_FAILED = "campaign_failed" + CAMPAIGN_NOT_FOUND = "campaign_not_found" + CANCELLATION_RECONCILIATION_TIMEOUT = "cancellation_reconciliation_timeout" + CONNECTION_PROJECT_MISMATCH = "connection_project_mismatch" + NO_ANSWER = "no_answer" + NO_ANSWER_TIMEOUT = "no_answer_timeout" + ORIGINATION_FENCE_NOT_RECORDED = "origination_fence_not_recorded" + ORIGINATION_RECONCILIATION_TIMEOUT = "origination_reconciliation_timeout" + OUTBOUND_CONNECTION_CHANGED = "outbound_connection_changed" + OUTBOUND_CONNECTION_UNAVAILABLE = "outbound_connection_unavailable" + PROVIDER_CALLBACK_TIMEOUT_CANCELLATION_RECONCILIATION_TIMEOUT = "provider_callback_timeout_cancellation_reconciliation_timeout" + TELEPHONY_BINDING_CHANGED = "telephony_binding_changed" + TELEPHONY_BINDING_INACTIVE = "telephony_binding_inactive" + TELEPHONY_BINDING_INVALID = "telephony_binding_invalid" + TELEPHONY_BINDING_NOT_FOUND = "telephony_binding_not_found" + VOICE_SESSION_CONFIGURATION_INVALID = "voice_session_configuration_invalid" + + + class azure.ai.projects.models.TelephonyCallLifecycleEvent(_Model): + name: Union[str, TelephonyCallLifecycleEventName] + observed_at: datetime + occurred_at: Optional[datetime] + outcome: Union[str, TelephonyCallLifecycleEventOutcome] + provider_event_id: Optional[str] + provider_sequence: Optional[int] + provider_status_code: Optional[int] + provider_sub_code: Optional[int] + reason: Optional[Union[str, TelephonyCallLifecycleEventReason]] + sequence: int + source: Union[str, TelephonyCallLifecycleEventSource] + timestamp_source: Union[str, TelephonyCallTimestampSource] + + @overload + def __init__( + self, + *, + name: Union[str, TelephonyCallLifecycleEventName], + observed_at: datetime, + occurred_at: Optional[datetime] = ..., + outcome: Union[str, TelephonyCallLifecycleEventOutcome], + provider_event_id: Optional[str] = ..., + provider_sequence: Optional[int] = ..., + provider_status_code: Optional[int] = ..., + provider_sub_code: Optional[int] = ..., + reason: Optional[Union[str, TelephonyCallLifecycleEventReason]] = ..., + source: Union[str, TelephonyCallLifecycleEventSource], + timestamp_source: Union[str, TelephonyCallTimestampSource] + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.TelephonyCallLifecycleEventName(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT_SESSION_CONNECT = "telephony.agent_session.connect" + BINDING_RESOLVE = "telephony.binding.resolve" + CALL_DISCONNECT = "telephony.call.disconnect" + CALL_HANGUP = "telephony.call.hangup" + CALL_TRANSFER = "telephony.call.transfer" + FIRST_AGENT_AUDIO = "telephony.media.first_agent_audio" + FIRST_CALLER_AUDIO = "telephony.media.first_caller_audio" + MEDIA_CONNECT = "telephony.media.connect" + PROVIDER_ANSWER = "telephony.provider.answer" + WEBHOOK_RECEIVED = "telephony.webhook.received" + WEBHOOK_VALIDATION = "telephony.webhook.validation" + + + class azure.ai.projects.models.TelephonyCallLifecycleEventOutcome(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CANCELLED = "cancelled" + FAILED = "failed" + OBSERVED = "observed" + REJECTED = "rejected" + STARTED = "started" + SUCCEEDED = "succeeded" + + + class azure.ai.projects.models.TelephonyCallLifecycleEventReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ADMISSION_CHECK_FAILED = "admission_check_failed" + ADMISSION_REJECTED = "admission_rejected" + AGENT_SESSION_CONNECT_FAILED = "agent_session_connect_failed" + ANSWER_FAILED = "answer_failed" + BINDING_NOT_FOUND = "binding_not_found" + BINDING_SUSPENDED = "binding_suspended" + BRIDGE_CANCELLED = "bridge_cancelled" + BRIDGE_FAILED = "bridge_failed" + CREDENTIAL_RESOLUTION_FAILED = "credential_resolution_failed" + ENDPOINT_RESOLUTION_FAILED = "endpoint_resolution_failed" + INGRESS_SETUP_FAILED = "ingress_setup_failed" + INVALID_BINDING_CONFIGURATION = "invalid_binding_configuration" + INVALID_WEBHOOK_PAYLOAD = "invalid_webhook_payload" + LIVE_CALL_CONFLICT = "live_call_conflict" + LIVE_CALL_PERSISTENCE_FAILED = "live_call_persistence_failed" + MANAGED_HANGUP = "managed_hangup" + MANAGED_TRANSFER = "managed_transfer" + MANAGE_HANGUP_FAILED = "manage_hangup_failed" + MANAGE_TRANSFER_FAILED = "manage_transfer_failed" + MEDIA_STREAM_ENDED = "media_stream_ended" + PROVIDER_BUSY = "provider_busy" + PROVIDER_CANCELLED = "provider_cancelled" + PROVIDER_DISCONNECTED = "provider_disconnected" + PROVIDER_FAILED = "provider_failed" + PROVIDER_NO_ANSWER = "provider_no_answer" + PROVIDER_RESOURCE_MISMATCH = "provider_resource_mismatch" + PROVIDER_STREAM_ERROR = "provider_stream_error" + PROVIDER_STREAM_STOPPED = "provider_stream_stopped" + ROUTE_AGENT_MISMATCH = "route_agent_mismatch" + WEBHOOK_VALIDATION_FAILED = "webhook_validation_failed" + + + class azure.ai.projects.models.TelephonyCallLifecycleEventSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + GATEWAY = "gateway" + TEAMS_PHONE_EXTENSION = "teams_phone_extension" + TWILIO = "twilio" + VOICE_AGENT = "voice_agent" + + + class azure.ai.projects.models.TelephonyCallPhase(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ADMITTED = "admitted" + AGENT_SESSION_READY = "agent_session_ready" + ANSWERED = "answered" + ANSWERING = "answering" + BRIDGING = "bridging" + COMPLETED = "completed" + FAILED = "failed" + MANAGING = "managing" + MEDIA_CONNECTED = "media_connected" + RECEIVED = "received" + REJECTED = "rejected" + VALIDATED = "validated" + + + class azure.ai.projects.models.TelephonyCallRecord(_Model): + agent_session_ready_at: Optional[datetime] + answered_at: Optional[datetime] + caller_number: Optional[str] + duration_ms: Optional[timedelta] + end_reason: Optional[Union[str, TelephonyCallEndReason]] + ended_at: Optional[datetime] + events: list[TelephonyCallLifecycleEvent] + events_truncated: bool + id: str + media_connected_at: Optional[datetime] + phase: Union[str, TelephonyCallPhase] + provider: Union[str, TelephonyProvider] + provider_call_id: Optional[str] + provider_message: Optional[str] + provider_number: Optional[str] + provider_status_code: Optional[int] + provider_sub_code: Optional[int] + started_at: datetime + status: Union[str, TelephonyCallStatus] + timing: TelephonyCallTiming + trace: Optional[TelephonyCallTrace] @overload def __init__( self, *, - memory_operations: list[MemoryOperation], - usage: MemoryStoreOperationUsage + agent_session_ready_at: Optional[datetime] = ..., + answered_at: Optional[datetime] = ..., + caller_number: Optional[str] = ..., + duration_ms: Optional[timedelta] = ..., + end_reason: Optional[Union[str, TelephonyCallEndReason]] = ..., + ended_at: Optional[datetime] = ..., + events: list[TelephonyCallLifecycleEvent], + events_truncated: bool, + id: str, + media_connected_at: Optional[datetime] = ..., + phase: Union[str, TelephonyCallPhase], + provider: Union[str, TelephonyProvider], + provider_call_id: Optional[str] = ..., + provider_message: Optional[str] = ..., + provider_number: Optional[str] = ..., + provider_status_code: Optional[int] = ..., + provider_sub_code: Optional[int] = ..., + started_at: datetime, + status: Union[str, TelephonyCallStatus], + timing: TelephonyCallTiming, + trace: Optional[TelephonyCallTrace] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreUpdateResult(_Model): - error: Optional[ApiError] - result: Optional[MemoryStoreUpdateCompletedResult] - status: Union[str, MemoryStoreUpdateStatus] - superseded_by: Optional[str] - update_id: str + class azure.ai.projects.models.TelephonyCallStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FAILED = "failed" + IN_PROGRESS = "in_progress" + SUCCESS = "success" + + + class azure.ai.projects.models.TelephonyCallSummary(_Model): + agent_session_ready_at: Optional[datetime] + answered_at: Optional[datetime] + caller_number: Optional[str] + duration_ms: Optional[timedelta] + end_reason: Optional[Union[str, TelephonyCallEndReason]] + ended_at: Optional[datetime] + id: str + media_connected_at: Optional[datetime] + phase: Union[str, TelephonyCallPhase] + provider: Union[str, TelephonyProvider] + provider_call_id: Optional[str] + provider_message: Optional[str] + provider_number: Optional[str] + provider_status_code: Optional[int] + provider_sub_code: Optional[int] + started_at: datetime + status: Union[str, TelephonyCallStatus] @overload def __init__( self, *, - error: Optional[ApiError] = ..., - result: Optional[MemoryStoreUpdateCompletedResult] = ..., - status: Union[str, MemoryStoreUpdateStatus], - superseded_by: Optional[str] = ..., - update_id: str + agent_session_ready_at: Optional[datetime] = ..., + answered_at: Optional[datetime] = ..., + caller_number: Optional[str] = ..., + duration_ms: Optional[timedelta] = ..., + end_reason: Optional[Union[str, TelephonyCallEndReason]] = ..., + ended_at: Optional[datetime] = ..., + id: str, + media_connected_at: Optional[datetime] = ..., + phase: Union[str, TelephonyCallPhase], + provider: Union[str, TelephonyProvider], + provider_call_id: Optional[str] = ..., + provider_message: Optional[str] = ..., + provider_number: Optional[str] = ..., + provider_status_code: Optional[int] = ..., + provider_sub_code: Optional[int] = ..., + started_at: datetime, + status: Union[str, TelephonyCallStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MemoryStoreUpdateStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - COMPLETED = "completed" - FAILED = "failed" - IN_PROGRESS = "in_progress" - QUEUED = "queued" - SUPERSEDED = "superseded" + class azure.ai.projects.models.TelephonyCallTimestampSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DERIVED = "derived" + GATEWAY = "gateway" + PROVIDER = "provider" - class azure.ai.projects.models.Microsoft365PermissionScopes(_Model): - resource_app_id: str - scopes: list[str] + class azure.ai.projects.models.TelephonyCallTiming(_Model): + admitted_at: Optional[datetime] + agent_session_ready_at: Optional[datetime] + answer_requested_at: Optional[datetime] + answered_at: Optional[datetime] + duration_basis: Optional[Union[str, TelephonyCallDurationBasis]] + ended_at: Optional[datetime] + first_agent_audio_at: Optional[datetime] + first_caller_audio_at: Optional[datetime] + media_connected_at: Optional[datetime] + received_at: Optional[datetime] + timestamp_source: Union[str, TelephonyCallTimestampSource] + validated_at: Optional[datetime] @overload def __init__( self, *, - resource_app_id: str, - scopes: list[str] + admitted_at: Optional[datetime] = ..., + agent_session_ready_at: Optional[datetime] = ..., + answer_requested_at: Optional[datetime] = ..., + answered_at: Optional[datetime] = ..., + duration_basis: Optional[Union[str, TelephonyCallDurationBasis]] = ..., + ended_at: Optional[datetime] = ..., + first_agent_audio_at: Optional[datetime] = ..., + first_caller_audio_at: Optional[datetime] = ..., + media_connected_at: Optional[datetime] = ..., + received_at: Optional[datetime] = ..., + timestamp_source: Union[str, TelephonyCallTimestampSource], + validated_at: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Microsoft365PublishDefaults(_Model): - agent_display_name: Optional[str] - agent_name: Optional[str] - app_publish_scope: Optional[Union[str, Microsoft365PublishScope]] - app_registration_client_id: Optional[str] - app_version: Optional[str] - bot_service_arm_id: Optional[str] - developer_name: Optional[str] - developer_website_url: Optional[str] - full_description: Optional[str] - privacy_url: Optional[str] - recommended_next_app_version: Optional[str] - short_description: Optional[str] - teams_app_id: Optional[str] - terms_of_use_url: Optional[str] - title_id: Optional[str] + class azure.ai.projects.models.TelephonyCallTrace(_Model): + conversation_id: Optional[str] + mode: Optional[Union[str, TelephonyCallTraceMode]] + root_span_id: Optional[str] + status: Union[str, TelephonyCallTraceStatus] + trace_id: Optional[str] @overload def __init__( self, *, - agent_display_name: Optional[str] = ..., - agent_name: Optional[str] = ..., - app_publish_scope: Optional[Union[str, Microsoft365PublishScope]] = ..., - app_registration_client_id: Optional[str] = ..., - app_version: Optional[str] = ..., - bot_service_arm_id: Optional[str] = ..., - developer_name: Optional[str] = ..., - developer_website_url: Optional[str] = ..., - full_description: Optional[str] = ..., - privacy_url: Optional[str] = ..., - recommended_next_app_version: Optional[str] = ..., - short_description: Optional[str] = ..., - teams_app_id: Optional[str] = ..., - terms_of_use_url: Optional[str] = ..., - title_id: Optional[str] = ... + conversation_id: Optional[str] = ..., + mode: Optional[Union[str, TelephonyCallTraceMode]] = ..., + root_span_id: Optional[str] = ..., + status: Union[str, TelephonyCallTraceStatus], + trace_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Microsoft365PublishResult(_Model): - teams_app_id: Optional[str] - title_id: Optional[str] + class azure.ai.projects.models.TelephonyCallTraceMode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LIVE = "live" + POST_CALL = "post_call" + + + class azure.ai.projects.models.TelephonyCallTraceStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AVAILABLE = "available" + EMITTING = "emitting" + FAILED = "failed" + NOT_APPLICABLE = "not_applicable" + NOT_RECORDED = "not_recorded" + PENDING = "pending" + + + class azure.ai.projects.models.TelephonyOutboundDestination(_Model): + type: Union[str, TelephonyOutboundDestinationType] + value: str @overload def __init__( self, *, - teams_app_id: Optional[str] = ..., - title_id: Optional[str] = ... + type: Union[str, TelephonyOutboundDestinationType], + value: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Microsoft365PublishScope(str, Enum, metaclass=CaseInsensitiveEnumMeta): - PERSONAL = "Personal" - SHARED = "Shared" - TENANT = "Tenant" + class azure.ai.projects.models.TelephonyOutboundDestinationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PHONE_NUMBER = "phone_number" - class azure.ai.projects.models.MicrosoftFabricPreviewTool(Tool, discriminator='fabric_dataagent_preview'): - fabric_dataagent_preview: FabricDataAgentToolParameters - type: Literal[ToolType.FABRIC_DATAAGENT_PREVIEW] + class azure.ai.projects.models.TelephonyOutboundFixedIntervalRetryPolicy(TelephonyOutboundRetryPolicy, discriminator='fixed_interval'): + interval: timedelta + max_attempts: int + type: Literal[TelephonyOutboundRetryPolicyType.FIXED_INTERVAL] @overload def __init__( self, *, - fabric_dataagent_preview: FabricDataAgentToolParameters + interval: timedelta, + max_attempts: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelCredentialRequest(_Model): - blob_uri: str + class azure.ai.projects.models.TelephonyOutboundRetryPolicy(_Model): + max_attempts: Optional[int] + type: str @overload def __init__( self, *, - blob_uri: str + max_attempts: Optional[int] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelDeployment(Deployment, discriminator='ModelDeployment'): - capabilities: dict[str, str] - connection_name: Optional[str] - model_name: str - model_publisher: str - model_version: str - name: str - sku: ModelDeploymentSku - type: Literal[DeploymentType.MODEL_DEPLOYMENT] + class azure.ai.projects.models.TelephonyOutboundRetryPolicyType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FIXED_INTERVAL = "fixed_interval" + + + class azure.ai.projects.models.TelephonyProvider(str, Enum, metaclass=CaseInsensitiveEnumMeta): + TEAMS_PHONE_EXTENSION = "teams_phone_extension" + TWILIO = "twilio" + + + class azure.ai.projects.models.TelephonyTransferDestination(_Model): + kind: str @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + kind: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelDeploymentSku(_Model): - capacity: int - family: str + class azure.ai.projects.models.TelephonyTransferDestinationKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PSTN = "pstn" + SIP = "sip" + TEAMS = "teams" + + + class azure.ai.projects.models.TelephonyTransferTarget(_Model): + description: str + destination: TelephonyTransferDestination name: str - size: str - tier: str @overload def __init__( self, *, - capacity: int, - family: str, - name: str, - size: str, - tier: str + description: str, + destination: TelephonyTransferDestination, + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelPendingUploadRequest(_Model): - connection_name: Optional[str] - pending_upload_id: Optional[str] - pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] + class azure.ai.projects.models.TelephonyTransferTargets(_Model): + transfer_targets: list[TelephonyTransferTarget] @overload def __init__( self, *, - connection_name: Optional[str] = ..., - pending_upload_id: Optional[str] = ..., - pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] + transfer_targets: list[TelephonyTransferTarget] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelPendingUploadResponse(_Model): - blob_reference: BlobReference - pending_upload_id: str - pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE] - version: Optional[str] + class azure.ai.projects.models.TestingCriterionAzureAIEvaluator(TypedDict, total=False): + key "data_mapping": Dict[str, str] + key "evaluator_name": Required[str] + key "evaluator_version": str + key "initialization_parameters": Dict[str, Any] + key "name": Required[str] + key "type": Required[Literal["azure_ai_evaluator"]] + + + class azure.ai.projects.models.TextResponseFormat(_Model): + type: str @overload def __init__( self, *, - blob_reference: BlobReference, - pending_upload_id: str, - pending_upload_type: Literal[PendingUploadType.TEMPORARY_BLOB_REFERENCE], - version: Optional[str] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelSamplingConfigParam(TypedDict, total=False): - key "max_completion_tokens": int - key "seed": int - key "temperature": float - key "top_p": float + class azure.ai.projects.models.TextResponseFormatConfigurationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + JSON_OBJECT = "json_object" + JSON_SCHEMA = "json_schema" + TEXT = "text" - class azure.ai.projects.models.ModelSamplingParams(_Model): - max_completion_tokens: Optional[int] - seed: Optional[int] - temperature: Optional[float] - top_p: Optional[float] + class azure.ai.projects.models.TextResponseFormatJsonObject(TextResponseFormat, discriminator='json_object'): + type: Literal[TextResponseFormatConfigurationType.JSON_OBJECT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.TextResponseFormatJsonSchema(TextResponseFormat, discriminator='json_schema'): + description: Optional[str] + name: str + schema: dict[str, Any] + strict: Optional[bool] + type: Literal[TextResponseFormatConfigurationType.JSON_SCHEMA] @overload def __init__( self, *, - max_completion_tokens: Optional[int] = ..., - seed: Optional[int] = ..., - temperature: Optional[float] = ..., - top_p: Optional[float] = ... + description: Optional[str] = ..., + name: str, + schema: dict[str, Any], + strict: Optional[bool] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelSourceData(_Model): - job_id: Optional[str] - source_type: Optional[Union[str, FoundryModelSourceType]] + class azure.ai.projects.models.TextResponseFormatText(TextResponseFormat, discriminator='text'): + type: Literal[TextResponseFormatConfigurationType.TEXT] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.TimerRoutineTrigger(RoutineTrigger, discriminator='timer'): + at: Optional[datetime] + type: Literal[RoutineTriggerType.TIMER] @overload def __init__( self, *, - job_id: Optional[str] = ..., - source_type: Optional[Union[str, FoundryModelSourceType]] = ... + at: Optional[datetime] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ModelVersion(_Model): - artifact_profile: Optional[ArtifactProfile] - base_model: Optional[str] - blob_uri: str - description: Optional[str] - id: Optional[str] - lora_config: Optional[LoraConfig] - name: str - source: Optional[ModelSourceData] - tags: Optional[dict[str, str]] - version: str - warnings: Optional[list[FoundryModelWarning]] - weight_type: Optional[Union[str, FoundryModelWeightType]] + class azure.ai.projects.models.Tool(_Model): + type: str @overload def __init__( self, *, - base_model: Optional[str] = ..., - blob_uri: str, - description: Optional[str] = ..., - lora_config: Optional[LoraConfig] = ..., - source: Optional[ModelSourceData] = ..., - tags: Optional[dict[str, str]] = ..., - weight_type: Optional[Union[str, FoundryModelWeightType]] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.MonthlyRecurrenceSchedule(RecurrenceSchedule, discriminator='Monthly'): - days_of_month: list[int] - type: Literal[RecurrenceType.MONTHLY] + class azure.ai.projects.models.ToolChoiceAllowed(ToolChoiceParam, discriminator='allowed_tools'): + mode: Literal["auto", "required"] + tools: list[dict[str, Any]] + type: Literal[ToolChoiceParamType.ALLOWED_TOOLS] @overload def __init__( self, *, - days_of_month: list[int] + mode: Literal["auto", "required"], + tools: list[dict[str, Any]] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.NamespaceToolParam(Tool, discriminator='namespace'): - description: str - name: str - tools: list[Union[FunctionToolParam, CustomToolParam]] - type: Literal[ToolType.NAMESPACE] + class azure.ai.projects.models.ToolChoiceCodeInterpreter(ToolChoiceParam, discriminator='code_interpreter'): + type: Literal[ToolChoiceParamType.CODE_INTERPRETER] @overload - def __init__( - self, - *, - description: str, - name: str, - tools: list[Union[FunctionToolParam, CustomToolParam]] - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.NoAuthenticationCredentials(BaseCredentials, discriminator='None'): - type: Literal[CredentialType.NONE] + class azure.ai.projects.models.ToolChoiceComputer(ToolChoiceParam, discriminator='computer'): + type: Literal[ToolChoiceParamType.COMPUTER] @overload def __init__(self) -> None: ... @@ -8142,25 +13264,18 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OneTimeTrigger(Trigger, discriminator='OneTime'): - time_zone: Optional[str] - trigger_at: datetime - type: Literal[TriggerType.ONE_TIME] + class azure.ai.projects.models.ToolChoiceComputerUse(ToolChoiceParam, discriminator='computer_use'): + type: Literal[ToolChoiceParamType.COMPUTER_USE] @overload - def __init__( - self, - *, - time_zone: Optional[str] = ..., - trigger_at: datetime - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiAnonymousAuthDetails(OpenApiAuthDetails, discriminator='anonymous'): - type: Literal[OpenApiAuthType.ANONYMOUS] + class azure.ai.projects.models.ToolChoiceComputerUsePreview(ToolChoiceParam, discriminator='computer_use_preview'): + type: Literal[ToolChoiceParamType.COMPUTER_USE_PREVIEW] @overload def __init__(self) -> None: ... @@ -8169,2055 +13284,2425 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiAuthDetails(_Model): - type: str + class azure.ai.projects.models.ToolChoiceCustom(ToolChoiceParam, discriminator='custom'): + name: str + type: Literal[ToolChoiceParamType.CUSTOM] @overload def __init__( self, *, - type: str + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiAuthType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ANONYMOUS = "anonymous" - MANAGED_IDENTITY = "managed_identity" - PROJECT_CONNECTION = "project_connection" + class azure.ai.projects.models.ToolChoiceFileSearch(ToolChoiceParam, discriminator='file_search'): + type: Literal[ToolChoiceParamType.FILE_SEARCH] + @overload + def __init__(self) -> None: ... - class azure.ai.projects.models.OpenApiFunctionDefinition(_Model): - auth: OpenApiAuthDetails - default_params: Optional[list[str]] - description: Optional[str] - functions: Optional[list[OpenApiFunctionDefinitionFunction]] + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ToolChoiceFunction(ToolChoiceParam, discriminator='function'): name: str - spec: dict[str, Any] + type: Literal[ToolChoiceParamType.FUNCTION] @overload def __init__( self, *, - auth: OpenApiAuthDetails, - default_params: Optional[list[str]] = ..., - description: Optional[str] = ..., - name: str, - spec: dict[str, Any] + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiFunctionDefinitionFunction(_Model): - description: Optional[str] - name: str - parameters: dict[str, Any] + class azure.ai.projects.models.ToolChoiceImageGeneration(ToolChoiceParam, discriminator='image_generation'): + type: Literal[ToolChoiceParamType.IMAGE_GENERATION] @overload - def __init__( - self, - *, - description: Optional[str] = ..., - name: str, - parameters: dict[str, Any] - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiManagedAuthDetails(OpenApiAuthDetails, discriminator='managed_identity'): - security_scheme: OpenApiManagedSecurityScheme - type: Literal[OpenApiAuthType.MANAGED_IDENTITY] + class azure.ai.projects.models.ToolChoiceMCP(ToolChoiceParam, discriminator='mcp'): + name: Optional[str] + server_label: str + type: Literal[ToolChoiceParamType.MCP] @overload def __init__( self, *, - security_scheme: OpenApiManagedSecurityScheme + name: Optional[str] = ..., + server_label: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiManagedSecurityScheme(_Model): - audience: str + class azure.ai.projects.models.ToolChoiceOptions(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AUTO = "auto" + NONE = "none" + REQUIRED = "required" + + + class azure.ai.projects.models.ToolChoiceParam(_Model): + type: str @overload def __init__( self, *, - audience: str + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiProjectConnectionAuthDetails(OpenApiAuthDetails, discriminator='project_connection'): - security_scheme: OpenApiProjectConnectionSecurityScheme - type: Literal[OpenApiAuthType.PROJECT_CONNECTION] + class azure.ai.projects.models.ToolChoiceParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ALLOWED_TOOLS = "allowed_tools" + APPLY_PATCH = "apply_patch" + CODE_INTERPRETER = "code_interpreter" + COMPUTER = "computer" + COMPUTER_USE = "computer_use" + COMPUTER_USE_PREVIEW = "computer_use_preview" + CUSTOM = "custom" + FILE_SEARCH = "file_search" + FUNCTION = "function" + IMAGE_GENERATION = "image_generation" + MCP = "mcp" + PROGRAMMATIC_TOOL_CALLING = "programmatic_tool_calling" + SHELL = "shell" + WEB_SEARCH_PREVIEW = "web_search_preview" + WEB_SEARCH_PREVIEW_2025_03_11 = "web_search_preview_2025_03_11" + + + class azure.ai.projects.models.ToolChoiceWebSearchPreview(ToolChoiceParam, discriminator='web_search_preview'): + type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW] @overload - def __init__( - self, - *, - security_scheme: OpenApiProjectConnectionSecurityScheme - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiProjectConnectionSecurityScheme(_Model): - project_connection_id: str + class azure.ai.projects.models.ToolChoiceWebSearchPreview20250311(ToolChoiceParam, discriminator='web_search_preview_2025_03_11'): + type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11] + + @overload + def __init__(self) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.ai.projects.models.ToolConfig(_Model): + additional_search_text: Optional[str] + pin: Optional[bool] @overload def __init__( self, *, - project_connection_id: str + additional_search_text: Optional[str] = ..., + pin: Optional[bool] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiTool(Tool, discriminator='openapi'): - openapi: OpenApiFunctionDefinition - tool_configs: Optional[dict[str, ToolConfig]] - type: Literal[ToolType.OPENAPI] + class azure.ai.projects.models.ToolDescription(_Model): + description: Optional[str] + name: Optional[str] @overload def __init__( self, *, - openapi: OpenApiFunctionDefinition, - tool_configs: Optional[dict[str, ToolConfig]] = ... + description: Optional[str] = ..., + name: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OpenApiToolboxTool(ToolboxTool, discriminator='openapi'): - description: str - name: str - openapi: OpenApiFunctionDefinition - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.OPENAPI] + class azure.ai.projects.models.ToolDescriptionParam(TypedDict, total=False): + key "description": str + key "name": str + + + class azure.ai.projects.models.ToolProjectConnection(_Model): + project_connection_id: str @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - openapi: OpenApiFunctionDefinition, - tool_configs: Optional[dict[str, ToolConfig]] = ... + project_connection_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.OperationState(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CANCELED = "Canceled" - FAILED = "Failed" - NOT_STARTED = "NotStarted" - RUNNING = "Running" - SUCCEEDED = "Succeeded" + class azure.ai.projects.models.ToolSearchExecutionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CLIENT = "client" + SERVER = "server" - class azure.ai.projects.models.OptimizedAgentIdentifier(_Model): - agent_name: str - agent_version: Optional[str] + class azure.ai.projects.models.ToolSearchToolParam(Tool, discriminator='tool_search'): + description: Optional[str] + execution: Optional[Union[str, ToolSearchExecutionType]] + parameters: Optional[EmptyModelParam] + type: Literal[ToolType.TOOL_SEARCH] @overload def __init__( self, *, - agent_name: str, - agent_version: Optional[str] = ... + description: Optional[str] = ..., + execution: Optional[Union[str, ToolSearchExecutionType]] = ..., + parameters: Optional[EmptyModelParam] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - - class azure.ai.projects.models.OtlpTelemetryEndpoint(TelemetryEndpoint, discriminator='OTLP'): - auth: TelemetryEndpointAuth - data: Union[list[str, TelemetryDataKind]] - endpoint: str - kind: Literal[TelemetryEndpointKind.OTLP] - protocol: Union[str, TelemetryTransportProtocol] - + + class azure.ai.projects.models.ToolSearchToolboxTool(ToolboxTool, discriminator='toolbox_search'): + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.TOOLBOX_SEARCH] + @overload def __init__( self, *, - auth: Optional[TelemetryEndpointAuth] = ..., - data: list[Union[str, TelemetryDataKind]], - endpoint: str, - protocol: Union[str, TelemetryTransportProtocol] + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PageOrder(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ASC = "asc" - DESC = "desc" + class azure.ai.projects.models.ToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + A2A_PREVIEW = "a2a_preview" + A2_A = "a2a" + APPLY_PATCH = "apply_patch" + AZURE_AI_SEARCH = "azure_ai_search" + AZURE_FUNCTION = "azure_function" + BING_CUSTOM_SEARCH_PREVIEW = "bing_custom_search_preview" + BING_GROUNDING = "bing_grounding" + BROWSER_AUTOMATION = "browser_automation" + BROWSER_AUTOMATION_PREVIEW = "browser_automation_preview" + CAPTURE_STRUCTURED_OUTPUTS = "capture_structured_outputs" + CODE_INTERPRETER = "code_interpreter" + COMPUTER = "computer" + COMPUTER_USE_PREVIEW = "computer_use_preview" + CUSTOM = "custom" + FABRIC_DATAAGENT_PREVIEW = "fabric_dataagent_preview" + FABRIC_IQ_PREVIEW = "fabric_iq_preview" + FILE_SEARCH = "file_search" + FUNCTION = "function" + GITHUB_COPILOT_TOOLSET_PREVIEW = "github_copilot_toolset_preview" + IMAGE_GENERATION = "image_generation" + LOCAL_SHELL = "local_shell" + MCP = "mcp" + MEMORY_SEARCH_PREVIEW = "memory_search_preview" + NAMESPACE = "namespace" + OPENAPI = "openapi" + PROGRAMMATIC_TOOL_CALLING = "programmatic_tool_calling" + SHAREPOINT_GROUNDING_PREVIEW = "sharepoint_grounding_preview" + SHELL = "shell" + TOOLBOX_SEARCH_PREVIEW = "toolbox_search_preview" + TOOL_SEARCH = "tool_search" + WEB_IQ_PREVIEW = "web_iq_preview" + WEB_SEARCH = "web_search" + WEB_SEARCH_PREVIEW = "web_search_preview" + WORK_IQ_PREVIEW = "work_iq_preview" - class azure.ai.projects.models.PendingUploadRequest(_Model): - connection_name: Optional[str] - pending_upload_id: Optional[str] - pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] + class azure.ai.projects.models.ToolUseFineTuningDataGenerationJobOptions(DataGenerationJobOptions, discriminator='tool_use'): + max_samples: int + model_options: DataGenerationModelOptions + train_split: float + type: Literal[DataGenerationJobType.TOOL_USE] @overload def __init__( self, *, - connection_name: Optional[str] = ..., - pending_upload_id: Optional[str] = ..., - pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] + max_samples: int, + model_options: Optional[DataGenerationModelOptions] = ..., + train_split: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PendingUploadResponse(_Model): - blob_reference: BlobReference - pending_upload_id: str - pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE] - version: Optional[str] + class azure.ai.projects.models.ToolboxObject(_Model): + default_version: str + id: str + name: str + updated_at: datetime + versions: ToolboxVersions @overload def __init__( self, *, - blob_reference: BlobReference, - pending_upload_id: str, - pending_upload_type: Literal[PendingUploadType.BLOB_REFERENCE], - version: Optional[str] = ... + default_version: str, + id: str, + name: str, + updated_at: datetime, + versions: ToolboxVersions ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PendingUploadType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - BLOB_REFERENCE = "BlobReference" - NONE = "None" - TEMPORARY_BLOB_REFERENCE = "TemporaryBlobReference" - - - class azure.ai.projects.models.ProceduralMemoryItem(MemoryItem, discriminator='procedural'): - content: str - kind: Literal[MemoryItemKind.PROCEDURAL] - memory_id: str - scope: str - updated_at: datetime + class azure.ai.projects.models.ToolboxPolicies(_Model): + rai_config: Optional[RaiConfig] @overload def __init__( self, *, - content: str, - memory_id: str, - scope: str, - updated_at: datetime + rai_config: Optional[RaiConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ProgrammaticToolCallingParam(Tool, discriminator='programmatic_tool_calling'): - type: Literal[ToolType.PROGRAMMATIC_TOOL_CALLING] + class azure.ai.projects.models.ToolboxSearchPreviewToolboxTool(ToolboxTool, discriminator='toolbox_search_preview'): + description: str + name: str + tool_configs: dict[str, ToolConfig] + type: Literal[ToolboxToolType.TOOLBOX_SEARCH_PREVIEW] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromotionInfo(_Model): - agent_name: str - agent_version: str - promoted_at: datetime + class azure.ai.projects.models.ToolboxShellContainerAutoEnvironment(ToolboxShellEnvironment, discriminator='container_auto'): + file_ids: Optional[list[str]] + memory_limit: Optional[Union[str, ContainerMemoryLimit]] + network_policy: Optional[ToolboxShellNetworkPolicy] + skills: Optional[list[ContainerSkill]] + type: Literal["container_auto"] @overload def __init__( self, *, - agent_name: str, - agent_version: str, - promoted_at: datetime + file_ids: Optional[list[str]] = ..., + memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., + network_policy: Optional[ToolboxShellNetworkPolicy] = ..., + skills: Optional[list[ContainerSkill]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromptAgentDefinition(AgentDefinition, discriminator='prompt'): - instructions: Optional[str] - kind: Literal[AgentKind.PROMPT] - model: str - rai_config: RaiConfig - reasoning: Optional[Reasoning] - structured_inputs: Optional[dict[str, StructuredInputDefinition]] - temperature: Optional[float] - text: Optional[PromptAgentDefinitionTextOptions] - tool_choice: Optional[Union[str, ToolChoiceParam]] - tools: Optional[list[Tool]] - top_p: Optional[float] + class azure.ai.projects.models.ToolboxShellContainerReferenceEnvironment(ToolboxShellEnvironment, discriminator='container_reference'): + container_id: str + type: Literal["container_reference"] @overload def __init__( self, *, - instructions: Optional[str] = ..., - model: str, - rai_config: Optional[RaiConfig] = ..., - reasoning: Optional[Reasoning] = ..., - structured_inputs: Optional[dict[str, StructuredInputDefinition]] = ..., - temperature: Optional[float] = ..., - text: Optional[PromptAgentDefinitionTextOptions] = ..., - tool_choice: Optional[Union[str, ToolChoiceParam]] = ..., - tools: Optional[list[Tool]] = ..., - top_p: Optional[float] = ... + container_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromptAgentDefinitionTextOptions(_Model): - format: Optional[TextResponseFormat] + class azure.ai.projects.models.ToolboxShellEnvironment(_Model): + type: str @overload def __init__( self, *, - format: Optional[TextResponseFormat] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromptBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='prompt'): - data_schema: dict[str, any] - init_parameters: dict[str, any] - metrics: dict[str, EvaluatorMetric] - prompt_text: str - type: Literal[EvaluatorDefinitionType.PROMPT] + class azure.ai.projects.models.ToolboxShellNetworkPolicy(_Model): + type: str @overload def __init__( self, *, - data_schema: Optional[dict[str, Any]] = ..., - init_parameters: Optional[dict[str, Any]] = ..., - metrics: Optional[dict[str, EvaluatorMetric]] = ..., - prompt_text: str + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromptDataGenerationJobSource(DataGenerationJobSource, discriminator='prompt'): - description: str - prompt: str - type: Literal[DataGenerationJobSourceType.PROMPT] + class azure.ai.projects.models.ToolboxShellNetworkPolicyDisabled(ToolboxShellNetworkPolicy, discriminator='disabled'): + type: Literal["disabled"] @overload - def __init__( - self, - *, - description: Optional[str] = ..., - prompt: str - ) -> None: ... + def __init__(self) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PromptEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='prompt'): - description: Optional[str] - prompt: str - type: Literal[EvaluatorGenerationJobSourceType.PROMPT] + class azure.ai.projects.models.ToolboxSkill(_Model): + type: str @overload def __init__( self, *, - description: Optional[str] = ..., - prompt: str + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ProtocolConfiguration(_Model): - a2a: Optional[A2AProtocolConfiguration] - activity: Optional[ActivityProtocolConfiguration] - invocations: Optional[InvocationsProtocolConfiguration] - invocations_ws: Optional[InvocationsWsProtocolConfiguration] - mcp: Optional[McpProtocolConfiguration] - responses: Optional[ResponsesProtocolConfiguration] + class azure.ai.projects.models.ToolboxSkillReference(ToolboxSkill, discriminator='skill_reference'): + name: str + type: Literal["skill_reference"] + version: Optional[str] @overload def __init__( self, *, - a2a: Optional[A2AProtocolConfiguration] = ..., - activity: Optional[ActivityProtocolConfiguration] = ..., - invocations: Optional[InvocationsProtocolConfiguration] = ..., - invocations_ws: Optional[InvocationsWsProtocolConfiguration] = ..., - mcp: Optional[McpProtocolConfiguration] = ..., - responses: Optional[ResponsesProtocolConfiguration] = ... + name: str, + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ProtocolVersionRecord(_Model): - protocol: Union[str, AgentEndpointProtocol] - version: str + class azure.ai.projects.models.ToolboxTool(_Model): + description: Optional[str] + name: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: str @overload def __init__( self, *, - protocol: Union[str, AgentEndpointProtocol], - version: str + description: Optional[str] = ..., + name: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.PublishApprovalStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - APPROVED = "approved" - NOT_PUBLISHED = "not_published" - NO_APPROVAL_NEEDED = "no_approval_needed" - PENDING = "pending" - REJECTED = "rejected" + class azure.ai.projects.models.ToolboxToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + A2A_PREVIEW = "a2a_preview" + A2_A = "a2a" + AZURE_AI_SEARCH = "azure_ai_search" + BROWSER_AUTOMATION_PREVIEW = "browser_automation_preview" + CODE_INTERPRETER = "code_interpreter" + FABRIC_IQ_PREVIEW = "fabric_iq_preview" + FILE_SEARCH = "file_search" + MCP = "mcp" + OPENAPI = "openapi" + REMINDER_PREVIEW = "reminder_preview" + SHELL = "shell" + TOOLBOX_SEARCH = "toolbox_search" + TOOLBOX_SEARCH_PREVIEW = "toolbox_search_preview" + WEB_IQ_PREVIEW = "web_iq_preview" + WEB_SEARCH = "web_search" + WORK_IQ_PREVIEW = "work_iq_preview" - class azure.ai.projects.models.RaiConfig(_Model): - rai_policy_name: str + class azure.ai.projects.models.ToolboxVersionObject(_Model): + created_at: datetime + description: Optional[str] + id: str + metadata: dict[str, str] + name: str + policies: Optional[ToolboxPolicies] + skills: Optional[list[ToolboxSkill]] + tools: list[ToolboxTool] + version: str @overload def __init__( self, *, - rai_policy_name: str + created_at: datetime, + description: Optional[str] = ..., + id: str, + metadata: dict[str, str], + name: str, + policies: Optional[ToolboxPolicies] = ..., + skills: Optional[list[ToolboxSkill]] = ..., + tools: list[ToolboxTool], + version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RankerVersionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AUTO = "auto" - DEFAULT_2024_11_15 = "default-2024-11-15" - - - class azure.ai.projects.models.RankingOptions(_Model): - hybrid_search: Optional[HybridSearchOptions] - ranker: Optional[Union[str, RankerVersionType]] - score_threshold: Optional[float] + class azure.ai.projects.models.ToolboxVersions(_Model): + latest: ToolboxVersionObject @overload def __init__( self, *, - hybrid_search: Optional[HybridSearchOptions] = ..., - ranker: Optional[Union[str, RankerVersionType]] = ..., - score_threshold: Optional[float] = ... + latest: ToolboxVersionObject ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Reasoning(_Model): - context: Optional[Literal["auto", "current_turn", "all_turns"]] - effort: Optional[Union[str, ReasoningEffort]] - generate_summary: Optional[Literal["auto", "concise", "detailed"]] - mode: Optional[Union[str, ReasoningModeEnum]] - summary: Optional[Literal["auto", "concise", "detailed"]] + class azure.ai.projects.models.TracesDataGenerationJobOptions(DataGenerationJobOptions, discriminator='traces'): + max_samples: Optional[int] + model_options: DataGenerationModelOptions + redact_private_content: Optional[bool] + train_split: float + type: Literal[DataGenerationJobType.TRACES] @overload def __init__( self, *, - context: Optional[Literal[auto, current_turn, all_turns]] = ..., - effort: Optional[Union[str, ReasoningEffort]] = ..., - generate_summary: Optional[Literal[auto, concise, detailed]] = ..., - mode: Optional[Union[str, ReasoningModeEnum]] = ..., - summary: Optional[Literal[auto, concise, detailed]] = ... + max_samples: Optional[int] = ..., + model_options: Optional[DataGenerationModelOptions] = ..., + redact_private_content: Optional[bool] = ..., + train_split: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ReasoningEffort(str, Enum, metaclass=CaseInsensitiveEnumMeta): - HIGH = "high" - LOW = "low" - MAX = "max" - MEDIUM = "medium" - MINIMAL = "minimal" - NONE = "none" - XHIGH = "xhigh" - - - class azure.ai.projects.models.ReasoningModeEnum(str, Enum, metaclass=CaseInsensitiveEnumMeta): - PRO = "pro" - STANDARD = "standard" - - - class azure.ai.projects.models.RecurrenceSchedule(_Model): - type: str + class azure.ai.projects.models.TracesDataGenerationJobSource(DataGenerationJobSource, discriminator='traces'): + agent_id: Optional[str] + agent_name: Optional[str] + agent_version: Optional[str] + description: str + end_time: Optional[datetime] + start_time: datetime + trace_ids: Optional[list[str]] + type: Literal[DataGenerationJobSourceType.TRACES] @overload def __init__( self, *, - type: str + agent_id: Optional[str] = ..., + agent_name: Optional[str] = ..., + agent_version: Optional[str] = ..., + description: Optional[str] = ..., + end_time: Optional[datetime] = ..., + start_time: datetime, + trace_ids: Optional[list[str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RecurrenceTrigger(Trigger, discriminator='Recurrence'): + class azure.ai.projects.models.TracesEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='traces'): + agent_id: Optional[str] + agent_name: Optional[str] + agent_version: Optional[str] + description: Optional[str] end_time: Optional[datetime] - interval: int - schedule: RecurrenceSchedule - start_time: Optional[datetime] - time_zone: Optional[str] - type: Literal[TriggerType.RECURRENCE] + start_time: datetime + type: Literal[EvaluatorGenerationJobSourceType.TRACES] @overload def __init__( self, *, + agent_id: Optional[str] = ..., + agent_name: Optional[str] = ..., + agent_version: Optional[str] = ..., + description: Optional[str] = ..., end_time: Optional[datetime] = ..., - interval: int, - schedule: RecurrenceSchedule, - start_time: Optional[datetime] = ..., - time_zone: Optional[str] = ... + start_time: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RecurrenceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - DAILY = "Daily" - HOURLY = "Hourly" - MONTHLY = "Monthly" - WEEKLY = "Weekly" + class azure.ai.projects.models.TracesPreviewEvalRunDataSource(TypedDict, total=False): + key "agent_id": str + key "agent_name": str + key "end_time": datetime + key "ingestion_delay_seconds": int + key "lookback_hours": int + key "max_traces": int + key "trace_ids": List[str] + key "type": Required[Literal["azure_ai_traces_preview"]] - class azure.ai.projects.models.RedTeam(_Model): - application_scenario: Optional[str] - attack_strategies: Optional[list[Union[str, AttackStrategy]]] - display_name: Optional[str] - name: str - num_turns: Optional[int] - properties: Optional[dict[str, str]] - risk_categories: Optional[list[Union[str, RiskCategory]]] - simulation_only: Optional[bool] - status: Optional[str] - tags: Optional[dict[str, str]] - target: RedTeamTargetConfig + class azure.ai.projects.models.TranscriptTextUsageDuration(CreateTranscriptionResponseJsonUsage, discriminator='duration'): + seconds: timedelta + type: Literal[CreateTranscriptionResponseJsonUsageType.DURATION] @overload def __init__( self, *, - application_scenario: Optional[str] = ..., - attack_strategies: Optional[list[Union[str, AttackStrategy]]] = ..., - display_name: Optional[str] = ..., - num_turns: Optional[int] = ..., - properties: Optional[dict[str, str]] = ..., - risk_categories: Optional[list[Union[str, RiskCategory]]] = ..., - simulation_only: Optional[bool] = ..., - tags: Optional[dict[str, str]] = ..., - target: RedTeamTargetConfig + seconds: timedelta ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RedTeamEvalRunDataSource(TypedDict, total=False): - key "item_generation_params": Required[Any] - key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] - key "type": Required[Literal["azure_ai_red_team"]] - - - class azure.ai.projects.models.RedTeamTargetConfig(_Model): - type: str + class azure.ai.projects.models.TranscriptTextUsageTokens(CreateTranscriptionResponseJsonUsage, discriminator='tokens'): + input_token_details: Optional[TranscriptTextUsageTokensInputTokenDetails] + input_tokens: int + output_tokens: int + total_tokens: int + type: Literal[CreateTranscriptionResponseJsonUsageType.TOKENS] @overload def __init__( self, *, - type: str + input_token_details: Optional[TranscriptTextUsageTokensInputTokenDetails] = ..., + input_tokens: int, + output_tokens: int, + total_tokens: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ReminderPreviewToolboxTool(ToolboxTool, discriminator='reminder_preview'): - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.REMINDER_PREVIEW] + class azure.ai.projects.models.TranscriptTextUsageTokensInputTokenDetails(_Model): + audio_tokens: Optional[int] + text_tokens: Optional[int] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + audio_tokens: Optional[int] = ..., + text_tokens: Optional[int] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ResponseRetrievalItemGenerationParams(TypedDict, total=False): - key "data_mapping": Required[Dict[str, str]] - key "max_num_turns": int - key "source": Required[Union[SourceFileContent, SourceFileID]] - key "type": Required[Literal["response_retrieval"]] - - - class azure.ai.projects.models.ResponseUsageInputTokensDetails(_Model): - cache_write_tokens: int - cached_tokens: int + class azure.ai.projects.models.TranscriptionLanguage(_Model): + code: str @overload def __init__( self, *, - cache_write_tokens: int, - cached_tokens: int + code: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ResponseUsageOutputTokensDetails(_Model): - reasoning_tokens: int + class azure.ai.projects.models.TreatmentEffectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CHANGED = "Changed" + DEGRADED = "Degraded" + IMPROVED = "Improved" + INCONCLUSIVE = "Inconclusive" + TOO_FEW_SAMPLES = "TooFewSamples" + + + class azure.ai.projects.models.Trigger(_Model): + type: str @overload def __init__( self, *, - reasoning_tokens: int + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ResponsesProtocolConfiguration(_Model): - - - class azure.ai.projects.models.RiskCategory(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CODE_VULNERABILITY = "CodeVulnerability" - HATE_UNFAIRNESS = "HateUnfairness" - PROHIBITED_ACTIONS = "ProhibitedActions" - PROTECTED_MATERIAL = "ProtectedMaterial" - SELF_HARM = "SelfHarm" - SENSITIVE_DATA_LEAKAGE = "SensitiveDataLeakage" - SEXUAL = "Sexual" - TASK_ADHERENCE = "TaskAdherence" - UNGROUNDED_ATTRIBUTES = "UngroundedAttributes" - VIOLENCE = "Violence" + class azure.ai.projects.models.TriggerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CRON = "Cron" + ONE_TIME = "OneTime" + RECURRENCE = "Recurrence" - class azure.ai.projects.models.Routine(_Model): - action: Optional[RoutineAction] - created_at: Optional[datetime] - description: Optional[str] - enabled: bool - name: Optional[str] - triggers: Optional[dict[str, RoutineTrigger]] - updated_at: Optional[datetime] + class azure.ai.projects.models.TwilioTelephonyBinding(TelephonyBinding, discriminator='twilio'): + connection_name: str + id: str + incoming_call_url: str + label: str + phone_number: str + provider: Literal[TelephonyProvider.TWILIO] + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - action: Optional[RoutineAction] = ..., - created_at: Optional[datetime] = ..., - description: Optional[str] = ..., - enabled: bool, - name: Optional[str] = ..., - triggers: Optional[dict[str, RoutineTrigger]] = ..., - updated_at: Optional[datetime] = ... + connection_name: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + phone_number: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineAction(_Model): - type: str + class azure.ai.projects.models.TwilioTelephonyBindingListItem(TelephonyBindingListItem, discriminator='twilio'): + connection_name: str + etag: str + id: str + incoming_call_url: str + label: str + phone_number: str + provider: Literal[TelephonyProvider.TWILIO] + status: Union[str, TelephonyBindingStatus] @overload def __init__( self, *, - type: str + connection_name: str, + id: str, + incoming_call_url: str, + label: Optional[str] = ..., + phone_number: str, + status: Union[str, TelephonyBindingStatus] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineActionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INVOKE_AGENT_INVOCATIONS_API = "invoke_agent_invocations_api" - INVOKE_AGENT_RESPONSES_API = "invoke_agent_responses_api" - + class azure.ai.projects.models.UpdateMemoriesLROPoller(LROPoller[MemoryStoreUpdateCompletedResult]): + property superseded_by: Optional[str] # Read-only + property update_id: str # Read-only - class azure.ai.projects.models.RoutineAttemptSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EVENT_FIRE = "event_fire" - MANUAL_DISPATCH = "manual_dispatch" - QUEUED_DISPATCH = "queued_dispatch" - SCHEDULE_DELIVERY = "schedule_delivery" - TIMER_DELIVERY = "timer_delivery" + @classmethod + def from_continuation_token( + cls, + polling_method: PollingMethod[MemoryStoreUpdateCompletedResult], + continuation_token: str, + **kwargs: Any + ) -> UpdateMemoriesLROPoller: ... - class azure.ai.projects.models.RoutineAuthorization(_Model): - identity: Optional[Union[str, RoutineDispatchIdentity]] + class azure.ai.projects.models.UpdateModelVersionRequest(_Model): + description: Optional[str] + tags: Optional[dict[str, str]] @overload def __init__( self, *, - identity: Optional[Union[str, RoutineDispatchIdentity]] = ... + description: Optional[str] = ..., + tags: Optional[dict[str, str]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineDispatchIdentity(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - CREATOR = "creator" - - - class azure.ai.projects.models.RoutineDispatchPayload(_Model): - type: str + class azure.ai.projects.models.UpdateTelephonyBindingRequest(_Model): + connection_name: Optional[str] + label: Optional[str] + phone_number: Optional[str] + status: Optional[Union[str, TelephonyBindingStatus]] @overload def __init__( self, *, - type: str + connection_name: Optional[str] = ..., + label: Optional[str] = ..., + phone_number: Optional[str] = ..., + status: Optional[Union[str, TelephonyBindingStatus]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineDispatchPayloadType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - INVOKE_AGENT_INVOCATIONS_API = "invoke_agent_invocations_api" - INVOKE_AGENT_RESPONSES_API = "invoke_agent_responses_api" - - - class azure.ai.projects.models.RoutineRun(_Model): - action_correlation_id: Optional[str] - action_type: Optional[Union[str, RoutineActionType]] - agent_endpoint_id: Optional[str] - agent_id: Optional[str] - attempt_source: Optional[Union[str, RoutineAttemptSource]] - conversation_id: Optional[str] - dispatch_id: Optional[str] - ended_at: Optional[datetime] - error_message: Optional[str] - error_status_code: Optional[int] - error_type: Optional[str] - id: str - phase: Optional[Union[str, RoutineRunPhase]] - response_id: Optional[str] - scheduled_fire_at: Optional[datetime] - session_id: Optional[str] - started_at: Optional[datetime] - status: Optional[RoutineRunStatus] - task_id: Optional[str] - trigger_event_payload: Optional[dict[str, Any]] - trigger_name: Optional[str] - trigger_type: Optional[Union[str, RoutineTriggerType]] - triggered_at: Optional[datetime] + class azure.ai.projects.models.UpdateToolboxRequest(_Model): + default_version: str @overload def __init__( self, *, - action_correlation_id: Optional[str] = ..., - action_type: Optional[Union[str, RoutineActionType]] = ..., - agent_endpoint_id: Optional[str] = ..., - agent_id: Optional[str] = ..., - attempt_source: Optional[Union[str, RoutineAttemptSource]] = ..., - conversation_id: Optional[str] = ..., - dispatch_id: Optional[str] = ..., - ended_at: Optional[datetime] = ..., - error_message: Optional[str] = ..., - error_status_code: Optional[int] = ..., - error_type: Optional[str] = ..., - phase: Optional[Union[str, RoutineRunPhase]] = ..., - response_id: Optional[str] = ..., - scheduled_fire_at: Optional[datetime] = ..., - session_id: Optional[str] = ..., - started_at: Optional[datetime] = ..., - status: Optional[RoutineRunStatus] = ..., - task_id: Optional[str] = ..., - trigger_event_payload: Optional[dict[str, Any]] = ..., - trigger_name: Optional[str] = ..., - trigger_type: Optional[Union[str, RoutineTriggerType]] = ..., - triggered_at: Optional[datetime] = ... + default_version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineRunPhase(str, Enum, metaclass=CaseInsensitiveEnumMeta): - COMPLETED = "completed" - DISPATCHING = "dispatching" - FAILED = "failed" - QUEUED = "queued" - - - class azure.ai.projects.models.RoutineTrigger(_Model): - type: str + class azure.ai.projects.models.UserProfileMemoryItem(MemoryItem, discriminator='user_profile'): + content: str + kind: Literal[MemoryItemKind.USER_PROFILE] + memory_id: str + scope: str + updated_at: datetime @overload def __init__( self, *, - type: str + content: str, + memory_id: str, + scope: str, + updated_at: datetime ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RoutineTriggerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CUSTOM = "custom" - GITHUB_ISSUE = "github_issue" - SCHEDULE = "schedule" - TIMER = "timer" - - - class azure.ai.projects.models.RubricBasedEvaluatorDefinition(EvaluatorDefinition, discriminator='rubric'): - data_schema: dict[str, any] - dimensions: list[Dimension] - init_parameters: dict[str, any] - metrics: dict[str, EvaluatorMetric] - pass_threshold: Optional[float] - type: Literal[EvaluatorDefinitionType.RUBRIC] + class azure.ai.projects.models.VersionIndicator(_Model): + type: str @overload def __init__( self, *, - data_schema: Optional[dict[str, Any]] = ..., - dimensions: list[Dimension], - init_parameters: Optional[dict[str, Any]] = ..., - metrics: Optional[dict[str, EvaluatorMetric]] = ..., - pass_threshold: Optional[float] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RubricGenerationInputQualityWarning(_Model): - code: Union[str, RubricGenerationInputQualityWarningCode] - message: str - severity: Union[str, RubricGenerationInputQualityWarningSeverity] - source: Union[str, RubricGenerationInputQualityWarningSource] - source_index: Optional[int] + class azure.ai.projects.models.VersionIndicatorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + VERSION_REF = "version_ref" + + + class azure.ai.projects.models.VersionRefIndicator(VersionIndicator, discriminator='version_ref'): + agent_version: str + type: Literal[VersionIndicatorType.VERSION_REF] @overload def __init__( self, *, - code: Union[str, RubricGenerationInputQualityWarningCode], - message: str, - severity: Union[str, RubricGenerationInputQualityWarningSeverity], - source: Union[str, RubricGenerationInputQualityWarningSource], - source_index: Optional[int] = ... + agent_version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.RubricGenerationInputQualityWarningCode(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EMPTY_AGENT_INSTRUCTIONS = "empty_agent_instructions" - EMPTY_DATASET_CONTENT = "empty_dataset_content" - EMPTY_PROMPT = "empty_prompt" - INSUFFICIENT_TOTAL_INPUT = "insufficient_total_input" - LOW_TRACE_COUNT = "low_trace_count" - SHORT_AGENT_INSTRUCTIONS = "short_agent_instructions" - SHORT_DATASET_CONTENT = "short_dataset_content" - SHORT_PROMPT = "short_prompt" - - - class azure.ai.projects.models.RubricGenerationInputQualityWarningSeverity(str, Enum, metaclass=CaseInsensitiveEnumMeta): - WARNING = "warning" - - - class azure.ai.projects.models.RubricGenerationInputQualityWarningSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): - AGENT = "agent" - AGGREGATE = "aggregate" - DATASET = "dataset" - PROMPT = "prompt" - - - class azure.ai.projects.models.SASCredentials(BaseCredentials, discriminator='SAS'): - sas_token: Optional[str] - type: Literal[CredentialType.SAS] + class azure.ai.projects.models.VersionSelectionRule(_Model): + agent_version: str + type: str @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + agent_version: str, + type: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SampleType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EVALUATION_RESULT_SAMPLE = "EvaluationResultSample" - - - class azure.ai.projects.models.Schedule(_Model): - description: Optional[str] - display_name: Optional[str] - enabled: bool - properties: Optional[dict[str, str]] - provisioning_status: Optional[Union[str, ScheduleProvisioningStatus]] - schedule_id: str - system_data: dict[str, str] - tags: Optional[dict[str, str]] - task: ScheduleTask - trigger: Trigger + class azure.ai.projects.models.VersionSelector(_Model): + version_selection_rules: list[VersionSelectionRule] @overload def __init__( self, *, - description: Optional[str] = ..., - display_name: Optional[str] = ..., - enabled: bool, - properties: Optional[dict[str, str]] = ..., - tags: Optional[dict[str, str]] = ..., - task: ScheduleTask, - trigger: Trigger + version_selection_rules: list[VersionSelectionRule] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ScheduleProvisioningStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CREATING = "Creating" - DELETING = "Deleting" - FAILED = "Failed" - SUCCEEDED = "Succeeded" - UPDATING = "Updating" + class azure.ai.projects.models.VersionSelectorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FIXED_RATIO = "FixedRatio" - class azure.ai.projects.models.ScheduleRoutineTrigger(RoutineTrigger, discriminator='schedule'): - cron_expression: str - time_zone: str - type: Literal[RoutineTriggerType.SCHEDULE] + class azure.ai.projects.models.VoiceAgentAnimationConfig(_Model): + model_name: Optional[str] + outputs: Optional[list[Union[str, VoiceAgentAnimationOutputType]]] @overload def __init__( self, *, - cron_expression: str, - time_zone: str + model_name: Optional[str] = ..., + outputs: Optional[list[Union[str, VoiceAgentAnimationOutputType]]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ScheduleRun(_Model): - error: Optional[str] - properties: dict[str, str] - run_id: str - schedule_id: str - success: bool - trigger_time: Optional[datetime] + class azure.ai.projects.models.VoiceAgentAnimationOutputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + BLENDSHAPES = "blendshapes" + VISEME_ID = "viseme_id" + + + class azure.ai.projects.models.VoiceAgentAudioConfig(_Model): + input: Optional[VoiceAgentAudioInputConfig] + output: Optional[VoiceAgentAudioOutputConfig] @overload def __init__( self, *, - schedule_id: str, - trigger_time: Optional[datetime] = ... + input: Optional[VoiceAgentAudioInputConfig] = ..., + output: Optional[VoiceAgentAudioOutputConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ScheduleTask(_Model): - configuration: Optional[dict[str, str]] - type: str + class azure.ai.projects.models.VoiceAgentAudioInputConfig(_Model): + echo_cancellation: Optional[VoiceAgentEchoCancellation] + format: Optional[RealtimeAudioFormats] + noise_reduction: Optional[VoiceAgentNoiseReduction] + transcription: Optional[VoiceAgentInputTranscription] + turn_detection: Optional[VoiceAgentTurnDetectionConfig] @overload def __init__( self, *, - configuration: Optional[dict[str, str]] = ..., - type: str + echo_cancellation: Optional[VoiceAgentEchoCancellation] = ..., + format: Optional[RealtimeAudioFormats] = ..., + noise_reduction: Optional[VoiceAgentNoiseReduction] = ..., + transcription: Optional[VoiceAgentInputTranscription] = ..., + turn_detection: Optional[VoiceAgentTurnDetectionConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ScheduleTaskType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - EVALUATION = "Evaluation" - INSIGHT = "Insight" - - - class azure.ai.projects.models.SearchContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - IMAGE = "image" - TEXT = "text" - - - class azure.ai.projects.models.SearchContextSize(str, Enum, metaclass=CaseInsensitiveEnumMeta): - HIGH = "high" - LOW = "low" - MEDIUM = "medium" - - - class azure.ai.projects.models.SessionConfiguration(_Model): - idle_timeout_seconds: Optional[timedelta] + class azure.ai.projects.models.VoiceAgentAudioOutputConfig(_Model): + custom_lexicon_url: Optional[str] + custom_text_normalization_url: Optional[str] + custom_voice_endpoint_id: Optional[str] + format: Optional[RealtimeAudioFormats] + output_audio_timestamp_types: Optional[list[Union[str, VoiceAgentAudioTimestampType]]] + personal_voice_model: Optional[str] + pitch: Optional[str] + prefer_locales: Optional[list[str]] + speed: Optional[float] + style: Optional[str] + voice: Optional[str] + voice_locale: Optional[str] + voice_temperature: Optional[float] + voice_type: Optional[Union[str, VoiceType]] + volume: Optional[str] @overload def __init__( self, *, - idle_timeout_seconds: Optional[timedelta] = ... + custom_lexicon_url: Optional[str] = ..., + custom_text_normalization_url: Optional[str] = ..., + custom_voice_endpoint_id: Optional[str] = ..., + format: Optional[RealtimeAudioFormats] = ..., + output_audio_timestamp_types: Optional[list[Union[str, VoiceAgentAudioTimestampType]]] = ..., + personal_voice_model: Optional[str] = ..., + pitch: Optional[str] = ..., + prefer_locales: Optional[list[str]] = ..., + speed: Optional[float] = ..., + style: Optional[str] = ..., + voice: Optional[str] = ..., + voice_locale: Optional[str] = ..., + voice_temperature: Optional[float] = ..., + voice_type: Optional[Union[str, VoiceType]] = ..., + volume: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SessionDirectoryEntry(_Model): - is_directory: bool - modified_time: datetime - name: str - size: int + class azure.ai.projects.models.VoiceAgentAudioTimestampType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + WORD = "word" + + + class azure.ai.projects.models.VoiceAgentAvatarConfig(_Model): + character: str + customized: Optional[bool] + model: Optional[str] + output_audit_audio: Optional[bool] + output_protocol: Optional[Union[str, VoiceAgentAvatarOutputProtocol]] + scene: Optional[VoiceAgentAvatarScene] + style: Optional[str] + type: Union[str, VoiceAgentAvatarType] + video: Optional[VoiceAgentAvatarVideoParams] @overload def __init__( self, *, - is_directory: bool, - modified_time: datetime, - name: str, - size: int + character: str, + customized: Optional[bool] = ..., + model: Optional[str] = ..., + output_audit_audio: Optional[bool] = ..., + output_protocol: Optional[Union[str, VoiceAgentAvatarOutputProtocol]] = ..., + scene: Optional[VoiceAgentAvatarScene] = ..., + style: Optional[str] = ..., + type: Union[str, VoiceAgentAvatarType], + video: Optional[VoiceAgentAvatarVideoParams] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SessionFileWriteResult(_Model): - bytes_written: int - path: str + class azure.ai.projects.models.VoiceAgentAvatarIceServer(_Model): + credential: Optional[str] + urls: list[str] + username: Optional[str] @overload def __init__( self, *, - bytes_written: int, - path: str + credential: Optional[str] = ..., + urls: list[str], + username: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SessionLogEvent(_Model): - data: str - event: Union[str, SessionLogEventType] + class azure.ai.projects.models.VoiceAgentAvatarOutputProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): + WEBRTC = "webrtc" + WEBSOCKET = "websocket" + + + class azure.ai.projects.models.VoiceAgentAvatarScene(_Model): + amplitude: Optional[float] + position_x: Optional[float] + position_y: Optional[float] + rotation_x: Optional[float] + rotation_y: Optional[float] + rotation_z: Optional[float] + zoom: Optional[float] @overload def __init__( self, *, - data: str, - event: Union[str, SessionLogEventType] + amplitude: Optional[float] = ..., + position_x: Optional[float] = ..., + position_y: Optional[float] = ..., + rotation_x: Optional[float] = ..., + rotation_y: Optional[float] = ..., + rotation_z: Optional[float] = ..., + zoom: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SessionLogEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - LOG = "log" + class azure.ai.projects.models.VoiceAgentAvatarType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PHOTO_AVATAR = "photo_avatar" + VIDEO_AVATAR = "video_avatar" - class azure.ai.projects.models.SharepointGroundingToolParameters(_Model): - project_connections: Optional[list[ToolProjectConnection]] + class azure.ai.projects.models.VoiceAgentAvatarVideoBackground(_Model): + color: Optional[str] + image_url: Optional[str] @overload def __init__( self, *, - project_connections: Optional[list[ToolProjectConnection]] = ... + color: Optional[str] = ..., + image_url: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SharepointPreviewTool(Tool, discriminator='sharepoint_grounding_preview'): - sharepoint_grounding_preview: SharepointGroundingToolParameters - type: Literal[ToolType.SHAREPOINT_GROUNDING_PREVIEW] + class azure.ai.projects.models.VoiceAgentAvatarVideoCrop(_Model): + bottom_right: list[int] + top_left: list[int] @overload def __init__( self, *, - sharepoint_grounding_preview: SharepointGroundingToolParameters + bottom_right: list[int], + top_left: list[int] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ShellToolboxTool(ToolboxTool, discriminator='shell'): - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] - description: str - environment: ToolboxShellEnvironment - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.SHELL] + class azure.ai.projects.models.VoiceAgentAvatarVideoParams(_Model): + background: Optional[VoiceAgentAvatarVideoBackground] + bitrate: Optional[int] + crop: Optional[VoiceAgentAvatarVideoCrop] + gop_size: Optional[int] + resolution: Optional[VoiceAgentAvatarVideoResolution] @overload def __init__( self, *, - allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., - description: Optional[str] = ..., - environment: ToolboxShellEnvironment, - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + background: Optional[VoiceAgentAvatarVideoBackground] = ..., + bitrate: Optional[int] = ..., + crop: Optional[VoiceAgentAvatarVideoCrop] = ..., + gop_size: Optional[int] = ..., + resolution: Optional[VoiceAgentAvatarVideoResolution] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SimpleQnADataGenerationJobOptions(DataGenerationJobOptions, discriminator='simple_qna'): - max_samples: int - model_options: DataGenerationModelOptions - question_types: Optional[list[Union[str, SimpleQnAFineTuningQuestionType]]] - train_split: float - type: Literal[DataGenerationJobType.SIMPLE_QNA] + class azure.ai.projects.models.VoiceAgentAvatarVideoResolution(_Model): + height: int + width: int @overload def __init__( self, *, - max_samples: int, - model_options: Optional[DataGenerationModelOptions] = ..., - question_types: Optional[list[Union[str, SimpleQnAFineTuningQuestionType]]] = ..., - train_split: Optional[float] = ... + height: int, + width: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SimpleQnAFineTuningQuestionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - LONG_ANSWER = "long_answer" - SHORT_ANSWER = "short_answer" - - - class azure.ai.projects.models.SimulationSeedDataGenerationJobOptions(DataGenerationJobOptions, discriminator='simulation_seed'): - max_samples: int - model_options: DataGenerationModelOptions - train_split: float - type: Literal[DataGenerationJobType.SIMULATION_SEED] + class azure.ai.projects.models.VoiceAgentAzureSemanticVadEnTurnDetection(VoiceAgentTurnDetectionConfig, discriminator='azure_semantic_vad_en'): + auto_truncate: bool + create_response: Optional[bool] + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] + idle_timeout_ms: Optional[timedelta] + interrupt_response: Optional[bool] + prefix_padding_ms: Optional[timedelta] + remove_filler_words: Optional[bool] + silence_duration_ms: Optional[timedelta] + speech_duration_ms: Optional[timedelta] + threshold: Optional[float] + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_EN] @overload def __init__( self, *, - max_samples: int, - model_options: Optional[DataGenerationModelOptions] = ..., - train_split: Optional[float] = ... + auto_truncate: Optional[bool] = ..., + create_response: Optional[bool] = ..., + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] = ..., + idle_timeout_ms: Optional[timedelta] = ..., + interrupt_response: Optional[bool] = ..., + prefix_padding_ms: Optional[timedelta] = ..., + remove_filler_words: Optional[bool] = ..., + silence_duration_ms: Optional[timedelta] = ..., + speech_duration_ms: Optional[timedelta] = ..., + threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SkillDetails(_Model): - created_at: datetime - default_version: str - description: str - id: str - latest_version: str - name: str + class azure.ai.projects.models.VoiceAgentAzureSemanticVadMultilingualTurnDetection(VoiceAgentTurnDetectionConfig, discriminator='azure_semantic_vad_multilingual'): + auto_truncate: bool + create_response: Optional[bool] + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] + idle_timeout_ms: Optional[timedelta] + interrupt_response: Optional[bool] + languages: Optional[list[str]] + prefix_padding_ms: Optional[timedelta] + remove_filler_words: Optional[bool] + silence_duration_ms: Optional[timedelta] + speech_duration_ms: Optional[timedelta] + threshold: Optional[float] + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_MULTILINGUAL] @overload def __init__( self, *, - created_at: datetime, - default_version: str, - description: str, - id: str, - latest_version: str, - name: str + auto_truncate: Optional[bool] = ..., + create_response: Optional[bool] = ..., + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] = ..., + idle_timeout_ms: Optional[timedelta] = ..., + interrupt_response: Optional[bool] = ..., + languages: Optional[list[str]] = ..., + prefix_padding_ms: Optional[timedelta] = ..., + remove_filler_words: Optional[bool] = ..., + silence_duration_ms: Optional[timedelta] = ..., + speech_duration_ms: Optional[timedelta] = ..., + threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SkillInlineContent(_Model): - allowed_tools: Optional[list[str]] - compatibility: Optional[str] - description: str - instructions: str - license: Optional[str] - metadata: Optional[dict[str, str]] + class azure.ai.projects.models.VoiceAgentAzureSemanticVadTurnDetection(VoiceAgentTurnDetectionConfig, discriminator='azure_semantic_vad'): + auto_truncate: bool + create_response: Optional[bool] + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] + idle_timeout_ms: Optional[timedelta] + interrupt_response: Optional[bool] + languages: Optional[list[str]] + prefix_padding_ms: Optional[timedelta] + remove_filler_words: Optional[bool] + silence_duration_ms: Optional[timedelta] + speech_duration_ms: Optional[timedelta] + threshold: Optional[float] + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD] @overload def __init__( self, *, - allowed_tools: Optional[list[str]] = ..., - compatibility: Optional[str] = ..., - description: str, - instructions: str, - license: Optional[str] = ..., - metadata: Optional[dict[str, str]] = ... + auto_truncate: Optional[bool] = ..., + create_response: Optional[bool] = ..., + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] = ..., + idle_timeout_ms: Optional[timedelta] = ..., + interrupt_response: Optional[bool] = ..., + languages: Optional[list[str]] = ..., + prefix_padding_ms: Optional[timedelta] = ..., + remove_filler_words: Optional[bool] = ..., + silence_duration_ms: Optional[timedelta] = ..., + speech_duration_ms: Optional[timedelta] = ..., + threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SkillReferenceParam(ContainerSkill, discriminator='skill_reference'): - skill_id: str - type: Literal[ContainerSkillType.SKILL_REFERENCE] - version: Optional[str] + class azure.ai.projects.models.VoiceAgentClientEventRtcCallSdpCreate(RealtimeClientEvent, discriminator='rtc.call.sdp.create'): + event_id: Optional[str] + sdp_offer: str + session: Optional[VoiceAgentSessionUpdateConfig] + type: Literal[RealtimeClientEventType.RTC_CALL_SDP_CREATE] @overload def __init__( self, *, - skill_id: str, - version: Optional[str] = ... + event_id: Optional[str] = ..., + sdp_offer: str, + session: Optional[VoiceAgentSessionUpdateConfig] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SkillVersion(_Model): - created_at: datetime - description: str - id: str - name: str - skill_id: str - version: str + class azure.ai.projects.models.VoiceAgentClientEventSessionAvatarConnect(RealtimeClientEvent, discriminator='session.avatar.connect'): + client_sdp: str + event_id: Optional[str] + type: Literal[RealtimeClientEventType.SESSION_AVATAR_CONNECT] @overload def __init__( self, *, - created_at: datetime, - description: str, - id: str, - name: str, - skill_id: str, - version: str + client_sdp: str, + event_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SpecificApplyPatchParam(ToolChoiceParam, discriminator='apply_patch'): - type: Literal[ToolChoiceParamType.APPLY_PATCH] + class azure.ai.projects.models.VoiceAgentClientEventSessionUpdate(_Model): + event_id: Optional[str] + session: VoiceAgentSessionUpdate + type: Literal[RealtimeClientEventType.SESSION_UPDATE] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + event_id: Optional[str] = ..., + session: VoiceAgentSessionUpdate, + type: Literal[RealtimeClientEventType.SESSION_UPDATE] + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SpecificFunctionShellParam(ToolChoiceParam, discriminator='shell'): - type: Literal[ToolChoiceParamType.SHELL] + class azure.ai.projects.models.VoiceAgentDefinition(AgentDefinition, discriminator='voice'): + audio: Optional[VoiceAgentAudioConfig] + avatar: Optional[VoiceAgentAvatarConfig] + conversation_engine: Optional[VoiceConversationEngine] + greeting: Optional[VoiceAgentGreetingConfig] + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] + instructions: Optional[str] + interim_response: Optional[VoiceAgentInterimResponseConfig] + kind: Literal[AgentKind.VOICE] + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] + model: Optional[str] + model_type: Optional[Union[str, VoiceModelType]] + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] + parallel_tool_calls: Optional[bool] + rai_config: RaiConfig + store: Optional[bool] + structured_inputs: Optional[dict[str, StructuredInputDefinition]] + subagent_config: Optional[VoiceAgentSubagentConfig] + tool_choice: Optional[VoiceAgentToolChoice] + tools: Optional[list[VoiceAgentTool]] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio: Optional[VoiceAgentAudioConfig] = ..., + avatar: Optional[VoiceAgentAvatarConfig] = ..., + conversation_engine: Optional[VoiceConversationEngine] = ..., + greeting: Optional[VoiceAgentGreetingConfig] = ..., + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] = ..., + instructions: Optional[str] = ..., + interim_response: Optional[VoiceAgentInterimResponseConfig] = ..., + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] = ..., + model: Optional[str] = ..., + model_type: Optional[Union[str, VoiceModelType]] = ..., + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] = ..., + parallel_tool_calls: Optional[bool] = ..., + rai_config: Optional[RaiConfig] = ..., + store: Optional[bool] = ..., + structured_inputs: Optional[dict[str, StructuredInputDefinition]] = ..., + subagent_config: Optional[VoiceAgentSubagentConfig] = ..., + tool_choice: Optional[VoiceAgentToolChoice] = ..., + tools: Optional[list[VoiceAgentTool]] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.SpecificProgrammaticToolCallingParam(ToolChoiceParam, discriminator='programmatic_tool_calling'): - type: Literal[ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING] + class azure.ai.projects.models.VoiceAgentEchoCancellation(_Model): + channels: Optional[int] + reference_source: Optional[Union[str, VoiceAgentEchoCancellationReferenceSource]] + type: Literal["server_echo_cancellation"] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + channels: Optional[int] = ..., + reference_source: Optional[Union[str, VoiceAgentEchoCancellationReferenceSource]] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.StructuredInputDefinition(_Model): - default_value: Optional[Any] - description: Optional[str] - required: Optional[bool] - schema: Optional[dict[str, Any]] + class azure.ai.projects.models.VoiceAgentEchoCancellationReferenceSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CLIENT = "client" + SERVER = "server" + + + class azure.ai.projects.models.VoiceAgentEndConversationSystemTool(VoiceAgentSystemTool, discriminator='end_conversation'): + description: str + name: Literal[VoiceAgentSystemToolName.END_CONVERSATION] + type: str @overload def __init__( self, *, - default_value: Optional[Any] = ..., - description: Optional[str] = ..., - required: Optional[bool] = ..., - schema: Optional[dict[str, Any]] = ... + description: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.StructuredOutputDefinition(_Model): - description: str - name: str - schema: dict[str, Any] - strict: bool + class azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection(_Model): + model: Union[str, VoiceAgentEndOfUtteranceDetectionModel] + threshold_level: Optional[Union[str, VoiceAgentEndOfUtteranceThresholdLevel]] + timeout_ms: Optional[timedelta] @overload def __init__( self, *, - description: str, - name: str, - schema: dict[str, Any], - strict: bool + model: Union[str, VoiceAgentEndOfUtteranceDetectionModel], + threshold_level: Optional[Union[str, VoiceAgentEndOfUtteranceThresholdLevel]] = ..., + timeout_ms: Optional[timedelta] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TargetCompletionEvalRunDataSource(TypedDict, total=False): - key "input_messages": Required[InputMessagesItemReference] - key "source": Required[Union[SourceFileContent, SourceFileID]] - key "target": Required[Union[AzureAIAgentTargetParam, AzureAIModelTargetParam, dict[str, Any]]] - key "type": Required[Literal["azure_ai_target_completions"]] + class azure.ai.projects.models.VoiceAgentEndOfUtteranceDetectionModel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + SEMANTIC_DETECTION_V1 = "semantic_detection_v1" + SEMANTIC_DETECTION_V1_EN = "semantic_detection_v1_en" + SEMANTIC_DETECTION_V1_MULTILINGUAL = "semantic_detection_v1_multilingual" + SMART_END_OF_TURN_DETECTION = "smart_end_of_turn_detection" - class azure.ai.projects.models.TaxonomyCategory(_Model): + class azure.ai.projects.models.VoiceAgentEndOfUtteranceThresholdLevel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + DEFAULT = "default" + HIGH = "high" + LOW = "low" + MEDIUM = "medium" + + + class azure.ai.projects.models.VoiceAgentFunctionTool(VoiceAgentTool, discriminator='function'): description: Optional[str] - id: str name: str - properties: Optional[dict[str, str]] - risk_category: Union[str, RiskCategory] - sub_categories: list[TaxonomySubCategory] + parameters: Optional[RealtimeFunctionToolParameters] + type: Literal["function"] @overload def __init__( self, *, description: Optional[str] = ..., - id: str, name: str, - properties: Optional[dict[str, str]] = ..., - risk_category: Union[str, RiskCategory], - sub_categories: list[TaxonomySubCategory] + parameters: Optional[RealtimeFunctionToolParameters] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TaxonomySubCategory(_Model): - description: Optional[str] - enabled: bool - id: str - name: str - properties: Optional[dict[str, str]] + class azure.ai.projects.models.VoiceAgentGreetingConfig(_Model): + type: str @overload def __init__( self, *, - description: Optional[str] = ..., - enabled: bool, - id: str, - name: str, - properties: Optional[dict[str, str]] = ... + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TelemetryConfig(_Model): - endpoints: list[TelemetryEndpoint] + class azure.ai.projects.models.VoiceAgentInputTranscription(_Model): + custom_speech: Optional[dict[str, str]] + delay: Optional[Literal["minimal", "low", "medium", "high", "xhigh"]] + keywords: Optional[list[str]] + language: Optional[str] + languages: Optional[list[str]] + model: Union[str, VoiceAgentInputTranscriptionModel] + phrase_list: Optional[list[str]] + prompt: Optional[str] @overload def __init__( self, *, - endpoints: list[TelemetryEndpoint] + custom_speech: Optional[dict[str, str]] = ..., + delay: Optional[Literal[minimal, low, medium, high, xhigh]] = ..., + keywords: Optional[list[str]] = ..., + language: Optional[str] = ..., + languages: Optional[list[str]] = ..., + model: Union[str, VoiceAgentInputTranscriptionModel], + phrase_list: Optional[list[str]] = ..., + prompt: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TelemetryDataKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CONTAINER_OTEL = "ContainerOtel" - CONTAINER_STDOUT_STDERR = "ContainerStdoutStderr" - METRICS = "Metrics" + class azure.ai.projects.models.VoiceAgentInputTranscriptionModel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AZURE_SPEECH = "azure-speech" + GPT4_O_MINI_TRANSCRIBE = "gpt-4o-mini-transcribe" + GPT4_O_TRANSCRIBE = "gpt-4o-transcribe" + GPT4_O_TRANSCRIBE_DIARIZE = "gpt-4o-transcribe-diarize" + GPT_LIVE_TRANSCRIBE = "gpt-live-transcribe" + GPT_REALTIME_WHISPER = "gpt-realtime-whisper" + GPT_TRANSCRIBE = "gpt-transcribe" + MAI_TRANSCRIBE = "mai-transcribe" + WHISPER1 = "whisper-1" - class azure.ai.projects.models.TelemetryEndpoint(_Model): - auth: Optional[TelemetryEndpointAuth] - data: list[Union[str, TelemetryDataKind]] - kind: str + class azure.ai.projects.models.VoiceAgentInterimResponseConfig(_Model): + latency_threshold_ms: Optional[timedelta] + triggers: Optional[list[Union[str, VoiceAgentInterimResponseTrigger]]] + type: str @overload def __init__( self, *, - auth: Optional[TelemetryEndpointAuth] = ..., - data: list[Union[str, TelemetryDataKind]], - kind: str + latency_threshold_ms: Optional[timedelta] = ..., + triggers: Optional[list[Union[str, VoiceAgentInterimResponseTrigger]]] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TelemetryEndpointAuth(_Model): - type: str + class azure.ai.projects.models.VoiceAgentInterimResponseTrigger(str, Enum, metaclass=CaseInsensitiveEnumMeta): + LATENCY = "latency" + TOOL = "tool" + + + class azure.ai.projects.models.VoiceAgentLlmGeneratedGreetingConfig(VoiceAgentGreetingConfig, discriminator='llm_generated'): + prompt: str + tool_choice: Optional[VoiceAgentToolChoice] + type: Literal["llm_generated"] @overload def __init__( self, *, - type: str + prompt: str, + tool_choice: Optional[VoiceAgentToolChoice] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TelemetryEndpointAuthType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - HEADER = "header" + class azure.ai.projects.models.VoiceAgentLlmInterimResponseConfig(VoiceAgentInterimResponseConfig, discriminator='llm_interim_response'): + instructions: Optional[str] + latency_threshold_ms: timedelta + max_completion_tokens: Optional[int] + model: Optional[str] + triggers: Union[list[str, VoiceAgentInterimResponseTrigger]] + type: Literal["llm_interim_response"] + @overload + def __init__( + self, + *, + instructions: Optional[str] = ..., + latency_threshold_ms: Optional[timedelta] = ..., + max_completion_tokens: Optional[int] = ..., + model: Optional[str] = ..., + triggers: Optional[list[Union[str, VoiceAgentInterimResponseTrigger]]] = ... + ) -> None: ... - class azure.ai.projects.models.TelemetryEndpointKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): - OTLP = "OTLP" + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TelemetryTransportProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): - GRPC = "Grpc" - HTTP = "Http" + class azure.ai.projects.models.VoiceAgentMcpTool(VoiceAgentTool, discriminator='mcp'): + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] + allowed_tools: Optional[Union[list[str], MCPToolFilter]] + authorization: Optional[str] + defer_loading: Optional[bool] + headers: Optional[dict[str, str]] + project_connection_id: Optional[str] + require_approval: Optional[Union[MCPToolRequireApproval, Literal["always"], Literal["never"]]] + response_scheduling: Optional[Union[str, VoiceAgentToolResponseScheduling]] + server_description: Optional[str] + server_label: str + server_url: Optional[str] + tool_configs: Optional[dict[str, ToolConfig]] + type: Literal["mcp"] + @overload + def __init__( + self, + *, + allowed_callers: Optional[list[Union[str, CallableToolAllowedCaller]]] = ..., + allowed_tools: Optional[Union[list[str], MCPToolFilter]] = ..., + authorization: Optional[str] = ..., + defer_loading: Optional[bool] = ..., + headers: Optional[dict[str, str]] = ..., + project_connection_id: Optional[str] = ..., + require_approval: Optional[Union[MCPToolRequireApproval, Literal[always], Literal[never]]] = ..., + response_scheduling: Optional[Union[str, VoiceAgentToolResponseScheduling]] = ..., + server_description: Optional[str] = ..., + server_label: str, + server_url: Optional[str] = ..., + tool_configs: Optional[dict[str, ToolConfig]] = ... + ) -> None: ... - class azure.ai.projects.models.TestingCriterionAzureAIEvaluator(TypedDict, total=False): - key "data_mapping": Dict[str, str] - key "evaluator_name": Required[str] - key "evaluator_version": str - key "initialization_parameters": Dict[str, Any] - key "name": Required[str] - key "type": Required[Literal["azure_ai_evaluator"]] + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TextResponseFormat(_Model): - type: str + class azure.ai.projects.models.VoiceAgentNoiseReduction(_Model): + type: Union[str, VoiceAgentNoiseReductionType] @overload def __init__( self, *, - type: str + type: Union[str, VoiceAgentNoiseReductionType] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TextResponseFormatConfigurationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - JSON_OBJECT = "json_object" - JSON_SCHEMA = "json_schema" - TEXT = "text" + class azure.ai.projects.models.VoiceAgentNoiseReductionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AZURE_DEEP_NOISE_SUPPRESSION = "azure_deep_noise_suppression" + FAR_FIELD = "far_field" + NEAR_FIELD = "near_field" - class azure.ai.projects.models.TextResponseFormatJsonObject(TextResponseFormat, discriminator='json_object'): - type: Literal[TextResponseFormatConfigurationType.JSON_OBJECT] + class azure.ai.projects.models.VoiceAgentRealtimeResponse(VoiceAgentRealtimeResponseBase): + audio: Optional[VoiceResponseAudio] + conversation_id: str + id: str + max_output_tokens: Union[int, str] + metadata: Metadata + object: str + output: Optional[list[RealtimeConversationItem]] + output_modalities: Union[list[str, str]] + status: Union[str, str, str, str, str] + status_details: RealtimeResponseStatusDetails + usage: RealtimeResponseUsage @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio: Optional[VoiceResponseAudio] = ..., + conversation_id: Optional[str] = ..., + id: Optional[str] = ..., + max_output_tokens: Optional[Union[int, Literal[inf]]] = ..., + metadata: Optional[Metadata] = ..., + object: Optional[Literal[response]] = ..., + output: Optional[list[RealtimeConversationItem]] = ..., + output_modalities: Optional[list[Literal[text, audio]]] = ..., + status: Optional[Literal[completed, cancelled, failed, incomplete, in_progress]] = ..., + status_details: Optional[RealtimeResponseStatusDetails] = ..., + usage: Optional[RealtimeResponseUsage] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TextResponseFormatJsonSchema(TextResponseFormat, discriminator='json_schema'): - description: Optional[str] - name: str - schema: dict[str, Any] - strict: Optional[bool] - type: Literal[TextResponseFormatConfigurationType.JSON_SCHEMA] + class azure.ai.projects.models.VoiceAgentRealtimeResponseBase(_Model): + conversation_id: Optional[str] + id: Optional[str] + max_output_tokens: Optional[Union[int, Literal["inf"]]] + metadata: Optional[Metadata] + object: Optional[Literal["response"]] + output_modalities: Optional[list[Literal["text", "audio"]]] + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] + status_details: Optional[RealtimeResponseStatusDetails] + usage: Optional[RealtimeResponseUsage] @overload def __init__( self, *, - description: Optional[str] = ..., - name: str, - schema: dict[str, Any], - strict: Optional[bool] = ... + conversation_id: Optional[str] = ..., + id: Optional[str] = ..., + max_output_tokens: Optional[Union[int, Literal[inf]]] = ..., + metadata: Optional[Metadata] = ..., + object: Optional[Literal[response]] = ..., + output_modalities: Optional[list[Literal[text, audio]]] = ..., + status: Optional[Literal[completed, cancelled, failed, incomplete, in_progress]] = ..., + status_details: Optional[RealtimeResponseStatusDetails] = ..., + usage: Optional[RealtimeResponseUsage] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TextResponseFormatText(TextResponseFormat, discriminator='text'): - type: Literal[TextResponseFormatConfigurationType.TEXT] + class azure.ai.projects.models.VoiceAgentResponseCreateParams(_Model): + audio: Optional[PickPropertiesVoiceAgentAudioConfig] + conversation: Optional[Union[Literal["auto"], Literal["none"], str]] + input: Optional[list[RealtimeConversationItem]] + instructions: Optional[str] + interim_response: Optional[VoiceAgentInterimResponseConfig] + max_output_tokens: Optional[Union[int, Literal["inf"]]] + metadata: Optional[Metadata] + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] + parallel_tool_calls: Optional[bool] + pre_generated_assistant_message: Optional[RealtimeConversationItem] + reasoning: Optional[RealtimeReasoning] + tool_choice: Optional[Union[str, ToolChoiceOptions, ToolChoiceFunction, ToolChoiceMCP]] + tools: Optional[list[Union[RealtimeFunctionTool, MCPTool]]] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio: Optional[PickPropertiesVoiceAgentAudioConfig] = ..., + conversation: Optional[Union[Literal[auto], Literal[none], str]] = ..., + input: Optional[list[RealtimeConversationItem]] = ..., + instructions: Optional[str] = ..., + interim_response: Optional[VoiceAgentInterimResponseConfig] = ..., + max_output_tokens: Optional[Union[int, Literal[inf]]] = ..., + metadata: Optional[Metadata] = ..., + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] = ..., + parallel_tool_calls: Optional[bool] = ..., + pre_generated_assistant_message: Optional[RealtimeConversationItem] = ..., + reasoning: Optional[RealtimeReasoning] = ..., + tool_choice: Optional[Union[str, ToolChoiceOptions, ToolChoiceFunction, ToolChoiceMCP]] = ..., + tools: Optional[list[Union[RealtimeFunctionTool, MCPTool]]] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TimerRoutineTrigger(RoutineTrigger, discriminator='timer'): - at: Optional[datetime] - type: Literal[RoutineTriggerType.TIMER] + class azure.ai.projects.models.VoiceAgentRtcCallErrorDetails(_Model): + code: Optional[str] + message: str + type: str @overload def __init__( self, *, - at: Optional[datetime] = ... + code: Optional[str] = ..., + message: str, + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.Tool(_Model): - type: str + class azure.ai.projects.models.VoiceAgentSemanticVadTurnDetection(VoiceAgentTurnDetectionConfig, discriminator='semantic_vad'): + auto_truncate: bool + create_response: Optional[bool] + eagerness: Optional[Literal["low", "medium", "high", "auto"]] + interrupt_response: Optional[bool] + type: Literal[VoiceAgentTurnDetectionType.SEMANTIC_VAD] @overload def __init__( self, *, - type: str + auto_truncate: Optional[bool] = ..., + create_response: Optional[bool] = ..., + eagerness: Optional[Literal[low, medium, high, auto]] = ..., + interrupt_response: Optional[bool] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceAllowed(ToolChoiceParam, discriminator='allowed_tools'): - mode: Literal["auto", "required"] - tools: list[dict[str, Any]] - type: Literal[ToolChoiceParamType.ALLOWED_TOOLS] + class azure.ai.projects.models.VoiceAgentServerEventResponseAnimationBlendshapesDelta(RealtimeServerEvent, discriminator='response.animation_blendshapes.delta'): + content_index: int + event_id: str + frame_index: int + frames: list[list[float]] + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DELTA] @overload def __init__( self, *, - mode: Literal["auto", "required"], - tools: list[dict[str, Any]] + content_index: int, + event_id: str, + frame_index: int, + frames: list[list[float]], + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceCodeInterpreter(ToolChoiceParam, discriminator='code_interpreter'): - type: Literal[ToolChoiceParamType.CODE_INTERPRETER] + class azure.ai.projects.models.VoiceAgentServerEventResponseAnimationBlendshapesDone(RealtimeServerEvent, discriminator='response.animation_blendshapes.done'): + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DONE] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + event_id: str, + item_id: str, + output_index: int, + response_id: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceComputer(ToolChoiceParam, discriminator='computer'): - type: Literal[ToolChoiceParamType.COMPUTER] + class azure.ai.projects.models.VoiceAgentServerEventResponseAnimationVisemeDelta(RealtimeServerEvent, discriminator='response.animation_viseme.delta'): + audio_offset_ms: timedelta + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DELTA] + viseme_id: int @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio_offset_ms: timedelta, + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str, + viseme_id: int + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceComputerUse(ToolChoiceParam, discriminator='computer_use'): - type: Literal[ToolChoiceParamType.COMPUTER_USE] + class azure.ai.projects.models.VoiceAgentServerEventResponseAnimationVisemeDone(RealtimeServerEvent, discriminator='response.animation_viseme.done'): + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DONE] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceComputerUsePreview(ToolChoiceParam, discriminator='computer_use_preview'): - type: Literal[ToolChoiceParamType.COMPUTER_USE_PREVIEW] + class azure.ai.projects.models.VoiceAgentServerEventResponseAudioTimestampDelta(RealtimeServerEvent, discriminator='response.audio_timestamp.delta'): + audio_duration_ms: timedelta + audio_offset_ms: timedelta + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + text: str + timestamp_type: Literal["word"] + type: Literal[RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DELTA] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + audio_duration_ms: timedelta, + audio_offset_ms: timedelta, + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str, + text: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceCustom(ToolChoiceParam, discriminator='custom'): - name: str - type: Literal[ToolChoiceParamType.CUSTOM] + class azure.ai.projects.models.VoiceAgentServerEventResponseAudioTimestampDone(RealtimeServerEvent, discriminator='response.audio_timestamp.done'): + content_index: int + event_id: str + item_id: str + output_index: int + response_id: str + type: Literal[RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DONE] @overload def __init__( self, *, - name: str + content_index: int, + event_id: str, + item_id: str, + output_index: int, + response_id: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceFileSearch(ToolChoiceParam, discriminator='file_search'): - type: Literal[ToolChoiceParamType.FILE_SEARCH] + class azure.ai.projects.models.VoiceAgentServerEventResponseVideoDelta(RealtimeServerEvent, discriminator='response.video.delta'): + codec: str + delta: str + event_id: str + output_index: int + type: Literal[RealtimeServerEventType.RESPONSE_VIDEO_DELTA] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + codec: str, + delta: str, + event_id: str, + output_index: int + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceFunction(ToolChoiceParam, discriminator='function'): - name: str - type: Literal[ToolChoiceParamType.FUNCTION] + class azure.ai.projects.models.VoiceAgentServerEventRtcCallError(RealtimeServerEvent, discriminator='rtc.call.error'): + error: VoiceAgentRtcCallErrorDetails + event_id: Optional[str] + operation: Optional[str] + rtc_call_id: Optional[str] + type: Literal[RealtimeServerEventType.RTC_CALL_ERROR] @overload def __init__( self, *, - name: str + error: VoiceAgentRtcCallErrorDetails, + event_id: Optional[str] = ..., + operation: Optional[str] = ..., + rtc_call_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceImageGeneration(ToolChoiceParam, discriminator='image_generation'): - type: Literal[ToolChoiceParamType.IMAGE_GENERATION] + class azure.ai.projects.models.VoiceAgentServerEventRtcCallSdpCreated(RealtimeServerEvent, discriminator='rtc.call.sdp.created'): + event_id: str + rtc_call_id: str + sdp_answer: str + type: Literal[RealtimeServerEventType.RTC_CALL_SDP_CREATED] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + event_id: str, + rtc_call_id: str, + sdp_answer: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceMCP(ToolChoiceParam, discriminator='mcp'): - name: Optional[str] - server_label: str - type: Literal[ToolChoiceParamType.MCP] + class azure.ai.projects.models.VoiceAgentServerEventSessionAvatarConnecting(RealtimeServerEvent, discriminator='session.avatar.connecting'): + event_id: str + server_sdp: str + type: Literal[RealtimeServerEventType.SESSION_AVATAR_CONNECTING] @overload def __init__( self, *, - name: Optional[str] = ..., - server_label: str + event_id: str, + server_sdp: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceParam(_Model): - type: str + class azure.ai.projects.models.VoiceAgentServerEventSessionAvatarSwitchToIdle(RealtimeServerEvent, discriminator='session.avatar.switch_to_idle'): + event_id: str + turn_id: Optional[str] + type: Literal[RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_IDLE] @overload def __init__( self, *, - type: str + event_id: str, + turn_id: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - ALLOWED_TOOLS = "allowed_tools" - APPLY_PATCH = "apply_patch" - CODE_INTERPRETER = "code_interpreter" - COMPUTER = "computer" - COMPUTER_USE = "computer_use" - COMPUTER_USE_PREVIEW = "computer_use_preview" - CUSTOM = "custom" - FILE_SEARCH = "file_search" - FUNCTION = "function" - IMAGE_GENERATION = "image_generation" - MCP = "mcp" - PROGRAMMATIC_TOOL_CALLING = "programmatic_tool_calling" - SHELL = "shell" - WEB_SEARCH_PREVIEW = "web_search_preview" - WEB_SEARCH_PREVIEW_2025_03_11 = "web_search_preview_2025_03_11" - - - class azure.ai.projects.models.ToolChoiceWebSearchPreview(ToolChoiceParam, discriminator='web_search_preview'): - type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW] + class azure.ai.projects.models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking(RealtimeServerEvent, discriminator='session.avatar.switch_to_speaking'): + event_id: str + turn_id: Optional[str] + type: Literal[RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_SPEAKING] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + event_id: str, + turn_id: Optional[str] = ... + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolChoiceWebSearchPreview20250311(ToolChoiceParam, discriminator='web_search_preview_2025_03_11'): - type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11] + class azure.ai.projects.models.VoiceAgentServerEventSessionSubagentAborted(RealtimeServerEvent, discriminator='session.subagent.aborted'): + call_id: str + consultation_id: str + event_id: str + reason: Union[str, VoiceAgentSubagentAbortReason] + subagent_name: str + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_ABORTED] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + call_id: str, + consultation_id: str, + event_id: str, + reason: Union[str, VoiceAgentSubagentAbortReason], + subagent_name: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolConfig(_Model): - additional_search_text: Optional[str] - pin: Optional[bool] + class azure.ai.projects.models.VoiceAgentServerEventSessionSubagentCompleted(RealtimeServerEvent, discriminator='session.subagent.completed'): + call_id: str + consultation_id: str + event_id: str + subagent_name: str + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_COMPLETED] @overload def __init__( self, *, - additional_search_text: Optional[str] = ..., - pin: Optional[bool] = ... + call_id: str, + consultation_id: str, + event_id: str, + subagent_name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolDescription(_Model): - description: Optional[str] - name: Optional[str] + class azure.ai.projects.models.VoiceAgentServerEventSessionSubagentStarted(RealtimeServerEvent, discriminator='session.subagent.started'): + call_id: str + consultation_id: str + event_id: str + subagent_name: str + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_STARTED] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ... + call_id: str, + consultation_id: str, + event_id: str, + subagent_name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolDescriptionParam(TypedDict, total=False): - key "description": str - key "name": str - - - class azure.ai.projects.models.ToolProjectConnection(_Model): - project_connection_id: str + class azure.ai.projects.models.VoiceAgentServerEventWarning(RealtimeServerEvent, discriminator='warning'): + event_id: str + type: Literal[RealtimeServerEventType.WARNING] + warning: VoiceAgentServerEventWarningDetails @overload def __init__( self, *, - project_connection_id: str + event_id: str, + warning: VoiceAgentServerEventWarningDetails ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolSearchExecutionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CLIENT = "client" - SERVER = "server" - - - class azure.ai.projects.models.ToolSearchToolParam(Tool, discriminator='tool_search'): - description: Optional[str] - execution: Optional[Union[str, ToolSearchExecutionType]] - parameters: Optional[EmptyModelParam] - type: Literal[ToolType.TOOL_SEARCH] + class azure.ai.projects.models.VoiceAgentServerEventWarningDetails(_Model): + code: Optional[str] + message: str + param: Optional[str] @overload def __init__( self, *, - description: Optional[str] = ..., - execution: Optional[Union[str, ToolSearchExecutionType]] = ..., - parameters: Optional[EmptyModelParam] = ... + code: Optional[str] = ..., + message: str, + param: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolSearchToolboxTool(ToolboxTool, discriminator='toolbox_search'): - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.TOOLBOX_SEARCH] + class azure.ai.projects.models.VoiceAgentServerVadTurnDetection(VoiceAgentTurnDetectionConfig, discriminator='server_vad'): + auto_truncate: bool + create_response: Optional[bool] + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] + idle_timeout_ms: Optional[int] + interrupt_response: Optional[bool] + prefix_padding_ms: Optional[int] + silence_duration_ms: Optional[int] + speech_duration_ms: Optional[timedelta] + threshold: Optional[float] + type: Literal[VoiceAgentTurnDetectionType.SERVER_VAD] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + auto_truncate: Optional[bool] = ..., + create_response: Optional[bool] = ..., + end_of_utterance_detection: Optional[VoiceAgentEndOfUtteranceDetection] = ..., + idle_timeout_ms: Optional[int] = ..., + interrupt_response: Optional[bool] = ..., + prefix_padding_ms: Optional[int] = ..., + silence_duration_ms: Optional[int] = ..., + speech_duration_ms: Optional[timedelta] = ..., + threshold: Optional[float] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - A2A_PREVIEW = "a2a_preview" - A2_A = "a2a" - APPLY_PATCH = "apply_patch" - AZURE_AI_SEARCH = "azure_ai_search" - AZURE_FUNCTION = "azure_function" - BING_CUSTOM_SEARCH_PREVIEW = "bing_custom_search_preview" - BING_GROUNDING = "bing_grounding" - BROWSER_AUTOMATION_PREVIEW = "browser_automation_preview" - CAPTURE_STRUCTURED_OUTPUTS = "capture_structured_outputs" - CODE_INTERPRETER = "code_interpreter" - COMPUTER = "computer" - COMPUTER_USE_PREVIEW = "computer_use_preview" - CUSTOM = "custom" - FABRIC_DATAAGENT_PREVIEW = "fabric_dataagent_preview" - FABRIC_IQ_PREVIEW = "fabric_iq_preview" - FILE_SEARCH = "file_search" - FUNCTION = "function" - IMAGE_GENERATION = "image_generation" - LOCAL_SHELL = "local_shell" - MCP = "mcp" - MEMORY_SEARCH_PREVIEW = "memory_search_preview" - NAMESPACE = "namespace" - OPENAPI = "openapi" - PROGRAMMATIC_TOOL_CALLING = "programmatic_tool_calling" - SHAREPOINT_GROUNDING_PREVIEW = "sharepoint_grounding_preview" - SHELL = "shell" - TOOLBOX_SEARCH_PREVIEW = "toolbox_search_preview" - TOOL_SEARCH = "tool_search" - WEB_IQ_PREVIEW = "web_iq_preview" - WEB_SEARCH = "web_search" - WEB_SEARCH_PREVIEW = "web_search_preview" - WORK_IQ_PREVIEW = "work_iq_preview" - - - class azure.ai.projects.models.ToolUseFineTuningDataGenerationJobOptions(DataGenerationJobOptions, discriminator='tool_use'): - max_samples: int - model_options: DataGenerationModelOptions - train_split: float - type: Literal[DataGenerationJobType.TOOL_USE] + class azure.ai.projects.models.VoiceAgentSessionAvatarConfig(VoiceAgentAvatarConfig): + character: str + customized: bool + ice_servers: Optional[list[VoiceAgentAvatarIceServer]] + model: str + output_audit_audio: bool + output_protocol: Union[str, VoiceAgentAvatarOutputProtocol] + scene: VoiceAgentAvatarScene + style: str + type: Union[str, VoiceAgentAvatarType] + video: VoiceAgentAvatarVideoParams @overload def __init__( self, - *, - max_samples: int, - model_options: Optional[DataGenerationModelOptions] = ..., - train_split: Optional[float] = ... + *, + character: str, + customized: Optional[bool] = ..., + ice_servers: Optional[list[VoiceAgentAvatarIceServer]] = ..., + model: Optional[str] = ..., + output_audit_audio: Optional[bool] = ..., + output_protocol: Optional[Union[str, VoiceAgentAvatarOutputProtocol]] = ..., + scene: Optional[VoiceAgentAvatarScene] = ..., + style: Optional[str] = ..., + type: Union[str, VoiceAgentAvatarType], + video: Optional[VoiceAgentAvatarVideoParams] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxObject(_Model): - default_version: str + class azure.ai.projects.models.VoiceAgentSessionIncludeOption(str, Enum, metaclass=CaseInsensitiveEnumMeta): + FILE_SEARCH_CALL_RESULTS = "file_search_call.results" + INPUT_AUDIO_TRANSCRIPTION_LOGPROBS = "item.input_audio_transcription.logprobs" + INPUT_AUDIO_TRANSCRIPTION_PHRASES = "item.input_audio_transcription.phrases" + + + class azure.ai.projects.models.VoiceAgentSessionResponseConfig(_Model): + animation: Optional[VoiceAgentAnimationConfig] + audio: Optional[VoiceAgentAudioConfig] + avatar: Optional[VoiceAgentSessionAvatarConfig] + expires_at: Optional[datetime] + greeting: Optional[VoiceAgentGreetingConfig] id: str - name: str + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] + instructions: Optional[str] + interim_response: Optional[VoiceAgentInterimResponseConfig] + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] + metadata: Optional[dict[str, str]] + model: str + object: Literal["session"] + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] + parallel_tool_calls: Optional[bool] + reasoning: Optional[RealtimeReasoning] + temperature: Optional[float] + tool_choice: Optional[VoiceAgentToolChoice] + tools: Optional[list[VoiceAgentTool]] + type: Literal["realtime"] @overload def __init__( self, *, - default_version: str, + animation: Optional[VoiceAgentAnimationConfig] = ..., + audio: Optional[VoiceAgentAudioConfig] = ..., + avatar: Optional[VoiceAgentSessionAvatarConfig] = ..., + expires_at: Optional[datetime] = ..., + greeting: Optional[VoiceAgentGreetingConfig] = ..., id: str, - name: str + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] = ..., + instructions: Optional[str] = ..., + interim_response: Optional[VoiceAgentInterimResponseConfig] = ..., + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] = ..., + metadata: Optional[dict[str, str]] = ..., + model: str, + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] = ..., + parallel_tool_calls: Optional[bool] = ..., + reasoning: Optional[RealtimeReasoning] = ..., + temperature: Optional[float] = ..., + tool_choice: Optional[VoiceAgentToolChoice] = ..., + tools: Optional[list[VoiceAgentTool]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxPolicies(_Model): - rai_config: Optional[RaiConfig] + class azure.ai.projects.models.VoiceAgentSessionUpdateConfig(_Model): + animation: Optional[VoiceAgentAnimationConfig] + audio: Optional[VoiceAgentAudioConfig] + avatar: Optional[VoiceAgentSessionAvatarConfig] + greeting: Optional[VoiceAgentGreetingConfig] + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] + instructions: Optional[str] + interim_response: Optional[VoiceAgentInterimResponseConfig] + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] + metadata: Optional[dict[str, str]] + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] + parallel_tool_calls: Optional[bool] + reasoning: Optional[RealtimeReasoning] + temperature: Optional[float] + tool_choice: Optional[VoiceAgentToolChoice] + tools: Optional[list[VoiceAgentTool]] + type: Literal["realtime"] @overload def __init__( self, *, - rai_config: Optional[RaiConfig] = ... + animation: Optional[VoiceAgentAnimationConfig] = ..., + audio: Optional[VoiceAgentAudioConfig] = ..., + avatar: Optional[VoiceAgentSessionAvatarConfig] = ..., + greeting: Optional[VoiceAgentGreetingConfig] = ..., + include: Optional[list[Union[str, VoiceAgentSessionIncludeOption]]] = ..., + instructions: Optional[str] = ..., + interim_response: Optional[VoiceAgentInterimResponseConfig] = ..., + max_output_tokens: Optional[VoiceAgentMaxOutputTokens] = ..., + metadata: Optional[dict[str, str]] = ..., + output_modalities: Optional[list[Union[str, VoiceOutputModality]]] = ..., + parallel_tool_calls: Optional[bool] = ..., + reasoning: Optional[RealtimeReasoning] = ..., + temperature: Optional[float] = ..., + tool_choice: Optional[VoiceAgentToolChoice] = ..., + tools: Optional[list[VoiceAgentTool]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxSearchPreviewToolboxTool(ToolboxTool, discriminator='toolbox_search_preview'): - description: str - name: str - tool_configs: dict[str, ToolConfig] - type: Literal[ToolboxToolType.TOOLBOX_SEARCH_PREVIEW] + class azure.ai.projects.models.VoiceAgentStaticInterimResponseConfig(VoiceAgentInterimResponseConfig, discriminator='static_interim_response'): + latency_threshold_ms: timedelta + texts: Optional[list[str]] + triggers: Union[list[str, VoiceAgentInterimResponseTrigger]] + type: Literal["static_interim_response"] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ... + latency_threshold_ms: Optional[timedelta] = ..., + texts: Optional[list[str]] = ..., + triggers: Optional[list[Union[str, VoiceAgentInterimResponseTrigger]]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxShellContainerAutoEnvironment(ToolboxShellEnvironment, discriminator='container_auto'): - file_ids: Optional[list[str]] - memory_limit: Optional[Union[str, ContainerMemoryLimit]] - network_policy: Optional[ToolboxShellNetworkPolicy] - skills: Optional[list[ContainerSkill]] - type: Literal["container_auto"] + class azure.ai.projects.models.VoiceAgentSubagent(_Model): + agent_capabilities: str + agent_name: str + agent_version: Optional[str] + invoke_timeout_seconds: Optional[timedelta] + response_policy: Optional[VoiceAgentSubagentResponsePolicy] @overload def __init__( self, *, - file_ids: Optional[list[str]] = ..., - memory_limit: Optional[Union[str, ContainerMemoryLimit]] = ..., - network_policy: Optional[ToolboxShellNetworkPolicy] = ..., - skills: Optional[list[ContainerSkill]] = ... + agent_capabilities: str, + agent_name: str, + agent_version: Optional[str] = ..., + invoke_timeout_seconds: Optional[timedelta] = ..., + response_policy: Optional[VoiceAgentSubagentResponsePolicy] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxShellContainerReferenceEnvironment(ToolboxShellEnvironment, discriminator='container_reference'): - container_id: str - type: Literal["container_reference"] + class azure.ai.projects.models.VoiceAgentSubagentAbortReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + CANCELLED = "cancelled" + FAILED = "failed" + STOPPED_BY_USER = "stopped_by_user" + SUPERSEDED = "superseded" + TIMEOUT = "timeout" + UNKNOWN_TARGET = "unknown_target" + + + class azure.ai.projects.models.VoiceAgentSubagentConfig(_Model): + subagents: list[VoiceAgentSubagent] @overload def __init__( self, *, - container_id: str + subagents: list[VoiceAgentSubagent] ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxShellEnvironment(_Model): - type: str + class azure.ai.projects.models.VoiceAgentSubagentResponsePolicy(_Model): + ack_instructions: Optional[str] + enable_delta_progress: Optional[bool] + gap_filling_instructions: Optional[str] + gap_filling_interval: Optional[timedelta] + immediate_ack: Optional[bool] + progress_instructions: Optional[str] + progress_update_interval: Optional[timedelta] @overload def __init__( self, *, - type: str + ack_instructions: Optional[str] = ..., + enable_delta_progress: Optional[bool] = ..., + gap_filling_instructions: Optional[str] = ..., + gap_filling_interval: Optional[timedelta] = ..., + immediate_ack: Optional[bool] = ..., + progress_instructions: Optional[str] = ..., + progress_update_interval: Optional[timedelta] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxShellNetworkPolicy(_Model): - type: str + class azure.ai.projects.models.VoiceAgentSystemTool(VoiceAgentTool, discriminator='system'): + description: Optional[str] + name: str + type: Literal["system"] @overload def __init__( self, *, - type: str + description: Optional[str] = ..., + name: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxShellNetworkPolicyDisabled(ToolboxShellNetworkPolicy, discriminator='disabled'): - type: Literal["disabled"] + class azure.ai.projects.models.VoiceAgentSystemToolName(str, Enum, metaclass=CaseInsensitiveEnumMeta): + END_CONVERSATION = "end_conversation" + + + class azure.ai.projects.models.VoiceAgentTemplateGreetingConfig(VoiceAgentGreetingConfig, discriminator='template'): + text: str + type: Literal["template"] @overload - def __init__(self) -> None: ... + def __init__( + self, + *, + text: str + ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxSkill(_Model): + class azure.ai.projects.models.VoiceAgentTool(_Model): type: str @overload @@ -10231,183 +15716,173 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxSkillReference(ToolboxSkill, discriminator='skill_reference'): - name: str - type: Literal["skill_reference"] - version: Optional[str] + class azure.ai.projects.models.VoiceAgentToolResponseScheduling(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INTERRUPT = "interrupt" + SILENT = "silent" + SKIP_IF_BUSY = "skip_if_busy" + WHEN_IDLE = "when_idle" + + + class azure.ai.projects.models.VoiceAgentToolboxTool(VoiceAgentTool, discriminator='toolbox'): + response_scheduling: Optional[Union[str, VoiceAgentToolResponseScheduling]] + toolbox_name: str + toolbox_version: str + type: Literal["toolbox"] @overload def __init__( self, *, - name: str, - version: Optional[str] = ... + response_scheduling: Optional[Union[str, VoiceAgentToolResponseScheduling]] = ..., + toolbox_name: str, + toolbox_version: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxTool(_Model): - description: Optional[str] - name: Optional[str] - tool_configs: Optional[dict[str, ToolConfig]] - type: str + class azure.ai.projects.models.VoiceAgentTranscriptionPhrase(_Model): + confidence: Optional[float] + duration_milliseconds: timedelta + locale: Optional[str] + offset_milliseconds: timedelta + text: str + words: Optional[list[VoiceAgentTranscriptionWord]] @overload def __init__( self, *, - description: Optional[str] = ..., - name: Optional[str] = ..., - tool_configs: Optional[dict[str, ToolConfig]] = ..., - type: str + confidence: Optional[float] = ..., + duration_milliseconds: timedelta, + locale: Optional[str] = ..., + offset_milliseconds: timedelta, + text: str, + words: Optional[list[VoiceAgentTranscriptionWord]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.ToolboxToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - A2A_PREVIEW = "a2a_preview" - A2_A = "a2a" - AZURE_AI_SEARCH = "azure_ai_search" - BROWSER_AUTOMATION_PREVIEW = "browser_automation_preview" - CODE_INTERPRETER = "code_interpreter" - FABRIC_IQ_PREVIEW = "fabric_iq_preview" - FILE_SEARCH = "file_search" - MCP = "mcp" - OPENAPI = "openapi" - REMINDER_PREVIEW = "reminder_preview" - SHELL = "shell" - TOOLBOX_SEARCH = "toolbox_search" - TOOLBOX_SEARCH_PREVIEW = "toolbox_search_preview" - WEB_IQ_PREVIEW = "web_iq_preview" - WEB_SEARCH = "web_search" - WORK_IQ_PREVIEW = "work_iq_preview" - - - class azure.ai.projects.models.ToolboxVersionObject(_Model): - created_at: datetime - description: Optional[str] - id: str - metadata: dict[str, str] - name: str - policies: Optional[ToolboxPolicies] - skills: Optional[list[ToolboxSkill]] - tools: list[ToolboxTool] - version: str + class azure.ai.projects.models.VoiceAgentTranscriptionWord(_Model): + duration_milliseconds: timedelta + offset_milliseconds: timedelta + text: str @overload def __init__( self, *, - created_at: datetime, - description: Optional[str] = ..., - id: str, - metadata: dict[str, str], - name: str, - policies: Optional[ToolboxPolicies] = ..., - skills: Optional[list[ToolboxSkill]] = ..., - tools: list[ToolboxTool], - version: str + duration_milliseconds: timedelta, + offset_milliseconds: timedelta, + text: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TracesDataGenerationJobOptions(DataGenerationJobOptions, discriminator='traces'): - max_samples: int - model_options: DataGenerationModelOptions - redact_private_content: Optional[bool] - train_split: float - type: Literal[DataGenerationJobType.TRACES] + class azure.ai.projects.models.VoiceAgentTurnDetectionConfig(_Model): + auto_truncate: Optional[bool] + type: str @overload def __init__( self, *, - max_samples: int, - model_options: Optional[DataGenerationModelOptions] = ..., - redact_private_content: Optional[bool] = ..., - train_split: Optional[float] = ... + auto_truncate: Optional[bool] = ..., + type: str ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TracesDataGenerationJobSource(DataGenerationJobSource, discriminator='traces'): - agent_id: Optional[str] - agent_name: Optional[str] - agent_version: Optional[str] - description: str - end_time: Optional[datetime] - start_time: datetime - type: Literal[DataGenerationJobSourceType.TRACES] + class azure.ai.projects.models.VoiceAgentTurnDetectionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AZURE_SEMANTIC_VAD = "azure_semantic_vad" + AZURE_SEMANTIC_VAD_EN = "azure_semantic_vad_en" + AZURE_SEMANTIC_VAD_MULTILINGUAL = "azure_semantic_vad_multilingual" + SEMANTIC_VAD = "semantic_vad" + SERVER_VAD = "server_vad" + + + class azure.ai.projects.models.VoiceAudioCodec(str, Enum, metaclass=CaseInsensitiveEnumMeta): + PCM16 = "pcm16" + PCMA = "pcma" + PCMU = "pcmu" + + + class azure.ai.projects.models.VoiceAudioContainerFormat(str, Enum, metaclass=CaseInsensitiveEnumMeta): + WAV = "wav" + + + class azure.ai.projects.models.VoiceAudioItem(_Model): + blob_uri: Optional[str] + channels: Optional[int] + codec: Optional[Union[str, VoiceAudioCodec]] + conversation_id: str + duration_ms: Optional[timedelta] + format: Optional[Union[str, VoiceAudioContainerFormat]] + item_id: str + role: Optional[Union[str, VoiceAudioRole]] + sample_rate: Optional[int] + start_offset_ms: Optional[timedelta] @overload def __init__( self, *, - agent_id: Optional[str] = ..., - agent_name: Optional[str] = ..., - agent_version: Optional[str] = ..., - description: Optional[str] = ..., - end_time: Optional[datetime] = ..., - start_time: datetime + blob_uri: Optional[str] = ..., + channels: Optional[int] = ..., + codec: Optional[Union[str, VoiceAudioCodec]] = ..., + conversation_id: str, + duration_ms: Optional[timedelta] = ..., + format: Optional[Union[str, VoiceAudioContainerFormat]] = ..., + item_id: str, + role: Optional[Union[str, VoiceAudioRole]] = ..., + sample_rate: Optional[int] = ..., + start_offset_ms: Optional[timedelta] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TracesEvaluatorGenerationJobSource(EvaluatorGenerationJobSource, discriminator='traces'): - agent_id: Optional[str] - agent_name: Optional[str] - agent_version: Optional[str] - description: Optional[str] - end_time: Optional[datetime] - start_time: datetime - type: Literal[EvaluatorGenerationJobSourceType.TRACES] + class azure.ai.projects.models.VoiceAudioRole(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AGENT = "agent" + USER = "user" + + + class azure.ai.projects.models.VoiceConversation(_Model): + completed_at: Optional[datetime] + created_at: datetime + id: str + last_error: Optional[ApiError] + metadata: Optional[dict[str, str]] + object: Literal["conversation"] + status: Union[str, VoiceConversationStatus] + usage: Optional[RealtimeResponseUsage] @overload def __init__( self, *, - agent_id: Optional[str] = ..., - agent_name: Optional[str] = ..., - agent_version: Optional[str] = ..., - description: Optional[str] = ..., - end_time: Optional[datetime] = ..., - start_time: datetime + completed_at: Optional[datetime] = ..., + created_at: datetime, + id: str, + last_error: Optional[ApiError] = ..., + metadata: Optional[dict[str, str]] = ..., + status: Union[str, VoiceConversationStatus], + usage: Optional[RealtimeResponseUsage] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TracesPreviewEvalRunDataSource(TypedDict, total=False): - key "agent_id": str - key "agent_name": str - key "end_time": datetime - key "ingestion_delay_seconds": int - key "lookback_hours": int - key "max_traces": int - key "trace_ids": List[str] - key "type": Required[Literal["azure_ai_traces_preview"]] - - - class azure.ai.projects.models.TreatmentEffectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CHANGED = "Changed" - DEGRADED = "Degraded" - IMPROVED = "Improved" - INCONCLUSIVE = "Inconclusive" - TOO_FEW_SAMPLES = "TooFewSamples" - - - class azure.ai.projects.models.Trigger(_Model): + class azure.ai.projects.models.VoiceConversationEngine(_Model): type: str @overload @@ -10421,141 +15896,215 @@ namespace azure.ai.projects.models def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.TriggerType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - CRON = "Cron" - ONE_TIME = "OneTime" - RECURRENCE = "Recurrence" + class azure.ai.projects.models.VoiceConversationStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + COMPLETED = "completed" + FAILED = "failed" + IN_PROGRESS = "in_progress" - class azure.ai.projects.models.UpdateMemoriesLROPoller(LROPoller[MemoryStoreUpdateCompletedResult]): - property superseded_by: Optional[str] # Read-only - property update_id: str # Read-only + class azure.ai.projects.models.VoiceGeneratedAudioItem(_Model): + blob_uri: Optional[str] + channels: Optional[int] + codec: Optional[Union[str, VoiceAudioCodec]] + conversation_id: str + duration_ms: Optional[timedelta] + format: Optional[Union[str, VoiceAudioContainerFormat]] + item_id: str + role: Optional[Union[str, VoiceAudioRole]] + sample_rate: Optional[int] + start_offset_ms: Optional[timedelta] - @classmethod - def from_continuation_token( - cls, - polling_method: PollingMethod[MemoryStoreUpdateCompletedResult], - continuation_token: str, - **kwargs: Any - ) -> UpdateMemoriesLROPoller: ... + @overload + def __init__( + self, + *, + blob_uri: Optional[str] = ..., + channels: Optional[int] = ..., + codec: Optional[Union[str, VoiceAudioCodec]] = ..., + conversation_id: str, + duration_ms: Optional[timedelta] = ..., + format: Optional[Union[str, VoiceAudioContainerFormat]] = ..., + item_id: str, + role: Optional[Union[str, VoiceAudioRole]] = ..., + sample_rate: Optional[int] = ..., + start_offset_ms: Optional[timedelta] = ... + ) -> None: ... + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.UpdateModelVersionRequest(_Model): - description: Optional[str] - tags: Optional[dict[str, str]] + + class azure.ai.projects.models.VoiceHostedAgentConversationEngine(VoiceConversationEngine, discriminator='hosted_agent'): + name: str + type: Literal["hosted_agent"] + version: Optional[str] @overload def __init__( self, *, - description: Optional[str] = ..., - tags: Optional[dict[str, str]] = ... + name: str, + version: Optional[str] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.UpdateToolboxRequest(_Model): - default_version: str + class azure.ai.projects.models.VoiceModelType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + MANAGED = "managed" + SELF_DEPLOYED = "self_deployed" + + + class azure.ai.projects.models.VoiceOutputModality(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ANIMATION = "animation" + AUDIO = "audio" + AVATAR = "avatar" + TEXT = "text" + + + class azure.ai.projects.models.VoiceRecording(_Model): + blob_uri: Optional[str] + channel_layout: VoiceRecordingChannelLayout + channels: int + conversation_id: str + duration_ms: timedelta + format: Union[str, VoiceAudioContainerFormat] + sample_rate: int @overload def __init__( self, *, - default_version: str + blob_uri: Optional[str] = ..., + channel_layout: VoiceRecordingChannelLayout, + channels: int, + conversation_id: str, + duration_ms: timedelta, + format: Union[str, VoiceAudioContainerFormat], + sample_rate: int ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.UserProfileMemoryItem(MemoryItem, discriminator='user_profile'): - content: str - kind: Literal[MemoryItemKind.USER_PROFILE] - memory_id: str - scope: str - updated_at: datetime + class azure.ai.projects.models.VoiceRecordingChannelLayout(_Model): + left: Literal["user"] + right: Literal["agent"] - @overload def __init__( self, - *, - content: str, - memory_id: str, - scope: str, - updated_at: datetime + *args: Any, + **kwargs: Any ) -> None: ... - @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: ... - - class azure.ai.projects.models.VersionIndicator(_Model): - type: str + class azure.ai.projects.models.VoiceResponse(VoiceResponseBase): + audio: Optional[VoiceResponseAudio] + completed_at: Optional[datetime] + conversation_id: str + created_at: Optional[datetime] + id: str + max_output_tokens: Union[int, str] + metadata: Optional[dict[str, str]] + object: str + output: Optional[list[RealtimeConversationItem]] + output_modalities: Union[list[str, str]] + status: Union[str, str, str, str, str] + status_details: RealtimeResponseStatusDetails + temperature: Optional[float] + usage: RealtimeResponseUsage @overload def __init__( self, *, - type: str + audio: Optional[VoiceResponseAudio] = ..., + completed_at: Optional[datetime] = ..., + conversation_id: str, + created_at: Optional[datetime] = ..., + id: str, + max_output_tokens: Optional[Union[int, Literal[inf]]] = ..., + metadata: Optional[dict[str, str]] = ..., + object: Optional[Literal[response]] = ..., + output: Optional[list[RealtimeConversationItem]] = ..., + output_modalities: Optional[list[Literal[text, audio]]] = ..., + status: Optional[Literal[completed, cancelled, failed, incomplete, in_progress]] = ..., + status_details: Optional[RealtimeResponseStatusDetails] = ..., + temperature: Optional[float] = ..., + usage: Optional[RealtimeResponseUsage] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.VersionIndicatorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - VERSION_REF = "version_ref" - - - class azure.ai.projects.models.VersionRefIndicator(VersionIndicator, discriminator='version_ref'): - agent_version: str - type: Literal[VersionIndicatorType.VERSION_REF] + class azure.ai.projects.models.VoiceResponseAudio(_Model): + output: Optional[VoiceResponseAudioOutput] @overload def __init__( self, *, - agent_version: str + output: Optional[VoiceResponseAudioOutput] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.VersionSelectionRule(_Model): - agent_version: str - type: str + class azure.ai.projects.models.VoiceResponseAudioOutput(_Model): + format: Optional[RealtimeAudioFormats] + voice: Optional[str] + voice_locale: Optional[str] + voice_type: Optional[Union[str, VoiceType]] @overload def __init__( self, *, - agent_version: str, - type: str + format: Optional[RealtimeAudioFormats] = ..., + voice: Optional[str] = ..., + voice_locale: Optional[str] = ..., + voice_type: Optional[Union[str, VoiceType]] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.VersionSelector(_Model): - version_selection_rules: list[VersionSelectionRule] + class azure.ai.projects.models.VoiceResponseBase(_Model): + max_output_tokens: Optional[Union[int, Literal["inf"]]] + object: Optional[Literal["response"]] + output_modalities: Optional[list[Literal["text", "audio"]]] + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] + status_details: Optional[RealtimeResponseStatusDetails] + usage: Optional[RealtimeResponseUsage] @overload def __init__( self, *, - version_selection_rules: list[VersionSelectionRule] + max_output_tokens: Optional[Union[int, Literal[inf]]] = ..., + object: Optional[Literal[response]] = ..., + output_modalities: Optional[list[Literal[text, audio]]] = ..., + status: Optional[Literal[completed, cancelled, failed, incomplete, in_progress]] = ..., + status_details: Optional[RealtimeResponseStatusDetails] = ..., + usage: Optional[RealtimeResponseUsage] = ... ) -> None: ... @overload def __init__(self, mapping: Mapping[str, Any]) -> None: ... - class azure.ai.projects.models.VersionSelectorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - FIXED_RATIO = "FixedRatio" + class azure.ai.projects.models.VoiceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + AVATAR_VOICE_SYNC = "avatar-voice-sync" + AZURE_CUSTOM = "azure-custom" + AZURE_PERSONAL = "azure-personal" + AZURE_REALTIME_NATIVE = "azure-realtime-native" + AZURE_STANDARD = "azure-standard" + OPENAI = "openai" class azure.ai.projects.models.WebIQPreviewTool(Tool, discriminator='web_iq_preview'): @@ -11495,6 +17044,13 @@ namespace azure.ai.projects.operations **kwargs: Any ) -> AgentOptimizationJob: ... + @distributed_trace + def create_from_prompt( + self, + body: GenerateAgentRequest, + **kwargs: Any + ) -> AgentDetails: ... + @distributed_trace def delete_optimization_job( self, @@ -11977,60 +17533,267 @@ namespace azure.ai.projects.operations class azure.ai.projects.operations.BetaMemoryStoresOperations(GenerateBetaMemoryStoresOperations): - def __init__( + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + def begin_update_memories( + self, + name: str, + *, + content_type: str = "application/json", + items: Optional[Union[str, ResponseInputParam]] = ..., + previous_update_id: Optional[str] = ..., + scope: str, + update_delay: Optional[int] = ..., + **kwargs: Any + ) -> UpdateMemoriesLROPoller: ... + + @overload + def begin_update_memories( + self, + name: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> UpdateMemoriesLROPoller: ... + + @overload + def begin_update_memories( + self, + name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> UpdateMemoriesLROPoller: ... + + @overload + def create( + self, + *, + content_type: str = "application/json", + definition: MemoryStoreDefinition, + description: Optional[str] = ..., + metadata: Optional[dict[str, str]] = ..., + name: str, + **kwargs: Any + ) -> MemoryStoreDetails: ... + + @overload + def create( + self, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> MemoryStoreDetails: ... + + @overload + def create( + self, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> MemoryStoreDetails: ... + + @overload + def create_memory( + self, + name: str, + *, + content: str, + content_type: str = "application/json", + kind: Union[str, MemoryItemKind], + scope: str, + **kwargs: Any + ) -> MemoryItem: ... + + @overload + def create_memory( + self, + name: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> MemoryItem: ... + + @overload + def create_memory( + self, + name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> MemoryItem: ... + + @distributed_trace + def delete( + self, + name: str, + **kwargs: Any + ) -> DeleteMemoryStoreResult: ... + + @distributed_trace + def delete_memory( + self, + name: str, + memory_id: str, + **kwargs: Any + ) -> DeleteMemoryResult: ... + + @overload + def delete_scope( + self, + name: str, + *, + content_type: str = "application/json", + scope: str, + **kwargs: Any + ) -> MemoryStoreDeleteScopeResult: ... + + @overload + def delete_scope( + self, + name: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> MemoryStoreDeleteScopeResult: ... + + @overload + def delete_scope( + self, + name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> MemoryStoreDeleteScopeResult: ... + + @distributed_trace + def get( + self, + name: str, + **kwargs: Any + ) -> MemoryStoreDetails: ... + + @distributed_trace + def get_memory( + self, + name: str, + memory_id: str, + **kwargs: Any + ) -> MemoryItem: ... + + @distributed_trace + def list( + self, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> ItemPaged[MemoryStoreDetails]: ... + + @overload + def list_memories( + self, + name: str, + *, + before: Optional[str] = ..., + content_type: str = "application/json", + kind: Optional[Union[str, MemoryItemKind]] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + scope: str, + **kwargs: Any + ) -> ItemPaged[MemoryItem]: ... + + @overload + def list_memories( + self, + name: str, + body: JSON, + *, + before: Optional[str] = ..., + content_type: str = "application/json", + kind: Optional[Union[str, MemoryItemKind]] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> ItemPaged[MemoryItem]: ... + + @overload + def list_memories( self, - *args, - **kwargs - ) -> None: ... + name: str, + body: IO[bytes], + *, + before: Optional[str] = ..., + content_type: str = "application/json", + kind: Optional[Union[str, MemoryItemKind]] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., + **kwargs: Any + ) -> ItemPaged[MemoryItem]: ... @overload - def begin_update_memories( + def search_memories( self, name: str, *, content_type: str = "application/json", items: Optional[Union[str, ResponseInputParam]] = ..., - previous_update_id: Optional[str] = ..., + options: Optional[MemorySearchOptions] = ..., + previous_search_id: Optional[str] = ..., scope: str, - update_delay: Optional[int] = ..., **kwargs: Any - ) -> UpdateMemoriesLROPoller: ... + ) -> MemoryStoreSearchResult: ... @overload - def begin_update_memories( + def search_memories( self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> UpdateMemoriesLROPoller: ... + ) -> MemoryStoreSearchResult: ... @overload - def begin_update_memories( + def search_memories( self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> UpdateMemoriesLROPoller: ... + ) -> MemoryStoreSearchResult: ... @overload - def create( + def update( self, + name: str, *, content_type: str = "application/json", - definition: MemoryStoreDefinition, description: Optional[str] = ..., metadata: Optional[dict[str, str]] = ..., - name: str, **kwargs: Any ) -> MemoryStoreDetails: ... @overload - def create( + def update( self, + name: str, body: JSON, *, content_type: str = "application/json", @@ -12038,8 +17801,9 @@ namespace azure.ai.projects.operations ) -> MemoryStoreDetails: ... @overload - def create( + def update( self, + name: str, body: IO[bytes], *, content_type: str = "application/json", @@ -12047,21 +17811,21 @@ namespace azure.ai.projects.operations ) -> MemoryStoreDetails: ... @overload - def create_memory( + def update_memory( self, name: str, + memory_id: str, *, content: str, content_type: str = "application/json", - kind: Union[str, MemoryItemKind], - scope: str, **kwargs: Any ) -> MemoryItem: ... @overload - def create_memory( + def update_memory( self, name: str, + memory_id: str, body: JSON, *, content_type: str = "application/json", @@ -12069,226 +17833,358 @@ namespace azure.ai.projects.operations ) -> MemoryItem: ... @overload - def create_memory( + def update_memory( self, name: str, + memory_id: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any ) -> MemoryItem: ... + + class azure.ai.projects.operations.BetaModelsOperations(BetaModelsOperationsGenerated): + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + def create( + self, + *, + azcopy_path: Optional[str] = ..., + base_model: Optional[str] = ..., + description: Optional[str] = ..., + name: str, + polling_interval: float = 2.0, + polling_timeout: float = 300.0, + source: Union[str, PathLike[str]], + tags: Optional[dict[str, str]] = ..., + version: str, + wait_for_commit: Literal[True] = True, + weight_type: Optional[str] = ..., + **kwargs: Any + ) -> ModelVersion: ... + + @overload + def create( + self, + *, + azcopy_path: Optional[str] = ..., + base_model: Optional[str] = ..., + description: Optional[str] = ..., + name: str, + polling_interval: float = 2.0, + polling_timeout: float = 300.0, + source: Union[str, PathLike[str]], + tags: Optional[dict[str, str]] = ..., + version: str, + wait_for_commit: Literal[False], + weight_type: Optional[str] = ..., + **kwargs: Any + ) -> None: ... + @distributed_trace def delete( self, name: str, + version: str, **kwargs: Any - ) -> DeleteMemoryStoreResult: ... + ) -> None: ... @distributed_trace - def delete_memory( + def get( self, name: str, - memory_id: str, + version: str, **kwargs: Any - ) -> DeleteMemoryResult: ... + ) -> ModelVersion: ... @overload - def delete_scope( + def get_credentials( self, name: str, + version: str, + credential_request: ModelCredentialRequest, *, content_type: str = "application/json", - scope: str, **kwargs: Any - ) -> MemoryStoreDeleteScopeResult: ... + ) -> DatasetCredential: ... @overload - def delete_scope( + def get_credentials( self, name: str, - body: JSON, + version: str, + credential_request: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryStoreDeleteScopeResult: ... + ) -> DatasetCredential: ... @overload - def delete_scope( + def get_credentials( self, name: str, - body: IO[bytes], + version: str, + credential_request: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryStoreDeleteScopeResult: ... + ) -> DatasetCredential: ... @distributed_trace - def get( + def list(self, **kwargs: Any) -> ItemPaged[ModelVersion]: ... + + @distributed_trace + def list_versions( self, name: str, **kwargs: Any - ) -> MemoryStoreDetails: ... + ) -> ItemPaged[ModelVersion]: ... - @distributed_trace - def get_memory( + @overload + def pending_create_version( self, name: str, - memory_id: str, + version: str, + model_version: ModelVersion, + *, + content_type: str = "application/json", **kwargs: Any - ) -> MemoryItem: ... + ) -> CreateAsyncResponse: ... - @distributed_trace - def list( + @overload + def pending_create_version( self, + name: str, + version: str, + model_version: JSON, *, - before: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + content_type: str = "application/json", **kwargs: Any - ) -> ItemPaged[MemoryStoreDetails]: ... + ) -> CreateAsyncResponse: ... @overload - def list_memories( + def pending_create_version( self, name: str, + version: str, + model_version: IO[bytes], *, - before: Optional[str] = ..., content_type: str = "application/json", - kind: Optional[Union[str, MemoryItemKind]] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., - scope: str, **kwargs: Any - ) -> ItemPaged[MemoryItem]: ... + ) -> CreateAsyncResponse: ... @overload - def list_memories( + def pending_upload( self, name: str, - body: JSON, + version: str, + pending_upload_request: ModelPendingUploadRequest, *, - before: Optional[str] = ..., content_type: str = "application/json", - kind: Optional[Union[str, MemoryItemKind]] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> ItemPaged[MemoryItem]: ... + ) -> ModelPendingUploadResponse: ... + + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> ModelPendingUploadResponse: ... + + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> ModelPendingUploadResponse: ... + + @overload + def update( + self, + name: str, + version: str, + model_version_update: UpdateModelVersionRequest, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> ModelVersion: ... + + @overload + def update( + self, + name: str, + version: str, + model_version_update: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> ModelVersion: ... + + @overload + def update( + self, + name: str, + version: str, + model_version_update: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> ModelVersion: ... + + + class azure.ai.projects.operations.BetaOperations(GeneratedBetaOperations): + agent_insight_monitors: BetaAgentInsightMonitorsOperations + agents: BetaAgentsOperations + datasets: BetaDatasetsOperations + evaluation_taxonomies: BetaEvaluationTaxonomiesOperations + evaluators: BetaEvaluatorsOperations + insights: BetaInsightsOperations + memory_stores: BetaMemoryStoresOperations + models: BetaModelsOperations + red_teams: BetaRedTeamsOperations + routines: BetaRoutinesOperations + schedules: BetaSchedulesOperations + skills: BetaSkillsOperations + voice_agents: BetaVoiceAgentsOperations - @overload - def list_memories( + def __init__( self, - name: str, - body: IO[bytes], - *, - before: Optional[str] = ..., - content_type: str = "application/json", - kind: Optional[Union[str, MemoryItemKind]] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + *args: Any, **kwargs: Any - ) -> ItemPaged[MemoryItem]: ... + ) -> None: ... - @overload - def search_memories( + + class azure.ai.projects.operations.BetaRealtime: + + def __init__( self, - name: str, - *, - content_type: str = "application/json", - items: Optional[Union[str, ResponseInputParam]] = ..., - options: Optional[MemorySearchOptions] = ..., - previous_search_id: Optional[str] = ..., - scope: str, + *args: Any, **kwargs: Any - ) -> MemoryStoreSearchResult: ... + ) -> None: ... - @overload - def search_memories( + def connect( self, - name: str, - body: JSON, *, - content_type: str = "application/json", + agent_name: str, + agent_session_id: Optional[str] = ..., + api_version: Optional[str] = ..., + connection_url: Optional[str] = ..., + credential_scopes: Optional[List[str]] = ..., + extra_headers: Optional[Mapping[str, str]] = ..., + extra_query: Optional[Mapping[str, str]] = ..., + structured_inputs: Optional[Mapping[str, Any]] = ..., **kwargs: Any - ) -> MemoryStoreSearchResult: ... + ) -> BetaRealtimeConnectionManager: ... - @overload - def search_memories( + + class azure.ai.projects.operations.BetaRealtimeConnection: implements ContextManager + property closed: bool # Read-only + + def __init__(self, connection: ClientConnection) -> None: ... + + def __iter__(self) -> Iterator[ServerEvent]: ... + + def __repr__(self) -> str: ... + + def close( self, - name: str, - body: IO[bytes], *, - content_type: str = "application/json", - **kwargs: Any - ) -> MemoryStoreSearchResult: ... + code: int = 1000, + reason: str = "" + ) -> None: ... - @overload - def update( + def recv( self, - name: str, *, - content_type: str = "application/json", - description: Optional[str] = ..., - metadata: Optional[dict[str, str]] = ..., - **kwargs: Any - ) -> MemoryStoreDetails: ... + timeout: Optional[float] = ... + ) -> ServerEvent: ... - @overload - def update( + def send(self, event: ClientEvent) -> None: ... + + + class azure.ai.projects.operations.BetaRealtimeConnectionManager: implements ContextManager + + def __init__( self, - name: str, - body: JSON, *, - content_type: str = "application/json", + agent_name: str, + agent_session_id: Optional[str] = ..., + api_version: str, + connection_url: Optional[str] = ..., + credential: TokenCredential, + credential_scopes: List[str], + endpoint: str, + extra_headers: Optional[Mapping[str, str]] = ..., + extra_query: Optional[Mapping[str, str]] = ..., + structured_inputs: Optional[Mapping[str, Any]] = ..., **kwargs: Any - ) -> MemoryStoreDetails: ... + ) -> None: ... + + def enter(self) -> BetaRealtimeConnection: ... + + + class azure.ai.projects.operations.BetaRedTeamsOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... @overload - def update( + def create( self, - name: str, - body: IO[bytes], + red_team: RedTeam, *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryStoreDetails: ... + ) -> RedTeam: ... @overload - def update_memory( + def create( self, - name: str, - memory_id: str, + red_team: JSON, *, - content: str, content_type: str = "application/json", **kwargs: Any - ) -> MemoryItem: ... + ) -> RedTeam: ... @overload - def update_memory( + def create( self, - name: str, - memory_id: str, - body: JSON, + red_team: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> MemoryItem: ... + ) -> RedTeam: ... - @overload - def update_memory( + @distributed_trace + def get( self, name: str, - memory_id: str, - body: IO[bytes], - *, - content_type: str = "application/json", **kwargs: Any - ) -> MemoryItem: ... + ) -> RedTeam: ... + @distributed_trace + def list(self, **kwargs: Any) -> ItemPaged[RedTeam]: ... - class azure.ai.projects.operations.BetaModelsOperations(BetaModelsOperationsGenerated): + + class azure.ai.projects.operations.BetaRoutinesOperations: def __init__( self, @@ -12297,222 +18193,201 @@ namespace azure.ai.projects.operations ) -> None: ... @overload - def create( + def create_or_update( self, + routine_name: str, *, - azcopy_path: Optional[str] = ..., - base_model: Optional[str] = ..., + action: Optional[RoutineAction] = ..., + authorization: Optional[RoutineAuthorization] = ..., + content_type: str = "application/json", description: Optional[str] = ..., - name: str, - polling_interval: float = 2.0, - polling_timeout: float = 300.0, - source: Union[str, PathLike[str]], - tags: Optional[dict[str, str]] = ..., - version: str, - wait_for_commit: Literal[True] = True, - weight_type: Optional[str] = ..., + enabled: Optional[bool] = ..., + triggers: Optional[dict[str, RoutineTrigger]] = ..., **kwargs: Any - ) -> ModelVersion: ... + ) -> Routine: ... @overload - def create( + def create_or_update( self, + routine_name: str, + body: JSON, *, - azcopy_path: Optional[str] = ..., - base_model: Optional[str] = ..., - description: Optional[str] = ..., - name: str, - polling_interval: float = 2.0, - polling_timeout: float = 300.0, - source: Union[str, PathLike[str]], - tags: Optional[dict[str, str]] = ..., - version: str, - wait_for_commit: Literal[False], - weight_type: Optional[str] = ..., + content_type: str = "application/json", **kwargs: Any - ) -> None: ... + ) -> Routine: ... + + @overload + def create_or_update( + self, + routine_name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> Routine: ... @distributed_trace def delete( self, - name: str, - version: str, + routine_name: str, **kwargs: Any ) -> None: ... @distributed_trace - def get( + def disable( self, - name: str, - version: str, + routine_name: str, **kwargs: Any - ) -> ModelVersion: ... + ) -> Routine: ... @overload - def get_credentials( + def dispatch( self, - name: str, - version: str, - credential_request: ModelCredentialRequest, + routine_name: str, *, content_type: str = "application/json", + payload: Optional[RoutineDispatchPayload] = ..., **kwargs: Any - ) -> DatasetCredential: ... + ) -> DispatchRoutineResult: ... @overload - def get_credentials( + def dispatch( self, - name: str, - version: str, - credential_request: JSON, + routine_name: str, + body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> DatasetCredential: ... + ) -> DispatchRoutineResult: ... @overload - def get_credentials( + def dispatch( self, - name: str, - version: str, - credential_request: IO[bytes], + routine_name: str, + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> DatasetCredential: ... + ) -> DispatchRoutineResult: ... @distributed_trace - def list(self, **kwargs: Any) -> ItemPaged[ModelVersion]: ... + def enable( + self, + routine_name: str, + **kwargs: Any + ) -> Routine: ... @distributed_trace - def list_versions( + def get( self, - name: str, + routine_name: str, **kwargs: Any - ) -> ItemPaged[ModelVersion]: ... + ) -> Routine: ... - @overload - def pending_create_version( + @distributed_trace + def list( self, - name: str, - version: str, - model_version: ModelVersion, *, - content_type: str = "application/json", + after: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> CreateAsyncResponse: ... + ) -> ItemPaged[Routine]: ... - @overload - def pending_create_version( + @distributed_trace + def list_runs( self, - name: str, - version: str, - model_version: JSON, + routine_name: str, *, - content_type: str = "application/json", + after: Optional[str] = ..., + filter: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> CreateAsyncResponse: ... + ) -> ItemPaged[RoutineRun]: ... + + + class azure.ai.projects.operations.BetaSchedulesOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... @overload - def pending_create_version( + def create_or_update( self, - name: str, - version: str, - model_version: IO[bytes], + schedule_id: str, + schedule: Schedule, *, content_type: str = "application/json", **kwargs: Any - ) -> CreateAsyncResponse: ... + ) -> Schedule: ... @overload - def pending_upload( + def create_or_update( self, - name: str, - version: str, - pending_upload_request: ModelPendingUploadRequest, + schedule_id: str, + schedule: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> ModelPendingUploadResponse: ... + ) -> Schedule: ... @overload - def pending_upload( + def create_or_update( self, - name: str, - version: str, - pending_upload_request: JSON, + schedule_id: str, + schedule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> ModelPendingUploadResponse: ... + ) -> Schedule: ... - @overload - def pending_upload( + @distributed_trace + def delete( self, - name: str, - version: str, - pending_upload_request: IO[bytes], - *, - content_type: str = "application/json", + schedule_id: str, **kwargs: Any - ) -> ModelPendingUploadResponse: ... + ) -> None: ... - @overload - def update( + @distributed_trace + def get( self, - name: str, - version: str, - model_version_update: UpdateModelVersionRequest, - *, - content_type: str = "application/merge-patch+json", + schedule_id: str, **kwargs: Any - ) -> ModelVersion: ... + ) -> Schedule: ... - @overload - def update( + @distributed_trace + def get_run( self, - name: str, - version: str, - model_version_update: JSON, - *, - content_type: str = "application/merge-patch+json", + schedule_id: str, + run_id: str, **kwargs: Any - ) -> ModelVersion: ... + ) -> ScheduleRun: ... - @overload - def update( + @distributed_trace + def list( self, - name: str, - version: str, - model_version_update: IO[bytes], *, - content_type: str = "application/merge-patch+json", + enabled: Optional[bool] = ..., + type: Optional[Union[str, ScheduleTaskType]] = ..., **kwargs: Any - ) -> ModelVersion: ... - - - class azure.ai.projects.operations.BetaOperations(GeneratedBetaOperations): - agent_insight_monitors: BetaAgentInsightMonitorsOperations - agents: BetaAgentsOperations - datasets: BetaDatasetsOperations - evaluation_taxonomies: BetaEvaluationTaxonomiesOperations - evaluators: BetaEvaluatorsOperations - insights: BetaInsightsOperations - memory_stores: BetaMemoryStoresOperations - models: BetaModelsOperations - red_teams: BetaRedTeamsOperations - routines: BetaRoutinesOperations - schedules: BetaSchedulesOperations - skills: BetaSkillsOperations + ) -> ItemPaged[Schedule]: ... - def __init__( + @distributed_trace + def list_runs( self, - *args: Any, + schedule_id: str, + *, + enabled: Optional[bool] = ..., + type: Optional[Union[str, ScheduleTaskType]] = ..., **kwargs: Any - ) -> None: ... + ) -> ItemPaged[ScheduleRun]: ... - class azure.ai.projects.operations.BetaRedTeamsOperations: + class azure.ai.projects.operations.BetaSkillsOperations: def __init__( self, @@ -12523,245 +18398,303 @@ namespace azure.ai.projects.operations @overload def create( self, - red_team: RedTeam, + name: str, *, content_type: str = "application/json", + default: Optional[bool] = ..., + inline_content: Optional[SkillInlineContent] = ..., **kwargs: Any - ) -> RedTeam: ... + ) -> SkillVersion: ... @overload def create( self, - red_team: JSON, + name: str, + body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> RedTeam: ... + ) -> SkillVersion: ... @overload def create( self, - red_team: IO[bytes], + name: str, + body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> RedTeam: ... + ) -> SkillVersion: ... - @distributed_trace - def get( + @overload + def create_from_files( self, name: str, + content: CreateSkillVersionFromFilesBody, **kwargs: Any - ) -> RedTeam: ... + ) -> SkillVersion: ... - @distributed_trace - def list(self, **kwargs: Any) -> ItemPaged[RedTeam]: ... + @overload + def create_from_files( + self, + name: str, + content: JSON, + **kwargs: Any + ) -> SkillVersion: ... + @distributed_trace + def delete( + self, + name: str, + **kwargs: Any + ) -> DeleteSkillResult: ... - class azure.ai.projects.operations.BetaRoutinesOperations: + @distributed_trace + def delete_version( + self, + name: str, + version: str, + **kwargs: Any + ) -> DeleteSkillVersionResult: ... - def __init__( + @distributed_trace + def download( self, - *args, - **kwargs - ) -> None: ... + name: str, + **kwargs: Any + ) -> Iterator[bytes]: ... - @overload - def create_or_update( + @distributed_trace + def download_version( self, - routine_name: str, - *, - action: Optional[RoutineAction] = ..., - authorization: Optional[RoutineAuthorization] = ..., - content_type: str = "application/json", - description: Optional[str] = ..., - enabled: Optional[bool] = ..., - triggers: Optional[dict[str, RoutineTrigger]] = ..., + name: str, + version: str, **kwargs: Any - ) -> Routine: ... + ) -> Iterator[bytes]: ... - @overload - def create_or_update( + @distributed_trace + def get( self, - routine_name: str, - body: JSON, - *, - content_type: str = "application/json", + name: str, **kwargs: Any - ) -> Routine: ... + ) -> SkillDetails: ... - @overload - def create_or_update( + @distributed_trace + def get_version( self, - routine_name: str, - body: IO[bytes], - *, - content_type: str = "application/json", + name: str, + version: str, **kwargs: Any - ) -> Routine: ... + ) -> SkillVersion: ... @distributed_trace - def delete( + def list( self, - routine_name: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> None: ... + ) -> ItemPaged[SkillDetails]: ... @distributed_trace - def disable( + def list_versions( self, - routine_name: str, + name: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> Routine: ... + ) -> ItemPaged[SkillVersion]: ... @overload - def dispatch( + def update( self, - routine_name: str, + name: str, *, content_type: str = "application/json", - payload: Optional[RoutineDispatchPayload] = ..., + default_version: str, **kwargs: Any - ) -> DispatchRoutineResult: ... + ) -> SkillDetails: ... @overload - def dispatch( + def update( self, - routine_name: str, + name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> DispatchRoutineResult: ... + ) -> SkillDetails: ... @overload - def dispatch( + def update( self, - routine_name: str, + name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> DispatchRoutineResult: ... + ) -> SkillDetails: ... + + + class azure.ai.projects.operations.BetaVoiceAgentsConversationsOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace + def delete( + self, + agent_name: str, + conversation_id: str, + **kwargs: Any + ) -> None: ... + + @distributed_trace + def download_audio( + self, + agent_name: str, + conversation_id: str, + **kwargs: Any + ) -> Iterator[bytes]: ... @distributed_trace - def enable( + def download_audio_item( self, - routine_name: str, + agent_name: str, + conversation_id: str, + item_id: str, **kwargs: Any - ) -> Routine: ... + ) -> Iterator[bytes]: ... @distributed_trace - def get( + def download_generated_audio_item( self, - routine_name: str, + agent_name: str, + conversation_id: str, + item_id: str, **kwargs: Any - ) -> Routine: ... + ) -> Iterator[bytes]: ... @distributed_trace - def list( + def get( self, - *, - after: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + agent_name: str, + conversation_id: str, **kwargs: Any - ) -> ItemPaged[Routine]: ... + ) -> VoiceConversation: ... @distributed_trace - def list_runs( + def get_audio( self, - routine_name: str, - *, - after: Optional[str] = ..., - filter: Optional[str] = ..., - limit: Optional[int] = ..., - order: Optional[Union[str, PageOrder]] = ..., + agent_name: str, + conversation_id: str, **kwargs: Any - ) -> ItemPaged[RoutineRun]: ... - - - class azure.ai.projects.operations.BetaSchedulesOperations: - - def __init__( - self, - *args, - **kwargs - ) -> None: ... + ) -> VoiceRecording: ... - @overload - def create_or_update( + @distributed_trace + def get_audio_item( self, - schedule_id: str, - schedule: Schedule, - *, - content_type: str = "application/json", + agent_name: str, + conversation_id: str, + item_id: str, **kwargs: Any - ) -> Schedule: ... + ) -> VoiceAudioItem: ... - @overload - def create_or_update( + @distributed_trace + def get_generated_audio_item( self, - schedule_id: str, - schedule: JSON, - *, - content_type: str = "application/json", + agent_name: str, + conversation_id: str, + item_id: str, **kwargs: Any - ) -> Schedule: ... + ) -> VoiceGeneratedAudioItem: ... - @overload - def create_or_update( + @distributed_trace + def get_item( self, - schedule_id: str, - schedule: IO[bytes], - *, - content_type: str = "application/json", + agent_name: str, + conversation_id: str, + item_id: str, **kwargs: Any - ) -> Schedule: ... + ) -> RealtimeConversationItem: ... @distributed_trace - def delete( + def get_response( self, - schedule_id: str, + agent_name: str, + conversation_id: str, + response_id: str, **kwargs: Any - ) -> None: ... + ) -> VoiceResponse: ... @distributed_trace - def get( + def list( self, - schedule_id: str, + agent_name: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> Schedule: ... + ) -> ItemPaged[VoiceConversation]: ... @distributed_trace - def get_run( + def list_items( self, - schedule_id: str, - run_id: str, + agent_name: str, + conversation_id: str, + *, + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> ScheduleRun: ... + ) -> ItemPaged[RealtimeConversationItem]: ... @distributed_trace - def list( + def list_response_items( self, + agent_name: str, + conversation_id: str, + response_id: str, *, - enabled: Optional[bool] = ..., - type: Optional[Union[str, ScheduleTaskType]] = ..., + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> ItemPaged[Schedule]: ... + ) -> ItemPaged[RealtimeConversationItem]: ... @distributed_trace - def list_runs( + def list_responses( self, - schedule_id: str, + agent_name: str, + conversation_id: str, *, - enabled: Optional[bool] = ..., - type: Optional[Union[str, ScheduleTaskType]] = ..., + before: Optional[str] = ..., + limit: Optional[int] = ..., + order: Optional[Union[str, PageOrder]] = ..., **kwargs: Any - ) -> ItemPaged[ScheduleRun]: ... + ) -> ItemPaged[VoiceResponse]: ... - class azure.ai.projects.operations.BetaSkillsOperations: + class azure.ai.projects.operations.BetaVoiceAgentsOperations(GeneratedBetaVoiceAgentsOperations): + conversations: BetaVoiceAgentsConversationsOperations + realtime: BetaRealtime + telephony: BetaVoiceAgentsTelephonyOperations + + def __init__( + self, + *args: Any, + **kwargs: Any + ) -> None: ... + + + class azure.ai.projects.operations.BetaVoiceAgentsTelephonyOperations: def __init__( self, @@ -12769,148 +18702,265 @@ namespace azure.ai.projects.operations **kwargs ) -> None: ... + @distributed_trace + def cancel_call_job( + self, + agent_name: str, + call_job_id: str, + *, + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyCallJob: ... + @overload - def create( + def create_binding( self, - name: str, + agent_name: str, + telephony_binding: CreateTelephonyBindingRequest, *, content_type: str = "application/json", - default: Optional[bool] = ..., - inline_content: Optional[SkillInlineContent] = ..., **kwargs: Any - ) -> SkillVersion: ... + ) -> TelephonyBinding: ... @overload - def create( + def create_binding( self, - name: str, - body: JSON, + agent_name: str, + telephony_binding: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> SkillVersion: ... + ) -> TelephonyBinding: ... @overload - def create( + def create_binding( self, - name: str, - body: IO[bytes], + agent_name: str, + telephony_binding: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> SkillVersion: ... + ) -> TelephonyBinding: ... @overload - def create_from_files( + def create_call_job( self, - name: str, - content: CreateSkillVersionFromFilesBody, + agent_name: str, + body: CreateTelephonyCallJobRequest, + *, + content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> SkillVersion: ... + ) -> TelephonyCallJob: ... @overload - def create_from_files( + def create_call_job( self, - name: str, - content: JSON, + agent_name: str, + body: JSON, + *, + content_type: str = "application/json", + idempotency_key: str, **kwargs: Any - ) -> SkillVersion: ... + ) -> TelephonyCallJob: ... + + @overload + def create_call_job( + self, + agent_name: str, + body: IO[bytes], + *, + content_type: str = "application/json", + idempotency_key: str, + **kwargs: Any + ) -> TelephonyCallJob: ... @distributed_trace - def delete( + def delete_binding( self, - name: str, + agent_name: str, + binding_id: str, + *, + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> DeleteSkillResult: ... + ) -> None: ... @distributed_trace - def delete_version( + def end_call( self, - name: str, - version: str, + agent_name: str, + call_id: str, **kwargs: Any - ) -> DeleteSkillVersionResult: ... + ) -> TelephonyCallRecord: ... @distributed_trace - def download( + def get_binding( self, - name: str, + agent_name: str, + binding_id: str, **kwargs: Any - ) -> Iterator[bytes]: ... + ) -> TelephonyBinding: ... @distributed_trace - def download_version( + def get_call( self, - name: str, - version: str, + agent_name: str, + call_id: str, **kwargs: Any - ) -> Iterator[bytes]: ... + ) -> TelephonyCallRecord: ... @distributed_trace - def get( + def get_call_job( self, - name: str, + agent_name: str, + call_job_id: str, **kwargs: Any - ) -> SkillDetails: ... + ) -> TelephonyCallJob: ... @distributed_trace - def get_version( + def get_transfer_targets( self, - name: str, - version: str, + agent_name: str, **kwargs: Any - ) -> SkillVersion: ... + ) -> TelephonyTransferTargets: ... @distributed_trace - def list( + def list_bindings( self, + agent_name: str, *, before: Optional[str] = ..., limit: Optional[int] = ..., order: Optional[Union[str, PageOrder]] = ..., + provider: Optional[Union[str, TelephonyProvider]] = ..., + status: Optional[Union[str, TelephonyBindingStatus]] = ..., **kwargs: Any - ) -> ItemPaged[SkillDetails]: ... + ) -> ItemPaged[TelephonyBindingListItem]: ... @distributed_trace - def list_versions( + def list_calls( self, - name: str, + agent_name: str, *, before: Optional[str] = ..., limit: Optional[int] = ..., order: Optional[Union[str, PageOrder]] = ..., + provider: Optional[Union[str, TelephonyProvider]] = ..., + started_after_time: Optional[datetime] = ..., + started_before_time: Optional[datetime] = ..., + status: Optional[Union[str, TelephonyCallStatus]] = ..., **kwargs: Any - ) -> ItemPaged[SkillVersion]: ... + ) -> ItemPaged[TelephonyCallSummary]: ... @overload - def update( + def replace_transfer_targets( self, - name: str, + agent_name: str, *, content_type: str = "application/json", - default_version: str, + etag: str, + match_condition: MatchConditions, + transfer_targets: List[TelephonyTransferTarget], **kwargs: Any - ) -> SkillDetails: ... + ) -> TelephonyTransferTargets: ... @overload - def update( + def replace_transfer_targets( self, - name: str, + agent_name: str, body: JSON, *, content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> SkillDetails: ... + ) -> TelephonyTransferTargets: ... @overload - def update( + def replace_transfer_targets( self, - name: str, + agent_name: str, body: IO[bytes], *, content_type: str = "application/json", + etag: str, + match_condition: MatchConditions, **kwargs: Any - ) -> SkillDetails: ... + ) -> TelephonyTransferTargets: ... + + @overload + def transfer_call( + self, + agent_name: str, + call_id: str, + *, + content_type: str = "application/json", + target: str, + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @overload + def transfer_call( + self, + agent_name: str, + call_id: str, + body: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @overload + def transfer_call( + self, + agent_name: str, + call_id: str, + body: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> TelephonyCallRecord: ... + + @overload + def update_binding( + self, + agent_name: str, + binding_id: str, + body: UpdateTelephonyBindingRequest, + *, + content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyBinding: ... + + @overload + def update_binding( + self, + agent_name: str, + binding_id: str, + body: JSON, + *, + content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyBinding: ... + + @overload + def update_binding( + self, + agent_name: str, + binding_id: str, + body: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> TelephonyBinding: ... class azure.ai.projects.operations.ConnectionsOperations(ConnectionsOperationsGenerated): @@ -13318,6 +19368,14 @@ namespace azure.ai.projects.operations **kwargs: Any ) -> ToolboxVersionObject: ... + @distributed_trace + def invoke_latest_toolbox_mcp( + self, + name: str, + request: dict[str, Any], + **kwargs: Any + ) -> Any: ... + @distributed_trace def list( self, diff --git a/sdk/ai/azure-ai-projects/api.metadata.yml b/sdk/ai/azure-ai-projects/api.metadata.yml index 66437be855bb..a6ed5d2aa7d2 100644 --- a/sdk/ai/azure-ai-projects/api.metadata.yml +++ b/sdk/ai/azure-ai-projects/api.metadata.yml @@ -1,4 +1,4 @@ -apiMdSha256: 1c370b038da6576b8d7c25941e2c895706bca3773521fbe51610b10fb5ccc967 -packageVersion: 2.6.1 +apiMdSha256: 938e87f2a714420f8211659300eb320b023c2250a7c49c0d58a28dc3cb5028b6 +packageVersion: 2.7.0 parserVersion: 0.3.31 pythonVersion: 3.12.10 diff --git a/sdk/ai/azure-ai-projects/apiview-properties.json b/sdk/ai/azure-ai-projects/apiview-properties.json index 12ce353dd066..3f0b1c69dc2c 100644 --- a/sdk/ai/azure-ai-projects/apiview-properties.json +++ b/sdk/ai/azure-ai-projects/apiview-properties.json @@ -24,6 +24,7 @@ "azure.ai.projects.models.AgentEndpointConfig": "Azure.AI.Projects.AgentEndpointConfig", "azure.ai.projects.models.EvaluatorGenerationJobSource": "Azure.AI.Projects.EvaluatorGenerationJobSource", "azure.ai.projects.models.AgentEvaluatorGenerationJobSource": "Azure.AI.Projects.AgentEvaluatorGenerationJobSource", + "azure.ai.projects.models.AgentHarness": "Azure.AI.Projects.AgentHarness", "azure.ai.projects.models.BaseCredentials": "Azure.AI.Projects.BaseCredentials", "azure.ai.projects.models.AgenticIdentityPreviewCredentials": "Azure.AI.Projects.AgenticIdentityPreviewCredentials", "azure.ai.projects.models.AgentIdentity": "Azure.AI.Projects.AgentIdentity", @@ -73,7 +74,7 @@ "azure.ai.projects.models.ApproximateLocation": "OpenAI.ApproximateLocation", "azure.ai.projects.models.ArtifactProfile": "Azure.AI.Projects.ArtifactProfile", "azure.ai.projects.models.AutoCodeInterpreterToolParam": "OpenAI.AutoCodeInterpreterToolParam", - "azure.ai.projects.models.EvaluationTarget": "Azure.AI.Projects.Target", + "azure.ai.projects.models.EvaluationTarget": "Azure.AI.Projects.FoundryEvaluationTarget", "azure.ai.projects.models.AzureAIAgentTarget": "Azure.AI.Projects.AzureAIAgentTarget", "azure.ai.projects.models.AzureAIModelTarget": "Azure.AI.Projects.AzureAIModelTarget", "azure.ai.projects.models.Index": "Azure.AI.Projects.Index", @@ -132,6 +133,11 @@ "azure.ai.projects.models.CosmosDBIndex": "Azure.AI.Projects.CosmosDBIndex", "azure.ai.projects.models.CreateAsyncResponse": "Azure.AI.Projects.createAsync.Response.anonymous", "azure.ai.projects.models.CreateSkillVersionFromFilesBody": "Azure.AI.Projects.CreateSkillVersionFromFilesBody", + "azure.ai.projects.models.CreateTelephonyBindingRequest": "Azure.AI.Projects.CreateTelephonyBindingRequest", + "azure.ai.projects.models.CreateTeamsPhoneExtensionTelephonyBindingRequest": "Azure.AI.Projects.CreateTeamsPhoneExtensionTelephonyBindingRequest", + "azure.ai.projects.models.CreateTelephonyCallJobRequest": "Azure.AI.Projects.CreateTelephonyCallJobRequest", + "azure.ai.projects.models.CreateTranscriptionResponseJsonUsage": "OpenAI.CreateTranscriptionResponseJsonUsage", + "azure.ai.projects.models.CreateTwilioTelephonyBindingRequest": "Azure.AI.Projects.CreateTwilioTelephonyBindingRequest", "azure.ai.projects.models.Trigger": "Azure.AI.Projects.Trigger", "azure.ai.projects.models.CronTrigger": "Azure.AI.Projects.CronTrigger", "azure.ai.projects.models.CustomCredential": "Azure.AI.Projects.CustomCredential", @@ -211,6 +217,11 @@ "azure.ai.projects.models.FunctionShellToolParamEnvironmentLocalEnvironmentParam": "OpenAI.FunctionShellToolParamEnvironmentLocalEnvironmentParam", "azure.ai.projects.models.FunctionTool": "OpenAI.FunctionTool", "azure.ai.projects.models.FunctionToolParam": "OpenAI.FunctionToolParam", + "azure.ai.projects.models.GenerateVoiceAgentRequest": "Azure.AI.Projects.GenerateVoiceAgentRequest", + "azure.ai.projects.models.GitHubCopilotHarness": "Azure.AI.Projects.GitHubCopilotHarness", + "azure.ai.projects.models.GitHubCopilotToolsetConfig": "Azure.AI.Projects.GitHubCopilotToolsetConfig", + "azure.ai.projects.models.GitHubCopilotToolsetDefaultConfig": "Azure.AI.Projects.GitHubCopilotToolsetDefaultConfig", + "azure.ai.projects.models.GitHubCopilotToolsetPreview": "Azure.AI.Projects.GitHubCopilotToolsetPreview", "azure.ai.projects.models.GitHubIssueRoutineTrigger": "Azure.AI.Projects.GitHubIssueRoutineTrigger", "azure.ai.projects.models.TelemetryEndpointAuth": "Azure.AI.Projects.TelemetryEndpointAuth", "azure.ai.projects.models.HeaderTelemetryEndpointAuth": "Azure.AI.Projects.HeaderTelemetryEndpointAuth", @@ -238,9 +249,13 @@ "azure.ai.projects.models.InvokeAgentResponsesApiRoutineAction": "Azure.AI.Projects.InvokeAgentResponsesApiRoutineAction", "azure.ai.projects.models.LocalShellToolParam": "OpenAI.LocalShellToolParam", "azure.ai.projects.models.LocalSkillParam": "OpenAI.LocalSkillParam", + "azure.ai.projects.models.LogProbProperties": "OpenAI.LogProbProperties", "azure.ai.projects.models.LoraConfig": "Azure.AI.Projects.LoraConfig", "azure.ai.projects.models.ManagedAgentIdentityBlueprintReference": "Azure.AI.Projects.ManagedAgentIdentityBlueprintReference", "azure.ai.projects.models.ManagedAzureAISearchIndex": "Azure.AI.Projects.ManagedAzureAISearchIndex", + "azure.ai.projects.models.MCPListToolsTool": "OpenAI.MCPListToolsTool", + "azure.ai.projects.models.MCPListToolsToolAnnotations": "OpenAI.MCPListToolsToolAnnotations", + "azure.ai.projects.models.MCPListToolsToolInputSchema": "OpenAI.MCPListToolsToolInputSchema", "azure.ai.projects.models.McpProtocolConfiguration": "Azure.AI.Projects.McpProtocolConfiguration", "azure.ai.projects.models.MCPTool": "OpenAI.MCPTool", "azure.ai.projects.models.MCPToolboxTool": "Azure.AI.Projects.MCPToolboxTool", @@ -259,6 +274,7 @@ "azure.ai.projects.models.MemoryStoreSearchResult": "Azure.AI.Projects.MemoryStoreSearchResponse", "azure.ai.projects.models.MemoryStoreUpdateCompletedResult": "Azure.AI.Projects.MemoryStoreUpdateCompletedResult", "azure.ai.projects.models.MemoryStoreUpdateResult": "Azure.AI.Projects.MemoryStoreUpdateResponse", + "azure.ai.projects.models.Metadata": "OpenAI.Metadata", "azure.ai.projects.models.Microsoft365PermissionScopes": "Azure.AI.Projects.Microsoft365PermissionScopes", "azure.ai.projects.models.Microsoft365PublishDefaults": "Azure.AI.Projects.Microsoft365PublishDefaults", "azure.ai.projects.models.Microsoft365PublishResult": "Azure.AI.Projects.Microsoft365PublishResponse", @@ -290,6 +306,7 @@ "azure.ai.projects.models.OtlpTelemetryEndpoint": "Azure.AI.Projects.OtlpTelemetryEndpoint", "azure.ai.projects.models.PendingUploadRequest": "Azure.AI.Projects.PendingUploadRequest", "azure.ai.projects.models.PendingUploadResponse": "Azure.AI.Projects.PendingUploadResponse", + "azure.ai.projects.models.PickPropertiesVoiceAgentAudioConfig": "TypeSpec.PickProperties", "azure.ai.projects.models.ProceduralMemoryItem": "Azure.AI.Projects.ProceduralMemoryItem", "azure.ai.projects.models.ProgrammaticToolCallingParam": "OpenAI.ProgrammaticToolCallingParam", "azure.ai.projects.models.PromotionInfo": "Azure.AI.Projects.PromotionInfo", @@ -300,8 +317,102 @@ "azure.ai.projects.models.PromptEvaluatorGenerationJobSource": "Azure.AI.Projects.PromptEvaluatorGenerationJobSource", "azure.ai.projects.models.ProtocolConfiguration": "Azure.AI.Projects.ProtocolConfiguration", "azure.ai.projects.models.ProtocolVersionRecord": "Azure.AI.Projects.ProtocolVersionRecord", + "azure.ai.projects.models.TelephonyTransferDestination": "Azure.AI.Projects.TelephonyTransferDestination", + "azure.ai.projects.models.PSTNTelephonyTransferDestination": "Azure.AI.Projects.PSTNTelephonyTransferDestination", "azure.ai.projects.models.RaiConfig": "Azure.AI.Projects.RaiConfig", + "azure.ai.projects.models.RaiInvocationModeration": "Azure.AI.Projects.RaiInvocationModeration", + "azure.ai.projects.models.RaiSseTextSelector": "Azure.AI.Projects.RaiSseTextSelector", "azure.ai.projects.models.RankingOptions": "OpenAI.RankingOptions", + "azure.ai.projects.models.RealtimeAudioFormats": "OpenAI.RealtimeAudioFormats", + "azure.ai.projects.models.RealtimeAudioFormatsAudioPcm": "OpenAI.RealtimeAudioFormatsAudioPcm", + "azure.ai.projects.models.RealtimeAudioFormatsAudioPcma": "OpenAI.RealtimeAudioFormatsAudioPcma", + "azure.ai.projects.models.RealtimeAudioFormatsAudioPcmu": "OpenAI.RealtimeAudioFormatsAudioPcmu", + "azure.ai.projects.models.RealtimeClientEvent": "OpenAI.RealtimeClientEvent", + "azure.ai.projects.models.RealtimeClientEventConversationItemCreate": "OpenAI.RealtimeClientEventConversationItemCreate", + "azure.ai.projects.models.RealtimeClientEventConversationItemDelete": "OpenAI.RealtimeClientEventConversationItemDelete", + "azure.ai.projects.models.RealtimeClientEventConversationItemRetrieve": "OpenAI.RealtimeClientEventConversationItemRetrieve", + "azure.ai.projects.models.RealtimeClientEventConversationItemTruncate": "OpenAI.RealtimeClientEventConversationItemTruncate", + "azure.ai.projects.models.RealtimeClientEventInputAudioBufferAppend": "OpenAI.RealtimeClientEventInputAudioBufferAppend", + "azure.ai.projects.models.RealtimeClientEventInputAudioBufferClear": "OpenAI.RealtimeClientEventInputAudioBufferClear", + "azure.ai.projects.models.RealtimeClientEventInputAudioBufferCommit": "OpenAI.RealtimeClientEventInputAudioBufferCommit", + "azure.ai.projects.models.RealtimeClientEventOutputAudioBufferClear": "OpenAI.RealtimeClientEventOutputAudioBufferClear", + "azure.ai.projects.models.RealtimeClientEventResponseCancel": "OpenAI.RealtimeClientEventResponseCancel", + "azure.ai.projects.models.RealtimeClientEventResponseCreate": "OpenAI.RealtimeClientEventResponseCreate", + "azure.ai.projects.models.RealtimeConversationItem": "OpenAI.RealtimeConversationItem", + "azure.ai.projects.models.RealtimeConversationItemFunctionCall": "OpenAI.RealtimeConversationItemFunctionCall", + "azure.ai.projects.models.RealtimeConversationItemFunctionCallOutput": "OpenAI.RealtimeConversationItemFunctionCallOutput", + "azure.ai.projects.models.RealtimeConversationItemMessage": "OpenAI.RealtimeConversationItemMessage", + "azure.ai.projects.models.RealtimeConversationItemMessageAssistant": "OpenAI.RealtimeConversationItemMessageAssistant", + "azure.ai.projects.models.RealtimeConversationItemMessageAssistantContent": "OpenAI.RealtimeConversationItemMessageAssistantContent", + "azure.ai.projects.models.RealtimeConversationItemMessageSystem": "OpenAI.RealtimeConversationItemMessageSystem", + "azure.ai.projects.models.RealtimeConversationItemMessageSystemContent": "OpenAI.RealtimeConversationItemMessageSystemContent", + "azure.ai.projects.models.RealtimeConversationItemMessageUser": "OpenAI.RealtimeConversationItemMessageUser", + "azure.ai.projects.models.RealtimeConversationItemMessageUserContent": "OpenAI.RealtimeConversationItemMessageUserContent", + "azure.ai.projects.models.RealtimeFunctionTool": "OpenAI.RealtimeFunctionTool", + "azure.ai.projects.models.RealtimeFunctionToolParameters": "OpenAI.RealtimeFunctionToolParameters", + "azure.ai.projects.models.RealtimeMCPApprovalRequest": "OpenAI.RealtimeMCPApprovalRequest", + "azure.ai.projects.models.RealtimeMCPApprovalResponse": "OpenAI.RealtimeMCPApprovalResponse", + "azure.ai.projects.models.RealtimeMCPError": "OpenAI.RealtimeMCPError", + "azure.ai.projects.models.RealtimeMCPHTTPError": "OpenAI.RealtimeMCPHTTPError", + "azure.ai.projects.models.RealtimeMCPListTools": "OpenAI.RealtimeMCPListTools", + "azure.ai.projects.models.RealtimeMCPProtocolError": "OpenAI.RealtimeMCPProtocolError", + "azure.ai.projects.models.RealtimeMCPToolCall": "OpenAI.RealtimeMCPToolCall", + "azure.ai.projects.models.RealtimeMCPToolExecutionError": "OpenAI.RealtimeMCPToolExecutionError", + "azure.ai.projects.models.RealtimeReasoning": "OpenAI.RealtimeReasoning", + "azure.ai.projects.models.RealtimeResponseStatusDetails": "OpenAI.RealtimeResponseStatusDetails", + "azure.ai.projects.models.RealtimeResponseStatusDetailsError": "OpenAI.RealtimeResponseStatusDetailsError", + "azure.ai.projects.models.RealtimeResponseUsage": "OpenAI.RealtimeResponseUsage", + "azure.ai.projects.models.RealtimeResponseUsageInputTokenDetails": "OpenAI.RealtimeResponseUsageInputTokenDetails", + "azure.ai.projects.models.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails": "OpenAI.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails", + "azure.ai.projects.models.RealtimeResponseUsageOutputTokenDetails": "OpenAI.RealtimeResponseUsageOutputTokenDetails", + "azure.ai.projects.models.RealtimeServerEvent": "OpenAI.RealtimeServerEvent", + "azure.ai.projects.models.RealtimeServerEventConversationItemAdded": "OpenAI.RealtimeServerEventConversationItemAdded", + "azure.ai.projects.models.RealtimeServerEventConversationItemCreated": "OpenAI.RealtimeServerEventConversationItemCreated", + "azure.ai.projects.models.RealtimeServerEventConversationItemDeleted": "OpenAI.RealtimeServerEventConversationItemDeleted", + "azure.ai.projects.models.RealtimeServerEventConversationItemDone": "OpenAI.RealtimeServerEventConversationItemDone", + "azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted": "OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted", + "azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta": "OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionDelta", + "azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed": "OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionFailed", + "azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError": "OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError", + "azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment": "OpenAI.RealtimeServerEventConversationItemInputAudioTranscriptionSegment", + "azure.ai.projects.models.RealtimeServerEventConversationItemRetrieved": "OpenAI.RealtimeServerEventConversationItemRetrieved", + "azure.ai.projects.models.RealtimeServerEventConversationItemTruncated": "OpenAI.RealtimeServerEventConversationItemTruncated", + "azure.ai.projects.models.RealtimeServerEventError": "OpenAI.RealtimeServerEventError", + "azure.ai.projects.models.RealtimeServerEventErrorError": "OpenAI.RealtimeServerEventErrorError", + "azure.ai.projects.models.RealtimeServerEventInputAudioBufferCleared": "OpenAI.RealtimeServerEventInputAudioBufferCleared", + "azure.ai.projects.models.RealtimeServerEventInputAudioBufferCommitted": "OpenAI.RealtimeServerEventInputAudioBufferCommitted", + "azure.ai.projects.models.RealtimeServerEventInputAudioBufferSpeechStarted": "OpenAI.RealtimeServerEventInputAudioBufferSpeechStarted", + "azure.ai.projects.models.RealtimeServerEventInputAudioBufferSpeechStopped": "OpenAI.RealtimeServerEventInputAudioBufferSpeechStopped", + "azure.ai.projects.models.RealtimeServerEventInputAudioBufferTimeoutTriggered": "OpenAI.RealtimeServerEventInputAudioBufferTimeoutTriggered", + "azure.ai.projects.models.RealtimeServerEventMCPListToolsCompleted": "OpenAI.RealtimeServerEventMCPListToolsCompleted", + "azure.ai.projects.models.RealtimeServerEventMCPListToolsFailed": "OpenAI.RealtimeServerEventMCPListToolsFailed", + "azure.ai.projects.models.RealtimeServerEventMCPListToolsInProgress": "OpenAI.RealtimeServerEventMCPListToolsInProgress", + "azure.ai.projects.models.RealtimeServerEventOutputAudioBufferCleared": "OpenAI.RealtimeServerEventOutputAudioBufferCleared", + "azure.ai.projects.models.RealtimeServerEventRateLimitsUpdated": "OpenAI.RealtimeServerEventRateLimitsUpdated", + "azure.ai.projects.models.RealtimeServerEventRateLimitsUpdatedRateLimits": "OpenAI.RealtimeServerEventRateLimitsUpdatedRateLimits", + "azure.ai.projects.models.RealtimeServerEventResponseAudioDelta": "OpenAI.RealtimeServerEventResponseAudioDelta", + "azure.ai.projects.models.RealtimeServerEventResponseAudioDone": "OpenAI.RealtimeServerEventResponseAudioDone", + "azure.ai.projects.models.RealtimeServerEventResponseAudioTranscriptDelta": "OpenAI.RealtimeServerEventResponseAudioTranscriptDelta", + "azure.ai.projects.models.RealtimeServerEventResponseAudioTranscriptDone": "OpenAI.RealtimeServerEventResponseAudioTranscriptDone", + "azure.ai.projects.models.RealtimeServerEventResponseContentPartAdded": "OpenAI.RealtimeServerEventResponseContentPartAdded", + "azure.ai.projects.models.RealtimeServerEventResponseContentPartAddedPart": "OpenAI.RealtimeServerEventResponseContentPartAddedPart", + "azure.ai.projects.models.RealtimeServerEventResponseContentPartDone": "OpenAI.RealtimeServerEventResponseContentPartDone", + "azure.ai.projects.models.RealtimeServerEventResponseContentPartDonePart": "OpenAI.RealtimeServerEventResponseContentPartDonePart", + "azure.ai.projects.models.RealtimeServerEventResponseCreated": "OpenAI.RealtimeServerEventResponseCreated", + "azure.ai.projects.models.RealtimeServerEventResponseDone": "OpenAI.RealtimeServerEventResponseDone", + "azure.ai.projects.models.RealtimeServerEventResponseFunctionCallArgumentsDelta": "OpenAI.RealtimeServerEventResponseFunctionCallArgumentsDelta", + "azure.ai.projects.models.RealtimeServerEventResponseFunctionCallArgumentsDone": "OpenAI.RealtimeServerEventResponseFunctionCallArgumentsDone", + "azure.ai.projects.models.RealtimeServerEventResponseMCPCallArgumentsDelta": "OpenAI.RealtimeServerEventResponseMCPCallArgumentsDelta", + "azure.ai.projects.models.RealtimeServerEventResponseMCPCallArgumentsDone": "OpenAI.RealtimeServerEventResponseMCPCallArgumentsDone", + "azure.ai.projects.models.RealtimeServerEventResponseMCPCallCompleted": "OpenAI.RealtimeServerEventResponseMCPCallCompleted", + "azure.ai.projects.models.RealtimeServerEventResponseMCPCallFailed": "OpenAI.RealtimeServerEventResponseMCPCallFailed", + "azure.ai.projects.models.RealtimeServerEventResponseMCPCallInProgress": "OpenAI.RealtimeServerEventResponseMCPCallInProgress", + "azure.ai.projects.models.RealtimeServerEventResponseOutputItemAdded": "OpenAI.RealtimeServerEventResponseOutputItemAdded", + "azure.ai.projects.models.RealtimeServerEventResponseOutputItemDone": "OpenAI.RealtimeServerEventResponseOutputItemDone", + "azure.ai.projects.models.RealtimeServerEventResponseTextDelta": "OpenAI.RealtimeServerEventResponseTextDelta", + "azure.ai.projects.models.RealtimeServerEventResponseTextDone": "OpenAI.RealtimeServerEventResponseTextDone", + "azure.ai.projects.models.RealtimeServerEventSessionCreated": "OpenAI.RealtimeServerEventSessionCreated", + "azure.ai.projects.models.RealtimeServerEventSessionUpdated": "OpenAI.RealtimeServerEventSessionUpdated", "azure.ai.projects.models.Reasoning": "OpenAI.Reasoning", "azure.ai.projects.models.RecurrenceTrigger": "Azure.AI.Projects.RecurrenceTrigger", "azure.ai.projects.models.RedTeam": "Azure.AI.Projects.RedTeam", @@ -327,8 +438,10 @@ "azure.ai.projects.models.ShellToolboxTool": "Azure.AI.Projects.ShellToolboxTool", "azure.ai.projects.models.SimpleQnADataGenerationJobOptions": "Azure.AI.Projects.SimpleQnADataGenerationJobOptions", "azure.ai.projects.models.SimulationSeedDataGenerationJobOptions": "Azure.AI.Projects.SimulationSeedDataGenerationJobOptions", + "azure.ai.projects.models.SipTelephonyTransferDestination": "Azure.AI.Projects.SipTelephonyTransferDestination", "azure.ai.projects.models.SkillDetails": "Azure.AI.Projects.Skill", "azure.ai.projects.models.SkillInlineContent": "Azure.AI.Projects.SkillInlineContent", + "azure.ai.projects.models.SkillReference": "Azure.AI.Projects.SkillReference", "azure.ai.projects.models.SkillReferenceParam": "OpenAI.SkillReferenceParam", "azure.ai.projects.models.SkillVersion": "Azure.AI.Projects.SkillVersion", "azure.ai.projects.models.ToolChoiceParam": "OpenAI.ToolChoiceParam", @@ -339,7 +452,25 @@ "azure.ai.projects.models.StructuredOutputDefinition": "Azure.AI.Projects.StructuredOutputDefinition", "azure.ai.projects.models.TaxonomyCategory": "Azure.AI.Projects.TaxonomyCategory", "azure.ai.projects.models.TaxonomySubCategory": "Azure.AI.Projects.TaxonomySubCategory", + "azure.ai.projects.models.TelephonyBinding": "Azure.AI.Projects.TelephonyBinding", + "azure.ai.projects.models.TeamsPhoneExtensionTelephonyBinding": "Azure.AI.Projects.TeamsPhoneExtensionTelephonyBinding", + "azure.ai.projects.models.TelephonyBindingListItem": "Azure.AI.Projects.TelephonyBindingListItem", + "azure.ai.projects.models.TeamsPhoneExtensionTelephonyBindingListItem": "Azure.AI.Projects.TeamsPhoneExtensionTelephonyBindingListItem", + "azure.ai.projects.models.TeamsTelephonyTransferDestination": "Azure.AI.Projects.TeamsTelephonyTransferDestination", "azure.ai.projects.models.TelemetryConfig": "Azure.AI.Projects.TelemetryConfig", + "azure.ai.projects.models.TelephonyCallJob": "Azure.AI.Projects.TelephonyCallJob", + "azure.ai.projects.models.TelephonyCallJobCancellation": "Azure.AI.Projects.TelephonyCallJobCancellation", + "azure.ai.projects.models.TelephonyCallJobSchedule": "Azure.AI.Projects.TelephonyCallJobSchedule", + "azure.ai.projects.models.TelephonyCallLifecycleEvent": "Azure.AI.Projects.TelephonyCallLifecycleEvent", + "azure.ai.projects.models.TelephonyCallRecord": "Azure.AI.Projects.TelephonyCallRecord", + "azure.ai.projects.models.TelephonyCallSummary": "Azure.AI.Projects.TelephonyCallSummary", + "azure.ai.projects.models.TelephonyCallTiming": "Azure.AI.Projects.TelephonyCallTiming", + "azure.ai.projects.models.TelephonyCallTrace": "Azure.AI.Projects.TelephonyCallTrace", + "azure.ai.projects.models.TelephonyOutboundDestination": "Azure.AI.Projects.TelephonyOutboundDestination", + "azure.ai.projects.models.TelephonyOutboundRetryPolicy": "Azure.AI.Projects.TelephonyOutboundRetryPolicy", + "azure.ai.projects.models.TelephonyOutboundFixedIntervalRetryPolicy": "Azure.AI.Projects.TelephonyOutboundFixedIntervalRetryPolicy", + "azure.ai.projects.models.TelephonyTransferTarget": "Azure.AI.Projects.TelephonyTransferTarget", + "azure.ai.projects.models.TelephonyTransferTargets": "Azure.AI.Projects.TelephonyTransferTargets", "azure.ai.projects.models.TextResponseFormat": "OpenAI.TextResponseFormatConfiguration", "azure.ai.projects.models.TextResponseFormatJsonObject": "OpenAI.TextResponseFormatConfigurationResponseFormatJsonObject", "azure.ai.projects.models.TextResponseFormatJsonSchema": "OpenAI.TextResponseFormatJsonSchema", @@ -356,6 +487,7 @@ "azure.ai.projects.models.ToolboxSkill": "Azure.AI.Projects.ToolboxSkill", "azure.ai.projects.models.ToolboxSkillReference": "Azure.AI.Projects.ToolboxSkillReference", "azure.ai.projects.models.ToolboxVersionObject": "Azure.AI.Projects.ToolboxVersionObject", + "azure.ai.projects.models.ToolboxVersions": "Azure.AI.Projects.ToolboxVersions", "azure.ai.projects.models.ToolChoiceAllowed": "OpenAI.ToolChoiceAllowed", "azure.ai.projects.models.ToolChoiceCodeInterpreter": "OpenAI.ToolChoiceCodeInterpreter", "azure.ai.projects.models.ToolChoiceComputer": "OpenAI.ToolChoiceComputer", @@ -377,12 +509,96 @@ "azure.ai.projects.models.TracesDataGenerationJobOptions": "Azure.AI.Projects.TracesDataGenerationJobOptions", "azure.ai.projects.models.TracesDataGenerationJobSource": "Azure.AI.Projects.TracesDataGenerationJobSource", "azure.ai.projects.models.TracesEvaluatorGenerationJobSource": "Azure.AI.Projects.TracesEvaluatorGenerationJobSource", + "azure.ai.projects.models.TranscriptionLanguage": "OpenAI.TranscriptionLanguage", + "azure.ai.projects.models.TranscriptTextUsageDuration": "OpenAI.TranscriptTextUsageDuration", + "azure.ai.projects.models.TranscriptTextUsageTokens": "OpenAI.TranscriptTextUsageTokens", + "azure.ai.projects.models.TranscriptTextUsageTokensInputTokenDetails": "OpenAI.TranscriptTextUsageTokensInputTokenDetails", + "azure.ai.projects.models.TwilioTelephonyBinding": "Azure.AI.Projects.TwilioTelephonyBinding", + "azure.ai.projects.models.TwilioTelephonyBindingListItem": "Azure.AI.Projects.TwilioTelephonyBindingListItem", "azure.ai.projects.models.UpdateModelVersionRequest": "Azure.AI.Projects.UpdateModelVersionRequest", + "azure.ai.projects.models.UpdateTelephonyBindingRequest": "Azure.AI.Projects.UpdateTelephonyBindingRequest", "azure.ai.projects.models.UpdateToolboxRequest": "Azure.AI.Projects.UpdateToolboxRequest", "azure.ai.projects.models.UserProfileMemoryItem": "Azure.AI.Projects.UserProfileMemoryItem", "azure.ai.projects.models.VersionIndicator": "Azure.AI.Projects.VersionIndicator", "azure.ai.projects.models.VersionRefIndicator": "Azure.AI.Projects.VersionRefIndicator", "azure.ai.projects.models.VersionSelector": "Azure.AI.Projects.VersionSelector", + "azure.ai.projects.models.VoiceAgentAnimationConfig": "Azure.AI.Projects.VoiceAgentAnimationConfig", + "azure.ai.projects.models.VoiceAgentAudioConfig": "Azure.AI.Projects.VoiceAgentAudioConfig", + "azure.ai.projects.models.VoiceAgentAudioInputConfig": "Azure.AI.Projects.VoiceAgentAudioInputConfig", + "azure.ai.projects.models.VoiceAgentAudioOutputConfig": "Azure.AI.Projects.VoiceAgentAudioOutputConfig", + "azure.ai.projects.models.VoiceAgentAvatarConfig": "Azure.AI.Projects.VoiceAgentAvatarConfig", + "azure.ai.projects.models.VoiceAgentAvatarIceServer": "Azure.AI.Projects.VoiceAgentAvatarIceServer", + "azure.ai.projects.models.VoiceAgentAvatarScene": "Azure.AI.Projects.VoiceAgentAvatarScene", + "azure.ai.projects.models.VoiceAgentAvatarVideoBackground": "Azure.AI.Projects.VoiceAgentAvatarVideoBackground", + "azure.ai.projects.models.VoiceAgentAvatarVideoCrop": "Azure.AI.Projects.VoiceAgentAvatarVideoCrop", + "azure.ai.projects.models.VoiceAgentAvatarVideoParams": "Azure.AI.Projects.VoiceAgentAvatarVideoParams", + "azure.ai.projects.models.VoiceAgentAvatarVideoResolution": "Azure.AI.Projects.VoiceAgentAvatarVideoResolution", + "azure.ai.projects.models.VoiceAgentTurnDetectionConfig": "Azure.AI.Projects.VoiceAgentTurnDetectionConfig", + "azure.ai.projects.models.VoiceAgentAzureSemanticVadEnTurnDetection": "Azure.AI.Projects.VoiceAgentAzureSemanticVadEnTurnDetection", + "azure.ai.projects.models.VoiceAgentAzureSemanticVadMultilingualTurnDetection": "Azure.AI.Projects.VoiceAgentAzureSemanticVadMultilingualTurnDetection", + "azure.ai.projects.models.VoiceAgentAzureSemanticVadTurnDetection": "Azure.AI.Projects.VoiceAgentAzureSemanticVadTurnDetection", + "azure.ai.projects.models.VoiceAgentClientEventRtcCallSdpCreate": "Azure.AI.Projects.VoiceAgentClientEventRtcCallSdpCreate", + "azure.ai.projects.models.VoiceAgentClientEventSessionAvatarConnect": "Azure.AI.Projects.VoiceAgentClientEventSessionAvatarConnect", + "azure.ai.projects.models.VoiceAgentClientEventSessionUpdate": "Azure.AI.Projects.VoiceAgentClientEventSessionUpdate", + "azure.ai.projects.models.VoiceAgentDefinition": "Azure.AI.Projects.VoiceAgentDefinition", + "azure.ai.projects.models.VoiceAgentEchoCancellation": "Azure.AI.Projects.VoiceAgentEchoCancellation", + "azure.ai.projects.models.VoiceAgentTool": "Azure.AI.Projects.VoiceAgentTool", + "azure.ai.projects.models.VoiceAgentSystemTool": "Azure.AI.Projects.VoiceAgentSystemTool", + "azure.ai.projects.models.VoiceAgentEndConversationSystemTool": "Azure.AI.Projects.VoiceAgentEndConversationSystemTool", + "azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection": "Azure.AI.Projects.VoiceAgentEndOfUtteranceDetection", + "azure.ai.projects.models.VoiceAgentFunctionTool": "Azure.AI.Projects.VoiceAgentFunctionTool", + "azure.ai.projects.models.VoiceAgentGreetingConfig": "Azure.AI.Projects.VoiceAgentGreetingConfig", + "azure.ai.projects.models.VoiceAgentInputTranscription": "Azure.AI.Projects.VoiceAgentInputTranscription", + "azure.ai.projects.models.VoiceAgentInterimResponseConfig": "Azure.AI.Projects.VoiceAgentInterimResponseConfig", + "azure.ai.projects.models.VoiceAgentLlmGeneratedGreetingConfig": "Azure.AI.Projects.VoiceAgentLlmGeneratedGreetingConfig", + "azure.ai.projects.models.VoiceAgentLlmInterimResponseConfig": "Azure.AI.Projects.VoiceAgentLlmInterimResponseConfig", + "azure.ai.projects.models.VoiceAgentMcpTool": "Azure.AI.Projects.VoiceAgentMcpTool", + "azure.ai.projects.models.VoiceAgentNoiseReduction": "Azure.AI.Projects.VoiceAgentNoiseReduction", + "azure.ai.projects.models.VoiceAgentRealtimeResponseBase": "Azure.AI.Projects.VoiceAgentRealtimeResponseBase", + "azure.ai.projects.models.VoiceAgentRealtimeResponse": "Azure.AI.Projects.VoiceAgentRealtimeResponse", + "azure.ai.projects.models.VoiceAgentResponseCreateParams": "Azure.AI.Projects.VoiceAgentResponseCreateParams", + "azure.ai.projects.models.VoiceAgentRtcCallErrorDetails": "Azure.AI.Projects.VoiceAgentRtcCallErrorDetails", + "azure.ai.projects.models.VoiceAgentSemanticVadTurnDetection": "Azure.AI.Projects.VoiceAgentSemanticVadTurnDetection", + "azure.ai.projects.models.VoiceAgentServerEventResponseAnimationBlendshapesDelta": "Azure.AI.Projects.VoiceAgentServerEventResponseAnimationBlendshapesDelta", + "azure.ai.projects.models.VoiceAgentServerEventResponseAnimationBlendshapesDone": "Azure.AI.Projects.VoiceAgentServerEventResponseAnimationBlendshapesDone", + "azure.ai.projects.models.VoiceAgentServerEventResponseAnimationVisemeDelta": "Azure.AI.Projects.VoiceAgentServerEventResponseAnimationVisemeDelta", + "azure.ai.projects.models.VoiceAgentServerEventResponseAnimationVisemeDone": "Azure.AI.Projects.VoiceAgentServerEventResponseAnimationVisemeDone", + "azure.ai.projects.models.VoiceAgentServerEventResponseAudioTimestampDelta": "Azure.AI.Projects.VoiceAgentServerEventResponseAudioTimestampDelta", + "azure.ai.projects.models.VoiceAgentServerEventResponseAudioTimestampDone": "Azure.AI.Projects.VoiceAgentServerEventResponseAudioTimestampDone", + "azure.ai.projects.models.VoiceAgentServerEventResponseVideoDelta": "Azure.AI.Projects.VoiceAgentServerEventResponseVideoDelta", + "azure.ai.projects.models.VoiceAgentServerEventRtcCallError": "Azure.AI.Projects.VoiceAgentServerEventRtcCallError", + "azure.ai.projects.models.VoiceAgentServerEventRtcCallSdpCreated": "Azure.AI.Projects.VoiceAgentServerEventRtcCallSdpCreated", + "azure.ai.projects.models.VoiceAgentServerEventSessionAvatarConnecting": "Azure.AI.Projects.VoiceAgentServerEventSessionAvatarConnecting", + "azure.ai.projects.models.VoiceAgentServerEventSessionAvatarSwitchToIdle": "Azure.AI.Projects.VoiceAgentServerEventSessionAvatarSwitchToIdle", + "azure.ai.projects.models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking": "Azure.AI.Projects.VoiceAgentServerEventSessionAvatarSwitchToSpeaking", + "azure.ai.projects.models.VoiceAgentServerEventSessionSubagentAborted": "Azure.AI.Projects.VoiceAgentServerEventSessionSubagentAborted", + "azure.ai.projects.models.VoiceAgentServerEventSessionSubagentCompleted": "Azure.AI.Projects.VoiceAgentServerEventSessionSubagentCompleted", + "azure.ai.projects.models.VoiceAgentServerEventSessionSubagentStarted": "Azure.AI.Projects.VoiceAgentServerEventSessionSubagentStarted", + "azure.ai.projects.models.VoiceAgentServerEventWarning": "Azure.AI.Projects.VoiceAgentServerEventWarning", + "azure.ai.projects.models.VoiceAgentServerEventWarningDetails": "Azure.AI.Projects.VoiceAgentServerEventWarningDetails", + "azure.ai.projects.models.VoiceAgentServerVadTurnDetection": "Azure.AI.Projects.VoiceAgentServerVadTurnDetection", + "azure.ai.projects.models.VoiceAgentSessionAvatarConfig": "Azure.AI.Projects.VoiceAgentSessionAvatarConfig", + "azure.ai.projects.models.VoiceAgentSessionResponseConfig": "Azure.AI.Projects.VoiceAgentSessionResponseConfig", + "azure.ai.projects.models.VoiceAgentSessionUpdateConfig": "Azure.AI.Projects.VoiceAgentSessionUpdateConfig", + "azure.ai.projects.models.VoiceAgentStaticInterimResponseConfig": "Azure.AI.Projects.VoiceAgentStaticInterimResponseConfig", + "azure.ai.projects.models.VoiceAgentSubagent": "Azure.AI.Projects.VoiceAgentSubagent", + "azure.ai.projects.models.VoiceAgentSubagentConfig": "Azure.AI.Projects.VoiceAgentSubagentConfig", + "azure.ai.projects.models.VoiceAgentSubagentResponsePolicy": "Azure.AI.Projects.VoiceAgentSubagentResponsePolicy", + "azure.ai.projects.models.VoiceAgentTemplateGreetingConfig": "Azure.AI.Projects.VoiceAgentTemplateGreetingConfig", + "azure.ai.projects.models.VoiceAgentToolboxTool": "Azure.AI.Projects.VoiceAgentToolboxTool", + "azure.ai.projects.models.VoiceAgentTranscriptionPhrase": "Azure.AI.Projects.VoiceAgentTranscriptionPhrase", + "azure.ai.projects.models.VoiceAgentTranscriptionWord": "Azure.AI.Projects.VoiceAgentTranscriptionWord", + "azure.ai.projects.models.VoiceAudioItem": "Azure.AI.Projects.VoiceAudioItem", + "azure.ai.projects.models.VoiceConversation": "Azure.AI.Projects.VoiceConversation", + "azure.ai.projects.models.VoiceConversationEngine": "Azure.AI.Projects.VoiceConversationEngine", + "azure.ai.projects.models.VoiceGeneratedAudioItem": "Azure.AI.Projects.VoiceGeneratedAudioItem", + "azure.ai.projects.models.VoiceHostedAgentConversationEngine": "Azure.AI.Projects.VoiceHostedAgentConversationEngine", + "azure.ai.projects.models.VoiceRecording": "Azure.AI.Projects.VoiceRecording", + "azure.ai.projects.models.VoiceRecordingChannelLayout": "Azure.AI.Projects.VoiceRecordingChannelLayout", + "azure.ai.projects.models.VoiceResponseBase": "Azure.AI.Projects.VoiceResponseBase", + "azure.ai.projects.models.VoiceResponse": "Azure.AI.Projects.VoiceResponse", + "azure.ai.projects.models.VoiceResponseAudio": "Azure.AI.Projects.VoiceResponseAudio", + "azure.ai.projects.models.VoiceResponseAudioOutput": "Azure.AI.Projects.VoiceResponseAudioOutput", "azure.ai.projects.models.WebIQPreviewTool": "Azure.AI.Projects.WebIQPreviewTool", "azure.ai.projects.models.WebIQPreviewToolboxTool": "Azure.AI.Projects.WebIQPreviewToolboxTool", "azure.ai.projects.models.WebSearchApproximateLocation": "OpenAI.WebSearchApproximateLocation", @@ -395,15 +611,48 @@ "azure.ai.projects.models.WorkflowAgentDefinition": "Azure.AI.Projects.WorkflowAgentDefinition", "azure.ai.projects.models.WorkIQPreviewTool": "Azure.AI.Projects.WorkIQPreviewTool", "azure.ai.projects.models.WorkIQPreviewToolboxTool": "Azure.AI.Projects.WorkIQPreviewToolboxTool", + "azure.ai.projects.models.VoiceConversationStatus": "Azure.AI.Projects.VoiceConversationStatus", "azure.ai.projects.models.PageOrder": "Azure.AI.Projects.PageOrder", - "azure.ai.projects.models.AgentInsightOverviewSource": "Azure.AI.Projects.AgentInsightOverviewSource", - "azure.ai.projects.models.JobStatus": "Azure.AI.Projects.JobStatus", - "azure.ai.projects.models.AgentInsightRunTrigger": "Azure.AI.Projects.AgentInsightRunTrigger", - "azure.ai.projects.models.AgentInsightSeverity": "Azure.AI.Projects.AgentInsightSeverity", - "azure.ai.projects.models.AgentInsightStatus": "Azure.AI.Projects.AgentInsightStatus", - "azure.ai.projects.models.AgentInsightProposedFixKind": "Azure.AI.Projects.AgentInsightProposedFixKind", - "azure.ai.projects.models.AgentInsightPromptSurface": "Azure.AI.Projects.AgentInsightPromptSurface", - "azure.ai.projects.models.EvaluationTaxonomyInputType": "Azure.AI.Projects.EvaluationTaxonomyInputType", + "azure.ai.projects.models.RealtimeConversationItemType": "OpenAI.RealtimeConversationItemType", + "azure.ai.projects.models.RealtimeMcpErrorType": "OpenAI.RealtimeMcpErrorType", + "azure.ai.projects.models.RealtimeConversationItemMessageType": "OpenAI.RealtimeConversationItemMessageType", + "azure.ai.projects.models.VoiceType": "Azure.AI.Projects.VoiceType", + "azure.ai.projects.models.RealtimeAudioFormatsType": "OpenAI.RealtimeAudioFormatsType", + "azure.ai.projects.models.VoiceAudioRole": "Azure.AI.Projects.VoiceAudioRole", + "azure.ai.projects.models.VoiceAudioContainerFormat": "Azure.AI.Projects.VoiceAudioContainerFormat", + "azure.ai.projects.models.VoiceAudioCodec": "Azure.AI.Projects.VoiceAudioCodec", + "azure.ai.projects.models.TelephonyProvider": "Azure.AI.Projects.TelephonyProvider", + "azure.ai.projects.models.TelephonyBindingStatus": "Azure.AI.Projects.TelephonyBindingStatus", + "azure.ai.projects.models.TelephonyCallStatus": "Azure.AI.Projects.TelephonyCallStatus", + "azure.ai.projects.models.TelephonyCallPhase": "Azure.AI.Projects.TelephonyCallPhase", + "azure.ai.projects.models.TelephonyCallEndReason": "Azure.AI.Projects.TelephonyCallEndReason", + "azure.ai.projects.models.TelephonyCallDurationBasis": "Azure.AI.Projects.TelephonyCallDurationBasis", + "azure.ai.projects.models.TelephonyCallTimestampSource": "Azure.AI.Projects.TelephonyCallTimestampSource", + "azure.ai.projects.models.TelephonyCallTraceStatus": "Azure.AI.Projects.TelephonyCallTraceStatus", + "azure.ai.projects.models.TelephonyCallTraceMode": "Azure.AI.Projects.TelephonyCallTraceMode", + "azure.ai.projects.models.TelephonyCallLifecycleEventName": "Azure.AI.Projects.TelephonyCallLifecycleEventName", + "azure.ai.projects.models.TelephonyCallLifecycleEventSource": "Azure.AI.Projects.TelephonyCallLifecycleEventSource", + "azure.ai.projects.models.TelephonyCallLifecycleEventOutcome": "Azure.AI.Projects.TelephonyCallLifecycleEventOutcome", + "azure.ai.projects.models.TelephonyCallLifecycleEventReason": "Azure.AI.Projects.TelephonyCallLifecycleEventReason", + "azure.ai.projects.models.TelephonyTransferDestinationKind": "Azure.AI.Projects.TelephonyTransferDestinationKind", + "azure.ai.projects.models.TelephonyOutboundDestinationType": "Azure.AI.Projects.TelephonyOutboundDestinationType", + "azure.ai.projects.models.TelephonyCallJobStatus": "Azure.AI.Projects.TelephonyCallJobStatus", + "azure.ai.projects.models.TelephonyOutboundRetryPolicyType": "Azure.AI.Projects.TelephonyOutboundRetryPolicyType", + "azure.ai.projects.models.TelephonyCallJobTerminalReason": "Azure.AI.Projects.TelephonyCallJobTerminalReason", + "azure.ai.projects.models.AgentObjectType": "Azure.AI.Projects.AgentObjectType", + "azure.ai.projects.models.AgentState": "Azure.AI.Projects.AgentState", + "azure.ai.projects.models.AgentStateSource": "Azure.AI.Projects.AgentStateSource", + "azure.ai.projects.models.AgentKind": "Azure.AI.Projects.AgentKind", + "azure.ai.projects.models.RaiInvocationContentType": "Azure.AI.Projects.RaiInvocationContentType", + "azure.ai.projects.models.RaiInvocationMode": "Azure.AI.Projects.RaiInvocationMode", + "azure.ai.projects.models.AgentEndpointProtocol": "Azure.AI.Projects.AgentEndpointProtocol", + "azure.ai.projects.models.CodeDependencyResolution": "Azure.AI.Projects.CodeDependencyResolution", + "azure.ai.projects.models.TelemetryEndpointKind": "Azure.AI.Projects.TelemetryEndpointKind", + "azure.ai.projects.models.TelemetryDataKind": "Azure.AI.Projects.TelemetryDataKind", + "azure.ai.projects.models.TelemetryEndpointAuthType": "Azure.AI.Projects.TelemetryEndpointAuthType", + "azure.ai.projects.models.TelemetryTransportProtocol": "Azure.AI.Projects.TelemetryTransportProtocol", + "azure.ai.projects.models.ReasoningModeEnum": "OpenAI.ReasoningModeEnum", + "azure.ai.projects.models.ReasoningEffort": "OpenAI.ReasoningEffort", "azure.ai.projects.models.ToolType": "OpenAI.ToolType", "azure.ai.projects.models.A2AProtocolVersion": "Azure.AI.Projects.A2AProtocolVersion", "azure.ai.projects.models.CallableToolAllowedCaller": "OpenAI.CallableToolAllowedCaller", @@ -414,6 +663,7 @@ "azure.ai.projects.models.CustomToolParamFormatType": "OpenAI.CustomToolParamFormatType", "azure.ai.projects.models.GrammarSyntax1": "OpenAI.GrammarSyntax1", "azure.ai.projects.models.RankerVersionType": "OpenAI.RankerVersionType", + "azure.ai.projects.models.GitHubCopilotBuiltInTool": "Azure.AI.Projects.GitHubCopilotBuiltInTool", "azure.ai.projects.models.InputFidelity": "OpenAI.InputFidelity", "azure.ai.projects.models.ImageGenAction": "OpenAI.ImageGenActionEnum", "azure.ai.projects.models.OpenApiAuthType": "Azure.AI.Projects.OpenApiAuthType", @@ -422,10 +672,44 @@ "azure.ai.projects.models.ToolSearchExecutionType": "OpenAI.ToolSearchExecutionType", "azure.ai.projects.models.SearchContextSize": "OpenAI.SearchContextSize", "azure.ai.projects.models.SearchContentType": "OpenAI.SearchContentType", + "azure.ai.projects.models.ToolChoiceParamType": "OpenAI.ToolChoiceParamType", + "azure.ai.projects.models.TextResponseFormatConfigurationType": "OpenAI.TextResponseFormatConfigurationType", + "azure.ai.projects.models.VoiceModelType": "Azure.AI.Projects.VoiceModelType", + "azure.ai.projects.models.VoiceAgentNoiseReductionType": "Azure.AI.Projects.VoiceAgentNoiseReductionType", + "azure.ai.projects.models.VoiceAgentTurnDetectionType": "Azure.AI.Projects.VoiceAgentTurnDetectionType", + "azure.ai.projects.models.VoiceAgentEndOfUtteranceDetectionModel": "Azure.AI.Projects.VoiceAgentEndOfUtteranceDetectionModel", + "azure.ai.projects.models.VoiceAgentEndOfUtteranceThresholdLevel": "Azure.AI.Projects.VoiceAgentEndOfUtteranceThresholdLevel", + "azure.ai.projects.models.VoiceAgentEchoCancellationReferenceSource": "Azure.AI.Projects.VoiceAgentEchoCancellationReferenceSource", + "azure.ai.projects.models.VoiceAgentInputTranscriptionModel": "Azure.AI.Projects.VoiceAgentInputTranscriptionModel", + "azure.ai.projects.models.VoiceAgentAudioTimestampType": "Azure.AI.Projects.VoiceAgentAudioTimestampType", + "azure.ai.projects.models.VoiceOutputModality": "Azure.AI.Projects.VoiceOutputModality", + "azure.ai.projects.models.VoiceAgentSessionIncludeOption": "Azure.AI.Projects.VoiceAgentSessionIncludeOption", + "azure.ai.projects.models.VoiceAgentInterimResponseTrigger": "Azure.AI.Projects.VoiceAgentInterimResponseTrigger", + "azure.ai.projects.models.VoiceAgentAvatarType": "Azure.AI.Projects.VoiceAgentAvatarType", + "azure.ai.projects.models.VoiceAgentAvatarOutputProtocol": "Azure.AI.Projects.VoiceAgentAvatarOutputProtocol", + "azure.ai.projects.models.VoiceAgentToolResponseScheduling": "Azure.AI.Projects.VoiceAgentToolResponseScheduling", + "azure.ai.projects.models.VoiceAgentSystemToolName": "Azure.AI.Projects.VoiceAgentSystemToolName", + "azure.ai.projects.models.AgentVersionStatus": "Azure.AI.Projects.AgentVersionStatus", + "azure.ai.projects.models.AgentIdentityStatus": "Azure.AI.Projects.AgentIdentityStatus", + "azure.ai.projects.models.AgentBlueprintReferenceType": "Azure.AI.Projects.AgentBlueprintReferenceType", + "azure.ai.projects.models.VersionSelectorType": "Azure.AI.Projects.VersionSelectorType", + "azure.ai.projects.models.ActivityProtocolAccessBoundary": "Azure.AI.Projects.ActivityProtocolAccessBoundary", + "azure.ai.projects.models.AgentEndpointAuthorizationSchemeType": "Azure.AI.Projects.AgentEndpointAuthorizationSchemeType", + "azure.ai.projects.models.PublishApprovalStatus": "Azure.AI.Projects.PublishApprovalStatus", + "azure.ai.projects.models.DigitalWorkerType": "Azure.AI.Projects.DigitalWorkerType", + "azure.ai.projects.models.AgentOptimizationDatasetInputType": "Azure.AI.Projects.AgentOptimizationDatasetInputType", + "azure.ai.projects.models.EvaluationLevel": "Azure.AI.Projects.EvaluationLevel", + "azure.ai.projects.models.JobStatus": "Azure.AI.Projects.JobStatus", + "azure.ai.projects.models.AgentInsightOverviewSource": "Azure.AI.Projects.AgentInsightOverviewSource", + "azure.ai.projects.models.AgentInsightRunTrigger": "Azure.AI.Projects.AgentInsightRunTrigger", + "azure.ai.projects.models.AgentInsightSeverity": "Azure.AI.Projects.AgentInsightSeverity", + "azure.ai.projects.models.AgentInsightStatus": "Azure.AI.Projects.AgentInsightStatus", + "azure.ai.projects.models.AgentInsightProposedFixKind": "Azure.AI.Projects.AgentInsightProposedFixKind", + "azure.ai.projects.models.AgentInsightPromptSurface": "Azure.AI.Projects.AgentInsightPromptSurface", + "azure.ai.projects.models.EvaluationTaxonomyInputType": "Azure.AI.Projects.EvaluationTaxonomyInputType", "azure.ai.projects.models.RiskCategory": "Azure.AI.Projects.RiskCategory", "azure.ai.projects.models.EvaluatorType": "Azure.AI.Projects.EvaluatorType", "azure.ai.projects.models.EvaluatorCategory": "Azure.AI.Projects.EvaluatorCategory", - "azure.ai.projects.models.EvaluationLevel": "Azure.AI.Projects.EvaluationLevel", "azure.ai.projects.models.EvaluatorDefinitionType": "Azure.AI.Projects.EvaluatorDefinitionType", "azure.ai.projects.models.EvaluatorMetricType": "Azure.AI.Projects.EvaluatorMetricType", "azure.ai.projects.models.EvaluatorMetricDirection": "Azure.AI.Projects.EvaluatorMetricDirection", @@ -465,30 +749,8 @@ "azure.ai.projects.models.DataGenerationJobType": "Azure.AI.Projects.DataGenerationJobType", "azure.ai.projects.models.SimpleQnAFineTuningQuestionType": "Azure.AI.Projects.SimpleQnAFineTuningQuestionType", "azure.ai.projects.models.DataGenerationJobScenario": "Azure.AI.Projects.DataGenerationJobScenario", + "azure.ai.projects.models.DataGenerationJobOutputWriteMode": "Azure.AI.Projects.DataGenerationJobOutputWriteMode", "azure.ai.projects.models.DataGenerationJobOutputType": "Azure.AI.Projects.DataGenerationJobOutputType", - "azure.ai.projects.models.AgentOptimizationDatasetInputType": "Azure.AI.Projects.AgentOptimizationDatasetInputType", - "azure.ai.projects.models.AgentObjectType": "Azure.AI.Projects.AgentObjectType", - "azure.ai.projects.models.AgentState": "Azure.AI.Projects.AgentState", - "azure.ai.projects.models.AgentStateSource": "Azure.AI.Projects.AgentStateSource", - "azure.ai.projects.models.AgentKind": "Azure.AI.Projects.AgentKind", - "azure.ai.projects.models.AgentEndpointProtocol": "Azure.AI.Projects.AgentEndpointProtocol", - "azure.ai.projects.models.CodeDependencyResolution": "Azure.AI.Projects.CodeDependencyResolution", - "azure.ai.projects.models.TelemetryEndpointKind": "Azure.AI.Projects.TelemetryEndpointKind", - "azure.ai.projects.models.TelemetryDataKind": "Azure.AI.Projects.TelemetryDataKind", - "azure.ai.projects.models.TelemetryEndpointAuthType": "Azure.AI.Projects.TelemetryEndpointAuthType", - "azure.ai.projects.models.TelemetryTransportProtocol": "Azure.AI.Projects.TelemetryTransportProtocol", - "azure.ai.projects.models.ReasoningModeEnum": "OpenAI.ReasoningModeEnum", - "azure.ai.projects.models.ReasoningEffort": "OpenAI.ReasoningEffort", - "azure.ai.projects.models.ToolChoiceParamType": "OpenAI.ToolChoiceParamType", - "azure.ai.projects.models.TextResponseFormatConfigurationType": "OpenAI.TextResponseFormatConfigurationType", - "azure.ai.projects.models.AgentVersionStatus": "Azure.AI.Projects.AgentVersionStatus", - "azure.ai.projects.models.AgentIdentityStatus": "Azure.AI.Projects.AgentIdentityStatus", - "azure.ai.projects.models.AgentBlueprintReferenceType": "Azure.AI.Projects.AgentBlueprintReferenceType", - "azure.ai.projects.models.VersionSelectorType": "Azure.AI.Projects.VersionSelectorType", - "azure.ai.projects.models.ActivityProtocolAccessBoundary": "Azure.AI.Projects.ActivityProtocolAccessBoundary", - "azure.ai.projects.models.AgentEndpointAuthorizationSchemeType": "Azure.AI.Projects.AgentEndpointAuthorizationSchemeType", - "azure.ai.projects.models.PublishApprovalStatus": "Azure.AI.Projects.PublishApprovalStatus", - "azure.ai.projects.models.DigitalWorkerType": "Azure.AI.Projects.DigitalWorkerType", "azure.ai.projects.models.VersionIndicatorType": "Azure.AI.Projects.VersionIndicatorType", "azure.ai.projects.models.AgentSessionStatus": "Azure.AI.Projects.AgentSessionStatus", "azure.ai.projects.models.SessionLogEventType": "Azure.AI.Projects.SessionLogEventType", @@ -502,6 +764,13 @@ "azure.ai.projects.models.IndexType": "Azure.AI.Projects.IndexType", "azure.ai.projects.models.ToolboxToolType": "Azure.AI.Projects.ToolboxToolType", "azure.ai.projects.models.MemoryStoreUpdateStatus": "Azure.AI.Projects.MemoryStoreUpdateStatus", + "azure.ai.projects.models.VoiceAgentAnimationOutputType": "Azure.AI.Projects.VoiceAgentAnimationOutputType", + "azure.ai.projects.models.RealtimeReasoningEffort": "OpenAI.RealtimeReasoningEffort", + "azure.ai.projects.models.RealtimeClientEventType": "OpenAI.RealtimeClientEventType", + "azure.ai.projects.models.ToolChoiceOptions": "OpenAI.ToolChoiceOptions", + "azure.ai.projects.models.RealtimeServerEventType": "OpenAI.RealtimeServerEventType", + "azure.ai.projects.models.CreateTranscriptionResponseJsonUsageType": "OpenAI.CreateTranscriptionResponseJsonUsageType", + "azure.ai.projects.models.VoiceAgentSubagentAbortReason": "Azure.AI.Projects.VoiceAgentSubagentAbortReason", "azure.ai.projects.operations.AgentsOperations.get": "Azure.AI.Projects.Agents.getAgent", "azure.ai.projects.aio.operations.AgentsOperations.get": "Azure.AI.Projects.Agents.getAgent", "azure.ai.projects.operations.AgentsOperations.delete": "Azure.AI.Projects.Agents.deleteAgent", @@ -600,6 +869,8 @@ "azure.ai.projects.aio.operations.ToolboxesOperations.list_versions": "Azure.AI.Projects.Toolboxes.listToolboxVersions", "azure.ai.projects.operations.ToolboxesOperations.get_version": "Azure.AI.Projects.Toolboxes.getToolboxVersion", "azure.ai.projects.aio.operations.ToolboxesOperations.get_version": "Azure.AI.Projects.Toolboxes.getToolboxVersion", + "azure.ai.projects.operations.ToolboxesOperations.invoke_latest_toolbox_mcp": "Azure.AI.Projects.Toolboxes.invokeLatestToolboxMcp", + "azure.ai.projects.aio.operations.ToolboxesOperations.invoke_latest_toolbox_mcp": "Azure.AI.Projects.Toolboxes.invokeLatestToolboxMcp", "azure.ai.projects.operations.ToolboxesOperations.update": "Azure.AI.Projects.Toolboxes.updateToolbox", "azure.ai.projects.aio.operations.ToolboxesOperations.update": "Azure.AI.Projects.Toolboxes.updateToolbox", "azure.ai.projects.operations.ToolboxesOperations.delete": "Azure.AI.Projects.Toolboxes.deleteToolbox", @@ -607,5 +878,5 @@ "azure.ai.projects.operations.ToolboxesOperations.delete_version": "Azure.AI.Projects.Toolboxes.deleteToolboxVersion", "azure.ai.projects.aio.operations.ToolboxesOperations.delete_version": "Azure.AI.Projects.Toolboxes.deleteToolboxVersion" }, - "CrossLanguageVersion": "4a45c56db1c7" + "CrossLanguageVersion": "c8bbe90c032a" } \ No newline at end of file diff --git a/sdk/ai/azure-ai-projects/assets.json b/sdk/ai/azure-ai-projects/assets.json index 30a0f2f5a752..8ea4f92ef1a6 100644 --- a/sdk/ai/azure-ai-projects/assets.json +++ b/sdk/ai/azure-ai-projects/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "python", "TagPrefix": "python/ai/azure-ai-projects", - "Tag": "python/ai/azure-ai-projects_9126e77e11" + "Tag": "python/ai/azure-ai-projects_59c7584f68" } diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_realtime.py b/sdk/ai/azure-ai-projects/azure/ai/projects/_realtime.py new file mode 100644 index 000000000000..18eec87d0f59 --- /dev/null +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_realtime.py @@ -0,0 +1,910 @@ +# pylint: disable=networking-import-outside-azure-core-transport +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------- +"""Hand-written sync realtime (WebSocket) streaming client for voice agents. + +This is the synchronous counterpart of :mod:`azure.ai.projects.aio._realtime`. See that +module's docstring for the full design rationale; the two modules are kept structurally +identical (sync method names drop the ``async``/``await`` keywords) so fixes/features land in +both at once. + +``websockets`` is required for this feature and is *not* a hard dependency of the package; it +is imported lazily so importing the SDK never fails when it is absent. +""" + +from __future__ import annotations + +import base64 +import json +import logging +from urllib.parse import quote, urlencode, urlparse +from typing import ( + Any, + Dict, + Iterator, + List, + Mapping, + Optional, + Protocol, + Tuple, + Type, + TYPE_CHECKING, + Union, + cast, +) + +from azure.core.pipeline.policies import UserAgentPolicy + +from . import models as _models +from .models._enums import _AgentDefinitionOptInKeys +from .models._patch import _FOUNDRY_FEATURES_HEADER_NAME, _has_header_case_insensitive +from ._utils.model_base import Model as _Model, SdkJSONEncoder +from ._version import VERSION + +_LOGGER = logging.getLogger(__name__) + +# The realtime WebSocket route is voice-agent-specific (see `_to_ws_url`'s +# `/endpoint/protocols/voice` path), so this is always the correct opt-in value -- callers +# cannot and do not need to override it. +_VOICE_AGENT_FEATURE_HEADER: str = _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + +# Identifies the SDK to the service on the WebSocket handshake, which otherwise falls back to +# the underlying `websockets` library's generic default (the generated HTTP surface gets this +# for free from the pipeline's own UserAgentPolicy; this hand-written client builds its own +# request instead, so it needs to opt in explicitly the same way). +_USER_AGENT: str = UserAgentPolicy(sdk_moniker=f"ai-projects/{VERSION}").user_agent + +if TYPE_CHECKING: + from websockets.sync.client import ClientConnection + from azure.core.credentials import TokenCredential + from ._configuration import AIProjectClientConfiguration + + +class _ConfigProvider(Protocol): + """Anything exposing the shared client configuration (endpoint, credential, etc.). + + :class:`~azure.ai.projects.operations.BetaVoiceAgentsOperations` (accessed as + ``client.beta.voice_agents``) satisfies this: it is constructed with the same shared + configuration instance as the top-level client, so ``client.beta.voice_agents.realtime`` can + reuse the endpoint/credential wiring without needing a back-reference to the top-level client + itself. + """ + + _config: "AIProjectClientConfiguration" + + +__all__ = [ + "BetaRealtime", + "BetaRealtimeConnection", + "BetaRealtimeConnectionManager", + "ClientEvent", + "ConversationItem", + "ServerEvent", +] + +# Union of the client event models sendable over the connection, plus a raw mapping escape +# hatch for forward compatibility with event types not yet represented in the generated models. +ClientEvent = Union[ + _models.RealtimeClientEventConversationItemCreate, + _models.RealtimeClientEventConversationItemDelete, + _models.RealtimeClientEventConversationItemRetrieve, + _models.RealtimeClientEventConversationItemTruncate, + _models.RealtimeClientEventInputAudioBufferAppend, + _models.RealtimeClientEventInputAudioBufferClear, + _models.RealtimeClientEventInputAudioBufferCommit, + _models.RealtimeClientEventOutputAudioBufferClear, + _models.RealtimeClientEventResponseCancel, + _models.RealtimeClientEventResponseCreate, + _models.VoiceAgentClientEventRtcCallSdpCreate, + _models.VoiceAgentClientEventSessionAvatarConnect, + _models.VoiceAgentClientEventSessionUpdate, + str, + Mapping[str, Any], +] + +# The conversation item variants accepted by ``conversation.item.create``. +ConversationItem = Union[ + _models.RealtimeConversationItemMessageSystem, + _models.RealtimeConversationItemMessageUser, + _models.RealtimeConversationItemMessageAssistant, + _models.RealtimeConversationItemFunctionCall, + _models.RealtimeConversationItemFunctionCallOutput, + _models.RealtimeMCPApprovalResponse, + Mapping[str, Any], +] + +# Every server event ``type`` string mapped to its generated model, used to deserialize +# inbound frames into strongly-typed objects. Event types not represented by a dedicated +# generated model in this package (for example ``conversation.created``) are intentionally +# left out here and fall back to a plain ``dict``, as do any newly-added service events. +_SERVER_EVENT_TYPES: Dict[str, Type[_Model]] = { + "conversation.item.added": _models.RealtimeServerEventConversationItemAdded, + "conversation.item.created": _models.RealtimeServerEventConversationItemCreated, + "conversation.item.deleted": _models.RealtimeServerEventConversationItemDeleted, + "conversation.item.done": _models.RealtimeServerEventConversationItemDone, + "conversation.item.input_audio_transcription.completed": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted + ), + "conversation.item.input_audio_transcription.delta": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta + ), + "conversation.item.input_audio_transcription.failed": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed + ), + "conversation.item.input_audio_transcription.segment": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment + ), + "conversation.item.retrieved": _models.RealtimeServerEventConversationItemRetrieved, + "conversation.item.truncated": _models.RealtimeServerEventConversationItemTruncated, + # Shared OpenAI-style BetaRealtime error event (not voice-agent specific in this package). + "error": _models.RealtimeServerEventError, + "input_audio_buffer.cleared": _models.RealtimeServerEventInputAudioBufferCleared, + "input_audio_buffer.committed": _models.RealtimeServerEventInputAudioBufferCommitted, + "input_audio_buffer.speech_started": _models.RealtimeServerEventInputAudioBufferSpeechStarted, + "input_audio_buffer.speech_stopped": _models.RealtimeServerEventInputAudioBufferSpeechStopped, + "input_audio_buffer.timeout_triggered": (_models.RealtimeServerEventInputAudioBufferTimeoutTriggered), + "mcp_list_tools.completed": _models.RealtimeServerEventMCPListToolsCompleted, + "mcp_list_tools.failed": _models.RealtimeServerEventMCPListToolsFailed, + "mcp_list_tools.in_progress": _models.RealtimeServerEventMCPListToolsInProgress, + "output_audio_buffer.cleared": _models.RealtimeServerEventOutputAudioBufferCleared, + "rate_limits.updated": _models.RealtimeServerEventRateLimitsUpdated, + "response.animation_blendshapes.delta": (_models.VoiceAgentServerEventResponseAnimationBlendshapesDelta), + "response.animation_blendshapes.done": (_models.VoiceAgentServerEventResponseAnimationBlendshapesDone), + "response.animation_viseme.delta": _models.VoiceAgentServerEventResponseAnimationVisemeDelta, + "response.animation_viseme.done": _models.VoiceAgentServerEventResponseAnimationVisemeDone, + "response.audio_timestamp.delta": _models.VoiceAgentServerEventResponseAudioTimestampDelta, + "response.audio_timestamp.done": _models.VoiceAgentServerEventResponseAudioTimestampDone, + "response.content_part.added": _models.RealtimeServerEventResponseContentPartAdded, + "response.content_part.done": _models.RealtimeServerEventResponseContentPartDone, + "response.created": _models.RealtimeServerEventResponseCreated, + "response.done": _models.RealtimeServerEventResponseDone, + "response.function_call_arguments.delta": (_models.RealtimeServerEventResponseFunctionCallArgumentsDelta), + "response.function_call_arguments.done": (_models.RealtimeServerEventResponseFunctionCallArgumentsDone), + "response.mcp_call.completed": _models.RealtimeServerEventResponseMCPCallCompleted, + "response.mcp_call.failed": _models.RealtimeServerEventResponseMCPCallFailed, + "response.mcp_call.in_progress": _models.RealtimeServerEventResponseMCPCallInProgress, + "response.mcp_call_arguments.delta": _models.RealtimeServerEventResponseMCPCallArgumentsDelta, + "response.mcp_call_arguments.done": _models.RealtimeServerEventResponseMCPCallArgumentsDone, + "response.output_audio.delta": _models.RealtimeServerEventResponseAudioDelta, + "response.output_audio.done": _models.RealtimeServerEventResponseAudioDone, + "response.output_audio_transcript.delta": (_models.RealtimeServerEventResponseAudioTranscriptDelta), + "response.output_audio_transcript.done": (_models.RealtimeServerEventResponseAudioTranscriptDone), + "response.output_item.added": _models.RealtimeServerEventResponseOutputItemAdded, + "response.output_item.done": _models.RealtimeServerEventResponseOutputItemDone, + "response.output_text.delta": _models.RealtimeServerEventResponseTextDelta, + "response.output_text.done": _models.RealtimeServerEventResponseTextDone, + "response.video.delta": _models.VoiceAgentServerEventResponseVideoDelta, + "rtc.call.error": _models.VoiceAgentServerEventRtcCallError, + "rtc.call.sdp.created": _models.VoiceAgentServerEventRtcCallSdpCreated, + "session.avatar.connecting": _models.VoiceAgentServerEventSessionAvatarConnecting, + "session.avatar.switch_to_idle": _models.VoiceAgentServerEventSessionAvatarSwitchToIdle, + "session.avatar.switch_to_speaking": _models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking, + "session.created": _models.RealtimeServerEventSessionCreated, + "session.subagent.aborted": _models.VoiceAgentServerEventSessionSubagentAborted, + "session.subagent.completed": _models.VoiceAgentServerEventSessionSubagentCompleted, + "session.subagent.started": _models.VoiceAgentServerEventSessionSubagentStarted, + "session.updated": _models.RealtimeServerEventSessionUpdated, + "warning": _models.VoiceAgentServerEventWarning, +} + +# Every generated server event model, for consumers that want a precise return type. +ServerEvent = Union[ + _models.RealtimeServerEventError, + _models.RealtimeServerEventResponseContentPartAdded, + _models.RealtimeServerEventConversationItemAdded, + _models.RealtimeServerEventConversationItemCreated, + _models.RealtimeServerEventConversationItemDeleted, + _models.RealtimeServerEventConversationItemDone, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment, + _models.RealtimeServerEventConversationItemRetrieved, + _models.RealtimeServerEventConversationItemTruncated, + _models.RealtimeServerEventInputAudioBufferCleared, + _models.RealtimeServerEventInputAudioBufferCommitted, + _models.RealtimeServerEventInputAudioBufferSpeechStarted, + _models.RealtimeServerEventInputAudioBufferSpeechStopped, + _models.RealtimeServerEventInputAudioBufferTimeoutTriggered, + _models.RealtimeServerEventMCPListToolsCompleted, + _models.RealtimeServerEventMCPListToolsFailed, + _models.RealtimeServerEventMCPListToolsInProgress, + _models.RealtimeServerEventOutputAudioBufferCleared, + _models.RealtimeServerEventRateLimitsUpdated, + _models.VoiceAgentServerEventResponseAnimationBlendshapesDelta, + _models.VoiceAgentServerEventResponseAnimationBlendshapesDone, + _models.VoiceAgentServerEventResponseAnimationVisemeDelta, + _models.VoiceAgentServerEventResponseAnimationVisemeDone, + _models.RealtimeServerEventResponseAudioDelta, + _models.RealtimeServerEventResponseAudioDone, + _models.VoiceAgentServerEventResponseAudioTimestampDelta, + _models.VoiceAgentServerEventResponseAudioTimestampDone, + _models.RealtimeServerEventResponseAudioTranscriptDelta, + _models.RealtimeServerEventResponseAudioTranscriptDone, + _models.RealtimeServerEventResponseContentPartDone, + _models.RealtimeServerEventResponseCreated, + _models.RealtimeServerEventResponseDone, + _models.RealtimeServerEventResponseFunctionCallArgumentsDelta, + _models.RealtimeServerEventResponseFunctionCallArgumentsDone, + _models.RealtimeServerEventResponseMCPCallArgumentsDelta, + _models.RealtimeServerEventResponseMCPCallArgumentsDone, + _models.RealtimeServerEventResponseMCPCallCompleted, + _models.RealtimeServerEventResponseMCPCallFailed, + _models.RealtimeServerEventResponseMCPCallInProgress, + _models.RealtimeServerEventResponseOutputItemAdded, + _models.RealtimeServerEventResponseOutputItemDone, + _models.RealtimeServerEventResponseTextDelta, + _models.RealtimeServerEventResponseTextDone, + _models.VoiceAgentServerEventResponseVideoDelta, + _models.VoiceAgentServerEventRtcCallError, + _models.VoiceAgentServerEventRtcCallSdpCreated, + _models.VoiceAgentServerEventSessionAvatarConnecting, + _models.VoiceAgentServerEventSessionAvatarSwitchToIdle, + _models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking, + _models.RealtimeServerEventSessionCreated, + _models.VoiceAgentServerEventSessionSubagentAborted, + _models.VoiceAgentServerEventSessionSubagentCompleted, + _models.VoiceAgentServerEventSessionSubagentStarted, + _models.RealtimeServerEventSessionUpdated, + _models.VoiceAgentServerEventWarning, + Mapping[str, Any], +] + + +def _to_ws_url(endpoint: str, agent_name: str) -> str: + """Build the realtime WebSocket URL from the HTTPS project endpoint. + + Only the ``https://`` scheme is translated (to ``wss://``); any other scheme is left + unchanged so that :meth:`BetaRealtimeConnectionManager.enter`'s ``wss://``-only check rejects + it with a clear error instead of silently producing an unencrypted ``ws://`` URL that would + also send the live Authorization token in plain text. + + :param str endpoint: The Foundry project endpoint (``https://.../api/projects/...``). + :param str agent_name: The name of the voice agent to connect to. + :return: A ``wss://`` URL targeting the realtime route. + :rtype: str + """ + base = endpoint.rstrip("/") + if base.startswith("https://"): + base = "wss://" + base[len("https://") :] + return f"{base}/agents/{quote(agent_name, safe='')}/endpoint/protocols/voice" + + +_DEFAULT_PORT_BY_SCHEME = {"http": 80, "https": 443, "ws": 80, "wss": 443} + + +def _normalized_authority(url: str) -> Tuple[str, Optional[int]]: + """Return a ``(hostname, port)`` tuple with the scheme's default port filled in. + + ``urlparse(...).port`` is ``None`` when a URL omits an explicit port, which would make + ``https://host/...`` and ``https://host:8443/...`` compare as equal on hostname alone. + Resolving the scheme's default port here lets callers compare authorities (not just + hostnames) so a same-host override on a different, non-default port is correctly rejected. + + :param str url: The URL to parse. + :return: A tuple of the lower-cased hostname (or empty string) and the resolved port + (or ``None`` if the scheme has no known default and none was specified). + :rtype: tuple[str, Optional[int]] + """ + parsed = urlparse(url) + port = parsed.port + if port is None: + port = _DEFAULT_PORT_BY_SCHEME.get((parsed.scheme or "").lower()) + return (parsed.hostname or "").lower(), port + + +def _assert_trusted_connection_url(connection_url: str, endpoint: str) -> None: + """Guard against attaching the caller's Entra bearer token to an untrusted host. + + ``connection_url`` is an escape hatch that lets a caller override the computed + scheme/host/path, but the Authorization header carrying the live credential's + token must never be sent to a host other than the configured Foundry project + endpoint: a caller-controlled or compromised URL could otherwise be used to + exfiltrate the token to an arbitrary host or port. + + :param str connection_url: The caller-supplied override URL. + :param str endpoint: The configured, trusted Foundry project endpoint. + :raises ValueError: If the override URL's host or port does not match the endpoint's. + """ + override_host, override_port = _normalized_authority(connection_url) + trusted_host, trusted_port = _normalized_authority(endpoint) + if not override_host or (override_host, override_port) != (trusted_host, trusted_port): + got = override_host or connection_url + if override_host and override_port: + got = f"{override_host}:{override_port}" + raise ValueError( + "The 'connection_url' override must target the same host and port as the configured " + f"Foundry project endpoint ('{trusted_host}:{trusted_port}') to avoid sending the " + f"Authorization token to an untrusted host; got '{got}'." + ) + + +class _BaseResource: # pylint: disable=too-few-public-methods + """Base helper that forwards typed helpers to the parent connection.""" + + def __init__(self, connection: "BetaRealtimeConnection") -> None: + self._connection = connection + + def _send(self, event: ClientEvent) -> None: + self._connection.send(event) + + +class SessionResource(_BaseResource): + """Send ``session.*`` client events.""" + + def update( + self, + *, + session: Union["_models.VoiceAgentSessionUpdateConfig", Mapping[str, Any]], + event_id: Optional[str] = None, + ) -> None: + """Update the realtime session configuration. + + :keyword session: The session configuration to apply. + :paramtype session: ~azure.ai.projects.models.VoiceAgentSessionUpdateConfig or + Mapping[str, Any] + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + cast(Any, _models.VoiceAgentClientEventSessionUpdate)( + type=_models.RealtimeClientEventType.SESSION_UPDATE, + session=session, + event_id=event_id, + ) + ) + + def avatar_connect(self, *, client_sdp: str, event_id: Optional[str] = None) -> None: + """Negotiate an avatar media session over WebRTC. + + :keyword str client_sdp: The client's SDP offer for avatar media negotiation. + :keyword event_id: An optional client-generated event identifier. + :paramtype event_id: str or None + """ + self._send( + _models.VoiceAgentClientEventSessionAvatarConnect( + client_sdp=client_sdp, + event_id=event_id, + ) + ) + + +class InputAudioBufferResource(_BaseResource): + """Send ``input_audio_buffer.*`` client events.""" + + def append(self, *, audio: Union[str, bytes], event_id: Optional[str] = None) -> None: + """Append audio bytes to the input buffer. + + :keyword audio: Raw audio bytes, or an already base64-encoded string. + :paramtype audio: str or bytes + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + if isinstance(audio, (bytes, bytearray)): + audio = base64.b64encode(bytes(audio)).decode("ascii") + self._send( + _models.RealtimeClientEventInputAudioBufferAppend( + audio=audio, + event_id=event_id, + ) + ) + + def commit(self, *, event_id: Optional[str] = None) -> None: + """Commit the buffered input audio as a user turn. + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send(_models.RealtimeClientEventInputAudioBufferCommit(event_id=event_id)) + + def clear(self, *, event_id: Optional[str] = None) -> None: + """Discard any buffered input audio. + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send(_models.RealtimeClientEventInputAudioBufferClear(event_id=event_id)) + + +class OutputAudioBufferResource(_BaseResource): # pylint: disable=too-few-public-methods + """Send ``output_audio_buffer.*`` client events.""" + + def clear(self, *, event_id: Optional[str] = None) -> None: + """Stop and clear any audio the service is currently playing back (barge-in). + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send(_models.RealtimeClientEventOutputAudioBufferClear(event_id=event_id)) + + +class ConversationItemResource(_BaseResource): + """Send ``conversation.item.*`` client events.""" + + def create( + self, + *, + item: ConversationItem, + previous_item_id: Optional[str] = None, + event_id: Optional[str] = None, + ) -> None: + """Insert an item into the conversation. + + :keyword item: The conversation item to create. + :paramtype item: ~azure.ai.projects.models.RealtimeConversationItemMessageSystem or + ~azure.ai.projects.models.RealtimeConversationItemMessageUser or + ~azure.ai.projects.models.RealtimeConversationItemMessageAssistant or + ~azure.ai.projects.models.RealtimeConversationItemFunctionCall or + ~azure.ai.projects.models.RealtimeConversationItemFunctionCallOutput or + ~azure.ai.projects.models.RealtimeMCPApprovalResponse or Mapping[str, Any] + :keyword previous_item_id: The ID of the preceding item after which the new item will be + inserted. Default value is None. + :paramtype previous_item_id: str or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + cast(Any, _models.RealtimeClientEventConversationItemCreate)( + item=item, + previous_item_id=previous_item_id, + event_id=event_id, + ) + ) + + def delete(self, *, item_id: str, event_id: Optional[str] = None) -> None: + """Delete an item from the conversation. + + :keyword str item_id: The ID of the item to delete. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + _models.RealtimeClientEventConversationItemDelete( + item_id=item_id, + event_id=event_id, + ) + ) + + def retrieve(self, *, item_id: str, event_id: Optional[str] = None) -> None: + """Ask the server to emit a ``conversation.item.retrieved`` event for an item. + + :keyword str item_id: The ID of the item to retrieve. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + _models.RealtimeClientEventConversationItemRetrieve( + item_id=item_id, + event_id=event_id, + ) + ) + + def truncate(self, *, item_id: str, content_index: int, audio_end_ms: int, event_id: Optional[str] = None) -> None: + """Truncate a previously produced assistant audio item (used for barge-in). + + :keyword str item_id: The ID of the assistant message item to truncate. + :keyword int content_index: The index of the content part to truncate. Use ``0``. + :keyword int audio_end_ms: The point, in milliseconds, to truncate the audio to. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + _models.RealtimeClientEventConversationItemTruncate( + item_id=item_id, + content_index=content_index, + audio_end_ms=audio_end_ms, + event_id=event_id, + ) + ) + + +class ConversationResource(_BaseResource): # pylint: disable=too-few-public-methods + """Send ``conversation.*`` client events.""" + + def __init__(self, connection: "BetaRealtimeConnection") -> None: + super().__init__(connection) + self.item: ConversationItemResource = ConversationItemResource(connection) + + +class ResponseResource(_BaseResource): + """Send ``response.*`` client events.""" + + def create( + self, + *, + response: Optional[Union["_models.VoiceAgentResponseCreateParams", Mapping[str, Any]]] = None, + event_id: Optional[str] = None, + ) -> None: + """Ask the model to generate a response. + + :keyword response: Optional per-response overrides. Default value is None. + :paramtype response: ~azure.ai.projects.models.VoiceAgentResponseCreateParams or + Mapping[str, Any] or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + cast(Any, _models.RealtimeClientEventResponseCreate)( + response=response, + event_id=event_id, + ) + ) + + def cancel(self, *, response_id: Optional[str] = None, event_id: Optional[str] = None) -> None: + """Cancel an in-progress response. + + :keyword response_id: The ID of the response to cancel, if targeting a specific one. + Default value is None. + :paramtype response_id: str or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + self._send( + _models.RealtimeClientEventResponseCancel( + response_id=response_id, + event_id=event_id, + ) + ) + + +class BetaRealtimeConnection: # pylint: disable=too-many-instance-attributes + """An open realtime WebSocket connection to a voice agent. + + Iterate over the connection to receive strongly-typed server events, and use the + sub-namespaces to send strongly-typed client events:: + + with client.beta.voice_agents.realtime.connect(agent_name="my-agent") as conn: + for event in conn: + if event.type == RealtimeServerEventType.RESPONSE_DONE: + break + """ + + def __init__(self, connection: "ClientConnection") -> None: + self._connection = connection + self._closed = False + self.session: SessionResource = SessionResource(self) + self.input_audio_buffer: InputAudioBufferResource = InputAudioBufferResource(self) + self.output_audio_buffer: OutputAudioBufferResource = OutputAudioBufferResource(self) + self.conversation: ConversationResource = ConversationResource(self) + self.response: ResponseResource = ResponseResource(self) + + def __enter__(self) -> "BetaRealtimeConnection": + return self + + def __exit__(self, *exc_details: Any) -> None: + self.close() + + def __repr__(self) -> str: + state = "closed" if self.closed else "open" + return f"" + + @property + def closed(self) -> bool: + """Whether the underlying WebSocket connection has been closed. + + :rtype: bool + """ + return self._closed + + def __iter__(self) -> Iterator[ServerEvent]: + return self._iter() + + def _iter(self) -> Iterator[ServerEvent]: + while True: + try: + yield self.recv() + except ConnectionResetError as exc: + # recv() below chains the *specific* websockets exception as the cause: a plain + # graceful closure has no cause (nothing went wrong), while an abnormal closure + # is chained from the ConnectionClosed that caused it. Only end iteration quietly + # for the former -- a `for event in conn:` caller must still see real failures + # (abnormal close codes, e.g. 1011) instead of silently observing end-of-stream. + if exc.__cause__ is None: + return + raise + + def recv(self, *, timeout: Optional[float] = None) -> ServerEvent: + """Receive and parse the next server event. + + Known event types are returned as their strongly-typed + ``VoiceAgentServerEventXxx`` model. Event types not (yet) represented by a + generated model are returned as a plain ``dict`` for forward compatibility. + + :keyword timeout: Maximum time in seconds to wait for the next event. If ``None`` + (the default), block until an event is received. If no event arrives within + ``timeout`` seconds, raise :exc:`TimeoutError`. + :paramtype timeout: float or None + :return: The parsed server event. + :rtype: ~azure.ai.projects.ServerEvent + :raises ConnectionResetError: If the connection was closed by the server, gracefully or + otherwise. Iterating over the connection (``for event in conn:``) treats only a graceful + closure as end-of-stream and re-raises this for an abnormal one. + :raises TimeoutError: If ``timeout`` elapses before an event is received. + """ + from websockets.exceptions import ( # pylint: disable=import-outside-toplevel + ConnectionClosed, + ConnectionClosedOK, + ) + + try: + raw = self._connection.recv(timeout=timeout) + except ConnectionClosedOK: + self._closed = True + raise ConnectionResetError("The realtime connection was closed.") from None + except ConnectionClosed as exc: + self._closed = True + raise ConnectionResetError(f"The realtime connection was closed abnormally: {exc}") from exc + data = raw.decode("utf-8") if isinstance(raw, (bytes, bytearray)) else raw + payload: Dict[str, Any] = json.loads(data) + event_type = payload.get("type") + _LOGGER.debug( + "WebSocket RECEIVE type=%s bytes=%d", + event_type if isinstance(event_type, str) else "unknown", + len(data.encode("utf-8")), + ) + if not isinstance(event_type, str): + return payload + event_cls = _SERVER_EVENT_TYPES.get(event_type) + if event_cls is None: + return payload + return event_cls(payload) + + def send(self, event: ClientEvent) -> None: + """Send a client event over the connection. + + :param event: A strongly-typed client event, a ready-made mapping, or a raw JSON string. + :type event: ~azure.ai.projects.ClientEvent or str + :raises ValueError: If ``event`` is a ``str`` that is not valid JSON. + """ + if isinstance(event, str): + try: + event_payload = json.loads(event) + except ValueError as exc: + raise ValueError(f"'event' is not valid JSON: {exc}") from exc + payload = event + else: + payload = json.dumps(event, cls=SdkJSONEncoder) + event_payload = json.loads(payload) + event_type = event_payload.get("type") if isinstance(event_payload, dict) else None + _LOGGER.debug( + "WebSocket SEND type=%s bytes=%d", + event_type if isinstance(event_type, str) else "unknown", + len(payload.encode("utf-8")), + ) + self._connection.send(payload) + + def close(self, *, code: int = 1000, reason: str = "") -> None: + """Close the connection. + + :keyword int code: The WebSocket close code. + :keyword str reason: The close reason. + """ + if self._closed: + return + _LOGGER.debug("WebSocket CLOSE code=%d", code) + try: + self._connection.close(code=code, reason=reason) + finally: + self._closed = True + + +class BetaRealtimeConnectionManager: # pylint: disable=too-many-instance-attributes + """Context manager that opens a :class:`BetaRealtimeConnection`. + + Returned by :meth:`BetaRealtime.connect`; you normally use it as + ``with client.beta.voice_agents.realtime.connect(...) as conn:``. + """ + + def __init__( # pylint: disable=too-many-arguments + self, + *, + endpoint: str, + credential: "TokenCredential", + credential_scopes: List[str], + api_version: str, + agent_name: str, + agent_session_id: Optional[str] = None, + structured_inputs: Optional[Mapping[str, Any]] = None, + connection_url: Optional[str] = None, + extra_query: Optional[Mapping[str, str]] = None, + extra_headers: Optional[Mapping[str, str]] = None, + **kwargs: Any, + ) -> None: + self._endpoint = endpoint + self._credential = credential + self._credential_scopes = credential_scopes + self._api_version = api_version + self._agent_name = agent_name + self._agent_session_id = agent_session_id + self._structured_inputs = structured_inputs + self._connection_url = connection_url + self._extra_query = dict(extra_query or {}) + self._extra_headers = dict(extra_headers or {}) + self._kwargs = kwargs + self._connection: Optional[BetaRealtimeConnection] = None + + def __enter__(self) -> BetaRealtimeConnection: + return self.enter() + + def enter(self) -> BetaRealtimeConnection: # pylint: disable=too-many-locals + """Open the connection. + + :return: The live realtime connection. + :rtype: ~azure.ai.projects.BetaRealtimeConnection + :raises RuntimeError: If ``websockets`` is not installed. + :raises ValueError: If the computed or supplied WebSocket URL does not use ``wss://``. + :raises ConnectionError: If the WebSocket upgrade handshake fails (for example, a + network error, DNS failure, or a non-101 response from the service). + """ + try: + from websockets.sync.client import connect as _ws_connect # pylint: disable=import-outside-toplevel + from websockets.typing import Subprotocol # pylint: disable=import-outside-toplevel + except ImportError as exc: # pragma: no cover - dependency guard + raise RuntimeError( + "The realtime client requires `websockets`. Install it with `pip install websockets`." + ) from exc + + # ``connection_url`` fully overrides the computed route (scheme/host/path). This is the + # escape hatch used to reach a specific data-plane host/path directly. + if self._connection_url is not None: + _assert_trusted_connection_url(self._connection_url, self._endpoint) + url = self._connection_url or _to_ws_url(self._endpoint, self._agent_name) + if not url.startswith("wss://"): + raise ValueError("The realtime WebSocket URL must use wss:// to protect credentials in transit.") + + params: Dict[str, str] = {"api-version": self._api_version, "x-ms-client-sdk": _USER_AGENT} + if self._agent_session_id is not None: + params["agent_session_id"] = self._agent_session_id + if self._structured_inputs is not None: + # The service reads this from the `structured_input` query parameter (see the + # generated `build_beta_voice_agents_realtime_connect_voice_agent_request`), not a + # header -- it must be serialized and appended to the URL below, not sent as one. + params["structured_input"] = json.dumps(self._structured_inputs, cls=SdkJSONEncoder) + params.update(self._extra_query) + + if params: + # Preserve an existing query string on a `connection_url` override (for example a + # SAS-style `?sig=...`) instead of unconditionally appending a second `?`. + delimiter = "&" if urlparse(url).query else "?" + full_url = f"{url}{delimiter}{urlencode(params)}" + else: + full_url = url + + target_url = urlparse(url)._replace(query="", fragment="").geturl() + _LOGGER.debug("WebSocket CONNECT target=%s", target_url) + + token = self._credential.get_token(*self._credential_scopes) + headers: Dict[str, str] = { + "Authorization": "Bearer " + token.token, + _FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENT_FEATURE_HEADER, + } + headers.update(self._extra_headers) + if not _has_header_case_insensitive(headers, "User-Agent"): + # Only set our default if the caller didn't supply their own (in any casing) -- + # a plain dict merge would otherwise leave both as separate keys (HTTP header names + # are case-insensitive, but Python dict keys are not), sending two User-Agent-like + # headers instead of cleanly honoring the caller's override. + headers["User-Agent"] = _USER_AGENT + + try: + # Force the "realtime" WebSocket subprotocol regardless of any caller-supplied + # override in ``self._kwargs``: the service requires this exact subprotocol, so + # silently accepting a different one here would just move the failure to a less + # clear error inside the handshake. Also disable ``websockets``' own + # ``user_agent_header`` default: unlike aiohttp, it is a wholly separate mechanism + # from ``additional_headers`` -- passing our own "User-Agent" there does not + # override it, so without this the connection would carry two distinct + # User-Agent-like values. + ws_connect_kwargs = dict(self._kwargs) + ws_connect_kwargs.pop("subprotocols", None) + connection = _ws_connect( + full_url, + additional_headers=headers, + subprotocols=[Subprotocol("realtime")], + user_agent_header=None, + **ws_connect_kwargs, + ) + except BaseException as exc: + if not isinstance(exc, Exception) or isinstance(exc, (ValueError, RuntimeError)): + raise + raise ConnectionError( + f"Failed to open the realtime WebSocket connection to voice agent " + f"'{self._agent_name}' at '{url}': {exc}" + ) from exc + _LOGGER.debug("WebSocket CONNECTED target=%s", target_url) + self._connection = BetaRealtimeConnection(connection) + return self._connection + + def __exit__(self, *exc_details: Any) -> None: + if self._connection is not None: + self._connection.close() + self._connection = None + + +class BetaRealtime: # pylint: disable=too-few-public-methods + """BetaRealtime streaming entry point, exposed as ``client.beta.voice_agents.realtime``. + + Follows the OpenAI Python realtime surface: obtain it from the HTTP client and open a + connection with :meth:`connect`:: + + from azure.ai.projects import AIProjectClient + from azure.identity import DefaultAzureCredential + + client = AIProjectClient(endpoint, DefaultAzureCredential()) + with client.beta.voice_agents.realtime.connect(agent_name="my-agent") as conn: + conn.input_audio_buffer.append(audio=chunk) + conn.input_audio_buffer.commit() + conn.response.create() + for event in conn: + if event.type == RealtimeServerEventType.RESPONSE_DONE: + break + + :param client: The object whose endpoint and credential are reused for the realtime + handshake -- the ``.beta.voice_agents`` sub-client, which shares the same underlying + configuration as the top-level client. + :type client: ~azure.ai.projects.operations.BetaVoiceAgentsOperations + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + input_args = list(args) + client: "_ConfigProvider" = input_args.pop(0) if input_args else kwargs.pop("client") + self._config = client._config # pylint: disable=protected-access + + def connect( # pylint: disable=too-many-arguments + self, + *, + agent_name: str, + agent_session_id: Optional[str] = None, + structured_inputs: Optional[Mapping[str, Any]] = None, + connection_url: Optional[str] = None, + api_version: Optional[str] = None, + credential_scopes: Optional[List[str]] = None, + extra_query: Optional[Mapping[str, str]] = None, + extra_headers: Optional[Mapping[str, str]] = None, + **kwargs: Any, + ) -> BetaRealtimeConnectionManager: + """Open a realtime WebSocket connection to a voice agent. + + :keyword str agent_name: The name of the voice agent to connect to. + :keyword agent_session_id: An optional identifier used to correlate the voice session. + Default value is None. + :paramtype agent_session_id: str or None + :keyword structured_inputs: A mapping of structured-input names to their values for this + session (see :attr:`~azure.ai.projects.models.CreateTelephonyCallJobRequest.structured_inputs` + for the analogous shape used elsewhere). Serialized to JSON on the wire. Default value is + None. + :paramtype structured_inputs: Mapping[str, Any] or None + :keyword connection_url: Full ``wss://`` URL that overrides the route computed + from the client endpoint. Query parameters are still appended. Default value is None. + :paramtype connection_url: str or None + :keyword api_version: Overrides the client's API version for the handshake. Default + value is None. + :paramtype api_version: str or None + :keyword credential_scopes: Overrides the client's token scopes for the handshake. + Default value is None. + :paramtype credential_scopes: list[str] or None + :keyword extra_query: Additional query-string parameters for the handshake. + :paramtype extra_query: Mapping[str, str] or None + :keyword extra_headers: Additional headers for the handshake. Pass + ``{"Foundry-Features": "..."}`` here to override the ``VoiceAgents=V1Preview`` value + this method always sends by default. + :paramtype extra_headers: Mapping[str, str] or None + :return: A context manager yielding a :class:`BetaRealtimeConnection`. + :rtype: ~azure.ai.projects.BetaRealtimeConnectionManager + """ + return BetaRealtimeConnectionManager( + endpoint=self._config.endpoint, + credential=self._config.credential, + credential_scopes=credential_scopes or self._config.credential_scopes, + api_version=api_version or self._config.api_version, + agent_name=agent_name, + agent_session_id=agent_session_id, + structured_inputs=structured_inputs, + connection_url=connection_url, + extra_query=extra_query, + extra_headers=extra_headers, + **kwargs, + ) diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_unions.py b/sdk/ai/azure-ai-projects/azure/ai/projects/_unions.py index abad0c3afee4..32e27a932c61 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/_unions.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_unions.py @@ -6,9 +6,16 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import TYPE_CHECKING, Union +from typing import Literal, TYPE_CHECKING, Union if TYPE_CHECKING: from . import models as _models Filters = Union["_models.ComparisonFilter", "_models.CompoundFilter"] +VoiceAgentToolChoice = Union[ + Literal["none"], Literal["auto"], Literal["required"], "_models.ToolChoiceFunction", "_models.ToolChoiceMCP" +] +VoiceAgentMaxOutputTokens = Union[int, Literal["inf"]] RoutineRunStatus = str +VoiceAgentSessionUpdate = Union["_models.VoiceAgentSessionUpdateConfig"] +VoiceAgentSessionResponse = Union["_models.VoiceAgentSessionResponseConfig"] +GenerateAgentRequest = Union["_models.GenerateVoiceAgentRequest"] diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_utils/utils.py b/sdk/ai/azure-ai-projects/azure/ai/projects/_utils/utils.py index c91d6470e2bf..13edbaf420db 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/_utils/utils.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_utils/utils.py @@ -9,8 +9,41 @@ import os from typing import Any, IO, Mapping, Optional, Union +from azure.core import MatchConditions + from .._utils.model_base import Model, SdkJSONEncoder + +def quote_etag(etag: Optional[str]) -> Optional[str]: + if not etag or etag == "*": + return etag + if etag.startswith("W/"): + return etag + if etag.startswith('"') and etag.endswith('"'): + return etag + if etag.startswith("'") and etag.endswith("'"): + return etag + return '"' + etag + '"' + + +def prep_if_match(etag: Optional[str], match_condition: Optional[MatchConditions]) -> Optional[str]: + if match_condition == MatchConditions.IfNotModified: + if_match = quote_etag(etag) if etag else None + return if_match + if match_condition == MatchConditions.IfPresent: + return "*" + return None + + +def prep_if_none_match(etag: Optional[str], match_condition: Optional[MatchConditions]) -> Optional[str]: + if match_condition == MatchConditions.IfModified: + if_none_match = quote_etag(etag) if etag else None + return if_none_match + if match_condition == MatchConditions.IfMissing: + return "*" + return None + + # file-like tuple could be `(filename, IO (or bytes))` or `(filename, IO (or bytes), content_type)` FileContent = Union[str, bytes, IO[str], IO[bytes]] diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/_version.py b/sdk/ai/azure-ai-projects/azure/ai/projects/_version.py index 5b65a7b6263e..e626e19dbb69 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/_version.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/_version.py @@ -6,4 +6,4 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -VERSION = "2.6.1" +VERSION = "2.7.0" diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_realtime.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_realtime.py new file mode 100644 index 000000000000..b2413b81c2ee --- /dev/null +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/_realtime.py @@ -0,0 +1,921 @@ +# pylint: disable=networking-import-outside-azure-core-transport +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------- +"""Hand-written async realtime (WebSocket) streaming client for voice agents. + +BetaRealtime uses a fundamentally different transport (a persistent WebSocket) than the +request/response HTTP surface generated from the service's TypeSpec definition, so it is +hand-written and exposed as the ``AIProjectClient.beta.voice_agents.realtime`` namespace. + +The connection ergonomics follow the OpenAI Python realtime client so that developers moving +between the libraries get a familiar surface: + +* :meth:`AsyncBetaRealtime.connect` returns an async context manager. +* Entering the context yields an :class:`AsyncBetaRealtimeConnection`. +* The connection is async-iterable over inbound, strongly-typed server events and exposes + sub-namespaces (``session``, ``input_audio_buffer``, ``output_audio_buffer``, + ``conversation``, ``response``) for sending strongly-typed outbound client events. + +Outbound and inbound events use the generated ``VoiceAgentClientEventXxx``/ +``VoiceAgentServerEventXxx`` models directly where one exists. ``send`` and ``recv`` still +accept/return plain ``dict`` objects as a forward-compatible fallback for any event ``type`` +the generated models don't yet know about (for example ``conversation.created``, which is a +valid event but does not (yet) have a dedicated generated model in this package). + +``aiohttp`` is required for this feature and is *not* a hard dependency of the package; it is +imported lazily so importing the SDK never fails when it is absent. +""" + +from __future__ import annotations + +import base64 +import json +import logging +from urllib.parse import quote, urlparse +from typing import ( + Any, + AsyncIterator, + cast, + Dict, + List, + Mapping, + Optional, + Protocol, + Tuple, + Type, + TYPE_CHECKING, + Union, +) + +from azure.core.pipeline.policies import UserAgentPolicy + +from .. import models as _models +from ..models._enums import _AgentDefinitionOptInKeys +from ..models._patch import _FOUNDRY_FEATURES_HEADER_NAME, _has_header_case_insensitive +from .._utils.model_base import Model as _Model, SdkJSONEncoder +from .._version import VERSION + +_LOGGER = logging.getLogger(__name__) + +# The realtime WebSocket route is voice-agent-specific (see `_to_ws_url`'s +# `/endpoint/protocols/voice` path), so this is always the correct opt-in value -- callers +# cannot and do not need to override it. +_VOICE_AGENT_FEATURE_HEADER: str = _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value + +# Identifies the SDK to the service on the WebSocket handshake, which otherwise falls back to +# the underlying `aiohttp` library's generic default (the generated HTTP surface gets this for +# free from the pipeline's own UserAgentPolicy; this hand-written client builds its own request +# instead, so it needs to opt in explicitly the same way). +_USER_AGENT: str = UserAgentPolicy(sdk_moniker=f"ai-projects/{VERSION}").user_agent + +if TYPE_CHECKING: + from aiohttp import ClientSession, ClientWebSocketResponse + from azure.core.credentials_async import AsyncTokenCredential + from ._configuration import AIProjectClientConfiguration + + +class _ConfigProvider(Protocol): + """Anything exposing the shared client configuration (endpoint, credential, etc.). + + :class:`~azure.ai.projects.aio.operations.BetaVoiceAgentsOperations` (accessed as + ``async_client.beta.voice_agents``) satisfies this: it is constructed with the same shared + configuration instance as the top-level client, so ``async_client.beta.voice_agents.realtime`` + can reuse the endpoint/credential wiring without needing a back-reference to the top-level + client itself. + """ + + _config: "AIProjectClientConfiguration" + + +__all__ = [ + "AsyncBetaRealtime", + "AsyncBetaRealtimeConnection", + "AsyncBetaRealtimeConnectionManager", + "ClientEvent", + "ConversationItem", + "ServerEvent", +] + +# Union of the client event models sendable over the connection, plus a raw mapping escape +# hatch for forward compatibility with event types not yet represented in the generated models. +ClientEvent = Union[ + _models.RealtimeClientEventConversationItemCreate, + _models.RealtimeClientEventConversationItemDelete, + _models.RealtimeClientEventConversationItemRetrieve, + _models.RealtimeClientEventConversationItemTruncate, + _models.RealtimeClientEventInputAudioBufferAppend, + _models.RealtimeClientEventInputAudioBufferClear, + _models.RealtimeClientEventInputAudioBufferCommit, + _models.RealtimeClientEventOutputAudioBufferClear, + _models.RealtimeClientEventResponseCancel, + _models.RealtimeClientEventResponseCreate, + _models.VoiceAgentClientEventRtcCallSdpCreate, + _models.VoiceAgentClientEventSessionAvatarConnect, + _models.VoiceAgentClientEventSessionUpdate, + str, + Mapping[str, Any], +] + +# The conversation item variants accepted by ``conversation.item.create``. +ConversationItem = Union[ + _models.RealtimeConversationItemMessageSystem, + _models.RealtimeConversationItemMessageUser, + _models.RealtimeConversationItemMessageAssistant, + _models.RealtimeConversationItemFunctionCall, + _models.RealtimeConversationItemFunctionCallOutput, + _models.RealtimeMCPApprovalResponse, + Mapping[str, Any], +] + +# Every server event ``type`` string mapped to its generated model, used to deserialize +# inbound frames into strongly-typed objects. Event types not represented by a dedicated +# generated model in this package (for example ``conversation.created``) are intentionally +# left out here and fall back to a plain ``dict``, as do any newly-added service events. +_SERVER_EVENT_TYPES: Dict[str, Type[_Model]] = { + "conversation.item.added": _models.RealtimeServerEventConversationItemAdded, + "conversation.item.created": _models.RealtimeServerEventConversationItemCreated, + "conversation.item.deleted": _models.RealtimeServerEventConversationItemDeleted, + "conversation.item.done": _models.RealtimeServerEventConversationItemDone, + "conversation.item.input_audio_transcription.completed": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted + ), + "conversation.item.input_audio_transcription.delta": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta + ), + "conversation.item.input_audio_transcription.failed": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed + ), + "conversation.item.input_audio_transcription.segment": ( + _models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment + ), + "conversation.item.retrieved": _models.RealtimeServerEventConversationItemRetrieved, + "conversation.item.truncated": _models.RealtimeServerEventConversationItemTruncated, + # Shared OpenAI-style BetaRealtime error event (not voice-agent specific in this package). + "error": _models.RealtimeServerEventError, + "input_audio_buffer.cleared": _models.RealtimeServerEventInputAudioBufferCleared, + "input_audio_buffer.committed": _models.RealtimeServerEventInputAudioBufferCommitted, + "input_audio_buffer.speech_started": _models.RealtimeServerEventInputAudioBufferSpeechStarted, + "input_audio_buffer.speech_stopped": _models.RealtimeServerEventInputAudioBufferSpeechStopped, + "input_audio_buffer.timeout_triggered": (_models.RealtimeServerEventInputAudioBufferTimeoutTriggered), + "mcp_list_tools.completed": _models.RealtimeServerEventMCPListToolsCompleted, + "mcp_list_tools.failed": _models.RealtimeServerEventMCPListToolsFailed, + "mcp_list_tools.in_progress": _models.RealtimeServerEventMCPListToolsInProgress, + "output_audio_buffer.cleared": _models.RealtimeServerEventOutputAudioBufferCleared, + "rate_limits.updated": _models.RealtimeServerEventRateLimitsUpdated, + "response.animation_blendshapes.delta": (_models.VoiceAgentServerEventResponseAnimationBlendshapesDelta), + "response.animation_blendshapes.done": (_models.VoiceAgentServerEventResponseAnimationBlendshapesDone), + "response.animation_viseme.delta": _models.VoiceAgentServerEventResponseAnimationVisemeDelta, + "response.animation_viseme.done": _models.VoiceAgentServerEventResponseAnimationVisemeDone, + "response.audio_timestamp.delta": _models.VoiceAgentServerEventResponseAudioTimestampDelta, + "response.audio_timestamp.done": _models.VoiceAgentServerEventResponseAudioTimestampDone, + "response.content_part.added": _models.RealtimeServerEventResponseContentPartAdded, + "response.content_part.done": _models.RealtimeServerEventResponseContentPartDone, + "response.created": _models.RealtimeServerEventResponseCreated, + "response.done": _models.RealtimeServerEventResponseDone, + "response.function_call_arguments.delta": (_models.RealtimeServerEventResponseFunctionCallArgumentsDelta), + "response.function_call_arguments.done": (_models.RealtimeServerEventResponseFunctionCallArgumentsDone), + "response.mcp_call.completed": _models.RealtimeServerEventResponseMCPCallCompleted, + "response.mcp_call.failed": _models.RealtimeServerEventResponseMCPCallFailed, + "response.mcp_call.in_progress": _models.RealtimeServerEventResponseMCPCallInProgress, + "response.mcp_call_arguments.delta": _models.RealtimeServerEventResponseMCPCallArgumentsDelta, + "response.mcp_call_arguments.done": _models.RealtimeServerEventResponseMCPCallArgumentsDone, + "response.output_audio.delta": _models.RealtimeServerEventResponseAudioDelta, + "response.output_audio.done": _models.RealtimeServerEventResponseAudioDone, + "response.output_audio_transcript.delta": (_models.RealtimeServerEventResponseAudioTranscriptDelta), + "response.output_audio_transcript.done": (_models.RealtimeServerEventResponseAudioTranscriptDone), + "response.output_item.added": _models.RealtimeServerEventResponseOutputItemAdded, + "response.output_item.done": _models.RealtimeServerEventResponseOutputItemDone, + "response.output_text.delta": _models.RealtimeServerEventResponseTextDelta, + "response.output_text.done": _models.RealtimeServerEventResponseTextDone, + "response.video.delta": _models.VoiceAgentServerEventResponseVideoDelta, + "rtc.call.error": _models.VoiceAgentServerEventRtcCallError, + "rtc.call.sdp.created": _models.VoiceAgentServerEventRtcCallSdpCreated, + "session.avatar.connecting": _models.VoiceAgentServerEventSessionAvatarConnecting, + "session.avatar.switch_to_idle": _models.VoiceAgentServerEventSessionAvatarSwitchToIdle, + "session.avatar.switch_to_speaking": _models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking, + "session.created": _models.RealtimeServerEventSessionCreated, + "session.subagent.aborted": _models.VoiceAgentServerEventSessionSubagentAborted, + "session.subagent.completed": _models.VoiceAgentServerEventSessionSubagentCompleted, + "session.subagent.started": _models.VoiceAgentServerEventSessionSubagentStarted, + "session.updated": _models.RealtimeServerEventSessionUpdated, + "warning": _models.VoiceAgentServerEventWarning, +} + +# Every generated server event model, for consumers that want a precise return type. +ServerEvent = Union[ + _models.RealtimeServerEventError, + _models.RealtimeServerEventResponseContentPartAdded, + _models.RealtimeServerEventConversationItemAdded, + _models.RealtimeServerEventConversationItemCreated, + _models.RealtimeServerEventConversationItemDeleted, + _models.RealtimeServerEventConversationItemDone, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionCompleted, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionDelta, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionFailed, + _models.RealtimeServerEventConversationItemInputAudioTranscriptionSegment, + _models.RealtimeServerEventConversationItemRetrieved, + _models.RealtimeServerEventConversationItemTruncated, + _models.RealtimeServerEventInputAudioBufferCleared, + _models.RealtimeServerEventInputAudioBufferCommitted, + _models.RealtimeServerEventInputAudioBufferSpeechStarted, + _models.RealtimeServerEventInputAudioBufferSpeechStopped, + _models.RealtimeServerEventInputAudioBufferTimeoutTriggered, + _models.RealtimeServerEventMCPListToolsCompleted, + _models.RealtimeServerEventMCPListToolsFailed, + _models.RealtimeServerEventMCPListToolsInProgress, + _models.RealtimeServerEventOutputAudioBufferCleared, + _models.RealtimeServerEventRateLimitsUpdated, + _models.VoiceAgentServerEventResponseAnimationBlendshapesDelta, + _models.VoiceAgentServerEventResponseAnimationBlendshapesDone, + _models.VoiceAgentServerEventResponseAnimationVisemeDelta, + _models.VoiceAgentServerEventResponseAnimationVisemeDone, + _models.RealtimeServerEventResponseAudioDelta, + _models.RealtimeServerEventResponseAudioDone, + _models.VoiceAgentServerEventResponseAudioTimestampDelta, + _models.VoiceAgentServerEventResponseAudioTimestampDone, + _models.RealtimeServerEventResponseAudioTranscriptDelta, + _models.RealtimeServerEventResponseAudioTranscriptDone, + _models.RealtimeServerEventResponseContentPartDone, + _models.RealtimeServerEventResponseCreated, + _models.RealtimeServerEventResponseDone, + _models.RealtimeServerEventResponseFunctionCallArgumentsDelta, + _models.RealtimeServerEventResponseFunctionCallArgumentsDone, + _models.RealtimeServerEventResponseMCPCallArgumentsDelta, + _models.RealtimeServerEventResponseMCPCallArgumentsDone, + _models.RealtimeServerEventResponseMCPCallCompleted, + _models.RealtimeServerEventResponseMCPCallFailed, + _models.RealtimeServerEventResponseMCPCallInProgress, + _models.RealtimeServerEventResponseOutputItemAdded, + _models.RealtimeServerEventResponseOutputItemDone, + _models.RealtimeServerEventResponseTextDelta, + _models.RealtimeServerEventResponseTextDone, + _models.VoiceAgentServerEventResponseVideoDelta, + _models.VoiceAgentServerEventRtcCallError, + _models.VoiceAgentServerEventRtcCallSdpCreated, + _models.VoiceAgentServerEventSessionAvatarConnecting, + _models.VoiceAgentServerEventSessionAvatarSwitchToIdle, + _models.VoiceAgentServerEventSessionAvatarSwitchToSpeaking, + _models.RealtimeServerEventSessionCreated, + _models.VoiceAgentServerEventSessionSubagentAborted, + _models.VoiceAgentServerEventSessionSubagentCompleted, + _models.VoiceAgentServerEventSessionSubagentStarted, + _models.RealtimeServerEventSessionUpdated, + _models.VoiceAgentServerEventWarning, + Mapping[str, Any], +] + + +def _to_ws_url(endpoint: str, agent_name: str) -> str: + """Build the realtime WebSocket URL from the HTTPS project endpoint. + + Only the ``https://`` scheme is translated (to ``wss://``); any other scheme is left + unchanged so that :meth:`AsyncBetaRealtimeConnectionManager.enter`'s ``wss://``-only check + rejects it with a clear error instead of silently producing an unencrypted ``ws://`` URL + that would also send the live Authorization token in plain text. + + :param str endpoint: The Foundry project endpoint (``https://.../api/projects/...``). + :param str agent_name: The name of the voice agent to connect to. + :return: A ``wss://`` URL targeting the realtime route. + :rtype: str + """ + base = endpoint.rstrip("/") + if base.startswith("https://"): + base = "wss://" + base[len("https://") :] + return f"{base}/agents/{quote(agent_name, safe='')}/endpoint/protocols/voice" + + +_DEFAULT_PORT_BY_SCHEME = {"http": 80, "https": 443, "ws": 80, "wss": 443} + + +def _normalized_authority(url: str) -> Tuple[str, Optional[int]]: + """Return a ``(hostname, port)`` tuple with the scheme's default port filled in. + + ``urlparse(...).port`` is ``None`` when a URL omits an explicit port, which would make + ``https://host/...`` and ``https://host:8443/...`` compare as equal on hostname alone. + Resolving the scheme's default port here lets callers compare authorities (not just + hostnames) so a same-host override on a different, non-default port is correctly rejected. + + :param str url: The URL to parse. + :return: A tuple of the lower-cased hostname (or empty string) and the resolved port + (or ``None`` if the scheme has no known default and none was specified). + :rtype: tuple[str, Optional[int]] + """ + parsed = urlparse(url) + port = parsed.port + if port is None: + port = _DEFAULT_PORT_BY_SCHEME.get((parsed.scheme or "").lower()) + return (parsed.hostname or "").lower(), port + + +def _assert_trusted_connection_url(connection_url: str, endpoint: str) -> None: + """Guard against attaching the caller's Entra bearer token to an untrusted host. + + ``connection_url`` is an escape hatch that lets a caller override the computed + scheme/host/path, but the Authorization header carrying the live credential's + token must never be sent to a host other than the configured Foundry project + endpoint: a caller-controlled or compromised URL could otherwise be used to + exfiltrate the token to an arbitrary host or port. + + :param str connection_url: The caller-supplied override URL. + :param str endpoint: The configured, trusted Foundry project endpoint. + :raises ValueError: If the override URL's host or port does not match the endpoint's. + """ + override_host, override_port = _normalized_authority(connection_url) + trusted_host, trusted_port = _normalized_authority(endpoint) + if not override_host or (override_host, override_port) != (trusted_host, trusted_port): + got = override_host or connection_url + if override_host and override_port: + got = f"{override_host}:{override_port}" + raise ValueError( + "The 'connection_url' override must target the same host and port as the configured " + f"Foundry project endpoint ('{trusted_host}:{trusted_port}') to avoid sending the " + f"Authorization token to an untrusted host; got '{got}'." + ) + + +class _BaseResource: # pylint: disable=too-few-public-methods + """Base helper that forwards typed helpers to the parent connection.""" + + def __init__(self, connection: "AsyncBetaRealtimeConnection") -> None: + self._connection = connection + + async def _send(self, event: ClientEvent) -> None: + await self._connection.send(event) + + +class SessionResource(_BaseResource): + """Send ``session.*`` client events.""" + + async def update( + self, + *, + session: Union["_models.VoiceAgentSessionUpdateConfig", Mapping[str, Any]], + event_id: Optional[str] = None, + ) -> None: + """Update the realtime session configuration. + + :keyword session: The session configuration to apply. + :paramtype session: ~azure.ai.projects.models.VoiceAgentSessionUpdateConfig or + Mapping[str, Any] + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + cast(Any, _models.VoiceAgentClientEventSessionUpdate)( + type=_models.RealtimeClientEventType.SESSION_UPDATE, + session=session, + event_id=event_id, + ) + ) + + async def avatar_connect(self, *, client_sdp: str, event_id: Optional[str] = None) -> None: + """Negotiate an avatar media session over WebRTC. + + :keyword str client_sdp: The client's SDP offer for avatar media negotiation. + :keyword event_id: An optional client-generated event identifier. + :paramtype event_id: str or None + """ + await self._send( + _models.VoiceAgentClientEventSessionAvatarConnect( + client_sdp=client_sdp, + event_id=event_id, + ) + ) + + +class InputAudioBufferResource(_BaseResource): + """Send ``input_audio_buffer.*`` client events.""" + + async def append(self, *, audio: Union[str, bytes], event_id: Optional[str] = None) -> None: + """Append audio bytes to the input buffer. + + :keyword audio: Raw audio bytes, or an already base64-encoded string. + :paramtype audio: str or bytes + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + if isinstance(audio, (bytes, bytearray)): + audio = base64.b64encode(bytes(audio)).decode("ascii") + await self._send( + _models.RealtimeClientEventInputAudioBufferAppend( + audio=audio, + event_id=event_id, + ) + ) + + async def commit(self, *, event_id: Optional[str] = None) -> None: + """Commit the buffered input audio as a user turn. + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send(_models.RealtimeClientEventInputAudioBufferCommit(event_id=event_id)) + + async def clear(self, *, event_id: Optional[str] = None) -> None: + """Discard any buffered input audio. + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send(_models.RealtimeClientEventInputAudioBufferClear(event_id=event_id)) + + +class OutputAudioBufferResource(_BaseResource): # pylint: disable=too-few-public-methods + """Send ``output_audio_buffer.*`` client events.""" + + async def clear(self, *, event_id: Optional[str] = None) -> None: + """Stop and clear any audio the service is currently playing back (barge-in). + + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send(_models.RealtimeClientEventOutputAudioBufferClear(event_id=event_id)) + + +class ConversationItemResource(_BaseResource): + """Send ``conversation.item.*`` client events.""" + + async def create( + self, + *, + item: ConversationItem, + previous_item_id: Optional[str] = None, + event_id: Optional[str] = None, + ) -> None: + """Insert an item into the conversation. + + :keyword item: The conversation item to create. + :paramtype item: ~azure.ai.projects.models.RealtimeConversationItemMessageSystem or + ~azure.ai.projects.models.RealtimeConversationItemMessageUser or + ~azure.ai.projects.models.RealtimeConversationItemMessageAssistant or + ~azure.ai.projects.models.RealtimeConversationItemFunctionCall or + ~azure.ai.projects.models.RealtimeConversationItemFunctionCallOutput or + ~azure.ai.projects.models.RealtimeMCPApprovalResponse or Mapping[str, Any] + :keyword previous_item_id: The ID of the preceding item after which the new item will be + inserted. Default value is None. + :paramtype previous_item_id: str or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + cast(Any, _models.RealtimeClientEventConversationItemCreate)( + item=item, + previous_item_id=previous_item_id, + event_id=event_id, + ) + ) + + async def delete(self, *, item_id: str, event_id: Optional[str] = None) -> None: + """Delete an item from the conversation. + + :keyword str item_id: The ID of the item to delete. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + _models.RealtimeClientEventConversationItemDelete( + item_id=item_id, + event_id=event_id, + ) + ) + + async def retrieve(self, *, item_id: str, event_id: Optional[str] = None) -> None: + """Ask the server to emit a ``conversation.item.retrieved`` event for an item. + + :keyword str item_id: The ID of the item to retrieve. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + _models.RealtimeClientEventConversationItemRetrieve( + item_id=item_id, + event_id=event_id, + ) + ) + + async def truncate( + self, *, item_id: str, content_index: int, audio_end_ms: int, event_id: Optional[str] = None + ) -> None: + """Truncate a previously produced assistant audio item (used for barge-in). + + :keyword str item_id: The ID of the assistant message item to truncate. + :keyword int content_index: The index of the content part to truncate. Use ``0``. + :keyword int audio_end_ms: The point, in milliseconds, to truncate the audio to. + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + _models.RealtimeClientEventConversationItemTruncate( + item_id=item_id, + content_index=content_index, + audio_end_ms=audio_end_ms, + event_id=event_id, + ) + ) + + +class ConversationResource(_BaseResource): # pylint: disable=too-few-public-methods + """Send ``conversation.*`` client events.""" + + def __init__(self, connection: "AsyncBetaRealtimeConnection") -> None: + super().__init__(connection) + self.item: ConversationItemResource = ConversationItemResource(connection) + + +class ResponseResource(_BaseResource): + """Send ``response.*`` client events.""" + + async def create( + self, + *, + response: Optional[Union["_models.VoiceAgentResponseCreateParams", Mapping[str, Any]]] = None, + event_id: Optional[str] = None, + ) -> None: + """Ask the model to generate a response. + + :keyword response: Optional per-response overrides. Default value is None. + :paramtype response: ~azure.ai.projects.models.VoiceAgentResponseCreateParams or + Mapping[str, Any] or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + cast(Any, _models.RealtimeClientEventResponseCreate)( + response=response, + event_id=event_id, + ) + ) + + async def cancel(self, *, response_id: Optional[str] = None, event_id: Optional[str] = None) -> None: + """Cancel an in-progress response. + + :keyword response_id: The ID of the response to cancel, if targeting a specific one. + Default value is None. + :paramtype response_id: str or None + :keyword event_id: Optional client-generated ID used to identify this event. + :paramtype event_id: str or None + """ + await self._send( + _models.RealtimeClientEventResponseCancel( + response_id=response_id, + event_id=event_id, + ) + ) + + +class _AbnormalWebSocketClosure(Exception): + """Internal marker chained onto :exc:`ConnectionResetError` for a non-graceful WebSocket + closure (an abnormal close code), so :meth:`AsyncBetaRealtimeConnection._iter` can tell it apart + from a normal end of stream, which chains no cause.""" + + +class AsyncBetaRealtimeConnection: # pylint: disable=too-many-instance-attributes + """An open realtime WebSocket connection to a voice agent. + + Iterate over the connection to receive strongly-typed server events, and use the + sub-namespaces to send strongly-typed client events:: + + async with client.beta.voice_agents.realtime.connect(agent_name="my-agent") as conn: + await conn.input_audio_buffer.append(audio=chunk) + await conn.input_audio_buffer.commit() + await conn.response.create() + async for event in conn: + if event.type == RealtimeServerEventType.RESPONSE_DONE: + break + """ + + def __init__(self, connection: "ClientWebSocketResponse", session: "ClientSession") -> None: + self._connection = connection + self._session = session + self.session: SessionResource = SessionResource(self) + self.input_audio_buffer: InputAudioBufferResource = InputAudioBufferResource(self) + self.output_audio_buffer: OutputAudioBufferResource = OutputAudioBufferResource(self) + self.conversation: ConversationResource = ConversationResource(self) + self.response: ResponseResource = ResponseResource(self) + + async def __aenter__(self) -> "AsyncBetaRealtimeConnection": + return self + + async def __aexit__(self, *exc_details: Any) -> None: + await self.close() + + def __repr__(self) -> str: + state = "closed" if self.closed else "open" + return f"" + + @property + def closed(self) -> bool: + """Whether the underlying WebSocket connection has been closed. + + :rtype: bool + """ + return self._connection.closed + + def __aiter__(self) -> AsyncIterator[ServerEvent]: + return self._iter() + + async def _iter(self) -> AsyncIterator[ServerEvent]: + while True: + try: + yield await self.recv() + except ConnectionResetError as exc: + # recv() below only chains a cause for a non-graceful closure or transport error + # (an abnormal close code, or the real exception behind a WSMsgType.ERROR); a + # graceful closure chains none. A `for event in conn:` caller must still see real + # failures instead of silently observing end-of-stream, so only the former ends + # iteration quietly. + if exc.__cause__ is None: + return + raise + + async def recv(self) -> ServerEvent: + """Receive and parse the next server event. + + Known event types are returned as their strongly-typed + ``VoiceAgentServerEventXxx`` model. Event types not (yet) represented by a + generated model are returned as a plain ``dict`` for forward compatibility. + + :return: The parsed server event. + :rtype: ~azure.ai.projects.aio.ServerEvent + :raises ConnectionResetError: If the connection was closed by the server, gracefully or + otherwise, or if the transport reported an error. Iterating over the connection + (``async for event in conn:``) treats only a graceful closure as end-of-stream and + re-raises this for an abnormal one. + """ + import aiohttp # pylint: disable=import-outside-toplevel + + msg = await self._connection.receive() + while msg.type in (aiohttp.WSMsgType.PING, aiohttp.WSMsgType.PONG): + msg = await self._connection.receive() + if msg.type in ( + aiohttp.WSMsgType.CLOSE, + aiohttp.WSMsgType.CLOSING, + aiohttp.WSMsgType.CLOSED, + ): + code = self._connection.close_code + if code not in (1000, 1001): + raise ConnectionResetError( + f"The realtime connection was closed abnormally (code {code!r})." + ) from _AbnormalWebSocketClosure(code) + raise ConnectionResetError("The realtime connection was closed.") + if msg.type == aiohttp.WSMsgType.ERROR: + raise ConnectionResetError( + "The realtime connection encountered an error." + ) from self._connection.exception() + raw = msg.data.decode("utf-8") if msg.type == aiohttp.WSMsgType.BINARY else msg.data + payload: Dict[str, Any] = json.loads(raw) + event_type = payload.get("type") + _LOGGER.debug( + "WebSocket RECEIVE type=%s bytes=%d", + event_type if isinstance(event_type, str) else "unknown", + len(raw.encode("utf-8")), + ) + if not isinstance(event_type, str): + return payload + event_cls = _SERVER_EVENT_TYPES.get(event_type) + if event_cls is None: + return payload + return event_cls(payload) + + async def send(self, event: ClientEvent) -> None: + """Send a client event over the connection. + + :param event: A strongly-typed client event, a ready-made mapping, or a raw JSON string. + :type event: ~azure.ai.projects.aio.ClientEvent or str + :raises ValueError: If ``event`` is a ``str`` that is not valid JSON. + """ + if isinstance(event, str): + try: + event_payload = json.loads(event) + except ValueError as exc: + raise ValueError(f"'event' is not valid JSON: {exc}") from exc + payload = event + else: + payload = json.dumps(event, cls=SdkJSONEncoder) + event_payload = json.loads(payload) + event_type = event_payload.get("type") if isinstance(event_payload, dict) else None + _LOGGER.debug( + "WebSocket SEND type=%s bytes=%d", + event_type if isinstance(event_type, str) else "unknown", + len(payload.encode("utf-8")), + ) + await self._connection.send_str(payload) + + async def close(self, *, code: int = 1000, reason: str = "") -> None: + """Close the connection and release the underlying HTTP session. + + :keyword int code: The WebSocket close code. + :keyword str reason: The close reason. + """ + _LOGGER.debug("WebSocket CLOSE code=%d", code) + try: + await self._connection.close(code=code, message=reason.encode("utf-8")) + finally: + await self._session.close() + + +class AsyncBetaRealtimeConnectionManager: # pylint: disable=too-many-instance-attributes + """Async context manager that opens an :class:`AsyncBetaRealtimeConnection`. + + Returned by :meth:`AsyncBetaRealtime.connect`; you normally use it as + ``async with client.beta.voice_agents.realtime.connect(...) as conn:``. + """ + + def __init__( # pylint: disable=too-many-arguments + self, + *, + endpoint: str, + credential: "AsyncTokenCredential", + credential_scopes: List[str], + api_version: str, + agent_name: str, + agent_session_id: Optional[str] = None, + structured_inputs: Optional[Mapping[str, Any]] = None, + connection_url: Optional[str] = None, + extra_query: Optional[Mapping[str, str]] = None, + extra_headers: Optional[Mapping[str, str]] = None, + **kwargs: Any, + ) -> None: + self._endpoint = endpoint + self._credential = credential + self._credential_scopes = credential_scopes + self._api_version = api_version + self._agent_name = agent_name + self._agent_session_id = agent_session_id + self._structured_inputs = structured_inputs + self._connection_url = connection_url + self._extra_query = dict(extra_query or {}) + self._extra_headers = dict(extra_headers or {}) + self._kwargs = kwargs + self._connection: Optional[AsyncBetaRealtimeConnection] = None + + async def __aenter__(self) -> AsyncBetaRealtimeConnection: + return await self.enter() + + async def enter(self) -> AsyncBetaRealtimeConnection: # pylint: disable=too-many-locals + """Open the connection. + + :return: The live realtime connection. + :rtype: ~azure.ai.projects.aio.AsyncBetaRealtimeConnection + :raises RuntimeError: If ``aiohttp`` is not installed. + :raises ValueError: If the computed or supplied WebSocket URL does not use ``wss://``. + :raises ConnectionError: If the WebSocket upgrade handshake fails (for example, a + network error, DNS failure, or a non-101 response from the service). + """ + try: + import aiohttp # pylint: disable=import-outside-toplevel + except ImportError as exc: # pragma: no cover - dependency guard + raise RuntimeError( + "The realtime client requires `aiohttp`. Install it with `pip install aiohttp`." + ) from exc + + # ``connection_url`` fully overrides the computed route (scheme/host/path). This is the + # escape hatch used to reach a specific data-plane host/path directly. + if self._connection_url is not None: + _assert_trusted_connection_url(self._connection_url, self._endpoint) + url = self._connection_url or _to_ws_url(self._endpoint, self._agent_name) + if not url.startswith("wss://"): + raise ValueError("The realtime WebSocket URL must use wss:// to protect credentials in transit.") + + params: Dict[str, str] = {"api-version": self._api_version, "x-ms-client-sdk": _USER_AGENT} + if self._agent_session_id is not None: + params["agent_session_id"] = self._agent_session_id + if self._structured_inputs is not None: + # The service reads this from the `structured_input` query parameter (see the + # generated `build_beta_voice_agents_realtime_connect_voice_agent_request`), not a + # header -- aiohttp appends `params` to the URL for us below. + params["structured_input"] = json.dumps(self._structured_inputs, cls=SdkJSONEncoder) + params.update(self._extra_query) + + target_url = urlparse(url)._replace(query="", fragment="").geturl() + _LOGGER.debug("WebSocket CONNECT target=%s", target_url) + + token = await self._credential.get_token(*self._credential_scopes) + headers: Dict[str, str] = { + "Authorization": "Bearer " + token.token, + _FOUNDRY_FEATURES_HEADER_NAME: _VOICE_AGENT_FEATURE_HEADER, + } + headers.update(self._extra_headers) + if not _has_header_case_insensitive(headers, "User-Agent"): + # Only set our default if the caller didn't supply their own (in any casing) -- + # a plain dict merge would otherwise leave both as separate keys (HTTP header names + # are case-insensitive, but Python dict keys are not), sending two User-Agent-like + # headers instead of cleanly honoring the caller's override. + headers["User-Agent"] = _USER_AGENT + + session = aiohttp.ClientSession() + try: + # Force the "realtime" WebSocket subprotocol regardless of any caller-supplied + # override in ``self._kwargs``: the service requires this exact subprotocol, so + # silently accepting a different one here would just move the failure to a less + # clear error inside aiohttp's handshake. + ws_connect_kwargs = dict(self._kwargs) + ws_connect_kwargs.pop("protocols", None) + connection = await session.ws_connect( + url, headers=headers, params=params, protocols=("realtime",), **ws_connect_kwargs + ) + except BaseException as exc: + await session.close() + if not isinstance(exc, Exception) or isinstance(exc, (ValueError, RuntimeError)): + raise + raise ConnectionError( + f"Failed to open the realtime WebSocket connection to voice agent " + f"'{self._agent_name}' at '{url}': {exc}" + ) from exc + _LOGGER.debug("WebSocket CONNECTED target=%s", target_url) + self._connection = AsyncBetaRealtimeConnection(cast("ClientWebSocketResponse", connection), session) + return self._connection + + async def __aexit__(self, *exc_details: Any) -> None: + if self._connection is not None: + await self._connection.close() + self._connection = None + + +class AsyncBetaRealtime: # pylint: disable=too-few-public-methods + """BetaRealtime streaming entry point, exposed as ``client.beta.voice_agents.realtime``. + + Follows the OpenAI Python realtime surface: obtain it from the HTTP client and open a + connection with :meth:`connect`:: + + from azure.ai.projects.aio import AIProjectClient + from azure.identity.aio import DefaultAzureCredential + + client = AIProjectClient(endpoint, DefaultAzureCredential()) + async with client.beta.voice_agents.realtime.connect(agent_name="my-agent") as conn: + await conn.input_audio_buffer.append(audio=chunk) + await conn.input_audio_buffer.commit() + await conn.response.create() + async for event in conn: + if event.type == RealtimeServerEventType.RESPONSE_DONE: + break + + :param client: The object whose endpoint and credential are reused for the realtime + handshake -- the ``.beta.voice_agents`` sub-client, which shares the same underlying + configuration as the top-level client. + :type client: ~azure.ai.projects.aio.operations.BetaVoiceAgentsOperations + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + input_args = list(args) + client: "_ConfigProvider" = input_args.pop(0) if input_args else kwargs.pop("client") + self._config = client._config # pylint: disable=protected-access + + def connect( # pylint: disable=too-many-arguments + self, + *, + agent_name: str, + agent_session_id: Optional[str] = None, + structured_inputs: Optional[Mapping[str, Any]] = None, + connection_url: Optional[str] = None, + api_version: Optional[str] = None, + credential_scopes: Optional[List[str]] = None, + extra_query: Optional[Mapping[str, str]] = None, + extra_headers: Optional[Mapping[str, str]] = None, + **kwargs: Any, + ) -> AsyncBetaRealtimeConnectionManager: + """Open a realtime WebSocket connection to a voice agent. + + :keyword str agent_name: The name of the voice agent to connect to. + :keyword agent_session_id: An optional identifier used to correlate the voice session. + Default value is None. + :paramtype agent_session_id: str or None + :keyword structured_inputs: A mapping of structured-input names to their values for this + session (see :attr:`~azure.ai.projects.models.CreateTelephonyCallJobRequest.structured_inputs` + for the analogous shape used elsewhere). Serialized to JSON on the wire. Default value is + None. + :paramtype structured_inputs: Mapping[str, Any] or None + :keyword connection_url: Full ``wss://`` URL that overrides the route computed + from the client endpoint. Query parameters are still appended. Default value is None. + :paramtype connection_url: str or None + :keyword api_version: Overrides the client's API version for the handshake. Default + value is None. + :paramtype api_version: str or None + :keyword credential_scopes: Overrides the client's token scopes for the handshake. + Default value is None. + :paramtype credential_scopes: list[str] or None + :keyword extra_query: Additional query-string parameters for the handshake. + :paramtype extra_query: Mapping[str, str] or None + :keyword extra_headers: Additional headers for the handshake. Pass + ``{"Foundry-Features": "..."}`` here to override the ``VoiceAgents=V1Preview`` value + this method always sends by default. + :paramtype extra_headers: Mapping[str, str] or None + :return: An async context manager yielding an :class:`AsyncBetaRealtimeConnection`. + :rtype: ~azure.ai.projects.aio.AsyncBetaRealtimeConnectionManager + """ + return AsyncBetaRealtimeConnectionManager( + endpoint=self._config.endpoint, + credential=self._config.credential, + credential_scopes=credential_scopes or self._config.credential_scopes, + api_version=api_version or self._config.api_version, + agent_name=agent_name, + agent_session_id=agent_session_id, + structured_inputs=structured_inputs, + connection_url=connection_url, + extra_query=extra_query, + extra_headers=extra_headers, + **kwargs, + ) diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_operations.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_operations.py index 2ddf8953b1ea..4f3ead6c6ad7 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_operations.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_operations.py @@ -7,12 +7,13 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- from collections.abc import MutableMapping +import datetime from io import IOBase import json -from typing import Any, AsyncIterator, Callable, IO, Literal, Optional, TypeVar, Union, cast, overload +from typing import Any, AsyncIterator, Callable, IO, Literal, Optional, TYPE_CHECKING, TypeVar, Union, cast, overload import urllib.parse -from azure.core import AsyncPipelineClient +from azure.core import AsyncPipelineClient, MatchConditions from azure.core.async_paging import AsyncItemPaged, AsyncList from azure.core.exceptions import ( ClientAuthenticationError, @@ -77,6 +78,7 @@ build_beta_agent_insight_monitors_update_insight_request, build_beta_agent_insight_monitors_update_request, build_beta_agents_cancel_optimization_job_request, + build_beta_agents_create_from_prompt_request, build_beta_agents_create_optimization_job_request, build_beta_agents_delete_optimization_job_request, build_beta_agents_get_optimization_job_request, @@ -156,6 +158,34 @@ build_beta_skills_list_request, build_beta_skills_list_versions_request, build_beta_skills_update_request, + build_beta_voice_agents_conversations_delete_request, + build_beta_voice_agents_conversations_download_audio_item_request, + build_beta_voice_agents_conversations_download_audio_request, + build_beta_voice_agents_conversations_download_generated_audio_item_request, + build_beta_voice_agents_conversations_get_audio_item_request, + build_beta_voice_agents_conversations_get_audio_request, + build_beta_voice_agents_conversations_get_generated_audio_item_request, + build_beta_voice_agents_conversations_get_item_request, + build_beta_voice_agents_conversations_get_request, + build_beta_voice_agents_conversations_get_response_request, + build_beta_voice_agents_conversations_list_items_request, + build_beta_voice_agents_conversations_list_request, + build_beta_voice_agents_conversations_list_response_items_request, + build_beta_voice_agents_conversations_list_responses_request, + build_beta_voice_agents_telephony_cancel_call_job_request, + build_beta_voice_agents_telephony_create_binding_request, + build_beta_voice_agents_telephony_create_call_job_request, + build_beta_voice_agents_telephony_delete_binding_request, + build_beta_voice_agents_telephony_end_call_request, + build_beta_voice_agents_telephony_get_binding_request, + build_beta_voice_agents_telephony_get_call_job_request, + build_beta_voice_agents_telephony_get_call_request, + build_beta_voice_agents_telephony_get_transfer_targets_request, + build_beta_voice_agents_telephony_list_bindings_request, + build_beta_voice_agents_telephony_list_calls_request, + build_beta_voice_agents_telephony_replace_transfer_targets_request, + build_beta_voice_agents_telephony_transfer_call_request, + build_beta_voice_agents_telephony_update_binding_request, build_connections_get_request, build_connections_get_with_credentials_request, build_connections_list_request, @@ -182,12 +212,15 @@ build_toolboxes_delete_version_request, build_toolboxes_get_request, build_toolboxes_get_version_request, + build_toolboxes_invoke_latest_toolbox_mcp_request, build_toolboxes_list_request, build_toolboxes_list_versions_request, build_toolboxes_update_request, ) from .._configuration import AIProjectClientConfiguration +if TYPE_CHECKING: + from ... import _unions JSON = MutableMapping[str, Any] _Unset: Any = object() T = TypeVar("T") @@ -212,6 +245,8 @@ def __init__(self, *args, **kwargs) -> None: self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + self.voice_agents = BetaVoiceAgentsOperations(self._client, self._config, self._serialize, self._deserialize) + self.agents = BetaAgentsOperations(self._client, self._config, self._serialize, self._deserialize) self.agent_insight_monitors = BetaAgentInsightMonitorsOperations( self._client, self._config, self._serialize, self._deserialize ) @@ -227,7 +262,6 @@ def __init__(self, *args, **kwargs) -> None: self.schedules = BetaSchedulesOperations(self._client, self._config, self._serialize, self._deserialize) self.skills = BetaSkillsOperations(self._client, self._config, self._serialize, self._deserialize) self.datasets = BetaDatasetsOperations(self._client, self._config, self._serialize, self._deserialize) - self.agents = BetaAgentsOperations(self._client, self._config, self._serialize, self._deserialize) class AgentsOperations: # pylint: disable=docstring-missing-param,too-many-public-methods @@ -406,7 +440,7 @@ def list( Returns a paged collection of agent resources. :keyword kind: Filter agents by kind. If not provided, all agents are returned. Known values - are: "prompt", "hosted", "workflow", and "external". Default value is None. + are: "prompt", "hosted", "workflow", "external", and "voice". Default value is None. :paramtype kind: str or ~azure.ai.projects.models.AgentKind :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and 100, and the @@ -5975,6 +6009,83 @@ async def get_version(self, name: str, version: str, **kwargs: Any) -> _models.T return deserialized # type: ignore + @distributed_trace_async + async def invoke_latest_toolbox_mcp(self, name: str, request: dict[str, Any], **kwargs: Any) -> Any: + """Invoke the latest toolbox version through MCP. + + Invokes the latest version of the specified toolbox through its MCP endpoint. + + :param name: The name of the toolbox. Required. + :type name: str + :param request: The MCP request body. Required. + :type request: dict[str, any] + :return: any + :rtype: any + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + content_type: str = kwargs.pop("content_type") + cls: ClsType[Any] = kwargs.pop("cls", None) + + _content = request + + _request = build_toolboxes_invoke_latest_toolbox_mcp_request( + name=name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["content-type"] = self._deserialize("str", response.headers.get("content-type")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(Any, response.text()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + @overload async def update( self, name: str, *, default_version: str, content_type: str = "application/json", **kwargs: Any @@ -6237,14 +6348,14 @@ async def delete_version(self, name: str, version: str, **kwargs: Any) -> None: return cls(pipeline_response, None, {}) # type: ignore -class BetaAgentInsightMonitorsOperations: # pylint: disable=docstring-missing-param +class BetaVoiceAgentsOperations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. Instead, you should access the following operations through :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`agent_insight_monitors` attribute. + :attr:`voice_agents` attribute. """ def __init__(self, *args, **kwargs) -> None: @@ -6254,154 +6365,43 @@ def __init__(self, *args, **kwargs) -> None: self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace - def list( - self, - *, - before: Optional[str] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - agent_name: Optional[str] = None, - **kwargs: Any - ) -> AsyncItemPaged["_models.AgentInsightMonitorListItem"]: - """List Agent Insights monitors, optionally filtered by agent name. - - :keyword before: A cursor that identifies the first item in the next page. Default value is - None. - :paramtype before: str - :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" - and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword agent_name: Filter monitors by agent name. Default value is None. - :paramtype agent_name: str - :return: An iterator like instance of AgentInsightMonitorListItem - :rtype: - ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.AgentInsightMonitorListItem] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.AgentInsightMonitorListItem]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(_continuation_token=None): - - _request = build_beta_agent_insight_monitors_list_request( - after=_continuation_token, - before=before, - limit=limit, - order=order, - agent_name=agent_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request - - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.AgentInsightMonitorListItem], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, AsyncList(list_of_elem) - - async def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) - - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - return pipeline_response - - return AsyncItemPaged(get_next, extract_data) - - @overload - async def create( - self, monitor: _models.AgentInsightMonitorCreate, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Create an Agent Insights monitor for an agent. - - :param monitor: The monitor to create. Required. - :type monitor: ~azure.ai.projects.models.AgentInsightMonitorCreate - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor - :raises ~azure.core.exceptions.HttpResponseError: - """ + self.conversations = BetaVoiceAgentsConversationsOperations( + self._client, self._config, self._serialize, self._deserialize + ) + self.telephony = BetaVoiceAgentsTelephonyOperations( + self._client, self._config, self._serialize, self._deserialize + ) - @overload - async def create( - self, monitor: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Create an Agent Insights monitor for an agent. - :param monitor: The monitor to create. Required. - :type monitor: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor - :raises ~azure.core.exceptions.HttpResponseError: - """ +class BetaAgentsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. - @overload - async def create( - self, monitor: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Create an Agent Insights monitor for an agent. + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`agents` attribute. + """ - :param monitor: The monitor to create. Required. - :type monitor: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor - :raises ~azure.core.exceptions.HttpResponseError: - """ + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") @distributed_trace_async - async def create( - self, monitor: Union[_models.AgentInsightMonitorCreate, JSON, IO[bytes]], **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Create an Agent Insights monitor for an agent. + async def create_from_prompt(self, body: "_unions.GenerateAgentRequest", **kwargs: Any) -> _models.AgentDetails: + """Generate an agent. - :param monitor: The monitor to create. Is one of the following types: - AgentInsightMonitorCreate, JSON, IO[bytes] Required. - :type monitor: ~azure.ai.projects.models.AgentInsightMonitorCreate or JSON or IO[bytes] - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor + Generates and creates an agent from kind-specific high-level inputs. The generated definition + remains fully editable through the standard agent versioning operations. + + :param body: The kind-specific inputs for generating and creating an agent. Is one of the + following types: GenerateVoiceAgentRequest Required. + :type body: ~azure.ai.projects.models.GenerateVoiceAgentRequest + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -6416,16 +6416,12 @@ async def create( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) content_type = content_type or "application/json" - _content = None - if isinstance(monitor, (IOBase, bytes)): - _content = monitor - else: - _content = json.dumps(monitor, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_agent_insight_monitors_create_request( + _request = build_beta_agents_create_from_prompt_request( content_type=content_type, api_version=self._config.api_version, content=_content, @@ -6445,7 +6441,7 @@ async def create( response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: try: await response.read() # Load the body in memory and close the socket @@ -6458,29 +6454,23 @@ async def create( ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) + deserialized = _deserialize(_models.AgentDetails, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace_async - async def get(self, monitor_id: str, **kwargs: Any) -> _models.AgentInsightMonitor: - """Get an Agent Insights monitor. - - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor - :raises ~azure.core.exceptions.HttpResponseError: - """ + async def _create_optimization_job_initial( + self, + job: Union[_models.AgentOptimizationJob, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> AsyncIterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -6489,14 +6479,24 @@ async def get(self, monitor_id: str, **kwargs: Any) -> _models.AgentInsightMonit } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_get_request( - monitor_id=monitor_id, + content_type = content_type or "application/json" + _content = None + if isinstance(job, (IOBase, bytes)): + _content = job + else: + _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_agents_create_optimization_job_request( + operation_id=operation_id, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -6506,19 +6506,18 @@ async def get(self, monitor_id: str, **kwargs: Any) -> _models.AgentInsightMonit _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = True pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [201]: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -6526,24 +6525,192 @@ async def get(self, monitor_id: str, **kwargs: Any) -> _models.AgentInsightMonit ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore + @overload + async def begin_create_optimization_job( + self, + job: _models.AgentOptimizationJob, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.AgentOptimizationJobResult]: + """Create an agent optimization job. + + Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent + retry. + + :param job: The job to create. Required. + :type job: ~azure.ai.projects.models.AgentOptimizationJob + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns AgentOptimizationJobResult. The + AgentOptimizationJobResult is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def begin_create_optimization_job( + self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.AgentOptimizationJobResult]: + """Create an agent optimization job. + + Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent + retry. + + :param job: The job to create. Required. + :type job: JSON + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns AgentOptimizationJobResult. The + AgentOptimizationJobResult is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def begin_create_optimization_job( + self, + job: IO[bytes], + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.AgentOptimizationJobResult]: + """Create an agent optimization job. + + Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent + retry. + + :param job: The job to create. Required. + :type job: IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns AgentOptimizationJobResult. The + AgentOptimizationJobResult is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + @distributed_trace_async - async def delete(self, monitor_id: str, **kwargs: Any) -> None: - """Delete an Agent Insights monitor and all of its runs, insights, and state. + async def begin_create_optimization_job( + self, + job: Union[_models.AgentOptimizationJob, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> AsyncLROPoller[_models.AgentOptimizationJobResult]: + """Create an agent optimization job. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :return: None - :rtype: None + Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent + retry. + + :param job: The job to create. Is one of the following types: AgentOptimizationJob, JSON, + IO[bytes] Required. + :type job: ~azure.ai.projects.models.AgentOptimizationJob or JSON or IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :return: An instance of AsyncLROPoller that returns AgentOptimizationJobResult. The + AgentOptimizationJobResult is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentOptimizationJobResult] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._create_optimization_job_initial( + job=job, + operation_id=operation_id, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = _deserialize(_models.AgentOptimizationJobResult, response.json().get("result", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized + + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) + else: + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.AgentOptimizationJobResult].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.AgentOptimizationJobResult]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) + + @distributed_trace_async + async def get_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOptimizationJob: + """Get an agent optimization job. + + Retrieves an optimization job by its identifier. + + :param job_id: The ID of the job. Required. + :type job_id: str + :return: AgentOptimizationJob. The AgentOptimizationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentOptimizationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -6557,10 +6724,10 @@ async def delete(self, monitor_id: str, **kwargs: Any) -> None: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentOptimizationJob] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_delete_request( - monitor_id=monitor_id, + _request = build_beta_agents_get_optimization_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -6570,14 +6737,20 @@ async def delete(self, monitor_id: str, **kwargs: Any) -> None: } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -6585,81 +6758,132 @@ async def delete(self, monitor_id: str, **kwargs: Any) -> None: ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentOptimizationJob, response.json()) + if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore - @overload - async def update( + return deserialized # type: ignore + + @distributed_trace + def list_optimization_jobs( self, - monitor_id: str, - monitor: _models.AgentInsightMonitorUpdate, *, - content_type: str = "application/merge-patch+json", + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + status: Optional[Union[str, _models.JobStatus]] = None, + agent_name: Optional[str] = None, **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Update an Agent Insights monitor. + ) -> AsyncItemPaged["_models.AgentOptimizationJobListItem"]: + """List agent optimization jobs. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param monitor: The monitor fields to update. Required. - :type monitor: ~azure.ai.projects.models.AgentInsightMonitorUpdate - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor + Lists optimization jobs with cursor pagination and optional status or agent name filters. + + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :keyword status: Filter to jobs in this lifecycle state. Known values are: "queued", + "in_progress", "succeeded", "failed", and "cancelled". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.JobStatus + :keyword agent_name: Filter to jobs targeting this agent name. Default value is None. + :paramtype agent_name: str + :return: An iterator like instance of AgentOptimizationJobListItem + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.AgentOptimizationJobListItem] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @overload - async def update( - self, monitor_id: str, monitor: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Update an Agent Insights monitor. + cls: ClsType[List[_models.AgentOptimizationJobListItem]] = kwargs.pop("cls", None) - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param monitor: The monitor fields to update. Required. - :type monitor: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor - :raises ~azure.core.exceptions.HttpResponseError: - """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - @overload - async def update( - self, monitor_id: str, monitor: IO[bytes], *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Update an Agent Insights monitor. + def prepare_request(_continuation_token=None): - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param monitor: The monitor fields to update. Required. - :type monitor: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor - :raises ~azure.core.exceptions.HttpResponseError: - """ + _request = build_beta_agents_list_optimization_jobs_request( + limit=limit, + order=order, + after=_continuation_token, + before=before, + status=status, + agent_name=agent_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.AgentOptimizationJobListItem], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) + + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) @distributed_trace_async - async def update( - self, monitor_id: str, monitor: Union[_models.AgentInsightMonitorUpdate, JSON, IO[bytes]], **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Update an Agent Insights monitor. + async def cancel_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOptimizationJob: + """Cancel an agent optimization job. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param monitor: The monitor fields to update. Is one of the following types: - AgentInsightMonitorUpdate, JSON, IO[bytes] Required. - :type monitor: ~azure.ai.projects.models.AgentInsightMonitorUpdate or JSON or IO[bytes] - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor + Requests cancellation of a running or queued job and returns an error if the job is already in + a terminal state. + + :param job_id: The ID of the job to cancel. Required. + :type job_id: str + :return: AgentOptimizationJob. The AgentOptimizationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentOptimizationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -6670,24 +6894,14 @@ async def update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) - - content_type = content_type or "application/merge-patch+json" - _content = None - if isinstance(monitor, (IOBase, bytes)): - _content = monitor - else: - _content = json.dumps(monitor, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.AgentOptimizationJob] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_update_request( - monitor_id=monitor_id, - content_type=content_type, + _request = build_beta_agents_cancel_optimization_job_request( + job_id=job_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -6720,7 +6934,7 @@ async def update( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) + deserialized = _deserialize(_models.AgentOptimizationJob, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -6728,11 +6942,13 @@ async def update( return deserialized # type: ignore @distributed_trace_async - async def reset(self, monitor_id: str, **kwargs: Any) -> None: - """Reset an Agent Insights monitor's overview, checkpoint, and active insight state. + async def delete_optimization_job(self, job_id: str, **kwargs: Any) -> None: + """Delete an agent optimization job. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str + Deletes the job and its candidate artifacts, canceling the job first if it is non-terminal. + + :param job_id: The ID of the job to delete. Required. + :type job_id: str :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -6750,8 +6966,8 @@ async def reset(self, monitor_id: str, **kwargs: Any) -> None: cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_reset_request( - monitor_id=monitor_id, + _request = build_beta_agents_delete_optimization_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -6779,14 +6995,56 @@ async def reset(self, monitor_id: str, **kwargs: Any) -> None: if cls: return cls(pipeline_response, None, {}) # type: ignore - async def _create_run_initial( + +class BetaAgentInsightMonitorsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`agent_insight_monitors` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def list( self, - monitor_id: str, - run: Union[_models.AgentInsightRunCreate, JSON, IO[bytes]], *, - operation_id: Optional[str] = None, + before: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + agent_name: Optional[str] = None, **kwargs: Any - ) -> AsyncIterator[bytes]: + ) -> AsyncItemPaged["_models.AgentInsightMonitorListItem"]: + """List Agent Insights monitors, optionally filtered by agent name. + + :keyword before: A cursor that identifies the first item in the next page. Default value is + None. + :paramtype before: str + :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" + and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword agent_name: Filter monitors by agent name. Default value is None. + :paramtype agent_name: str + :return: An iterator like instance of AgentInsightMonitorListItem + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.AgentInsightMonitorListItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.AgentInsightMonitorListItem]] = kwargs.pop("cls", None) + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -6795,22 +7053,138 @@ async def _create_run_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) + def prepare_request(_continuation_token=None): - content_type = content_type or "application/json" - _content = None - if isinstance(run, (IOBase, bytes)): - _content = run + _request = build_beta_agent_insight_monitors_list_request( + after=_continuation_token, + before=before, + limit=limit, + order=order, + agent_name=agent_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.AgentInsightMonitorListItem], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) + + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @overload + async def create( + self, monitor: _models.AgentInsightMonitorCreate, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Create an Agent Insights monitor for an agent. + + :param monitor: The monitor to create. Required. + :type monitor: ~azure.ai.projects.models.AgentInsightMonitorCreate + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create( + self, monitor: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Create an Agent Insights monitor for an agent. + + :param monitor: The monitor to create. Required. + :type monitor: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create( + self, monitor: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Create an Agent Insights monitor for an agent. + + :param monitor: The monitor to create. Required. + :type monitor: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create( + self, monitor: Union[_models.AgentInsightMonitorCreate, JSON, IO[bytes]], **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Create an Agent Insights monitor for an agent. + + :param monitor: The monitor to create. Is one of the following types: + AgentInsightMonitorCreate, JSON, IO[bytes] Required. + :type monitor: ~azure.ai.projects.models.AgentInsightMonitorCreate or JSON or IO[bytes] + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(monitor, (IOBase, bytes)): + _content = monitor else: - _content = json.dumps(run, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(monitor, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_agent_insight_monitors_create_run_request( - monitor_id=monitor_id, - operation_id=operation_id, + _request = build_beta_agent_insight_monitors_create_request( content_type=content_type, api_version=self._config.api_version, content=_content, @@ -6823,7 +7197,7 @@ async def _create_run_initial( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -6831,10 +7205,11 @@ async def _create_run_initial( response = pipeline_response.http_response if response.status_code not in [201]: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -6843,326 +7218,57 @@ async def _create_run_initial( raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @overload - async def begin_create_run( - self, - monitor_id: str, - run: _models.AgentInsightRunCreate, - *, - operation_id: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> AsyncLROPoller[_models.AgentInsightRunResult]: - """Start an Agent Insights run for a monitor. + @distributed_trace_async + async def get(self, monitor_id: str, **kwargs: Any) -> _models.AgentInsightMonitor: + """Get an Agent Insights monitor. :param monitor_id: The identifier of the monitor. Required. :type monitor_id: str - :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. - Required. - :type run: ~azure.ai.projects.models.AgentInsightRunCreate - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns AgentInsightRunResult. The - AgentInsightRunResult is compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentInsightRunResult] + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - @overload - async def begin_create_run( - self, - monitor_id: str, - run: JSON, - *, - operation_id: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> AsyncLROPoller[_models.AgentInsightRunResult]: - """Start an Agent Insights run for a monitor. + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. - Required. - :type run: JSON - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns AgentInsightRunResult. The - AgentInsightRunResult is compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentInsightRunResult] - :raises ~azure.core.exceptions.HttpResponseError: - """ + cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) - @overload - async def begin_create_run( - self, - monitor_id: str, - run: IO[bytes], - *, - operation_id: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> AsyncLROPoller[_models.AgentInsightRunResult]: - """Start an Agent Insights run for a monitor. + _request = build_beta_agent_insight_monitors_get_request( + monitor_id=monitor_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. - Required. - :type run: IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns AgentInsightRunResult. The - AgentInsightRunResult is compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentInsightRunResult] - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @distributed_trace_async - async def begin_create_run( - self, - monitor_id: str, - run: Union[_models.AgentInsightRunCreate, JSON, IO[bytes]], - *, - operation_id: Optional[str] = None, - **kwargs: Any - ) -> AsyncLROPoller[_models.AgentInsightRunResult]: - """Start an Agent Insights run for a monitor. - - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. Is - one of the following types: AgentInsightRunCreate, JSON, IO[bytes] Required. - :type run: ~azure.ai.projects.models.AgentInsightRunCreate or JSON or IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :return: An instance of AsyncLROPoller that returns AgentInsightRunResult. The - AgentInsightRunResult is compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentInsightRunResult] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentInsightRunResult] = kwargs.pop("cls", None) - polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = await self._create_run_initial( - monitor_id=monitor_id, - run=run, - operation_id=operation_id, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - await raw_result.http_response.read() # type: ignore - kwargs.pop("error_map", None) - - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Operation-Location"] = self._deserialize( - "str", response.headers.get("Operation-Location") - ) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = _deserialize(_models.AgentInsightRunResult, response.json().get("result", {})) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized - - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - - if polling is True: - polling_method: AsyncPollingMethod = cast( - AsyncPollingMethod, - AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), - ) - elif polling is False: - polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) - else: - polling_method = polling - if cont_token: - return AsyncLROPoller[_models.AgentInsightRunResult].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return AsyncLROPoller[_models.AgentInsightRunResult]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) - - @distributed_trace - def list_runs( - self, - monitor_id: str, - *, - before: Optional[str] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - status: Optional[Union[str, _models.JobStatus]] = None, - trigger: Optional[Union[str, _models.AgentInsightRunTrigger]] = None, - **kwargs: Any - ) -> AsyncItemPaged["_models.AgentInsightRun"]: - """List Agent Insights runs for a monitor. - - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :keyword before: A cursor that identifies the first item in the next page. Default value is - None. - :paramtype before: str - :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" - and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword status: Filter runs by status. Known values are: "queued", "in_progress", "succeeded", - "failed", and "cancelled". Default value is None. - :paramtype status: str or ~azure.ai.projects.models.JobStatus - :keyword trigger: Filter runs by trigger. Known values are: "on_demand" and "scheduled". - Default value is None. - :paramtype trigger: str or ~azure.ai.projects.models.AgentInsightRunTrigger - :return: An iterator like instance of AgentInsightRun - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.AgentInsightRun] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.AgentInsightRun]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(_continuation_token=None): - - _request = build_beta_agent_insight_monitors_list_runs_request( - monitor_id=monitor_id, - after=_continuation_token, - before=before, - limit=limit, - order=order, - status=status, - trigger=trigger, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request - - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.AgentInsightRun], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, AsyncList(list_of_elem) - - async def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) - - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - return pipeline_response - - return AsyncItemPaged(get_next, extract_data) - - @distributed_trace_async - async def get_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models.AgentInsightRun: - """Get an Agent Insights run. - - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param run_id: The identifier of the run. Required. - :type run_id: str - :return: AgentInsightRun. The AgentInsightRun is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightRun - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models.AgentInsightRun] = kwargs.pop("cls", None) - - _request = build_beta_agent_insight_monitors_get_run_request( - monitor_id=monitor_id, - run_id=run_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) response = pipeline_response.http_response @@ -7182,7 +7288,7 @@ async def get_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models. if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentInsightRun, response.json()) + deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -7190,15 +7296,13 @@ async def get_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models. return deserialized # type: ignore @distributed_trace_async - async def cancel_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models.AgentInsightRun: - """Cancel an Agent Insights run. + async def delete(self, monitor_id: str, **kwargs: Any) -> None: + """Delete an Agent Insights monitor and all of its runs, insights, and state. :param monitor_id: The identifier of the monitor. Required. :type monitor_id: str - :param run_id: The identifier of the run. Required. - :type run_id: str - :return: AgentInsightRun. The AgentInsightRun is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightRun + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7212,11 +7316,10 @@ async def cancel_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _mode _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentInsightRun] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_cancel_run_request( + _request = build_beta_agent_insight_monitors_delete_request( monitor_id=monitor_id, - run_id=run_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7226,20 +7329,14 @@ async def cancel_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _mode } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -7247,138 +7344,81 @@ async def cancel_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _mode ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentInsightRun, response.json()) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + return cls(pipeline_response, None, {}) # type: ignore - @distributed_trace - def list_insights( + @overload + async def update( self, monitor_id: str, + monitor: _models.AgentInsightMonitorUpdate, *, - before: Optional[str] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - category: Optional[str] = None, - severity: Optional[Union[str, _models.AgentInsightSeverity]] = None, - status: Optional[Union[str, _models.AgentInsightStatus]] = None, - include_details: Optional[bool] = None, + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> AsyncItemPaged["_models.AgentInsight"]: - """List current insights for an Agent Insights monitor. + ) -> _models.AgentInsightMonitor: + """Update an Agent Insights monitor. :param monitor_id: The identifier of the monitor. Required. :type monitor_id: str - :keyword before: A cursor that identifies the first item in the next page. Default value is - None. - :paramtype before: str - :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" - and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword category: Filter insights by category. Default value is None. - :paramtype category: str - :keyword severity: Filter insights by severity. Known values are: "high", "medium", and "low". - Default value is None. - :paramtype severity: str or ~azure.ai.projects.models.AgentInsightSeverity - :keyword status: Filter insights by lifecycle status. Known values are: "active", "resolved", - and "ignored". Default value is None. - :paramtype status: str or ~azure.ai.projects.models.AgentInsightStatus - :keyword include_details: Whether to include expanded insight details such as evidence and run - links in the response. Defaults to false. Default value is None. - :paramtype include_details: bool - :return: An iterator like instance of AgentInsight - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.AgentInsight] + :param monitor: The monitor fields to update. Required. + :type monitor: ~azure.ai.projects.models.AgentInsightMonitorUpdate + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.AgentInsight]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(_continuation_token=None): - - _request = build_beta_agent_insight_monitors_list_insights_request( - monitor_id=monitor_id, - after=_continuation_token, - before=before, - limit=limit, - order=order, - category=category, - severity=severity, - status=status, - include_details=include_details, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request - - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.AgentInsight], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, AsyncList(list_of_elem) - - async def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + @overload + async def update( + self, monitor_id: str, monitor: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Update an Agent Insights monitor. - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param monitor: The monitor fields to update. Required. + :type monitor: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :raises ~azure.core.exceptions.HttpResponseError: + """ - return pipeline_response + @overload + async def update( + self, monitor_id: str, monitor: IO[bytes], *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Update an Agent Insights monitor. - return AsyncItemPaged(get_next, extract_data) + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param monitor: The monitor fields to update. Required. + :type monitor: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace_async - async def get_insight( - self, monitor_id: str, insight_id: str, *, include_details: Optional[bool] = None, **kwargs: Any - ) -> _models.AgentInsight: - """Get a full insight for an Agent Insights monitor. + async def update( + self, monitor_id: str, monitor: Union[_models.AgentInsightMonitorUpdate, JSON, IO[bytes]], **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Update an Agent Insights monitor. :param monitor_id: The identifier of the monitor. Required. :type monitor_id: str - :param insight_id: The identifier of the insight. Required. - :type insight_id: str - :keyword include_details: Whether to include expanded insight details such as evidence and run - links in the response. Defaults to false. Default value is None. - :paramtype include_details: bool - :return: AgentInsight. The AgentInsight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsight + :param monitor: The monitor fields to update. Is one of the following types: + AgentInsightMonitorUpdate, JSON, IO[bytes] Required. + :type monitor: ~azure.ai.projects.models.AgentInsightMonitorUpdate or JSON or IO[bytes] + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7389,16 +7429,24 @@ async def get_insight( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentInsight] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_get_insight_request( + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(monitor, (IOBase, bytes)): + _content = monitor + else: + _content = json.dumps(monitor, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_agent_insight_monitors_update_request( monitor_id=monitor_id, - insight_id=insight_id, - include_details=include_details, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -7431,112 +7479,73 @@ async def get_insight( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentInsight, response.json()) + deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - async def update_insight( - self, - monitor_id: str, - insight_id: str, - update: _models.AgentInsightUpdate, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.AgentInsight: - """Update the lifecycle status of an insight. + @distributed_trace_async + async def reset(self, monitor_id: str, **kwargs: Any) -> None: + """Reset an Agent Insights monitor's overview, checkpoint, and active insight state. :param monitor_id: The identifier of the monitor. Required. :type monitor_id: str - :param insight_id: The identifier of the insight. Required. - :type insight_id: str - :param update: The insight fields to update. Required. - :type update: ~azure.ai.projects.models.AgentInsightUpdate - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: AgentInsight. The AgentInsight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsight + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - @overload - async def update_insight( + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_beta_agent_insight_monitors_reset_request( + monitor_id=monitor_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + async def _create_run_initial( self, monitor_id: str, - insight_id: str, - update: JSON, + run: Union[_models.AgentInsightRunCreate, JSON, IO[bytes]], *, - content_type: str = "application/merge-patch+json", + operation_id: Optional[str] = None, **kwargs: Any - ) -> _models.AgentInsight: - """Update the lifecycle status of an insight. - - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param insight_id: The identifier of the insight. Required. - :type insight_id: str - :param update: The insight fields to update. Required. - :type update: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: AgentInsight. The AgentInsight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsight - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def update_insight( - self, - monitor_id: str, - insight_id: str, - update: IO[bytes], - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.AgentInsight: - """Update the lifecycle status of an insight. - - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param insight_id: The identifier of the insight. Required. - :type insight_id: str - :param update: The insight fields to update. Required. - :type update: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: AgentInsight. The AgentInsight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsight - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @distributed_trace_async - async def update_insight( - self, - monitor_id: str, - insight_id: str, - update: Union[_models.AgentInsightUpdate, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.AgentInsight: - """Update the lifecycle status of an insight. - - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param insight_id: The identifier of the insight. Required. - :type insight_id: str - :param update: The insight fields to update. Is one of the following types: AgentInsightUpdate, - JSON, IO[bytes] Required. - :type update: ~azure.ai.projects.models.AgentInsightUpdate or JSON or IO[bytes] - :return: AgentInsight. The AgentInsight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsight - :raises ~azure.core.exceptions.HttpResponseError: - """ + ) -> AsyncIterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -7549,18 +7558,18 @@ async def update_insight( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentInsight] = kwargs.pop("cls", None) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - content_type = content_type or "application/merge-patch+json" + content_type = content_type or "application/json" _content = None - if isinstance(update, (IOBase, bytes)): - _content = update + if isinstance(run, (IOBase, bytes)): + _content = run else: - _content = json.dumps(update, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(run, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_agent_insight_monitors_update_insight_request( + _request = build_beta_agent_insight_monitors_create_run_request( monitor_id=monitor_id, - insight_id=insight_id, + operation_id=operation_id, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -7573,19 +7582,18 @@ async def update_insight( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = True pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [201]: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -7593,118 +7601,225 @@ async def update_insight( ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentInsight, response.json()) + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore + @overload + async def begin_create_run( + self, + monitor_id: str, + run: _models.AgentInsightRunCreate, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.AgentInsightRunResult]: + """Start an Agent Insights run for a monitor. -class BetaEvaluationTaxonomiesOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`evaluation_taxonomies` attribute. - """ + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. + Required. + :type run: ~azure.ai.projects.models.AgentInsightRunCreate + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns AgentInsightRunResult. The + AgentInsightRunResult is compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentInsightRunResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @overload + async def begin_create_run( + self, + monitor_id: str, + run: JSON, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.AgentInsightRunResult]: + """Start an Agent Insights run for a monitor. - @distributed_trace_async - async def get(self, name: str, **kwargs: Any) -> _models.EvaluationTaxonomy: - """Get an evaluation taxonomy. + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. + Required. + :type run: JSON + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns AgentInsightRunResult. The + AgentInsightRunResult is compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentInsightRunResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ - Retrieves the specified evaluation taxonomy. + @overload + async def begin_create_run( + self, + monitor_id: str, + run: IO[bytes], + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.AgentInsightRunResult]: + """Start an Agent Insights run for a monitor. - :param name: The name of the resource. Required. - :type name: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. + Required. + :type run: IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns AgentInsightRunResult. The + AgentInsightRunResult is compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentInsightRunResult] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) + @distributed_trace_async + async def begin_create_run( + self, + monitor_id: str, + run: Union[_models.AgentInsightRunCreate, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> AsyncLROPoller[_models.AgentInsightRunResult]: + """Start an Agent Insights run for a monitor. - _request = build_beta_evaluation_taxonomies_get_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. Is + one of the following types: AgentInsightRunCreate, JSON, IO[bytes] Required. + :type run: ~azure.ai.projects.models.AgentInsightRunCreate or JSON or IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :return: An instance of AsyncLROPoller that returns AgentInsightRunResult. The + AgentInsightRunResult is compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentInsightRunResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentInsightRunResult] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._create_run_initial( + monitor_id=monitor_id, + run=run, + operation_id=operation_id, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) + deserialized = _deserialize(_models.AgentInsightRunResult, response.json().get("result", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } - return deserialized # type: ignore + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) + else: + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.AgentInsightRunResult].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.AgentInsightRunResult]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) @distributed_trace - def list( - self, *, input_name: Optional[str] = None, input_type: Optional[str] = None, **kwargs: Any - ) -> AsyncItemPaged["_models.EvaluationTaxonomy"]: - """List evaluation taxonomies. - - Returns the evaluation taxonomies available in the project, optionally filtered by input name - or input type. + def list_runs( + self, + monitor_id: str, + *, + before: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + status: Optional[Union[str, _models.JobStatus]] = None, + trigger: Optional[Union[str, _models.AgentInsightRunTrigger]] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.AgentInsightRun"]: + """List Agent Insights runs for a monitor. - :keyword input_name: Filter by the evaluation input name. Default value is None. - :paramtype input_name: str - :keyword input_type: Filter by taxonomy input type. Default value is None. - :paramtype input_type: str - :return: An iterator like instance of EvaluationTaxonomy - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.EvaluationTaxonomy] + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :keyword before: A cursor that identifies the first item in the next page. Default value is + None. + :paramtype before: str + :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" + and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword status: Filter runs by status. Known values are: "queued", "in_progress", "succeeded", + "failed", and "cancelled". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.JobStatus + :keyword trigger: Filter runs by trigger. Known values are: "on_demand" and "scheduled". + Default value is None. + :paramtype trigger: str or ~azure.ai.projects.models.AgentInsightRunTrigger + :return: An iterator like instance of AgentInsightRun + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.AgentInsightRun] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.EvaluationTaxonomy]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.AgentInsightRun]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -7714,60 +7829,38 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_evaluation_taxonomies_list_request( - input_name=input_name, - input_type=input_type, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + def prepare_request(_continuation_token=None): + _request = build_beta_agent_insight_monitors_list_runs_request( + monitor_id=monitor_id, + after=_continuation_token, + before=before, + limit=limit, + order=order, + status=status, + trigger=trigger, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.EvaluationTaxonomy], - deserialized.get("value", []), + List[_models.AgentInsightRun], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - async def get_next(next_link=None): - _request = prepare_request(next_link) + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access @@ -7777,22 +7870,26 @@ async def get_next(next_link=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) return pipeline_response return AsyncItemPaged(get_next, extract_data) @distributed_trace_async - async def delete(self, name: str, **kwargs: Any) -> None: - """Delete an evaluation taxonomy. - - Removes the specified evaluation taxonomy from the project. + async def get_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models.AgentInsightRun: + """Get an Agent Insights run. - :param name: The name of the resource. Required. - :type name: str - :return: None - :rtype: None + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run_id: The identifier of the run. Required. + :type run_id: str + :return: AgentInsightRun. The AgentInsightRun is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightRun :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7806,10 +7903,11 @@ async def delete(self, name: str, **kwargs: Any) -> None: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentInsightRun] = kwargs.pop("cls", None) - _request = build_beta_evaluation_taxonomies_delete_request( - name=name, + _request = build_beta_agent_insight_monitors_get_run_request( + monitor_id=monitor_id, + run_id=run_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7819,95 +7917,47 @@ async def delete(self, name: str, **kwargs: Any) -> None: } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentInsightRun, response.json()) if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore - @overload - async def create( - self, name: str, taxonomy: _models.EvaluationTaxonomy, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Create an evaluation taxonomy. + return deserialized # type: ignore - Creates or replaces the specified evaluation taxonomy with the provided definition. + @distributed_trace_async + async def cancel_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models.AgentInsightRun: + """Cancel an Agent Insights run. - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create( - self, name: str, taxonomy: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Create an evaluation taxonomy. - - Creates or replaces the specified evaluation taxonomy with the provided definition. - - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create( - self, name: str, taxonomy: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Create an evaluation taxonomy. - - Creates or replaces the specified evaluation taxonomy with the provided definition. - - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @distributed_trace_async - async def create( - self, name: str, taxonomy: Union[_models.EvaluationTaxonomy, JSON, IO[bytes]], **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Create an evaluation taxonomy. - - Creates or replaces the specified evaluation taxonomy with the provided definition. - - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Is one of the following types: EvaluationTaxonomy, - JSON, IO[bytes] Required. - :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy or JSON or IO[bytes] - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run_id: The identifier of the run. Required. + :type run_id: str + :return: AgentInsightRun. The AgentInsightRun is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightRun :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7918,24 +7968,15 @@ async def create( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(taxonomy, (IOBase, bytes)): - _content = taxonomy - else: - _content = json.dumps(taxonomy, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.AgentInsightRun] = kwargs.pop("cls", None) - _request = build_beta_evaluation_taxonomies_create_request( - name=name, - content_type=content_type, + _request = build_beta_agent_insight_monitors_cancel_run_request( + monitor_id=monitor_id, + run_id=run_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -7952,102 +7993,75 @@ async def create( response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: await response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) + deserialized = _deserialize(_models.AgentInsightRun, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - async def update( - self, name: str, taxonomy: _models.EvaluationTaxonomy, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Update an evaluation taxonomy. - - Modifies the specified evaluation taxonomy with the provided changes. - - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def update( - self, name: str, taxonomy: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Update an evaluation taxonomy. - - Modifies the specified evaluation taxonomy with the provided changes. - - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def update( - self, name: str, taxonomy: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Update an evaluation taxonomy. - - Modifies the specified evaluation taxonomy with the provided changes. + @distributed_trace + def list_insights( + self, + monitor_id: str, + *, + before: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + category: Optional[str] = None, + severity: Optional[Union[str, _models.AgentInsightSeverity]] = None, + status: Optional[Union[str, _models.AgentInsightStatus]] = None, + include_details: Optional[bool] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.AgentInsight"]: + """List current insights for an Agent Insights monitor. - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :keyword before: A cursor that identifies the first item in the next page. Default value is + None. + :paramtype before: str + :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" + and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword category: Filter insights by category. Default value is None. + :paramtype category: str + :keyword severity: Filter insights by severity. Known values are: "high", "medium", and "low". + Default value is None. + :paramtype severity: str or ~azure.ai.projects.models.AgentInsightSeverity + :keyword status: Filter insights by lifecycle status. Known values are: "active", "resolved", + and "ignored". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.AgentInsightStatus + :keyword include_details: Whether to include expanded insight details such as evidence and run + links in the response. Defaults to false. Default value is None. + :paramtype include_details: bool + :return: An iterator like instance of AgentInsight + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.AgentInsight] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @distributed_trace_async - async def update( - self, name: str, taxonomy: Union[_models.EvaluationTaxonomy, JSON, IO[bytes]], **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Update an evaluation taxonomy. - - Modifies the specified evaluation taxonomy with the provided changes. + cls: ClsType[List[_models.AgentInsight]] = kwargs.pop("cls", None) - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Is one of the following types: EvaluationTaxonomy, - JSON, IO[bytes] Required. - :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy or JSON or IO[bytes] - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy - :raises ~azure.core.exceptions.HttpResponseError: - """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -8056,35 +8070,105 @@ async def update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + def prepare_request(_continuation_token=None): - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) + _request = build_beta_agent_insight_monitors_list_insights_request( + monitor_id=monitor_id, + after=_continuation_token, + before=before, + limit=limit, + order=order, + category=category, + severity=severity, + status=status, + include_details=include_details, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - content_type = content_type or "application/json" - _content = None - if isinstance(taxonomy, (IOBase, bytes)): - _content = taxonomy - else: - _content = json.dumps(taxonomy, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.AgentInsight], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - _request = build_beta_evaluation_taxonomies_update_request( - name=name, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace_async + async def get_insight( + self, monitor_id: str, insight_id: str, *, include_details: Optional[bool] = None, **kwargs: Any + ) -> _models.AgentInsight: + """Get a full insight for an Agent Insights monitor. + + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param insight_id: The identifier of the insight. Required. + :type insight_id: str + :keyword include_details: Whether to include expanded insight details such as evidence and run + links in the response. Defaults to false. Default value is None. + :paramtype include_details: bool + :return: AgentInsight. The AgentInsight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsight + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.AgentInsight] = kwargs.pop("cls", None) + + _request = build_beta_agent_insight_monitors_get_insight_request( + monitor_id=monitor_id, + insight_id=insight_id, + include_details=include_details, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -8097,67 +8181,121 @@ async def update( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) + deserialized = _deserialize(_models.AgentInsight, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + @overload + async def update_insight( + self, + monitor_id: str, + insight_id: str, + update: _models.AgentInsightUpdate, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.AgentInsight: + """Update the lifecycle status of an insight. -class BetaEvaluatorsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param insight_id: The identifier of the insight. Required. + :type insight_id: str + :param update: The insight fields to update. Required. + :type update: ~azure.ai.projects.models.AgentInsightUpdate + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: AgentInsight. The AgentInsight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsight + :raises ~azure.core.exceptions.HttpResponseError: + """ - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`evaluators` attribute. - """ + @overload + async def update_insight( + self, + monitor_id: str, + insight_id: str, + update: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.AgentInsight: + """Update the lifecycle status of an insight. - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param insight_id: The identifier of the insight. Required. + :type insight_id: str + :param update: The insight fields to update. Required. + :type update: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: AgentInsight. The AgentInsight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsight + :raises ~azure.core.exceptions.HttpResponseError: + """ - @distributed_trace - def list_versions( + @overload + async def update_insight( self, - name: str, + monitor_id: str, + insight_id: str, + update: IO[bytes], *, - type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, - limit: Optional[int] = None, + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> AsyncItemPaged["_models.EvaluatorVersion"]: - """List evaluator versions. - - Returns the available versions for the specified evaluator. + ) -> _models.AgentInsight: + """Update the lifecycle status of an insight. - :param name: The name of the resource. Required. - :type name: str - :keyword type: Filter evaluators by type. Possible values: 'all', 'custom', 'builtin'. Is one - of the following types: Literal["builtin"], Literal["custom"], Literal["all"], str Default - value is None. - :paramtype type: str or str or str or str - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the default is 20. Default value is None. - :paramtype limit: int - :return: An iterator like instance of EvaluatorVersion - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.EvaluatorVersion] + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param insight_id: The identifier of the insight. Required. + :type insight_id: str + :param update: The insight fields to update. Required. + :type update: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: AgentInsight. The AgentInsight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsight :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.EvaluatorVersion]] = kwargs.pop("cls", None) + @distributed_trace_async + async def update_insight( + self, + monitor_id: str, + insight_id: str, + update: Union[_models.AgentInsightUpdate, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.AgentInsight: + """Update the lifecycle status of an insight. + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param insight_id: The identifier of the insight. Required. + :type insight_id: str + :param update: The insight fields to update. Is one of the following types: AgentInsightUpdate, + JSON, IO[bytes] Required. + :type update: ~azure.ai.projects.models.AgentInsightUpdate or JSON or IO[bytes] + :return: AgentInsight. The AgentInsight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsight + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -8166,103 +8304,166 @@ def list_versions( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_evaluators_list_versions_request( - name=name, - type=type, - limit=limit, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - return _request + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentInsight] = kwargs.pop("cls", None) - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.EvaluatorVersion], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(update, (IOBase, bytes)): + _content = update + else: + _content = json.dumps(update, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - async def get_next(next_link=None): - _request = prepare_request(next_link) + _request = build_beta_agent_insight_monitors_update_insight_request( + monitor_id=monitor_id, + insight_id=insight_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response + raise HttpResponseError(response=response, model=error) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentInsight, response.json()) - return pipeline_response + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore - return AsyncItemPaged(get_next, extract_data) + return deserialized # type: ignore + + +class BetaEvaluationTaxonomiesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`evaluation_taxonomies` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace_async + async def get(self, name: str, **kwargs: Any) -> _models.EvaluationTaxonomy: + """Get an evaluation taxonomy. + + Retrieves the specified evaluation taxonomy. + + :param name: The name of the resource. Required. + :type name: str + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) + + _request = build_beta_evaluation_taxonomies_get_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace def list( - self, - *, - type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, - limit: Optional[int] = None, - **kwargs: Any - ) -> AsyncItemPaged["_models.EvaluatorVersion"]: - """List latest evaluator versions. + self, *, input_name: Optional[str] = None, input_type: Optional[str] = None, **kwargs: Any + ) -> AsyncItemPaged["_models.EvaluationTaxonomy"]: + """List evaluation taxonomies. - Lists the latest version of each evaluator. + Returns the evaluation taxonomies available in the project, optionally filtered by input name + or input type. - :keyword type: Filter evaluators by type. Possible values: 'all', 'custom', 'builtin'. Is one - of the following types: Literal["builtin"], Literal["custom"], Literal["all"], str Default - value is None. - :paramtype type: str or str or str or str - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the default is 20. Default value is None. - :paramtype limit: int - :return: An iterator like instance of EvaluatorVersion - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.EvaluatorVersion] + :keyword input_name: Filter by the evaluation input name. Default value is None. + :paramtype input_name: str + :keyword input_type: Filter by taxonomy input type. Default value is None. + :paramtype input_type: str + :return: An iterator like instance of EvaluationTaxonomy + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.EvaluationTaxonomy] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.EvaluatorVersion]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.EvaluationTaxonomy]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -8275,9 +8476,9 @@ def list( def prepare_request(next_link=None): if not next_link: - _request = build_beta_evaluators_list_request( - type=type, - limit=limit, + _request = build_beta_evaluation_taxonomies_list_request( + input_name=input_name, + input_type=input_type, api_version=self._config.api_version, headers=_headers, params=_params, @@ -8317,7 +8518,7 @@ def prepare_request(next_link=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.EvaluatorVersion], + List[_models.EvaluationTaxonomy], deserialized.get("value", []), ) if cls: @@ -8342,17 +8543,15 @@ async def get_next(next_link=None): return AsyncItemPaged(get_next, extract_data) @distributed_trace_async - async def get_version(self, name: str, version: str, **kwargs: Any) -> _models.EvaluatorVersion: - """Get an evaluator version. + async def delete(self, name: str, **kwargs: Any) -> None: + """Delete an evaluation taxonomy. - Retrieves the specified evaluator version, returning 404 if it does not exist. + Removes the specified evaluation taxonomy from the project. :param name: The name of the resource. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to retrieve. Required. - :type version: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8366,11 +8565,10 @@ async def get_version(self, name: str, version: str, **kwargs: Any) -> _models.E _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_evaluators_get_version_request( + _request = build_beta_evaluation_taxonomies_delete_request( name=name, - version=version, api_version=self._config.api_version, headers=_headers, params=_params, @@ -8380,166 +8578,95 @@ async def get_version(self, name: str, version: str, **kwargs: Any) -> _models.E } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) raise HttpResponseError(response=response) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.EvaluatorVersion, response.json()) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + return cls(pipeline_response, None, {}) # type: ignore - @distributed_trace_async - async def delete_version(self, name: str, version: str, **kwargs: Any) -> None: - """Delete an evaluator version. + @overload + async def create( + self, name: str, taxonomy: _models.EvaluationTaxonomy, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Create an evaluation taxonomy. - Removes the specified evaluator version. Returns 204 whether the version existed or not. + Creates or replaces the specified evaluation taxonomy with the provided definition. - :param name: The name of the resource. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param version: The version of the EvaluatorVersion to delete. Required. - :type version: str - :return: None - :rtype: None + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + @overload + async def create( + self, name: str, taxonomy: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Create an evaluation taxonomy. - _request = build_beta_evaluators_delete_version_request( - name=name, - version=version, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + Creates or replaces the specified evaluation taxonomy with the provided definition. - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if cls: - return cls(pipeline_response, None, {}) # type: ignore - - @overload - async def create_version( - self, - name: str, - evaluator_version: _models.EvaluatorVersion, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.EvaluatorVersion: - """Create an evaluator version. - - Creates a new evaluator version with an auto-incremented version identifier. - - :param name: The name of the resource. Required. - :type name: str - :param evaluator_version: Required. - :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create_version( - self, name: str, evaluator_version: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluatorVersion: - """Create an evaluator version. - - Creates a new evaluator version with an auto-incremented version identifier. - - :param name: The name of the resource. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param evaluator_version: Required. - :type evaluator_version: JSON + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def create_version( - self, name: str, evaluator_version: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluatorVersion: - """Create an evaluator version. + async def create( + self, name: str, taxonomy: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Create an evaluation taxonomy. - Creates a new evaluator version with an auto-incremented version identifier. + Creates or replaces the specified evaluation taxonomy with the provided definition. - :param name: The name of the resource. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param evaluator_version: Required. - :type evaluator_version: IO[bytes] + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def create_version( - self, name: str, evaluator_version: Union[_models.EvaluatorVersion, JSON, IO[bytes]], **kwargs: Any - ) -> _models.EvaluatorVersion: - """Create an evaluator version. + async def create( + self, name: str, taxonomy: Union[_models.EvaluationTaxonomy, JSON, IO[bytes]], **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Create an evaluation taxonomy. - Creates a new evaluator version with an auto-incremented version identifier. + Creates or replaces the specified evaluation taxonomy with the provided definition. - :param name: The name of the resource. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param evaluator_version: Is one of the following types: EvaluatorVersion, JSON, IO[bytes] - Required. - :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion or JSON or IO[bytes] - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :param taxonomy: The evaluation taxonomy. Is one of the following types: EvaluationTaxonomy, + JSON, IO[bytes] Required. + :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy or JSON or IO[bytes] + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8554,16 +8681,16 @@ async def create_version( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) + cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None - if isinstance(evaluator_version, (IOBase, bytes)): - _content = evaluator_version + if isinstance(taxonomy, (IOBase, bytes)): + _content = taxonomy else: - _content = json.dumps(evaluator_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(taxonomy, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_evaluators_create_version_request( + _request = build_beta_evaluation_taxonomies_create_request( name=name, content_type=content_type, api_version=self._config.api_version, @@ -8584,7 +8711,7 @@ async def create_version( response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200, 201]: if _stream: try: await response.read() # Load the body in memory and close the socket @@ -8596,7 +8723,7 @@ async def create_version( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluatorVersion, response.json()) + deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -8604,104 +8731,80 @@ async def create_version( return deserialized # type: ignore @overload - async def update_version( - self, - name: str, - version: str, - evaluator_version: _models.EvaluatorVersion, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.EvaluatorVersion: - """Update an evaluator version. + async def update( + self, name: str, taxonomy: _models.EvaluationTaxonomy, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Update an evaluation taxonomy. - Updates the specified evaluator version in place. + Modifies the specified evaluation taxonomy with the provided changes. - :param name: The name of the resource. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param version: The version of the EvaluatorVersion to update. Required. - :type version: str - :param evaluator_version: Evaluator resource. Required. - :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def update_version( - self, name: str, version: str, evaluator_version: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluatorVersion: - """Update an evaluator version. + async def update( + self, name: str, taxonomy: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Update an evaluation taxonomy. - Updates the specified evaluator version in place. + Modifies the specified evaluation taxonomy with the provided changes. - :param name: The name of the resource. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param version: The version of the EvaluatorVersion to update. Required. - :type version: str - :param evaluator_version: Evaluator resource. Required. - :type evaluator_version: JSON + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def update_version( - self, - name: str, - version: str, - evaluator_version: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.EvaluatorVersion: - """Update an evaluator version. + async def update( + self, name: str, taxonomy: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Update an evaluation taxonomy. - Updates the specified evaluator version in place. + Modifies the specified evaluation taxonomy with the provided changes. - :param name: The name of the resource. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param version: The version of the EvaluatorVersion to update. Required. - :type version: str - :param evaluator_version: Evaluator resource. Required. - :type evaluator_version: IO[bytes] + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def update_version( - self, - name: str, - version: str, - evaluator_version: Union[_models.EvaluatorVersion, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.EvaluatorVersion: - """Update an evaluator version. + async def update( + self, name: str, taxonomy: Union[_models.EvaluationTaxonomy, JSON, IO[bytes]], **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Update an evaluation taxonomy. - Updates the specified evaluator version in place. + Modifies the specified evaluation taxonomy with the provided changes. - :param name: The name of the resource. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param version: The version of the EvaluatorVersion to update. Required. - :type version: str - :param evaluator_version: Evaluator resource. Is one of the following types: EvaluatorVersion, + :param taxonomy: The evaluation taxonomy. Is one of the following types: EvaluationTaxonomy, JSON, IO[bytes] Required. - :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion or JSON or IO[bytes] - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy or JSON or IO[bytes] + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8716,18 +8819,17 @@ async def update_version( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) + cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None - if isinstance(evaluator_version, (IOBase, bytes)): - _content = evaluator_version + if isinstance(taxonomy, (IOBase, bytes)): + _content = taxonomy else: - _content = json.dumps(evaluator_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(taxonomy, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_evaluators_update_version_request( + _request = build_beta_evaluation_taxonomies_update_request( name=name, - version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -8759,125 +8861,62 @@ async def update_version( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluatorVersion, response.json()) + deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - async def pending_upload( + +class BetaEvaluatorsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`evaluators` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def list_versions( self, name: str, - version: str, - pending_upload_request: _models.PendingUploadRequest, *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified evaluator - version. - - :param name: The name path parameter. Required. - :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def pending_upload( - self, - name: str, - version: str, - pending_upload_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified evaluator - version. - - :param name: The name path parameter. Required. - :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def pending_upload( - self, - name: str, - version: str, - pending_upload_request: IO[bytes], - *, - content_type: str = "application/json", + type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, + limit: Optional[int] = None, **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. + ) -> AsyncItemPaged["_models.EvaluatorVersion"]: + """List evaluator versions. - Initiates a new pending upload or retrieves an existing one for the specified evaluator - version. + Returns the available versions for the specified evaluator. - :param name: The name path parameter. Required. + :param name: The name of the resource. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :keyword type: Filter evaluators by type. Possible values: 'all', 'custom', 'builtin'. Is one + of the following types: Literal["builtin"], Literal["custom"], Literal["all"], str Default + value is None. + :paramtype type: str or str or str or str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. Default value is None. + :paramtype limit: int + :return: An iterator like instance of EvaluatorVersion + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.EvaluatorVersion] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @distributed_trace_async - async def pending_upload( - self, - name: str, - version: str, - pending_upload_request: Union[_models.PendingUploadRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified evaluator - version. + cls: ClsType[List[_models.EvaluatorVersion]] = kwargs.pop("cls", None) - :param name: The name path parameter. Required. - :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Is one of the following - types: PendingUploadRequest, JSON, IO[bytes] Required. - :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest or JSON or - IO[bytes] - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -8886,174 +8925,193 @@ async def pending_upload( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + def prepare_request(next_link=None): + if not next_link: - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.PendingUploadResponse] = kwargs.pop("cls", None) + _request = build_beta_evaluators_list_versions_request( + name=name, + type=type, + limit=limit, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - content_type = content_type or "application/json" - _content = None - if isinstance(pending_upload_request, (IOBase, bytes)): - _content = pending_upload_request - else: - _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _request = build_beta_evaluators_pending_upload_request( - name=name, - version=version, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.EvaluatorVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) - response = pipeline_response.http_response + async def get_next(next_link=None): + _request = prepare_request(next_link) - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) - raise HttpResponseError(response=response, model=error) + response = pipeline_response.http_response - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.PendingUploadResponse, response.json()) + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return pipeline_response - return deserialized # type: ignore + return AsyncItemPaged(get_next, extract_data) - @overload - async def get_credentials( + @distributed_trace + def list( self, - name: str, - version: str, - credential_request: _models.EvaluatorCredentialRequest, *, - content_type: str = "application/json", + type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, + limit: Optional[int] = None, **kwargs: Any - ) -> _models.DatasetCredential: - """Get evaluator credentials. + ) -> AsyncItemPaged["_models.EvaluatorVersion"]: + """List latest evaluator versions. - Retrieves SAS credentials for accessing the storage account associated with the specified - evaluator version. + Lists the latest version of each evaluator. - :param name: The name path parameter. Required. - :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param credential_request: The credential request parameters. Required. - :type credential_request: ~azure.ai.projects.models.EvaluatorCredentialRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :keyword type: Filter evaluators by type. Possible values: 'all', 'custom', 'builtin'. Is one + of the following types: Literal["builtin"], Literal["custom"], Literal["all"], str Default + value is None. + :paramtype type: str or str or str or str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. Default value is None. + :paramtype limit: int + :return: An iterator like instance of EvaluatorVersion + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.EvaluatorVersion] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @overload - async def get_credentials( - self, - name: str, - version: str, - credential_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.DatasetCredential: - """Get evaluator credentials. + cls: ClsType[List[_models.EvaluatorVersion]] = kwargs.pop("cls", None) - Retrieves SAS credentials for accessing the storage account associated with the specified - evaluator version. + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - :param name: The name path parameter. Required. - :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param credential_request: The credential request parameters. Required. - :type credential_request: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential - :raises ~azure.core.exceptions.HttpResponseError: - """ + def prepare_request(next_link=None): + if not next_link: - @overload - async def get_credentials( - self, - name: str, - version: str, - credential_request: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.DatasetCredential: - """Get evaluator credentials. + _request = build_beta_evaluators_list_request( + type=type, + limit=limit, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - Retrieves SAS credentials for accessing the storage account associated with the specified - evaluator version. + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - :param name: The name path parameter. Required. - :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param credential_request: The credential request parameters. Required. - :type credential_request: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential - :raises ~azure.core.exceptions.HttpResponseError: - """ + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.EvaluatorVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) @distributed_trace_async - async def get_credentials( - self, - name: str, - version: str, - credential_request: Union[_models.EvaluatorCredentialRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.DatasetCredential: - """Get evaluator credentials. + async def get_version(self, name: str, version: str, **kwargs: Any) -> _models.EvaluatorVersion: + """Get an evaluator version. - Retrieves SAS credentials for accessing the storage account associated with the specified - evaluator version. + Retrieves the specified evaluator version, returning 404 if it does not exist. - :param name: The name path parameter. Required. + :param name: The name of the resource. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :param version: The specific version id of the EvaluatorVersion to retrieve. Required. :type version: str - :param credential_request: The credential request parameters. Is one of the following types: - EvaluatorCredentialRequest, JSON, IO[bytes] Required. - :type credential_request: ~azure.ai.projects.models.EvaluatorCredentialRequest or JSON or - IO[bytes] - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9064,25 +9122,15 @@ async def get_credentials( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(credential_request, (IOBase, bytes)): - _content = credential_request - else: - _content = json.dumps(credential_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) - _request = build_beta_evaluators_get_credentials_request( + _request = build_beta_evaluators_get_version_request( name=name, version=version, - content_type=content_type, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -9106,29 +9154,32 @@ async def get_credentials( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DatasetCredential, response.json()) + deserialized = _deserialize(_models.EvaluatorVersion, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - async def _create_generation_job_initial( - self, - job: Union[_models.EvaluatorGenerationJob, JSON, IO[bytes]], - *, - operation_id: Optional[str] = None, - **kwargs: Any - ) -> AsyncIterator[bytes]: + @distributed_trace_async + async def delete_version(self, name: str, version: str, **kwargs: Any) -> None: + """Delete an evaluator version. + + Removes the specified evaluator version. Returns 204 whether the version existed or not. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the EvaluatorVersion to delete. Required. + :type version: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -9137,24 +9188,15 @@ async def _create_generation_job_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(job, (IOBase, bytes)): - _content = job - else: - _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_evaluators_create_generation_job_request( - operation_id=operation_id, - content_type=content_type, + _request = build_beta_evaluators_delete_version_request( + name=name, + version=version, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -9163,208 +9205,100 @@ async def _create_generation_job_initial( } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - response_headers = {} - response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + raise HttpResponseError(response=response) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - - return deserialized # type: ignore + return cls(pipeline_response, None, {}) # type: ignore @overload - async def begin_create_generation_job( + async def create_version( self, - job: _models.EvaluatorGenerationJob, + name: str, + evaluator_version: _models.EvaluatorVersion, *, - operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.EvaluatorVersion]: - """Create an evaluator generation job. + ) -> _models.EvaluatorVersion: + """Create an evaluator version. - Creates an evaluator generation job. The service generates rubric-based evaluator definitions - from the provided source materials asynchronously. + Creates a new evaluator version with an auto-incremented version identifier. - :param job: The job to create. Required. - :type job: ~azure.ai.projects.models.EvaluatorGenerationJob - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param name: The name of the resource. Required. + :type name: str + :param evaluator_version: Required. + :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns EvaluatorVersion. The EvaluatorVersion is - compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.EvaluatorVersion] + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def begin_create_generation_job( - self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.EvaluatorVersion]: - """Create an evaluator generation job. + async def create_version( + self, name: str, evaluator_version: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluatorVersion: + """Create an evaluator version. - Creates an evaluator generation job. The service generates rubric-based evaluator definitions - from the provided source materials asynchronously. + Creates a new evaluator version with an auto-incremented version identifier. - :param job: The job to create. Required. - :type job: JSON - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param name: The name of the resource. Required. + :type name: str + :param evaluator_version: Required. + :type evaluator_version: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns EvaluatorVersion. The EvaluatorVersion is - compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.EvaluatorVersion] + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def begin_create_generation_job( - self, - job: IO[bytes], - *, - operation_id: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> AsyncLROPoller[_models.EvaluatorVersion]: - """Create an evaluator generation job. + async def create_version( + self, name: str, evaluator_version: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluatorVersion: + """Create an evaluator version. - Creates an evaluator generation job. The service generates rubric-based evaluator definitions - from the provided source materials asynchronously. + Creates a new evaluator version with an auto-incremented version identifier. - :param job: The job to create. Required. - :type job: IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param name: The name of the resource. Required. + :type name: str + :param evaluator_version: Required. + :type evaluator_version: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns EvaluatorVersion. The EvaluatorVersion is - compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.EvaluatorVersion] - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @distributed_trace_async - async def begin_create_generation_job( - self, - job: Union[_models.EvaluatorGenerationJob, JSON, IO[bytes]], - *, - operation_id: Optional[str] = None, - **kwargs: Any - ) -> AsyncLROPoller[_models.EvaluatorVersion]: - """Create an evaluator generation job. - - Creates an evaluator generation job. The service generates rubric-based evaluator definitions - from the provided source materials asynchronously. - - :param job: The job to create. Is one of the following types: EvaluatorGenerationJob, JSON, - IO[bytes] Required. - :type job: ~azure.ai.projects.models.EvaluatorGenerationJob or JSON or IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :return: An instance of AsyncLROPoller that returns EvaluatorVersion. The EvaluatorVersion is - compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.EvaluatorVersion] + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) - polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = await self._create_generation_job_initial( - job=job, - operation_id=operation_id, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - await raw_result.http_response.read() # type: ignore - kwargs.pop("error_map", None) - - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Operation-Location"] = self._deserialize( - "str", response.headers.get("Operation-Location") - ) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = _deserialize(_models.EvaluatorVersion, response.json().get("result", {})) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized - - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - - if polling is True: - polling_method: AsyncPollingMethod = cast( - AsyncPollingMethod, - AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), - ) - elif polling is False: - polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) - else: - polling_method = polling - if cont_token: - return AsyncLROPoller[_models.EvaluatorVersion].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return AsyncLROPoller[_models.EvaluatorVersion]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) @distributed_trace_async - async def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.EvaluatorGenerationJob: - """Get an evaluator generation job. + async def create_version( + self, name: str, evaluator_version: Union[_models.EvaluatorVersion, JSON, IO[bytes]], **kwargs: Any + ) -> _models.EvaluatorVersion: + """Create an evaluator version. - Gets the details of an evaluator generation job by its ID. + Creates a new evaluator version with an auto-incremented version identifier. - :param job_id: The ID of the job. Required. - :type job_id: str - :return: EvaluatorGenerationJob. The EvaluatorGenerationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorGenerationJob + :param name: The name of the resource. Required. + :type name: str + :param evaluator_version: Is one of the following types: EvaluatorVersion, JSON, IO[bytes] + Required. + :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion or JSON or IO[bytes] + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9375,14 +9309,24 @@ async def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.Evalua } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.EvaluatorGenerationJob] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) - _request = build_beta_evaluators_get_generation_job_request( - job_id=job_id, + content_type = content_type or "application/json" + _content = None + if isinstance(evaluator_version, (IOBase, bytes)): + _content = evaluator_version + else: + _content = json.dumps(evaluator_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_evaluators_create_version_request( + name=name, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -9399,137 +9343,124 @@ async def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.Evalua response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [201]: if _stream: try: await response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluatorGenerationJob, response.json()) + deserialized = _deserialize(_models.EvaluatorVersion, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def list_generation_jobs( + @overload + async def update_version( self, + name: str, + version: str, + evaluator_version: _models.EvaluatorVersion, *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, + content_type: str = "application/json", **kwargs: Any - ) -> AsyncItemPaged["_models.EvaluatorGenerationJob"]: - """List evaluator generation jobs. + ) -> _models.EvaluatorVersion: + """Update an evaluator version. - Returns a list of evaluator generation jobs. The List API has up to a few seconds of - propagation delay, so a recently created job may not appear immediately; use the Get evaluator - generation job API with the job ID to retrieve a specific job without delay. + Updates the specified evaluator version in place. - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of EvaluatorGenerationJob - :rtype: - ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.EvaluatorGenerationJob] + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the EvaluatorVersion to update. Required. + :type version: str + :param evaluator_version: Evaluator resource. Required. + :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.EvaluatorGenerationJob]] = kwargs.pop("cls", None) + @overload + async def update_version( + self, name: str, version: str, evaluator_version: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluatorVersion: + """Update an evaluator version. - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(_continuation_token=None): - - _request = build_beta_evaluators_list_generation_jobs_request( - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request - - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.EvaluatorGenerationJob], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, AsyncList(list_of_elem) - - async def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + Updates the specified evaluator version in place. - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the EvaluatorVersion to update. Required. + :type version: str + :param evaluator_version: Evaluator resource. Required. + :type evaluator_version: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + @overload + async def update_version( + self, + name: str, + version: str, + evaluator_version: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.EvaluatorVersion: + """Update an evaluator version. - return pipeline_response + Updates the specified evaluator version in place. - return AsyncItemPaged(get_next, extract_data) + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the EvaluatorVersion to update. Required. + :type version: str + :param evaluator_version: Evaluator resource. Required. + :type evaluator_version: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace_async - async def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.EvaluatorGenerationJob: - """Cancel an evaluator generation job. + async def update_version( + self, + name: str, + version: str, + evaluator_version: Union[_models.EvaluatorVersion, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.EvaluatorVersion: + """Update an evaluator version. - Cancels an evaluator generation job by its ID. + Updates the specified evaluator version in place. - :param job_id: The ID of the job to cancel. Required. - :type job_id: str - :return: EvaluatorGenerationJob. The EvaluatorGenerationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorGenerationJob + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the EvaluatorVersion to update. Required. + :type version: str + :param evaluator_version: Evaluator resource. Is one of the following types: EvaluatorVersion, + JSON, IO[bytes] Required. + :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion or JSON or IO[bytes] + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9540,14 +9471,25 @@ async def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.Eva } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.EvaluatorGenerationJob] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) - _request = build_beta_evaluators_cancel_generation_job_request( - job_id=job_id, + content_type = content_type or "application/json" + _content = None + if isinstance(evaluator_version, (IOBase, bytes)): + _content = evaluator_version + else: + _content = json.dumps(evaluator_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_evaluators_update_version_request( + name=name, + version=version, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -9571,163 +9513,128 @@ async def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.Eva except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluatorGenerationJob, response.json()) + deserialized = _deserialize(_models.EvaluatorVersion, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace_async - async def delete_generation_job(self, job_id: str, **kwargs: Any) -> None: - """Delete an evaluator generation job. - - Deletes an evaluator generation job by its ID. Deletes the job record only; the generated - evaluator (if any) is preserved. - - :param job_id: The ID of the job to delete. Required. - :type job_id: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[None] = kwargs.pop("cls", None) - - _request = build_beta_evaluators_delete_generation_job_request( - job_id=job_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - if cls: - return cls(pipeline_response, None, {}) # type: ignore - - -class BetaInsightsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`insights` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @overload - async def generate( - self, insight: _models.Insight, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Insight: - """Generate insights. + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: _models.PendingUploadRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. - Generates an insights report from the provided evaluation configuration. + Initiates a new pending upload or retrieves an existing one for the specified evaluator + version. - :param insight: Complete evaluation configuration including data source, evaluators, and result - settings. Required. - :type insight: ~azure.ai.projects.models.Insight + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: Insight. The Insight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Insight + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def generate( - self, insight: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Insight: - """Generate insights. - - Generates an insights report from the provided evaluation configuration. - - :param insight: Complete evaluation configuration including data source, evaluators, and result - settings. Required. - :type insight: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified evaluator + version. + + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: Insight. The Insight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Insight + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def generate( - self, insight: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Insight: - """Generate insights. + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. - Generates an insights report from the provided evaluation configuration. + Initiates a new pending upload or retrieves an existing one for the specified evaluator + version. - :param insight: Complete evaluation configuration including data source, evaluators, and result - settings. Required. - :type insight: IO[bytes] + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: Insight. The Insight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Insight + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def generate(self, insight: Union[_models.Insight, JSON, IO[bytes]], **kwargs: Any) -> _models.Insight: - """Generate insights. + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: Union[_models.PendingUploadRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. - Generates an insights report from the provided evaluation configuration. + Initiates a new pending upload or retrieves an existing one for the specified evaluator + version. - :param insight: Complete evaluation configuration including data source, evaluators, and result - settings. Is one of the following types: Insight, JSON, IO[bytes] Required. - :type insight: ~azure.ai.projects.models.Insight or JSON or IO[bytes] - :return: Insight. The Insight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Insight + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Is one of the following + types: PendingUploadRequest, JSON, IO[bytes] Required. + :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest or JSON or + IO[bytes] + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9742,16 +9649,18 @@ async def generate(self, insight: Union[_models.Insight, JSON, IO[bytes]], **kwa _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Insight] = kwargs.pop("cls", None) + cls: ClsType[_models.PendingUploadResponse] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None - if isinstance(insight, (IOBase, bytes)): - _content = insight + if isinstance(pending_upload_request, (IOBase, bytes)): + _content = pending_upload_request else: - _content = json.dumps(insight, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_insights_generate_request( + _request = build_beta_evaluators_pending_upload_request( + name=name, + version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -9771,7 +9680,7 @@ async def generate(self, insight: Union[_models.Insight, JSON, IO[bytes]], **kwa response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: try: await response.read() # Load the body in memory and close the socket @@ -9787,28 +9696,123 @@ async def generate(self, insight: Union[_models.Insight, JSON, IO[bytes]], **kwa if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Insight, response.json()) + deserialized = _deserialize(_models.PendingUploadResponse, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + @overload + async def get_credentials( + self, + name: str, + version: str, + credential_request: _models.EvaluatorCredentialRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.DatasetCredential: + """Get evaluator credentials. + + Retrieves SAS credentials for accessing the storage account associated with the specified + evaluator version. + + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param credential_request: The credential request parameters. Required. + :type credential_request: ~azure.ai.projects.models.EvaluatorCredentialRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def get_credentials( + self, + name: str, + version: str, + credential_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.DatasetCredential: + """Get evaluator credentials. + + Retrieves SAS credentials for accessing the storage account associated with the specified + evaluator version. + + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param credential_request: The credential request parameters. Required. + :type credential_request: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def get_credentials( + self, + name: str, + version: str, + credential_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.DatasetCredential: + """Get evaluator credentials. + + Retrieves SAS credentials for accessing the storage account associated with the specified + evaluator version. + + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param credential_request: The credential request parameters. Required. + :type credential_request: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential + :raises ~azure.core.exceptions.HttpResponseError: + """ + @distributed_trace_async - async def get( - self, insight_id: str, *, include_coordinates: Optional[bool] = None, **kwargs: Any - ) -> _models.Insight: - """Get an insight. + async def get_credentials( + self, + name: str, + version: str, + credential_request: Union[_models.EvaluatorCredentialRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.DatasetCredential: + """Get evaluator credentials. - Retrieves the specified insight report and its results. + Retrieves SAS credentials for accessing the storage account associated with the specified + evaluator version. - :param insight_id: The unique identifier for the insights report. Required. - :type insight_id: str - :keyword include_coordinates: Whether to include coordinates for visualization in the response. - Defaults to false. Default value is None. - :paramtype include_coordinates: bool - :return: Insight. The Insight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Insight + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param credential_request: The credential request parameters. Is one of the following types: + EvaluatorCredentialRequest, JSON, IO[bytes] Required. + :type credential_request: ~azure.ai.projects.models.EvaluatorCredentialRequest or JSON or + IO[bytes] + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9819,15 +9823,25 @@ async def get( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Insight] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) - _request = build_beta_insights_get_request( - insight_id=insight_id, - include_coordinates=include_coordinates, + content_type = content_type or "application/json" + _content = None + if isinstance(credential_request, (IOBase, bytes)): + _content = credential_request + else: + _content = json.dumps(credential_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_evaluators_get_credentials_request( + name=name, + version=version, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -9860,49 +9874,20 @@ async def get( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Insight, response.json()) + deserialized = _deserialize(_models.DatasetCredential, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def list( + async def _create_generation_job_initial( self, + job: Union[_models.EvaluatorGenerationJob, JSON, IO[bytes]], *, - type: Optional[Union[str, _models.InsightType]] = None, - eval_id: Optional[str] = None, - run_id: Optional[str] = None, - agent_name: Optional[str] = None, - include_coordinates: Optional[bool] = None, + operation_id: Optional[str] = None, **kwargs: Any - ) -> AsyncItemPaged["_models.Insight"]: - """List insights. - - Returns insights in reverse chronological order, with the most recent entries first. - - :keyword type: Filter by the type of analysis. Known values are: "EvaluationRunClusterInsight", - "AgentClusterInsight", and "EvaluationComparison". Default value is None. - :paramtype type: str or ~azure.ai.projects.models.InsightType - :keyword eval_id: Filter by the evaluation ID. Default value is None. - :paramtype eval_id: str - :keyword run_id: Filter by the evaluation run ID. Default value is None. - :paramtype run_id: str - :keyword agent_name: Filter by the agent name. Default value is None. - :paramtype agent_name: str - :keyword include_coordinates: Whether to include coordinates for visualization in the response. - Defaults to false. Default value is None. - :paramtype include_coordinates: bool - :return: An iterator like instance of Insight - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Insight] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.Insight]] = kwargs.pop("cls", None) - + ) -> AsyncIterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -9911,196 +9896,234 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - _request = build_beta_insights_list_request( - type=type, - eval_id=eval_id, - run_id=run_id, - agent_name=agent_name, - include_coordinates=include_coordinates, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + content_type = content_type or "application/json" + _content = None + if isinstance(job, (IOBase, bytes)): + _content = job + else: + _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - return _request + _request = build_beta_evaluators_create_generation_job_request( + operation_id=operation_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Insight], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + _decompress = kwargs.pop("decompress", True) + _stream = True + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - async def get_next(next_link=None): - _request = prepare_request(next_link) + response = pipeline_response.http_response - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if response.status_code not in [201]: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - return pipeline_response - - return AsyncItemPaged(get_next, extract_data) + raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) -class BetaMemoryStoresOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + deserialized = response.iter_bytes() if _decompress else response.iter_raw() - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`memory_stores` attribute. - """ + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + return deserialized # type: ignore @overload - async def create( + async def begin_create_generation_job( self, + job: _models.EvaluatorGenerationJob, *, - name: str, - definition: _models.MemoryStoreDefinition, + operation_id: Optional[str] = None, content_type: str = "application/json", - description: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Create a memory store. + ) -> AsyncLROPoller[_models.EvaluatorVersion]: + """Create an evaluator generation job. - Creates a memory store resource with the provided configuration. + Creates an evaluator generation job. The service generates rubric-based evaluator definitions + from the provided source materials asynchronously. - :keyword name: The name of the memory store. Required. - :paramtype name: str - :keyword definition: The memory store definition. Required. - :paramtype definition: ~azure.ai.projects.models.MemoryStoreDefinition + :param job: The job to create. Required. + :type job: ~azure.ai.projects.models.EvaluatorGenerationJob + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword description: A human-readable description of the memory store. Default value is None. - :paramtype description: str - :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default - value is None. - :paramtype metadata: dict[str, str] - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :return: An instance of AsyncLROPoller that returns EvaluatorVersion. The EvaluatorVersion is + compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.EvaluatorVersion] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def create( - self, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Create a memory store. + async def begin_create_generation_job( + self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.EvaluatorVersion]: + """Create an evaluator generation job. - Creates a memory store resource with the provided configuration. + Creates an evaluator generation job. The service generates rubric-based evaluator definitions + from the provided source materials asynchronously. - :param body: Required. - :type body: JSON + :param job: The job to create. Required. + :type job: JSON + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :return: An instance of AsyncLROPoller that returns EvaluatorVersion. The EvaluatorVersion is + compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.EvaluatorVersion] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def create( - self, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Create a memory store. + async def begin_create_generation_job( + self, + job: IO[bytes], + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.EvaluatorVersion]: + """Create an evaluator generation job. - Creates a memory store resource with the provided configuration. + Creates an evaluator generation job. The service generates rubric-based evaluator definitions + from the provided source materials asynchronously. - :param body: Required. - :type body: IO[bytes] + :param job: The job to create. Required. + :type job: IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :return: An instance of AsyncLROPoller that returns EvaluatorVersion. The EvaluatorVersion is + compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.EvaluatorVersion] :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def create( + async def begin_create_generation_job( self, - body: Union[JSON, IO[bytes]] = _Unset, + job: Union[_models.EvaluatorGenerationJob, JSON, IO[bytes]], *, - name: str = _Unset, - definition: _models.MemoryStoreDefinition = _Unset, - description: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, + operation_id: Optional[str] = None, **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Create a memory store. + ) -> AsyncLROPoller[_models.EvaluatorVersion]: + """Create an evaluator generation job. - Creates a memory store resource with the provided configuration. + Creates an evaluator generation job. The service generates rubric-based evaluator definitions + from the provided source materials asynchronously. - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword name: The name of the memory store. Required. - :paramtype name: str - :keyword definition: The memory store definition. Required. - :paramtype definition: ~azure.ai.projects.models.MemoryStoreDefinition - :keyword description: A human-readable description of the memory store. Default value is None. - :paramtype description: str - :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default - value is None. - :paramtype metadata: dict[str, str] - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :param job: The job to create. Is one of the following types: EvaluatorGenerationJob, JSON, + IO[bytes] Required. + :type job: ~azure.ai.projects.models.EvaluatorGenerationJob or JSON or IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :return: An instance of AsyncLROPoller that returns EvaluatorVersion. The EvaluatorVersion is + compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.EvaluatorVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._create_generation_job_initial( + job=job, + operation_id=operation_id, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = _deserialize(_models.EvaluatorVersion, response.json().get("result", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized + + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) + else: + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.EvaluatorVersion].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.EvaluatorVersion]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) + + @distributed_trace_async + async def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.EvaluatorGenerationJob: + """Get an evaluator generation job. + + Gets the details of an evaluator generation job by its ID. + + :param job_id: The ID of the job. Required. + :type job_id: str + :return: EvaluatorGenerationJob. The EvaluatorGenerationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorGenerationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -10111,30 +10134,14 @@ async def create( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) - - if body is _Unset: - if name is _Unset: - raise TypeError("missing required argument: name") - if definition is _Unset: - raise TypeError("missing required argument: definition") - body = {"definition": definition, "description": description, "metadata": metadata, "name": name} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.EvaluatorGenerationJob] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_create_request( - content_type=content_type, + _request = build_beta_evaluators_get_generation_job_request( + job_id=job_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -10164,112 +10171,58 @@ async def create( ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) + deserialized = _deserialize(_models.EvaluatorGenerationJob, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @overload - async def update( + @distributed_trace + def list_generation_jobs( self, - name: str, *, - content_type: str = "application/json", - description: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Update a memory store. - - Updates the specified memory store with the supplied configuration changes. - - :param name: The name of the memory store to update. Required. - :type name: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword description: A human-readable description of the memory store. Default value is None. - :paramtype description: str - :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default - value is None. - :paramtype metadata: dict[str, str] - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def update( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Update a memory store. - - Updates the specified memory store with the supplied configuration changes. - - :param name: The name of the memory store to update. Required. - :type name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def update( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Update a memory store. + ) -> AsyncItemPaged["_models.EvaluatorGenerationJob"]: + """List evaluator generation jobs. - Updates the specified memory store with the supplied configuration changes. + Returns a list of evaluator generation jobs. The List API has up to a few seconds of + propagation delay, so a recently created job may not appear immediately; use the Get evaluator + generation job API with the job ID to retrieve a specific job without delay. - :param name: The name of the memory store to update. Required. - :type name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of EvaluatorGenerationJob + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.EvaluatorGenerationJob] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @distributed_trace_async - async def update( - self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - description: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, - **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Update a memory store. - - Updates the specified memory store with the supplied configuration changes. + cls: ClsType[List[_models.EvaluatorGenerationJob]] = kwargs.pop("cls", None) - :param name: The name of the memory store to update. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword description: A human-readable description of the memory store. Default value is None. - :paramtype description: str - :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default - value is None. - :paramtype metadata: dict[str, str] - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -10278,76 +10231,64 @@ async def update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + def prepare_request(_continuation_token=None): - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) + _request = build_beta_evaluators_list_generation_jobs_request( + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - if body is _Unset: - body = {"description": description, "metadata": metadata} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - - _request = build_beta_memory_stores_update_request( - name=name, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.EvaluatorGenerationJob], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - response = pipeline_response.http_response + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) - raise HttpResponseError(response=response, model=error) + response = pipeline_response.http_response - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return pipeline_response - return deserialized # type: ignore + return AsyncItemPaged(get_next, extract_data) @distributed_trace_async - async def get(self, name: str, **kwargs: Any) -> _models.MemoryStoreDetails: - """Get a memory store. + async def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.EvaluatorGenerationJob: + """Cancel an evaluator generation job. - Retrieves the specified memory store and its current configuration. + Cancels an evaluator generation job by its ID. - :param name: The name of the memory store to retrieve. Required. - :type name: str - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :param job_id: The ID of the job to cancel. Required. + :type job_id: str + :return: EvaluatorGenerationJob. The EvaluatorGenerationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorGenerationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -10361,10 +10302,10 @@ async def get(self, name: str, **kwargs: Any) -> _models.MemoryStoreDetails: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) + cls: ClsType[_models.EvaluatorGenerationJob] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_get_request( - name=name, + _request = build_beta_evaluators_cancel_generation_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -10398,115 +10339,24 @@ async def get(self, name: str, **kwargs: Any) -> _models.MemoryStoreDetails: if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) + deserialized = _deserialize(_models.EvaluatorGenerationJob, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def list( - self, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> AsyncItemPaged["_models.MemoryStoreDetails"]: - """List memory stores. - - Returns the memory stores available to the caller. - - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of MemoryStoreDetails - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.MemoryStoreDetails] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.MemoryStoreDetails]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(_continuation_token=None): - - _request = build_beta_memory_stores_list_request( - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request - - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.MemoryStoreDetails], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, AsyncList(list_of_elem) - - async def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) - - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - return pipeline_response - - return AsyncItemPaged(get_next, extract_data) - @distributed_trace_async - async def delete(self, name: str, **kwargs: Any) -> _models.DeleteMemoryStoreResult: - """Delete a memory store. + async def delete_generation_job(self, job_id: str, **kwargs: Any) -> None: + """Delete an evaluator generation job. - Deletes the specified memory store. + Deletes an evaluator generation job by its ID. Deletes the job record only; the generated + evaluator (if any) is preserved. - :param name: The name of the memory store to delete. Required. - :type name: str - :return: DeleteMemoryStoreResult. The DeleteMemoryStoreResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DeleteMemoryStoreResult + :param job_id: The ID of the job to delete. Required. + :type job_id: str + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -10520,10 +10370,10 @@ async def delete(self, name: str, **kwargs: Any) -> _models.DeleteMemoryStoreRes _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DeleteMemoryStoreResult] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_delete_request( - name=name, + _request = build_beta_evaluators_delete_generation_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -10533,20 +10383,14 @@ async def delete(self, name: str, **kwargs: Any) -> _models.DeleteMemoryStoreRes } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -10554,69 +10398,95 @@ async def delete(self, name: str, **kwargs: Any) -> _models.DeleteMemoryStoreRes ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.DeleteMemoryStoreResult, response.json()) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, None, {}) # type: ignore - return deserialized # type: ignore - @overload - async def _search_memories( - self, - name: str, - *, - scope: str, - content_type: str = "application/json", - items: Optional[List[dict[str, Any]]] = None, - previous_search_id: Optional[str] = None, - options: Optional[_models.MemorySearchOptions] = None, - **kwargs: Any - ) -> _models.MemoryStoreSearchResult: ... - @overload - async def _search_memories( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreSearchResult: ... - @overload - async def _search_memories( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreSearchResult: ... +class BetaInsightsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. - @distributed_trace_async - async def _search_memories( - self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - scope: str = _Unset, - items: Optional[List[dict[str, Any]]] = None, - previous_search_id: Optional[str] = None, - options: Optional[_models.MemorySearchOptions] = None, - **kwargs: Any - ) -> _models.MemoryStoreSearchResult: - """Search memories. + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`insights` attribute. + """ - Searches the specified memory store for memories relevant to the provided conversation context. + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - :param name: The name of the memory store to search. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword items: Items for which to search for relevant memories. Default value is None. - :paramtype items: list[dict[str, any]] - :keyword previous_search_id: The unique ID of the previous search request, enabling incremental - memory search from where the last operation left off. Default value is None. - :paramtype previous_search_id: str - :keyword options: Memory search options. Default value is None. - :paramtype options: ~azure.ai.projects.models.MemorySearchOptions - :return: MemoryStoreSearchResult. The MemoryStoreSearchResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreSearchResult + @overload + async def generate( + self, insight: _models.Insight, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Insight: + """Generate insights. + + Generates an insights report from the provided evaluation configuration. + + :param insight: Complete evaluation configuration including data source, evaluators, and result + settings. Required. + :type insight: ~azure.ai.projects.models.Insight + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Insight. The Insight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Insight + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def generate( + self, insight: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Insight: + """Generate insights. + + Generates an insights report from the provided evaluation configuration. + + :param insight: Complete evaluation configuration including data source, evaluators, and result + settings. Required. + :type insight: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Insight. The Insight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Insight + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def generate( + self, insight: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Insight: + """Generate insights. + + Generates an insights report from the provided evaluation configuration. + + :param insight: Complete evaluation configuration including data source, evaluators, and result + settings. Required. + :type insight: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: Insight. The Insight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Insight + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def generate(self, insight: Union[_models.Insight, JSON, IO[bytes]], **kwargs: Any) -> _models.Insight: + """Generate insights. + + Generates an insights report from the provided evaluation configuration. + + :param insight: Complete evaluation configuration including data source, evaluators, and result + settings. Is one of the following types: Insight, JSON, IO[bytes] Required. + :type insight: ~azure.ai.projects.models.Insight or JSON or IO[bytes] + :return: Insight. The Insight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Insight :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -10631,22 +10501,16 @@ async def _search_memories( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryStoreSearchResult] = kwargs.pop("cls", None) + cls: ClsType[_models.Insight] = kwargs.pop("cls", None) - if body is _Unset: - if scope is _Unset: - raise TypeError("missing required argument: scope") - body = {"items": items, "options": options, "previous_search_id": previous_search_id, "scope": scope} - body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(body, (IOBase, bytes)): - _content = body + if isinstance(insight, (IOBase, bytes)): + _content = insight else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(insight, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_memory_stores_search_memories_request( - name=name, + _request = build_beta_insights_generate_request( content_type=content_type, api_version=self._config.api_version, content=_content, @@ -10666,7 +10530,7 @@ async def _search_memories( response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [201]: if _stream: try: await response.read() # Load the body in memory and close the socket @@ -10682,24 +10546,30 @@ async def _search_memories( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryStoreSearchResult, response.json()) + deserialized = _deserialize(_models.Insight, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - async def _update_memories_initial( - self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - scope: str = _Unset, - items: Optional[List[dict[str, Any]]] = None, - previous_update_id: Optional[str] = None, - update_delay: Optional[int] = None, - **kwargs: Any - ) -> AsyncIterator[bytes]: + @distributed_trace_async + async def get( + self, insight_id: str, *, include_coordinates: Optional[bool] = None, **kwargs: Any + ) -> _models.Insight: + """Get an insight. + + Retrieves the specified insight report and its results. + + :param insight_id: The unique identifier for the insights report. Required. + :type insight_id: str + :keyword include_coordinates: Whether to include coordinates for visualization in the response. + Defaults to false. Default value is None. + :paramtype include_coordinates: bool + :return: Insight. The Insight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Insight + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -10708,34 +10578,15 @@ async def _update_memories_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - - if body is _Unset: - if scope is _Unset: - raise TypeError("missing required argument: scope") - body = { - "items": items, - "previous_update_id": previous_update_id, - "scope": scope, - "update_delay": update_delay, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.Insight] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_update_memories_request( - name=name, - content_type=content_type, + _request = build_beta_insights_get_request( + insight_id=insight_id, + include_coordinates=include_coordinates, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -10745,18 +10596,19 @@ async def _update_memories_initial( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [202]: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -10764,221 +10616,250 @@ async def _update_memories_initial( ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Insight, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - async def _begin_update_memories( + @distributed_trace + def list( self, - name: str, *, - scope: str, - content_type: str = "application/json", - items: Optional[List[dict[str, Any]]] = None, - previous_update_id: Optional[str] = None, - update_delay: Optional[int] = None, + type: Optional[Union[str, _models.InsightType]] = None, + eval_id: Optional[str] = None, + run_id: Optional[str] = None, + agent_name: Optional[str] = None, + include_coordinates: Optional[bool] = None, **kwargs: Any - ) -> AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult]: ... - @overload - async def _begin_update_memories( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult]: ... - @overload - async def _begin_update_memories( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult]: ... + ) -> AsyncItemPaged["_models.Insight"]: + """List insights. - @distributed_trace_async - async def _begin_update_memories( - self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - scope: str = _Unset, - items: Optional[List[dict[str, Any]]] = None, - previous_update_id: Optional[str] = None, - update_delay: Optional[int] = None, - **kwargs: Any - ) -> AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult]: - """Update memories. + Returns insights in reverse chronological order, with the most recent entries first. - Starts an update that writes conversation memories into the specified memory store. The - operation returns a long-running status location for polling the update result. + :keyword type: Filter by the type of analysis. Known values are: "EvaluationRunClusterInsight", + "AgentClusterInsight", and "EvaluationComparison". Default value is None. + :paramtype type: str or ~azure.ai.projects.models.InsightType + :keyword eval_id: Filter by the evaluation ID. Default value is None. + :paramtype eval_id: str + :keyword run_id: Filter by the evaluation run ID. Default value is None. + :paramtype run_id: str + :keyword agent_name: Filter by the agent name. Default value is None. + :paramtype agent_name: str + :keyword include_coordinates: Whether to include coordinates for visualization in the response. + Defaults to false. Default value is None. + :paramtype include_coordinates: bool + :return: An iterator like instance of Insight + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Insight] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - :param name: The name of the memory store to update. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword items: Conversation items to be stored in memory. Default value is None. - :paramtype items: list[dict[str, any]] - :keyword previous_update_id: The unique ID of the previous update request, enabling incremental - memory updates from where the last operation left off. Default value is None. - :paramtype previous_update_id: str - :keyword update_delay: Timeout period before processing the memory update in seconds. - If a new update request is received during this period, it will cancel the current request and - reset the timeout. - Set to 0 to immediately trigger the update without delay. - Defaults to 300 (5 minutes). Default value is None. - :paramtype update_delay: int - :return: An instance of AsyncLROPoller that returns MemoryStoreUpdateCompletedResult. The - MemoryStoreUpdateCompletedResult is compatible with MutableMapping - :rtype: - ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.MemoryStoreUpdateCompletedResult] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + cls: ClsType[List[_models.Insight]] = kwargs.pop("cls", None) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryStoreUpdateCompletedResult] = kwargs.pop("cls", None) - polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = await self._update_memories_initial( - name=name, - body=body, - scope=scope, - items=items, - previous_update_id=previous_update_id, - update_delay=update_delay, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - await raw_result.http_response.read() # type: ignore - kwargs.pop("error_map", None) + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Operation-Location"] = self._deserialize( - "str", response.headers.get("Operation-Location") - ) + def prepare_request(next_link=None): + if not next_link: - deserialized = _deserialize(_models.MemoryStoreUpdateCompletedResult, response.json().get("result", {})) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized + _request = build_beta_insights_list_request( + type=type, + eval_id=eval_id, + run_id=run_id, + agent_name=agent_name, + include_coordinates=include_coordinates, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - if polling is True: - polling_method: AsyncPollingMethod = cast( - AsyncPollingMethod, - AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Insight], + deserialized.get("value", []), ) - elif polling is False: - polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) - else: - polling_method = polling - if cont_token: - return AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) - return AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + +class BetaMemoryStoresOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`memory_stores` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") @overload - async def delete_scope( - self, name: str, *, scope: str, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDeleteScopeResult: - """Delete memories by scope. + async def create( + self, + *, + name: str, + definition: _models.MemoryStoreDefinition, + content_type: str = "application/json", + description: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Create a memory store. - Deletes all memories in the specified memory store that are associated with the provided scope. + Creates a memory store resource with the provided configuration. - :param name: The name of the memory store. Required. - :type name: str - :keyword scope: The namespace that logically groups and isolates memories to delete, such as a - user ID. Required. - :paramtype scope: str + :keyword name: The name of the memory store. Required. + :paramtype name: str + :keyword definition: The memory store definition. Required. + :paramtype definition: ~azure.ai.projects.models.MemoryStoreDefinition :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult + :keyword description: A human-readable description of the memory store. Default value is None. + :paramtype description: str + :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default + value is None. + :paramtype metadata: dict[str, str] + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def delete_scope( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDeleteScopeResult: - """Delete memories by scope. + async def create( + self, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Create a memory store. - Deletes all memories in the specified memory store that are associated with the provided scope. + Creates a memory store resource with the provided configuration. - :param name: The name of the memory store. Required. - :type name: str :param body: Required. :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def delete_scope( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDeleteScopeResult: - """Delete memories by scope. + async def create( + self, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Create a memory store. - Deletes all memories in the specified memory store that are associated with the provided scope. + Creates a memory store resource with the provided configuration. - :param name: The name of the memory store. Required. - :type name: str :param body: Required. :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def delete_scope( - self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, scope: str = _Unset, **kwargs: Any - ) -> _models.MemoryStoreDeleteScopeResult: - """Delete memories by scope. - - Deletes all memories in the specified memory store that are associated with the provided scope. - - :param name: The name of the memory store. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword scope: The namespace that logically groups and isolates memories to delete, such as a - user ID. Required. - :paramtype scope: str - :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult + async def create( + self, + body: Union[JSON, IO[bytes]] = _Unset, + *, + name: str = _Unset, + definition: _models.MemoryStoreDefinition = _Unset, + description: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Create a memory store. + + Creates a memory store resource with the provided configuration. + + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword name: The name of the memory store. Required. + :paramtype name: str + :keyword definition: The memory store definition. Required. + :paramtype definition: ~azure.ai.projects.models.MemoryStoreDefinition + :keyword description: A human-readable description of the memory store. Default value is None. + :paramtype description: str + :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default + value is None. + :paramtype metadata: dict[str, str] + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -10993,12 +10874,14 @@ async def delete_scope( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryStoreDeleteScopeResult] = kwargs.pop("cls", None) + cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) if body is _Unset: - if scope is _Unset: - raise TypeError("missing required argument: scope") - body = {"scope": scope} + if name is _Unset: + raise TypeError("missing required argument: name") + if definition is _Unset: + raise TypeError("missing required argument: definition") + body = {"definition": definition, "description": description, "metadata": metadata, "name": name} body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None @@ -11007,8 +10890,7 @@ async def delete_scope( else: _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_memory_stores_delete_scope_request( - name=name, + _request = build_beta_memory_stores_create_request( content_type=content_type, api_version=self._config.api_version, content=_content, @@ -11044,7 +10926,7 @@ async def delete_scope( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryStoreDeleteScopeResult, response.json()) + deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -11052,107 +10934,99 @@ async def delete_scope( return deserialized # type: ignore @overload - async def create_memory( + async def update( self, name: str, *, - scope: str, - content: str, - kind: Union[str, _models.MemoryItemKind], content_type: str = "application/json", + description: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, **kwargs: Any - ) -> _models.MemoryItem: - """Create a memory item. + ) -> _models.MemoryStoreDetails: + """Update a memory store. - Creates a memory item in the specified memory store. + Updates the specified memory store with the supplied configuration changes. - :param name: The name of the memory store. Required. + :param name: The name of the memory store to update. Required. :type name: str - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword content: The content of the memory. Required. - :paramtype content: str - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Required. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :keyword description: A human-readable description of the memory store. Default value is None. + :paramtype description: str + :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default + value is None. + :paramtype metadata: dict[str, str] + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def create_memory( + async def update( self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryItem: - """Create a memory item. + ) -> _models.MemoryStoreDetails: + """Update a memory store. - Creates a memory item in the specified memory store. + Updates the specified memory store with the supplied configuration changes. - :param name: The name of the memory store. Required. + :param name: The name of the memory store to update. Required. :type name: str :param body: Required. :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def create_memory( + async def update( self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryItem: - """Create a memory item. + ) -> _models.MemoryStoreDetails: + """Update a memory store. - Creates a memory item in the specified memory store. + Updates the specified memory store with the supplied configuration changes. - :param name: The name of the memory store. Required. + :param name: The name of the memory store to update. Required. :type name: str :param body: Required. :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def create_memory( + async def update( self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, - scope: str = _Unset, - content: str = _Unset, - kind: Union[str, _models.MemoryItemKind] = _Unset, + description: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, **kwargs: Any - ) -> _models.MemoryItem: - """Create a memory item. + ) -> _models.MemoryStoreDetails: + """Update a memory store. - Creates a memory item in the specified memory store. + Updates the specified memory store with the supplied configuration changes. - :param name: The name of the memory store. Required. + :param name: The name of the memory store to update. Required. :type name: str :param body: Is either a JSON type or a IO[bytes] type. Required. :type body: JSON or IO[bytes] - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword content: The content of the memory. Required. - :paramtype content: str - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Required. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :keyword description: A human-readable description of the memory store. Default value is None. + :paramtype description: str + :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default + value is None. + :paramtype metadata: dict[str, str] + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -11167,16 +11041,10 @@ async def create_memory( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) + cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) if body is _Unset: - if scope is _Unset: - raise TypeError("missing required argument: scope") - if content is _Unset: - raise TypeError("missing required argument: content") - if kind is _Unset: - raise TypeError("missing required argument: kind") - body = {"content": content, "kind": kind, "scope": scope} + body = {"description": description, "metadata": metadata} body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None @@ -11185,7 +11053,7 @@ async def create_memory( else: _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_memory_stores_create_memory_request( + _request = build_beta_memory_stores_update_request( name=name, content_type=content_type, api_version=self._config.api_version, @@ -11222,97 +11090,23 @@ async def create_memory( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryItem, response.json()) + deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - async def update_memory( - self, name: str, memory_id: str, *, content: str, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryItem: - """Update a memory item. - - Updates the specified memory item in the memory store. - - :param name: The name of the memory store. Required. - :type name: str - :param memory_id: The ID of the memory item to update. Required. - :type memory_id: str - :keyword content: The updated content of the memory. Required. - :paramtype content: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def update_memory( - self, name: str, memory_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryItem: - """Update a memory item. - - Updates the specified memory item in the memory store. - - :param name: The name of the memory store. Required. - :type name: str - :param memory_id: The ID of the memory item to update. Required. - :type memory_id: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def update_memory( - self, name: str, memory_id: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryItem: - """Update a memory item. - - Updates the specified memory item in the memory store. - - :param name: The name of the memory store. Required. - :type name: str - :param memory_id: The ID of the memory item to update. Required. - :type memory_id: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem - :raises ~azure.core.exceptions.HttpResponseError: - """ - @distributed_trace_async - async def update_memory( - self, name: str, memory_id: str, body: Union[JSON, IO[bytes]] = _Unset, *, content: str = _Unset, **kwargs: Any - ) -> _models.MemoryItem: - """Update a memory item. + async def get(self, name: str, **kwargs: Any) -> _models.MemoryStoreDetails: + """Get a memory store. - Updates the specified memory item in the memory store. + Retrieves the specified memory store and its current configuration. - :param name: The name of the memory store. Required. + :param name: The name of the memory store to retrieve. Required. :type name: str - :param memory_id: The ID of the memory item to update. Required. - :type memory_id: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword content: The updated content of the memory. Required. - :paramtype content: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -11323,30 +11117,14 @@ async def update_memory( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) - - if body is _Unset: - if content is _Unset: - raise TypeError("missing required argument: content") - body = {"content": content} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_update_memory_request( + _request = build_beta_memory_stores_get_request( name=name, - memory_id=memory_id, - content_type=content_type, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -11379,25 +11157,115 @@ async def update_memory( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryItem, response.json()) + deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + @distributed_trace + def list( + self, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.MemoryStoreDetails"]: + """List memory stores. + + Returns the memory stores available to the caller. + + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of MemoryStoreDetails + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.MemoryStoreDetails] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.MemoryStoreDetails]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_beta_memory_stores_list_request( + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.MemoryStoreDetails], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) + + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + @distributed_trace_async - async def get_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models.MemoryItem: - """Get a memory item. + async def delete(self, name: str, **kwargs: Any) -> _models.DeleteMemoryStoreResult: + """Delete a memory store. - Retrieves the specified memory item from the memory store. + Deletes the specified memory store. - :param name: The name of the memory store. Required. + :param name: The name of the memory store to delete. Required. :type name: str - :param memory_id: The ID of the memory item to retrieve. Required. - :type memory_id: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :return: DeleteMemoryStoreResult. The DeleteMemoryStoreResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DeleteMemoryStoreResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -11411,11 +11279,10 @@ async def get_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models. _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) + cls: ClsType[_models.DeleteMemoryStoreResult] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_get_memory_request( + _request = build_beta_memory_stores_delete_request( name=name, - memory_id=memory_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -11449,7 +11316,7 @@ async def get_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models. if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryItem, response.json()) + deserialized = _deserialize(_models.DeleteMemoryStoreResult, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -11457,194 +11324,3859 @@ async def get_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models. return deserialized # type: ignore @overload - def list_memories( + async def _search_memories( self, name: str, *, scope: str, - kind: Optional[Union[str, _models.MemoryItemKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, content_type: str = "application/json", + items: Optional[List[dict[str, Any]]] = None, + previous_search_id: Optional[str] = None, + options: Optional[_models.MemorySearchOptions] = None, **kwargs: Any - ) -> AsyncItemPaged["_models.MemoryItem"]: - """List memory items. - - Returns memory items from the specified memory store. - - :param name: The name of the memory store. Required. - :type name: str - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Default value is None. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: An iterator like instance of MemoryItem - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.MemoryItem] - :raises ~azure.core.exceptions.HttpResponseError: - """ - + ) -> _models.MemoryStoreSearchResult: ... @overload - def list_memories( + async def _search_memories( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreSearchResult: ... + @overload + async def _search_memories( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreSearchResult: ... + + @distributed_trace_async + async def _search_memories( self, name: str, - body: JSON, + body: Union[JSON, IO[bytes]] = _Unset, *, - kind: Optional[Union[str, _models.MemoryItemKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - content_type: str = "application/json", + scope: str = _Unset, + items: Optional[List[dict[str, Any]]] = None, + previous_search_id: Optional[str] = None, + options: Optional[_models.MemorySearchOptions] = None, **kwargs: Any - ) -> AsyncItemPaged["_models.MemoryItem"]: - """List memory items. + ) -> _models.MemoryStoreSearchResult: + """Search memories. - Returns memory items from the specified memory store. + Searches the specified memory store for memories relevant to the provided conversation context. - :param name: The name of the memory store. Required. + :param name: The name of the memory store to search. Required. :type name: str - :param body: Required. - :type body: JSON - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Default value is None. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: An iterator like instance of MemoryItem - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.MemoryItem] + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword items: Items for which to search for relevant memories. Default value is None. + :paramtype items: list[dict[str, any]] + :keyword previous_search_id: The unique ID of the previous search request, enabling incremental + memory search from where the last operation left off. Default value is None. + :paramtype previous_search_id: str + :keyword options: Memory search options. Default value is None. + :paramtype options: ~azure.ai.projects.models.MemorySearchOptions + :return: MemoryStoreSearchResult. The MemoryStoreSearchResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreSearchResult :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - @overload - def list_memories( - self, - name: str, - body: IO[bytes], - *, - kind: Optional[Union[str, _models.MemoryItemKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> AsyncItemPaged["_models.MemoryItem"]: - """List memory items. + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - Returns memory items from the specified memory store. + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.MemoryStoreSearchResult] = kwargs.pop("cls", None) + + if body is _Unset: + if scope is _Unset: + raise TypeError("missing required argument: scope") + body = {"items": items, "options": options, "previous_search_id": previous_search_id, "scope": scope} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_memory_stores_search_memories_request( + name=name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.MemoryStoreSearchResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + async def _update_memories_initial( + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + scope: str = _Unset, + items: Optional[List[dict[str, Any]]] = None, + previous_update_id: Optional[str] = None, + update_delay: Optional[int] = None, + **kwargs: Any + ) -> AsyncIterator[bytes]: + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) + + if body is _Unset: + if scope is _Unset: + raise TypeError("missing required argument: scope") + body = { + "items": items, + "previous_update_id": previous_update_id, + "scope": scope, + "update_delay": update_delay, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_memory_stores_update_memories_request( + name=name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = True + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + async def _begin_update_memories( + self, + name: str, + *, + scope: str, + content_type: str = "application/json", + items: Optional[List[dict[str, Any]]] = None, + previous_update_id: Optional[str] = None, + update_delay: Optional[int] = None, + **kwargs: Any + ) -> AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult]: ... + @overload + async def _begin_update_memories( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult]: ... + @overload + async def _begin_update_memories( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult]: ... + + @distributed_trace_async + async def _begin_update_memories( + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + scope: str = _Unset, + items: Optional[List[dict[str, Any]]] = None, + previous_update_id: Optional[str] = None, + update_delay: Optional[int] = None, + **kwargs: Any + ) -> AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult]: + """Update memories. + + Starts an update that writes conversation memories into the specified memory store. The + operation returns a long-running status location for polling the update result. + + :param name: The name of the memory store to update. Required. + :type name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword items: Conversation items to be stored in memory. Default value is None. + :paramtype items: list[dict[str, any]] + :keyword previous_update_id: The unique ID of the previous update request, enabling incremental + memory updates from where the last operation left off. Default value is None. + :paramtype previous_update_id: str + :keyword update_delay: Timeout period before processing the memory update in seconds. + If a new update request is received during this period, it will cancel the current request and + reset the timeout. + Set to 0 to immediately trigger the update without delay. + Defaults to 300 (5 minutes). Default value is None. + :paramtype update_delay: int + :return: An instance of AsyncLROPoller that returns MemoryStoreUpdateCompletedResult. The + MemoryStoreUpdateCompletedResult is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.MemoryStoreUpdateCompletedResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.MemoryStoreUpdateCompletedResult] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._update_memories_initial( + name=name, + body=body, + scope=scope, + items=items, + previous_update_id=previous_update_id, + update_delay=update_delay, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + + deserialized = _deserialize(_models.MemoryStoreUpdateCompletedResult, response.json().get("result", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized + + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) + else: + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.MemoryStoreUpdateCompletedResult]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) + + @overload + async def delete_scope( + self, name: str, *, scope: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDeleteScopeResult: + """Delete memories by scope. + + Deletes all memories in the specified memory store that are associated with the provided scope. + + :param name: The name of the memory store. Required. + :type name: str + :keyword scope: The namespace that logically groups and isolates memories to delete, such as a + user ID. Required. + :paramtype scope: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def delete_scope( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDeleteScopeResult: + """Delete memories by scope. + + Deletes all memories in the specified memory store that are associated with the provided scope. + + :param name: The name of the memory store. Required. + :type name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def delete_scope( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDeleteScopeResult: + """Delete memories by scope. + + Deletes all memories in the specified memory store that are associated with the provided scope. + + :param name: The name of the memory store. Required. + :type name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def delete_scope( + self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, scope: str = _Unset, **kwargs: Any + ) -> _models.MemoryStoreDeleteScopeResult: + """Delete memories by scope. + + Deletes all memories in the specified memory store that are associated with the provided scope. + + :param name: The name of the memory store. Required. + :type name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword scope: The namespace that logically groups and isolates memories to delete, such as a + user ID. Required. + :paramtype scope: str + :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.MemoryStoreDeleteScopeResult] = kwargs.pop("cls", None) + + if body is _Unset: + if scope is _Unset: + raise TypeError("missing required argument: scope") + body = {"scope": scope} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_memory_stores_delete_scope_request( + name=name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.MemoryStoreDeleteScopeResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + async def create_memory( + self, + name: str, + *, + scope: str, + content: str, + kind: Union[str, _models.MemoryItemKind], + content_type: str = "application/json", + **kwargs: Any + ) -> _models.MemoryItem: + """Create a memory item. + + Creates a memory item in the specified memory store. + + :param name: The name of the memory store. Required. + :type name: str + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword content: The content of the memory. Required. + :paramtype content: str + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Required. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_memory( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryItem: + """Create a memory item. + + Creates a memory item in the specified memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_memory( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryItem: + """Create a memory item. + + Creates a memory item in the specified memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create_memory( + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + scope: str = _Unset, + content: str = _Unset, + kind: Union[str, _models.MemoryItemKind] = _Unset, + **kwargs: Any + ) -> _models.MemoryItem: + """Create a memory item. + + Creates a memory item in the specified memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword content: The content of the memory. Required. + :paramtype content: str + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Required. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) + + if body is _Unset: + if scope is _Unset: + raise TypeError("missing required argument: scope") + if content is _Unset: + raise TypeError("missing required argument: content") + if kind is _Unset: + raise TypeError("missing required argument: kind") + body = {"content": content, "kind": kind, "scope": scope} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_memory_stores_create_memory_request( + name=name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.MemoryItem, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + async def update_memory( + self, name: str, memory_id: str, *, content: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryItem: + """Update a memory item. + + Updates the specified memory item in the memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param memory_id: The ID of the memory item to update. Required. + :type memory_id: str + :keyword content: The updated content of the memory. Required. + :paramtype content: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def update_memory( + self, name: str, memory_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryItem: + """Update a memory item. + + Updates the specified memory item in the memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param memory_id: The ID of the memory item to update. Required. + :type memory_id: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def update_memory( + self, name: str, memory_id: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryItem: + """Update a memory item. + + Updates the specified memory item in the memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param memory_id: The ID of the memory item to update. Required. + :type memory_id: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def update_memory( + self, name: str, memory_id: str, body: Union[JSON, IO[bytes]] = _Unset, *, content: str = _Unset, **kwargs: Any + ) -> _models.MemoryItem: + """Update a memory item. + + Updates the specified memory item in the memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param memory_id: The ID of the memory item to update. Required. + :type memory_id: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword content: The updated content of the memory. Required. + :paramtype content: str + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) + + if body is _Unset: + if content is _Unset: + raise TypeError("missing required argument: content") + body = {"content": content} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_memory_stores_update_memory_request( + name=name, + memory_id=memory_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.MemoryItem, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models.MemoryItem: + """Get a memory item. + + Retrieves the specified memory item from the memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param memory_id: The ID of the memory item to retrieve. Required. + :type memory_id: str + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) + + _request = build_beta_memory_stores_get_memory_request( + name=name, + memory_id=memory_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.MemoryItem, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def list_memories( + self, + name: str, + *, + scope: str, + kind: Optional[Union[str, _models.MemoryItemKind]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncItemPaged["_models.MemoryItem"]: + """List memory items. + + Returns memory items from the specified memory store. + + :param name: The name of the memory store. Required. + :type name: str + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Default value is None. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An iterator like instance of MemoryItem + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.MemoryItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def list_memories( + self, + name: str, + body: JSON, + *, + kind: Optional[Union[str, _models.MemoryItemKind]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncItemPaged["_models.MemoryItem"]: + """List memory items. + + Returns memory items from the specified memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param body: Required. + :type body: JSON + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Default value is None. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An iterator like instance of MemoryItem + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.MemoryItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def list_memories( + self, + name: str, + body: IO[bytes], + *, + kind: Optional[Union[str, _models.MemoryItemKind]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncItemPaged["_models.MemoryItem"]: + """List memory items. + + Returns memory items from the specified memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param body: Required. + :type body: IO[bytes] + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Default value is None. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An iterator like instance of MemoryItem + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.MemoryItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def list_memories( + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + scope: str = _Unset, + kind: Optional[Union[str, _models.MemoryItemKind]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.MemoryItem"]: + """List memory items. + + Returns memory items from the specified memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Default value is None. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of MemoryItem + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.MemoryItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.MemoryItem]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + if body is _Unset: + if scope is _Unset: + raise TypeError("missing required argument: scope") + body = {"scope": scope} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + def prepare_request(_continuation_token=None): + + _request = build_beta_memory_stores_list_memories_request( + name=name, + kind=kind, + limit=limit, + order=order, + after=_continuation_token, + before=before, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.MemoryItem], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) + + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace_async + async def delete_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models.DeleteMemoryResult: + """Delete a memory item. + + Deletes the specified memory item from the memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param memory_id: The ID of the memory item to delete. Required. + :type memory_id: str + :return: DeleteMemoryResult. The DeleteMemoryResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DeleteMemoryResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.DeleteMemoryResult] = kwargs.pop("cls", None) + + _request = build_beta_memory_stores_delete_memory_request( + name=name, + memory_id=memory_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DeleteMemoryResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +class BetaModelsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`models` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def list_versions(self, name: str, **kwargs: Any) -> AsyncItemPaged["_models.ModelVersion"]: + """List versions. + + List all versions of the given ModelVersion. + + :param name: The name of the resource. Required. + :type name: str + :return: An iterator like instance of ModelVersion + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.ModelVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ModelVersion]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_models_list_versions_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ModelVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace + def list(self, **kwargs: Any) -> AsyncItemPaged["_models.ModelVersion"]: + """List latest versions. + + List the latest version of each ModelVersion. + + :return: An iterator like instance of ModelVersion + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.ModelVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ModelVersion]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_models_list_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ModelVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace_async + async def get(self, name: str, version: str, **kwargs: Any) -> _models.ModelVersion: + """Get a model version. + + Retrieves the specified model version, returning 404 if it does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the ModelVersion to retrieve. Required. + :type version: str + :return: ModelVersion. The ModelVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ModelVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.ModelVersion] = kwargs.pop("cls", None) + + _request = build_beta_models_get_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.ModelVersion, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def delete(self, name: str, version: str, **kwargs: Any) -> None: + """Delete a model version. + + Removes the specified model version. Returns 200 whether the version existed or not. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the ModelVersion to delete. Required. + :type version: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_beta_models_delete_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @overload + async def update( + self, + name: str, + version: str, + model_version_update: _models.UpdateModelVersionRequest, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.ModelVersion: + """Update a model version. + + Updates an existing model version identified by its version ID. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the UpdateModelVersionRequest to create or update. + Required. + :type version: str + :param model_version_update: The UpdateModelVersionRequest to create or update. Required. + :type model_version_update: ~azure.ai.projects.models.UpdateModelVersionRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: ModelVersion. The ModelVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ModelVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def update( + self, + name: str, + version: str, + model_version_update: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.ModelVersion: + """Update a model version. + + Updates an existing model version identified by its version ID. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the UpdateModelVersionRequest to create or update. + Required. + :type version: str + :param model_version_update: The UpdateModelVersionRequest to create or update. Required. + :type model_version_update: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: ModelVersion. The ModelVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ModelVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def update( + self, + name: str, + version: str, + model_version_update: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.ModelVersion: + """Update a model version. + + Updates an existing model version identified by its version ID. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the UpdateModelVersionRequest to create or update. + Required. + :type version: str + :param model_version_update: The UpdateModelVersionRequest to create or update. Required. + :type model_version_update: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: ModelVersion. The ModelVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ModelVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def update( + self, + name: str, + version: str, + model_version_update: Union[_models.UpdateModelVersionRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.ModelVersion: + """Update a model version. + + Updates an existing model version identified by its version ID. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the UpdateModelVersionRequest to create or update. + Required. + :type version: str + :param model_version_update: The UpdateModelVersionRequest to create or update. Is one of the + following types: UpdateModelVersionRequest, JSON, IO[bytes] Required. + :type model_version_update: ~azure.ai.projects.models.UpdateModelVersionRequest or JSON or + IO[bytes] + :return: ModelVersion. The ModelVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ModelVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.ModelVersion] = kwargs.pop("cls", None) + + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(model_version_update, (IOBase, bytes)): + _content = model_version_update + else: + _content = json.dumps(model_version_update, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_models_update_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.ModelVersion, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + async def pending_create_version( + self, + name: str, + version: str, + model_version: _models.ModelVersion, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.CreateAsyncResponse: + """Create a model version async. + + Creates a model version asynchronously with blob content validation. Returns 202 Accepted with + a location header for polling the operation status. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param model_version: Model version to create. Required. + :type model_version: ~azure.ai.projects.models.ModelVersion + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def pending_create_version( + self, name: str, version: str, model_version: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.CreateAsyncResponse: + """Create a model version async. + + Creates a model version asynchronously with blob content validation. Returns 202 Accepted with + a location header for polling the operation status. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param model_version: Model version to create. Required. + :type model_version: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def pending_create_version( + self, + name: str, + version: str, + model_version: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.CreateAsyncResponse: + """Create a model version async. + + Creates a model version asynchronously with blob content validation. Returns 202 Accepted with + a location header for polling the operation status. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param model_version: Model version to create. Required. + :type model_version: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def pending_create_version( + self, name: str, version: str, model_version: Union[_models.ModelVersion, JSON, IO[bytes]], **kwargs: Any + ) -> _models.CreateAsyncResponse: + """Create a model version async. + + Creates a model version asynchronously with blob content validation. Returns 202 Accepted with + a location header for polling the operation status. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param model_version: Model version to create. Is one of the following types: ModelVersion, + JSON, IO[bytes] Required. + :type model_version: ~azure.ai.projects.models.ModelVersion or JSON or IO[bytes] + :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.CreateAsyncResponse] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(model_version, (IOBase, bytes)): + _content = model_version + else: + _content = json.dumps(model_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_models_pending_create_version_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.CreateAsyncResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: _models.ModelPendingUploadRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ModelPendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified model version. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param pending_upload_request: The pending upload request request body. Required. + :type pending_upload_request: ~azure.ai.projects.models.ModelPendingUploadRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ModelPendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified model version. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param pending_upload_request: The pending upload request request body. Required. + :type pending_upload_request: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ModelPendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified model version. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param pending_upload_request: The pending upload request request body. Required. + :type pending_upload_request: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def pending_upload( + self, + name: str, + version: str, + pending_upload_request: Union[_models.ModelPendingUploadRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.ModelPendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified model version. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param pending_upload_request: The pending upload request request body. Is one of the following + types: ModelPendingUploadRequest, JSON, IO[bytes] Required. + :type pending_upload_request: ~azure.ai.projects.models.ModelPendingUploadRequest or JSON or + IO[bytes] + :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.ModelPendingUploadResponse] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(pending_upload_request, (IOBase, bytes)): + _content = pending_upload_request + else: + _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_models_pending_upload_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.ModelPendingUploadResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + async def get_credentials( + self, + name: str, + version: str, + credential_request: _models.ModelCredentialRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.DatasetCredential: + """Get model asset credentials. + + Retrieves temporary credentials for accessing the storage backing the specified model version. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param credential_request: The credential request request body. Required. + :type credential_request: ~azure.ai.projects.models.ModelCredentialRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def get_credentials( + self, + name: str, + version: str, + credential_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.DatasetCredential: + """Get model asset credentials. + + Retrieves temporary credentials for accessing the storage backing the specified model version. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param credential_request: The credential request request body. Required. + :type credential_request: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def get_credentials( + self, + name: str, + version: str, + credential_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.DatasetCredential: + """Get model asset credentials. + + Retrieves temporary credentials for accessing the storage backing the specified model version. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param credential_request: The credential request request body. Required. + :type credential_request: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def get_credentials( + self, + name: str, + version: str, + credential_request: Union[_models.ModelCredentialRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.DatasetCredential: + """Get model asset credentials. + + Retrieves temporary credentials for accessing the storage backing the specified model version. + + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param credential_request: The credential request request body. Is one of the following types: + ModelCredentialRequest, JSON, IO[bytes] Required. + :type credential_request: ~azure.ai.projects.models.ModelCredentialRequest or JSON or IO[bytes] + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(credential_request, (IOBase, bytes)): + _content = credential_request + else: + _content = json.dumps(credential_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_models_get_credentials_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DatasetCredential, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +class BetaRedTeamsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`red_teams` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace_async + async def get(self, name: str, **kwargs: Any) -> _models.RedTeam: + """Get a redteam. + + Retrieves the specified redteam and its configuration. + + :param name: Identifier of the red team run. Required. + :type name: str + :return: RedTeam. The RedTeam is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.RedTeam + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.RedTeam] = kwargs.pop("cls", None) + + _request = build_beta_red_teams_get_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.RedTeam, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list(self, **kwargs: Any) -> AsyncItemPaged["_models.RedTeam"]: + """List redteams. + + Returns the redteams available in the current project. + + :return: An iterator like instance of RedTeam + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.RedTeam] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RedTeam]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_red_teams_list_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.RedTeam], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @overload + async def create( + self, red_team: _models.RedTeam, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.RedTeam: + """Create a redteam run. + + Submits a new redteam run for execution with the provided configuration. + + :param red_team: Redteam to be run. Required. + :type red_team: ~azure.ai.projects.models.RedTeam + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: RedTeam. The RedTeam is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.RedTeam + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create(self, red_team: JSON, *, content_type: str = "application/json", **kwargs: Any) -> _models.RedTeam: + """Create a redteam run. + + Submits a new redteam run for execution with the provided configuration. + + :param red_team: Redteam to be run. Required. + :type red_team: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: RedTeam. The RedTeam is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.RedTeam + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create( + self, red_team: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.RedTeam: + """Create a redteam run. + + Submits a new redteam run for execution with the provided configuration. + + :param red_team: Redteam to be run. Required. + :type red_team: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: RedTeam. The RedTeam is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.RedTeam + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwargs: Any) -> _models.RedTeam: + """Create a redteam run. + + Submits a new redteam run for execution with the provided configuration. + + :param red_team: Redteam to be run. Is one of the following types: RedTeam, JSON, IO[bytes] + Required. + :type red_team: ~azure.ai.projects.models.RedTeam or JSON or IO[bytes] + :return: RedTeam. The RedTeam is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.RedTeam + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RedTeam] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(red_team, (IOBase, bytes)): + _content = red_team + else: + _content = json.dumps(red_team, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_red_teams_create_request( + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [201]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.RedTeam, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +class BetaRoutinesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`routines` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @overload + async def create_or_update( + self, + routine_name: str, + *, + content_type: str = "application/json", + description: Optional[str] = None, + enabled: Optional[bool] = None, + triggers: Optional[dict[str, _models.RoutineTrigger]] = None, + action: Optional[_models.RoutineAction] = None, + authorization: Optional[_models.RoutineAuthorization] = None, + **kwargs: Any + ) -> _models.Routine: + """Create or update a routine. + + Creates a new routine or replaces an existing routine with the supplied definition. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword description: A human-readable description of the routine. Default value is None. + :paramtype description: str + :keyword enabled: Whether the routine is enabled. Default value is None. + :paramtype enabled: bool + :keyword triggers: The triggers configured for the routine. In v1, exactly one trigger entry is + supported. Default value is None. + :paramtype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] + :keyword action: The action executed when the routine fires. Default value is None. + :paramtype action: ~azure.ai.projects.models.RoutineAction + :keyword authorization: Optional authorization configuration for dispatching a newly created + routine. Ignored when updating an existing routine. Default value is None. + :paramtype authorization: ~azure.ai.projects.models.RoutineAuthorization + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_or_update( + self, routine_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Routine: + """Create or update a routine. + + Creates a new routine or replaces an existing routine with the supplied definition. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_or_update( + self, routine_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Routine: + """Create or update a routine. + + Creates a new routine or replaces an existing routine with the supplied definition. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create_or_update( + self, + routine_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + description: Optional[str] = None, + enabled: Optional[bool] = None, + triggers: Optional[dict[str, _models.RoutineTrigger]] = None, + action: Optional[_models.RoutineAction] = None, + authorization: Optional[_models.RoutineAuthorization] = None, + **kwargs: Any + ) -> _models.Routine: + """Create or update a routine. + + Creates a new routine or replaces an existing routine with the supplied definition. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword description: A human-readable description of the routine. Default value is None. + :paramtype description: str + :keyword enabled: Whether the routine is enabled. Default value is None. + :paramtype enabled: bool + :keyword triggers: The triggers configured for the routine. In v1, exactly one trigger entry is + supported. Default value is None. + :paramtype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] + :keyword action: The action executed when the routine fires. Default value is None. + :paramtype action: ~azure.ai.projects.models.RoutineAction + :keyword authorization: Optional authorization configuration for dispatching a newly created + routine. Ignored when updating an existing routine. Default value is None. + :paramtype authorization: ~azure.ai.projects.models.RoutineAuthorization + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + + if body is _Unset: + body = { + "action": action, + "authorization": authorization, + "description": description, + "enabled": enabled, + "triggers": triggers, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_routines_create_or_update_request( + routine_name=routine_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Routine, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get(self, routine_name: str, **kwargs: Any) -> _models.Routine: + """Get a routine. + + Retrieves the specified routine and its current configuration. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + + _request = build_beta_routines_get_request( + routine_name=routine_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Routine, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def enable(self, routine_name: str, **kwargs: Any) -> _models.Routine: + """Enable a routine. + + Enables the specified routine so it can be dispatched. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + + _request = build_beta_routines_enable_request( + routine_name=routine_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Routine, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def disable(self, routine_name: str, **kwargs: Any) -> _models.Routine: + """Disable a routine. + + Disables the specified routine so it no longer runs. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + + _request = build_beta_routines_disable_request( + routine_name=routine_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Routine, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + limit: Optional[int] = None, + after: Optional[str] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.Routine"]: + """List routines. + + Returns the routines available in the current project. + + :keyword limit: The maximum number of routines to return. Default value is None. + :paramtype limit: int + :keyword after: An opaque continuation token identifying where to resume the list. Prefer + following the ``next_link`` returned by the previous response, which embeds this value. Default + value is None. + :paramtype after: str + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :return: An iterator like instance of Routine + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Routine] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Routine]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_routines_list_request( + limit=limit, + after=after, + order=order, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Routine], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("next_link") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace_async + async def delete(self, routine_name: str, **kwargs: Any) -> None: + """Delete a routine. + + Deletes the specified routine. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_beta_routines_delete_request( + routine_name=routine_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace + def list_runs( + self, + routine_name: str, + *, + filter: Optional[str] = None, + limit: Optional[int] = None, + after: Optional[str] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.RoutineRun"]: + """List prior runs for a routine. + + Returns prior runs recorded for the specified routine. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :keyword filter: An optional MLflow search-runs filter expression applied within the routine's + experiment. Default value is None. + :paramtype filter: str + :keyword limit: The maximum number of runs to return. Default value is None. + :paramtype limit: int + :keyword after: An opaque continuation token identifying where to resume the list. Prefer + following the ``next_link`` returned by the previous response, which embeds this value. Default + value is None. + :paramtype after: str + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :return: An iterator like instance of RoutineRun + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.RoutineRun] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RoutineRun]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_routines_list_runs_request( + routine_name=routine_name, + filter=filter, + limit=limit, + after=after, + order=order, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.RoutineRun], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("next_link") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @overload + async def dispatch( + self, + routine_name: str, + *, + content_type: str = "application/json", + payload: Optional[_models.RoutineDispatchPayload] = None, + **kwargs: Any + ) -> _models.DispatchRoutineResult: + """Queue an asynchronous routine dispatch. + + Queues an asynchronous dispatch for the specified routine. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword payload: A direct action-input override sent downstream when testing a routine. + Default value is None. + :paramtype payload: ~azure.ai.projects.models.RoutineDispatchPayload + :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DispatchRoutineResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def dispatch( + self, routine_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.DispatchRoutineResult: + """Queue an asynchronous routine dispatch. + + Queues an asynchronous dispatch for the specified routine. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DispatchRoutineResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def dispatch( + self, routine_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.DispatchRoutineResult: + """Queue an asynchronous routine dispatch. + + Queues an asynchronous dispatch for the specified routine. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DispatchRoutineResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def dispatch( + self, + routine_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + payload: Optional[_models.RoutineDispatchPayload] = None, + **kwargs: Any + ) -> _models.DispatchRoutineResult: + """Queue an asynchronous routine dispatch. + + Queues an asynchronous dispatch for the specified routine. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword payload: A direct action-input override sent downstream when testing a routine. + Default value is None. + :paramtype payload: ~azure.ai.projects.models.RoutineDispatchPayload + :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DispatchRoutineResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.DispatchRoutineResult] = kwargs.pop("cls", None) + + if body is _Unset: + body = {"payload": payload} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_routines_dispatch_request( + routine_name=routine_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DispatchRoutineResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +class BetaSchedulesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`schedules` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace_async + async def delete(self, schedule_id: str, **kwargs: Any) -> None: + """Delete a schedule. + + Deletes the specified schedule resource. + + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_beta_schedules_delete_request( + schedule_id=schedule_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace_async + async def get(self, schedule_id: str, **kwargs: Any) -> _models.Schedule: + """Get a schedule. + + Retrieves the specified schedule resource. + + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :return: Schedule. The Schedule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Schedule + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Schedule] = kwargs.pop("cls", None) + + _request = build_beta_schedules_get_request( + schedule_id=schedule_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Schedule, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + type: Optional[Union[str, _models.ScheduleTaskType]] = None, + enabled: Optional[bool] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.Schedule"]: + """List schedules. + + Returns schedules that match the supplied type and enabled filters. + + :keyword type: Filter by the type of schedule. Known values are: "Evaluation" and "Insight". + Default value is None. + :paramtype type: str or ~azure.ai.projects.models.ScheduleTaskType + :keyword enabled: Filter by the enabled status. Default value is None. + :paramtype enabled: bool + :return: An iterator like instance of Schedule + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Schedule] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Schedule]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_schedules_list_request( + type=type, + enabled=enabled, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Schedule], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @overload + async def create_or_update( + self, schedule_id: str, schedule: _models.Schedule, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Schedule: + """Create or update a schedule. + + Creates a new schedule or updates an existing schedule with the supplied definition. + + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :param schedule: The resource instance. Required. + :type schedule: ~azure.ai.projects.models.Schedule + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Schedule. The Schedule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Schedule + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_or_update( + self, schedule_id: str, schedule: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Schedule: + """Create or update a schedule. + + Creates a new schedule or updates an existing schedule with the supplied definition. + + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :param schedule: The resource instance. Required. + :type schedule: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Schedule. The Schedule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Schedule + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_or_update( + self, schedule_id: str, schedule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Schedule: + """Create or update a schedule. + + Creates a new schedule or updates an existing schedule with the supplied definition. + + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :param schedule: The resource instance. Required. + :type schedule: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: Schedule. The Schedule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Schedule + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create_or_update( + self, schedule_id: str, schedule: Union[_models.Schedule, JSON, IO[bytes]], **kwargs: Any + ) -> _models.Schedule: + """Create or update a schedule. + + Creates a new schedule or updates an existing schedule with the supplied definition. + + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :param schedule: The resource instance. Is one of the following types: Schedule, JSON, + IO[bytes] Required. + :type schedule: ~azure.ai.projects.models.Schedule or JSON or IO[bytes] + :return: Schedule. The Schedule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Schedule + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.Schedule] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(schedule, (IOBase, bytes)): + _content = schedule + else: + _content = json.dumps(schedule, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_schedules_create_or_update_request( + schedule_id=schedule_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - :param name: The name of the memory store. Required. - :type name: str - :param body: Required. - :type body: IO[bytes] - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Default value is None. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: An iterator like instance of MemoryItem - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.MemoryItem] + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Schedule, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get_run(self, schedule_id: str, run_id: str, **kwargs: Any) -> _models.ScheduleRun: + """Get a schedule run. + + Retrieves the specified run for a schedule. + + :param schedule_id: The unique identifier of the schedule. Required. + :type schedule_id: str + :param run_id: The unique identifier of the schedule run. Required. + :type run_id: str + :return: ScheduleRun. The ScheduleRun is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ScheduleRun :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.ScheduleRun] = kwargs.pop("cls", None) + + _request = build_beta_schedules_get_run_request( + schedule_id=schedule_id, + run_id=run_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.ScheduleRun, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace - def list_memories( + def list_runs( self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, + schedule_id: str, *, - scope: str = _Unset, - kind: Optional[Union[str, _models.MemoryItemKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, + type: Optional[Union[str, _models.ScheduleTaskType]] = None, + enabled: Optional[bool] = None, **kwargs: Any - ) -> AsyncItemPaged["_models.MemoryItem"]: - """List memory items. + ) -> AsyncItemPaged["_models.ScheduleRun"]: + """List schedule runs. - Returns memory items from the specified memory store. + Returns schedule runs that match the supplied filters. - :param name: The name of the memory store. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Default value is None. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :keyword type: Filter by the type of schedule. Known values are: "Evaluation" and "Insight". Default value is None. - :paramtype before: str - :return: An iterator like instance of MemoryItem - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.MemoryItem] + :paramtype type: str or ~azure.ai.projects.models.ScheduleTaskType + :keyword enabled: Filter by the enabled status. Default value is None. + :paramtype enabled: bool + :return: An iterator like instance of ScheduleRun + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.ScheduleRun] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[List[_models.MemoryItem]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.ScheduleRun]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -11653,51 +15185,62 @@ def list_memories( 304: ResourceNotModifiedError, } error_map.update(kwargs.pop("error_map", {}) or {}) - if body is _Unset: - if scope is _Unset: - raise TypeError("missing required argument: scope") - body = {"scope": scope} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - def prepare_request(_continuation_token=None): + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_schedules_list_runs_request( + schedule_id=schedule_id, + type=type, + enabled=enabled, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _request = build_beta_memory_stores_list_memories_request( - name=name, - kind=kind, - limit=limit, - order=order, - after=_continuation_token, - before=before, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.MemoryItem], - deserialized.get("data", []), + list_of_elem = _deserialize( + List[_models.ScheduleRun], + deserialized.get("value", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, AsyncList(list_of_elem) + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) - async def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + async def get_next(next_link=None): + _request = prepare_request(next_link) _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access @@ -11707,28 +15250,40 @@ async def get_next(_continuation_token=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) return pipeline_response return AsyncItemPaged(get_next, extract_data) + +class BetaSkillsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`skills` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @distributed_trace_async - async def delete_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models.DeleteMemoryResult: - """Delete a memory item. + async def get(self, name: str, **kwargs: Any) -> _models.SkillDetails: + """Retrieve a skill. - Deletes the specified memory item from the memory store. + Retrieves the specified skill and its current configuration. - :param name: The name of the memory store. Required. + :param name: The unique name of the skill. Required. :type name: str - :param memory_id: The ID of the memory item to delete. Required. - :type memory_id: str - :return: DeleteMemoryResult. The DeleteMemoryResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DeleteMemoryResult + :return: SkillDetails. The SkillDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -11742,11 +15297,10 @@ async def delete_memory(self, name: str, memory_id: str, **kwargs: Any) -> _mode _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DeleteMemoryResult] = kwargs.pop("cls", None) + cls: ClsType[_models.SkillDetails] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_delete_memory_request( + _request = build_beta_skills_get_request( name=name, - memory_id=memory_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -11780,47 +15334,48 @@ async def delete_memory(self, name: str, memory_id: str, **kwargs: Any) -> _mode if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DeleteMemoryResult, response.json()) + deserialized = _deserialize(_models.SkillDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - -class BetaModelsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`models` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace - def list_versions(self, name: str, **kwargs: Any) -> AsyncItemPaged["_models.ModelVersion"]: - """List versions. + def list( + self, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.SkillDetails"]: + """List skills. - List all versions of the given ModelVersion. + Returns the skills available in the current project. - :param name: The name of the resource. Required. - :type name: str - :return: An iterator like instance of ModelVersion - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.ModelVersion] + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of SkillDetails + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.SkillDetails] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.ModelVersion]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.SkillDetails]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -11830,59 +15385,35 @@ def list_versions(self, name: str, **kwargs: Any) -> AsyncItemPaged["_models.Mod } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_models_list_versions_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + def prepare_request(_continuation_token=None): + _request = build_beta_skills_list_request( + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.ModelVersion], - deserialized.get("value", []), + List[_models.SkillDetails], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - async def get_next(next_link=None): - _request = prepare_request(next_link) + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access @@ -11892,114 +15423,94 @@ async def get_next(next_link=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) return pipeline_response return AsyncItemPaged(get_next, extract_data) - @distributed_trace - def list(self, **kwargs: Any) -> AsyncItemPaged["_models.ModelVersion"]: - """List latest versions. - - List the latest version of each ModelVersion. - - :return: An iterator like instance of ModelVersion - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.ModelVersion] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.ModelVersion]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_models_list_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + @overload + async def update( + self, name: str, *, default_version: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.SkillDetails: + """Update a skill. - return _request + Modifies the specified skill's configuration. - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.ModelVersion], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + :param name: The name of the skill to update. Required. + :type name: str + :keyword default_version: The version identifier that the skill should point to. When set, the + skill's default version will resolve to this version instead of the latest. Required. + :paramtype default_version: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: SkillDetails. The SkillDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ - async def get_next(next_link=None): - _request = prepare_request(next_link) + @overload + async def update( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.SkillDetails: + """Update a skill. - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + Modifies the specified skill's configuration. - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + :param name: The name of the skill to update. Required. + :type name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: SkillDetails. The SkillDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ - return pipeline_response + @overload + async def update( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.SkillDetails: + """Update a skill. - return AsyncItemPaged(get_next, extract_data) + Modifies the specified skill's configuration. + + :param name: The name of the skill to update. Required. + :type name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: SkillDetails. The SkillDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace_async - async def get(self, name: str, version: str, **kwargs: Any) -> _models.ModelVersion: - """Get a model version. + async def update( + self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, default_version: str = _Unset, **kwargs: Any + ) -> _models.SkillDetails: + """Update a skill. - Retrieves the specified model version, returning 404 if it does not exist. + Modifies the specified skill's configuration. - :param name: The name of the resource. Required. + :param name: The name of the skill to update. Required. :type name: str - :param version: The specific version id of the ModelVersion to retrieve. Required. - :type version: str - :return: ModelVersion. The ModelVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ModelVersion + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword default_version: The version identifier that the skill should point to. When set, the + skill's default version will resolve to this version instead of the latest. Required. + :paramtype default_version: str + :return: SkillDetails. The SkillDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -12010,15 +15521,29 @@ async def get(self, name: str, version: str, **kwargs: Any) -> _models.ModelVers } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.ModelVersion] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.SkillDetails] = kwargs.pop("cls", None) - _request = build_beta_models_get_request( + if body is _Unset: + if default_version is _Unset: + raise TypeError("missing required argument: default_version") + body = {"default_version": default_version} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_skills_update_request( name=name, - version=version, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -12042,12 +15567,16 @@ async def get(self, name: str, version: str, **kwargs: Any) -> _models.ModelVers except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.ModelVersion, response.json()) + deserialized = _deserialize(_models.SkillDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -12055,168 +15584,15 @@ async def get(self, name: str, version: str, **kwargs: Any) -> _models.ModelVers return deserialized # type: ignore @distributed_trace_async - async def delete(self, name: str, version: str, **kwargs: Any) -> None: - """Delete a model version. - - Removes the specified model version. Returns 200 whether the version existed or not. - - :param name: The name of the resource. Required. - :type name: str - :param version: The version of the ModelVersion to delete. Required. - :type version: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[None] = kwargs.pop("cls", None) - - _request = build_beta_models_delete_request( - name=name, - version=version, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if cls: - return cls(pipeline_response, None, {}) # type: ignore - - @overload - async def update( - self, - name: str, - version: str, - model_version_update: _models.UpdateModelVersionRequest, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.ModelVersion: - """Update a model version. - - Updates an existing model version identified by its version ID. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the UpdateModelVersionRequest to create or update. - Required. - :type version: str - :param model_version_update: The UpdateModelVersionRequest to create or update. Required. - :type model_version_update: ~azure.ai.projects.models.UpdateModelVersionRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: ModelVersion. The ModelVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ModelVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def update( - self, - name: str, - version: str, - model_version_update: JSON, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.ModelVersion: - """Update a model version. - - Updates an existing model version identified by its version ID. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the UpdateModelVersionRequest to create or update. - Required. - :type version: str - :param model_version_update: The UpdateModelVersionRequest to create or update. Required. - :type model_version_update: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: ModelVersion. The ModelVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ModelVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def update( - self, - name: str, - version: str, - model_version_update: IO[bytes], - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.ModelVersion: - """Update a model version. - - Updates an existing model version identified by its version ID. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the UpdateModelVersionRequest to create or update. - Required. - :type version: str - :param model_version_update: The UpdateModelVersionRequest to create or update. Required. - :type model_version_update: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: ModelVersion. The ModelVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ModelVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @distributed_trace_async - async def update( - self, - name: str, - version: str, - model_version_update: Union[_models.UpdateModelVersionRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.ModelVersion: - """Update a model version. + async def delete(self, name: str, **kwargs: Any) -> _models.DeleteSkillResult: + """Delete a skill. - Updates an existing model version identified by its version ID. + Removes the specified skill and its associated versions. - :param name: The name of the resource. Required. + :param name: The unique name of the skill. Required. :type name: str - :param version: The specific version id of the UpdateModelVersionRequest to create or update. - Required. - :type version: str - :param model_version_update: The UpdateModelVersionRequest to create or update. Is one of the - following types: UpdateModelVersionRequest, JSON, IO[bytes] Required. - :type model_version_update: ~azure.ai.projects.models.UpdateModelVersionRequest or JSON or - IO[bytes] - :return: ModelVersion. The ModelVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ModelVersion + :return: DeleteSkillResult. The DeleteSkillResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DeleteSkillResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -12227,25 +15603,14 @@ async def update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.ModelVersion] = kwargs.pop("cls", None) - - content_type = content_type or "application/merge-patch+json" - _content = None - if isinstance(model_version_update, (IOBase, bytes)): - _content = model_version_update - else: - _content = json.dumps(model_version_update, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.DeleteSkillResult] = kwargs.pop("cls", None) - _request = build_beta_models_update_request( + _request = build_beta_skills_delete_request( name=name, - version=version, - content_type=content_type, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -12262,19 +15627,23 @@ async def update( response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: await response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.ModelVersion, response.json()) + deserialized = _deserialize(_models.DeleteSkillResult, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -12282,104 +15651,99 @@ async def update( return deserialized # type: ignore @overload - async def pending_create_version( + async def create( self, name: str, - version: str, - model_version: _models.ModelVersion, *, content_type: str = "application/json", + inline_content: Optional[_models.SkillInlineContent] = None, + default: Optional[bool] = None, **kwargs: Any - ) -> _models.CreateAsyncResponse: - """Create a model version async. + ) -> _models.SkillVersion: + """Create a new version of a skill. - Creates a model version asynchronously with blob content validation. Returns 202 Accepted with - a location header for polling the operation status. + Creates a new version of a skill. If the skill does not exist, it will be created. - :param name: Name of the model. Required. + :param name: The name of the skill. If the skill does not exist, it will be created. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param model_version: Model version to create. Required. - :type model_version: ~azure.ai.projects.models.ModelVersion :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :keyword inline_content: Inline skill content for simple skills without file uploads. + Foundry-specific extension. Default value is None. + :paramtype inline_content: ~azure.ai.projects.models.SkillInlineContent + :keyword default: Whether to set this version as the default. Default value is None. + :paramtype default: bool + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def pending_create_version( - self, name: str, version: str, model_version: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.CreateAsyncResponse: - """Create a model version async. + async def create( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.SkillVersion: + """Create a new version of a skill. - Creates a model version asynchronously with blob content validation. Returns 202 Accepted with - a location header for polling the operation status. + Creates a new version of a skill. If the skill does not exist, it will be created. - :param name: Name of the model. Required. + :param name: The name of the skill. If the skill does not exist, it will be created. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param model_version: Model version to create. Required. - :type model_version: JSON + :param body: Required. + :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def pending_create_version( - self, - name: str, - version: str, - model_version: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.CreateAsyncResponse: - """Create a model version async. + async def create( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.SkillVersion: + """Create a new version of a skill. - Creates a model version asynchronously with blob content validation. Returns 202 Accepted with - a location header for polling the operation status. + Creates a new version of a skill. If the skill does not exist, it will be created. - :param name: Name of the model. Required. + :param name: The name of the skill. If the skill does not exist, it will be created. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param model_version: Model version to create. Required. - :type model_version: IO[bytes] + :param body: Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def pending_create_version( - self, name: str, version: str, model_version: Union[_models.ModelVersion, JSON, IO[bytes]], **kwargs: Any - ) -> _models.CreateAsyncResponse: - """Create a model version async. + async def create( + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + inline_content: Optional[_models.SkillInlineContent] = None, + default: Optional[bool] = None, + **kwargs: Any + ) -> _models.SkillVersion: + """Create a new version of a skill. - Creates a model version asynchronously with blob content validation. Returns 202 Accepted with - a location header for polling the operation status. + Creates a new version of a skill. If the skill does not exist, it will be created. - :param name: Name of the model. Required. + :param name: The name of the skill. If the skill does not exist, it will be created. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param model_version: Model version to create. Is one of the following types: ModelVersion, - JSON, IO[bytes] Required. - :type model_version: ~azure.ai.projects.models.ModelVersion or JSON or IO[bytes] - :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword inline_content: Inline skill content for simple skills without file uploads. + Foundry-specific extension. Default value is None. + :paramtype inline_content: ~azure.ai.projects.models.SkillInlineContent + :keyword default: Whether to set this version as the default. Default value is None. + :paramtype default: bool + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -12394,18 +15758,20 @@ async def pending_create_version( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.CreateAsyncResponse] = kwargs.pop("cls", None) + cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) + if body is _Unset: + body = {"default": default, "inline_content": inline_content} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(model_version, (IOBase, bytes)): - _content = model_version + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(model_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_models_pending_create_version_request( + _request = build_beta_skills_create_request( name=name, - version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -12425,138 +15791,76 @@ async def pending_create_version( response = pipeline_response.http_response - if response.status_code not in [202]: + if response.status_code not in [200]: if _stream: try: await response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - response_headers = {} - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.CreateAsyncResponse, response.json()) + deserialized = _deserialize(_models.SkillVersion, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @overload - async def pending_upload( - self, - name: str, - version: str, - pending_upload_request: _models.ModelPendingUploadRequest, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.ModelPendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified model version. - - :param name: Name of the model. Required. - :type name: str - :param version: Version of the model. Required. - :type version: str - :param pending_upload_request: The pending upload request request body. Required. - :type pending_upload_request: ~azure.ai.projects.models.ModelPendingUploadRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def pending_upload( - self, - name: str, - version: str, - pending_upload_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.ModelPendingUploadResponse: - """Start a pending upload. + async def create_from_files( + self, name: str, content: _models.CreateSkillVersionFromFilesBody, **kwargs: Any + ) -> _models.SkillVersion: + """Create a skill version from uploaded files. - Initiates a new pending upload or retrieves an existing one for the specified model version. + Creates a new version of a skill from uploaded files via multipart form data. - :param name: Name of the model. Required. + :param name: The name of the skill. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param pending_upload_request: The pending upload request request body. Required. - :type pending_upload_request: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def pending_upload( - self, - name: str, - version: str, - pending_upload_request: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.ModelPendingUploadResponse: - """Start a pending upload. + :param content: The multipart request content. Required. + :type content: ~azure.ai.projects.models.CreateSkillVersionFromFilesBody + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ - Initiates a new pending upload or retrieves an existing one for the specified model version. + @overload + async def create_from_files(self, name: str, content: JSON, **kwargs: Any) -> _models.SkillVersion: + """Create a skill version from uploaded files. - :param name: Name of the model. Required. + Creates a new version of a skill from uploaded files via multipart form data. + + :param name: The name of the skill. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param pending_upload_request: The pending upload request request body. Required. - :type pending_upload_request: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse + :param content: The multipart request content. Required. + :type content: JSON + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def pending_upload( - self, - name: str, - version: str, - pending_upload_request: Union[_models.ModelPendingUploadRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.ModelPendingUploadResponse: - """Start a pending upload. + async def create_from_files( + self, name: str, content: Union[_models.CreateSkillVersionFromFilesBody, JSON], **kwargs: Any + ) -> _models.SkillVersion: + """Create a skill version from uploaded files. - Initiates a new pending upload or retrieves an existing one for the specified model version. + Creates a new version of a skill from uploaded files via multipart form data. - :param name: Name of the model. Required. + :param name: The name of the skill. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param pending_upload_request: The pending upload request request body. Is one of the following - types: ModelPendingUploadRequest, JSON, IO[bytes] Required. - :type pending_upload_request: ~azure.ai.projects.models.ModelPendingUploadRequest or JSON or - IO[bytes] - :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse + :param content: The multipart request content. Is either a CreateSkillVersionFromFilesBody type + or a JSON type. Required. + :type content: ~azure.ai.projects.models.CreateSkillVersionFromFilesBody or JSON + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -12567,25 +15871,20 @@ async def pending_upload( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.ModelPendingUploadResponse] = kwargs.pop("cls", None) + cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) - content_type = content_type or "application/json" - _content = None - if isinstance(pending_upload_request, (IOBase, bytes)): - _content = pending_upload_request - else: - _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _body = content.as_dict() if isinstance(content, _Model) else content + _file_fields: list[str] = ["files"] + _data_fields: list[str] = ["default"] + _files = prepare_multipart_form_data(_body, _file_fields, _data_fields) - _request = build_beta_models_pending_upload_request( + _request = build_beta_skills_create_from_files_request( name=name, - version=version, - content_type=content_type, api_version=self._config.api_version, - content=_content, + files=_files, headers=_headers, params=_params, ) @@ -12609,123 +15908,130 @@ async def pending_upload( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.ModelPendingUploadResponse, response.json()) + deserialized = _deserialize(_models.SkillVersion, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - async def get_credentials( + @distributed_trace + def list_versions( self, name: str, - version: str, - credential_request: _models.ModelCredentialRequest, *, - content_type: str = "application/json", + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> _models.DatasetCredential: - """Get model asset credentials. + ) -> AsyncItemPaged["_models.SkillVersion"]: + """List skill versions. - Retrieves temporary credentials for accessing the storage backing the specified model version. + Returns the available versions for the specified skill. - :param name: Name of the model. Required. + :param name: The name of the skill to list versions for. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param credential_request: The credential request request body. Required. - :type credential_request: ~azure.ai.projects.models.ModelCredentialRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of SkillVersion + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.SkillVersion] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @overload - async def get_credentials( - self, - name: str, - version: str, - credential_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.DatasetCredential: - """Get model asset credentials. + cls: ClsType[List[_models.SkillVersion]] = kwargs.pop("cls", None) - Retrieves temporary credentials for accessing the storage backing the specified model version. + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - :param name: Name of the model. Required. - :type name: str - :param version: Version of the model. Required. - :type version: str - :param credential_request: The credential request request body. Required. - :type credential_request: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential - :raises ~azure.core.exceptions.HttpResponseError: - """ + def prepare_request(_continuation_token=None): - @overload - async def get_credentials( - self, - name: str, - version: str, - credential_request: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.DatasetCredential: - """Get model asset credentials. + _request = build_beta_skills_list_versions_request( + name=name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - Retrieves temporary credentials for accessing the storage backing the specified model version. + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.SkillVersion], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - :param name: Name of the model. Required. - :type name: str - :param version: Version of the model. Required. - :type version: str - :param credential_request: The credential request request body. Required. - :type credential_request: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential - :raises ~azure.core.exceptions.HttpResponseError: - """ + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) @distributed_trace_async - async def get_credentials( - self, - name: str, - version: str, - credential_request: Union[_models.ModelCredentialRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.DatasetCredential: - """Get model asset credentials. + async def get_version(self, name: str, version: str, **kwargs: Any) -> _models.SkillVersion: + """Retrieve a specific version of a skill. - Retrieves temporary credentials for accessing the storage backing the specified model version. + Retrieves the specified version of a skill by name and version identifier. - :param name: Name of the model. Required. + :param name: The name of the skill. Required. :type name: str - :param version: Version of the model. Required. + :param version: The version identifier to retrieve. Required. :type version: str - :param credential_request: The credential request request body. Is one of the following types: - ModelCredentialRequest, JSON, IO[bytes] Required. - :type credential_request: ~azure.ai.projects.models.ModelCredentialRequest or JSON or IO[bytes] - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -12736,25 +16042,15 @@ async def get_credentials( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(credential_request, (IOBase, bytes)): - _content = credential_request - else: - _content = json.dumps(credential_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) - _request = build_beta_models_get_credentials_request( + _request = build_beta_skills_get_version_request( name=name, version=version, - content_type=content_type, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -12778,46 +16074,32 @@ async def get_credentials( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DatasetCredential, response.json()) + deserialized = _deserialize(_models.SkillVersion, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - -class BetaRedTeamsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`red_teams` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace_async - async def get(self, name: str, **kwargs: Any) -> _models.RedTeam: - """Get a redteam. + async def download(self, name: str, **kwargs: Any) -> AsyncIterator[bytes]: + """Download the zip content for the default version of a skill. - Retrieves the specified redteam and its configuration. + Downloads the zip content for the default version of a skill. - :param name: Identifier of the red team run. Required. + :param name: The name of the skill. Required. :type name: str - :return: RedTeam. The RedTeam is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.RedTeam + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -12831,9 +16113,9 @@ async def get(self, name: str, **kwargs: Any) -> _models.RedTeam: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.RedTeam] = kwargs.pop("cls", None) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_beta_red_teams_get_request( + _request = build_beta_skills_download_request( name=name, api_version=self._config.api_version, headers=_headers, @@ -12845,7 +16127,7 @@ async def get(self, name: str, **kwargs: Any) -> _models.RedTeam: _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -12859,33 +16141,36 @@ async def get(self, name: str, **kwargs: Any) -> _models.RedTeam: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.RedTeam, response.json()) + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace - def list(self, **kwargs: Any) -> AsyncItemPaged["_models.RedTeam"]: - """List redteams. + @distributed_trace_async + async def download_version(self, name: str, version: str, **kwargs: Any) -> AsyncIterator[bytes]: + """Download the zip content for a specific version of a skill. - Returns the redteams available in the current project. + Downloads the zip content for a specific version of a skill. - :return: An iterator like instance of RedTeam - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.RedTeam] + :param name: The name of the skill. Required. + :type name: str + :param version: The version to download content for. Required. + :type version: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.RedTeam]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -12894,136 +16179,67 @@ def list(self, **kwargs: Any) -> AsyncItemPaged["_models.RedTeam"]: } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_red_teams_list_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - return _request + _request = build_beta_skills_download_version_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.RedTeam], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - async def get_next(next_link=None): - _request = prepare_request(next_link) + response = pipeline_response.http_response - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - return pipeline_response - - return AsyncItemPaged(get_next, extract_data) - - @overload - async def create( - self, red_team: _models.RedTeam, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RedTeam: - """Create a redteam run. - - Submits a new redteam run for execution with the provided configuration. - - :param red_team: Redteam to be run. Required. - :type red_team: ~azure.ai.projects.models.RedTeam - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RedTeam. The RedTeam is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.RedTeam - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create(self, red_team: JSON, *, content_type: str = "application/json", **kwargs: Any) -> _models.RedTeam: - """Create a redteam run. - - Submits a new redteam run for execution with the provided configuration. + raise HttpResponseError(response=response, model=error) - :param red_team: Redteam to be run. Required. - :type red_team: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RedTeam. The RedTeam is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.RedTeam - :raises ~azure.core.exceptions.HttpResponseError: - """ + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - @overload - async def create( - self, red_team: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RedTeam: - """Create a redteam run. + deserialized = response.iter_bytes() if _decompress else response.iter_raw() - Submits a new redteam run for execution with the provided configuration. + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore - :param red_team: Redteam to be run. Required. - :type red_team: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: RedTeam. The RedTeam is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.RedTeam - :raises ~azure.core.exceptions.HttpResponseError: - """ + return deserialized # type: ignore @distributed_trace_async - async def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwargs: Any) -> _models.RedTeam: - """Create a redteam run. + async def delete_version(self, name: str, version: str, **kwargs: Any) -> _models.DeleteSkillVersionResult: + """Delete a specific version of a skill. - Submits a new redteam run for execution with the provided configuration. + Removes the specified version of a skill. - :param red_team: Redteam to be run. Is one of the following types: RedTeam, JSON, IO[bytes] - Required. - :type red_team: ~azure.ai.projects.models.RedTeam or JSON or IO[bytes] - :return: RedTeam. The RedTeam is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.RedTeam + :param name: The name of the skill. Required. + :type name: str + :param version: The version identifier to delete. Required. + :type version: str + :return: DeleteSkillVersionResult. The DeleteSkillVersionResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.DeleteSkillVersionResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -13034,23 +16250,15 @@ async def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwar } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RedTeam] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(red_team, (IOBase, bytes)): - _content = red_team - else: - _content = json.dumps(red_team, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.DeleteSkillVersionResult] = kwargs.pop("cls", None) - _request = build_beta_red_teams_create_request( - content_type=content_type, + _request = build_beta_skills_delete_version_request( + name=name, + version=version, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -13067,7 +16275,7 @@ async def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwar response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: try: await response.read() # Load the body in memory and close the socket @@ -13083,7 +16291,7 @@ async def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwar if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.RedTeam, response.json()) + deserialized = _deserialize(_models.DeleteSkillVersionResult, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -13091,14 +16299,14 @@ async def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwar return deserialized # type: ignore -class BetaRoutinesOperations: # pylint: disable=docstring-missing-param +class BetaDatasetsOperations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. Instead, you should access the following operations through :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`routines` attribute. + :attr:`datasets` attribute. """ def __init__(self, *args, **kwargs) -> None: @@ -13108,120 +16316,16 @@ def __init__(self, *args, **kwargs) -> None: self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @overload - async def create_or_update( - self, - routine_name: str, - *, - content_type: str = "application/json", - description: Optional[str] = None, - enabled: Optional[bool] = None, - triggers: Optional[dict[str, _models.RoutineTrigger]] = None, - action: Optional[_models.RoutineAction] = None, - authorization: Optional[_models.RoutineAuthorization] = None, - **kwargs: Any - ) -> _models.Routine: - """Create or update a routine. - - Creates a new routine or replaces an existing routine with the supplied definition. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword description: A human-readable description of the routine. Default value is None. - :paramtype description: str - :keyword enabled: Whether the routine is enabled. Default value is None. - :paramtype enabled: bool - :keyword triggers: The triggers configured for the routine. In v1, exactly one trigger entry is - supported. Default value is None. - :paramtype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] - :keyword action: The action executed when the routine fires. Default value is None. - :paramtype action: ~azure.ai.projects.models.RoutineAction - :keyword authorization: Optional authorization configuration for dispatching a newly created - routine. Ignored when updating an existing routine. Default value is None. - :paramtype authorization: ~azure.ai.projects.models.RoutineAuthorization - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create_or_update( - self, routine_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Routine: - """Create or update a routine. - - Creates a new routine or replaces an existing routine with the supplied definition. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create_or_update( - self, routine_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Routine: - """Create or update a routine. - - Creates a new routine or replaces an existing routine with the supplied definition. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine - :raises ~azure.core.exceptions.HttpResponseError: - """ - @distributed_trace_async - async def create_or_update( - self, - routine_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - description: Optional[str] = None, - enabled: Optional[bool] = None, - triggers: Optional[dict[str, _models.RoutineTrigger]] = None, - action: Optional[_models.RoutineAction] = None, - authorization: Optional[_models.RoutineAuthorization] = None, - **kwargs: Any - ) -> _models.Routine: - """Create or update a routine. + async def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerationJob: + """Get a data generation job. - Creates a new routine or replaces an existing routine with the supplied definition. + Retrieves the specified data generation job and its current status. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword description: A human-readable description of the routine. Default value is None. - :paramtype description: str - :keyword enabled: Whether the routine is enabled. Default value is None. - :paramtype enabled: bool - :keyword triggers: The triggers configured for the routine. In v1, exactly one trigger entry is - supported. Default value is None. - :paramtype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] - :keyword action: The action executed when the routine fires. Default value is None. - :paramtype action: ~azure.ai.projects.models.RoutineAction - :keyword authorization: Optional authorization configuration for dispatching a newly created - routine. Ignored when updating an existing routine. Default value is None. - :paramtype authorization: ~azure.ai.projects.models.RoutineAuthorization - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine + :param job_id: The ID of the job. Required. + :type job_id: str + :return: DataGenerationJob. The DataGenerationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DataGenerationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -13232,33 +16336,14 @@ async def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Routine] = kwargs.pop("cls", None) - - if body is _Unset: - body = { - "action": action, - "authorization": authorization, - "description": description, - "enabled": enabled, - "triggers": triggers, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.DataGenerationJob] = kwargs.pop("cls", None) - _request = build_beta_routines_create_or_update_request( - routine_name=routine_name, - content_type=content_type, + _request = build_beta_datasets_get_generation_job_request( + job_id=job_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -13286,30 +16371,120 @@ async def create_or_update( _models.ApiErrorResponse, response, ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DataGenerationJob, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list_generation_jobs( + self, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.DataGenerationJob"]: + """List data generation jobs. + + Returns a list of data generation jobs. + + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of DataGenerationJob + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.DataGenerationJob] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.DataGenerationJob]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_beta_datasets_list_generation_jobs_request( + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.DataGenerationJob], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Routine, response.json()) + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response - return deserialized # type: ignore + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - @distributed_trace_async - async def get(self, routine_name: str, **kwargs: Any) -> _models.Routine: - """Get a routine. + return pipeline_response - Retrieves the specified routine and its current configuration. + return AsyncItemPaged(get_next, extract_data) - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine - :raises ~azure.core.exceptions.HttpResponseError: - """ + async def _create_generation_job_initial( + self, + job: Union[_models.DataGenerationJob, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> AsyncIterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -13318,14 +16493,24 @@ async def get(self, routine_name: str, **kwargs: Any) -> _models.Routine: } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_beta_routines_get_request( - routine_name=routine_name, + content_type = content_type or "application/json" + _content = None + if isinstance(job, (IOBase, bytes)): + _content = job + else: + _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_datasets_create_generation_job_request( + operation_id=operation_id, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -13335,19 +16520,18 @@ async def get(self, routine_name: str, **kwargs: Any) -> _models.Routine: _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = True pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [201]: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -13355,93 +16539,184 @@ async def get(self, routine_name: str, **kwargs: Any) -> _models.Routine: ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Routine, response.json()) + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace_async - async def enable(self, routine_name: str, **kwargs: Any) -> _models.Routine: - """Enable a routine. + @overload + async def begin_create_generation_job( + self, + job: _models.DataGenerationJob, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.DataGenerationJobResult]: + """Create a data generation job. - Enables the specified routine so it can be dispatched. + Submits a new data generation job for asynchronous execution. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine + :param job: The job to create. Required. + :type job: ~azure.ai.projects.models.DataGenerationJob + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns DataGenerationJobResult. The + DataGenerationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.DataGenerationJobResult] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + @overload + async def begin_create_generation_job( + self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.DataGenerationJobResult]: + """Create a data generation job. - cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + Submits a new data generation job for asynchronous execution. - _request = build_beta_routines_enable_request( - routine_name=routine_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + :param job: The job to create. Required. + :type job: JSON + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns DataGenerationJobResult. The + DataGenerationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + @overload + async def begin_create_generation_job( + self, + job: IO[bytes], + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.DataGenerationJobResult]: + """Create a data generation job. - response = pipeline_response.http_response + Submits a new data generation job for asynchronous execution. - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, + :param job: The job to create. Required. + :type job: IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns DataGenerationJobResult. The + DataGenerationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def begin_create_generation_job( + self, + job: Union[_models.DataGenerationJob, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> AsyncLROPoller[_models.DataGenerationJobResult]: + """Create a data generation job. + + Submits a new data generation job for asynchronous execution. + + :param job: The job to create. Is one of the following types: DataGenerationJob, JSON, + IO[bytes] Required. + :type job: ~azure.ai.projects.models.DataGenerationJob or JSON or IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :return: An instance of AsyncLROPoller that returns DataGenerationJobResult. The + DataGenerationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.DataGenerationJobResult] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._create_generation_job_initial( + job=job, + operation_id=operation_id, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs ) - raise HttpResponseError(response=response, model=error) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Routine, response.json()) + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = _deserialize(_models.DataGenerationJobResult, response.json().get("result", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } - return deserialized # type: ignore + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) + else: + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.DataGenerationJobResult].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.DataGenerationJobResult]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) @distributed_trace_async - async def disable(self, routine_name: str, **kwargs: Any) -> _models.Routine: - """Disable a routine. + async def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerationJob: + """Cancel a data generation job. - Disables the specified routine so it no longer runs. + Cancels the specified data generation job if it is still in progress. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine + :param job_id: The ID of the job to cancel. Required. + :type job_id: str + :return: DataGenerationJob. The DataGenerationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DataGenerationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -13455,10 +16730,10 @@ async def disable(self, routine_name: str, **kwargs: Any) -> _models.Routine: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + cls: ClsType[_models.DataGenerationJob] = kwargs.pop("cls", None) - _request = build_beta_routines_disable_request( - routine_name=routine_name, + _request = build_beta_datasets_cancel_generation_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -13492,135 +16767,21 @@ async def disable(self, routine_name: str, **kwargs: Any) -> _models.Routine: if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Routine, response.json()) + deserialized = _deserialize(_models.DataGenerationJob, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def list( - self, - *, - limit: Optional[int] = None, - after: Optional[str] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - **kwargs: Any - ) -> AsyncItemPaged["_models.Routine"]: - """List routines. - - Returns the routines available in the current project. - - :keyword limit: The maximum number of routines to return. Default value is None. - :paramtype limit: int - :keyword after: An opaque continuation token identifying where to resume the list. Prefer - following the ``next_link`` returned by the previous response, which embeds this value. Default - value is None. - :paramtype after: str - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :return: An iterator like instance of Routine - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Routine] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.Routine]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_routines_list_request( - limit=limit, - after=after, - order=order, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Routine], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("next_link") or None, AsyncList(list_of_elem) - - async def get_next(next_link=None): - _request = prepare_request(next_link) - - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - return pipeline_response - - return AsyncItemPaged(get_next, extract_data) - @distributed_trace_async - async def delete(self, routine_name: str, **kwargs: Any) -> None: - """Delete a routine. + async def delete_generation_job(self, job_id: str, **kwargs: Any) -> None: + """Delete a data generation job. - Deletes the specified routine. + Removes the specified data generation job and its associated output. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str + :param job_id: The ID of the job to delete. Required. + :type job_id: str :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -13638,8 +16799,8 @@ async def delete(self, routine_name: str, **kwargs: Any) -> None: cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_routines_delete_request( - routine_name=routine_name, + _request = build_beta_datasets_delete_generation_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -13667,110 +16828,103 @@ async def delete(self, routine_name: str, **kwargs: Any) -> None: if cls: return cls(pipeline_response, None, {}) # type: ignore + +class BetaVoiceAgentsConversationsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`conversations` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @distributed_trace - def list_runs( + def list( self, - routine_name: str, + agent_name: str, *, - filter: Optional[str] = None, limit: Optional[int] = None, - after: Optional[str] = None, order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> AsyncItemPaged["_models.RoutineRun"]: - """List prior runs for a routine. + ) -> AsyncItemPaged["_models.VoiceConversation"]: + """List voice agent conversations. - Returns prior runs recorded for the specified routine. + Returns the conversations persisted for the specified voice agent endpoint. Conversations are + present when the session's effective ``store`` setting is ``true``, whether inherited from the + agent definition or enabled by the WebSocket session override. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :keyword filter: An optional MLflow search-runs filter expression applied within the routine's - experiment. Default value is None. - :paramtype filter: str - :keyword limit: The maximum number of runs to return. Default value is None. + :param agent_name: The name of the agent. Required. + :type agent_name: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. :paramtype limit: int - :keyword after: An opaque continuation token identifying where to resume the list. Prefer - following the ``next_link`` returned by the previous response, which embeds this value. Default - value is None. - :paramtype after: str :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for ascending order and``desc`` for descending order. Known values are: "asc" and "desc". Default value is None. :paramtype order: str or ~azure.ai.projects.models.PageOrder - :return: An iterator like instance of RoutineRun - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.RoutineRun] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.RoutineRun]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_routines_list_runs_request( - routine_name=routine_name, - filter=filter, - limit=limit, - after=after, - order=order, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceConversation + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.VoiceConversation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + cls: ClsType[List[_models.VoiceConversation]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + _request = build_beta_voice_agents_conversations_list_request( + agent_name=agent_name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.RoutineRun], + List[_models.VoiceConversation], deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("next_link") or None, AsyncList(list_of_elem) + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - async def get_next(next_link=None): - _request = prepare_request(next_link) + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access @@ -13790,94 +16944,19 @@ async def get_next(next_link=None): return AsyncItemPaged(get_next, extract_data) - @overload - async def dispatch( - self, - routine_name: str, - *, - content_type: str = "application/json", - payload: Optional[_models.RoutineDispatchPayload] = None, - **kwargs: Any - ) -> _models.DispatchRoutineResult: - """Queue an asynchronous routine dispatch. - - Queues an asynchronous dispatch for the specified routine. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword payload: A direct action-input override sent downstream when testing a routine. - Default value is None. - :paramtype payload: ~azure.ai.projects.models.RoutineDispatchPayload - :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DispatchRoutineResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def dispatch( - self, routine_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.DispatchRoutineResult: - """Queue an asynchronous routine dispatch. - - Queues an asynchronous dispatch for the specified routine. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DispatchRoutineResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def dispatch( - self, routine_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.DispatchRoutineResult: - """Queue an asynchronous routine dispatch. - - Queues an asynchronous dispatch for the specified routine. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DispatchRoutineResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - @distributed_trace_async - async def dispatch( - self, - routine_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - payload: Optional[_models.RoutineDispatchPayload] = None, - **kwargs: Any - ) -> _models.DispatchRoutineResult: - """Queue an asynchronous routine dispatch. + async def get(self, agent_name: str, conversation_id: str, **kwargs: Any) -> _models.VoiceConversation: + """Get a voice agent conversation. - Queues an asynchronous dispatch for the specified routine. + Retrieves a single conversation recorded for the specified voice agent endpoint by its id. + Returns ``404`` when the conversation was not persisted (``store = false``) or does not exist. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword payload: A direct action-input override sent downstream when testing a routine. - Default value is None. - :paramtype payload: ~azure.ai.projects.models.RoutineDispatchPayload - :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DispatchRoutineResult + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to retrieve. Required. + :type conversation_id: str + :return: VoiceConversation. The VoiceConversation is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceConversation :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -13888,27 +16967,15 @@ async def dispatch( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DispatchRoutineResult] = kwargs.pop("cls", None) - - if body is _Unset: - body = {"payload": payload} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.VoiceConversation] = kwargs.pop("cls", None) - _request = build_beta_routines_dispatch_request( - routine_name=routine_name, - content_type=content_type, + _request = build_beta_voice_agents_conversations_get_request( + agent_name=agent_name, + conversation_id=conversation_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -13941,43 +17008,116 @@ async def dispatch( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DispatchRoutineResult, response.json()) + deserialized = _deserialize(_models.VoiceConversation, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + @distributed_trace_async + async def delete(self, agent_name: str, conversation_id: str, **kwargs: Any) -> None: + """Delete a voice agent conversation. -class BetaSchedulesOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + Deletes a conversation and all of its stored data — responses, items, and any audio (cascade). + This is the customer's explicit data-deletion control for voice conversations. - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`schedules` attribute. - """ + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to delete. Required. + :type conversation_id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @distributed_trace_async - async def delete(self, schedule_id: str, **kwargs: Any) -> None: - """Delete a schedule. + cls: ClsType[None] = kwargs.pop("cls", None) - Deletes the specified schedule resource. + _request = build_beta_voice_agents_conversations_delete_request( + agent_name=agent_name, + conversation_id=conversation_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :return: None - :rtype: None + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace + def list_responses( + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.VoiceResponse"]: + """List responses in a voice agent conversation. + + Returns a paged collection of the responses (model inference turns) recorded for the specified + conversation. The per-response ``output`` projection may be omitted here; use the + response-items route for the canonical paged output. Returns ``404`` when the conversation was + not persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose responses are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceResponse + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.VoiceResponse] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.VoiceResponse]] = kwargs.pop("cls", None) + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -13986,46 +17126,74 @@ async def delete(self, schedule_id: str, **kwargs: Any) -> None: } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + def prepare_request(_continuation_token=None): - cls: ClsType[None] = kwargs.pop("cls", None) + _request = build_beta_voice_agents_conversations_list_responses_request( + agent_name=agent_name, + conversation_id=conversation_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - _request = build_beta_schedules_delete_request( - schedule_id=schedule_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.VoiceResponse], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - response = pipeline_response.http_response + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if cls: - return cls(pipeline_response, None, {}) # type: ignore + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) @distributed_trace_async - async def get(self, schedule_id: str, **kwargs: Any) -> _models.Schedule: - """Get a schedule. + async def get_response( + self, agent_name: str, conversation_id: str, response_id: str, **kwargs: Any + ) -> _models.VoiceResponse: + """Get a voice agent conversation response. - Retrieves the specified schedule resource. + Retrieves a single response from the specified conversation by its id, including its ``output`` + items, ``usage``, and status. Returns ``404`` when the conversation or response was not + persisted (``store = false``). - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :return: Schedule. The Schedule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Schedule + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response to retrieve. Required. + :type response_id: str + :return: VoiceResponse. The VoiceResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceResponse :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14039,10 +17207,12 @@ async def get(self, schedule_id: str, **kwargs: Any) -> _models.Schedule: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Schedule] = kwargs.pop("cls", None) + cls: ClsType[_models.VoiceResponse] = kwargs.pop("cls", None) - _request = build_beta_schedules_get_request( - schedule_id=schedule_id, + _request = build_beta_voice_agents_conversations_get_response_request( + agent_name=agent_name, + conversation_id=conversation_id, + response_id=response_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -14067,12 +17237,16 @@ async def get(self, schedule_id: str, **kwargs: Any) -> _models.Schedule: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Schedule, response.json()) + deserialized = _deserialize(_models.VoiceResponse, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -14080,30 +17254,53 @@ async def get(self, schedule_id: str, **kwargs: Any) -> _models.Schedule: return deserialized # type: ignore @distributed_trace - def list( + def list_response_items( self, + agent_name: str, + conversation_id: str, + response_id: str, *, - type: Optional[Union[str, _models.ScheduleTaskType]] = None, - enabled: Optional[bool] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> AsyncItemPaged["_models.Schedule"]: - """List schedules. + ) -> AsyncItemPaged["_models.RealtimeConversationItem"]: + """List items produced by a voice agent conversation response. - Returns schedules that match the supplied type and enabled filters. + Returns a paged collection of the output items produced by a specific response (the response's + output projection). For the complete ordered conversation history — including user input and + client-created tool outputs — use the conversation items route instead. Returns ``404`` when + the conversation or response was not persisted (``store = false``). - :keyword type: Filter by the type of schedule. Known values are: "Evaluation" and "Insight". + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response whose output items are listed. Required. + :type response_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. - :paramtype type: str or ~azure.ai.projects.models.ScheduleTaskType - :keyword enabled: Filter by the enabled status. Default value is None. - :paramtype enabled: bool - :return: An iterator like instance of Schedule - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.Schedule] + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.RealtimeConversationItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.Schedule]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.RealtimeConversationItem]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -14113,60 +17310,141 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: + def prepare_request(_continuation_token=None): - _request = build_beta_schedules_list_request( - type=type, - enabled=enabled, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _request = build_beta_voice_agents_conversations_list_response_items_request( + agent_name=agent_name, + conversation_id=conversation_id, + response_id=response_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.RealtimeConversationItem], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, AsyncList(list_of_elem) + + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace + def list_items( + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> AsyncItemPaged["_models.RealtimeConversationItem"]: + """List items in a voice agent conversation. + + Returns a paged collection of items — the complete ordered conversation history, including user + input, assistant output, and client-created tool outputs (transcripts + tool events). Returns + ``404`` when the conversation was not persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose items are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.RealtimeConversationItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RealtimeConversationItem]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + _request = build_beta_voice_agents_conversations_list_items_request( + agent_name=agent_name, + conversation_id=conversation_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.Schedule], - deserialized.get("value", []), + List[_models.RealtimeConversationItem], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + return deserialized.get("last_id") or None, AsyncList(list_of_elem) - async def get_next(next_link=None): - _request = prepare_request(next_link) + async def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access @@ -14176,87 +17454,37 @@ async def get_next(next_link=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) return pipeline_response return AsyncItemPaged(get_next, extract_data) - @overload - async def create_or_update( - self, schedule_id: str, schedule: _models.Schedule, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Schedule: - """Create or update a schedule. - - Creates a new schedule or updates an existing schedule with the supplied definition. - - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :param schedule: The resource instance. Required. - :type schedule: ~azure.ai.projects.models.Schedule - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: Schedule. The Schedule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Schedule - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create_or_update( - self, schedule_id: str, schedule: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Schedule: - """Create or update a schedule. - - Creates a new schedule or updates an existing schedule with the supplied definition. - - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :param schedule: The resource instance. Required. - :type schedule: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: Schedule. The Schedule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Schedule - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create_or_update( - self, schedule_id: str, schedule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Schedule: - """Create or update a schedule. - - Creates a new schedule or updates an existing schedule with the supplied definition. - - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :param schedule: The resource instance. Required. - :type schedule: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: Schedule. The Schedule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Schedule - :raises ~azure.core.exceptions.HttpResponseError: - """ - @distributed_trace_async - async def create_or_update( - self, schedule_id: str, schedule: Union[_models.Schedule, JSON, IO[bytes]], **kwargs: Any - ) -> _models.Schedule: - """Create or update a schedule. + async def get_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.RealtimeConversationItem: + """Get a voice agent conversation item. - Creates a new schedule or updates an existing schedule with the supplied definition. + Retrieves a single item from the specified conversation by its id, including its transcript. An + ``input_audio``/``output_audio`` content part indicates that audio is available for the item; + the canonical per-item audio metadata is the ``/items/{item_id}/audio`` resource, and the bytes + are streamed by ``/items/{item_id}/audio/content``. Returns ``404`` when the conversation or + item was not persisted (``store = false``). - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :param schedule: The resource instance. Is one of the following types: Schedule, JSON, - IO[bytes] Required. - :type schedule: ~azure.ai.projects.models.Schedule or JSON or IO[bytes] - :return: Schedule. The Schedule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Schedule + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item to retrieve. Required. + :type item_id: str + :return: RealtimeConversationItem. The RealtimeConversationItem is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.RealtimeConversationItem :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14267,24 +17495,16 @@ async def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Schedule] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(schedule, (IOBase, bytes)): - _content = schedule - else: - _content = json.dumps(schedule, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.RealtimeConversationItem] = kwargs.pop("cls", None) - _request = build_beta_schedules_create_or_update_request( - schedule_id=schedule_id, - content_type=content_type, + _request = build_beta_voice_agents_conversations_get_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -14301,19 +17521,23 @@ async def create_or_update( response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: await response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Schedule, response.json()) + deserialized = _deserialize(_models.RealtimeConversationItem, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -14321,17 +17545,27 @@ async def create_or_update( return deserialized # type: ignore @distributed_trace_async - async def get_run(self, schedule_id: str, run_id: str, **kwargs: Any) -> _models.ScheduleRun: - """Get a schedule run. - - Retrieves the specified run for a schedule. + async def get_audio_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceAudioItem: + """Get a voice agent conversation item's audio metadata. + + Returns metadata for a single conversation item's audio segment, including the common playback + facts (role, format/codec, sample rate, channels, offset, duration) for both Foundry-managed + and bring-your-own-storage (BYOS) recordings; for BYOS the response additionally includes + ``blob_uri``, the URI of the recording in the customer's own storage (no SAS) that the customer + downloads with their own credentials. Requires the conversation to have persisted audio + (``store = true``); returns ``404`` when the conversation, item, or its audio was not + persisted. - :param schedule_id: The unique identifier of the schedule. Required. - :type schedule_id: str - :param run_id: The unique identifier of the schedule run. Required. - :type run_id: str - :return: ScheduleRun. The ScheduleRun is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ScheduleRun + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio metadata is retrieved. Required. + :type item_id: str + :return: VoiceAudioItem. The VoiceAudioItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceAudioItem :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14345,11 +17579,12 @@ async def get_run(self, schedule_id: str, run_id: str, **kwargs: Any) -> _models _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.ScheduleRun] = kwargs.pop("cls", None) + cls: ClsType[_models.VoiceAudioItem] = kwargs.pop("cls", None) - _request = build_beta_schedules_get_run_request( - schedule_id=schedule_id, - run_id=run_id, + _request = build_beta_voice_agents_conversations_get_audio_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -14380,151 +17615,37 @@ async def get_run(self, schedule_id: str, run_id: str, **kwargs: Any) -> _models ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.ScheduleRun, response.json()) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - @distributed_trace - def list_runs( - self, - schedule_id: str, - *, - type: Optional[Union[str, _models.ScheduleTaskType]] = None, - enabled: Optional[bool] = None, - **kwargs: Any - ) -> AsyncItemPaged["_models.ScheduleRun"]: - """List schedule runs. - - Returns schedule runs that match the supplied filters. - - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :keyword type: Filter by the type of schedule. Known values are: "Evaluation" and "Insight". - Default value is None. - :paramtype type: str or ~azure.ai.projects.models.ScheduleTaskType - :keyword enabled: Filter by the enabled status. Default value is None. - :paramtype enabled: bool - :return: An iterator like instance of ScheduleRun - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.ScheduleRun] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.ScheduleRun]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_schedules_list_runs_request( - schedule_id=schedule_id, - type=type, - enabled=enabled, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.ScheduleRun], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, AsyncList(list_of_elem) - - async def get_next(next_link=None): - _request = prepare_request(next_link) - - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - return pipeline_response - - return AsyncItemPaged(get_next, extract_data) - - -class BetaSkillsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceAudioItem, response.json()) - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`skills` attribute. - """ + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + return deserialized # type: ignore @distributed_trace_async - async def get(self, name: str, **kwargs: Any) -> _models.SkillDetails: - """Retrieve a skill. + async def download_audio_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> AsyncIterator[bytes]: + """Stream a voice agent conversation item's audio. - Retrieves the specified skill and its current configuration. + Streams a single conversation item's audio as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the item's ``/audio`` + metadata route — so this route returns ``409 Conflict`` for BYOS recordings. Returns ``404`` + when the conversation, item, or its audio was not persisted (``store = false``). - :param name: The unique name of the skill. Required. - :type name: str - :return: SkillDetails. The SkillDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillDetails + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio is streamed. Required. + :type item_id: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14538,10 +17659,12 @@ async def get(self, name: str, **kwargs: Any) -> _models.SkillDetails: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.SkillDetails] = kwargs.pop("cls", None) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_beta_skills_get_request( - name=name, + _request = build_beta_voice_agents_conversations_download_audio_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -14552,7 +17675,7 @@ async def get(self, name: str, **kwargs: Any) -> _models.SkillDetails: _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -14572,52 +17695,39 @@ async def get(self, name: str, **kwargs: Any) -> _models.SkillDetails: ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.SkillDetails, response.json()) + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace - def list( - self, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> AsyncItemPaged["_models.SkillDetails"]: - """List skills. + @distributed_trace_async + async def get_generated_audio_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceGeneratedAudioItem: + """Get a voice agent conversation item's generated audio metadata. - Returns the skills available in the current project. + Returns metadata for a conversation item's generated audio. This subordinate artifact is + separate from the canonical heard-audio segment and exists only when playback was interrupted + and the service rendered more audio than the listener heard, including when the response ends + as cancelled. Returns ``404`` when the conversation or item was not persisted, or when no + generated audio exists beyond the heard segment. - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of SkillDetails - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.SkillDetails] + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio metadata is retrieved. + Required. + :type item_id: str + :return: VoiceGeneratedAudioItem. The VoiceGeneratedAudioItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceGeneratedAudioItem :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.SkillDetails]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -14626,132 +17736,77 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): - - _request = build_beta_skills_list_request( - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request - - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.SkillDetails], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, AsyncList(list_of_elem) - - async def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) - - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - return pipeline_response - - return AsyncItemPaged(get_next, extract_data) - - @overload - async def update( - self, name: str, *, default_version: str, content_type: str = "application/json", **kwargs: Any - ) -> _models.SkillDetails: - """Update a skill. + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - Modifies the specified skill's configuration. + cls: ClsType[_models.VoiceGeneratedAudioItem] = kwargs.pop("cls", None) - :param name: The name of the skill to update. Required. - :type name: str - :keyword default_version: The version identifier that the skill should point to. When set, the - skill's default version will resolve to this version instead of the latest. Required. - :paramtype default_version: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: SkillDetails. The SkillDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + _request = build_beta_voice_agents_conversations_get_generated_audio_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - @overload - async def update( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.SkillDetails: - """Update a skill. + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - Modifies the specified skill's configuration. + response = pipeline_response.http_response - :param name: The name of the skill to update. Required. - :type name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: SkillDetails. The SkillDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - @overload - async def update( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.SkillDetails: - """Update a skill. + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceGeneratedAudioItem, response.json()) - Modifies the specified skill's configuration. + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore - :param name: The name of the skill to update. Required. - :type name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: SkillDetails. The SkillDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + return deserialized # type: ignore @distributed_trace_async - async def update( - self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, default_version: str = _Unset, **kwargs: Any - ) -> _models.SkillDetails: - """Update a skill. + async def download_generated_audio_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> AsyncIterator[bytes]: + """Stream a voice agent conversation item's generated audio. - Modifies the specified skill's configuration. + Streams a conversation item's generated audio as a WAV (``audio/wav``) byte stream through the + service. This subordinate artifact exists only when playback was interrupted and the service + rendered more audio than the listener heard, including when the response ends as cancelled. + This route serves Foundry-managed storage only. For bring-your-own-storage (BYOS) recordings + the bytes are not proxied, so this route returns ``409 Conflict``. Returns ``404`` when the + conversation or item was not persisted, or when no generated audio exists beyond the heard + segment. - :param name: The name of the skill to update. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword default_version: The version identifier that the skill should point to. When set, the - skill's default version will resolve to this version instead of the latest. Required. - :paramtype default_version: str - :return: SkillDetails. The SkillDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillDetails + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio is streamed. Required. + :type item_id: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14762,29 +17817,16 @@ async def update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SkillDetails] = kwargs.pop("cls", None) - - if body is _Unset: - if default_version is _Unset: - raise TypeError("missing required argument: default_version") - body = {"default_version": default_version} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_beta_skills_update_request( - name=name, - content_type=content_type, + _request = build_beta_voice_agents_conversations_download_generated_audio_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -14794,7 +17836,7 @@ async def update( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -14814,26 +17856,40 @@ async def update( ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.SkillDetails, response.json()) + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace_async - async def delete(self, name: str, **kwargs: Any) -> _models.DeleteSkillResult: - """Delete a skill. - - Removes the specified skill and its associated versions. + async def get_audio(self, agent_name: str, conversation_id: str, **kwargs: Any) -> _models.VoiceRecording: + """Get a voice agent conversation's merged recording metadata. + + Returns metadata for the whole-call merged stereo recording (user audio on the left channel, + agent audio on the right). The common metadata (format, sample rate, channels, channel layout, + duration) is returned for both Foundry-managed and bring-your-own-storage (BYOS) recordings; + for BYOS the response additionally includes ``blob_uri``, the URI of the recording in the + customer's own storage (no SAS) that the customer downloads with their own credentials. The + recording is built once from the per-turn segments after persistence finalization succeeds. + While the conversation is ``in_progress``, this route returns retriable ``409 Conflict`` with + ``error.code = recording_not_ready`` and a ``Retry-After`` header when retry guidance is + available. When the conversation is ``failed``, it returns terminal ``409 Conflict`` with + ``error.code = recording_unavailable``. For a ``completed`` conversation, metadata is available + subject to the existing BYOS behavior. Requires the conversation to have persisted audio + (``store = true``); otherwise returns ``404``. - :param name: The unique name of the skill. Required. - :type name: str - :return: DeleteSkillResult. The DeleteSkillResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DeleteSkillResult + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording metadata is + retrieved. Required. + :type conversation_id: str + :return: VoiceRecording. The VoiceRecording is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceRecording :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14847,10 +17903,11 @@ async def delete(self, name: str, **kwargs: Any) -> _models.DeleteSkillResult: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DeleteSkillResult] = kwargs.pop("cls", None) + cls: ClsType[_models.VoiceRecording] = kwargs.pop("cls", None) - _request = build_beta_skills_delete_request( - name=name, + _request = build_beta_voice_agents_conversations_get_audio_request( + agent_name=agent_name, + conversation_id=conversation_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -14884,107 +17941,35 @@ async def delete(self, name: str, **kwargs: Any) -> _models.DeleteSkillResult: if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DeleteSkillResult, response.json()) + deserialized = _deserialize(_models.VoiceRecording, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - async def create( - self, - name: str, - *, - content_type: str = "application/json", - inline_content: Optional[_models.SkillInlineContent] = None, - default: Optional[bool] = None, - **kwargs: Any - ) -> _models.SkillVersion: - """Create a new version of a skill. - - Creates a new version of a skill. If the skill does not exist, it will be created. - - :param name: The name of the skill. If the skill does not exist, it will be created. Required. - :type name: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword inline_content: Inline skill content for simple skills without file uploads. - Foundry-specific extension. Default value is None. - :paramtype inline_content: ~azure.ai.projects.models.SkillInlineContent - :keyword default: Whether to set this version as the default. Default value is None. - :paramtype default: bool - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.SkillVersion: - """Create a new version of a skill. - - Creates a new version of a skill. If the skill does not exist, it will be created. - - :param name: The name of the skill. If the skill does not exist, it will be created. Required. - :type name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def create( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.SkillVersion: - """Create a new version of a skill. - - Creates a new version of a skill. If the skill does not exist, it will be created. - - :param name: The name of the skill. If the skill does not exist, it will be created. Required. - :type name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - @distributed_trace_async - async def create( - self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - inline_content: Optional[_models.SkillInlineContent] = None, - default: Optional[bool] = None, - **kwargs: Any - ) -> _models.SkillVersion: - """Create a new version of a skill. - - Creates a new version of a skill. If the skill does not exist, it will be created. + async def download_audio(self, agent_name: str, conversation_id: str, **kwargs: Any) -> AsyncIterator[bytes]: + """Stream a voice agent conversation's merged recording. + + Streams the whole-call merged stereo recording as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the metadata route — so this + route returns ``409 Conflict`` for BYOS recordings. While the conversation is ``in_progress``, + this route returns retriable ``409 Conflict`` with ``error.code = recording_not_ready`` and a + ``Retry-After`` header when retry guidance is available. When the conversation is ``failed``, + it returns terminal ``409 Conflict`` with ``error.code = recording_unavailable``. For a + ``completed`` conversation, content is available subject to the existing BYOS behavior. A + conversation without persisted audio (``store = false``) returns ``404``. - :param name: The name of the skill. If the skill does not exist, it will be created. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword inline_content: Inline skill content for simple skills without file uploads. - Foundry-specific extension. Default value is None. - :paramtype inline_content: ~azure.ai.projects.models.SkillInlineContent - :keyword default: Whether to set this version as the default. Default value is None. - :paramtype default: bool - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording is streamed. + Required. + :type conversation_id: str + :return: AsyncIterator[bytes] + :rtype: AsyncIterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14995,27 +17980,15 @@ async def create( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) - - if body is _Unset: - body = {"default": default, "inline_content": inline_content} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_beta_skills_create_request( - name=name, - content_type=content_type, + _request = build_beta_voice_agents_conversations_download_audio_request( + agent_name=agent_name, + conversation_id=conversation_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -15025,7 +17998,7 @@ async def create( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -15045,63 +18018,118 @@ async def create( ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.SkillVersion, response.json()) + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore + +class BetaVoiceAgentsTelephonyOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s + :attr:`telephony` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @overload - async def create_from_files( - self, name: str, content: _models.CreateSkillVersionFromFilesBody, **kwargs: Any - ) -> _models.SkillVersion: - """Create a skill version from uploaded files. + async def create_binding( + self, + agent_name: str, + telephony_binding: _models.CreateTelephonyBindingRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. - Creates a new version of a skill from uploaded files via multipart form data. + Creates a telephony binding for the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param content: The multipart request content. Required. - :type content: ~azure.ai.projects.models.CreateSkillVersionFromFilesBody - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param telephony_binding: The provider-specific binding to create. Required. + :type telephony_binding: ~azure.ai.projects.models.CreateTelephonyBindingRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def create_from_files(self, name: str, content: JSON, **kwargs: Any) -> _models.SkillVersion: - """Create a skill version from uploaded files. + async def create_binding( + self, agent_name: str, telephony_binding: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. - Creates a new version of a skill from uploaded files via multipart form data. + Creates a telephony binding for the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param content: The multipart request content. Required. - :type content: JSON - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param telephony_binding: The provider-specific binding to create. Required. + :type telephony_binding: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_binding( + self, agent_name: str, telephony_binding: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param telephony_binding: The provider-specific binding to create. Required. + :type telephony_binding: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def create_from_files( - self, name: str, content: Union[_models.CreateSkillVersionFromFilesBody, JSON], **kwargs: Any - ) -> _models.SkillVersion: - """Create a skill version from uploaded files. + async def create_binding( + self, + agent_name: str, + telephony_binding: Union[_models.CreateTelephonyBindingRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. - Creates a new version of a skill from uploaded files via multipart form data. + Creates a telephony binding for the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param content: The multipart request content. Is either a CreateSkillVersionFromFilesBody type - or a JSON type. Required. - :type content: ~azure.ai.projects.models.CreateSkillVersionFromFilesBody or JSON - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param telephony_binding: The provider-specific binding to create. Is one of the following + types: CreateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type telephony_binding: ~azure.ai.projects.models.CreateTelephonyBindingRequest or JSON or + IO[bytes] + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -15112,20 +18140,24 @@ async def create_from_files( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) - _body = content.as_dict() if isinstance(content, _Model) else content - _file_fields: list[str] = ["files"] - _data_fields: list[str] = ["default"] - _files = prepare_multipart_form_data(_body, _file_fields, _data_fields) + content_type = content_type or "application/json" + _content = None + if isinstance(telephony_binding, (IOBase, bytes)): + _content = telephony_binding + else: + _content = json.dumps(telephony_binding, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_skills_create_from_files_request( - name=name, + _request = build_beta_voice_agents_telephony_create_binding_request( + agent_name=agent_name, + content_type=content_type, api_version=self._config.api_version, - files=_files, + content=_content, headers=_headers, params=_params, ) @@ -15142,7 +18174,7 @@ async def create_from_files( response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [201]: if _stream: try: await response.read() # Load the body in memory and close the socket @@ -15155,32 +18187,43 @@ async def create_from_files( ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.SkillVersion, response.json()) + deserialized = _deserialize(_models.TelephonyBinding, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace - def list_versions( + def list_bindings( self, - name: str, + agent_name: str, *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyBindingStatus]] = None, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, before: Optional[str] = None, **kwargs: Any - ) -> AsyncItemPaged["_models.SkillVersion"]: - """List skill versions. + ) -> AsyncItemPaged["_models.TelephonyBindingListItem"]: + """List agent telephony bindings. - Returns the available versions for the specified skill. + Returns the telephony bindings owned by the voice agent named in the path. - :param name: The name of the skill to list versions for. Required. - :type name: str + :param agent_name: The name of the voice agent whose bindings are listed. Required. + :type agent_name: str + :keyword provider: Filters bindings by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters bindings by lifecycle status. Known values are: "active" and + "suspended". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyBindingStatus :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20. Default value is None. @@ -15195,14 +18238,15 @@ def list_versions( subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. :paramtype before: str - :return: An iterator like instance of SkillVersion - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.SkillVersion] + :return: An iterator like instance of TelephonyBindingListItem + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.TelephonyBindingListItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.SkillVersion]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.TelephonyBindingListItem]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -15214,8 +18258,10 @@ def list_versions( def prepare_request(_continuation_token=None): - _request = build_beta_skills_list_versions_request( - name=name, + _request = build_beta_voice_agents_telephony_list_bindings_request( + agent_name=agent_name, + provider=provider, + status=status, limit=limit, order=order, after=_continuation_token, @@ -15233,7 +18279,7 @@ def prepare_request(_continuation_token=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.SkillVersion], + List[_models.TelephonyBindingListItem], deserialized.get("data", []), ) if cls: @@ -15262,17 +18308,17 @@ async def get_next(_continuation_token=None): return AsyncItemPaged(get_next, extract_data) @distributed_trace_async - async def get_version(self, name: str, version: str, **kwargs: Any) -> _models.SkillVersion: - """Retrieve a specific version of a skill. + async def get_binding(self, agent_name: str, binding_id: str, **kwargs: Any) -> _models.TelephonyBinding: + """Get an agent telephony binding. - Retrieves the specified version of a skill by name and version identifier. + Retrieves a telephony binding owned by the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param version: The version identifier to retrieve. Required. - :type version: str - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -15286,11 +18332,11 @@ async def get_version(self, name: str, version: str, **kwargs: Any) -> _models.S _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) - _request = build_beta_skills_get_version_request( - name=name, - version=version, + _request = build_beta_voice_agents_telephony_get_binding_request( + agent_name=agent_name, + binding_id=binding_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -15321,166 +18367,149 @@ async def get_version(self, name: str, version: str, **kwargs: Any) -> _models.S ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.SkillVersion, response.json()) + deserialized = _deserialize(_models.TelephonyBinding, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace_async - async def download(self, name: str, **kwargs: Any) -> AsyncIterator[bytes]: - """Download the zip content for the default version of a skill. + @overload + async def update_binding( + self, + agent_name: str, + binding_id: str, + body: _models.UpdateTelephonyBindingRequest, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. - Downloads the zip content for the default version of a skill. + Updates a telephony binding owned by the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :return: AsyncIterator[bytes] - :rtype: AsyncIterator[bytes] + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - - _request = build_beta_skills_download_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - response_headers = {} - response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - - return deserialized # type: ignore - - @distributed_trace_async - async def download_version(self, name: str, version: str, **kwargs: Any) -> AsyncIterator[bytes]: - """Download the zip content for a specific version of a skill. + @overload + async def update_binding( + self, + agent_name: str, + binding_id: str, + body: JSON, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. - Downloads the zip content for a specific version of a skill. + Updates a telephony binding owned by the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param version: The version to download content for. Required. - :type version: str - :return: AsyncIterator[bytes] - :rtype: AsyncIterator[bytes] + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - - _request = build_beta_skills_download_version_request( - name=name, - version=version, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - response_headers = {} - response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + @overload + async def update_binding( + self, + agent_name: str, + binding_id: str, + body: IO[bytes], + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + Updates a telephony binding owned by the voice agent named in the path. - return deserialized # type: ignore + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace_async - async def delete_version(self, name: str, version: str, **kwargs: Any) -> _models.DeleteSkillVersionResult: - """Delete a specific version of a skill. + async def update_binding( + self, + agent_name: str, + binding_id: str, + body: Union[_models.UpdateTelephonyBindingRequest, JSON, IO[bytes]], + *, + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. - Removes the specified version of a skill. + Updates a telephony binding owned by the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param version: The version identifier to delete. Required. - :type version: str - :return: DeleteSkillVersionResult. The DeleteSkillVersionResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.DeleteSkillVersionResult + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Is one of the following types: + UpdateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest or JSON or IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -15491,15 +18520,27 @@ async def delete_version(self, name: str, version: str, **kwargs: Any) -> _model } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DeleteSkillVersionResult] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) - _request = build_beta_skills_delete_version_request( - name=name, - version=version, + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_voice_agents_telephony_update_binding_request( + agent_name=agent_name, + binding_id=binding_id, + etag=etag, + match_condition=match_condition, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -15529,44 +18570,37 @@ async def delete_version(self, name: str, version: str, **kwargs: Any) -> _model ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DeleteSkillVersionResult, response.json()) + deserialized = _deserialize(_models.TelephonyBinding, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - -class BetaDatasetsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`datasets` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore @distributed_trace_async - async def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerationJob: - """Get a data generation job. + async def delete_binding( + self, agent_name: str, binding_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any + ) -> None: + """Delete an agent telephony binding. - Retrieves the specified data generation job and its current status. + Deletes a telephony binding owned by the voice agent named in the path. - :param job_id: The ID of the job. Required. - :type job_id: str - :return: DataGenerationJob. The DataGenerationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DataGenerationJob + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -15580,10 +18614,13 @@ async def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGe _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DataGenerationJob] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_datasets_get_generation_job_request( - job_id=job_id, + _request = build_beta_voice_agents_telephony_delete_binding_request( + agent_name=agent_name, + binding_id=binding_id, + etag=etag, + match_condition=match_condition, api_version=self._config.api_version, headers=_headers, params=_params, @@ -15593,20 +18630,14 @@ async def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGe } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -15614,32 +18645,41 @@ async def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGe ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.DataGenerationJob, response.json()) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - - return deserialized # type: ignore + return cls(pipeline_response, None, {}) # type: ignore @distributed_trace - def list_generation_jobs( + def list_calls( self, + agent_name: str, *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyCallStatus]] = None, + started_after_time: Optional[datetime.datetime] = None, + started_before_time: Optional[datetime.datetime] = None, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, before: Optional[str] = None, **kwargs: Any - ) -> AsyncItemPaged["_models.DataGenerationJob"]: - """List data generation jobs. + ) -> AsyncItemPaged["_models.TelephonyCallSummary"]: + """List agent telephony calls. - Returns a list of data generation jobs. + Returns the durable inbound call history for the voice agent named in the path. + :param agent_name: The name of the voice agent whose calls are listed. Required. + :type agent_name: str + :keyword provider: Filters calls by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters calls by lifecycle status. Known values are: "in_progress", "success", + and "failed". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyCallStatus + :keyword started_after_time: Includes calls that started at or after this Unix timestamp in + seconds. Default value is None. + :paramtype started_after_time: ~datetime.datetime + :keyword started_before_time: Includes calls that started at or before this Unix timestamp in + seconds. Default value is None. + :paramtype started_before_time: ~datetime.datetime :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20. Default value is None. @@ -15654,14 +18694,14 @@ def list_generation_jobs( subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. :paramtype before: str - :return: An iterator like instance of DataGenerationJob - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.DataGenerationJob] + :return: An iterator like instance of TelephonyCallSummary + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.TelephonyCallSummary] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.DataGenerationJob]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.TelephonyCallSummary]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -15673,7 +18713,12 @@ def list_generation_jobs( def prepare_request(_continuation_token=None): - _request = build_beta_datasets_list_generation_jobs_request( + _request = build_beta_voice_agents_telephony_list_calls_request( + agent_name=agent_name, + provider=provider, + status=status, + started_after_time=started_after_time, + started_before_time=started_before_time, limit=limit, order=order, after=_continuation_token, @@ -15691,7 +18736,7 @@ def prepare_request(_continuation_token=None): async def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.DataGenerationJob], + List[_models.TelephonyCallSummary], deserialized.get("data", []), ) if cls: @@ -15719,13 +18764,20 @@ async def get_next(_continuation_token=None): return AsyncItemPaged(get_next, extract_data) - async def _create_generation_job_initial( - self, - job: Union[_models.DataGenerationJob, JSON, IO[bytes]], - *, - operation_id: Optional[str] = None, - **kwargs: Any - ) -> AsyncIterator[bytes]: + @distributed_trace_async + async def get_call(self, agent_name: str, call_id: str, **kwargs: Any) -> _models.TelephonyCallRecord: + """Get an agent telephony call. + + Retrieves a durable inbound call record owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the call record. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -15734,24 +18786,15 @@ async def _create_generation_job_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(job, (IOBase, bytes)): - _content = job - else: - _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) - _request = build_beta_datasets_create_generation_job_request( - operation_id=operation_id, - content_type=content_type, + _request = build_beta_voice_agents_telephony_get_call_request( + agent_name=agent_name, + call_id=call_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -15761,18 +18804,19 @@ async def _create_generation_job_initial( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -15780,184 +18824,106 @@ async def _create_generation_job_initial( ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @overload - async def begin_create_generation_job( - self, - job: _models.DataGenerationJob, - *, - operation_id: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> AsyncLROPoller[_models.DataGenerationJobResult]: - """Create a data generation job. + async def transfer_call( + self, agent_name: str, call_id: str, *, target: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. - Submits a new data generation job for asynchronous execution. + Transfers an active inbound call to a configured target for the voice agent named in the path. - :param job: The job to create. Required. - :type job: ~azure.ai.projects.models.DataGenerationJob - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns DataGenerationJobResult. The - DataGenerationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def begin_create_generation_job( - self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.DataGenerationJobResult]: - """Create a data generation job. + async def transfer_call( + self, agent_name: str, call_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. - Submits a new data generation job for asynchronous execution. + Transfers an active inbound call to a configured target for the voice agent named in the path. - :param job: The job to create. Required. - :type job: JSON - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns DataGenerationJobResult. The - DataGenerationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def begin_create_generation_job( - self, - job: IO[bytes], - *, - operation_id: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> AsyncLROPoller[_models.DataGenerationJobResult]: - """Create a data generation job. + async def transfer_call( + self, agent_name: str, call_id: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. - Submits a new data generation job for asynchronous execution. + Transfers an active inbound call to a configured target for the voice agent named in the path. - :param job: The job to create. Required. - :type job: IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns DataGenerationJobResult. The - DataGenerationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def begin_create_generation_job( + async def transfer_call( self, - job: Union[_models.DataGenerationJob, JSON, IO[bytes]], + agent_name: str, + call_id: str, + body: Union[JSON, IO[bytes]] = _Unset, *, - operation_id: Optional[str] = None, + target: str = _Unset, **kwargs: Any - ) -> AsyncLROPoller[_models.DataGenerationJobResult]: - """Create a data generation job. - - Submits a new data generation job for asynchronous execution. - - :param job: The job to create. Is one of the following types: DataGenerationJob, JSON, - IO[bytes] Required. - :type job: ~azure.ai.projects.models.DataGenerationJob or JSON or IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :return: An instance of AsyncLROPoller that returns DataGenerationJobResult. The - DataGenerationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.DataGenerationJobResult] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DataGenerationJobResult] = kwargs.pop("cls", None) - polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = await self._create_generation_job_initial( - job=job, - operation_id=operation_id, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - await raw_result.http_response.read() # type: ignore - kwargs.pop("error_map", None) - - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Operation-Location"] = self._deserialize( - "str", response.headers.get("Operation-Location") - ) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = _deserialize(_models.DataGenerationJobResult, response.json().get("result", {})) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized - - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - - if polling is True: - polling_method: AsyncPollingMethod = cast( - AsyncPollingMethod, - AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), - ) - elif polling is False: - polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) - else: - polling_method = polling - if cont_token: - return AsyncLROPoller[_models.DataGenerationJobResult].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return AsyncLROPoller[_models.DataGenerationJobResult]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) - - @distributed_trace_async - async def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerationJob: - """Cancel a data generation job. + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. - Cancels the specified data generation job if it is still in progress. + Transfers an active inbound call to a configured target for the voice agent named in the path. - :param job_id: The ID of the job to cancel. Required. - :type job_id: str - :return: DataGenerationJob. The DataGenerationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DataGenerationJob + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -15968,14 +18934,30 @@ async def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.Dat } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DataGenerationJob] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) + + if body is _Unset: + if target is _Unset: + raise TypeError("missing required argument: target") + body = {"target": target} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_datasets_cancel_generation_job_request( - job_id=job_id, + _request = build_beta_voice_agents_telephony_transfer_call_request( + agent_name=agent_name, + call_id=call_id, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -16008,7 +18990,7 @@ async def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.Dat if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DataGenerationJob, response.json()) + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -16016,15 +18998,17 @@ async def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.Dat return deserialized # type: ignore @distributed_trace_async - async def delete_generation_job(self, job_id: str, **kwargs: Any) -> None: - """Delete a data generation job. + async def end_call(self, agent_name: str, call_id: str, **kwargs: Any) -> _models.TelephonyCallRecord: + """End an active agent telephony call. - Removes the specified data generation job and its associated output. + Ends an active inbound call owned by the voice agent named in the path. - :param job_id: The ID of the job to delete. Required. - :type job_id: str - :return: None - :rtype: None + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -16038,10 +19022,11 @@ async def delete_generation_job(self, job_id: str, **kwargs: Any) -> None: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) - _request = build_beta_datasets_delete_generation_job_request( - job_id=job_id, + _request = build_beta_voice_agents_telephony_end_call_request( + agent_name=agent_name, + call_id=call_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -16051,14 +19036,20 @@ async def delete_generation_job(self, job_id: str, **kwargs: Any) -> None: } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -16066,34 +19057,29 @@ async def delete_generation_job(self, job_id: str, **kwargs: Any) -> None: ) raise HttpResponseError(response=response, model=error) - if cls: - return cls(pipeline_response, None, {}) # type: ignore + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore -class BetaAgentsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + return deserialized # type: ignore - Instead, you should access the following operations through - :class:`~azure.ai.projects.aio.AIProjectClient`'s - :attr:`agents` attribute. - """ + @distributed_trace_async + async def get_transfer_targets(self, agent_name: str, **kwargs: Any) -> _models.TelephonyTransferTargets: + """Get agent telephony transfer targets. - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + Returns all transfer targets configured for the voice agent named in the path. - async def _create_optimization_job_initial( - self, - job: Union[_models.AgentOptimizationJob, JSON, IO[bytes]], - *, - operation_id: Optional[str] = None, - **kwargs: Any - ) -> AsyncIterator[bytes]: + :param agent_name: The name of the voice agent whose transfer targets are retrieved. Required. + :type agent_name: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -16102,24 +19088,14 @@ async def _create_optimization_job_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(job, (IOBase, bytes)): - _content = job - else: - _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.TelephonyTransferTargets] = kwargs.pop("cls", None) - _request = build_beta_agents_create_optimization_job_request( - operation_id=operation_id, - content_type=content_type, + _request = build_beta_voice_agents_telephony_get_transfer_targets_request( + agent_name=agent_name, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -16129,18 +19105,19 @@ async def _create_optimization_job_initial( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: - try: - await response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -16149,10 +19126,12 @@ async def _create_optimization_job_initial( raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyTransferTargets, response.json()) if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore @@ -16160,180 +19139,131 @@ async def _create_optimization_job_initial( return deserialized # type: ignore @overload - async def begin_create_optimization_job( + async def replace_transfer_targets( self, - job: _models.AgentOptimizationJob, + agent_name: str, *, - operation_id: Optional[str] = None, + etag: str, + match_condition: MatchConditions, + transfer_targets: List[_models.TelephonyTransferTarget], content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.AgentOptimizationJobResult]: - """Create an agent optimization job. + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent - retry. + Replaces all transfer targets configured for the voice agent named in the path. - :param job: The job to create. Required. - :type job: ~azure.ai.projects.models.AgentOptimizationJob - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns AgentOptimizationJobResult. The - AgentOptimizationJobResult is compatible with MutableMapping - :rtype: - ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def begin_create_optimization_job( - self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.AgentOptimizationJobResult]: - """Create an agent optimization job. + async def replace_transfer_targets( + self, + agent_name: str, + body: JSON, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent - retry. + Replaces all transfer targets configured for the voice agent named in the path. - :param job: The job to create. Required. - :type job: JSON - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns AgentOptimizationJobResult. The - AgentOptimizationJobResult is compatible with MutableMapping - :rtype: - ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def begin_create_optimization_job( + async def replace_transfer_targets( self, - job: IO[bytes], + agent_name: str, + body: IO[bytes], *, - operation_id: Optional[str] = None, + etag: str, + match_condition: MatchConditions, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.AgentOptimizationJobResult]: - """Create an agent optimization job. + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent - retry. + Replaces all transfer targets configured for the voice agent named in the path. - :param job: The job to create. Required. - :type job: IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns AgentOptimizationJobResult. The - AgentOptimizationJobResult is compatible with MutableMapping - :rtype: - ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def begin_create_optimization_job( + async def replace_transfer_targets( self, - job: Union[_models.AgentOptimizationJob, JSON, IO[bytes]], + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, *, - operation_id: Optional[str] = None, - **kwargs: Any - ) -> AsyncLROPoller[_models.AgentOptimizationJobResult]: - """Create an agent optimization job. - - Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent - retry. - - :param job: The job to create. Is one of the following types: AgentOptimizationJob, JSON, - IO[bytes] Required. - :type job: ~azure.ai.projects.models.AgentOptimizationJob or JSON or IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :return: An instance of AsyncLROPoller that returns AgentOptimizationJobResult. The - AgentOptimizationJobResult is compatible with MutableMapping - :rtype: - ~azure.core.polling.AsyncLROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentOptimizationJobResult] = kwargs.pop("cls", None) - polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = await self._create_optimization_job_initial( - job=job, - operation_id=operation_id, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - await raw_result.http_response.read() # type: ignore - kwargs.pop("error_map", None) - - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Operation-Location"] = self._deserialize( - "str", response.headers.get("Operation-Location") - ) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = _deserialize(_models.AgentOptimizationJobResult, response.json().get("result", {})) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized - - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - - if polling is True: - polling_method: AsyncPollingMethod = cast( - AsyncPollingMethod, - AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), - ) - elif polling is False: - polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) - else: - polling_method = polling - if cont_token: - return AsyncLROPoller[_models.AgentOptimizationJobResult].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return AsyncLROPoller[_models.AgentOptimizationJobResult]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) - - @distributed_trace_async - async def get_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOptimizationJob: - """Get an agent optimization job. + etag: str, + match_condition: MatchConditions, + transfer_targets: List[_models.TelephonyTransferTarget] = _Unset, + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - Retrieves an optimization job by its identifier. + Replaces all transfer targets configured for the voice agent named in the path. - :param job_id: The ID of the job. Required. - :type job_id: str - :return: AgentOptimizationJob. The AgentOptimizationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentOptimizationJob + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -16344,14 +19274,31 @@ async def get_optimization_job(self, job_id: str, **kwargs: Any) -> _models.Agen } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentOptimizationJob] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyTransferTargets] = kwargs.pop("cls", None) - _request = build_beta_agents_get_optimization_job_request( - job_id=job_id, + if body is _Unset: + if transfer_targets is _Unset: + raise TypeError("missing required argument: transfer_targets") + body = {"transfer_targets": transfer_targets} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_voice_agents_telephony_replace_transfer_targets_request( + agent_name=agent_name, + etag=etag, + match_condition=match_condition, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -16382,62 +19329,134 @@ async def get_optimization_job(self, job_id: str, **kwargs: Any) -> _models.Agen raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentOptimizationJob, response.json()) + deserialized = _deserialize(_models.TelephonyTransferTargets, response.json()) if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace - def list_optimization_jobs( + @overload + async def create_call_job( self, + agent_name: str, + body: _models.CreateTelephonyCallJobRequest, *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - status: Optional[Union[str, _models.JobStatus]] = None, - agent_name: Optional[str] = None, + idempotency_key: str, + content_type: str = "application/json", **kwargs: Any - ) -> AsyncItemPaged["_models.AgentOptimizationJobListItem"]: - """List agent optimization jobs. + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. - Lists optimization jobs with cursor pagination and optional status or agent name filters. + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :keyword status: Filter to jobs in this lifecycle state. Known values are: "queued", - "in_progress", "succeeded", "failed", and "cancelled". Default value is None. - :paramtype status: str or ~azure.ai.projects.models.JobStatus - :keyword agent_name: Filter to jobs targeting this agent name. Default value is None. - :paramtype agent_name: str - :return: An iterator like instance of AgentOptimizationJobListItem - :rtype: - ~azure.core.async_paging.AsyncItemPaged[~azure.ai.projects.models.AgentOptimizationJobListItem] + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCallJobRequest + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.AgentOptimizationJobListItem]] = kwargs.pop("cls", None) + @overload + async def create_call_job( + self, + agent_name: str, + body: JSON, + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. + + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. + + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: JSON + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create_call_job( + self, + agent_name: str, + body: IO[bytes], + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. + + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: IO[bytes] + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create_call_job( + self, + agent_name: str, + body: Union[_models.CreateTelephonyCallJobRequest, JSON, IO[bytes]], + *, + idempotency_key: str, + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. + + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. + + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Is one of the following types: + CreateTelephonyCallJobRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCallJobRequest or JSON or IO[bytes] + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -16446,67 +19465,81 @@ def list_optimization_jobs( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - _request = build_beta_agents_list_optimization_jobs_request( - limit=limit, - order=order, - after=_continuation_token, - before=before, - status=status, - agent_name=agent_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) - async def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.AgentOptimizationJobListItem], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, AsyncList(list_of_elem) + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - async def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + _request = build_beta_voice_agents_telephony_create_call_job_request( + agent_name=agent_name, + idempotency_key=idempotency_key, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response + raise HttpResponseError(response=response, model=error) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + response_headers["Retry-After"] = self._deserialize("duration-seconds-int", response.headers.get("Retry-After")) - return pipeline_response + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) - return AsyncItemPaged(get_next, extract_data) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore @distributed_trace_async - async def cancel_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOptimizationJob: - """Cancel an agent optimization job. + async def get_call_job(self, agent_name: str, call_job_id: str, **kwargs: Any) -> _models.TelephonyCallJob: + """Get an outbound telephony call job. - Requests cancellation of a running or queued job and returns an error if the job is already in - a terminal state. + Retrieves a durable direct or campaign-created outbound call job. - :param job_id: The ID of the job to cancel. Required. - :type job_id: str - :return: AgentOptimizationJob. The AgentOptimizationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentOptimizationJob + :param agent_name: Required. + :type agent_name: str + :param call_job_id: Required. + :type call_job_id: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -16520,10 +19553,11 @@ async def cancel_optimization_job(self, job_id: str, **kwargs: Any) -> _models.A _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentOptimizationJob] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) - _request = build_beta_agents_cancel_optimization_job_request( - job_id=job_id, + _request = build_beta_voice_agents_telephony_get_call_job_request( + agent_name=agent_name, + call_job_id=call_job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -16554,26 +19588,37 @@ async def cancel_optimization_job(self, job_id: str, **kwargs: Any) -> _models.A ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentOptimizationJob, response.json()) + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace_async - async def delete_optimization_job(self, job_id: str, **kwargs: Any) -> None: - """Delete an agent optimization job. + async def cancel_call_job( + self, agent_name: str, call_job_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any + ) -> _models.TelephonyCallJob: + """Cancel an outbound telephony call job. - Deletes the job and its candidate artifacts, canceling the job first if it is non-terminal. + Requests cancellation of a durable outbound call job. A connected call is allowed to finish. - :param job_id: The ID of the job to delete. Required. - :type job_id: str - :return: None - :rtype: None + :param agent_name: Required. + :type agent_name: str + :param call_job_id: Required. + :type call_job_id: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -16587,10 +19632,13 @@ async def delete_optimization_job(self, job_id: str, **kwargs: Any) -> None: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) - _request = build_beta_agents_delete_optimization_job_request( - job_id=job_id, + _request = build_beta_voice_agents_telephony_cancel_call_job_request( + agent_name=agent_name, + call_job_id=call_job_id, + etag=etag, + match_condition=match_condition, api_version=self._config.api_version, headers=_headers, params=_params, @@ -16600,14 +19648,20 @@ async def delete_optimization_job(self, job_id: str, **kwargs: Any) -> None: } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200, 202]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -16615,5 +19669,23 @@ async def delete_optimization_job(self, job_id: str, **kwargs: Any) -> None: ) raise HttpResponseError(response=response, model=error) + response_headers = {} + if response.status_code == 200: + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if response.status_code == 202: + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + response_headers["Retry-After"] = self._deserialize( + "duration-seconds-int", response.headers.get("Retry-After") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) + if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch.py b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch.py index 6462512ea065..cc02cb579218 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/aio/operations/_patch.py @@ -19,6 +19,14 @@ from ._patch_memories_async import BetaMemoryStoresOperations from ._patch_models_async import BetaModelsOperations from ...operations._patch import _BETA_OPERATION_FEATURE_HEADERS, _OperationMethodHeaderProxy +from .._realtime import ( + AsyncBetaRealtime, + AsyncBetaRealtimeConnection, + AsyncBetaRealtimeConnectionManager, + ClientEvent, + ConversationItem, + ServerEvent, +) from ._operations import ( BetaEvaluationTaxonomiesOperations, BetaInsightsOperations, @@ -27,9 +35,37 @@ BetaRoutinesOperations, BetaSchedulesOperations, BetaSkillsOperations, + BetaVoiceAgentsConversationsOperations, + BetaVoiceAgentsOperations as GeneratedBetaVoiceAgentsOperations, + BetaVoiceAgentsTelephonyOperations, ) +class BetaVoiceAgentsOperations(GeneratedBetaVoiceAgentsOperations): + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.aio.AIProjectClient`'s :attr:`beta` attribute's + :attr:`~azure.ai.projects.aio.operations.BetaOperations.voice_agents` attribute. + """ + + conversations: BetaVoiceAgentsConversationsOperations + """:class:`~azure.ai.projects.aio.operations.BetaVoiceAgentsConversationsOperations` operations""" + telephony: BetaVoiceAgentsTelephonyOperations + """:class:`~azure.ai.projects.aio.operations.BetaVoiceAgentsTelephonyOperations` operations""" + realtime: AsyncBetaRealtime + """:class:`~azure.ai.projects.aio.operations.AsyncBetaRealtime` operations""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + # The generator does not emit realtime operations at all, since azure-core's HTTP + # pipeline has no way to keep a WebSocket upgrade's resulting socket alive. Add our + # hand-written client, which manages a real, long-lived connection, in its place. + self.realtime = AsyncBetaRealtime(self) + + class BetaOperations(GeneratedBetaOperations): """ .. warning:: @@ -64,6 +100,8 @@ class BetaOperations(GeneratedBetaOperations): """:class:`~azure.ai.projects.aio.operations.BetaSkillsOperations` operations""" datasets: BetaDatasetsOperations """:class:`~azure.ai.projects.aio.operations.BetaDatasetsOperations` operations""" + voice_agents: BetaVoiceAgentsOperations + """:class:`~azure.ai.projects.aio.operations.BetaVoiceAgentsOperations` operations""" def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) @@ -81,6 +119,8 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: self.agent_insight_monitors = BetaAgentInsightMonitorsOperations( self._client, self._config, self._serialize, self._deserialize ) + # Replace with patched class that wires up the hand-written realtime client + self.voice_agents = BetaVoiceAgentsOperations(self._client, self._config, self._serialize, self._deserialize) for property_name, foundry_features_value in _BETA_OPERATION_FEATURE_HEADERS.items(): setattr( @@ -92,6 +132,9 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: __all__: List[str] = [ "AgentsOperations", + "AsyncBetaRealtime", + "AsyncBetaRealtimeConnection", + "AsyncBetaRealtimeConnectionManager", "BetaAgentInsightMonitorsOperations", "BetaAgentsOperations", "BetaDatasetsOperations", @@ -105,9 +148,15 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: "BetaRoutinesOperations", "BetaSchedulesOperations", "BetaSkillsOperations", + "BetaVoiceAgentsConversationsOperations", + "BetaVoiceAgentsOperations", + "BetaVoiceAgentsTelephonyOperations", + "ClientEvent", "ConnectionsOperations", + "ConversationItem", "DatasetsOperations", "EvaluationRulesOperations", + "ServerEvent", "TelemetryOperations", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/models/__init__.py b/sdk/ai/azure-ai-projects/azure/ai/projects/models/__init__.py index 2a0def115184..ff1fcd74ac3f 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/models/__init__.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/models/__init__.py @@ -33,6 +33,7 @@ AgentEndpointAuthorizationScheme, AgentEndpointConfig, AgentEvaluatorGenerationJobSource, + AgentHarness, AgentIdentity, AgentInsight, AgentInsightDetails, @@ -132,6 +133,11 @@ CosmosDBIndex, CreateAsyncResponse, CreateSkillVersionFromFilesBody, + CreateTeamsPhoneExtensionTelephonyBindingRequest, + CreateTelephonyBindingRequest, + CreateTelephonyCallJobRequest, + CreateTranscriptionResponseJsonUsage, + CreateTwilioTelephonyBindingRequest, CronTrigger, CustomCredential, CustomGrammarFormatParam, @@ -212,6 +218,11 @@ FunctionShellToolParamEnvironmentLocalEnvironmentParam, FunctionTool, FunctionToolParam, + GenerateVoiceAgentRequest, + GitHubCopilotHarness, + GitHubCopilotToolsetConfig, + GitHubCopilotToolsetDefaultConfig, + GitHubCopilotToolsetPreview, GitHubIssueRoutineTrigger, HeaderTelemetryEndpointAuth, HostedAgentDefinition, @@ -240,7 +251,11 @@ InvokeAgentResponsesApiRoutineAction, LocalShellToolParam, LocalSkillParam, + LogProbProperties, LoraConfig, + MCPListToolsTool, + MCPListToolsToolAnnotations, + MCPListToolsToolInputSchema, MCPTool, MCPToolFilter, MCPToolRequireApproval, @@ -262,6 +277,7 @@ MemoryStoreSearchResult, MemoryStoreUpdateCompletedResult, MemoryStoreUpdateResult, + Metadata, Microsoft365PermissionScopes, Microsoft365PublishDefaults, Microsoft365PublishResult, @@ -290,8 +306,10 @@ OpenApiToolboxTool, OptimizedAgentIdentifier, OtlpTelemetryEndpoint, + PSTNTelephonyTransferDestination, PendingUploadRequest, PendingUploadResponse, + PickPropertiesVoiceAgentAudioConfig, ProceduralMemoryItem, ProgrammaticToolCallingParam, PromotionInfo, @@ -303,7 +321,99 @@ ProtocolConfiguration, ProtocolVersionRecord, RaiConfig, + RaiInvocationModeration, + RaiSseTextSelector, RankingOptions, + RealtimeAudioFormats, + RealtimeAudioFormatsAudioPcm, + RealtimeAudioFormatsAudioPcma, + RealtimeAudioFormatsAudioPcmu, + RealtimeClientEvent, + RealtimeClientEventConversationItemCreate, + RealtimeClientEventConversationItemDelete, + RealtimeClientEventConversationItemRetrieve, + RealtimeClientEventConversationItemTruncate, + RealtimeClientEventInputAudioBufferAppend, + RealtimeClientEventInputAudioBufferClear, + RealtimeClientEventInputAudioBufferCommit, + RealtimeClientEventOutputAudioBufferClear, + RealtimeClientEventResponseCancel, + RealtimeClientEventResponseCreate, + RealtimeConversationItem, + RealtimeConversationItemFunctionCall, + RealtimeConversationItemFunctionCallOutput, + RealtimeConversationItemMessage, + RealtimeConversationItemMessageAssistant, + RealtimeConversationItemMessageAssistantContent, + RealtimeConversationItemMessageSystem, + RealtimeConversationItemMessageSystemContent, + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeFunctionTool, + RealtimeFunctionToolParameters, + RealtimeMCPApprovalRequest, + RealtimeMCPApprovalResponse, + RealtimeMCPError, + RealtimeMCPHTTPError, + RealtimeMCPListTools, + RealtimeMCPProtocolError, + RealtimeMCPToolCall, + RealtimeMCPToolExecutionError, + RealtimeReasoning, + RealtimeResponseStatusDetails, + RealtimeResponseStatusDetailsError, + RealtimeResponseUsage, + RealtimeResponseUsageInputTokenDetails, + RealtimeResponseUsageInputTokenDetailsCachedTokensDetails, + RealtimeResponseUsageOutputTokenDetails, + RealtimeServerEvent, + RealtimeServerEventConversationItemAdded, + RealtimeServerEventConversationItemCreated, + RealtimeServerEventConversationItemDeleted, + RealtimeServerEventConversationItemDone, + RealtimeServerEventConversationItemInputAudioTranscriptionCompleted, + RealtimeServerEventConversationItemInputAudioTranscriptionDelta, + RealtimeServerEventConversationItemInputAudioTranscriptionFailed, + RealtimeServerEventConversationItemInputAudioTranscriptionFailedError, + RealtimeServerEventConversationItemInputAudioTranscriptionSegment, + RealtimeServerEventConversationItemRetrieved, + RealtimeServerEventConversationItemTruncated, + RealtimeServerEventError, + RealtimeServerEventErrorError, + RealtimeServerEventInputAudioBufferCleared, + RealtimeServerEventInputAudioBufferCommitted, + RealtimeServerEventInputAudioBufferSpeechStarted, + RealtimeServerEventInputAudioBufferSpeechStopped, + RealtimeServerEventInputAudioBufferTimeoutTriggered, + RealtimeServerEventMCPListToolsCompleted, + RealtimeServerEventMCPListToolsFailed, + RealtimeServerEventMCPListToolsInProgress, + RealtimeServerEventOutputAudioBufferCleared, + RealtimeServerEventRateLimitsUpdated, + RealtimeServerEventRateLimitsUpdatedRateLimits, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioDone, + RealtimeServerEventResponseAudioTranscriptDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseContentPartAdded, + RealtimeServerEventResponseContentPartAddedPart, + RealtimeServerEventResponseContentPartDone, + RealtimeServerEventResponseContentPartDonePart, + RealtimeServerEventResponseCreated, + RealtimeServerEventResponseDone, + RealtimeServerEventResponseFunctionCallArgumentsDelta, + RealtimeServerEventResponseFunctionCallArgumentsDone, + RealtimeServerEventResponseMCPCallArgumentsDelta, + RealtimeServerEventResponseMCPCallArgumentsDone, + RealtimeServerEventResponseMCPCallCompleted, + RealtimeServerEventResponseMCPCallFailed, + RealtimeServerEventResponseMCPCallInProgress, + RealtimeServerEventResponseOutputItemAdded, + RealtimeServerEventResponseOutputItemDone, + RealtimeServerEventResponseTextDelta, + RealtimeServerEventResponseTextDone, + RealtimeServerEventSessionCreated, + RealtimeServerEventSessionUpdated, Reasoning, RecurrenceSchedule, RecurrenceTrigger, @@ -335,8 +445,10 @@ ShellToolboxTool, SimpleQnADataGenerationJobOptions, SimulationSeedDataGenerationJobOptions, + SipTelephonyTransferDestination, SkillDetails, SkillInlineContent, + SkillReference, SkillReferenceParam, SkillVersion, SpecificApplyPatchParam, @@ -346,9 +458,28 @@ StructuredOutputDefinition, TaxonomyCategory, TaxonomySubCategory, + TeamsPhoneExtensionTelephonyBinding, + TeamsPhoneExtensionTelephonyBindingListItem, + TeamsTelephonyTransferDestination, TelemetryConfig, TelemetryEndpoint, TelemetryEndpointAuth, + TelephonyBinding, + TelephonyBindingListItem, + TelephonyCallJob, + TelephonyCallJobCancellation, + TelephonyCallJobSchedule, + TelephonyCallLifecycleEvent, + TelephonyCallRecord, + TelephonyCallSummary, + TelephonyCallTiming, + TelephonyCallTrace, + TelephonyOutboundDestination, + TelephonyOutboundFixedIntervalRetryPolicy, + TelephonyOutboundRetryPolicy, + TelephonyTransferDestination, + TelephonyTransferTarget, + TelephonyTransferTargets, TextResponseFormat, TextResponseFormatJsonObject, TextResponseFormatJsonSchema, @@ -386,17 +517,102 @@ ToolboxSkillReference, ToolboxTool, ToolboxVersionObject, + ToolboxVersions, TracesDataGenerationJobOptions, TracesDataGenerationJobSource, TracesEvaluatorGenerationJobSource, + TranscriptTextUsageDuration, + TranscriptTextUsageTokens, + TranscriptTextUsageTokensInputTokenDetails, + TranscriptionLanguage, Trigger, + TwilioTelephonyBinding, + TwilioTelephonyBindingListItem, UpdateModelVersionRequest, + UpdateTelephonyBindingRequest, UpdateToolboxRequest, UserProfileMemoryItem, VersionIndicator, VersionRefIndicator, VersionSelectionRule, VersionSelector, + VoiceAgentAnimationConfig, + VoiceAgentAudioConfig, + VoiceAgentAudioInputConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentAvatarConfig, + VoiceAgentAvatarIceServer, + VoiceAgentAvatarScene, + VoiceAgentAvatarVideoBackground, + VoiceAgentAvatarVideoCrop, + VoiceAgentAvatarVideoParams, + VoiceAgentAvatarVideoResolution, + VoiceAgentAzureSemanticVadEnTurnDetection, + VoiceAgentAzureSemanticVadMultilingualTurnDetection, + VoiceAgentAzureSemanticVadTurnDetection, + VoiceAgentClientEventRtcCallSdpCreate, + VoiceAgentClientEventSessionAvatarConnect, + VoiceAgentClientEventSessionUpdate, + VoiceAgentDefinition, + VoiceAgentEchoCancellation, + VoiceAgentEndConversationSystemTool, + VoiceAgentEndOfUtteranceDetection, + VoiceAgentFunctionTool, + VoiceAgentGreetingConfig, + VoiceAgentInputTranscription, + VoiceAgentInterimResponseConfig, + VoiceAgentLlmGeneratedGreetingConfig, + VoiceAgentLlmInterimResponseConfig, + VoiceAgentMcpTool, + VoiceAgentNoiseReduction, + VoiceAgentRealtimeResponse, + VoiceAgentRealtimeResponseBase, + VoiceAgentResponseCreateParams, + VoiceAgentRtcCallErrorDetails, + VoiceAgentSemanticVadTurnDetection, + VoiceAgentServerEventResponseAnimationBlendshapesDelta, + VoiceAgentServerEventResponseAnimationBlendshapesDone, + VoiceAgentServerEventResponseAnimationVisemeDelta, + VoiceAgentServerEventResponseAnimationVisemeDone, + VoiceAgentServerEventResponseAudioTimestampDelta, + VoiceAgentServerEventResponseAudioTimestampDone, + VoiceAgentServerEventResponseVideoDelta, + VoiceAgentServerEventRtcCallError, + VoiceAgentServerEventRtcCallSdpCreated, + VoiceAgentServerEventSessionAvatarConnecting, + VoiceAgentServerEventSessionAvatarSwitchToIdle, + VoiceAgentServerEventSessionAvatarSwitchToSpeaking, + VoiceAgentServerEventSessionSubagentAborted, + VoiceAgentServerEventSessionSubagentCompleted, + VoiceAgentServerEventSessionSubagentStarted, + VoiceAgentServerEventWarning, + VoiceAgentServerEventWarningDetails, + VoiceAgentServerVadTurnDetection, + VoiceAgentSessionAvatarConfig, + VoiceAgentSessionResponseConfig, + VoiceAgentSessionUpdateConfig, + VoiceAgentStaticInterimResponseConfig, + VoiceAgentSubagent, + VoiceAgentSubagentConfig, + VoiceAgentSubagentResponsePolicy, + VoiceAgentSystemTool, + VoiceAgentTemplateGreetingConfig, + VoiceAgentTool, + VoiceAgentToolboxTool, + VoiceAgentTranscriptionPhrase, + VoiceAgentTranscriptionWord, + VoiceAgentTurnDetectionConfig, + VoiceAudioItem, + VoiceConversation, + VoiceConversationEngine, + VoiceGeneratedAudioItem, + VoiceHostedAgentConversationEngine, + VoiceRecording, + VoiceRecordingChannelLayout, + VoiceResponse, + VoiceResponseAudio, + VoiceResponseAudioOutput, + VoiceResponseBase, WebIQPreviewTool, WebIQPreviewToolboxTool, WebSearchApproximateLocation, @@ -440,9 +656,11 @@ ContainerMemoryLimit, ContainerNetworkPolicyParamType, ContainerSkillType, + CreateTranscriptionResponseJsonUsageType, CredentialType, CustomToolParamFormatType, DataGenerationJobOutputType, + DataGenerationJobOutputWriteMode, DataGenerationJobScenario, DataGenerationJobSourceType, DataGenerationJobType, @@ -467,6 +685,7 @@ FoundryModelWeightType, FunctionShellToolParamEnvironmentType, GenerationWarningType, + GitHubCopilotBuiltInTool, GitHubIssueEvent, GrammarSyntax1, ImageGenAction, @@ -485,7 +704,16 @@ PageOrder, PendingUploadType, PublishApprovalStatus, + RaiInvocationContentType, + RaiInvocationMode, RankerVersionType, + RealtimeAudioFormatsType, + RealtimeClientEventType, + RealtimeConversationItemMessageType, + RealtimeConversationItemType, + RealtimeMcpErrorType, + RealtimeReasoningEffort, + RealtimeServerEventType, ReasoningEffort, ReasoningModeEnum, RecurrenceType, @@ -510,7 +738,26 @@ TelemetryEndpointAuthType, TelemetryEndpointKind, TelemetryTransportProtocol, + TelephonyBindingStatus, + TelephonyCallDurationBasis, + TelephonyCallEndReason, + TelephonyCallJobStatus, + TelephonyCallJobTerminalReason, + TelephonyCallLifecycleEventName, + TelephonyCallLifecycleEventOutcome, + TelephonyCallLifecycleEventReason, + TelephonyCallLifecycleEventSource, + TelephonyCallPhase, + TelephonyCallStatus, + TelephonyCallTimestampSource, + TelephonyCallTraceMode, + TelephonyCallTraceStatus, + TelephonyOutboundDestinationType, + TelephonyOutboundRetryPolicyType, + TelephonyProvider, + TelephonyTransferDestinationKind, TextResponseFormatConfigurationType, + ToolChoiceOptions, ToolChoiceParamType, ToolSearchExecutionType, ToolType, @@ -519,6 +766,28 @@ TriggerType, VersionIndicatorType, VersionSelectorType, + VoiceAgentAnimationOutputType, + VoiceAgentAudioTimestampType, + VoiceAgentAvatarOutputProtocol, + VoiceAgentAvatarType, + VoiceAgentEchoCancellationReferenceSource, + VoiceAgentEndOfUtteranceDetectionModel, + VoiceAgentEndOfUtteranceThresholdLevel, + VoiceAgentInputTranscriptionModel, + VoiceAgentInterimResponseTrigger, + VoiceAgentNoiseReductionType, + VoiceAgentSessionIncludeOption, + VoiceAgentSubagentAbortReason, + VoiceAgentSystemToolName, + VoiceAgentToolResponseScheduling, + VoiceAgentTurnDetectionType, + VoiceAudioCodec, + VoiceAudioContainerFormat, + VoiceAudioRole, + VoiceConversationStatus, + VoiceModelType, + VoiceOutputModality, + VoiceType, ) from ._patch import __all__ as _patch_all from ._patch import * @@ -543,6 +812,7 @@ "AgentEndpointAuthorizationScheme", "AgentEndpointConfig", "AgentEvaluatorGenerationJobSource", + "AgentHarness", "AgentIdentity", "AgentInsight", "AgentInsightDetails", @@ -642,6 +912,11 @@ "CosmosDBIndex", "CreateAsyncResponse", "CreateSkillVersionFromFilesBody", + "CreateTeamsPhoneExtensionTelephonyBindingRequest", + "CreateTelephonyBindingRequest", + "CreateTelephonyCallJobRequest", + "CreateTranscriptionResponseJsonUsage", + "CreateTwilioTelephonyBindingRequest", "CronTrigger", "CustomCredential", "CustomGrammarFormatParam", @@ -722,6 +997,11 @@ "FunctionShellToolParamEnvironmentLocalEnvironmentParam", "FunctionTool", "FunctionToolParam", + "GenerateVoiceAgentRequest", + "GitHubCopilotHarness", + "GitHubCopilotToolsetConfig", + "GitHubCopilotToolsetDefaultConfig", + "GitHubCopilotToolsetPreview", "GitHubIssueRoutineTrigger", "HeaderTelemetryEndpointAuth", "HostedAgentDefinition", @@ -750,7 +1030,11 @@ "InvokeAgentResponsesApiRoutineAction", "LocalShellToolParam", "LocalSkillParam", + "LogProbProperties", "LoraConfig", + "MCPListToolsTool", + "MCPListToolsToolAnnotations", + "MCPListToolsToolInputSchema", "MCPTool", "MCPToolFilter", "MCPToolRequireApproval", @@ -772,6 +1056,7 @@ "MemoryStoreSearchResult", "MemoryStoreUpdateCompletedResult", "MemoryStoreUpdateResult", + "Metadata", "Microsoft365PermissionScopes", "Microsoft365PublishDefaults", "Microsoft365PublishResult", @@ -800,8 +1085,10 @@ "OpenApiToolboxTool", "OptimizedAgentIdentifier", "OtlpTelemetryEndpoint", + "PSTNTelephonyTransferDestination", "PendingUploadRequest", "PendingUploadResponse", + "PickPropertiesVoiceAgentAudioConfig", "ProceduralMemoryItem", "ProgrammaticToolCallingParam", "PromotionInfo", @@ -813,7 +1100,99 @@ "ProtocolConfiguration", "ProtocolVersionRecord", "RaiConfig", + "RaiInvocationModeration", + "RaiSseTextSelector", "RankingOptions", + "RealtimeAudioFormats", + "RealtimeAudioFormatsAudioPcm", + "RealtimeAudioFormatsAudioPcma", + "RealtimeAudioFormatsAudioPcmu", + "RealtimeClientEvent", + "RealtimeClientEventConversationItemCreate", + "RealtimeClientEventConversationItemDelete", + "RealtimeClientEventConversationItemRetrieve", + "RealtimeClientEventConversationItemTruncate", + "RealtimeClientEventInputAudioBufferAppend", + "RealtimeClientEventInputAudioBufferClear", + "RealtimeClientEventInputAudioBufferCommit", + "RealtimeClientEventOutputAudioBufferClear", + "RealtimeClientEventResponseCancel", + "RealtimeClientEventResponseCreate", + "RealtimeConversationItem", + "RealtimeConversationItemFunctionCall", + "RealtimeConversationItemFunctionCallOutput", + "RealtimeConversationItemMessage", + "RealtimeConversationItemMessageAssistant", + "RealtimeConversationItemMessageAssistantContent", + "RealtimeConversationItemMessageSystem", + "RealtimeConversationItemMessageSystemContent", + "RealtimeConversationItemMessageUser", + "RealtimeConversationItemMessageUserContent", + "RealtimeFunctionTool", + "RealtimeFunctionToolParameters", + "RealtimeMCPApprovalRequest", + "RealtimeMCPApprovalResponse", + "RealtimeMCPError", + "RealtimeMCPHTTPError", + "RealtimeMCPListTools", + "RealtimeMCPProtocolError", + "RealtimeMCPToolCall", + "RealtimeMCPToolExecutionError", + "RealtimeReasoning", + "RealtimeResponseStatusDetails", + "RealtimeResponseStatusDetailsError", + "RealtimeResponseUsage", + "RealtimeResponseUsageInputTokenDetails", + "RealtimeResponseUsageInputTokenDetailsCachedTokensDetails", + "RealtimeResponseUsageOutputTokenDetails", + "RealtimeServerEvent", + "RealtimeServerEventConversationItemAdded", + "RealtimeServerEventConversationItemCreated", + "RealtimeServerEventConversationItemDeleted", + "RealtimeServerEventConversationItemDone", + "RealtimeServerEventConversationItemInputAudioTranscriptionCompleted", + "RealtimeServerEventConversationItemInputAudioTranscriptionDelta", + "RealtimeServerEventConversationItemInputAudioTranscriptionFailed", + "RealtimeServerEventConversationItemInputAudioTranscriptionFailedError", + "RealtimeServerEventConversationItemInputAudioTranscriptionSegment", + "RealtimeServerEventConversationItemRetrieved", + "RealtimeServerEventConversationItemTruncated", + "RealtimeServerEventError", + "RealtimeServerEventErrorError", + "RealtimeServerEventInputAudioBufferCleared", + "RealtimeServerEventInputAudioBufferCommitted", + "RealtimeServerEventInputAudioBufferSpeechStarted", + "RealtimeServerEventInputAudioBufferSpeechStopped", + "RealtimeServerEventInputAudioBufferTimeoutTriggered", + "RealtimeServerEventMCPListToolsCompleted", + "RealtimeServerEventMCPListToolsFailed", + "RealtimeServerEventMCPListToolsInProgress", + "RealtimeServerEventOutputAudioBufferCleared", + "RealtimeServerEventRateLimitsUpdated", + "RealtimeServerEventRateLimitsUpdatedRateLimits", + "RealtimeServerEventResponseAudioDelta", + "RealtimeServerEventResponseAudioDone", + "RealtimeServerEventResponseAudioTranscriptDelta", + "RealtimeServerEventResponseAudioTranscriptDone", + "RealtimeServerEventResponseContentPartAdded", + "RealtimeServerEventResponseContentPartAddedPart", + "RealtimeServerEventResponseContentPartDone", + "RealtimeServerEventResponseContentPartDonePart", + "RealtimeServerEventResponseCreated", + "RealtimeServerEventResponseDone", + "RealtimeServerEventResponseFunctionCallArgumentsDelta", + "RealtimeServerEventResponseFunctionCallArgumentsDone", + "RealtimeServerEventResponseMCPCallArgumentsDelta", + "RealtimeServerEventResponseMCPCallArgumentsDone", + "RealtimeServerEventResponseMCPCallCompleted", + "RealtimeServerEventResponseMCPCallFailed", + "RealtimeServerEventResponseMCPCallInProgress", + "RealtimeServerEventResponseOutputItemAdded", + "RealtimeServerEventResponseOutputItemDone", + "RealtimeServerEventResponseTextDelta", + "RealtimeServerEventResponseTextDone", + "RealtimeServerEventSessionCreated", + "RealtimeServerEventSessionUpdated", "Reasoning", "RecurrenceSchedule", "RecurrenceTrigger", @@ -845,8 +1224,10 @@ "ShellToolboxTool", "SimpleQnADataGenerationJobOptions", "SimulationSeedDataGenerationJobOptions", + "SipTelephonyTransferDestination", "SkillDetails", "SkillInlineContent", + "SkillReference", "SkillReferenceParam", "SkillVersion", "SpecificApplyPatchParam", @@ -856,9 +1237,28 @@ "StructuredOutputDefinition", "TaxonomyCategory", "TaxonomySubCategory", + "TeamsPhoneExtensionTelephonyBinding", + "TeamsPhoneExtensionTelephonyBindingListItem", + "TeamsTelephonyTransferDestination", "TelemetryConfig", "TelemetryEndpoint", "TelemetryEndpointAuth", + "TelephonyBinding", + "TelephonyBindingListItem", + "TelephonyCallJob", + "TelephonyCallJobCancellation", + "TelephonyCallJobSchedule", + "TelephonyCallLifecycleEvent", + "TelephonyCallRecord", + "TelephonyCallSummary", + "TelephonyCallTiming", + "TelephonyCallTrace", + "TelephonyOutboundDestination", + "TelephonyOutboundFixedIntervalRetryPolicy", + "TelephonyOutboundRetryPolicy", + "TelephonyTransferDestination", + "TelephonyTransferTarget", + "TelephonyTransferTargets", "TextResponseFormat", "TextResponseFormatJsonObject", "TextResponseFormatJsonSchema", @@ -896,17 +1296,102 @@ "ToolboxSkillReference", "ToolboxTool", "ToolboxVersionObject", + "ToolboxVersions", "TracesDataGenerationJobOptions", "TracesDataGenerationJobSource", "TracesEvaluatorGenerationJobSource", + "TranscriptTextUsageDuration", + "TranscriptTextUsageTokens", + "TranscriptTextUsageTokensInputTokenDetails", + "TranscriptionLanguage", "Trigger", + "TwilioTelephonyBinding", + "TwilioTelephonyBindingListItem", "UpdateModelVersionRequest", + "UpdateTelephonyBindingRequest", "UpdateToolboxRequest", "UserProfileMemoryItem", "VersionIndicator", "VersionRefIndicator", "VersionSelectionRule", "VersionSelector", + "VoiceAgentAnimationConfig", + "VoiceAgentAudioConfig", + "VoiceAgentAudioInputConfig", + "VoiceAgentAudioOutputConfig", + "VoiceAgentAvatarConfig", + "VoiceAgentAvatarIceServer", + "VoiceAgentAvatarScene", + "VoiceAgentAvatarVideoBackground", + "VoiceAgentAvatarVideoCrop", + "VoiceAgentAvatarVideoParams", + "VoiceAgentAvatarVideoResolution", + "VoiceAgentAzureSemanticVadEnTurnDetection", + "VoiceAgentAzureSemanticVadMultilingualTurnDetection", + "VoiceAgentAzureSemanticVadTurnDetection", + "VoiceAgentClientEventRtcCallSdpCreate", + "VoiceAgentClientEventSessionAvatarConnect", + "VoiceAgentClientEventSessionUpdate", + "VoiceAgentDefinition", + "VoiceAgentEchoCancellation", + "VoiceAgentEndConversationSystemTool", + "VoiceAgentEndOfUtteranceDetection", + "VoiceAgentFunctionTool", + "VoiceAgentGreetingConfig", + "VoiceAgentInputTranscription", + "VoiceAgentInterimResponseConfig", + "VoiceAgentLlmGeneratedGreetingConfig", + "VoiceAgentLlmInterimResponseConfig", + "VoiceAgentMcpTool", + "VoiceAgentNoiseReduction", + "VoiceAgentRealtimeResponse", + "VoiceAgentRealtimeResponseBase", + "VoiceAgentResponseCreateParams", + "VoiceAgentRtcCallErrorDetails", + "VoiceAgentSemanticVadTurnDetection", + "VoiceAgentServerEventResponseAnimationBlendshapesDelta", + "VoiceAgentServerEventResponseAnimationBlendshapesDone", + "VoiceAgentServerEventResponseAnimationVisemeDelta", + "VoiceAgentServerEventResponseAnimationVisemeDone", + "VoiceAgentServerEventResponseAudioTimestampDelta", + "VoiceAgentServerEventResponseAudioTimestampDone", + "VoiceAgentServerEventResponseVideoDelta", + "VoiceAgentServerEventRtcCallError", + "VoiceAgentServerEventRtcCallSdpCreated", + "VoiceAgentServerEventSessionAvatarConnecting", + "VoiceAgentServerEventSessionAvatarSwitchToIdle", + "VoiceAgentServerEventSessionAvatarSwitchToSpeaking", + "VoiceAgentServerEventSessionSubagentAborted", + "VoiceAgentServerEventSessionSubagentCompleted", + "VoiceAgentServerEventSessionSubagentStarted", + "VoiceAgentServerEventWarning", + "VoiceAgentServerEventWarningDetails", + "VoiceAgentServerVadTurnDetection", + "VoiceAgentSessionAvatarConfig", + "VoiceAgentSessionResponseConfig", + "VoiceAgentSessionUpdateConfig", + "VoiceAgentStaticInterimResponseConfig", + "VoiceAgentSubagent", + "VoiceAgentSubagentConfig", + "VoiceAgentSubagentResponsePolicy", + "VoiceAgentSystemTool", + "VoiceAgentTemplateGreetingConfig", + "VoiceAgentTool", + "VoiceAgentToolboxTool", + "VoiceAgentTranscriptionPhrase", + "VoiceAgentTranscriptionWord", + "VoiceAgentTurnDetectionConfig", + "VoiceAudioItem", + "VoiceConversation", + "VoiceConversationEngine", + "VoiceGeneratedAudioItem", + "VoiceHostedAgentConversationEngine", + "VoiceRecording", + "VoiceRecordingChannelLayout", + "VoiceResponse", + "VoiceResponseAudio", + "VoiceResponseAudioOutput", + "VoiceResponseBase", "WebIQPreviewTool", "WebIQPreviewToolboxTool", "WebSearchApproximateLocation", @@ -947,9 +1432,11 @@ "ContainerMemoryLimit", "ContainerNetworkPolicyParamType", "ContainerSkillType", + "CreateTranscriptionResponseJsonUsageType", "CredentialType", "CustomToolParamFormatType", "DataGenerationJobOutputType", + "DataGenerationJobOutputWriteMode", "DataGenerationJobScenario", "DataGenerationJobSourceType", "DataGenerationJobType", @@ -974,6 +1461,7 @@ "FoundryModelWeightType", "FunctionShellToolParamEnvironmentType", "GenerationWarningType", + "GitHubCopilotBuiltInTool", "GitHubIssueEvent", "GrammarSyntax1", "ImageGenAction", @@ -992,7 +1480,16 @@ "PageOrder", "PendingUploadType", "PublishApprovalStatus", + "RaiInvocationContentType", + "RaiInvocationMode", "RankerVersionType", + "RealtimeAudioFormatsType", + "RealtimeClientEventType", + "RealtimeConversationItemMessageType", + "RealtimeConversationItemType", + "RealtimeMcpErrorType", + "RealtimeReasoningEffort", + "RealtimeServerEventType", "ReasoningEffort", "ReasoningModeEnum", "RecurrenceType", @@ -1017,7 +1514,26 @@ "TelemetryEndpointAuthType", "TelemetryEndpointKind", "TelemetryTransportProtocol", + "TelephonyBindingStatus", + "TelephonyCallDurationBasis", + "TelephonyCallEndReason", + "TelephonyCallJobStatus", + "TelephonyCallJobTerminalReason", + "TelephonyCallLifecycleEventName", + "TelephonyCallLifecycleEventOutcome", + "TelephonyCallLifecycleEventReason", + "TelephonyCallLifecycleEventSource", + "TelephonyCallPhase", + "TelephonyCallStatus", + "TelephonyCallTimestampSource", + "TelephonyCallTraceMode", + "TelephonyCallTraceStatus", + "TelephonyOutboundDestinationType", + "TelephonyOutboundRetryPolicyType", + "TelephonyProvider", + "TelephonyTransferDestinationKind", "TextResponseFormatConfigurationType", + "ToolChoiceOptions", "ToolChoiceParamType", "ToolSearchExecutionType", "ToolType", @@ -1026,6 +1542,28 @@ "TriggerType", "VersionIndicatorType", "VersionSelectorType", + "VoiceAgentAnimationOutputType", + "VoiceAgentAudioTimestampType", + "VoiceAgentAvatarOutputProtocol", + "VoiceAgentAvatarType", + "VoiceAgentEchoCancellationReferenceSource", + "VoiceAgentEndOfUtteranceDetectionModel", + "VoiceAgentEndOfUtteranceThresholdLevel", + "VoiceAgentInputTranscriptionModel", + "VoiceAgentInterimResponseTrigger", + "VoiceAgentNoiseReductionType", + "VoiceAgentSessionIncludeOption", + "VoiceAgentSubagentAbortReason", + "VoiceAgentSystemToolName", + "VoiceAgentToolResponseScheduling", + "VoiceAgentTurnDetectionType", + "VoiceAudioCodec", + "VoiceAudioContainerFormat", + "VoiceAudioRole", + "VoiceConversationStatus", + "VoiceModelType", + "VoiceOutputModality", + "VoiceType", ] __all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore _patch_sdk() diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_enums.py b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_enums.py index d2e0105f2403..5b3a8963e41d 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_enums.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_enums.py @@ -12,7 +12,7 @@ class _AgentDefinitionOptInKeys(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Feature opt-in keys for agent definition operations supporting hosted or workflow agents.""" + """Feature opt-in keys for agent definition operations supporting conditional preview features.""" WORKFLOW_AGENTS_V1_PREVIEW = "WorkflowAgents=V1Preview" """WORKFLOW_AGENTS_V1_PREVIEW.""" @@ -24,6 +24,10 @@ class _AgentDefinitionOptInKeys(str, Enum, metaclass=CaseInsensitiveEnumMeta): """VOICE_AGENTS_V1_PREVIEW.""" DIGITAL_WORKER_V1_PREVIEW = "DigitalWorker=V1Preview" """DIGITAL_WORKER_V1_PREVIEW.""" + GITHUB_COPILOT_V1_PREVIEW = "GitHubCopilot=V1Preview" + """GITHUB_COPILOT_V1_PREVIEW.""" + SKILLS_V1_PREVIEW = "Skills=V1Preview" + """SKILLS_V1_PREVIEW.""" class _FoundryFeaturesOptInKeys(str, Enum, metaclass=CaseInsensitiveEnumMeta): @@ -136,6 +140,8 @@ class AgentEndpointProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): """MCP.""" INVOCATIONS = "invocations" """INVOCATIONS.""" + VOICE = "voice" + """VOICE.""" INVOCATIONS_WS = "invocations_ws" """WebSocket-based protocol for hosted voice and real-time streaming agents.""" @@ -222,6 +228,8 @@ class AgentKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): """WORKFLOW.""" EXTERNAL = "external" """EXTERNAL.""" + VOICE = "voice" + """VOICE.""" class AgentObjectType(str, Enum, metaclass=CaseInsensitiveEnumMeta): @@ -480,6 +488,15 @@ class ContainerSkillType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """INLINE.""" +class CreateTranscriptionResponseJsonUsageType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of CreateTranscriptionResponseJsonUsageType.""" + + TOKENS = "tokens" + """TOKENS.""" + DURATION = "duration" + """DURATION.""" + + class CredentialType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """The credential type used by the connection.""" @@ -515,6 +532,18 @@ class DataGenerationJobOutputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """The generated data is a Dataset.""" +class DataGenerationJobOutputWriteMode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The supported write modes for data generation job outputs.""" + + OVERWRITE = "overwrite" + """Default behavior. Create the next dataset version using only newly generated rows, replacing + the previous version's rows in the new version.""" + MERGE = "merge" + """Applicable only for trace data generation jobs that output evaluation datasets. Create the next + dataset version by merging newly generated rows with the latest existing dataset version and + de-duping trace rows.""" + + class DataGenerationJobScenario(str, Enum, metaclass=CaseInsensitiveEnumMeta): """The supported scenarios for a data generation job.""" @@ -784,6 +813,21 @@ class GenerationWarningType(str, Enum, metaclass=CaseInsensitiveEnumMeta): ``generation_job_id`` to fetch the detailed warning payloads.""" +class GitHubCopilotBuiltInTool(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A customer-configurable GitHub Copilot built-in tool.""" + + FILESYSTEM_READ = "filesystem_read" + """Read and search files in the harness workspace.""" + FILESYSTEM_WRITE = "filesystem_write" + """Create and modify files in the harness workspace.""" + SHELL = "shell" + """Execute operating-system commands.""" + WEB = "web" + """Fetch content and search external network resources.""" + SUBAGENTS = "subagents" + """Delegate work to additional agents.""" + + class GitHubIssueEvent(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Known GitHub issue events that can fire a routine.""" @@ -1001,6 +1045,28 @@ class PublishApprovalStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): tenant-scoped titles are reviewed.""" +class RaiInvocationContentType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """How an invocations request/response body is parsed to locate text for content-safety + moderation. + """ + + JSON = "json" + """Parse the body as JSON and evaluate the declared paths/selectors.""" + TEXT = "text" + """Treat the whole (size-capped) body as text; paths/selectors are ignored.""" + + +class RaiInvocationMode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Author-declared response shape for the invocations protocol.""" + + NON_STREAMING = "non_streaming" + """Non-streaming response body.""" + STREAMING = "streaming" + """Streaming response body.""" + BOTH = "both" + """Both non-streaming and streaming response bodies.""" + + class RankerVersionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Type of RankerVersionType.""" @@ -1010,6 +1076,235 @@ class RankerVersionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """DEFAULT_2024_11_15.""" +class RealtimeAudioFormatsType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeAudioFormatsType.""" + + AUDIO_PCM = "audio/pcm" + """AUDIO_PCM.""" + AUDIO_PCMU = "audio/pcmu" + """AUDIO_PCMU.""" + AUDIO_PCMA = "audio/pcma" + """AUDIO_PCMA.""" + + +class RealtimeClientEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeClientEventType.""" + + CONVERSATION_ITEM_CREATE = "conversation.item.create" + """CONVERSATION_ITEM_CREATE.""" + CONVERSATION_ITEM_DELETE = "conversation.item.delete" + """CONVERSATION_ITEM_DELETE.""" + CONVERSATION_ITEM_RETRIEVE = "conversation.item.retrieve" + """CONVERSATION_ITEM_RETRIEVE.""" + CONVERSATION_ITEM_TRUNCATE = "conversation.item.truncate" + """CONVERSATION_ITEM_TRUNCATE.""" + INPUT_AUDIO_BUFFER_APPEND = "input_audio_buffer.append" + """INPUT_AUDIO_BUFFER_APPEND.""" + INPUT_AUDIO_BUFFER_CLEAR = "input_audio_buffer.clear" + """INPUT_AUDIO_BUFFER_CLEAR.""" + OUTPUT_AUDIO_BUFFER_CLEAR = "output_audio_buffer.clear" + """OUTPUT_AUDIO_BUFFER_CLEAR.""" + INPUT_AUDIO_BUFFER_COMMIT = "input_audio_buffer.commit" + """INPUT_AUDIO_BUFFER_COMMIT.""" + RESPONSE_CANCEL = "response.cancel" + """RESPONSE_CANCEL.""" + RESPONSE_CREATE = "response.create" + """RESPONSE_CREATE.""" + SESSION_UPDATE = "session.update" + """SESSION_UPDATE.""" + SESSION_AVATAR_CONNECT = "session.avatar.connect" + """SESSION_AVATAR_CONNECT.""" + RTC_CALL_SDP_CREATE = "rtc.call.sdp.create" + """RTC_CALL_SDP_CREATE.""" + + +class RealtimeConversationItemMessageType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeConversationItemMessageType.""" + + SYSTEM = "system" + """SYSTEM.""" + USER = "user" + """USER.""" + ASSISTANT = "assistant" + """ASSISTANT.""" + + +class RealtimeConversationItemType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeConversationItemType.""" + + FUNCTION_CALL = "function_call" + """FUNCTION_CALL.""" + FUNCTION_CALL_OUTPUT = "function_call_output" + """FUNCTION_CALL_OUTPUT.""" + MCP_APPROVAL_RESPONSE = "mcp_approval_response" + """MCP_APPROVAL_RESPONSE.""" + MCP_LIST_TOOLS = "mcp_list_tools" + """MCP_LIST_TOOLS.""" + MCP_CALL = "mcp_call" + """MCP_CALL.""" + MCP_APPROVAL_REQUEST = "mcp_approval_request" + """MCP_APPROVAL_REQUEST.""" + MESSAGE = "message" + """MESSAGE.""" + + +class RealtimeMcpErrorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeMcpErrorType.""" + + PROTOCOL_ERROR = "protocol_error" + """PROTOCOL_ERROR.""" + TOOL_EXECUTION_ERROR = "tool_execution_error" + """TOOL_EXECUTION_ERROR.""" + HTTP_ERROR = "http_error" + """HTTP_ERROR.""" + + +class RealtimeReasoningEffort(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Constrains effort on reasoning for reasoning-capable Realtime models such as + ``gpt-realtime-2``. + """ + + MINIMAL = "minimal" + """MINIMAL.""" + LOW = "low" + """LOW.""" + MEDIUM = "medium" + """MEDIUM.""" + HIGH = "high" + """HIGH.""" + XHIGH = "xhigh" + """XHIGH.""" + + +class RealtimeServerEventType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Type of RealtimeServerEventType.""" + + CONVERSATION_CREATED = "conversation.created" + """CONVERSATION_CREATED.""" + CONVERSATION_ITEM_CREATED = "conversation.item.created" + """CONVERSATION_ITEM_CREATED.""" + CONVERSATION_ITEM_DELETED = "conversation.item.deleted" + """CONVERSATION_ITEM_DELETED.""" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED = "conversation.item.input_audio_transcription.completed" + """CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED.""" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA = "conversation.item.input_audio_transcription.delta" + """CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA.""" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED = "conversation.item.input_audio_transcription.failed" + """CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED.""" + CONVERSATION_ITEM_RETRIEVED = "conversation.item.retrieved" + """CONVERSATION_ITEM_RETRIEVED.""" + CONVERSATION_ITEM_TRUNCATED = "conversation.item.truncated" + """CONVERSATION_ITEM_TRUNCATED.""" + ERROR = "error" + """ERROR.""" + INPUT_AUDIO_BUFFER_CLEARED = "input_audio_buffer.cleared" + """INPUT_AUDIO_BUFFER_CLEARED.""" + INPUT_AUDIO_BUFFER_COMMITTED = "input_audio_buffer.committed" + """INPUT_AUDIO_BUFFER_COMMITTED.""" + INPUT_AUDIO_BUFFER_DTMF_EVENT_RECEIVED = "input_audio_buffer.dtmf_event_received" + """INPUT_AUDIO_BUFFER_DTMF_EVENT_RECEIVED.""" + INPUT_AUDIO_BUFFER_SPEECH_STARTED = "input_audio_buffer.speech_started" + """INPUT_AUDIO_BUFFER_SPEECH_STARTED.""" + INPUT_AUDIO_BUFFER_SPEECH_STOPPED = "input_audio_buffer.speech_stopped" + """INPUT_AUDIO_BUFFER_SPEECH_STOPPED.""" + RATE_LIMITS_UPDATED = "rate_limits.updated" + """RATE_LIMITS_UPDATED.""" + RESPONSE_OUTPUT_AUDIO_DELTA = "response.output_audio.delta" + """RESPONSE_OUTPUT_AUDIO_DELTA.""" + RESPONSE_OUTPUT_AUDIO_DONE = "response.output_audio.done" + """RESPONSE_OUTPUT_AUDIO_DONE.""" + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA = "response.output_audio_transcript.delta" + """RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA.""" + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE = "response.output_audio_transcript.done" + """RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE.""" + RESPONSE_CONTENT_PART_ADDED = "response.content_part.added" + """RESPONSE_CONTENT_PART_ADDED.""" + RESPONSE_CONTENT_PART_DONE = "response.content_part.done" + """RESPONSE_CONTENT_PART_DONE.""" + RESPONSE_CREATED = "response.created" + """RESPONSE_CREATED.""" + RESPONSE_DONE = "response.done" + """RESPONSE_DONE.""" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA = "response.function_call_arguments.delta" + """RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA.""" + RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE = "response.function_call_arguments.done" + """RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE.""" + RESPONSE_OUTPUT_ITEM_ADDED = "response.output_item.added" + """RESPONSE_OUTPUT_ITEM_ADDED.""" + RESPONSE_OUTPUT_ITEM_DONE = "response.output_item.done" + """RESPONSE_OUTPUT_ITEM_DONE.""" + RESPONSE_OUTPUT_TEXT_DELTA = "response.output_text.delta" + """RESPONSE_OUTPUT_TEXT_DELTA.""" + RESPONSE_OUTPUT_TEXT_DONE = "response.output_text.done" + """RESPONSE_OUTPUT_TEXT_DONE.""" + SESSION_CREATED = "session.created" + """SESSION_CREATED.""" + SESSION_UPDATED = "session.updated" + """SESSION_UPDATED.""" + OUTPUT_AUDIO_BUFFER_STARTED = "output_audio_buffer.started" + """OUTPUT_AUDIO_BUFFER_STARTED.""" + OUTPUT_AUDIO_BUFFER_STOPPED = "output_audio_buffer.stopped" + """OUTPUT_AUDIO_BUFFER_STOPPED.""" + OUTPUT_AUDIO_BUFFER_CLEARED = "output_audio_buffer.cleared" + """OUTPUT_AUDIO_BUFFER_CLEARED.""" + CONVERSATION_ITEM_ADDED = "conversation.item.added" + """CONVERSATION_ITEM_ADDED.""" + CONVERSATION_ITEM_DONE = "conversation.item.done" + """CONVERSATION_ITEM_DONE.""" + INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED = "input_audio_buffer.timeout_triggered" + """INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED.""" + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT = "conversation.item.input_audio_transcription.segment" + """CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT.""" + MCP_LIST_TOOLS_IN_PROGRESS = "mcp_list_tools.in_progress" + """MCP_LIST_TOOLS_IN_PROGRESS.""" + MCP_LIST_TOOLS_COMPLETED = "mcp_list_tools.completed" + """MCP_LIST_TOOLS_COMPLETED.""" + MCP_LIST_TOOLS_FAILED = "mcp_list_tools.failed" + """MCP_LIST_TOOLS_FAILED.""" + RESPONSE_MCP_CALL_ARGUMENTS_DELTA = "response.mcp_call_arguments.delta" + """RESPONSE_MCP_CALL_ARGUMENTS_DELTA.""" + RESPONSE_MCP_CALL_ARGUMENTS_DONE = "response.mcp_call_arguments.done" + """RESPONSE_MCP_CALL_ARGUMENTS_DONE.""" + RESPONSE_MCP_CALL_IN_PROGRESS = "response.mcp_call.in_progress" + """RESPONSE_MCP_CALL_IN_PROGRESS.""" + RESPONSE_MCP_CALL_COMPLETED = "response.mcp_call.completed" + """RESPONSE_MCP_CALL_COMPLETED.""" + RESPONSE_MCP_CALL_FAILED = "response.mcp_call.failed" + """RESPONSE_MCP_CALL_FAILED.""" + WARNING = "warning" + """WARNING.""" + SESSION_SUBAGENT_STARTED = "session.subagent.started" + """SESSION_SUBAGENT_STARTED.""" + SESSION_SUBAGENT_COMPLETED = "session.subagent.completed" + """SESSION_SUBAGENT_COMPLETED.""" + SESSION_SUBAGENT_ABORTED = "session.subagent.aborted" + """SESSION_SUBAGENT_ABORTED.""" + SESSION_AVATAR_CONNECTING = "session.avatar.connecting" + """SESSION_AVATAR_CONNECTING.""" + SESSION_AVATAR_SWITCH_TO_SPEAKING = "session.avatar.switch_to_speaking" + """SESSION_AVATAR_SWITCH_TO_SPEAKING.""" + SESSION_AVATAR_SWITCH_TO_IDLE = "session.avatar.switch_to_idle" + """SESSION_AVATAR_SWITCH_TO_IDLE.""" + RTC_CALL_SDP_CREATED = "rtc.call.sdp.created" + """RTC_CALL_SDP_CREATED.""" + RTC_CALL_ERROR = "rtc.call.error" + """RTC_CALL_ERROR.""" + RESPONSE_AUDIO_TIMESTAMP_DELTA = "response.audio_timestamp.delta" + """RESPONSE_AUDIO_TIMESTAMP_DELTA.""" + RESPONSE_AUDIO_TIMESTAMP_DONE = "response.audio_timestamp.done" + """RESPONSE_AUDIO_TIMESTAMP_DONE.""" + RESPONSE_ANIMATION_BLENDSHAPES_DELTA = "response.animation_blendshapes.delta" + """RESPONSE_ANIMATION_BLENDSHAPES_DELTA.""" + RESPONSE_ANIMATION_BLENDSHAPES_DONE = "response.animation_blendshapes.done" + """RESPONSE_ANIMATION_BLENDSHAPES_DONE.""" + RESPONSE_ANIMATION_VISEME_DELTA = "response.animation_viseme.delta" + """RESPONSE_ANIMATION_VISEME_DELTA.""" + RESPONSE_ANIMATION_VISEME_DONE = "response.animation_viseme.done" + """RESPONSE_ANIMATION_VISEME_DONE.""" + RESPONSE_VIDEO_DELTA = "response.video.delta" + """RESPONSE_VIDEO_DELTA.""" + + class ReasoningEffort(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Constrains effort on reasoning for reasoning models. Currently supported values are ``none``, ``minimal``, ``low``, ``medium``, ``high``, ``xhigh``, and ``max``. Reducing reasoning effort @@ -1307,6 +1602,418 @@ class TelemetryTransportProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): """gRPC transport protocol.""" +class TelephonyBindingStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The lifecycle status of a telephony binding.""" + + ACTIVE = "active" + """The binding accepts new inbound calls.""" + SUSPENDED = "suspended" + """The binding remains configured but rejects new inbound calls.""" + + +class TelephonyCallDurationBasis(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The timestamp used as the basis for call duration.""" + + ANSWERED = "answered" + """Duration starts when the provider reports the call as answered.""" + RECEIVED = "received" + """Duration starts when the inbound webhook is received because no answered timestamp is + available.""" + + +class TelephonyCallEndReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Known service-generated reasons that one telephony call ended, rather than reasons for an + overall outbound call job. Additional string codes may be returned. + """ + + INVALID_WEBHOOK_PAYLOAD = "invalid_webhook_payload" + """The provider webhook payload was invalid.""" + WEBHOOK_VALIDATION_FAILED = "webhook_validation_failed" + """Validation of the provider webhook failed.""" + BINDING_NOT_FOUND = "binding_not_found" + """No matching telephony binding was found.""" + BINDING_SUSPENDED = "binding_suspended" + """The telephony binding was suspended.""" + ADMISSION_REJECTED = "admission_rejected" + """The call was rejected by admission policy.""" + ADMISSION_CHECK_FAILED = "admission_check_failed" + """The service could not complete the call admission check.""" + ROUTE_AGENT_MISMATCH = "route_agent_mismatch" + """The webhook route did not match the resolved voice agent.""" + INVALID_BINDING_CONFIGURATION = "invalid_binding_configuration" + """The telephony binding configuration was invalid.""" + CREDENTIAL_RESOLUTION_FAILED = "credential_resolution_failed" + """The service could not resolve the telephony provider credentials.""" + PROVIDER_RESOURCE_MISMATCH = "provider_resource_mismatch" + """The provider resource did not match the configured telephony resource.""" + ENDPOINT_RESOLUTION_FAILED = "endpoint_resolution_failed" + """The service could not resolve the endpoint needed to handle the call.""" + INGRESS_SETUP_FAILED = "ingress_setup_failed" + """The service could not set up the incoming call.""" + LIVE_CALL_CONFLICT = "live_call_conflict" + """The call conflicted with an existing live call.""" + LIVE_CALL_PERSISTENCE_FAILED = "live_call_persistence_failed" + """The service could not persist the live call state.""" + ANSWER_FAILED = "answer_failed" + """The attempt to answer the provider call failed.""" + PROVIDER_DISCONNECTED = "provider_disconnected" + """The provider reported that the call disconnected.""" + PROVIDER_BUSY = "provider_busy" + """The provider reported that the destination was busy.""" + PROVIDER_NO_ANSWER = "provider_no_answer" + """The provider reported that the call was not answered.""" + PROVIDER_CANCELLED = "provider_cancelled" + """The provider reported that the call was cancelled.""" + PROVIDER_FAILED = "provider_failed" + """The provider reported that the call failed.""" + PROVIDER_STREAM_ERROR = "provider_stream_error" + """The provider reported a media-stream error.""" + PROVIDER_STREAM_STOPPED = "provider_stream_stopped" + """The provider reported that the media stream stopped.""" + AGENT_SESSION_CONNECT_FAILED = "agent_session_connect_failed" + """The call could not connect to the voice-agent session.""" + MEDIA_STREAM_ENDED = "media_stream_ended" + """The call's media stream ended.""" + BRIDGE_CANCELLED = "bridge_cancelled" + """The telephony media bridge was cancelled.""" + BRIDGE_FAILED = "bridge_failed" + """The telephony media bridge failed.""" + MANAGED_HANGUP = "managed_hangup" + """A managed call hang-up command succeeded.""" + MANAGED_TRANSFER = "managed_transfer" + """A managed call-transfer command succeeded.""" + MANAGE_HANGUP_FAILED = "manage_hangup_failed" + """A managed call hang-up command failed.""" + MANAGE_TRANSFER_FAILED = "manage_transfer_failed" + """A managed call-transfer command failed.""" + + +class TelephonyCallJobStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The lifecycle status of a durable outbound call job.""" + + ACCEPTED = "accepted" + """ACCEPTED.""" + WAITING_FOR_SCHEDULE = "waiting_for_schedule" + """WAITING_FOR_SCHEDULE.""" + QUEUED = "queued" + """QUEUED.""" + DISPATCHING = "dispatching" + """DISPATCHING.""" + IN_PROGRESS = "in_progress" + """IN_PROGRESS.""" + WAITING_FOR_RETRY = "waiting_for_retry" + """WAITING_FOR_RETRY.""" + CANCELLATION_REQUESTED = "cancellation_requested" + """CANCELLATION_REQUESTED.""" + COMPLETED = "completed" + """COMPLETED.""" + BLOCKED = "blocked" + """BLOCKED.""" + EXPIRED = "expired" + """EXPIRED.""" + FAILED = "failed" + """FAILED.""" + CANCELLED = "cancelled" + """CANCELLED.""" + + +class TelephonyCallJobTerminalReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Known terminal reasons for an overall outbound call job, which can span multiple provider + attempts. These are distinct from individual call lifecycle reasons. Additional string codes + may be returned. + """ + + NO_ANSWER = "no_answer" + """The provider call ended before the service observed it as connected.""" + NO_ANSWER_TIMEOUT = "no_answer_timeout" + """The provider accepted the call, but no connection was observed before the timeout and + cancellation was reconciled. This does not prove that the recipient never answered.""" + ANSWER_FAILED = "answer_failed" + """The attempt to answer the provider call failed.""" + BRIDGE_CANCELLED = "bridge_cancelled" + """The telephony media bridge was cancelled.""" + BRIDGE_FAILED = "bridge_failed" + """The telephony media bridge failed.""" + VOICE_SESSION_CONFIGURATION_INVALID = "voice_session_configuration_invalid" + """The voice-agent session configuration was invalid for outbound calling.""" + CONNECTION_PROJECT_MISMATCH = "connection_project_mismatch" + """The outbound call job's project context did not match its expected project.""" + OUTBOUND_CONNECTION_CHANGED = "outbound_connection_changed" + """The resolved outbound connection or caller identity no longer matched the call job + configuration.""" + OUTBOUND_CONNECTION_UNAVAILABLE = "outbound_connection_unavailable" + """The configured outbound connection could not be resolved or used.""" + TELEPHONY_BINDING_INVALID = "telephony_binding_invalid" + """The telephony binding was invalid for outbound calling.""" + TELEPHONY_BINDING_NOT_FOUND = "telephony_binding_not_found" + """The telephony binding could not be found.""" + TELEPHONY_BINDING_INACTIVE = "telephony_binding_inactive" + """The telephony binding was not active.""" + TELEPHONY_BINDING_CHANGED = "telephony_binding_changed" + """The telephony binding changed after the call job was configured.""" + CAMPAIGN_NOT_FOUND = "campaign_not_found" + """The campaign associated with the call job could not be found.""" + CAMPAIGN_CANCELLED = "campaign_cancelled" + """The campaign associated with the call job was cancelled.""" + CAMPAIGN_COMPLETED = "campaign_completed" + """The campaign associated with the call job had already completed.""" + CAMPAIGN_FAILED = "campaign_failed" + """The campaign associated with the call job had failed.""" + ORIGINATION_FENCE_NOT_RECORDED = "origination_fence_not_recorded" + """The service could not record the guard against duplicate call origination.""" + ORIGINATION_RECONCILIATION_TIMEOUT = "origination_reconciliation_timeout" + """The service could not reconcile the outcome of call origination before the timeout.""" + CANCELLATION_RECONCILIATION_TIMEOUT = "cancellation_reconciliation_timeout" + """The service could not confirm the outcome of call cancellation before the timeout.""" + PROVIDER_CALLBACK_TIMEOUT_CANCELLATION_RECONCILIATION_TIMEOUT = ( + "provider_callback_timeout_cancellation_reconciliation_timeout" + ) + """Provider callbacks timed out, and the service could not confirm the subsequent cancellation + before its reconciliation timeout.""" + + +class TelephonyCallLifecycleEventName(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A provider-neutral lifecycle event name. Known values are stable; additional values may be + added over time. + """ + + WEBHOOK_RECEIVED = "telephony.webhook.received" + """The provider webhook was received.""" + WEBHOOK_VALIDATION = "telephony.webhook.validation" + """The provider webhook was validated.""" + BINDING_RESOLVE = "telephony.binding.resolve" + """The service attempted to resolve the agent binding.""" + PROVIDER_ANSWER = "telephony.provider.answer" + """The service requested or observed provider answer state.""" + MEDIA_CONNECT = "telephony.media.connect" + """The provider media channel changed connection state.""" + AGENT_SESSION_CONNECT = "telephony.agent_session.connect" + """The voice-agent session changed connection state.""" + FIRST_CALLER_AUDIO = "telephony.media.first_caller_audio" + """The first caller audio was observed.""" + FIRST_AGENT_AUDIO = "telephony.media.first_agent_audio" + """The first agent audio was observed.""" + CALL_TRANSFER = "telephony.call.transfer" + """A call transfer changed state.""" + CALL_HANGUP = "telephony.call.hangup" + """A call hang-up changed state.""" + CALL_DISCONNECT = "telephony.call.disconnect" + """The call disconnected.""" + + +class TelephonyCallLifecycleEventOutcome(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The outcome of one telephony lifecycle observation.""" + + OBSERVED = "observed" + """The event was observed without a success or failure result.""" + STARTED = "started" + """The operation started.""" + SUCCEEDED = "succeeded" + """The operation succeeded.""" + FAILED = "failed" + """The operation failed.""" + REJECTED = "rejected" + """The operation or call was rejected.""" + CANCELLED = "cancelled" + """The operation was cancelled.""" + + +class TelephonyCallLifecycleEventReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Known service-generated reasons for a telephony lifecycle event. An event reason does not + necessarily describe the final outcome of the call. Additional string codes may be returned. + """ + + INVALID_WEBHOOK_PAYLOAD = "invalid_webhook_payload" + """The provider webhook payload was invalid.""" + WEBHOOK_VALIDATION_FAILED = "webhook_validation_failed" + """Validation of the provider webhook failed.""" + BINDING_NOT_FOUND = "binding_not_found" + """No matching telephony binding was found.""" + BINDING_SUSPENDED = "binding_suspended" + """The telephony binding was suspended.""" + ADMISSION_REJECTED = "admission_rejected" + """The call was rejected by admission policy.""" + ADMISSION_CHECK_FAILED = "admission_check_failed" + """The service could not complete the call admission check.""" + ROUTE_AGENT_MISMATCH = "route_agent_mismatch" + """The webhook route did not match the resolved voice agent.""" + INVALID_BINDING_CONFIGURATION = "invalid_binding_configuration" + """The telephony binding configuration was invalid.""" + CREDENTIAL_RESOLUTION_FAILED = "credential_resolution_failed" + """The service could not resolve the telephony provider credentials.""" + PROVIDER_RESOURCE_MISMATCH = "provider_resource_mismatch" + """The provider resource did not match the configured telephony resource.""" + ENDPOINT_RESOLUTION_FAILED = "endpoint_resolution_failed" + """The service could not resolve the endpoint needed to handle the call.""" + INGRESS_SETUP_FAILED = "ingress_setup_failed" + """The service could not set up the incoming call.""" + LIVE_CALL_CONFLICT = "live_call_conflict" + """The call conflicted with an existing live call.""" + LIVE_CALL_PERSISTENCE_FAILED = "live_call_persistence_failed" + """The service could not persist the live call state.""" + ANSWER_FAILED = "answer_failed" + """The attempt to answer the provider call failed.""" + PROVIDER_DISCONNECTED = "provider_disconnected" + """The provider reported that the call disconnected.""" + PROVIDER_BUSY = "provider_busy" + """The provider reported that the destination was busy.""" + PROVIDER_NO_ANSWER = "provider_no_answer" + """The provider reported that the call was not answered.""" + PROVIDER_CANCELLED = "provider_cancelled" + """The provider reported that the call was cancelled.""" + PROVIDER_FAILED = "provider_failed" + """The provider reported that the call failed.""" + PROVIDER_STREAM_ERROR = "provider_stream_error" + """The provider reported a media-stream error.""" + PROVIDER_STREAM_STOPPED = "provider_stream_stopped" + """The provider reported that the media stream stopped.""" + AGENT_SESSION_CONNECT_FAILED = "agent_session_connect_failed" + """The call could not connect to the voice-agent session.""" + MEDIA_STREAM_ENDED = "media_stream_ended" + """The call's media stream ended.""" + BRIDGE_CANCELLED = "bridge_cancelled" + """The telephony media bridge was cancelled.""" + BRIDGE_FAILED = "bridge_failed" + """The telephony media bridge failed.""" + MANAGED_HANGUP = "managed_hangup" + """A managed call hang-up command succeeded.""" + MANAGED_TRANSFER = "managed_transfer" + """A managed call-transfer command succeeded.""" + MANAGE_HANGUP_FAILED = "manage_hangup_failed" + """A managed call hang-up command failed.""" + MANAGE_TRANSFER_FAILED = "manage_transfer_failed" + """A managed call-transfer command failed.""" + + +class TelephonyCallLifecycleEventSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The component that supplied a telephony lifecycle observation.""" + + GATEWAY = "gateway" + """The Foundry telephony gateway supplied the observation.""" + TEAMS_PHONE_EXTENSION = "teams_phone_extension" + """Microsoft Teams Phone Extension supplied the observation.""" + TWILIO = "twilio" + """Twilio supplied the observation.""" + VOICE_AGENT = "voice_agent" + """The voice-agent runtime supplied the observation.""" + + +class TelephonyCallPhase(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The provider-neutral phase reached by an inbound telephony call.""" + + RECEIVED = "received" + """The provider webhook was received.""" + VALIDATED = "validated" + """The provider webhook was validated.""" + ADMITTED = "admitted" + """The call was admitted to a configured agent binding.""" + ANSWERING = "answering" + """The provider was asked to answer the call.""" + ANSWERED = "answered" + """The provider reported that the call was answered.""" + MEDIA_CONNECTED = "media_connected" + """The provider media channel was connected.""" + AGENT_SESSION_READY = "agent_session_ready" + """The voice-agent session was ready.""" + BRIDGING = "bridging" + """Media was actively bridged between the caller and the voice agent.""" + MANAGING = "managing" + """A mid-call management command was in progress.""" + COMPLETED = "completed" + """The call completed.""" + REJECTED = "rejected" + """The call was rejected before admission or answer.""" + FAILED = "failed" + """The call failed.""" + + +class TelephonyCallStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The lifecycle status of an inbound telephony call.""" + + IN_PROGRESS = "in_progress" + """The call has started and has not reached a terminal state.""" + SUCCESS = "success" + """The call ended successfully.""" + FAILED = "failed" + """The call ended because of a provider or management failure.""" + + +class TelephonyCallTimestampSource(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The source of a telephony lifecycle timestamp.""" + + PROVIDER = "provider" + """The telephony provider supplied the timestamp.""" + GATEWAY = "gateway" + """The Foundry telephony gateway observed the event.""" + DERIVED = "derived" + """The service derived the timestamp from another observation.""" + + +class TelephonyCallTraceMode(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The mode used to expose a telephony call as a customer-facing Foundry trace.""" + + LIVE = "live" + """The trace was created while the voice-agent conversation was live.""" + POST_CALL = "post_call" + """The trace summarizes a validated, customer-owned call that ended before a live voice-agent + conversation was created.""" + + +class TelephonyCallTraceStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The availability status of a customer-facing telephony call trace.""" + + PENDING = "pending" + """Trace creation has not completed.""" + EMITTING = "emitting" + """Trace creation is in progress.""" + AVAILABLE = "available" + """The trace is available.""" + NOT_RECORDED = "not_recorded" + """Tracing was disabled or no trace listener recorded the call.""" + NOT_APPLICABLE = "not_applicable" + """The call was not eligible for a customer-facing trace.""" + FAILED = "failed" + """Trace creation failed.""" + + +class TelephonyOutboundDestinationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The type of destination for an outbound call.""" + + PHONE_NUMBER = "phone_number" + """An E.164 phone number.""" + + +class TelephonyOutboundRetryPolicyType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The retry strategy for an outbound call.""" + + FIXED_INTERVAL = "fixed_interval" + """Retry after a fixed interval between attempts.""" + + +class TelephonyProvider(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A telephony provider supported by an agent binding. Known values are stable; additional values + may be added over time. + """ + + TEAMS_PHONE_EXTENSION = "teams_phone_extension" + """Microsoft Teams Phone Extension.""" + TWILIO = "twilio" + """Twilio Programmable Voice.""" + + +class TelephonyTransferDestinationKind(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The kind of telephony transfer destination. Known values are stable; additional values may be + added over time. + """ + + PSTN = "pstn" + """A public switched telephone network destination.""" + TEAMS = "teams" + """A Microsoft Teams user or resource-account destination.""" + SIP = "sip" + """A Session Initiation Protocol destination.""" + + class TextResponseFormatConfigurationType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Type of TextResponseFormatConfigurationType.""" @@ -1355,6 +2062,17 @@ class ToolboxToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """WEB_IQ_PREVIEW.""" +class ToolChoiceOptions(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Tool choice mode.""" + + NONE = "none" + """NONE.""" + AUTO = "auto" + """AUTO.""" + REQUIRED = "required" + """REQUIRED.""" + + class ToolChoiceParamType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Type of ToolChoiceParamType.""" @@ -1454,6 +2172,8 @@ class ToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """TOOLBOX_SEARCH_PREVIEW.""" WEB_IQ_PREVIEW = "web_iq_preview" """WEB_IQ_PREVIEW.""" + GITHUB_COPILOT_TOOLSET_PREVIEW = "github_copilot_toolset_preview" + """GITHUB_COPILOT_TOOLSET_PREVIEW.""" A2_A = "a2a" """A2_A.""" AZURE_AI_SEARCH = "azure_ai_search" @@ -1462,6 +2182,8 @@ class ToolType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """AZURE_FUNCTION.""" BING_GROUNDING = "bing_grounding" """BING_GROUNDING.""" + BROWSER_AUTOMATION = "browser_automation" + """BROWSER_AUTOMATION.""" CAPTURE_STRUCTURED_OUTPUTS = "capture_structured_outputs" """CAPTURE_STRUCTURED_OUTPUTS.""" OPENAPI = "openapi" @@ -1506,3 +2228,276 @@ class VersionSelectorType(str, Enum, metaclass=CaseInsensitiveEnumMeta): FIXED_RATIO = "FixedRatio" """FIXED_RATIO.""" + + +class VoiceAgentAnimationOutputType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """An animation output produced by a voice-agent session.""" + + BLENDSHAPES = "blendshapes" + """BLENDSHAPES.""" + VISEME_ID = "viseme_id" + """VISEME_ID.""" + + +class VoiceAgentAudioTimestampType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """An output-audio timestamp kind supported by a voice agent.""" + + WORD = "word" + """Word-level timestamps.""" + + +class VoiceAgentAvatarOutputProtocol(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The transport used to deliver the avatar video stream.""" + + WEBRTC = "webrtc" + """WEBRTC.""" + WEBSOCKET = "websocket" + """WEBSOCKET.""" + + +class VoiceAgentAvatarType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The avatar type.""" + + VIDEO_AVATAR = "video_avatar" + """VIDEO_AVATAR.""" + PHOTO_AVATAR = "photo_avatar" + """PHOTO_AVATAR.""" + + +class VoiceAgentEchoCancellationReferenceSource( # pylint: disable=name-too-long + str, Enum, metaclass=CaseInsensitiveEnumMeta +): + """The source of reference audio used for echo cancellation.""" + + SERVER = "server" + """SERVER.""" + CLIENT = "client" + """CLIENT.""" + + +class VoiceAgentEndOfUtteranceDetectionModel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The semantic end-of-utterance detection model.""" + + SEMANTIC_DETECTION_V1 = "semantic_detection_v1" + """The default semantic detection model.""" + SEMANTIC_DETECTION_V1_EN = "semantic_detection_v1_en" + """The English-optimized semantic detection model.""" + SEMANTIC_DETECTION_V1_MULTILINGUAL = "semantic_detection_v1_multilingual" + """The multilingual semantic detection model.""" + SMART_END_OF_TURN_DETECTION = "smart_end_of_turn_detection" + """The smart end-of-turn detection model.""" + + +class VoiceAgentEndOfUtteranceThresholdLevel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The sensitivity threshold for semantic end-of-utterance detection.""" + + LOW = "low" + """The low sensitivity threshold.""" + MEDIUM = "medium" + """The medium sensitivity threshold.""" + HIGH = "high" + """The high sensitivity threshold.""" + DEFAULT = "default" + """The service-selected sensitivity threshold.""" + + +class VoiceAgentInputTranscriptionModel(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The input-audio transcription model identifier. This is a model name, not a Foundry deployment + name. Mirrors the transcription models supported by the managed voice backend, covering the + OpenAI Realtime transcription models plus the Azure and MAI models. Additional values may be + added over time. + """ + + WHISPER1 = "whisper-1" + """OpenAI Whisper.""" + GPT_REALTIME_WHISPER = "gpt-realtime-whisper" + """OpenAI GPT Realtime Whisper.""" + GPT4_O_TRANSCRIBE = "gpt-4o-transcribe" + """OpenAI GPT-4o transcribe.""" + GPT4_O_MINI_TRANSCRIBE = "gpt-4o-mini-transcribe" + """OpenAI GPT-4o mini transcribe.""" + GPT4_O_TRANSCRIBE_DIARIZE = "gpt-4o-transcribe-diarize" + """OpenAI GPT-4o transcribe with speaker diarization.""" + GPT_TRANSCRIBE = "gpt-transcribe" + """OpenAI GPT Transcribe.""" + GPT_LIVE_TRANSCRIBE = "gpt-live-transcribe" + """OpenAI GPT Live Transcribe.""" + MAI_TRANSCRIBE = "mai-transcribe" + """MAI transcription.""" + AZURE_SPEECH = "azure-speech" + """Azure AI Speech to text.""" + + +class VoiceAgentInterimResponseTrigger(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A condition that may trigger an interim response.""" + + LATENCY = "latency" + """LATENCY.""" + TOOL = "tool" + """TOOL.""" + + +class VoiceAgentNoiseReductionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The input audio noise reduction mode.""" + + NEAR_FIELD = "near_field" + """NEAR_FIELD.""" + FAR_FIELD = "far_field" + """FAR_FIELD.""" + AZURE_DEEP_NOISE_SUPPRESSION = "azure_deep_noise_suppression" + """Azure deep noise suppression.""" + + +class VoiceAgentSessionIncludeOption(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Additional fields that a voice-agent session may include in service outputs.""" + + INPUT_AUDIO_TRANSCRIPTION_LOGPROBS = "item.input_audio_transcription.logprobs" + """INPUT_AUDIO_TRANSCRIPTION_LOGPROBS.""" + INPUT_AUDIO_TRANSCRIPTION_PHRASES = "item.input_audio_transcription.phrases" + """INPUT_AUDIO_TRANSCRIPTION_PHRASES.""" + FILE_SEARCH_CALL_RESULTS = "file_search_call.results" + """FILE_SEARCH_CALL_RESULTS.""" + + +class VoiceAgentSubagentAbortReason(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The reason a subagent consultation was aborted.""" + + UNKNOWN_TARGET = "unknown_target" + """The requested subagent was not configured for the voice agent.""" + TIMEOUT = "timeout" + """The subagent invocation exceeded its configured timeout.""" + CANCELLED = "cancelled" + """The consultation was cancelled because the voice session ended.""" + STOPPED_BY_USER = "stopped_by_user" + """The consultation was stopped at the user's request.""" + SUPERSEDED = "superseded" + """The consultation was replaced by a newer request.""" + FAILED = "failed" + """The consultation failed.""" + + +class VoiceAgentSystemToolName(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A service-managed voice-session control action. Known values are stable; additional values may + be added over time. + """ + + END_CONVERSATION = "end_conversation" + """Ends the active conversation.""" + + +class VoiceAgentToolResponseScheduling(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """When a tool invocation creates a follow-up response. Additional values may be added over time.""" + + SILENT = "silent" + """Do not create a follow-up response after the service-executed tool invocation completes.""" + WHEN_IDLE = "when_idle" + """Create a follow-up response when the conversation is idle.""" + INTERRUPT = "interrupt" + """Interrupt the active response and create a follow-up response.""" + SKIP_IF_BUSY = "skip_if_busy" + """Create a follow-up response only when no response is active.""" + + +class VoiceAgentTurnDetectionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The turn-detection strategy. Additional values may be added over time.""" + + SERVER_VAD = "server_vad" + """Server-side voice activity detection.""" + SEMANTIC_VAD = "semantic_vad" + """Semantic voice activity detection.""" + AZURE_SEMANTIC_VAD = "azure_semantic_vad" + """Azure semantic voice activity detection.""" + AZURE_SEMANTIC_VAD_EN = "azure_semantic_vad_en" + """English-optimized Azure semantic voice activity detection.""" + AZURE_SEMANTIC_VAD_MULTILINGUAL = "azure_semantic_vad_multilingual" + """Multilingual Azure semantic voice activity detection.""" + + +class VoiceAudioCodec(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """An audio codec. Additional values may be added over time.""" + + PCM16 = "pcm16" + """16-bit pulse-code modulation.""" + PCMU = "pcmu" + """G.711 mu-law.""" + PCMA = "pcma" + """G.711 A-law.""" + + +class VoiceAudioContainerFormat(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """An audio container format. Additional values may be added over time.""" + + WAV = "wav" + """Waveform Audio File Format.""" + + +class VoiceAudioRole(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """A voice-audio participant role. Additional values may be added over time.""" + + USER = "user" + """Audio produced by the user.""" + AGENT = "agent" + """Audio produced by the agent.""" + + +class VoiceConversationStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The lifecycle status of a persisted voice conversation: + + * `in_progress`: the live session is active, or post-session persistence finalization is pending. + * `completed`: finalization succeeded after normal or client close, `end_conversation`, a max-duration `1001` close, + or a client or network disconnect that the service can still finalize. + * `failed`: a terminal service, bridge, storage, or unrecoverable transport failure prevented finalization. + """ + + IN_PROGRESS = "in_progress" + """The live session is active, or post-session persistence finalization is still pending.""" + COMPLETED = "completed" + """Persistence finalization succeeded. This includes normal or client-initiated close, the + ``end_conversation`` system tool, a max-duration ``1001`` close, and client or network + disconnects that the service can still finalize.""" + FAILED = "failed" + """A terminal service, bridge, storage, or unrecoverable transport failure prevented persistence + finalization.""" + + +class VoiceModelType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """How the model backing a voice agent is served. This is independent of the architecture + (realtime or cascaded), which the service derives from the selected model. + """ + + MANAGED = "managed" + """The service hosts and manages the named model, for example ``gpt-realtime``.""" + SELF_DEPLOYED = "self_deployed" + """The service uses the customer's own Foundry deployment named by ``model``.""" + + +class VoiceOutputModality(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """An output modality the agent may produce. ``animation`` and ``avatar`` are used when an avatar + is configured. + """ + + TEXT = "text" + """TEXT.""" + AUDIO = "audio" + """AUDIO.""" + ANIMATION = "animation" + """ANIMATION.""" + AVATAR = "avatar" + """AVATAR.""" + + +class VoiceType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The voice implementation. Additional values may be added over time.""" + + OPENAI = "openai" + """An OpenAI voice.""" + AZURE_STANDARD = "azure-standard" + """An Azure standard voice.""" + AZURE_CUSTOM = "azure-custom" + """An Azure custom voice.""" + AZURE_PERSONAL = "azure-personal" + """An Azure personal voice.""" + AVATAR_VOICE_SYNC = "avatar-voice-sync" + """A voice synchronized with an avatar.""" + AZURE_REALTIME_NATIVE = "azure-realtime-native" + """An Azure native realtime voice.""" diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_models.py b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_models.py index 53167fbac63d..3ca198e821b9 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_models.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_models.py @@ -21,6 +21,7 @@ AgentOptimizationDatasetInputType, ContainerNetworkPolicyParamType, ContainerSkillType, + CreateTranscriptionResponseJsonUsageType, CredentialType, CustomToolParamFormatType, DataGenerationJobOutputType, @@ -40,6 +41,12 @@ MemoryStoreObjectType, OpenApiAuthType, PendingUploadType, + RealtimeAudioFormatsType, + RealtimeClientEventType, + RealtimeConversationItemMessageType, + RealtimeConversationItemType, + RealtimeMcpErrorType, + RealtimeServerEventType, RecurrenceType, RoutineActionType, RoutineDispatchPayloadType, @@ -48,6 +55,9 @@ ScheduleTaskType, TelemetryEndpointAuthType, TelemetryEndpointKind, + TelephonyOutboundRetryPolicyType, + TelephonyProvider, + TelephonyTransferDestinationKind, TextResponseFormatConfigurationType, ToolChoiceParamType, ToolType, @@ -55,6 +65,8 @@ TriggerType, VersionIndicatorType, VersionSelectorType, + VoiceAgentSystemToolName, + VoiceAgentTurnDetectionType, ) if TYPE_CHECKING: @@ -160,9 +172,10 @@ class Tool(_Model): # pylint: disable=docstring-keyword-should-match-keyword-on BingCustomSearchPreviewTool, BingGroundingTool, BrowserAutomationPreviewTool, CaptureStructuredOutputsTool, CodeInterpreterTool, ComputerTool, ComputerUsePreviewTool, CustomToolParam, MicrosoftFabricPreviewTool, FabricIQPreviewTool, FileSearchTool, FunctionTool, - ImageGenTool, LocalShellToolParam, MCPTool, MemorySearchPreviewTool, NamespaceToolParam, - OpenApiTool, ProgrammaticToolCallingParam, SharepointPreviewTool, FunctionShellToolParam, - ToolSearchToolParam, WebIQPreviewTool, WebSearchTool, WebSearchPreviewTool, WorkIQPreviewTool + GitHubCopilotToolsetPreview, ImageGenTool, LocalShellToolParam, MCPTool, + MemorySearchPreviewTool, NamespaceToolParam, OpenApiTool, ProgrammaticToolCallingParam, + SharepointPreviewTool, FunctionShellToolParam, ToolSearchToolParam, WebIQPreviewTool, + WebSearchTool, WebSearchPreviewTool, WorkIQPreviewTool :ivar type: Required. Known values are: "function", "file_search", "computer", "computer_use_preview", "web_search", "mcp", "code_interpreter", "programmatic_tool_calling", @@ -170,8 +183,8 @@ class Tool(_Model): # pylint: disable=docstring-keyword-should-match-keyword-on "web_search_preview", "apply_patch", "a2a_preview", "bing_custom_search_preview", "browser_automation_preview", "fabric_dataagent_preview", "sharepoint_grounding_preview", "memory_search_preview", "work_iq_preview", "fabric_iq_preview", "toolbox_search_preview", - "web_iq_preview", "a2a", "azure_ai_search", "azure_function", "bing_grounding", - "capture_structured_outputs", and "openapi". + "web_iq_preview", "github_copilot_toolset_preview", "a2a", "azure_ai_search", "azure_function", + "bing_grounding", "browser_automation", "capture_structured_outputs", and "openapi". :vartype type: str or ~azure.ai.projects.models.ToolType """ @@ -183,9 +196,9 @@ class Tool(_Model): # pylint: disable=docstring-keyword-should-match-keyword-on \"namespace\", \"tool_search\", \"web_search_preview\", \"apply_patch\", \"a2a_preview\", \"bing_custom_search_preview\", \"browser_automation_preview\", \"fabric_dataagent_preview\", \"sharepoint_grounding_preview\", \"memory_search_preview\", \"work_iq_preview\", - \"fabric_iq_preview\", \"toolbox_search_preview\", \"web_iq_preview\", \"a2a\", - \"azure_ai_search\", \"azure_function\", \"bing_grounding\", \"capture_structured_outputs\", - and \"openapi\".""" + \"fabric_iq_preview\", \"toolbox_search_preview\", \"web_iq_preview\", + \"github_copilot_toolset_preview\", \"a2a\", \"azure_ai_search\", \"azure_function\", + \"bing_grounding\", \"browser_automation\", \"capture_structured_outputs\", and \"openapi\".""" @overload def __init__( @@ -939,9 +952,11 @@ class AgentDefinition(_Model): # pylint: disable=docstring-keyword-should-match """AgentDefinition. You probably want to use the sub-classes and not this class directly. Known sub-classes are: - ExternalAgentDefinition, HostedAgentDefinition, PromptAgentDefinition, WorkflowAgentDefinition + ExternalAgentDefinition, HostedAgentDefinition, PromptAgentDefinition, VoiceAgentDefinition, + WorkflowAgentDefinition - :ivar kind: Required. Known values are: "prompt", "hosted", "workflow", and "external". + :ivar kind: Required. Known values are: "prompt", "hosted", "workflow", "external", and + "voice". :vartype kind: str or ~azure.ai.projects.models.AgentKind :ivar rai_config: Configuration for Responsible AI (RAI) content filtering and safety features. :vartype rai_config: ~azure.ai.projects.models.RaiConfig @@ -949,7 +964,7 @@ class AgentDefinition(_Model): # pylint: disable=docstring-keyword-should-match __mapping__: dict[str, _Model] = {} kind: str = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) - """Required. Known values are: \"prompt\", \"hosted\", \"workflow\", and \"external\".""" + """Required. Known values are: \"prompt\", \"hosted\", \"workflow\", \"external\", and \"voice\".""" rai_config: Optional["_models.RaiConfig"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Configuration for Responsible AI (RAI) content filtering and safety features.""" @@ -984,6 +999,10 @@ class AgentDetails(_Model): # pylint: disable=docstring-keyword-should-match-ke :ivar state: The operational state of the agent. Controls whether the agent endpoint accepts or rejects requests. Required. Known values are: "enabled" and "disabled". :vartype state: str or ~azure.ai.projects.models.AgentState + :ivar configuration_state: The administrative configuration state of the agent. This reflects + whether the agent was explicitly enabled or disabled, independently of identity-derived + operational state. Required. Known values are: "enabled" and "disabled". + :vartype configuration_state: str or ~azure.ai.projects.models.AgentState :ivar state_source: The source of the agent's operational state. When the agent is disabled, indicates where the disabled state originates from. Empty when not derived from a specific source. Known values are: "agent_instance_identity" and "agent_blueprint". @@ -1014,6 +1033,10 @@ class AgentDetails(_Model): # pylint: disable=docstring-keyword-should-match-ke state: Union[str, "_models.AgentState"] = rest_field(visibility=["read"]) """The operational state of the agent. Controls whether the agent endpoint accepts or rejects requests. Required. Known values are: \"enabled\" and \"disabled\".""" + configuration_state: Union[str, "_models.AgentState"] = rest_field(visibility=["read"]) + """The administrative configuration state of the agent. This reflects whether the agent was + explicitly enabled or disabled, independently of identity-derived operational state. Required. + Known values are: \"enabled\" and \"disabled\".""" state_source: Optional[Union[str, "_models.AgentStateSource"]] = rest_field(visibility=["read"]) """The source of the agent's operational state. When the agent is disabled, indicates where the disabled state originates from. Empty when not derived from a specific source. Known values @@ -1243,6 +1266,38 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: self.type = EvaluatorGenerationJobSourceType.AGENT # type: ignore +class AgentHarness(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A managed runtime and agent loop used to execute a prompt agent. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + GitHubCopilotHarness + + :ivar type: The type of managed harness. Required. Default value is None. + :vartype type: str + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The type of managed harness. Required. Default value is None.""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + class BaseCredentials(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """A base class for connection credentials. @@ -2936,6 +2991,10 @@ class AgentSessionResource(_Model): # pylint: disable=docstring-keyword-should- :ivar expires_at: The Unix timestamp (in seconds) when the session expires (rolling, 30 days from last activity). Required. :vartype expires_at: ~datetime.datetime + :ivar stopped_at: The Unix timestamp (in seconds) when the session sandbox was last observed to + stop or go idle. Present only after the session has gone idle at least once, used for accurate + idle-billing reconciliation. + :vartype stopped_at: ~datetime.datetime """ agent_session_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) @@ -2956,6 +3015,10 @@ class AgentSessionResource(_Model): # pylint: disable=docstring-keyword-should- expires_at: datetime.datetime = rest_field(visibility=["read"], format="unix-timestamp") """The Unix timestamp (in seconds) when the session expires (rolling, 30 days from last activity). Required.""" + stopped_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) when the session sandbox was last observed to stop or go idle. + Present only after the session has gone idle at least once, used for accurate idle-billing + reconciliation.""" @overload def __init__( @@ -5362,6 +5425,7 @@ class ComparisonFilter(_Model): # pylint: disable=docstring-keyword-should-matc * `in`: in * `nin`: not in. Required. Is one of the following types: Literal["eq"], Literal["ne"], Literal["gt"], Literal["gte"], Literal["lt"], Literal["lte"], Literal["in"], Literal["nin"] + :vartype type: str or str or str or str or str or str or str or str :ivar key: The key to compare against the value. Required. :vartype key: str @@ -6106,6 +6170,251 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class CreateTelephonyBindingRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The request to create a telephony binding. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + CreateTeamsPhoneExtensionTelephonyBindingRequest, CreateTwilioTelephonyBindingRequest + + :ivar provider: The telephony provider. Required. Known values are: "teams_phone_extension" and + "twilio". + :vartype provider: str or ~azure.ai.projects.models.TelephonyProvider + :ivar connection_name: The Foundry connection name for the telephony provider. Required. + :vartype connection_name: str + :ivar label: An optional display label for the binding. + :vartype label: str + """ + + __mapping__: dict[str, _Model] = {} + provider: str = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) + """The telephony provider. Required. Known values are: \"teams_phone_extension\" and \"twilio\".""" + connection_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Foundry connection name for the telephony provider. Required.""" + label: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional display label for the binding.""" + + @overload + def __init__( + self, + *, + provider: str, + connection_name: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class CreateTeamsPhoneExtensionTelephonyBindingRequest( + CreateTelephonyBindingRequest, discriminator="teams_phone_extension" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The request to create a Microsoft Teams Phone Extension binding. + + :ivar connection_name: The Foundry connection name for the telephony provider. Required. + :vartype connection_name: str + :ivar label: An optional display label for the binding. + :vartype label: str + :ivar provider: The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone + Extension. + :vartype provider: str or ~azure.ai.projects.models.TEAMS_PHONE_EXTENSION + :ivar phone_number: The optional display phone number for the Teams resource account. + :vartype phone_number: str + :ivar resource_account_object_id: The Microsoft Teams resource-account object identifier as a + GUID. Required. + :vartype resource_account_object_id: str + """ + + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone Extension.""" + phone_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The optional display phone number for the Teams resource account.""" + resource_account_object_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Microsoft Teams resource-account object identifier as a GUID. Required.""" + + @overload + def __init__( + self, + *, + connection_name: str, + resource_account_object_id: str, + label: Optional[str] = None, + phone_number: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TEAMS_PHONE_EXTENSION # type: ignore + + +class CreateTelephonyCallJobRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A request to create one durable direct outbound call job. + + :ivar destination: The phone destination to call. Required. + :vartype destination: ~azure.ai.projects.models.TelephonyOutboundDestination + :ivar connection_name: The Foundry connection name in the current project used to originate the + call. Its category selects Twilio or Azure Communication Services / Teams Phone Extension. No + inbound telephony binding is required. Required. + :vartype connection_name: str + :ivar source: The caller identity used to originate the call. For a Twilio connection, provide + an authorized E.164 phone number. For an Azure Communication Services / Teams Phone Extension + connection, provide the Teams Resource Account object ID. The identity type is inferred from + the connection category; originating does not change inbound routing. Required. + :vartype source: str + :ivar purpose: An optional customer-declared purpose for placing the call. + :vartype purpose: str + :ivar structured_inputs: Structured input values available to the agent and greeting for this + call. Agent-declared inputs are validated against their schemas; omitted optional inputs may + use their Agent-defined default values, while omitted required inputs are rejected. Additional + inputs remain available as dynamic template variables. + :vartype structured_inputs: dict[str, any] + :ivar schedule: The optional execution window. + :vartype schedule: ~azure.ai.projects.models.TelephonyCallJobSchedule + :ivar retry_policy: The provider-attempt retry policy. Omit it for one attempt with no retry + delay. + :vartype retry_policy: ~azure.ai.projects.models.TelephonyOutboundRetryPolicy + """ + + destination: "_models.TelephonyOutboundDestination" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The phone destination to call. Required.""" + connection_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Foundry connection name in the current project used to originate the call. Its category + selects Twilio or Azure Communication Services / Teams Phone Extension. No inbound telephony + binding is required. Required.""" + source: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The caller identity used to originate the call. For a Twilio connection, provide an authorized + E.164 phone number. For an Azure Communication Services / Teams Phone Extension connection, + provide the Teams Resource Account object ID. The identity type is inferred from the connection + category; originating does not change inbound routing. Required.""" + purpose: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional customer-declared purpose for placing the call.""" + structured_inputs: Optional[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Structured input values available to the agent and greeting for this call. Agent-declared + inputs are validated against their schemas; omitted optional inputs may use their Agent-defined + default values, while omitted required inputs are rejected. Additional inputs remain available + as dynamic template variables.""" + schedule: Optional["_models.TelephonyCallJobSchedule"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The optional execution window.""" + retry_policy: Optional["_models.TelephonyOutboundRetryPolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The provider-attempt retry policy. Omit it for one attempt with no retry delay.""" + + @overload + def __init__( + self, + *, + destination: "_models.TelephonyOutboundDestination", + connection_name: str, + source: str, + purpose: Optional[str] = None, + structured_inputs: Optional[dict[str, Any]] = None, + schedule: Optional["_models.TelephonyCallJobSchedule"] = None, + retry_policy: Optional["_models.TelephonyOutboundRetryPolicy"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class CreateTranscriptionResponseJsonUsage(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Token usage statistics for the request. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TranscriptTextUsageDuration, TranscriptTextUsageTokens + + :ivar type: Required. Known values are: "tokens" and "duration". + :vartype type: str or ~azure.ai.projects.models.CreateTranscriptionResponseJsonUsageType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"tokens\" and \"duration\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class CreateTwilioTelephonyBindingRequest( + CreateTelephonyBindingRequest, discriminator="twilio" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The request to create a Twilio binding. + + :ivar connection_name: The Foundry connection name for the telephony provider. Required. + :vartype connection_name: str + :ivar label: An optional display label for the binding. + :vartype label: str + :ivar provider: The Twilio provider. Required. Twilio Programmable Voice. + :vartype provider: str or ~azure.ai.projects.models.TWILIO + :ivar phone_number: The Twilio E.164 phone number. Required. + :vartype phone_number: str + """ + + provider: Literal[TelephonyProvider.TWILIO] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Twilio provider. Required. Twilio Programmable Voice.""" + phone_number: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Twilio E.164 phone number. Required.""" + + @overload + def __init__( + self, + *, + connection_name: str, + phone_number: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TWILIO # type: ignore + + class Trigger(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """Base model for Trigger of the schedule. @@ -6656,8 +6965,6 @@ class DataGenerationJobOptions(_Model): # pylint: disable=docstring-keyword-sho :ivar type: The data generation job type. Required. Known values are: "simple_qna", "traces", "tool_use", and "simulation_seed". :vartype type: str or ~azure.ai.projects.models.DataGenerationJobType - :ivar max_samples: Maximum number of samples to generate. Required. - :vartype max_samples: int :ivar train_split: The proportion of the generated data to be used for training when the data is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. :vartype train_split: float @@ -6669,8 +6976,6 @@ class DataGenerationJobOptions(_Model): # pylint: disable=docstring-keyword-sho type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) """The data generation job type. Required. Known values are: \"simple_qna\", \"traces\", \"tool_use\", and \"simulation_seed\".""" - max_samples: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Maximum number of samples to generate. Required.""" train_split: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The proportion of the generated data to be used for training when the data is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1.""" @@ -6684,7 +6989,6 @@ def __init__( self, *, type: str, - max_samples: int, train_split: Optional[float] = None, model_options: Optional["_models.DataGenerationModelOptions"] = None, ) -> None: ... @@ -6744,6 +7048,10 @@ class DataGenerationJobOutputOptions(_Model): # pylint: disable=docstring-keywo :ivar tags: Tags to assign to the output. Applies only to dataset outputs (evaluation scenario); ignored for Azure OpenAI file outputs. :vartype tags: dict[str, str] + :ivar write_mode: Controls how dataset outputs are written. If omitted, defaults to + ``overwrite`` and creates the next dataset version using only newly generated rows. Known + values are: "overwrite" and "merge". + :vartype write_mode: str or ~azure.ai.projects.models.DataGenerationJobOutputWriteMode """ name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @@ -6755,6 +7063,12 @@ class DataGenerationJobOutputOptions(_Model): # pylint: disable=docstring-keywo tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Tags to assign to the output. Applies only to dataset outputs (evaluation scenario); ignored for Azure OpenAI file outputs.""" + write_mode: Optional[Union[str, "_models.DataGenerationJobOutputWriteMode"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Controls how dataset outputs are written. If omitted, defaults to ``overwrite`` and creates the + next dataset version using only newly generated rows. Known values are: \"overwrite\" and + \"merge\".""" @overload def __init__( @@ -6763,6 +7077,7 @@ def __init__( name: Optional[str] = None, description: Optional[str] = None, tags: Optional[dict[str, str]] = None, + write_mode: Optional[Union[str, "_models.DataGenerationJobOutputWriteMode"]] = None, ) -> None: ... @overload @@ -9753,50 +10068,86 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: self.type: Literal["function"] = "function" -class GitHubIssueRoutineTrigger( - RoutineTrigger, discriminator="github_issue" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A GitHub issue routine trigger. +class GenerateVoiceAgentRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The inputs for generating a voice agent. Only ``kind`` and ``name`` are always required. The + authoring service expands these inputs into a full, editable ``VoiceAgentDefinition``, which is + then created through ``POST /agents``. The generated ``instructions`` and audio/voice settings + are stored as separate fields on the resulting agent definition, so the caller can edit or + override any of them afterward via standard agent versioning. - :ivar type: The trigger type. Required. A GitHub issue trigger. - :vartype type: str or ~azure.ai.projects.models.GITHUB_ISSUE - :ivar connection_id: The workspace connection identifier that resolves the GitHub configuration - for the trigger. Required. - :vartype connection_id: str - :ivar owner: The GitHub owner or organization that scopes which issues can fire the trigger. + :ivar kind: The agent kind. Always ``voice``. Required. VOICE. + :vartype kind: str or ~azure.ai.projects.models.VOICE + :ivar name: The unique name for the agent to create. Must be a non-empty DNS-like agent name. Required. - :vartype owner: str - :ivar repository: The GitHub repository filter that scopes which issues can fire the trigger. - Required. - :vartype repository: str - :ivar issue_event: The GitHub issue event that fires the routine. Required. Known values are: - "opened" and "closed". - :vartype issue_event: str or ~azure.ai.projects.models.GitHubIssueEvent + :vartype name: str + :ivar model_type: Optional inference mode. When omitted, the authoring service uses + ``managed``. When supplied, use ``managed`` or ``self_deployed``. Known values are: "managed" + and "self_deployed". + :vartype model_type: str or ~azure.ai.projects.models.VoiceModelType + :ivar model: Optional model identifier. Required when ``model_type`` is ``self_deployed``; + optional when ``model_type`` is ``managed`` or omitted. The service never invents a customer + deployment name. + :vartype model: str + :ivar use_case: An optional authoring use case. An empty string is accepted. + :vartype use_case: str + :ivar goal: An optional natural-language description of what the agent should do. When + supplied, it seeds the generated instructions. + :vartype goal: str + :ivar description: An optional agent description. The authoring service resolves its fallback + when omitted. + :vartype description: str + :ivar tools: Optional tools carried through verbatim onto the generated agent (see + ``VoiceAgentTool``). + :vartype tools: list[~azure.ai.projects.models.VoiceAgentTool] + :ivar draft: (Preview) When ``true``, the generated voice agent is created as a draft — an + editable, unpublished version the caller can review and refine before publishing it via the + standard create/version path. The service defaults to ``false`` if a value is not specified by + the caller, in which case the agent is created and published normally. + :vartype draft: bool """ - type: Literal[RoutineTriggerType.GITHUB_ISSUE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The trigger type. Required. A GitHub issue trigger.""" - connection_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The workspace connection identifier that resolves the GitHub configuration for the trigger. - Required.""" - owner: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The GitHub owner or organization that scopes which issues can fire the trigger. Required.""" - repository: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The GitHub repository filter that scopes which issues can fire the trigger. Required.""" - issue_event: Union[str, "_models.GitHubIssueEvent"] = rest_field( + kind: Literal[AgentKind.VOICE] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent kind. Always ``voice``. Required. VOICE.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique name for the agent to create. Must be a non-empty DNS-like agent name. Required.""" + model_type: Optional[Union[str, "_models.VoiceModelType"]] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The GitHub issue event that fires the routine. Required. Known values are: \"opened\" and - \"closed\".""" + """Optional inference mode. When omitted, the authoring service uses ``managed``. When supplied, + use ``managed`` or ``self_deployed``. Known values are: \"managed\" and \"self_deployed\".""" + model: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional model identifier. Required when ``model_type`` is ``self_deployed``; optional when + ``model_type`` is ``managed`` or omitted. The service never invents a customer deployment name.""" + use_case: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional authoring use case. An empty string is accepted.""" + goal: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional natural-language description of what the agent should do. When supplied, it seeds + the generated instructions.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional agent description. The authoring service resolves its fallback when omitted.""" + tools: Optional[list["_models.VoiceAgentTool"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional tools carried through verbatim onto the generated agent (see ``VoiceAgentTool``).""" + draft: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """(Preview) When ``true``, the generated voice agent is created as a draft — an editable, + unpublished version the caller can review and refine before publishing it via the standard + create/version path. The service defaults to ``false`` if a value is not specified by the + caller, in which case the agent is created and published normally.""" @overload def __init__( self, *, - connection_id: str, - owner: str, - repository: str, - issue_event: Union[str, "_models.GitHubIssueEvent"], + kind: Literal[AgentKind.VOICE], + name: str, + model_type: Optional[Union[str, "_models.VoiceModelType"]] = None, + model: Optional[str] = None, + use_case: Optional[str] = None, + goal: Optional[str] = None, + description: Optional[str] = None, + tools: Optional[list["_models.VoiceAgentTool"]] = None, + draft: Optional[bool] = None, ) -> None: ... @overload @@ -9808,28 +10159,23 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = RoutineTriggerType.GITHUB_ISSUE # type: ignore -class TelemetryEndpointAuth(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Authentication configuration for a telemetry endpoint. - - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - HeaderTelemetryEndpointAuth +class GitHubCopilotHarness(AgentHarness, discriminator="github_copilot_preview"): + """The GitHub Copilot managed harness for prompt agents. - :ivar type: The authentication type. Required. "header" - :vartype type: str or ~azure.ai.projects.models.TelemetryEndpointAuthType + :ivar type: The type of managed harness. Always ``github_copilot_preview``. Required. Default + value is "github_copilot_preview". + :vartype type: str """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """The authentication type. Required. \"header\"""" + type: Literal["github_copilot_preview"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of managed harness. Always ``github_copilot_preview``. Required. Default value is + \"github_copilot_preview\".""" @overload def __init__( self, - *, - type: str, ) -> None: ... @overload @@ -9841,41 +10187,245 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "github_copilot_preview" # type: ignore -class HeaderTelemetryEndpointAuth( - TelemetryEndpointAuth, discriminator="header" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Header-based secret authentication for a telemetry endpoint. The resolved secret value is - injected as an HTTP header. +class GitHubCopilotToolsetConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An enablement override for a GitHub Copilot built-in tool. - :ivar type: The authentication type, always 'header' for header-based secret authentication. - Required. Header-based secret authentication. - :vartype type: str or ~azure.ai.projects.models.HEADER - :ivar header_name: The name of the HTTP header to inject the secret value into. Required. - :vartype header_name: str - :ivar secret_id: The identifier of the secret store or connection. Required. - :vartype secret_id: str - :ivar secret_key: The key within the secret to retrieve the authentication value. Required. - :vartype secret_key: str + :ivar name: The built-in tool to configure. Required. Known values are: "filesystem_read", + "filesystem_write", "shell", "web", and "subagents". + :vartype name: str or ~azure.ai.projects.models.GitHubCopilotBuiltInTool + :ivar enabled: Whether the built-in tool is enabled. If omitted, the toolset default applies. + :vartype enabled: bool """ - type: Literal[TelemetryEndpointAuthType.HEADER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The authentication type, always 'header' for header-based secret authentication. Required. - Header-based secret authentication.""" - header_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the HTTP header to inject the secret value into. Required.""" - secret_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The identifier of the secret store or connection. Required.""" - secret_key: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The key within the secret to retrieve the authentication value. Required.""" + name: Union[str, "_models.GitHubCopilotBuiltInTool"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The built-in tool to configure. Required. Known values are: \"filesystem_read\", + \"filesystem_write\", \"shell\", \"web\", and \"subagents\".""" + enabled: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the built-in tool is enabled. If omitted, the toolset default applies.""" @overload def __init__( self, *, - header_name: str, - secret_id: str, + name: Union[str, "_models.GitHubCopilotBuiltInTool"], + enabled: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class GitHubCopilotToolsetDefaultConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The default enablement setting for GitHub Copilot built-in tools. + + :ivar enabled: Whether built-in tools are enabled by default. Defaults to true. + :vartype enabled: bool + """ + + enabled: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether built-in tools are enabled by default. Defaults to true.""" + + @overload + def __init__( + self, + *, + enabled: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class GitHubCopilotToolsetPreview( + Tool, discriminator="github_copilot_toolset_preview" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Configuration overrides for GitHub Copilot built-in tools. + + :ivar type: The type of the toolset. Always ``github_copilot_toolset_preview``. Required. + GITHUB_COPILOT_TOOLSET_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.GITHUB_COPILOT_TOOLSET_PREVIEW + :ivar default_config: The default configuration for built-in tools. If omitted, built-in tools + are enabled by default. + :vartype default_config: ~azure.ai.projects.models.GitHubCopilotToolsetDefaultConfig + :ivar configs: Per-tool configuration overrides. Duplicate built-in tool names are not allowed. + :vartype configs: list[~azure.ai.projects.models.GitHubCopilotToolsetConfig] + """ + + type: Literal[ToolType.GITHUB_COPILOT_TOOLSET_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the toolset. Always ``github_copilot_toolset_preview``. Required. + GITHUB_COPILOT_TOOLSET_PREVIEW.""" + default_config: Optional["_models.GitHubCopilotToolsetDefaultConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The default configuration for built-in tools. If omitted, built-in tools are enabled by + default.""" + configs: Optional[list["_models.GitHubCopilotToolsetConfig"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Per-tool configuration overrides. Duplicate built-in tool names are not allowed.""" + + @overload + def __init__( + self, + *, + default_config: Optional["_models.GitHubCopilotToolsetDefaultConfig"] = None, + configs: Optional[list["_models.GitHubCopilotToolsetConfig"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolType.GITHUB_COPILOT_TOOLSET_PREVIEW # type: ignore + + +class GitHubIssueRoutineTrigger( + RoutineTrigger, discriminator="github_issue" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A GitHub issue routine trigger. + + :ivar type: The trigger type. Required. A GitHub issue trigger. + :vartype type: str or ~azure.ai.projects.models.GITHUB_ISSUE + :ivar connection_id: The workspace connection identifier that resolves the GitHub configuration + for the trigger. Required. + :vartype connection_id: str + :ivar owner: The GitHub owner or organization that scopes which issues can fire the trigger. + Required. + :vartype owner: str + :ivar repository: The GitHub repository filter that scopes which issues can fire the trigger. + Required. + :vartype repository: str + :ivar issue_event: The GitHub issue event that fires the routine. Required. Known values are: + "opened" and "closed". + :vartype issue_event: str or ~azure.ai.projects.models.GitHubIssueEvent + """ + + type: Literal[RoutineTriggerType.GITHUB_ISSUE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The trigger type. Required. A GitHub issue trigger.""" + connection_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The workspace connection identifier that resolves the GitHub configuration for the trigger. + Required.""" + owner: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The GitHub owner or organization that scopes which issues can fire the trigger. Required.""" + repository: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The GitHub repository filter that scopes which issues can fire the trigger. Required.""" + issue_event: Union[str, "_models.GitHubIssueEvent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The GitHub issue event that fires the routine. Required. Known values are: \"opened\" and + \"closed\".""" + + @overload + def __init__( + self, + *, + connection_id: str, + owner: str, + repository: str, + issue_event: Union[str, "_models.GitHubIssueEvent"], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RoutineTriggerType.GITHUB_ISSUE # type: ignore + + +class TelemetryEndpointAuth(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Authentication configuration for a telemetry endpoint. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + HeaderTelemetryEndpointAuth + + :ivar type: The authentication type. Required. "header" + :vartype type: str or ~azure.ai.projects.models.TelemetryEndpointAuthType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The authentication type. Required. \"header\"""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class HeaderTelemetryEndpointAuth( + TelemetryEndpointAuth, discriminator="header" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Header-based secret authentication for a telemetry endpoint. The resolved secret value is + injected as an HTTP header. + + :ivar type: The authentication type, always 'header' for header-based secret authentication. + Required. Header-based secret authentication. + :vartype type: str or ~azure.ai.projects.models.HEADER + :ivar header_name: The name of the HTTP header to inject the secret value into. Required. + :vartype header_name: str + :ivar secret_id: The identifier of the secret store or connection. Required. + :vartype secret_id: str + :ivar secret_key: The key within the secret to retrieve the authentication value. Required. + :vartype secret_key: str + """ + + type: Literal[TelemetryEndpointAuthType.HEADER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The authentication type, always 'header' for header-based secret authentication. Required. + Header-based secret authentication.""" + header_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the HTTP header to inject the secret value into. Required.""" + secret_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the secret store or connection. Required.""" + secret_key: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The key within the secret to retrieve the authentication value. Required.""" + + @overload + def __init__( + self, + *, + header_name: str, + secret_id: str, secret_key: str, ) -> None: ... @@ -10996,6 +11546,44 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class LogProbProperties(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A log probability object. + + :ivar token: The token that was used to generate the log probability. Required. + :vartype token: str + :ivar logprob: The log probability of the token. Required. + :vartype logprob: float + :ivar bytes: The bytes that were used to generate the log probability. Required. + :vartype bytes: list[int] + """ + + token: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The token that was used to generate the log probability. Required.""" + logprob: float = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The log probability of the token. Required.""" + bytes: list[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The bytes that were used to generate the log probability. Required.""" + + @overload + def __init__( + self, + *, + token: str, + logprob: float, + bytes: list[int], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + class LoraConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """Adapter-specific metadata for LoRA models. Drives serving engine configuration at deployment time. @@ -11126,6 +11714,59 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: self.type = IndexType.MANAGED_AZURE_SEARCH # type: ignore +class MCPListToolsTool(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """MCP list tools tool. + + :ivar name: The name of the tool. Required. + :vartype name: str + :ivar description: + :vartype description: str + :ivar input_schema: The JSON schema describing the tool's input. Required. + :vartype input_schema: ~azure.ai.projects.models.MCPListToolsToolInputSchema + :ivar annotations: + :vartype annotations: ~azure.ai.projects.models.MCPListToolsToolAnnotations + """ + + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the tool. Required.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + input_schema: "_models.MCPListToolsToolInputSchema" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The JSON schema describing the tool's input. Required.""" + annotations: Optional["_models.MCPListToolsToolAnnotations"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + name: str, + input_schema: "_models.MCPListToolsToolInputSchema", + description: Optional[str] = None, + annotations: Optional["_models.MCPListToolsToolAnnotations"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class MCPListToolsToolAnnotations(_Model): + """MCPListToolsToolAnnotations.""" + + +class MCPListToolsToolInputSchema(_Model): + """MCPListToolsToolInputSchema.""" + + class McpProtocolConfiguration(_Model): """Configuration specific to the MCP protocol.""" @@ -11157,6 +11798,7 @@ class MCPTool(Tool, discriminator="mcp"): # pylint: disable=docstring-keyword-s Literal["connector_googledrive"], Literal["connector_microsoftteams"], Literal["connector_outlookcalendar"], Literal["connector_outlookemail"], Literal["connector_sharepoint"] + :vartype connector_id: str or str or str or str or str or str or str or str :ivar tunnel_id: The Secure MCP Tunnel ID to use instead of a direct server URL. One of ``server_url``, ``connector_id``, or ``tunnel_id`` must be provided. @@ -11330,6 +11972,7 @@ class MCPToolboxTool(ToolboxTool, discriminator="mcp"): # pylint: disable=docst Literal["connector_googledrive"], Literal["connector_microsoftteams"], Literal["connector_outlookcalendar"], Literal["connector_outlookemail"], Literal["connector_sharepoint"] + :vartype connector_id: str or str or str or str or str or str or str or str :ivar tunnel_id: The Secure MCP Tunnel ID to use instead of a direct server URL. One of ``server_url``, ``connector_id``, or ``tunnel_id`` must be provided. @@ -12128,6 +12771,15 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class Metadata(_Model): + """Set of 16 key-value pairs that can be attached to an object. This can be useful for storing + additional information about the object in a structured format, and querying for objects via + API or the dashboard. Keys are strings with a maximum length of 64 characters. Values are + strings with a maximum length of 512 characters. + + """ + + class Microsoft365PermissionScopes(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """A set of delegated permission scopes requested from a single resource application. @@ -13523,16 +14175,46 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class ProceduralMemoryItem( - MemoryItem, discriminator="procedural" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A memory item containing a procedure extracted from conversations. +class PickPropertiesVoiceAgentAudioConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The template for picking properties. - :ivar memory_id: The unique ID of the memory item. Required. - :vartype memory_id: str - :ivar updated_at: The last update time of the memory item. Required. - :vartype updated_at: ~datetime.datetime - :ivar scope: The namespace that logically groups and isolates memories, such as a user ID. + :ivar output: Output (agent speech) audio configuration. + :vartype output: ~azure.ai.projects.models.VoiceAgentAudioOutputConfig + """ + + output: Optional["_models.VoiceAgentAudioOutputConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Output (agent speech) audio configuration.""" + + @overload + def __init__( + self, + *, + output: Optional["_models.VoiceAgentAudioOutputConfig"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ProceduralMemoryItem( + MemoryItem, discriminator="procedural" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A memory item containing a procedure extracted from conversations. + + :ivar memory_id: The unique ID of the memory item. Required. + :vartype memory_id: str + :ivar updated_at: The last update time of the memory item. Required. + :vartype updated_at: ~datetime.datetime + :ivar scope: The namespace that logically groups and isolates memories, such as a user ID. Required. :vartype scope: str :ivar content: The content of the memory. Required. @@ -13645,10 +14327,15 @@ class PromptAgentDefinition( :vartype rai_config: ~azure.ai.projects.models.RaiConfig :ivar kind: Required. PROMPT. :vartype kind: str or ~azure.ai.projects.models.PROMPT + :ivar harness: The managed runtime and agent loop used to execute this prompt agent. + :vartype harness: ~azure.ai.projects.models.AgentHarness :ivar model: The model deployment to use for this agent. Required. :vartype model: str :ivar instructions: A system (or developer) message inserted into the model's context. :vartype instructions: str + :ivar skills: The Foundry skills available to this prompt agent. An omitted skill version is + resolved and pinned when the agent version is created. + :vartype skills: list[~azure.ai.projects.models.SkillReference] :ivar temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. We generally recommend altering this or ``top_p`` but not both. Defaults to @@ -13678,10 +14365,17 @@ class PromptAgentDefinition( kind: Literal[AgentKind.PROMPT] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore """Required. PROMPT.""" + harness: Optional["_models.AgentHarness"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The managed runtime and agent loop used to execute this prompt agent.""" model: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The model deployment to use for this agent. Required.""" instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """A system (or developer) message inserted into the model's context.""" + skills: Optional[list["_models.SkillReference"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The Foundry skills available to this prompt agent. An omitted skill version is resolved and + pinned when the agent version is created.""" temperature: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. We @@ -13718,7 +14412,9 @@ def __init__( *, model: str, rai_config: Optional["_models.RaiConfig"] = None, + harness: Optional["_models.AgentHarness"] = None, instructions: Optional[str] = None, + skills: Optional[list["_models.SkillReference"]] = None, temperature: Optional[float] = None, top_p: Optional[float] = None, reasoning: Optional["_models.Reasoning"] = None, @@ -13974,7 +14670,7 @@ class ProtocolVersionRecord(_Model): # pylint: disable=docstring-keyword-should """A record mapping for a single protocol and its version. :ivar protocol: The protocol type. Required. Known values are: "activity", "responses", "a2a", - "mcp", "invocations", and "invocations_ws". + "mcp", "invocations", "voice", and "invocations_ws". :vartype protocol: str or ~azure.ai.projects.models.AgentEndpointProtocol :ivar version: The version string for the protocol, e.g. 'v0.1.1'. Required. :vartype version: str @@ -13984,7 +14680,7 @@ class ProtocolVersionRecord(_Model): # pylint: disable=docstring-keyword-should visibility=["read", "create", "update", "delete", "query"] ) """The protocol type. Required. Known values are: \"activity\", \"responses\", \"a2a\", \"mcp\", - \"invocations\", and \"invocations_ws\".""" + \"invocations\", \"voice\", and \"invocations_ws\".""" version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The version string for the protocol, e.g. 'v0.1.1'. Required.""" @@ -14007,21 +14703,212 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) +class TelephonyTransferDestination(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A destination for a telephony transfer target. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + PSTNTelephonyTransferDestination, SipTelephonyTransferDestination, + TeamsTelephonyTransferDestination + + :ivar kind: The telephony transfer destination type. Required. Known values are: "pstn", + "teams", and "sip". + :vartype kind: str or ~azure.ai.projects.models.TelephonyTransferDestinationKind + """ + + __mapping__: dict[str, _Model] = {} + kind: str = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) + """The telephony transfer destination type. Required. Known values are: \"pstn\", \"teams\", and + \"sip\".""" + + @overload + def __init__( + self, + *, + kind: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class PSTNTelephonyTransferDestination( + TelephonyTransferDestination, discriminator="pstn" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A PSTN destination for a telephony transfer target. + + :ivar kind: The PSTN destination type. Required. A public switched telephone network + destination. + :vartype kind: str or ~azure.ai.projects.models.PSTN + :ivar value: The E.164 phone number to call. Required. + :vartype value: str + """ + + kind: Literal[TelephonyTransferDestinationKind.PSTN] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The PSTN destination type. Required. A public switched telephone network destination.""" + value: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The E.164 phone number to call. Required.""" + + @overload + def __init__( + self, + *, + value: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind = TelephonyTransferDestinationKind.PSTN # type: ignore + + class RaiConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """Configuration for Responsible AI (RAI) content filtering and safety features. :ivar rai_policy_name: The name of the RAI policy to apply. Required. :vartype rai_policy_name: str + :ivar invocations_moderation: Author-declared configuration telling the platform where + user/agent text lives in the agent-defined invocations request/response bodies, so + content-safety guardrails can extract and moderate it. Optional; a rai_config without it leaves + the invocations path without content-safety moderation. + :vartype invocations_moderation: ~azure.ai.projects.models.RaiInvocationModeration """ rai_policy_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The name of the RAI policy to apply. Required.""" + invocations_moderation: Optional["_models.RaiInvocationModeration"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Author-declared configuration telling the platform where user/agent text lives in the + agent-defined invocations request/response bodies, so content-safety guardrails can extract and + moderate it. Optional; a rai_config without it leaves the invocations path without + content-safety moderation.""" @overload def __init__( self, *, rai_policy_name: str, + invocations_moderation: Optional["_models.RaiInvocationModeration"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RaiInvocationModeration(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Declares where request/response text lives so content-safety guardrails can extract it. + + :ivar input_content_type: How the REQUEST body is parsed. When omitted, the service defaults to + ``json``. Known values are: "json" and "text". + :vartype input_content_type: str or ~azure.ai.projects.models.RaiInvocationContentType + :ivar output_content_type: How the RESPONSE body is parsed. When omitted, the service defaults + to ``json``. Known values are: "json" and "text". + :vartype output_content_type: str or ~azure.ai.projects.models.RaiInvocationContentType + :ivar response_mode: Author-declared response shape; drives which output gate runs and which + fields are required. Required. Known values are: "non_streaming", "streaming", and "both". + :vartype response_mode: str or ~azure.ai.projects.models.RaiInvocationMode + :ivar input_paths: Path(s) to user text in the REQUEST body. Required when input_content_type + is ``json``. + :vartype input_paths: list[str] + :ivar output_paths: Path(s) to agent text in a NON-STREAMING response body. Required when + response_mode is non_streaming/both and output_content_type is ``json``. + :vartype output_paths: list[str] + :ivar stream_selectors: One SSE event->field selector per event type carrying text. Required + when response_mode is streaming/both and output_content_type is ``json``. + :vartype stream_selectors: list[~azure.ai.projects.models.RaiSseTextSelector] + """ + + input_content_type: Optional[Union[str, "_models.RaiInvocationContentType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """How the REQUEST body is parsed. When omitted, the service defaults to ``json``. Known values + are: \"json\" and \"text\".""" + output_content_type: Optional[Union[str, "_models.RaiInvocationContentType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """How the RESPONSE body is parsed. When omitted, the service defaults to ``json``. Known values + are: \"json\" and \"text\".""" + response_mode: Union[str, "_models.RaiInvocationMode"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Author-declared response shape; drives which output gate runs and which fields are required. + Required. Known values are: \"non_streaming\", \"streaming\", and \"both\".""" + input_paths: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Path(s) to user text in the REQUEST body. Required when input_content_type is ``json``.""" + output_paths: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Path(s) to agent text in a NON-STREAMING response body. Required when response_mode is + non_streaming/both and output_content_type is ``json``.""" + stream_selectors: Optional[list["_models.RaiSseTextSelector"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """One SSE event->field selector per event type carrying text. Required when response_mode is + streaming/both and output_content_type is ``json``.""" + + @overload + def __init__( + self, + *, + response_mode: Union[str, "_models.RaiInvocationMode"], + input_content_type: Optional[Union[str, "_models.RaiInvocationContentType"]] = None, + output_content_type: Optional[Union[str, "_models.RaiInvocationContentType"]] = None, + input_paths: Optional[list[str]] = None, + output_paths: Optional[list[str]] = None, + stream_selectors: Optional[list["_models.RaiSseTextSelector"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RaiSseTextSelector(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An SSE event-type to text-field selector for streaming invocation output. + + :ivar event_type: The SSE event ``type`` value that carries text. Required. + :vartype event_type: str + :ivar text_field: The field on a matched event holding the text delta. When omitted, the + service defaults to ``delta``. + :vartype text_field: str + """ + + event_type: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The SSE event ``type`` value that carries text. Required.""" + text_field: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The field on a matched event holding the text delta. When omitted, the service defaults to + ``delta``.""" + + @overload + def __init__( + self, + *, + event_type: str, + text_field: Optional[str] = None, ) -> None: ... @overload @@ -14083,57 +14970,25 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class Reasoning(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Reasoning. +class RealtimeAudioFormats(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeAudioFormats. - :ivar mode: Controls the reasoning execution mode for the request. When returned on a response, - this is the effective execution mode. Known values are: "standard" and "pro". - :vartype mode: str or ~azure.ai.projects.models.ReasoningModeEnum - :ivar effort: Known values are: "none", "minimal", "low", "medium", "high", "xhigh", and "max". - :vartype effort: str or ~azure.ai.projects.models.ReasoningEffort - :ivar summary: Is one of the following types: Literal["auto"], Literal["concise"], - Literal["detailed"] - :vartype summary: str or str or str - :ivar context: Is one of the following types: Literal["auto"], Literal["current_turn"], - Literal["all_turns"] - :vartype context: str or str or str - :ivar generate_summary: Is one of the following types: Literal["auto"], Literal["concise"], - Literal["detailed"] - :vartype generate_summary: str or str or str + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeAudioFormatsAudioPcm, RealtimeAudioFormatsAudioPcma, RealtimeAudioFormatsAudioPcmu + + :ivar type: Required. Known values are: "audio/pcm", "audio/pcmu", and "audio/pcma". + :vartype type: str or ~azure.ai.projects.models.RealtimeAudioFormatsType """ - mode: Optional[Union[str, "_models.ReasoningModeEnum"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Controls the reasoning execution mode for the request. When returned on a response, this is the - effective execution mode. Known values are: \"standard\" and \"pro\".""" - effort: Optional[Union[str, "_models.ReasoningEffort"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Known values are: \"none\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", and \"max\".""" - summary: Optional[Literal["auto", "concise", "detailed"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Is one of the following types: Literal[\"auto\"], Literal[\"concise\"], Literal[\"detailed\"]""" - context: Optional[Literal["auto", "current_turn", "all_turns"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Is one of the following types: Literal[\"auto\"], Literal[\"current_turn\"], - Literal[\"all_turns\"]""" - generate_summary: Optional[Literal["auto", "concise", "detailed"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Is one of the following types: Literal[\"auto\"], Literal[\"concise\"], Literal[\"detailed\"]""" + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"audio/pcm\", \"audio/pcmu\", and \"audio/pcma\".""" @overload def __init__( self, *, - mode: Optional[Union[str, "_models.ReasoningModeEnum"]] = None, - effort: Optional[Union[str, "_models.ReasoningEffort"]] = None, - summary: Optional[Literal["auto", "concise", "detailed"]] = None, - context: Optional[Literal["auto", "current_turn", "all_turns"]] = None, - generate_summary: Optional[Literal["auto", "concise", "detailed"]] = None, + type: str, ) -> None: ... @overload @@ -14147,51 +15002,27 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class RecurrenceTrigger( - Trigger, discriminator="Recurrence" +class RealtimeAudioFormatsAudioPcm( + RealtimeAudioFormats, discriminator="audio/pcm" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """Recurrence based trigger. + """RealtimeAudioFormatsAudioPcm. - :ivar type: Type of the trigger. Required. Recurrence based trigger. - :vartype type: str or ~azure.ai.projects.models.RECURRENCE - :ivar start_time: Start time for the recurrence schedule in ISO 8601 format. - :vartype start_time: ~datetime.datetime - :ivar end_time: End time for the recurrence schedule in ISO 8601 format. - :vartype end_time: ~datetime.datetime - :ivar time_zone: Time zone for the recurrence schedule. Defaults to ``UTC``. - :vartype time_zone: str - :ivar interval: Interval for the recurrence schedule. Required. - :vartype interval: int - :ivar schedule: Recurrence schedule for the recurrence trigger. Required. - :vartype schedule: ~azure.ai.projects.models.RecurrenceSchedule + :ivar type: Required. AUDIO_PCM. + :vartype type: str or ~azure.ai.projects.models.AUDIO_PCM + :ivar rate: Default value is 24000. + :vartype rate: int """ - type: Literal[TriggerType.RECURRENCE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Type of the trigger. Required. Recurrence based trigger.""" - start_time: Optional[datetime.datetime] = rest_field( - name="startTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" - ) - """Start time for the recurrence schedule in ISO 8601 format.""" - end_time: Optional[datetime.datetime] = rest_field( - name="endTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" - ) - """End time for the recurrence schedule in ISO 8601 format.""" - time_zone: Optional[str] = rest_field(name="timeZone", visibility=["read", "create", "update", "delete", "query"]) - """Time zone for the recurrence schedule. Defaults to ``UTC``.""" - interval: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Interval for the recurrence schedule. Required.""" - schedule: "_models.RecurrenceSchedule" = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Recurrence schedule for the recurrence trigger. Required.""" + type: Literal[RealtimeAudioFormatsType.AUDIO_PCM] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. AUDIO_PCM.""" + rate: Optional[Literal[24000]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Default value is 24000.""" @overload def __init__( self, *, - interval: int, - schedule: "_models.RecurrenceSchedule", - start_time: Optional[datetime.datetime] = None, - end_time: Optional[datetime.datetime] = None, - time_zone: Optional[str] = None, + rate: Optional[Literal[24000]] = None, ) -> None: ... @overload @@ -14203,88 +15034,22 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = TriggerType.RECURRENCE # type: ignore + self.type = RealtimeAudioFormatsType.AUDIO_PCM # type: ignore -class RedTeam(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Red team details. +class RealtimeAudioFormatsAudioPcma(RealtimeAudioFormats, discriminator="audio/pcma"): + """RealtimeAudioFormatsAudioPcma. - :ivar name: Identifier of the red team run. Required. - :vartype name: str - :ivar display_name: Name of the red-team run. - :vartype display_name: str - :ivar num_turns: Number of simulation rounds. - :vartype num_turns: int - :ivar attack_strategies: List of attack strategies or nested lists of attack strategies. - :vartype attack_strategies: list[str or ~azure.ai.projects.models.AttackStrategy] - :ivar simulation_only: Simulation-only or Simulation + Evaluation. If ``true`` the scan outputs - conversation not evaluation result. The service defaults to ``false`` if a value is not - specified by the caller. - :vartype simulation_only: bool - :ivar risk_categories: List of risk categories to generate attack objectives for. - :vartype risk_categories: list[str or ~azure.ai.projects.models.RiskCategory] - :ivar application_scenario: Application scenario for the red team operation, to generate - scenario specific attacks. - :vartype application_scenario: str - :ivar tags: Red team's tags. Unlike properties, tags are fully mutable. - :vartype tags: dict[str, str] - :ivar properties: Red team's properties. Unlike tags, properties are add-only. Once added, a - property cannot be removed. - :vartype properties: dict[str, str] - :ivar status: Status of the red-team. It is set by service and is read-only. - :vartype status: str - :ivar target: Target configuration for the red-team run. Required. - :vartype target: ~azure.ai.projects.models.RedTeamTargetConfig + :ivar type: Required. AUDIO_PCMA. + :vartype type: str or ~azure.ai.projects.models.AUDIO_PCMA """ - name: str = rest_field(name="id", visibility=["read"]) - """Identifier of the red team run. Required.""" - display_name: Optional[str] = rest_field( - name="displayName", visibility=["read", "create", "update", "delete", "query"] - ) - """Name of the red-team run.""" - num_turns: Optional[int] = rest_field(name="numTurns", visibility=["read", "create", "update", "delete", "query"]) - """Number of simulation rounds.""" - attack_strategies: Optional[list[Union[str, "_models.AttackStrategy"]]] = rest_field( - name="attackStrategies", visibility=["read", "create", "update", "delete", "query"] - ) - """List of attack strategies or nested lists of attack strategies.""" - simulation_only: Optional[bool] = rest_field( - name="simulationOnly", visibility=["read", "create", "update", "delete", "query"] - ) - """Simulation-only or Simulation + Evaluation. If ``true`` the scan outputs conversation not - evaluation result. The service defaults to ``false`` if a value is not specified by the caller.""" - risk_categories: Optional[list[Union[str, "_models.RiskCategory"]]] = rest_field( - name="riskCategories", visibility=["read", "create", "update", "delete", "query"] - ) - """List of risk categories to generate attack objectives for.""" - application_scenario: Optional[str] = rest_field( - name="applicationScenario", visibility=["read", "create", "update", "delete", "query"] - ) - """Application scenario for the red team operation, to generate scenario specific attacks.""" - tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Red team's tags. Unlike properties, tags are fully mutable.""" - properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Red team's properties. Unlike tags, properties are add-only. Once added, a property cannot be - removed.""" - status: Optional[str] = rest_field(visibility=["read"]) - """Status of the red-team. It is set by service and is read-only.""" - target: "_models.RedTeamTargetConfig" = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Target configuration for the red-team run. Required.""" + type: Literal[RealtimeAudioFormatsType.AUDIO_PCMA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. AUDIO_PCMA.""" @overload def __init__( self, - *, - target: "_models.RedTeamTargetConfig", - display_name: Optional[str] = None, - num_turns: Optional[int] = None, - attack_strategies: Optional[list[Union[str, "_models.AttackStrategy"]]] = None, - simulation_only: Optional[bool] = None, - risk_categories: Optional[list[Union[str, "_models.RiskCategory"]]] = None, - application_scenario: Optional[str] = None, - tags: Optional[dict[str, str]] = None, - properties: Optional[dict[str, str]] = None, ) -> None: ... @overload @@ -14296,35 +15061,22 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeAudioFormatsType.AUDIO_PCMA # type: ignore -class ReminderPreviewToolboxTool( - ToolboxTool, discriminator="reminder_preview" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A reminder tool stored in a toolbox. +class RealtimeAudioFormatsAudioPcmu(RealtimeAudioFormats, discriminator="audio/pcmu"): + """RealtimeAudioFormatsAudioPcmu. - :ivar name: Optional user-defined name for this tool or configuration. - :vartype name: str - :ivar description: Optional user-defined description for this tool or configuration. - :vartype description: str - :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all - default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names - are silently ignored at runtime. - :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] - :ivar type: Required. REMINDER_PREVIEW. - :vartype type: str or ~azure.ai.projects.models.REMINDER_PREVIEW + :ivar type: Required. AUDIO_PCMU. + :vartype type: str or ~azure.ai.projects.models.AUDIO_PCMU """ - type: Literal[ToolboxToolType.REMINDER_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. REMINDER_PREVIEW.""" + type: Literal[RealtimeAudioFormatsType.AUDIO_PCMU] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. AUDIO_PCMU.""" @overload def __init__( self, - *, - name: Optional[str] = None, - description: Optional[str] = None, - tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, ) -> None: ... @overload @@ -14336,33 +15088,98 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolboxToolType.REMINDER_PREVIEW # type: ignore - + self.type = RealtimeAudioFormatsType.AUDIO_PCMU # type: ignore -class ResponsesProtocolConfiguration(_Model): - """Configuration specific to the responses protocol.""" +class RealtimeClientEvent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A realtime client event. -class ResponseUsageInputTokensDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """ResponseUsageInputTokensDetails. + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeClientEventConversationItemCreate, RealtimeClientEventConversationItemDelete, + RealtimeClientEventConversationItemRetrieve, RealtimeClientEventConversationItemTruncate, + RealtimeClientEventInputAudioBufferAppend, RealtimeClientEventInputAudioBufferClear, + RealtimeClientEventInputAudioBufferCommit, RealtimeClientEventOutputAudioBufferClear, + RealtimeClientEventResponseCancel, RealtimeClientEventResponseCreate, + VoiceAgentClientEventRtcCallSdpCreate, VoiceAgentClientEventSessionAvatarConnect - :ivar cached_tokens: Required. - :vartype cached_tokens: int - :ivar cache_write_tokens: Required. - :vartype cache_write_tokens: int + :ivar type: Required. Known values are: "conversation.item.create", "conversation.item.delete", + "conversation.item.retrieve", "conversation.item.truncate", "input_audio_buffer.append", + "input_audio_buffer.clear", "output_audio_buffer.clear", "input_audio_buffer.commit", + "response.cancel", "response.create", "session.update", "session.avatar.connect", and + "rtc.call.sdp.create". + :vartype type: str or ~azure.ai.projects.models.RealtimeClientEventType """ - cached_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Required.""" - cache_write_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"conversation.item.create\", \"conversation.item.delete\", + \"conversation.item.retrieve\", \"conversation.item.truncate\", \"input_audio_buffer.append\", + \"input_audio_buffer.clear\", \"output_audio_buffer.clear\", \"input_audio_buffer.commit\", + \"response.cancel\", \"response.create\", \"session.update\", \"session.avatar.connect\", and + \"rtc.call.sdp.create\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeClientEventConversationItemCreate( + RealtimeClientEvent, discriminator="conversation.item.create" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Add a new Item to the Conversation's context, including messages, function calls, and function + call responses. This event can be used both to populate a "history" of the conversation and to + add new items mid-stream, but has the current limitation that it cannot populate assistant + audio messages. If successful, the server will respond with a ``conversation.item.created`` + event, otherwise an ``error`` event will be sent. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.create``. Required. + CONVERSATION_ITEM_CREATE. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_CREATE + :ivar previous_item_id: The ID of the preceding item after which the new item will be inserted. + If not set, the new item will be appended to the end of the conversation. If set to ``root``, + the new item will be added to the beginning of the conversation. If set to an existing ID, it + allows an item to be inserted mid-conversation. If the ID cannot be found, an error will be + returned and the item will not be added. + :vartype previous_item_id: str + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_CREATE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.create``. Required. CONVERSATION_ITEM_CREATE.""" + previous_item_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the preceding item after which the new item will be inserted. If not set, the new + item will be appended to the end of the conversation. If set to ``root``, the new item will be + added to the beginning of the conversation. If set to an existing ID, it allows an item to be + inserted mid-conversation. If the ID cannot be found, an error will be returned and the item + will not be added.""" + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) """Required.""" @overload def __init__( self, *, - cached_tokens: int, - cache_write_tokens: int, + item: "_models.RealtimeConversationItem", + event_id: Optional[str] = None, + previous_item_id: Optional[str] = None, ) -> None: ... @overload @@ -14374,23 +15191,38 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.CONVERSATION_ITEM_CREATE # type: ignore -class ResponseUsageOutputTokensDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """ResponseUsageOutputTokensDetails. +class RealtimeClientEventConversationItemDelete( + RealtimeClientEvent, discriminator="conversation.item.delete" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Send this event when you want to remove any item from the conversation history. The server will + respond with a ``conversation.item.deleted`` event, unless the item does not exist in the + conversation history, in which case the server will respond with an error. - :ivar reasoning_tokens: Required. - :vartype reasoning_tokens: int + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.delete``. Required. + CONVERSATION_ITEM_DELETE. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_DELETE + :ivar item_id: The ID of the item to delete. Required. + :vartype item_id: str """ - reasoning_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Required.""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_DELETE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.delete``. Required. CONVERSATION_ITEM_DELETE.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item to delete. Required.""" @overload def __init__( self, *, - reasoning_tokens: int, + item_id: str, + event_id: Optional[str] = None, ) -> None: ... @overload @@ -14402,59 +15234,40 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.CONVERSATION_ITEM_DELETE # type: ignore -class Routine(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A routine definition returned by the service. +class RealtimeClientEventConversationItemRetrieve( + RealtimeClientEvent, discriminator="conversation.item.retrieve" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Send this event when you want to retrieve the server's representation of a specific item in the + conversation history. This is useful, for example, to inspect user audio after noise + cancellation and VAD. The server will respond with a ``conversation.item.retrieved`` event, + unless the item does not exist in the conversation history, in which case the server will + respond with an error. - :ivar name: The routine name. - :vartype name: str - :ivar description: A human-readable description of the routine. - :vartype description: str - :ivar enabled: Whether the routine is enabled. Required. - :vartype enabled: bool - :ivar triggers: The triggers configured for the routine. - :vartype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] - :ivar action: The action executed when the routine fires. - :vartype action: ~azure.ai.projects.models.RoutineAction - :ivar created_at: The time when the routine was created. - :vartype created_at: ~datetime.datetime - :ivar updated_at: The time when the routine was last updated. - :vartype updated_at: ~datetime.datetime + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.retrieve``. Required. + CONVERSATION_ITEM_RETRIEVE. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_RETRIEVE + :ivar item_id: The ID of the item to retrieve. Required. + :vartype item_id: str """ - name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The routine name.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of the routine.""" - enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Whether the routine is enabled. Required.""" - triggers: Optional[dict[str, "_models.RoutineTrigger"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The triggers configured for the routine.""" - action: Optional["_models.RoutineAction"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The action executed when the routine fires.""" - created_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The time when the routine was created.""" - updated_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The time when the routine was last updated.""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_RETRIEVE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.retrieve``. Required. CONVERSATION_ITEM_RETRIEVE.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item to retrieve. Required.""" @overload def __init__( self, *, - enabled: bool, - name: Optional[str] = None, - description: Optional[str] = None, - triggers: Optional[dict[str, "_models.RoutineTrigger"]] = None, - action: Optional["_models.RoutineAction"] = None, - created_at: Optional[datetime.datetime] = None, - updated_at: Optional[datetime.datetime] = None, + item_id: str, + event_id: Optional[str] = None, ) -> None: ... @overload @@ -14466,29 +15279,109 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.CONVERSATION_ITEM_RETRIEVE # type: ignore -class RoutineAuthorization(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Optional authorization configuration for a routine dispatch. +class RealtimeClientEventConversationItemTruncate( + RealtimeClientEvent, discriminator="conversation.item.truncate" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Send this event to truncate a previous assistant message’s audio. The server will produce audio + faster than realtime, so this event is useful when the user interrupts to truncate audio that + has already been sent to the client but not yet played. This will synchronize the server's + understanding of the audio with the client's playback. Truncating audio will delete the + server-side text transcript to ensure there is not text in the context that hasn't been heard + by the user. If successful, the server will respond with a ``conversation.item.truncated`` + event. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.truncate``. Required. + CONVERSATION_ITEM_TRUNCATE. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_TRUNCATE + :ivar item_id: The ID of the assistant message item to truncate. Only assistant message items + can be truncated. Required. + :vartype item_id: str + :ivar content_index: The index of the content part to truncate. Set this to ``0``. Required. + :vartype content_index: int + :ivar audio_end_ms: Inclusive duration up to which audio is truncated, in milliseconds. If the + audio_end_ms is greater than the actual audio duration, the server will respond with an error. + Required. + :vartype audio_end_ms: int + """ - :ivar identity: The identity used when dispatching the routine. Defaults to agent when omitted; - set to creator only when the customer opts in to creator identity dispatch. Known values are: - "agent" and "creator". - :vartype identity: str or ~azure.ai.projects.models.RoutineDispatchIdentity + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.CONVERSATION_ITEM_TRUNCATE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.truncate``. Required. CONVERSATION_ITEM_TRUNCATE.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the assistant message item to truncate. Only assistant message items can be + truncated. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part to truncate. Set this to ``0``. Required.""" + audio_end_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Inclusive duration up to which audio is truncated, in milliseconds. If the audio_end_ms is + greater than the actual audio duration, the server will respond with an error. Required.""" + + @overload + def __init__( + self, + *, + item_id: str, + content_index: int, + audio_end_ms: int, + event_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.CONVERSATION_ITEM_TRUNCATE # type: ignore + + +class RealtimeClientEventInputAudioBufferAppend( + RealtimeClientEvent, discriminator="input_audio_buffer.append" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Send this event to append audio bytes to the input audio buffer. The audio buffer is temporary + storage you can write to and later commit. A "commit" will create a new user message item in + the conversation history from the buffer content and clear the buffer. Input audio + transcription (if enabled) will be generated when the buffer is committed. If VAD is enabled + the audio buffer is used to detect speech and the server will decide when to commit. When + Server VAD is disabled, you must commit the audio buffer manually. Input audio noise reduction + operates on writes to the audio buffer. The client may choose how much audio to place in each + event up to a maximum of 15 MiB, for example streaming smaller chunks from the client may allow + the VAD to be more responsive. Unlike most other client events, the server will not send a + confirmation response to this event. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.append``. Required. + INPUT_AUDIO_BUFFER_APPEND. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_APPEND + :ivar audio: Base64-encoded audio bytes. This must be in the format specified by the + ``input_audio_format`` field in the session configuration. Required. + :vartype audio: str """ - identity: Optional[Union[str, "_models.RoutineDispatchIdentity"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The identity used when dispatching the routine. Defaults to agent when omitted; set to creator - only when the customer opts in to creator identity dispatch. Known values are: \"agent\" and - \"creator\".""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_APPEND] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.append``. Required. INPUT_AUDIO_BUFFER_APPEND.""" + audio: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Base64-encoded audio bytes. This must be in the format specified by the ``input_audio_format`` + field in the session configuration. Required.""" @overload def __init__( self, *, - identity: Optional[Union[str, "_models.RoutineDispatchIdentity"]] = None, + audio: str, + event_id: Optional[str] = None, ) -> None: ... @overload @@ -14500,164 +15393,9640 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.INPUT_AUDIO_BUFFER_APPEND # type: ignore -class RoutineRun(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A single routine run returned from the run history API. +class RealtimeClientEventInputAudioBufferClear( + RealtimeClientEvent, discriminator="input_audio_buffer.clear" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Send this event to clear the audio bytes in the buffer. The server will respond with an + ``input_audio_buffer.cleared`` event. - :ivar id: The unique run identifier for the routine attempt. Required. - :vartype id: str - :ivar status: The run status. Is one of the following types: str - :vartype status: str - :ivar phase: The AgentExtensions lifecycle phase for the routine attempt. Known values are: - "queued", "dispatching", "completed", and "failed". - :vartype phase: str or ~azure.ai.projects.models.RoutineRunPhase - :ivar trigger_type: The trigger type that produced the routine attempt. Known values are: - "custom", "github_issue", "schedule", and "timer". - :vartype trigger_type: str or ~azure.ai.projects.models.RoutineTriggerType - :ivar trigger_name: The configured trigger name that produced the routine attempt. - :vartype trigger_name: str - :ivar trigger_event_payload: The event payload captured from the event that triggered the - routine attempt, when available. - :vartype trigger_event_payload: dict[str, any] - :ivar attempt_source: The source path that created the routine attempt. Known values are: - "event_fire", "manual_dispatch", "queued_dispatch", "schedule_delivery", and "timer_delivery". - :vartype attempt_source: str or ~azure.ai.projects.models.RoutineAttemptSource - :ivar action_type: The action type dispatched for the routine attempt. Known values are: - "invoke_agent_responses_api" and "invoke_agent_invocations_api". - :vartype action_type: str or ~azure.ai.projects.models.RoutineActionType - :ivar agent_id: The project-scoped agent identifier recorded for the routine attempt. - :vartype agent_id: str - :ivar agent_endpoint_id: The legacy endpoint-scoped agent identifier recorded for the routine - attempt. - :vartype agent_endpoint_id: str - :ivar conversation_id: The conversation identifier used by a responses API dispatch. - :vartype conversation_id: str - :ivar session_id: The hosted-agent session identifier used by an invocations API dispatch. - :vartype session_id: str - :ivar triggered_at: The logical trigger time recorded for the routine attempt. - :vartype triggered_at: ~datetime.datetime - :ivar scheduled_fire_at: The scheduled fire time recorded for timer and schedule deliveries. - :vartype scheduled_fire_at: ~datetime.datetime - :ivar started_at: The time when the underlying run started. - :vartype started_at: ~datetime.datetime - :ivar ended_at: The time when the underlying run reached a terminal state. - :vartype ended_at: ~datetime.datetime - :ivar dispatch_id: The dispatch identifier associated with the routine attempt. - :vartype dispatch_id: str - :ivar action_correlation_id: The downstream action correlation identifier, when available. - :vartype action_correlation_id: str - :ivar response_id: The downstream response or invocation identifier, when available. - :vartype response_id: str - :ivar task_id: The workspace task identifier linked to the routine attempt, when available. - :vartype task_id: str - :ivar error_status_code: The downstream error status code captured for a failed attempt, when - available. - :vartype error_status_code: int - :ivar error_type: The fully qualified error type captured for a failed attempt, when available. - :vartype error_type: str - :ivar error_message: The truncated failure message captured for a failed attempt, when - available. - :vartype error_message: str + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.clear``. Required. + INPUT_AUDIO_BUFFER_CLEAR. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_CLEAR """ - id: str = rest_field(visibility=["read"]) - """The unique run identifier for the routine attempt. Required.""" - status: Optional["_unions.RoutineRunStatus"] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The run status. Is one of the following types: str""" - phase: Optional[Union[str, "_models.RoutineRunPhase"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The AgentExtensions lifecycle phase for the routine attempt. Known values are: \"queued\", - \"dispatching\", \"completed\", and \"failed\".""" - trigger_type: Optional[Union[str, "_models.RoutineTriggerType"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The trigger type that produced the routine attempt. Known values are: \"custom\", + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_CLEAR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.clear``. Required. INPUT_AUDIO_BUFFER_CLEAR.""" + + @overload + def __init__( + self, + *, + event_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.INPUT_AUDIO_BUFFER_CLEAR # type: ignore + + +class RealtimeClientEventInputAudioBufferCommit( + RealtimeClientEvent, discriminator="input_audio_buffer.commit" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Send this event to commit the user input audio buffer, which will create a new user message + item in the conversation. This event will produce an error if the input audio buffer is empty. + When in Server VAD mode, the client does not need to send this event, the server will commit + the audio buffer automatically. Committing the input audio buffer will trigger input audio + transcription (if enabled in session configuration), but it will not create a response from + the model. The server will respond with an ``input_audio_buffer.committed`` event. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.commit``. Required. + INPUT_AUDIO_BUFFER_COMMIT. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_COMMIT + """ + + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.INPUT_AUDIO_BUFFER_COMMIT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.commit``. Required. INPUT_AUDIO_BUFFER_COMMIT.""" + + @overload + def __init__( + self, + *, + event_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.INPUT_AUDIO_BUFFER_COMMIT # type: ignore + + +class RealtimeClientEventOutputAudioBufferClear( + RealtimeClientEvent, discriminator="output_audio_buffer.clear" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """**WebRTC/SIP Only:** Emit to cut off the current audio response. This will trigger the server + to stop generating audio and emit a ``output_audio_buffer.cleared`` event. This event should be + preceded by a ``response.cancel`` client event to stop the generation of the current response. + `Learn more + `_. + + :ivar event_id: The unique ID of the client event used for error handling. + :vartype event_id: str + :ivar type: The event type, must be ``output_audio_buffer.clear``. Required. + OUTPUT_AUDIO_BUFFER_CLEAR. + :vartype type: str or ~azure.ai.projects.models.OUTPUT_AUDIO_BUFFER_CLEAR + """ + + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the client event used for error handling.""" + type: Literal[RealtimeClientEventType.OUTPUT_AUDIO_BUFFER_CLEAR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``output_audio_buffer.clear``. Required. OUTPUT_AUDIO_BUFFER_CLEAR.""" + + @overload + def __init__( + self, + *, + event_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.OUTPUT_AUDIO_BUFFER_CLEAR # type: ignore + + +class RealtimeClientEventResponseCancel( + RealtimeClientEvent, discriminator="response.cancel" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Send this event to cancel an in-progress response. The server will respond with a + ``response.done`` event with a status of ``response.status=cancelled``. If there is no response + to cancel, the server will respond with an error. It's safe to call ``response.cancel`` even if + no response is in progress, an error will be returned the session will remain unaffected. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``response.cancel``. Required. RESPONSE_CANCEL. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_CANCEL + :ivar response_id: A specific response ID to cancel - if not provided, will cancel an + in-progress response in the default conversation. + :vartype response_id: str + """ + + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.RESPONSE_CANCEL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.cancel``. Required. RESPONSE_CANCEL.""" + response_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A specific response ID to cancel - if not provided, will cancel an in-progress response in the + default conversation.""" + + @overload + def __init__( + self, + *, + event_id: Optional[str] = None, + response_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.RESPONSE_CANCEL # type: ignore + + +class RealtimeClientEventResponseCreate( + RealtimeClientEvent, discriminator="response.create" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """This event instructs the server to create a Response, which means triggering model inference. + When in Server VAD mode, the server will create Responses automatically. A Response will + include at least one Item, and may have two, in which case the second will be a function call. + These Items will be appended to the conversation history by default. The server will respond + with a ``response.created`` event, events for Items and content created, and finally a + ``response.done`` event to indicate the Response is complete. The ``response.create`` event + includes inference configuration like ``instructions`` and ``tools``. If these are set, they + will override the Session's configuration for this Response only. Responses can be created + out-of-band of the default Conversation, meaning that they can have arbitrary input, and it's + possible to disable writing the output to the Conversation. Only one Response can write to the + default Conversation at a time, but otherwise multiple Responses can be created in parallel. + The ``metadata`` field is a good way to disambiguate multiple simultaneous Responses. Clients + can set ``conversation`` to ``none`` to create a Response that does not write to the default + Conversation. Arbitrary input can be provided with the ``input`` field, which is an array + accepting raw Items and references to existing Items. + + :ivar event_id: Optional client-generated ID used to identify this event. + :vartype event_id: str + :ivar type: The event type, must be ``response.create``. Required. RESPONSE_CREATE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_CREATE + :ivar response: + :vartype response: ~azure.ai.projects.models.VoiceAgentResponseCreateParams + """ + + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event.""" + type: Literal[RealtimeClientEventType.RESPONSE_CREATE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.create``. Required. RESPONSE_CREATE.""" + response: Optional["_models.VoiceAgentResponseCreateParams"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + event_id: Optional[str] = None, + response: Optional["_models.VoiceAgentResponseCreateParams"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeClientEventType.RESPONSE_CREATE # type: ignore + + +class RealtimeConversationItem(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A single item within a Realtime conversation. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeConversationItemFunctionCall, RealtimeConversationItemFunctionCallOutput, + RealtimeMCPApprovalRequest, RealtimeMCPApprovalResponse, RealtimeMCPToolCall, + RealtimeMCPListTools, RealtimeConversationItemMessage + + :ivar type: Required. Known values are: "function_call", "function_call_output", + "mcp_approval_response", "mcp_list_tools", "mcp_call", "mcp_approval_request", and "message". + :vartype type: str or ~azure.ai.projects.models.RealtimeConversationItemType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"function_call\", \"function_call_output\", + \"mcp_approval_response\", \"mcp_list_tools\", \"mcp_call\", \"mcp_approval_request\", and + \"message\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeConversationItemFunctionCall( + RealtimeConversationItem, discriminator="function_call" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime function call item. + + :ivar id: The unique ID of the item. This may be provided by the client or generated by the + server. + :vartype id: str + :ivar object: Identifier for the API object being returned - always ``realtime.item``. Optional + when creating a new item. Default value is "realtime.item". + :vartype object: str + :ivar type: The type of the item. Always ``function_call``. Required. FUNCTION_CALL. + :vartype type: str or ~azure.ai.projects.models.FUNCTION_CALL + :ivar status: The status of the item. Has no effect on the conversation. Is one of the + following types: Literal["completed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str + :ivar call_id: The ID of the function call. + :vartype call_id: str + :ivar name: The name of the function being called. Required. + :vartype name: str + :ivar arguments: The arguments of the function call. This is a JSON-encoded string representing + the arguments passed to the function, for example ``{"arg1": "value1", "arg2": 42}``. Required. + :vartype arguments: str + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the item. This may be provided by the client or generated by the server.""" + object: Optional[Literal["realtime.item"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Identifier for the API object being returned - always ``realtime.item``. Optional when creating + a new item. Default value is \"realtime.item\".""" + type: Literal[RealtimeConversationItemType.FUNCTION_CALL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``function_call``. Required. FUNCTION_CALL.""" + status: Optional[Literal["completed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The status of the item. Has no effect on the conversation. Is one of the following types: + Literal[\"completed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + call_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the function being called. Required.""" + arguments: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The arguments of the function call. This is a JSON-encoded string representing the arguments + passed to the function, for example ``{\"arg1\": \"value1\", \"arg2\": 42}``. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + name: str, + arguments: str, + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.item"]] = None, + status: Optional[Literal["completed", "incomplete", "in_progress"]] = None, + call_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.FUNCTION_CALL # type: ignore + + +class RealtimeConversationItemFunctionCallOutput( + RealtimeConversationItem, discriminator="function_call_output" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Realtime function call output item. + + :ivar id: The unique ID of the item. This may be provided by the client or generated by the + server. + :vartype id: str + :ivar object: Identifier for the API object being returned - always ``realtime.item``. Optional + when creating a new item. Default value is "realtime.item". + :vartype object: str + :ivar type: The type of the item. Always ``function_call_output``. Required. + FUNCTION_CALL_OUTPUT. + :vartype type: str or ~azure.ai.projects.models.FUNCTION_CALL_OUTPUT + :ivar status: The status of the item. Has no effect on the conversation. Is one of the + following types: Literal["completed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str + :ivar call_id: The ID of the function call this output is for. Required. + :vartype call_id: str + :ivar output: The output of the function call, this is free text and can contain any + information or simply be empty. Required. + :vartype output: str + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + :ivar name: The name of the function that was called. A Foundry extension: OpenAI's + function_call_output does not carry the function name, only ``call_id``. + :vartype name: str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the item. This may be provided by the client or generated by the server.""" + object: Optional[Literal["realtime.item"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Identifier for the API object being returned - always ``realtime.item``. Optional when creating + a new item. Default value is \"realtime.item\".""" + type: Literal[RealtimeConversationItemType.FUNCTION_CALL_OUTPUT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``function_call_output``. Required. FUNCTION_CALL_OUTPUT.""" + status: Optional[Literal["completed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The status of the item. Has no effect on the conversation. Is one of the following types: + Literal[\"completed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call this output is for. Required.""" + output: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The output of the function call, this is free text and can contain any information or simply be + empty. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the function that was called. A Foundry extension: OpenAI's function_call_output + does not carry the function name, only ``call_id``.""" + + @overload + def __init__( + self, + *, + call_id: str, + output: str, + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.item"]] = None, + status: Optional[Literal["completed", "incomplete", "in_progress"]] = None, + name: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.FUNCTION_CALL_OUTPUT # type: ignore + + +class RealtimeConversationItemMessage( + RealtimeConversationItem, discriminator="message" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeConversationItemMessage. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeConversationItemMessageAssistant, RealtimeConversationItemMessageSystem, + RealtimeConversationItemMessageUser + + :ivar role: Required. Known values are: "system", "user", and "assistant". + :vartype role: str or ~azure.ai.projects.models.RealtimeConversationItemMessageType + :ivar type: Required. MESSAGE. + :vartype type: str or ~azure.ai.projects.models.MESSAGE + """ + + __mapping__: dict[str, _Model] = {} + role: str = rest_discriminator(name="role", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"system\", \"user\", and \"assistant\".""" + type: Literal[RealtimeConversationItemType.MESSAGE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. MESSAGE.""" + + @overload + def __init__( + self, + *, + role: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.MESSAGE # type: ignore + + +class RealtimeConversationItemMessageAssistant( + RealtimeConversationItemMessage, discriminator="assistant" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime assistant message item. + + :ivar id: The unique ID of the item. This may be provided by the client or generated by the + server. + :vartype id: str + :ivar object: Identifier for the API object being returned - always ``realtime.item``. Optional + when creating a new item. Default value is "realtime.item". + :vartype object: str + :ivar type: The type of the item. Always ``message``. Required. MESSAGE. + :vartype type: str or ~azure.ai.projects.models.MESSAGE + :ivar status: The status of the item. Has no effect on the conversation. Is one of the + following types: Literal["completed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str + :ivar role: The role of the message sender. Always ``assistant``. Required. ASSISTANT. + :vartype role: str or ~azure.ai.projects.models.ASSISTANT + :ivar content: The content of the message. Required. + :vartype content: + list[~azure.ai.projects.models.RealtimeConversationItemMessageAssistantContent] + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the item. This may be provided by the client or generated by the server.""" + object: Optional[Literal["realtime.item"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Identifier for the API object being returned - always ``realtime.item``. Optional when creating + a new item. Default value is \"realtime.item\".""" + status: Optional[Literal["completed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The status of the item. Has no effect on the conversation. Is one of the following types: + Literal[\"completed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + role: Literal[RealtimeConversationItemMessageType.ASSISTANT] = rest_discriminator(name="role", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The role of the message sender. Always ``assistant``. Required. ASSISTANT.""" + content: list["_models.RealtimeConversationItemMessageAssistantContent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The content of the message. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + type: Literal[RealtimeConversationItemType.MESSAGE], + content: list["_models.RealtimeConversationItemMessageAssistantContent"], + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.item"]] = None, + status: Optional[Literal["completed", "incomplete", "in_progress"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.role = RealtimeConversationItemMessageType.ASSISTANT # type: ignore + + +class RealtimeConversationItemMessageAssistantContent( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeConversationItemMessageAssistantContent. + + :ivar type: Is either a Literal["output_text"] type or a Literal["output_audio"] type. + :vartype type: str or str + :ivar text: + :vartype text: str + :ivar audio: + :vartype audio: str + :ivar transcript: + :vartype transcript: str + """ + + type: Optional[Literal["output_text", "output_audio"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is either a Literal[\"output_text\"] type or a Literal[\"output_audio\"] type.""" + text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + transcript: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[Literal["output_text", "output_audio"]] = None, + text: Optional[str] = None, + audio: Optional[str] = None, + transcript: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeConversationItemMessageSystem( + RealtimeConversationItemMessage, discriminator="system" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime system message item. + + :ivar id: The unique ID of the item. This may be provided by the client or generated by the + server. + :vartype id: str + :ivar object: Identifier for the API object being returned - always ``realtime.item``. Optional + when creating a new item. Default value is "realtime.item". + :vartype object: str + :ivar type: The type of the item. Always ``message``. Required. MESSAGE. + :vartype type: str or ~azure.ai.projects.models.MESSAGE + :ivar status: The status of the item. Has no effect on the conversation. Is one of the + following types: Literal["completed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str + :ivar role: The role of the message sender. Always ``system``. Required. SYSTEM. + :vartype role: str or ~azure.ai.projects.models.SYSTEM + :ivar content: The content of the message. Required. + :vartype content: list[~azure.ai.projects.models.RealtimeConversationItemMessageSystemContent] + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the item. This may be provided by the client or generated by the server.""" + object: Optional[Literal["realtime.item"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Identifier for the API object being returned - always ``realtime.item``. Optional when creating + a new item. Default value is \"realtime.item\".""" + status: Optional[Literal["completed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The status of the item. Has no effect on the conversation. Is one of the following types: + Literal[\"completed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + role: Literal[RealtimeConversationItemMessageType.SYSTEM] = rest_discriminator(name="role", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The role of the message sender. Always ``system``. Required. SYSTEM.""" + content: list["_models.RealtimeConversationItemMessageSystemContent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The content of the message. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + type: Literal[RealtimeConversationItemType.MESSAGE], + content: list["_models.RealtimeConversationItemMessageSystemContent"], + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.item"]] = None, + status: Optional[Literal["completed", "incomplete", "in_progress"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.role = RealtimeConversationItemMessageType.SYSTEM # type: ignore + + +class RealtimeConversationItemMessageSystemContent( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeConversationItemMessageSystemContent. + + :ivar type: Default value is "input_text". + :vartype type: str + :ivar text: + :vartype text: str + """ + + type: Optional[Literal["input_text"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Default value is \"input_text\".""" + text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[Literal["input_text"]] = None, + text: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeConversationItemMessageUser( + RealtimeConversationItemMessage, discriminator="user" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime user message item. + + :ivar id: The unique ID of the item. This may be provided by the client or generated by the + server. + :vartype id: str + :ivar object: Identifier for the API object being returned - always ``realtime.item``. Optional + when creating a new item. Default value is "realtime.item". + :vartype object: str + :ivar type: The type of the item. Always ``message``. Required. MESSAGE. + :vartype type: str or ~azure.ai.projects.models.MESSAGE + :ivar status: The status of the item. Has no effect on the conversation. Is one of the + following types: Literal["completed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str + :ivar role: The role of the message sender. Always ``user``. Required. USER. + :vartype role: str or ~azure.ai.projects.models.USER + :ivar content: The content of the message. Required. + :vartype content: list[~azure.ai.projects.models.RealtimeConversationItemMessageUserContent] + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the item. This may be provided by the client or generated by the server.""" + object: Optional[Literal["realtime.item"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Identifier for the API object being returned - always ``realtime.item``. Optional when creating + a new item. Default value is \"realtime.item\".""" + status: Optional[Literal["completed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The status of the item. Has no effect on the conversation. Is one of the following types: + Literal[\"completed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + role: Literal[RealtimeConversationItemMessageType.USER] = rest_discriminator(name="role", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The role of the message sender. Always ``user``. Required. USER.""" + content: list["_models.RealtimeConversationItemMessageUserContent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The content of the message. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + type: Literal[RealtimeConversationItemType.MESSAGE], + content: list["_models.RealtimeConversationItemMessageUserContent"], + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.item"]] = None, + status: Optional[Literal["completed", "incomplete", "in_progress"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.role = RealtimeConversationItemMessageType.USER # type: ignore + + +class RealtimeConversationItemMessageUserContent( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeConversationItemMessageUserContent. + + :ivar type: Is one of the following types: Literal["input_text"], Literal["input_audio"], + Literal["input_image"] + :vartype type: str or str or str + :ivar text: + :vartype text: str + :ivar audio: + :vartype audio: str + :ivar image_url: + :vartype image_url: str + :ivar detail: Is one of the following types: Literal["auto"], Literal["low"], Literal["high"] + :vartype detail: str or str or str + :ivar transcript: + :vartype transcript: str + """ + + type: Optional[Literal["input_text", "input_audio", "input_image"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"input_text\"], Literal[\"input_audio\"], + Literal[\"input_image\"]""" + text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + image_url: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + detail: Optional[Literal["auto", "low", "high"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"auto\"], Literal[\"low\"], Literal[\"high\"]""" + transcript: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[Literal["input_text", "input_audio", "input_image"]] = None, + text: Optional[str] = None, + audio: Optional[str] = None, + image_url: Optional[str] = None, + detail: Optional[Literal["auto", "low", "high"]] = None, + transcript: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeFunctionTool(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Function tool. + + :ivar type: The type of the tool, i.e. ``function``. Default value is "function". + :vartype type: str + :ivar name: The name of the function. + :vartype name: str + :ivar description: The description of the function, including guidance on when and how to call + it, and guidance about what to tell the user when calling (if anything). + :vartype description: str + :ivar parameters: Parameters of the function in JSON Schema. + :vartype parameters: ~azure.ai.projects.models.RealtimeFunctionToolParameters + """ + + type: Optional[Literal["function"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The type of the tool, i.e. ``function``. Default value is \"function\".""" + name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the function.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The description of the function, including guidance on when and how to call it, and guidance + about what to tell the user when calling (if anything).""" + parameters: Optional["_models.RealtimeFunctionToolParameters"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Parameters of the function in JSON Schema.""" + + @overload + def __init__( + self, + *, + type: Optional[Literal["function"]] = None, + name: Optional[str] = None, + description: Optional[str] = None, + parameters: Optional["_models.RealtimeFunctionToolParameters"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeFunctionToolParameters(_Model): + """RealtimeFunctionToolParameters.""" + + +class RealtimeMCPApprovalRequest( + RealtimeConversationItem, discriminator="mcp_approval_request" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP approval request. + + :ivar type: The type of the item. Always ``mcp_approval_request``. Required. + MCP_APPROVAL_REQUEST. + :vartype type: str or ~azure.ai.projects.models.MCP_APPROVAL_REQUEST + :ivar id: The unique ID of the approval request. Required. + :vartype id: str + :ivar server_label: The label of the MCP server making the request. Required. + :vartype server_label: str + :ivar name: The name of the tool to run. Required. + :vartype name: str + :ivar arguments: A JSON string of arguments for the tool. Required. + :vartype arguments: str + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + type: Literal[RealtimeConversationItemType.MCP_APPROVAL_REQUEST] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``mcp_approval_request``. Required. MCP_APPROVAL_REQUEST.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the approval request. Required.""" + server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The label of the MCP server making the request. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the tool to run. Required.""" + arguments: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A JSON string of arguments for the tool. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + server_label: str, + name: str, + arguments: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.MCP_APPROVAL_REQUEST # type: ignore + + +class RealtimeMCPApprovalResponse( + RealtimeConversationItem, discriminator="mcp_approval_response" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP approval response. + + :ivar type: The type of the item. Always ``mcp_approval_response``. Required. + MCP_APPROVAL_RESPONSE. + :vartype type: str or ~azure.ai.projects.models.MCP_APPROVAL_RESPONSE + :ivar id: The unique ID of the approval response. Required. + :vartype id: str + :ivar approval_request_id: The ID of the approval request being answered. Required. + :vartype approval_request_id: str + :ivar approve: Whether the request was approved. Required. + :vartype approve: bool + :ivar reason: + :vartype reason: str + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + type: Literal[RealtimeConversationItemType.MCP_APPROVAL_RESPONSE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``mcp_approval_response``. Required. MCP_APPROVAL_RESPONSE.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the approval response. Required.""" + approval_request_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the approval request being answered. Required.""" + approve: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the request was approved. Required.""" + reason: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + approval_request_id: str, + approve: bool, + reason: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.MCP_APPROVAL_RESPONSE # type: ignore + + +class RealtimeMCPError(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeMCPError. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeMCPHTTPError, RealtimeMCPProtocolError, RealtimeMCPToolExecutionError + + :ivar type: Required. Known values are: "protocol_error", "tool_execution_error", and + "http_error". + :vartype type: str or ~azure.ai.projects.models.RealtimeMcpErrorType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"protocol_error\", \"tool_execution_error\", and \"http_error\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeMCPHTTPError( + RealtimeMCPError, discriminator="http_error" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP HTTP error. + + :ivar type: Required. HTTP_ERROR. + :vartype type: str or ~azure.ai.projects.models.HTTP_ERROR + :ivar code: Required. + :vartype code: int + :ivar message: Required. + :vartype message: str + """ + + type: Literal[RealtimeMcpErrorType.HTTP_ERROR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. HTTP_ERROR.""" + code: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + code: int, + message: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeMcpErrorType.HTTP_ERROR # type: ignore + + +class RealtimeMCPListTools( + RealtimeConversationItem, discriminator="mcp_list_tools" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP list tools. + + :ivar type: The type of the item. Always ``mcp_list_tools``. Required. MCP_LIST_TOOLS. + :vartype type: str or ~azure.ai.projects.models.MCP_LIST_TOOLS + :ivar id: The unique ID of the list. + :vartype id: str + :ivar server_label: The label of the MCP server. Required. + :vartype server_label: str + :ivar tools: The tools available on the server. Required. + :vartype tools: list[~azure.ai.projects.models.MCPListToolsTool] + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + type: Literal[RealtimeConversationItemType.MCP_LIST_TOOLS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``mcp_list_tools``. Required. MCP_LIST_TOOLS.""" + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the list.""" + server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The label of the MCP server. Required.""" + tools: list["_models.MCPListToolsTool"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The tools available on the server. Required.""" + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + server_label: str, + tools: list["_models.MCPListToolsTool"], + id: Optional[str] = None, # pylint: disable=redefined-builtin + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.MCP_LIST_TOOLS # type: ignore + + +class RealtimeMCPProtocolError( + RealtimeMCPError, discriminator="protocol_error" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP protocol error. + + :ivar type: Required. PROTOCOL_ERROR. + :vartype type: str or ~azure.ai.projects.models.PROTOCOL_ERROR + :ivar code: Required. + :vartype code: int + :ivar message: Required. + :vartype message: str + """ + + type: Literal[RealtimeMcpErrorType.PROTOCOL_ERROR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. PROTOCOL_ERROR.""" + code: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + code: int, + message: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeMcpErrorType.PROTOCOL_ERROR # type: ignore + + +class RealtimeMCPToolCall( + RealtimeConversationItem, discriminator="mcp_call" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP tool call. + + :ivar type: The type of the item. Always ``mcp_call``. Required. MCP_CALL. + :vartype type: str or ~azure.ai.projects.models.MCP_CALL + :ivar id: The unique ID of the tool call. Required. + :vartype id: str + :ivar server_label: The label of the MCP server running the tool. Required. + :vartype server_label: str + :ivar name: The name of the tool that was run. Required. + :vartype name: str + :ivar arguments: A JSON string of the arguments passed to the tool. Required. + :vartype arguments: str + :ivar approval_request_id: + :vartype approval_request_id: str + :ivar output: + :vartype output: str + :ivar error: + :vartype error: ~azure.ai.projects.models.RealtimeMCPError + :ivar created_at: The Unix timestamp (in seconds) for when the item was persisted. + :vartype created_at: ~datetime.datetime + :ivar response_id: The id of the response that produced this item, when applicable. + :vartype response_id: str + """ + + type: Literal[RealtimeConversationItemType.MCP_CALL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the item. Always ``mcp_call``. Required. MCP_CALL.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the tool call. Required.""" + server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The label of the MCP server running the tool. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the tool that was run. Required.""" + arguments: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A JSON string of the arguments passed to the tool. Required.""" + approval_request_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + output: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + error: Optional["_models.RealtimeMCPError"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + created_at: Optional[datetime.datetime] = rest_field(visibility=["read"], format="unix-timestamp") + """The Unix timestamp (in seconds) for when the item was persisted.""" + response_id: Optional[str] = rest_field(visibility=["read"]) + """The id of the response that produced this item, when applicable.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + server_label: str, + name: str, + arguments: str, + approval_request_id: Optional[str] = None, + output: Optional[str] = None, + error: Optional["_models.RealtimeMCPError"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeConversationItemType.MCP_CALL # type: ignore + + +class RealtimeMCPToolExecutionError( + RealtimeMCPError, discriminator="tool_execution_error" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime MCP tool execution error. + + :ivar type: Required. TOOL_EXECUTION_ERROR. + :vartype type: str or ~azure.ai.projects.models.TOOL_EXECUTION_ERROR + :ivar message: Required. + :vartype message: str + """ + + type: Literal[RealtimeMcpErrorType.TOOL_EXECUTION_ERROR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. TOOL_EXECUTION_ERROR.""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + message: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeMcpErrorType.TOOL_EXECUTION_ERROR # type: ignore + + +class RealtimeReasoning(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Realtime reasoning configuration. + + :ivar effort: Known values are: "minimal", "low", "medium", "high", and "xhigh". + :vartype effort: str or ~azure.ai.projects.models.RealtimeReasoningEffort + """ + + effort: Optional[Union[str, "_models.RealtimeReasoningEffort"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Known values are: \"minimal\", \"low\", \"medium\", \"high\", and \"xhigh\".""" + + @overload + def __init__( + self, + *, + effort: Optional[Union[str, "_models.RealtimeReasoningEffort"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseStatusDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeResponseStatusDetails. + + :ivar type: Is one of the following types: Literal["completed"], Literal["cancelled"], + Literal["failed"], Literal["incomplete"] + :vartype type: str or str or str or str + :ivar reason: Is one of the following types: Literal["turn_detected"], + Literal["client_cancelled"], Literal["max_output_tokens"], Literal["content_filter"] + :vartype reason: str or str or str or str + :ivar error: + :vartype error: ~azure.ai.projects.models.RealtimeResponseStatusDetailsError + """ + + type: Optional[Literal["completed", "cancelled", "failed", "incomplete"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"completed\"], Literal[\"cancelled\"], + Literal[\"failed\"], Literal[\"incomplete\"]""" + reason: Optional[Literal["turn_detected", "client_cancelled", "max_output_tokens", "content_filter"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"turn_detected\"], Literal[\"client_cancelled\"], + Literal[\"max_output_tokens\"], Literal[\"content_filter\"]""" + error: Optional["_models.RealtimeResponseStatusDetailsError"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + type: Optional[Literal["completed", "cancelled", "failed", "incomplete"]] = None, + reason: Optional[Literal["turn_detected", "client_cancelled", "max_output_tokens", "content_filter"]] = None, + error: Optional["_models.RealtimeResponseStatusDetailsError"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseStatusDetailsError(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeResponseStatusDetailsError. + + :ivar type: + :vartype type: str + :ivar code: + :vartype code: str + """ + + type: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[str] = None, + code: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseUsage(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeResponseUsage. + + :ivar total_tokens: + :vartype total_tokens: int + :ivar input_tokens: + :vartype input_tokens: int + :ivar output_tokens: + :vartype output_tokens: int + :ivar input_token_details: + :vartype input_token_details: ~azure.ai.projects.models.RealtimeResponseUsageInputTokenDetails + :ivar output_token_details: + :vartype output_token_details: + ~azure.ai.projects.models.RealtimeResponseUsageOutputTokenDetails + """ + + total_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + input_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + output_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + input_token_details: Optional["_models.RealtimeResponseUsageInputTokenDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + output_token_details: Optional["_models.RealtimeResponseUsageOutputTokenDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + total_tokens: Optional[int] = None, + input_tokens: Optional[int] = None, + output_tokens: Optional[int] = None, + input_token_details: Optional["_models.RealtimeResponseUsageInputTokenDetails"] = None, + output_token_details: Optional["_models.RealtimeResponseUsageOutputTokenDetails"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseUsageInputTokenDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeResponseUsageInputTokenDetails. + + :ivar cached_tokens: + :vartype cached_tokens: int + :ivar text_tokens: + :vartype text_tokens: int + :ivar image_tokens: + :vartype image_tokens: int + :ivar audio_tokens: + :vartype audio_tokens: int + :ivar cached_tokens_details: + :vartype cached_tokens_details: + ~azure.ai.projects.models.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails + """ + + cached_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + text_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + image_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + cached_tokens_details: Optional["_models.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + cached_tokens: Optional[int] = None, + text_tokens: Optional[int] = None, + image_tokens: Optional[int] = None, + audio_tokens: Optional[int] = None, + cached_tokens_details: Optional["_models.RealtimeResponseUsageInputTokenDetailsCachedTokensDetails"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseUsageInputTokenDetailsCachedTokensDetails( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeResponseUsageInputTokenDetailsCachedTokensDetails. + + :ivar text_tokens: + :vartype text_tokens: int + :ivar image_tokens: + :vartype image_tokens: int + :ivar audio_tokens: + :vartype audio_tokens: int + """ + + text_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + image_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + text_tokens: Optional[int] = None, + image_tokens: Optional[int] = None, + audio_tokens: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeResponseUsageOutputTokenDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeResponseUsageOutputTokenDetails. + + :ivar text_tokens: + :vartype text_tokens: int + :ivar audio_tokens: + :vartype audio_tokens: int + """ + + text_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + text_tokens: Optional[int] = None, + audio_tokens: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEvent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A realtime server event. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + RealtimeServerEventConversationItemAdded, RealtimeServerEventConversationItemCreated, + RealtimeServerEventConversationItemDeleted, RealtimeServerEventConversationItemDone, + RealtimeServerEventConversationItemInputAudioTranscriptionCompleted, + RealtimeServerEventConversationItemInputAudioTranscriptionDelta, + RealtimeServerEventConversationItemInputAudioTranscriptionFailed, + RealtimeServerEventConversationItemInputAudioTranscriptionSegment, + RealtimeServerEventConversationItemRetrieved, RealtimeServerEventConversationItemTruncated, + RealtimeServerEventInputAudioBufferCleared, RealtimeServerEventInputAudioBufferCommitted, + RealtimeServerEventInputAudioBufferSpeechStarted, + RealtimeServerEventInputAudioBufferSpeechStopped, + RealtimeServerEventInputAudioBufferTimeoutTriggered, RealtimeServerEventMCPListToolsCompleted, + RealtimeServerEventMCPListToolsFailed, RealtimeServerEventMCPListToolsInProgress, + RealtimeServerEventOutputAudioBufferCleared, RealtimeServerEventRateLimitsUpdated, + VoiceAgentServerEventResponseAnimationBlendshapesDelta, + VoiceAgentServerEventResponseAnimationBlendshapesDone, + VoiceAgentServerEventResponseAnimationVisemeDelta, + VoiceAgentServerEventResponseAnimationVisemeDone, + VoiceAgentServerEventResponseAudioTimestampDelta, + VoiceAgentServerEventResponseAudioTimestampDone, RealtimeServerEventResponseContentPartAdded, + RealtimeServerEventResponseContentPartDone, RealtimeServerEventResponseCreated, + RealtimeServerEventResponseDone, RealtimeServerEventResponseFunctionCallArgumentsDelta, + RealtimeServerEventResponseFunctionCallArgumentsDone, + RealtimeServerEventResponseMCPCallCompleted, RealtimeServerEventResponseMCPCallFailed, + RealtimeServerEventResponseMCPCallInProgress, RealtimeServerEventResponseMCPCallArgumentsDelta, + RealtimeServerEventResponseMCPCallArgumentsDone, RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioDone, RealtimeServerEventResponseAudioTranscriptDelta, + RealtimeServerEventResponseAudioTranscriptDone, RealtimeServerEventResponseOutputItemAdded, + RealtimeServerEventResponseOutputItemDone, RealtimeServerEventResponseTextDelta, + RealtimeServerEventResponseTextDone, VoiceAgentServerEventResponseVideoDelta, + VoiceAgentServerEventRtcCallError, VoiceAgentServerEventRtcCallSdpCreated, + VoiceAgentServerEventSessionAvatarConnecting, VoiceAgentServerEventSessionAvatarSwitchToIdle, + VoiceAgentServerEventSessionAvatarSwitchToSpeaking, RealtimeServerEventSessionCreated, + VoiceAgentServerEventSessionSubagentAborted, VoiceAgentServerEventSessionSubagentCompleted, + VoiceAgentServerEventSessionSubagentStarted, RealtimeServerEventSessionUpdated, + VoiceAgentServerEventWarning + + :ivar type: Required. Known values are: "conversation.created", "conversation.item.created", + "conversation.item.deleted", "conversation.item.input_audio_transcription.completed", + "conversation.item.input_audio_transcription.delta", + "conversation.item.input_audio_transcription.failed", "conversation.item.retrieved", + "conversation.item.truncated", "error", "input_audio_buffer.cleared", + "input_audio_buffer.committed", "input_audio_buffer.dtmf_event_received", + "input_audio_buffer.speech_started", "input_audio_buffer.speech_stopped", + "rate_limits.updated", "response.output_audio.delta", "response.output_audio.done", + "response.output_audio_transcript.delta", "response.output_audio_transcript.done", + "response.content_part.added", "response.content_part.done", "response.created", + "response.done", "response.function_call_arguments.delta", + "response.function_call_arguments.done", "response.output_item.added", + "response.output_item.done", "response.output_text.delta", "response.output_text.done", + "session.created", "session.updated", "output_audio_buffer.started", + "output_audio_buffer.stopped", "output_audio_buffer.cleared", "conversation.item.added", + "conversation.item.done", "input_audio_buffer.timeout_triggered", + "conversation.item.input_audio_transcription.segment", "mcp_list_tools.in_progress", + "mcp_list_tools.completed", "mcp_list_tools.failed", "response.mcp_call_arguments.delta", + "response.mcp_call_arguments.done", "response.mcp_call.in_progress", + "response.mcp_call.completed", "response.mcp_call.failed", "warning", + "session.subagent.started", "session.subagent.completed", "session.subagent.aborted", + "session.avatar.connecting", "session.avatar.switch_to_speaking", + "session.avatar.switch_to_idle", "rtc.call.sdp.created", "rtc.call.error", + "response.audio_timestamp.delta", "response.audio_timestamp.done", + "response.animation_blendshapes.delta", "response.animation_blendshapes.done", + "response.animation_viseme.delta", "response.animation_viseme.done", and + "response.video.delta". + :vartype type: str or ~azure.ai.projects.models.RealtimeServerEventType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"conversation.created\", \"conversation.item.created\", + \"conversation.item.deleted\", \"conversation.item.input_audio_transcription.completed\", + \"conversation.item.input_audio_transcription.delta\", + \"conversation.item.input_audio_transcription.failed\", \"conversation.item.retrieved\", + \"conversation.item.truncated\", \"error\", \"input_audio_buffer.cleared\", + \"input_audio_buffer.committed\", \"input_audio_buffer.dtmf_event_received\", + \"input_audio_buffer.speech_started\", \"input_audio_buffer.speech_stopped\", + \"rate_limits.updated\", \"response.output_audio.delta\", \"response.output_audio.done\", + \"response.output_audio_transcript.delta\", \"response.output_audio_transcript.done\", + \"response.content_part.added\", \"response.content_part.done\", \"response.created\", + \"response.done\", \"response.function_call_arguments.delta\", + \"response.function_call_arguments.done\", \"response.output_item.added\", + \"response.output_item.done\", \"response.output_text.delta\", \"response.output_text.done\", + \"session.created\", \"session.updated\", \"output_audio_buffer.started\", + \"output_audio_buffer.stopped\", \"output_audio_buffer.cleared\", \"conversation.item.added\", + \"conversation.item.done\", \"input_audio_buffer.timeout_triggered\", + \"conversation.item.input_audio_transcription.segment\", \"mcp_list_tools.in_progress\", + \"mcp_list_tools.completed\", \"mcp_list_tools.failed\", \"response.mcp_call_arguments.delta\", + \"response.mcp_call_arguments.done\", \"response.mcp_call.in_progress\", + \"response.mcp_call.completed\", \"response.mcp_call.failed\", \"warning\", + \"session.subagent.started\", \"session.subagent.completed\", \"session.subagent.aborted\", + \"session.avatar.connecting\", \"session.avatar.switch_to_speaking\", + \"session.avatar.switch_to_idle\", \"rtc.call.sdp.created\", \"rtc.call.error\", + \"response.audio_timestamp.delta\", \"response.audio_timestamp.done\", + \"response.animation_blendshapes.delta\", \"response.animation_blendshapes.done\", + \"response.animation_viseme.delta\", \"response.animation_viseme.done\", and + \"response.video.delta\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventConversationItemAdded( + RealtimeServerEvent, discriminator="conversation.item.added" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Sent by the server when an Item is added to the default Conversation. This can happen in + several cases: + + * When the client sends a `conversation.item.create` event. + * When the input audio buffer is committed. In this case the item will be a user message containing the audio from + the buffer. + * When the model is generating a Response. In this case the `conversation.item.added` event will be sent when the + model starts generating a specific Item, and thus it will not yet have any content (and `status` will be + `in_progress`). The event will include the full content of the Item (except when model is generating a Response) + except for audio data, which can be retrieved separately with a `conversation.item.retrieve` event if necessary. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.added``. Required. + CONVERSATION_ITEM_ADDED. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_ADDED + :ivar previous_item_id: + :vartype previous_item_id: str + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_ADDED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.added``. Required. CONVERSATION_ITEM_ADDED.""" + previous_item_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item: "_models.RealtimeConversationItem", + previous_item_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_ADDED # type: ignore + + +class RealtimeServerEventConversationItemCreated( + RealtimeServerEvent, discriminator="conversation.item.created" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when a conversation item is created. There are several scenarios that produce this + event: + + * The server is generating a Response, which if successful will produce either one or two Items, which will be of + type `message` (role `assistant`) or type `function_call`. + * The input audio buffer has been committed, either by the client or the server (in `server_vad` mode). The server + will take the content of the input audio buffer and add it to a new user message Item. + * The client has sent a `conversation.item.create` event to add a new Item to the Conversation. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.created``. Required. + CONVERSATION_ITEM_CREATED. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_CREATED + :ivar previous_item_id: + :vartype previous_item_id: str + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_CREATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.created``. Required. CONVERSATION_ITEM_CREATED.""" + previous_item_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item: "_models.RealtimeConversationItem", + previous_item_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_CREATED # type: ignore + + +class RealtimeServerEventConversationItemDeleted( + RealtimeServerEvent, discriminator="conversation.item.deleted" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an item in the conversation is deleted by the client with a + ``conversation.item.delete`` event. This event is used to synchronize the server's + understanding of the conversation history with the client's view. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.deleted``. Required. + CONVERSATION_ITEM_DELETED. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_DELETED + :ivar item_id: The ID of the item that was deleted. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_DELETED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.deleted``. Required. CONVERSATION_ITEM_DELETED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item that was deleted. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_DELETED # type: ignore + + +class RealtimeServerEventConversationItemDone( + RealtimeServerEvent, discriminator="conversation.item.done" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when a conversation item is finalized. The event will include the full content of the + Item except for audio data, which can be retrieved separately with a + ``conversation.item.retrieve`` event if needed. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.done``. Required. + CONVERSATION_ITEM_DONE. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_DONE + :ivar previous_item_id: + :vartype previous_item_id: str + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.done``. Required. CONVERSATION_ITEM_DONE.""" + previous_item_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item: "_models.RealtimeConversationItem", + previous_item_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_DONE # type: ignore + + +class RealtimeServerEventConversationItemInputAudioTranscriptionCompleted( + RealtimeServerEvent, discriminator="conversation.item.input_audio_transcription.completed" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """This event is the output of audio transcription for user audio written to the user audio + buffer. Transcription begins when the input audio buffer is committed by the client or server + (when VAD is enabled). Transcription runs asynchronously with Response creation, so this event + may come before or after the Response events. Realtime API models accept audio natively, and + thus input transcription is a separate process run on a separate ASR (Automatic Speech + Recognition) model. The transcript may diverge somewhat from the model's interpretation, and + should be treated as a rough guide. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.input_audio_transcription.completed``. + Required. CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED. + :vartype type: str or + ~azure.ai.projects.models.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED + :ivar item_id: The ID of the item containing the audio that is being transcribed. Required. + :vartype item_id: str + :ivar content_index: The index of the content part containing the audio. Required. + :vartype content_index: int + :ivar transcript: The transcribed text. Required. + :vartype transcript: str + :ivar languages: The languages detected in the audio. Returned by ``gpt-transcribe``. An empty + array indicates that no language could be reliably detected. + :vartype languages: list[~azure.ai.projects.models.TranscriptionLanguage] + :ivar logprobs: + :vartype logprobs: list[~azure.ai.projects.models.LogProbProperties] + :ivar usage: Usage statistics for the transcription, this is billed according to the ASR + model's pricing rather than the realtime model's pricing. Required. Is either a + TranscriptTextUsageTokens type or a TranscriptTextUsageDuration type. + :vartype usage: ~azure.ai.projects.models.TranscriptTextUsageTokens or + ~azure.ai.projects.models.TranscriptTextUsageDuration + :ivar phrases: Phrase-level transcription timing and confidence details. + :vartype phrases: list[~azure.ai.projects.models.VoiceAgentTranscriptionPhrase] + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.input_audio_transcription.completed``. Required. + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item containing the audio that is being transcribed. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part containing the audio. Required.""" + transcript: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The transcribed text. Required.""" + languages: Optional[list["_models.TranscriptionLanguage"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The languages detected in the audio. Returned by ``gpt-transcribe``. An empty array indicates + that no language could be reliably detected.""" + logprobs: Optional[list["_models.LogProbProperties"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + usage: Union["_models.TranscriptTextUsageTokens", "_models.TranscriptTextUsageDuration"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Usage statistics for the transcription, this is billed according to the ASR model's pricing + rather than the realtime model's pricing. Required. Is either a TranscriptTextUsageTokens type + or a TranscriptTextUsageDuration type.""" + phrases: Optional[list["_models.VoiceAgentTranscriptionPhrase"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Phrase-level transcription timing and confidence details.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + content_index: int, + transcript: str, + usage: Union["_models.TranscriptTextUsageTokens", "_models.TranscriptTextUsageDuration"], + languages: Optional[list["_models.TranscriptionLanguage"]] = None, + logprobs: Optional[list["_models.LogProbProperties"]] = None, + phrases: Optional[list["_models.VoiceAgentTranscriptionPhrase"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED # type: ignore + + +class RealtimeServerEventConversationItemInputAudioTranscriptionDelta( + RealtimeServerEvent, discriminator="conversation.item.input_audio_transcription.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the text value of an input audio transcription content part is updated with + incremental transcription results. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.input_audio_transcription.delta``. + Required. CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA. + :vartype type: str or + ~azure.ai.projects.models.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA + :ivar item_id: The ID of the item containing the audio that is being transcribed. Required. + :vartype item_id: str + :ivar content_index: The index of the content part in the item's content array. + :vartype content_index: int + :ivar delta: The text delta. + :vartype delta: str + :ivar logprobs: + :vartype logprobs: list[~azure.ai.projects.models.LogProbProperties] + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.input_audio_transcription.delta``. Required. + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item containing the audio that is being transcribed. Required.""" + content_index: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array.""" + delta: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The text delta.""" + logprobs: Optional[list["_models.LogProbProperties"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + content_index: Optional[int] = None, + delta: Optional[str] = None, + logprobs: Optional[list["_models.LogProbProperties"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_DELTA # type: ignore + + +class RealtimeServerEventConversationItemInputAudioTranscriptionFailed( + RealtimeServerEvent, discriminator="conversation.item.input_audio_transcription.failed" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when input audio transcription is configured, and a transcription request for a user + message failed. These events are separate from other ``error`` events so that the client can + identify the related Item. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.input_audio_transcription.failed``. + Required. CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED. + :vartype type: str or + ~azure.ai.projects.models.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED + :ivar item_id: The ID of the user message item. Required. + :vartype item_id: str + :ivar content_index: The index of the content part containing the audio. Required. + :vartype content_index: int + :ivar error: Details of the transcription error. Required. + :vartype error: + ~azure.ai.projects.models.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.input_audio_transcription.failed``. Required. + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the user message item. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part containing the audio. Required.""" + error: "_models.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Details of the transcription error. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + content_index: int, + error: "_models.RealtimeServerEventConversationItemInputAudioTranscriptionFailedError", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED # type: ignore + + +class RealtimeServerEventConversationItemInputAudioTranscriptionFailedError( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeServerEventConversationItemInputAudioTranscriptionFailedError. + + :ivar type: + :vartype type: str + :ivar code: + :vartype code: str + :ivar message: + :vartype message: str + :ivar param: + :vartype param: str + """ + + type: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + param: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[str] = None, + code: Optional[str] = None, + message: Optional[str] = None, + param: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventConversationItemInputAudioTranscriptionSegment( + RealtimeServerEvent, discriminator="conversation.item.input_audio_transcription.segment" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an input audio transcription segment is identified for an item. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.input_audio_transcription.segment``. + Required. CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT. + :vartype type: str or + ~azure.ai.projects.models.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT + :ivar item_id: The ID of the item containing the input audio content. Required. + :vartype item_id: str + :ivar content_index: The index of the input audio content part within the item. Required. + :vartype content_index: int + :ivar text: The text for this segment. Required. + :vartype text: str + :ivar id: The segment identifier. Required. + :vartype id: str + :ivar speaker: The detected speaker label for this segment. Required. + :vartype speaker: str + :ivar start: Start time of the segment in seconds. Required. + :vartype start: float + :ivar end: End time of the segment in seconds. Required. + :vartype end: float + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.input_audio_transcription.segment``. Required. + CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item containing the input audio content. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the input audio content part within the item. Required.""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The text for this segment. Required.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The segment identifier. Required.""" + speaker: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The detected speaker label for this segment. Required.""" + start: float = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Start time of the segment in seconds. Required.""" + end: float = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """End time of the segment in seconds. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + content_index: int, + text: str, + id: str, # pylint: disable=redefined-builtin + speaker: str, + start: float, + end: float, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_INPUT_AUDIO_TRANSCRIPTION_SEGMENT # type: ignore + + +class RealtimeServerEventConversationItemRetrieved( + RealtimeServerEvent, discriminator="conversation.item.retrieved" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when a conversation item is retrieved with ``conversation.item.retrieve``. This is + provided as a way to fetch the server's representation of an item, for example to get access to + the post-processed audio data after noise cancellation and VAD. It includes the full content of + the Item, including audio data. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.retrieved``. Required. + CONVERSATION_ITEM_RETRIEVED. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_RETRIEVED + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_RETRIEVED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.retrieved``. Required. CONVERSATION_ITEM_RETRIEVED.""" + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item: "_models.RealtimeConversationItem", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_RETRIEVED # type: ignore + + +class RealtimeServerEventConversationItemTruncated( + RealtimeServerEvent, discriminator="conversation.item.truncated" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an earlier assistant audio message item is truncated by the client with a + ``conversation.item.truncate`` event. This event is used to synchronize the server's + understanding of the audio with the client's playback. This action will truncate the audio and + remove the server-side text transcript to ensure there is no text in the context that hasn't + been heard by the user. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``conversation.item.truncated``. Required. + CONVERSATION_ITEM_TRUNCATED. + :vartype type: str or ~azure.ai.projects.models.CONVERSATION_ITEM_TRUNCATED + :ivar item_id: The ID of the assistant message item that was truncated. Required. + :vartype item_id: str + :ivar content_index: The index of the content part that was truncated. Required. + :vartype content_index: int + :ivar audio_end_ms: The duration up to which the audio was truncated, in milliseconds. + Required. + :vartype audio_end_ms: int + :ivar item: The assistant message after truncation, when the service returns the updated item. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.CONVERSATION_ITEM_TRUNCATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``conversation.item.truncated``. Required. CONVERSATION_ITEM_TRUNCATED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the assistant message item that was truncated. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part that was truncated. Required.""" + audio_end_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The duration up to which the audio was truncated, in milliseconds. Required.""" + item: Optional["_models.RealtimeConversationItem"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The assistant message after truncation, when the service returns the updated item.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + content_index: int, + audio_end_ms: int, + item: Optional["_models.RealtimeConversationItem"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.CONVERSATION_ITEM_TRUNCATED # type: ignore + + +class RealtimeServerEventError(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when an error occurs, which could be a client problem or a server problem. Most errors + are recoverable and the session will stay open, we recommend to implementors to monitor and log + error messages by default. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``error``. Required. Default value is "error". + :vartype type: str + :ivar error: Details of the error. Required. + :vartype error: ~azure.ai.projects.models.RealtimeServerEventErrorError + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal["error"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The event type, must be ``error``. Required. Default value is \"error\".""" + error: "_models.RealtimeServerEventErrorError" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Details of the error. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + error: "_models.RealtimeServerEventErrorError", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type: Literal["error"] = "error" + + +class RealtimeServerEventErrorError(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """RealtimeServerEventErrorError. + + :ivar type: Required. + :vartype type: str + :ivar code: + :vartype code: str + :ivar message: Required. + :vartype message: str + :ivar param: + :vartype param: str + :ivar event_id: + :vartype event_id: str + """ + + type: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + param: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: str, + message: str, + code: Optional[str] = None, + param: Optional[str] = None, + event_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventInputAudioBufferCleared( + RealtimeServerEvent, discriminator="input_audio_buffer.cleared" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the input audio buffer is cleared by the client with a + ``input_audio_buffer.clear`` event. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.cleared``. Required. + INPUT_AUDIO_BUFFER_CLEARED. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_CLEARED + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_CLEARED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.cleared``. Required. INPUT_AUDIO_BUFFER_CLEARED.""" + + @overload + def __init__( + self, + *, + event_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.INPUT_AUDIO_BUFFER_CLEARED # type: ignore + + +class RealtimeServerEventInputAudioBufferCommitted( + RealtimeServerEvent, discriminator="input_audio_buffer.committed" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an input audio buffer is committed, either by the client or automatically in + server VAD mode. The ``item_id`` property is the ID of the user message item that will be + created, thus a ``conversation.item.created`` event will also be sent to the client. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.committed``. Required. + INPUT_AUDIO_BUFFER_COMMITTED. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_COMMITTED + :ivar previous_item_id: + :vartype previous_item_id: str + :ivar item_id: The ID of the user message item that will be created. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_COMMITTED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.committed``. Required. + INPUT_AUDIO_BUFFER_COMMITTED.""" + previous_item_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the user message item that will be created. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + previous_item_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.INPUT_AUDIO_BUFFER_COMMITTED # type: ignore + + +class RealtimeServerEventInputAudioBufferSpeechStarted( + RealtimeServerEvent, discriminator="input_audio_buffer.speech_started" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Sent by the server when in ``server_vad`` mode to indicate that speech has been detected in the + audio buffer. This can happen any time audio is added to the buffer (unless speech is already + detected). The client may want to use this event to interrupt audio playback or provide visual + feedback to the user. The client should expect to receive a + ``input_audio_buffer.speech_stopped`` event when speech stops. The ``item_id`` property is the + ID of the user message item that will be created when speech stops and will also be included in + the ``input_audio_buffer.speech_stopped`` event (unless the client manually commits the audio + buffer during VAD activation). + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.speech_started``. Required. + INPUT_AUDIO_BUFFER_SPEECH_STARTED. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_SPEECH_STARTED + :ivar audio_start_ms: Milliseconds from the start of all audio written to the buffer during the + session when speech was first detected. This will correspond to the beginning of audio sent to + the model, and thus includes the ``prefix_padding_ms`` configured in the Session. Required. + :vartype audio_start_ms: int + :ivar item_id: The ID of the user message item that will be created when speech stops. + Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STARTED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.speech_started``. Required. + INPUT_AUDIO_BUFFER_SPEECH_STARTED.""" + audio_start_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Milliseconds from the start of all audio written to the buffer during the session when speech + was first detected. This will correspond to the beginning of audio sent to the model, and thus + includes the ``prefix_padding_ms`` configured in the Session. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the user message item that will be created when speech stops. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + audio_start_ms: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STARTED # type: ignore + + +class RealtimeServerEventInputAudioBufferSpeechStopped( + RealtimeServerEvent, discriminator="input_audio_buffer.speech_stopped" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned in ``server_vad`` mode when the server detects the end of speech in the audio buffer. + The server will also send an ``conversation.item.created`` event with the user message item + that is created from the audio buffer. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.speech_stopped``. Required. + INPUT_AUDIO_BUFFER_SPEECH_STOPPED. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_SPEECH_STOPPED + :ivar audio_end_ms: Milliseconds since the session started when speech stopped. This will + correspond to the end of audio sent to the model, and thus includes the + ``min_silence_duration_ms`` configured in the Session. Required. + :vartype audio_end_ms: int + :ivar item_id: The ID of the user message item that will be created. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STOPPED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.speech_stopped``. Required. + INPUT_AUDIO_BUFFER_SPEECH_STOPPED.""" + audio_end_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Milliseconds since the session started when speech stopped. This will correspond to the end of + audio sent to the model, and thus includes the ``min_silence_duration_ms`` configured in the + Session. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the user message item that will be created. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + audio_end_ms: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.INPUT_AUDIO_BUFFER_SPEECH_STOPPED # type: ignore + + +class RealtimeServerEventInputAudioBufferTimeoutTriggered( + RealtimeServerEvent, discriminator="input_audio_buffer.timeout_triggered" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the Server VAD timeout is triggered for the input audio buffer. This is + configured with ``idle_timeout_ms`` in the ``turn_detection`` settings of the session, and it + indicates that there hasn't been any speech detected for the configured duration. The + ``audio_start_ms`` and ``audio_end_ms`` fields indicate the segment of audio after the last + model response up to the triggering time, as an offset from the beginning of audio written to + the input audio buffer. This means it demarcates the segment of audio that was silent and the + difference between the start and end values will roughly match the configured timeout. The + empty audio will be committed to the conversation as an ``input_audio`` item (there will be a + ``input_audio_buffer.committed`` event) and a model response will be generated. There may be + speech that didn't trigger VAD but is still detected by the model, so the model may respond + with something relevant to the conversation or a prompt to continue speaking. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``input_audio_buffer.timeout_triggered``. Required. + INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED. + :vartype type: str or ~azure.ai.projects.models.INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED + :ivar audio_start_ms: Millisecond offset of audio written to the input audio buffer that was + after the playback time of the last model response. Required. + :vartype audio_start_ms: int + :ivar audio_end_ms: Millisecond offset of audio written to the input audio buffer at the time + the timeout was triggered. Required. + :vartype audio_end_ms: int + :ivar item_id: The ID of the item associated with this segment. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``input_audio_buffer.timeout_triggered``. Required. + INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED.""" + audio_start_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Millisecond offset of audio written to the input audio buffer that was after the playback time + of the last model response. Required.""" + audio_end_ms: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Millisecond offset of audio written to the input audio buffer at the time the timeout was + triggered. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item associated with this segment. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + audio_start_ms: int, + audio_end_ms: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.INPUT_AUDIO_BUFFER_TIMEOUT_TRIGGERED # type: ignore + + +class RealtimeServerEventMCPListToolsCompleted( + RealtimeServerEvent, discriminator="mcp_list_tools.completed" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when listing MCP tools has completed for an item. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``mcp_list_tools.completed``. Required. + MCP_LIST_TOOLS_COMPLETED. + :vartype type: str or ~azure.ai.projects.models.MCP_LIST_TOOLS_COMPLETED + :ivar item_id: The ID of the MCP list tools item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_COMPLETED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``mcp_list_tools.completed``. Required. MCP_LIST_TOOLS_COMPLETED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP list tools item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.MCP_LIST_TOOLS_COMPLETED # type: ignore + + +class RealtimeServerEventMCPListToolsFailed( + RealtimeServerEvent, discriminator="mcp_list_tools.failed" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when listing MCP tools has failed for an item. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``mcp_list_tools.failed``. Required. MCP_LIST_TOOLS_FAILED. + :vartype type: str or ~azure.ai.projects.models.MCP_LIST_TOOLS_FAILED + :ivar item_id: The ID of the MCP list tools item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_FAILED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``mcp_list_tools.failed``. Required. MCP_LIST_TOOLS_FAILED.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP list tools item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.MCP_LIST_TOOLS_FAILED # type: ignore + + +class RealtimeServerEventMCPListToolsInProgress( + RealtimeServerEvent, discriminator="mcp_list_tools.in_progress" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when listing MCP tools is in progress for an item. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``mcp_list_tools.in_progress``. Required. + MCP_LIST_TOOLS_IN_PROGRESS. + :vartype type: str or ~azure.ai.projects.models.MCP_LIST_TOOLS_IN_PROGRESS + :ivar item_id: The ID of the MCP list tools item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.MCP_LIST_TOOLS_IN_PROGRESS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``mcp_list_tools.in_progress``. Required. MCP_LIST_TOOLS_IN_PROGRESS.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP list tools item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.MCP_LIST_TOOLS_IN_PROGRESS # type: ignore + + +class RealtimeServerEventOutputAudioBufferCleared( + RealtimeServerEvent, discriminator="output_audio_buffer.cleared" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """**WebRTC/SIP Only:** Emitted when the output audio buffer is cleared. This happens either in + VAD mode when the user has interrupted (``input_audio_buffer.speech_started``), or when the + client has emitted the ``output_audio_buffer.clear`` event to manually cut off the current + audio response. `Learn more + `_. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``output_audio_buffer.cleared``. Required. + OUTPUT_AUDIO_BUFFER_CLEARED. + :vartype type: str or ~azure.ai.projects.models.OUTPUT_AUDIO_BUFFER_CLEARED + :ivar response_id: The unique ID of the response that produced the audio. Required. + :vartype response_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.OUTPUT_AUDIO_BUFFER_CLEARED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``output_audio_buffer.cleared``. Required. OUTPUT_AUDIO_BUFFER_CLEARED.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the response that produced the audio. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.OUTPUT_AUDIO_BUFFER_CLEARED # type: ignore + + +class RealtimeServerEventRateLimitsUpdated( + RealtimeServerEvent, discriminator="rate_limits.updated" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Emitted at the beginning of a Response to indicate the updated rate limits. When a Response is + created some tokens will be "reserved" for the output tokens, the rate limits shown here + reflect that reservation, which is then adjusted accordingly once the Response is completed. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``rate_limits.updated``. Required. RATE_LIMITS_UPDATED. + :vartype type: str or ~azure.ai.projects.models.RATE_LIMITS_UPDATED + :ivar rate_limits: List of rate limit information. Required. + :vartype rate_limits: + list[~azure.ai.projects.models.RealtimeServerEventRateLimitsUpdatedRateLimits] + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RATE_LIMITS_UPDATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``rate_limits.updated``. Required. RATE_LIMITS_UPDATED.""" + rate_limits: list["_models.RealtimeServerEventRateLimitsUpdatedRateLimits"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """List of rate limit information. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + rate_limits: list["_models.RealtimeServerEventRateLimitsUpdatedRateLimits"], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RATE_LIMITS_UPDATED # type: ignore + + +class RealtimeServerEventRateLimitsUpdatedRateLimits( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeServerEventRateLimitsUpdatedRateLimits. + + :ivar name: Is either a Literal["requests"] type or a Literal["tokens"] type. + :vartype name: str or str + :ivar limit: + :vartype limit: int + :ivar remaining: + :vartype remaining: int + :ivar reset_seconds: + :vartype reset_seconds: float + """ + + name: Optional[Literal["requests", "tokens"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is either a Literal[\"requests\"] type or a Literal[\"tokens\"] type.""" + limit: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + remaining: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + reset_seconds: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + name: Optional[Literal["requests", "tokens"]] = None, + limit: Optional[int] = None, + remaining: Optional[int] = None, + reset_seconds: Optional[float] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventResponseAudioDelta( + RealtimeServerEvent, discriminator="response.output_audio.delta" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when the model-generated audio is updated. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_audio.delta``. Required. + RESPONSE_OUTPUT_AUDIO_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_AUDIO_DELTA + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar delta: Base64-encoded audio data delta. Required. + :vartype delta: bytes + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_audio.delta``. Required. RESPONSE_OUTPUT_AUDIO_DELTA.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + delta: bytes = rest_field(visibility=["read", "create", "update", "delete", "query"], format="base64") + """Base64-encoded audio data delta. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + delta: bytes, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DELTA # type: ignore + + +class RealtimeServerEventResponseAudioDone( + RealtimeServerEvent, discriminator="response.output_audio.done" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when the model-generated audio is done. Also emitted when a Response is interrupted, + incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_audio.done``. Required. + RESPONSE_OUTPUT_AUDIO_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_AUDIO_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_audio.done``. Required. RESPONSE_OUTPUT_AUDIO_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_DONE # type: ignore + + +class RealtimeServerEventResponseAudioTranscriptDelta( + RealtimeServerEvent, discriminator="response.output_audio_transcript.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the model-generated transcription of audio output is updated. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_audio_transcript.delta``. Required. + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar delta: The transcript delta. Required. + :vartype delta: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_audio_transcript.delta``. Required. + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + delta: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The transcript delta. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + delta: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DELTA # type: ignore + + +class RealtimeServerEventResponseAudioTranscriptDone( + RealtimeServerEvent, discriminator="response.output_audio_transcript.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the model-generated transcription of audio output is done streaming. Also emitted + when a Response is interrupted, incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_audio_transcript.done``. Required. + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar transcript: The final transcript of the audio. Required. + :vartype transcript: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_audio_transcript.done``. Required. + RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + transcript: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The final transcript of the audio. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + transcript: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_AUDIO_TRANSCRIPT_DONE # type: ignore + + +class RealtimeServerEventResponseContentPartAdded( + RealtimeServerEvent, discriminator="response.content_part.added" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when a new content part is added to an assistant message item during response + generation. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.content_part.added``. Required. + RESPONSE_CONTENT_PART_ADDED. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_CONTENT_PART_ADDED + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item to which the content part was added. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar part: The content part that was added. Required. + :vartype part: ~azure.ai.projects.models.RealtimeServerEventResponseContentPartAddedPart + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_CONTENT_PART_ADDED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.content_part.added``. Required. RESPONSE_CONTENT_PART_ADDED.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item to which the content part was added. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + part: "_models.RealtimeServerEventResponseContentPartAddedPart" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The content part that was added. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + part: "_models.RealtimeServerEventResponseContentPartAddedPart", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_CONTENT_PART_ADDED # type: ignore + + +class RealtimeServerEventResponseContentPartAddedPart( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeServerEventResponseContentPartAddedPart. + + :ivar type: Is either a Literal["audio"] type or a Literal["text"] type. + :vartype type: str or str + :ivar text: + :vartype text: str + :ivar audio: + :vartype audio: str + :ivar transcript: + :vartype transcript: str + """ + + type: Optional[Literal["audio", "text"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Is either a Literal[\"audio\"] type or a Literal[\"text\"] type.""" + text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + transcript: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + type: Optional[Literal["audio", "text"]] = None, + text: Optional[str] = None, + audio: Optional[str] = None, + transcript: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventResponseContentPartDone( + RealtimeServerEvent, discriminator="response.content_part.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when a content part is done streaming in an assistant message item. Also emitted when + a Response is interrupted, incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.content_part.done``. Required. + RESPONSE_CONTENT_PART_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_CONTENT_PART_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar part: The content part that is done. Required. + :vartype part: ~azure.ai.projects.models.RealtimeServerEventResponseContentPartDonePart + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_CONTENT_PART_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.content_part.done``. Required. RESPONSE_CONTENT_PART_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + part: "_models.RealtimeServerEventResponseContentPartDonePart" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The content part that is done. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + part: "_models.RealtimeServerEventResponseContentPartDonePart", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_CONTENT_PART_DONE # type: ignore + + +class RealtimeServerEventResponseContentPartDonePart( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """RealtimeServerEventResponseContentPartDonePart. + + :ivar type: Is either a Literal["audio"] type or a Literal["text"] type. + :vartype type: str or str + :ivar text: + :vartype text: str + :ivar audio: + :vartype audio: str + :ivar transcript: + :vartype transcript: str + :ivar format: The audio format, when this is an audio content part. + :vartype format: ~azure.ai.projects.models.RealtimeAudioFormats + """ + + type: Optional[Literal["audio", "text"]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Is either a Literal[\"audio\"] type or a Literal[\"text\"] type.""" + text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + transcript: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + format: Optional["_models.RealtimeAudioFormats"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio format, when this is an audio content part.""" + + @overload + def __init__( + self, + *, + type: Optional[Literal["audio", "text"]] = None, + text: Optional[str] = None, + audio: Optional[str] = None, + transcript: Optional[str] = None, + format: Optional["_models.RealtimeAudioFormats"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RealtimeServerEventResponseCreated( + RealtimeServerEvent, discriminator="response.created" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when a new Response is created. The first event of response creation, where the + response is in an initial state of ``in_progress``. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.created``. Required. RESPONSE_CREATED. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_CREATED + :ivar response: Required. + :vartype response: ~azure.ai.projects.models.VoiceAgentRealtimeResponse + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_CREATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.created``. Required. RESPONSE_CREATED.""" + response: "_models.VoiceAgentRealtimeResponse" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response: "_models.VoiceAgentRealtimeResponse", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_CREATED # type: ignore + + +class RealtimeServerEventResponseDone( + RealtimeServerEvent, discriminator="response.done" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when a Response is done streaming. Always emitted, no matter the final state. The + Response object included in the ``response.done`` event will include all output Items in the + Response but will omit the raw audio data. Clients should check the ``status`` field of the + Response to determine if it was successful (``completed``) or if there was another outcome: + ``cancelled``, ``failed``, or ``incomplete``. A response will contain all output items that + were generated during the response, excluding any audio content. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.done``. Required. RESPONSE_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_DONE + :ivar response: Required. + :vartype response: ~azure.ai.projects.models.VoiceAgentRealtimeResponse + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.done``. Required. RESPONSE_DONE.""" + response: "_models.VoiceAgentRealtimeResponse" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response: "_models.VoiceAgentRealtimeResponse", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_DONE # type: ignore + + +class RealtimeServerEventResponseFunctionCallArgumentsDelta( + RealtimeServerEvent, discriminator="response.function_call_arguments.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the model-generated function call arguments are updated. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.function_call_arguments.delta``. Required. + RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the function call item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar call_id: The ID of the function call. Required. + :vartype call_id: str + :ivar delta: The arguments delta as a JSON string. Required. + :vartype delta: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.function_call_arguments.delta``. Required. + RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call. Required.""" + delta: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The arguments delta as a JSON string. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + call_id: str, + delta: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA # type: ignore + + +class RealtimeServerEventResponseFunctionCallArgumentsDone( + RealtimeServerEvent, discriminator="response.function_call_arguments.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when the model-generated function call arguments are done streaming. Also emitted when + a Response is interrupted, incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.function_call_arguments.done``. Required. + RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the function call item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar call_id: The ID of the function call. Required. + :vartype call_id: str + :ivar name: The name of the function that was called. Required. + :vartype name: str + :ivar arguments: The final arguments as a JSON string. Required. + :vartype arguments: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.function_call_arguments.done``. Required. + RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the function call. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the function that was called. Required.""" + arguments: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The final arguments as a JSON string. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + call_id: str, + name: str, + arguments: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE # type: ignore + + +class RealtimeServerEventResponseMCPCallArgumentsDelta( + RealtimeServerEvent, discriminator="response.mcp_call_arguments.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when MCP tool call arguments are updated during response generation. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.mcp_call_arguments.delta``. Required. + RESPONSE_MCP_CALL_ARGUMENTS_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_MCP_CALL_ARGUMENTS_DELTA + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the MCP tool call item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar delta: The JSON-encoded arguments delta. Required. + :vartype delta: str + :ivar obfuscation: + :vartype obfuscation: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.mcp_call_arguments.delta``. Required. + RESPONSE_MCP_CALL_ARGUMENTS_DELTA.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP tool call item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + delta: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The JSON-encoded arguments delta. Required.""" + obfuscation: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + delta: str, + obfuscation: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DELTA # type: ignore + + +class RealtimeServerEventResponseMCPCallArgumentsDone( + RealtimeServerEvent, discriminator="response.mcp_call_arguments.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when MCP tool call arguments are finalized during response generation. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.mcp_call_arguments.done``. Required. + RESPONSE_MCP_CALL_ARGUMENTS_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_MCP_CALL_ARGUMENTS_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the MCP tool call item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar arguments: The final JSON-encoded arguments string. Required. + :vartype arguments: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.mcp_call_arguments.done``. Required. + RESPONSE_MCP_CALL_ARGUMENTS_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP tool call item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + arguments: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The final JSON-encoded arguments string. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + arguments: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_MCP_CALL_ARGUMENTS_DONE # type: ignore + + +class RealtimeServerEventResponseMCPCallCompleted( + RealtimeServerEvent, discriminator="response.mcp_call.completed" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an MCP tool call has completed successfully. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.mcp_call.completed``. Required. + RESPONSE_MCP_CALL_COMPLETED. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_MCP_CALL_COMPLETED + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar item_id: The ID of the MCP tool call item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_COMPLETED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.mcp_call.completed``. Required. RESPONSE_MCP_CALL_COMPLETED.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP tool call item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + output_index: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_MCP_CALL_COMPLETED # type: ignore + + +class RealtimeServerEventResponseMCPCallFailed( + RealtimeServerEvent, discriminator="response.mcp_call.failed" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when an MCP tool call has failed. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.mcp_call.failed``. Required. + RESPONSE_MCP_CALL_FAILED. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_MCP_CALL_FAILED + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar item_id: The ID of the MCP tool call item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_FAILED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.mcp_call.failed``. Required. RESPONSE_MCP_CALL_FAILED.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP tool call item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + output_index: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_MCP_CALL_FAILED # type: ignore + + +class RealtimeServerEventResponseMCPCallInProgress( + RealtimeServerEvent, discriminator="response.mcp_call.in_progress" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an MCP tool call has started and is in progress. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.mcp_call.in_progress``. Required. + RESPONSE_MCP_CALL_IN_PROGRESS. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_MCP_CALL_IN_PROGRESS + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar item_id: The ID of the MCP tool call item. Required. + :vartype item_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_MCP_CALL_IN_PROGRESS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.mcp_call.in_progress``. Required. + RESPONSE_MCP_CALL_IN_PROGRESS.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the MCP tool call item. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + output_index: int, + item_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_MCP_CALL_IN_PROGRESS # type: ignore + + +class RealtimeServerEventResponseOutputItemAdded( + RealtimeServerEvent, discriminator="response.output_item.added" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when a new Item is created during Response generation. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_item.added``. Required. + RESPONSE_OUTPUT_ITEM_ADDED. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_ITEM_ADDED + :ivar response_id: The ID of the Response to which the item belongs. Required. + :vartype response_id: str + :ivar output_index: The index of the output item in the Response. Required. + :vartype output_index: int + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_ADDED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_item.added``. Required. RESPONSE_OUTPUT_ITEM_ADDED.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the Response to which the item belongs. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the Response. Required.""" + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + output_index: int, + item: "_models.RealtimeConversationItem", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_ADDED # type: ignore + + +class RealtimeServerEventResponseOutputItemDone( + RealtimeServerEvent, discriminator="response.output_item.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Returned when an Item is done streaming. Also emitted when a Response is interrupted, + incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_item.done``. Required. + RESPONSE_OUTPUT_ITEM_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_ITEM_DONE + :ivar response_id: The ID of the Response to which the item belongs. Required. + :vartype response_id: str + :ivar output_index: The index of the output item in the Response. Required. + :vartype output_index: int + :ivar item: Required. + :vartype item: ~azure.ai.projects.models.RealtimeConversationItem + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_item.done``. Required. RESPONSE_OUTPUT_ITEM_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the Response to which the item belongs. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the Response. Required.""" + item: "_models.RealtimeConversationItem" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + output_index: int, + item: "_models.RealtimeConversationItem", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_ITEM_DONE # type: ignore + + +class RealtimeServerEventResponseTextDelta( + RealtimeServerEvent, discriminator="response.output_text.delta" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when the text value of an "output_text" content part is updated. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_text.delta``. Required. + RESPONSE_OUTPUT_TEXT_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_TEXT_DELTA + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar delta: The text delta. Required. + :vartype delta: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_text.delta``. Required. RESPONSE_OUTPUT_TEXT_DELTA.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + delta: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The text delta. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + delta: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DELTA # type: ignore + + +class RealtimeServerEventResponseTextDone( + RealtimeServerEvent, discriminator="response.output_text.done" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when the text value of an "output_text" content part is done streaming. Also emitted + when a Response is interrupted, incomplete, or cancelled. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``response.output_text.done``. Required. + RESPONSE_OUTPUT_TEXT_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_OUTPUT_TEXT_DONE + :ivar response_id: The ID of the response. Required. + :vartype response_id: str + :ivar item_id: The ID of the item. Required. + :vartype item_id: str + :ivar output_index: The index of the output item in the response. Required. + :vartype output_index: int + :ivar content_index: The index of the content part in the item's content array. Required. + :vartype content_index: int + :ivar text: The final text content. Required. + :vartype text: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``response.output_text.done``. Required. RESPONSE_OUTPUT_TEXT_DONE.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the response. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the item. Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the output item in the response. Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the content part in the item's content array. Required.""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The final text content. Required.""" + + @overload + def __init__( + self, + *, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + text: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_OUTPUT_TEXT_DONE # type: ignore + + +class RealtimeServerEventSessionCreated( + RealtimeServerEvent, discriminator="session.created" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when a Session is created. Emitted automatically when a new connection is established + as the first server event. This event will contain the default Session configuration. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``session.created``. Required. SESSION_CREATED. + :vartype type: str or ~azure.ai.projects.models.SESSION_CREATED + :ivar session: The session configuration. Required. Is one of the following types: + VoiceAgentSessionResponseConfig + :vartype session: ~azure.ai.projects.models.VoiceAgentSessionResponseConfig + :ivar conversation_id: The session-scoped conversation id. When present, responses attached to + the session conversation use the same value in ``response.created`` and ``response.done``. + :vartype conversation_id: str + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.SESSION_CREATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``session.created``. Required. SESSION_CREATED.""" + session: "_unions.VoiceAgentSessionResponse" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The session configuration. Required. Is one of the following types: + VoiceAgentSessionResponseConfig""" + conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The session-scoped conversation id. When present, responses attached to the session + conversation use the same value in ``response.created`` and ``response.done``.""" + + @overload + def __init__( + self, + *, + event_id: str, + session: "_unions.VoiceAgentSessionResponse", + conversation_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.SESSION_CREATED # type: ignore + + +class RealtimeServerEventSessionUpdated( + RealtimeServerEvent, discriminator="session.updated" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Returned when a session is updated with a ``session.update`` event, unless there is an error. + + :ivar event_id: The unique ID of the server event. Required. + :vartype event_id: str + :ivar type: The event type, must be ``session.updated``. Required. SESSION_UPDATED. + :vartype type: str or ~azure.ai.projects.models.SESSION_UPDATED + :ivar session: The session configuration. Required. Is one of the following types: + VoiceAgentSessionResponseConfig + :vartype session: ~azure.ai.projects.models.VoiceAgentSessionResponseConfig + """ + + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the server event. Required.""" + type: Literal[RealtimeServerEventType.SESSION_UPDATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type, must be ``session.updated``. Required. SESSION_UPDATED.""" + session: "_unions.VoiceAgentSessionResponse" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The session configuration. Required. Is one of the following types: + VoiceAgentSessionResponseConfig""" + + @overload + def __init__( + self, + *, + event_id: str, + session: "_unions.VoiceAgentSessionResponse", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.SESSION_UPDATED # type: ignore + + +class Reasoning(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Reasoning. + + :ivar mode: Controls the reasoning execution mode for the request. When returned on a response, + this is the effective execution mode. Known values are: "standard" and "pro". + :vartype mode: str or ~azure.ai.projects.models.ReasoningModeEnum + :ivar effort: Known values are: "none", "minimal", "low", "medium", "high", "xhigh", and "max". + :vartype effort: str or ~azure.ai.projects.models.ReasoningEffort + :ivar summary: Is one of the following types: Literal["auto"], Literal["concise"], + Literal["detailed"] + :vartype summary: str or str or str + :ivar context: Is one of the following types: Literal["auto"], Literal["current_turn"], + Literal["all_turns"] + :vartype context: str or str or str + :ivar generate_summary: Is one of the following types: Literal["auto"], Literal["concise"], + Literal["detailed"] + :vartype generate_summary: str or str or str + """ + + mode: Optional[Union[str, "_models.ReasoningModeEnum"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Controls the reasoning execution mode for the request. When returned on a response, this is the + effective execution mode. Known values are: \"standard\" and \"pro\".""" + effort: Optional[Union[str, "_models.ReasoningEffort"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Known values are: \"none\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", and \"max\".""" + summary: Optional[Literal["auto", "concise", "detailed"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"auto\"], Literal[\"concise\"], Literal[\"detailed\"]""" + context: Optional[Literal["auto", "current_turn", "all_turns"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"auto\"], Literal[\"current_turn\"], + Literal[\"all_turns\"]""" + generate_summary: Optional[Literal["auto", "concise", "detailed"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is one of the following types: Literal[\"auto\"], Literal[\"concise\"], Literal[\"detailed\"]""" + + @overload + def __init__( + self, + *, + mode: Optional[Union[str, "_models.ReasoningModeEnum"]] = None, + effort: Optional[Union[str, "_models.ReasoningEffort"]] = None, + summary: Optional[Literal["auto", "concise", "detailed"]] = None, + context: Optional[Literal["auto", "current_turn", "all_turns"]] = None, + generate_summary: Optional[Literal["auto", "concise", "detailed"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RecurrenceTrigger( + Trigger, discriminator="Recurrence" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Recurrence based trigger. + + :ivar type: Type of the trigger. Required. Recurrence based trigger. + :vartype type: str or ~azure.ai.projects.models.RECURRENCE + :ivar start_time: Start time for the recurrence schedule in ISO 8601 format. + :vartype start_time: ~datetime.datetime + :ivar end_time: End time for the recurrence schedule in ISO 8601 format. + :vartype end_time: ~datetime.datetime + :ivar time_zone: Time zone for the recurrence schedule. Defaults to ``UTC``. + :vartype time_zone: str + :ivar interval: Interval for the recurrence schedule. Required. + :vartype interval: int + :ivar schedule: Recurrence schedule for the recurrence trigger. Required. + :vartype schedule: ~azure.ai.projects.models.RecurrenceSchedule + """ + + type: Literal[TriggerType.RECURRENCE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Type of the trigger. Required. Recurrence based trigger.""" + start_time: Optional[datetime.datetime] = rest_field( + name="startTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" + ) + """Start time for the recurrence schedule in ISO 8601 format.""" + end_time: Optional[datetime.datetime] = rest_field( + name="endTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" + ) + """End time for the recurrence schedule in ISO 8601 format.""" + time_zone: Optional[str] = rest_field(name="timeZone", visibility=["read", "create", "update", "delete", "query"]) + """Time zone for the recurrence schedule. Defaults to ``UTC``.""" + interval: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Interval for the recurrence schedule. Required.""" + schedule: "_models.RecurrenceSchedule" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Recurrence schedule for the recurrence trigger. Required.""" + + @overload + def __init__( + self, + *, + interval: int, + schedule: "_models.RecurrenceSchedule", + start_time: Optional[datetime.datetime] = None, + end_time: Optional[datetime.datetime] = None, + time_zone: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TriggerType.RECURRENCE # type: ignore + + +class RedTeam(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Red team details. + + :ivar name: Identifier of the red team run. Required. + :vartype name: str + :ivar display_name: Name of the red-team run. + :vartype display_name: str + :ivar num_turns: Number of simulation rounds. + :vartype num_turns: int + :ivar attack_strategies: List of attack strategies or nested lists of attack strategies. + :vartype attack_strategies: list[str or ~azure.ai.projects.models.AttackStrategy] + :ivar simulation_only: Simulation-only or Simulation + Evaluation. If ``true`` the scan outputs + conversation not evaluation result. The service defaults to ``false`` if a value is not + specified by the caller. + :vartype simulation_only: bool + :ivar risk_categories: List of risk categories to generate attack objectives for. + :vartype risk_categories: list[str or ~azure.ai.projects.models.RiskCategory] + :ivar application_scenario: Application scenario for the red team operation, to generate + scenario specific attacks. + :vartype application_scenario: str + :ivar tags: Red team's tags. Unlike properties, tags are fully mutable. + :vartype tags: dict[str, str] + :ivar properties: Red team's properties. Unlike tags, properties are add-only. Once added, a + property cannot be removed. + :vartype properties: dict[str, str] + :ivar status: Status of the red-team. It is set by service and is read-only. + :vartype status: str + :ivar target: Target configuration for the red-team run. Required. + :vartype target: ~azure.ai.projects.models.RedTeamTargetConfig + """ + + name: str = rest_field(name="id", visibility=["read"]) + """Identifier of the red team run. Required.""" + display_name: Optional[str] = rest_field( + name="displayName", visibility=["read", "create", "update", "delete", "query"] + ) + """Name of the red-team run.""" + num_turns: Optional[int] = rest_field(name="numTurns", visibility=["read", "create", "update", "delete", "query"]) + """Number of simulation rounds.""" + attack_strategies: Optional[list[Union[str, "_models.AttackStrategy"]]] = rest_field( + name="attackStrategies", visibility=["read", "create", "update", "delete", "query"] + ) + """List of attack strategies or nested lists of attack strategies.""" + simulation_only: Optional[bool] = rest_field( + name="simulationOnly", visibility=["read", "create", "update", "delete", "query"] + ) + """Simulation-only or Simulation + Evaluation. If ``true`` the scan outputs conversation not + evaluation result. The service defaults to ``false`` if a value is not specified by the caller.""" + risk_categories: Optional[list[Union[str, "_models.RiskCategory"]]] = rest_field( + name="riskCategories", visibility=["read", "create", "update", "delete", "query"] + ) + """List of risk categories to generate attack objectives for.""" + application_scenario: Optional[str] = rest_field( + name="applicationScenario", visibility=["read", "create", "update", "delete", "query"] + ) + """Application scenario for the red team operation, to generate scenario specific attacks.""" + tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Red team's tags. Unlike properties, tags are fully mutable.""" + properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Red team's properties. Unlike tags, properties are add-only. Once added, a property cannot be + removed.""" + status: Optional[str] = rest_field(visibility=["read"]) + """Status of the red-team. It is set by service and is read-only.""" + target: "_models.RedTeamTargetConfig" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Target configuration for the red-team run. Required.""" + + @overload + def __init__( + self, + *, + target: "_models.RedTeamTargetConfig", + display_name: Optional[str] = None, + num_turns: Optional[int] = None, + attack_strategies: Optional[list[Union[str, "_models.AttackStrategy"]]] = None, + simulation_only: Optional[bool] = None, + risk_categories: Optional[list[Union[str, "_models.RiskCategory"]]] = None, + application_scenario: Optional[str] = None, + tags: Optional[dict[str, str]] = None, + properties: Optional[dict[str, str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ReminderPreviewToolboxTool( + ToolboxTool, discriminator="reminder_preview" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A reminder tool stored in a toolbox. + + :ivar name: Optional user-defined name for this tool or configuration. + :vartype name: str + :ivar description: Optional user-defined description for this tool or configuration. + :vartype description: str + :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all + default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names + are silently ignored at runtime. + :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] + :ivar type: Required. REMINDER_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.REMINDER_PREVIEW + """ + + type: Literal[ToolboxToolType.REMINDER_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. REMINDER_PREVIEW.""" + + @overload + def __init__( + self, + *, + name: Optional[str] = None, + description: Optional[str] = None, + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolboxToolType.REMINDER_PREVIEW # type: ignore + + +class ResponsesProtocolConfiguration(_Model): + """Configuration specific to the responses protocol.""" + + +class ResponseUsageInputTokensDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """ResponseUsageInputTokensDetails. + + :ivar cached_tokens: Required. + :vartype cached_tokens: int + :ivar cache_write_tokens: Required. + :vartype cache_write_tokens: int + """ + + cached_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + cache_write_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + cached_tokens: int, + cache_write_tokens: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ResponseUsageOutputTokensDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """ResponseUsageOutputTokensDetails. + + :ivar reasoning_tokens: Required. + :vartype reasoning_tokens: int + """ + + reasoning_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + + @overload + def __init__( + self, + *, + reasoning_tokens: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class Routine(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A routine definition returned by the service. + + :ivar name: The routine name. + :vartype name: str + :ivar description: A human-readable description of the routine. + :vartype description: str + :ivar enabled: Whether the routine is enabled. Required. + :vartype enabled: bool + :ivar triggers: The triggers configured for the routine. + :vartype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] + :ivar action: The action executed when the routine fires. + :vartype action: ~azure.ai.projects.models.RoutineAction + :ivar created_at: The time when the routine was created. + :vartype created_at: ~datetime.datetime + :ivar updated_at: The time when the routine was last updated. + :vartype updated_at: ~datetime.datetime + """ + + name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The routine name.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of the routine.""" + enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the routine is enabled. Required.""" + triggers: Optional[dict[str, "_models.RoutineTrigger"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The triggers configured for the routine.""" + action: Optional["_models.RoutineAction"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The action executed when the routine fires.""" + created_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The time when the routine was created.""" + updated_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The time when the routine was last updated.""" + + @overload + def __init__( + self, + *, + enabled: bool, + name: Optional[str] = None, + description: Optional[str] = None, + triggers: Optional[dict[str, "_models.RoutineTrigger"]] = None, + action: Optional["_models.RoutineAction"] = None, + created_at: Optional[datetime.datetime] = None, + updated_at: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RoutineAuthorization(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Optional authorization configuration for a routine dispatch. + + :ivar identity: The identity used when dispatching the routine. Defaults to agent when omitted; + set to creator only when the customer opts in to creator identity dispatch. Known values are: + "agent" and "creator". + :vartype identity: str or ~azure.ai.projects.models.RoutineDispatchIdentity + """ + + identity: Optional[Union[str, "_models.RoutineDispatchIdentity"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The identity used when dispatching the routine. Defaults to agent when omitted; set to creator + only when the customer opts in to creator identity dispatch. Known values are: \"agent\" and + \"creator\".""" + + @overload + def __init__( + self, + *, + identity: Optional[Union[str, "_models.RoutineDispatchIdentity"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RoutineRun(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A single routine run returned from the run history API. + + :ivar id: The unique run identifier for the routine attempt. Required. + :vartype id: str + :ivar status: The run status. Is one of the following types: str + :vartype status: str + :ivar phase: The AgentExtensions lifecycle phase for the routine attempt. Known values are: + "queued", "dispatching", "completed", and "failed". + :vartype phase: str or ~azure.ai.projects.models.RoutineRunPhase + :ivar trigger_type: The trigger type that produced the routine attempt. Known values are: + "custom", "github_issue", "schedule", and "timer". + :vartype trigger_type: str or ~azure.ai.projects.models.RoutineTriggerType + :ivar trigger_name: The configured trigger name that produced the routine attempt. + :vartype trigger_name: str + :ivar trigger_event_payload: The event payload captured from the event that triggered the + routine attempt, when available. + :vartype trigger_event_payload: dict[str, any] + :ivar attempt_source: The source path that created the routine attempt. Known values are: + "event_fire", "manual_dispatch", "queued_dispatch", "schedule_delivery", and "timer_delivery". + :vartype attempt_source: str or ~azure.ai.projects.models.RoutineAttemptSource + :ivar action_type: The action type dispatched for the routine attempt. Known values are: + "invoke_agent_responses_api" and "invoke_agent_invocations_api". + :vartype action_type: str or ~azure.ai.projects.models.RoutineActionType + :ivar agent_id: The project-scoped agent identifier recorded for the routine attempt. + :vartype agent_id: str + :ivar agent_endpoint_id: The legacy endpoint-scoped agent identifier recorded for the routine + attempt. + :vartype agent_endpoint_id: str + :ivar conversation_id: The conversation identifier used by a responses API dispatch. + :vartype conversation_id: str + :ivar session_id: The hosted-agent session identifier used by an invocations API dispatch. + :vartype session_id: str + :ivar triggered_at: The logical trigger time recorded for the routine attempt. + :vartype triggered_at: ~datetime.datetime + :ivar scheduled_fire_at: The scheduled fire time recorded for timer and schedule deliveries. + :vartype scheduled_fire_at: ~datetime.datetime + :ivar started_at: The time when the underlying run started. + :vartype started_at: ~datetime.datetime + :ivar ended_at: The time when the underlying run reached a terminal state. + :vartype ended_at: ~datetime.datetime + :ivar dispatch_id: The dispatch identifier associated with the routine attempt. + :vartype dispatch_id: str + :ivar action_correlation_id: The downstream action correlation identifier, when available. + :vartype action_correlation_id: str + :ivar response_id: The downstream response or invocation identifier, when available. + :vartype response_id: str + :ivar task_id: The workspace task identifier linked to the routine attempt, when available. + :vartype task_id: str + :ivar error_status_code: The downstream error status code captured for a failed attempt, when + available. + :vartype error_status_code: int + :ivar error_type: The fully qualified error type captured for a failed attempt, when available. + :vartype error_type: str + :ivar error_message: The truncated failure message captured for a failed attempt, when + available. + :vartype error_message: str + """ + + id: str = rest_field(visibility=["read"]) + """The unique run identifier for the routine attempt. Required.""" + status: Optional["_unions.RoutineRunStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The run status. Is one of the following types: str""" + phase: Optional[Union[str, "_models.RoutineRunPhase"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The AgentExtensions lifecycle phase for the routine attempt. Known values are: \"queued\", + \"dispatching\", \"completed\", and \"failed\".""" + trigger_type: Optional[Union[str, "_models.RoutineTriggerType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The trigger type that produced the routine attempt. Known values are: \"custom\", \"github_issue\", \"schedule\", and \"timer\".""" trigger_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) """The configured trigger name that produced the routine attempt.""" trigger_event_payload: Optional[dict[str, Any]] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The event payload captured from the event that triggered the routine attempt, when available.""" - attempt_source: Optional[Union[str, "_models.RoutineAttemptSource"]] = rest_field( + """The event payload captured from the event that triggered the routine attempt, when available.""" + attempt_source: Optional[Union[str, "_models.RoutineAttemptSource"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The source path that created the routine attempt. Known values are: \"event_fire\", + \"manual_dispatch\", \"queued_dispatch\", \"schedule_delivery\", and \"timer_delivery\".""" + action_type: Optional[Union[str, "_models.RoutineActionType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The action type dispatched for the routine attempt. Known values are: + \"invoke_agent_responses_api\" and \"invoke_agent_invocations_api\".""" + agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The project-scoped agent identifier recorded for the routine attempt.""" + agent_endpoint_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The legacy endpoint-scoped agent identifier recorded for the routine attempt.""" + conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The conversation identifier used by a responses API dispatch.""" + session_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The hosted-agent session identifier used by an invocations API dispatch.""" + triggered_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The logical trigger time recorded for the routine attempt.""" + scheduled_fire_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The scheduled fire time recorded for timer and schedule deliveries.""" + started_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The time when the underlying run started.""" + ended_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The time when the underlying run reached a terminal state.""" + dispatch_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The dispatch identifier associated with the routine attempt.""" + action_correlation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The downstream action correlation identifier, when available.""" + response_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The downstream response or invocation identifier, when available.""" + task_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The workspace task identifier linked to the routine attempt, when available.""" + error_status_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The downstream error status code captured for a failed attempt, when available.""" + error_type: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The fully qualified error type captured for a failed attempt, when available.""" + error_message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The truncated failure message captured for a failed attempt, when available.""" + + @overload + def __init__( + self, + *, + status: Optional["_unions.RoutineRunStatus"] = None, + phase: Optional[Union[str, "_models.RoutineRunPhase"]] = None, + trigger_type: Optional[Union[str, "_models.RoutineTriggerType"]] = None, + trigger_name: Optional[str] = None, + trigger_event_payload: Optional[dict[str, Any]] = None, + attempt_source: Optional[Union[str, "_models.RoutineAttemptSource"]] = None, + action_type: Optional[Union[str, "_models.RoutineActionType"]] = None, + agent_id: Optional[str] = None, + agent_endpoint_id: Optional[str] = None, + conversation_id: Optional[str] = None, + session_id: Optional[str] = None, + triggered_at: Optional[datetime.datetime] = None, + scheduled_fire_at: Optional[datetime.datetime] = None, + started_at: Optional[datetime.datetime] = None, + ended_at: Optional[datetime.datetime] = None, + dispatch_id: Optional[str] = None, + action_correlation_id: Optional[str] = None, + response_id: Optional[str] = None, + task_id: Optional[str] = None, + error_status_code: Optional[int] = None, + error_type: Optional[str] = None, + error_message: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RubricBasedEvaluatorDefinition( + EvaluatorDefinition, discriminator="rubric" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Rubric-based evaluator definition — stores dimensions produced by the generate API. Used for + both quality and safety evaluators. + + :ivar init_parameters: The JSON schema (Draft 2020-12) for the evaluator's input parameters. + This includes parameters like type, properties, required. + :vartype init_parameters: dict[str, any] + :ivar data_schema: The JSON schema (Draft 2020-12) for the evaluator's input data. This + includes parameters like type, properties, required. + :vartype data_schema: dict[str, any] + :ivar metrics: List of output metrics produced by this evaluator. + :vartype metrics: dict[str, ~azure.ai.projects.models.EvaluatorMetric] + :ivar type: Required. Rubric-based evaluator definition. Stores dimensions (the scoring + blueprint) for both quality and safety evaluators. Can be created via the generate API or + manually via createVersion. + :vartype type: str or ~azure.ai.projects.models.RUBRIC + :ivar dimensions: The set of dimensions — the scoring blueprint used by the LLM judge. Quality + evaluators include a non-editable residual dimension with id 'general_quality' + (always_applicable: true); safety evaluators include 'general_policy_compliance'. Both use the + same Dimension structure. Required. + :vartype dimensions: list[~azure.ai.projects.models.Dimension] + :ivar pass_threshold: Pass/fail threshold for the aggregate rubric score, on the same + normalized 0.0-1.0 scale as the emitted ``score``. When the runtime weighted average meets or + exceeds this value, the result is ``pass``. Defaults to 0.5 (equivalent to a raw 1-5 weighted + average of 3.0). The 'any dimension scored 1 → fail' rule still applies regardless of this + threshold. + :vartype pass_threshold: float + """ + + type: Literal[EvaluatorDefinitionType.RUBRIC] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Rubric-based evaluator definition. Stores dimensions (the scoring blueprint) for both + quality and safety evaluators. Can be created via the generate API or manually via + createVersion.""" + dimensions: list["_models.Dimension"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The set of dimensions — the scoring blueprint used by the LLM judge. Quality evaluators include + a non-editable residual dimension with id 'general_quality' (always_applicable: true); safety + evaluators include 'general_policy_compliance'. Both use the same Dimension structure. + Required.""" + pass_threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Pass/fail threshold for the aggregate rubric score, on the same normalized 0.0-1.0 scale as the + emitted ``score``. When the runtime weighted average meets or exceeds this value, the result is + ``pass``. Defaults to 0.5 (equivalent to a raw 1-5 weighted average of 3.0). The 'any dimension + scored 1 → fail' rule still applies regardless of this threshold.""" + + @overload + def __init__( + self, + *, + dimensions: list["_models.Dimension"], + init_parameters: Optional[dict[str, Any]] = None, + data_schema: Optional[dict[str, Any]] = None, + metrics: Optional[dict[str, "_models.EvaluatorMetric"]] = None, + pass_threshold: Optional[float] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = EvaluatorDefinitionType.RUBRIC # type: ignore + + +class RubricGenerationInputQualityWarning(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A non-fatal advisory produced during rubric evaluator generation when resolved inputs are + technically valid but likely too weak to produce a high-quality rubric. Read-only; + service-generated. Persisted with the terminal EvaluatorGenerationJob. + + :ivar code: Stable searchable machine-readable warning code. Required. Known values are: + "empty_prompt", "short_prompt", "empty_agent_instructions", "short_agent_instructions", + "empty_dataset_content", "short_dataset_content", "low_trace_count", and + "insufficient_total_input". + :vartype code: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningCode + :ivar severity: Advisory severity. Initial values: ``warning``. Required. "warning" + :vartype severity: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningSeverity + :ivar message: Human-readable message suitable for direct SDK/CLI/UI display. Must not include + raw prompt, instruction, dataset, or trace text. Required. + :vartype message: str + :ivar source: Which source category the warning applies to. ``aggregate`` is used only for + cross-source warnings. Required. Known values are: "prompt", "agent", "dataset", and + "aggregate". + :vartype source: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningSource + :ivar source_index: Zero-based index into ``EvaluatorGenerationJob.inputs.sources`` when the + warning applies to a specific source. Omitted for aggregate warnings and for warnings not tied + to one source. + :vartype source_index: int + """ + + code: Union[str, "_models.RubricGenerationInputQualityWarningCode"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Stable searchable machine-readable warning code. Required. Known values are: \"empty_prompt\", + \"short_prompt\", \"empty_agent_instructions\", \"short_agent_instructions\", + \"empty_dataset_content\", \"short_dataset_content\", \"low_trace_count\", and + \"insufficient_total_input\".""" + severity: Union[str, "_models.RubricGenerationInputQualityWarningSeverity"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Advisory severity. Initial values: ``warning``. Required. \"warning\"""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Human-readable message suitable for direct SDK/CLI/UI display. Must not include raw prompt, + instruction, dataset, or trace text. Required.""" + source: Union[str, "_models.RubricGenerationInputQualityWarningSource"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Which source category the warning applies to. ``aggregate`` is used only for cross-source + warnings. Required. Known values are: \"prompt\", \"agent\", \"dataset\", and \"aggregate\".""" + source_index: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Zero-based index into ``EvaluatorGenerationJob.inputs.sources`` when the warning applies to a + specific source. Omitted for aggregate warnings and for warnings not tied to one source.""" + + @overload + def __init__( + self, + *, + code: Union[str, "_models.RubricGenerationInputQualityWarningCode"], + severity: Union[str, "_models.RubricGenerationInputQualityWarningSeverity"], + message: str, + source: Union[str, "_models.RubricGenerationInputQualityWarningSource"], + source_index: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SASCredentials(BaseCredentials, discriminator="SAS"): + """Shared Access Signature (SAS) credential definition. + + :ivar type: The credential type. Required. Shared Access Signature (SAS) credential. + :vartype type: str or ~azure.ai.projects.models.SAS + :ivar sas_token: SAS token. + :vartype sas_token: str + """ + + type: Literal[CredentialType.SAS] = rest_discriminator(name="type", visibility=["read"]) # type: ignore + """The credential type. Required. Shared Access Signature (SAS) credential.""" + sas_token: Optional[str] = rest_field(name="SAS", visibility=["read"]) + """SAS token.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = CredentialType.SAS # type: ignore + + +class Schedule(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Schedule model. + + :ivar schedule_id: Identifier of the schedule. Required. + :vartype schedule_id: str + :ivar display_name: Name of the schedule. + :vartype display_name: str + :ivar description: Description of the schedule. + :vartype description: str + :ivar enabled: Enabled status of the schedule. Required. + :vartype enabled: bool + :ivar provisioning_status: Provisioning status of the schedule. Known values are: "Creating", + "Updating", "Deleting", "Succeeded", and "Failed". + :vartype provisioning_status: str or ~azure.ai.projects.models.ScheduleProvisioningStatus + :ivar trigger: Trigger for the schedule. Required. + :vartype trigger: ~azure.ai.projects.models.Trigger + :ivar task: Task for the schedule. Required. + :vartype task: ~azure.ai.projects.models.ScheduleTask + :ivar tags: Schedule's tags. Unlike properties, tags are fully mutable. + :vartype tags: dict[str, str] + :ivar properties: Schedule's properties. Unlike tags, properties are add-only. Once added, a + property cannot be removed. + :vartype properties: dict[str, str] + :ivar system_data: System metadata for the resource. Required. + :vartype system_data: dict[str, str] + """ + + schedule_id: str = rest_field(name="id", visibility=["read"]) + """Identifier of the schedule. Required.""" + display_name: Optional[str] = rest_field( + name="displayName", visibility=["read", "create", "update", "delete", "query"] + ) + """Name of the schedule.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Description of the schedule.""" + enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Enabled status of the schedule. Required.""" + provisioning_status: Optional[Union[str, "_models.ScheduleProvisioningStatus"]] = rest_field( + name="provisioningStatus", visibility=["read"] + ) + """Provisioning status of the schedule. Known values are: \"Creating\", \"Updating\", + \"Deleting\", \"Succeeded\", and \"Failed\".""" + trigger: "_models.Trigger" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Trigger for the schedule. Required.""" + task: "_models.ScheduleTask" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Task for the schedule. Required.""" + tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Schedule's tags. Unlike properties, tags are fully mutable.""" + properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Schedule's properties. Unlike tags, properties are add-only. Once added, a property cannot be + removed.""" + system_data: dict[str, str] = rest_field(name="systemData", visibility=["read"]) + """System metadata for the resource. Required.""" + + @overload + def __init__( + self, + *, + enabled: bool, + trigger: "_models.Trigger", + task: "_models.ScheduleTask", + display_name: Optional[str] = None, + description: Optional[str] = None, + tags: Optional[dict[str, str]] = None, + properties: Optional[dict[str, str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ScheduleRoutineTrigger( + RoutineTrigger, discriminator="schedule" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A recurring cron-based routine trigger. + + :ivar type: The trigger type. Required. A recurring cron-based trigger. + :vartype type: str or ~azure.ai.projects.models.SCHEDULE + :ivar cron_expression: A 5-field cron expression. The service enforces a minimum interval of + five minutes by default. Required. + :vartype cron_expression: str + :ivar time_zone: An IANA or Windows time zone identifier for the schedule. Required. + :vartype time_zone: str + """ + + type: Literal[RoutineTriggerType.SCHEDULE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The trigger type. Required. A recurring cron-based trigger.""" + cron_expression: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A 5-field cron expression. The service enforces a minimum interval of five minutes by default. + Required.""" + time_zone: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An IANA or Windows time zone identifier for the schedule. Required.""" + + @overload + def __init__( + self, + *, + cron_expression: str, + time_zone: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RoutineTriggerType.SCHEDULE # type: ignore + + +class ScheduleRun(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Schedule run model. + + :ivar run_id: Identifier of the schedule run. Required. + :vartype run_id: str + :ivar schedule_id: Identifier of the schedule. Required. + :vartype schedule_id: str + :ivar success: Trigger success status of the schedule run. Required. + :vartype success: bool + :ivar trigger_time: Trigger time of the schedule run. + :vartype trigger_time: ~datetime.datetime + :ivar error: Error information for the schedule run. + :vartype error: str + :ivar properties: Properties of the schedule run. Required. + :vartype properties: dict[str, str] + """ + + run_id: str = rest_field(name="id", visibility=["read"]) + """Identifier of the schedule run. Required.""" + schedule_id: str = rest_field(name="scheduleId", visibility=["read", "create", "update", "delete", "query"]) + """Identifier of the schedule. Required.""" + success: bool = rest_field(visibility=["read"]) + """Trigger success status of the schedule run. Required.""" + trigger_time: Optional[datetime.datetime] = rest_field( + name="triggerTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" + ) + """Trigger time of the schedule run.""" + error: Optional[str] = rest_field(visibility=["read"]) + """Error information for the schedule run.""" + properties: dict[str, str] = rest_field(visibility=["read"]) + """Properties of the schedule run. Required.""" + + @overload + def __init__( + self, + *, + schedule_id: str, + trigger_time: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SessionConfiguration(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Session defaults applied to sessions created for a hosted agent version. + + :ivar idle_timeout_seconds: The idle duration, in seconds, before a session's sandbox is + suspended. Optional — when unset, the server default of 900 seconds is used. Must be between + 120 and 3600 seconds (inclusive). + :vartype idle_timeout_seconds: ~datetime.timedelta + """ + + idle_timeout_seconds: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The idle duration, in seconds, before a session's sandbox is suspended. Optional — when unset, + the server default of 900 seconds is used. Must be between 120 and 3600 seconds (inclusive).""" + + @overload + def __init__( + self, + *, + idle_timeout_seconds: Optional[datetime.timedelta] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SessionDirectoryEntry(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A single entry in a directory listing. + + :ivar name: The name of the file or directory. Required. + :vartype name: str + :ivar size: The size in bytes (0 for directories). Required. + :vartype size: int + :ivar is_directory: Whether this entry is a directory. Required. + :vartype is_directory: bool + :ivar modified_time: The Unix timestamp (in seconds) when the file was last modified. Required. + :vartype modified_time: ~datetime.datetime + """ + + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the file or directory. Required.""" + size: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The size in bytes (0 for directories). Required.""" + is_directory: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether this entry is a directory. Required.""" + modified_time: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) when the file was last modified. Required.""" + + @overload + def __init__( + self, + *, + name: str, + size: int, + is_directory: bool, + modified_time: datetime.datetime, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SessionFileWriteResult(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Response from uploading a file to a session sandbox. + + :ivar path: The path where the file was written, relative to the session home directory. + Required. + :vartype path: str + :ivar bytes_written: Number of bytes written. Required. + :vartype bytes_written: int + """ + + path: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The path where the file was written, relative to the session home directory. Required.""" + bytes_written: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Number of bytes written. Required.""" + + @overload + def __init__( + self, + *, + path: str, + bytes_written: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SessionLogEvent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A single Server-Sent Event frame emitted by the hosted agent session log stream. + + Each frame contains an ``event`` field identifying the event type and a ``data`` + field carrying the payload as plain text. Although the current ``data`` payload + is JSON-formatted, its schema is not contractual — additional keys may appear + and the format may change over time. Clients should treat ``data`` as an + opaque string and optionally attempt JSON parsing. + + New event types may be added in the future. Clients should gracefully + ignore unrecognized event types. + + Wire format: + + .. code-block:: + + event: log + data: {"timestamp":"2026-03-10T09:33:17.121Z","stream":"stdout","message":"Starting server on port 18080"} + + event: log + data: {"timestamp":"2026-03-10T09:34:52.714Z","stream":"status","message":"Successfully connected to container"} + + :ivar event: The SSE event type. Currently ``log``, but additional event types may be added in + the future. Clients should ignore unrecognized event types. Required. "log" + :vartype event: str or ~azure.ai.projects.models.SessionLogEventType + :ivar data: The event payload as plain text. Currently JSON-formatted but the schema is not + contractual and may change. Required. + :vartype data: str + """ + + event: Union[str, "_models.SessionLogEventType"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The SSE event type. Currently ``log``, but additional event types may be added in the future. + Clients should ignore unrecognized event types. Required. \"log\"""" + data: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The event payload as plain text. Currently JSON-formatted but the schema is not contractual and + may change. Required.""" + + @overload + def __init__( + self, + *, + event: Union[str, "_models.SessionLogEventType"], + data: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SharepointGroundingToolParameters(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The sharepoint grounding tool parameters. + + :ivar project_connections: The project connections attached to this tool. There can be a + maximum of 1 connection resource attached to the tool. + :vartype project_connections: list[~azure.ai.projects.models.ToolProjectConnection] + """ + + project_connections: Optional[list["_models.ToolProjectConnection"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The project connections attached to this tool. There can be a maximum of 1 connection resource + attached to the tool.""" + + @overload + def __init__( + self, + *, + project_connections: Optional[list["_models.ToolProjectConnection"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SharepointPreviewTool( + Tool, discriminator="sharepoint_grounding_preview" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The input definition information for a sharepoint tool as used to configure an agent. + + :ivar type: The object type, which is always 'sharepoint_grounding_preview'. Required. + SHAREPOINT_GROUNDING_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.SHAREPOINT_GROUNDING_PREVIEW + :ivar sharepoint_grounding_preview: The sharepoint grounding tool parameters. Required. + :vartype sharepoint_grounding_preview: + ~azure.ai.projects.models.SharepointGroundingToolParameters + """ + + type: Literal[ToolType.SHAREPOINT_GROUNDING_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The object type, which is always 'sharepoint_grounding_preview'. Required. + SHAREPOINT_GROUNDING_PREVIEW.""" + sharepoint_grounding_preview: "_models.SharepointGroundingToolParameters" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The sharepoint grounding tool parameters. Required.""" + + @overload + def __init__( + self, + *, + sharepoint_grounding_preview: "_models.SharepointGroundingToolParameters", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolType.SHAREPOINT_GROUNDING_PREVIEW # type: ignore + + +class ShellToolboxTool( + ToolboxTool, discriminator="shell" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A shell tool stored in a toolbox. This model is additive to toolbox configuration and does not + modify the OpenAI tool contract or existing toolbox tool definitions. + + :ivar name: Optional user-defined name for this tool or configuration. + :vartype name: str + :ivar description: Optional user-defined description for this tool or configuration. + :vartype description: str + :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all + default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names + are silently ignored at runtime. + :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] + :ivar type: The type of the tool. Always ``shell``. Required. SHELL. + :vartype type: str or ~azure.ai.projects.models.SHELL + :ivar allowed_callers: + :vartype allowed_callers: list[str or ~azure.ai.projects.models.CallableToolAllowedCaller] + :ivar environment: The environment in which shell commands are executed. Specify an + automatically provisioned container or an existing container. Required. + :vartype environment: ~azure.ai.projects.models.ToolboxShellEnvironment + """ + + type: Literal[ToolboxToolType.SHELL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``shell``. Required. SHELL.""" + allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + environment: "_models.ToolboxShellEnvironment" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The environment in which shell commands are executed. Specify an automatically provisioned + container or an existing container. Required.""" + + @overload + def __init__( + self, + *, + environment: "_models.ToolboxShellEnvironment", + name: Optional[str] = None, + description: Optional[str] = None, + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolboxToolType.SHELL # type: ignore + + +class SimpleQnADataGenerationJobOptions( + DataGenerationJobOptions, discriminator="simple_qna" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The options for a data generation job with SimpleQnA type. + + :ivar train_split: The proportion of the generated data to be used for training when the data + is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. + :vartype train_split: float + :ivar model_options: The LLM model options. + :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions + :ivar type: The data generation job type, which is SimpleQnA for this model. Required. Simple + question and answers between user and agent. + :vartype type: str or ~azure.ai.projects.models.SIMPLE_QNA + :ivar max_samples: Maximum number of samples to generate, up to service-defined limits. + Required. + :vartype max_samples: int + :ivar question_types: The question types to generate. Used only for fine-tuning scenarios. + :vartype question_types: list[str or ~azure.ai.projects.models.SimpleQnAFineTuningQuestionType] + """ + + type: Literal[DataGenerationJobType.SIMPLE_QNA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The data generation job type, which is SimpleQnA for this model. Required. Simple question and + answers between user and agent.""" + max_samples: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Maximum number of samples to generate, up to service-defined limits. Required.""" + question_types: Optional[list[Union[str, "_models.SimpleQnAFineTuningQuestionType"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The question types to generate. Used only for fine-tuning scenarios.""" + + @overload + def __init__( + self, + *, + max_samples: int, + train_split: Optional[float] = None, + model_options: Optional["_models.DataGenerationModelOptions"] = None, + question_types: Optional[list[Union[str, "_models.SimpleQnAFineTuningQuestionType"]]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = DataGenerationJobType.SIMPLE_QNA # type: ignore + + +class SimulationSeedDataGenerationJobOptions( + DataGenerationJobOptions, discriminator="simulation_seed" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The options for a task generation data generation job. Use with multiturn evaluation scenarios + and with prompt, file, or agent sources. Generated dataset rows include fields such as ``id``, + ``category``, ``test_case_description``, and ``desired_num_turns``. + + :ivar train_split: The proportion of the generated data to be used for training when the data + is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. + :vartype train_split: float + :ivar model_options: The LLM model options. + :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions + :ivar type: The data generation job type, which is SimulationSeed for this model. Required. + Simulation seed for evaluation scenarios. + :vartype type: str or ~azure.ai.projects.models.SIMULATION_SEED + """ + + type: Literal[DataGenerationJobType.SIMULATION_SEED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The data generation job type, which is SimulationSeed for this model. Required. Simulation seed + for evaluation scenarios.""" + + @overload + def __init__( + self, + *, + train_split: Optional[float] = None, + model_options: Optional["_models.DataGenerationModelOptions"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = DataGenerationJobType.SIMULATION_SEED # type: ignore + + +class SipTelephonyTransferDestination( + TelephonyTransferDestination, discriminator="sip" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A SIP destination for a telephony transfer target. + + :ivar kind: The SIP destination type. Required. A Session Initiation Protocol destination. + :vartype kind: str or ~azure.ai.projects.models.SIP + :ivar value: The SIP or SIPS URI to call. Required. + :vartype value: str + """ + + kind: Literal[TelephonyTransferDestinationKind.SIP] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The SIP destination type. Required. A Session Initiation Protocol destination.""" + value: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The SIP or SIPS URI to call. Required.""" + + @overload + def __init__( + self, + *, + value: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind = TelephonyTransferDestinationKind.SIP # type: ignore + + +class SkillDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A skill resource. + + :ivar id: The unique identifier of the skill. Required. + :vartype id: str + :ivar name: The unique name of the skill. Required. + :vartype name: str + :ivar description: A human-readable description of the skill. Required. + :vartype description: str + :ivar created_at: The Unix timestamp (seconds) when the skill was created. Required. + :vartype created_at: ~datetime.datetime + :ivar default_version: The default version for the skill. Can be changed via updateSkill. + Required. + :vartype default_version: str + :ivar latest_version: The latest version for the skill. Required. + :vartype latest_version: str + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique identifier of the skill. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique name of the skill. Required.""" + description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of the skill. Required.""" + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (seconds) when the skill was created. Required.""" + default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The default version for the skill. Can be changed via updateSkill. Required.""" + latest_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The latest version for the skill. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + name: str, + description: str, + created_at: datetime.datetime, + default_version: str, + latest_version: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SkillInlineContent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Inline content for defining a simple skill without uploading files. Follows the agentskills.io + SKILL.md specification. + + :ivar description: A human-readable description of what the skill does and when to use it. + Required. + :vartype description: str + :ivar instructions: The skill instructions in markdown format. This is the body content of the + SKILL.md file. Required. + :vartype instructions: str + :ivar license: License name or reference to a bundled license file. + :vartype license: str + :ivar compatibility: Environment requirements or compatibility notes for the skill. + :vartype compatibility: str + :ivar metadata: Arbitrary key-value metadata for additional properties. + :vartype metadata: dict[str, str] + :ivar allowed_tools: List of pre-approved tools the skill may use. Experimental. + :vartype allowed_tools: list[str] + """ + + description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of what the skill does and when to use it. Required.""" + instructions: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The skill instructions in markdown format. This is the body content of the SKILL.md file. + Required.""" + license: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """License name or reference to a bundled license file.""" + compatibility: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Environment requirements or compatibility notes for the skill.""" + metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Arbitrary key-value metadata for additional properties.""" + allowed_tools: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """List of pre-approved tools the skill may use. Experimental.""" + + @overload + def __init__( + self, + *, + description: str, + instructions: str, + license: Optional[str] = None, + compatibility: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + allowed_tools: Optional[list[str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SkillReference(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A reference to a versioned Foundry skill. + + :ivar name: The name of the skill. Required. + :vartype name: str + :ivar version: The skill version. If omitted, the current default version is resolved and + pinned when the agent version is created. + :vartype version: str + """ + + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the skill. Required.""" + version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The skill version. If omitted, the current default version is resolved and pinned when the + agent version is created.""" + + @overload + def __init__( + self, + *, + name: str, + version: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SkillReferenceParam( + ContainerSkill, discriminator="skill_reference" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """SkillReferenceParam. + + :ivar type: References a skill created with the /v1/skills endpoint. Required. SKILL_REFERENCE. + :vartype type: str or ~azure.ai.projects.models.SKILL_REFERENCE + :ivar skill_id: The ID of the referenced skill. Required. + :vartype skill_id: str + :ivar version: Optional skill version. Use a positive integer or 'latest'. Omit for default. + :vartype version: str + """ + + type: Literal[ContainerSkillType.SKILL_REFERENCE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """References a skill created with the /v1/skills endpoint. Required. SKILL_REFERENCE.""" + skill_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the referenced skill. Required.""" + version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional skill version. Use a positive integer or 'latest'. Omit for default.""" + + @overload + def __init__( + self, + *, + skill_id: str, + version: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ContainerSkillType.SKILL_REFERENCE # type: ignore + + +class SkillVersion(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A specific version of a skill. + + :ivar id: The unique identifier of the skill version. Required. + :vartype id: str + :ivar skill_id: The identifier of the parent skill. Required. + :vartype skill_id: str + :ivar name: The name of the skill version. Required. + :vartype name: str + :ivar version: The version identifier. Skill versions are immutable. Required. + :vartype version: str + :ivar description: A human-readable description of the skill version. Required. + :vartype description: str + :ivar created_at: The Unix timestamp (seconds) when the skill version was created. Required. + :vartype created_at: ~datetime.datetime + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique identifier of the skill version. Required.""" + skill_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the parent skill. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the skill version. Required.""" + version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version identifier. Skill versions are immutable. Required.""" + description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of the skill version. Required.""" + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (seconds) when the skill version was created. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + skill_id: str, + name: str, + version: str, + description: str, + created_at: datetime.datetime, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolChoiceParam(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """How the model should select which tool (or tools) to use when generating a response. See the + ``tools`` parameter to see how to specify which tools the model can call. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + ToolChoiceAllowed, SpecificApplyPatchParam, ToolChoiceCodeInterpreter, ToolChoiceComputer, + ToolChoiceComputerUse, ToolChoiceComputerUsePreview, ToolChoiceCustom, ToolChoiceFileSearch, + ToolChoiceFunction, ToolChoiceImageGeneration, ToolChoiceMCP, + SpecificProgrammaticToolCallingParam, SpecificFunctionShellParam, ToolChoiceWebSearchPreview, + ToolChoiceWebSearchPreview20250311 + + :ivar type: Required. Known values are: "allowed_tools", "function", "mcp", "custom", + "programmatic_tool_calling", "apply_patch", "shell", "file_search", "web_search_preview", + "computer_use_preview", "web_search_preview_2025_03_11", "image_generation", + "code_interpreter", "computer", and "computer_use". + :vartype type: str or ~azure.ai.projects.models.ToolChoiceParamType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"allowed_tools\", \"function\", \"mcp\", \"custom\", + \"programmatic_tool_calling\", \"apply_patch\", \"shell\", \"file_search\", + \"web_search_preview\", \"computer_use_preview\", \"web_search_preview_2025_03_11\", + \"image_generation\", \"code_interpreter\", \"computer\", and \"computer_use\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SpecificApplyPatchParam(ToolChoiceParam, discriminator="apply_patch"): + """Specific apply patch tool choice. + + :ivar type: The tool to call. Always ``apply_patch``. Required. APPLY_PATCH. + :vartype type: str or ~azure.ai.projects.models.APPLY_PATCH + """ + + type: Literal[ToolChoiceParamType.APPLY_PATCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The tool to call. Always ``apply_patch``. Required. APPLY_PATCH.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.APPLY_PATCH # type: ignore + + +class SpecificFunctionShellParam(ToolChoiceParam, discriminator="shell"): + """Specific shell tool choice. + + :ivar type: The tool to call. Always ``shell``. Required. SHELL. + :vartype type: str or ~azure.ai.projects.models.SHELL + """ + + type: Literal[ToolChoiceParamType.SHELL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The tool to call. Always ``shell``. Required. SHELL.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.SHELL # type: ignore + + +class SpecificProgrammaticToolCallingParam(ToolChoiceParam, discriminator="programmatic_tool_calling"): + """SpecificProgrammaticToolCallingParam. + + :ivar type: The tool to call. Always ``programmatic_tool_calling``. Required. + PROGRAMMATIC_TOOL_CALLING. + :vartype type: str or ~azure.ai.projects.models.PROGRAMMATIC_TOOL_CALLING + """ + + type: Literal[ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The tool to call. Always ``programmatic_tool_calling``. Required. PROGRAMMATIC_TOOL_CALLING.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING # type: ignore + + +class StructuredInputDefinition(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An structured input that can participate in prompt template substitutions and tool argument + binding. + + :ivar description: A human-readable description of the input. + :vartype description: str + :ivar default_value: The default value for the input if no run-time value is provided. + :vartype default_value: any + :ivar schema: The JSON schema for the structured input (optional). + :vartype schema: dict[str, any] + :ivar required: Whether the input property is required when the agent is invoked. The service + defaults to ``false`` if a value is not specified by the caller. + :vartype required: bool + """ + + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of the input.""" + default_value: Optional[Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The default value for the input if no run-time value is provided.""" + schema: Optional[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The JSON schema for the structured input (optional).""" + required: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the input property is required when the agent is invoked. The service defaults to + ``false`` if a value is not specified by the caller.""" + + @overload + def __init__( + self, + *, + description: Optional[str] = None, + default_value: Optional[Any] = None, + schema: Optional[dict[str, Any]] = None, + required: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class StructuredOutputDefinition(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A structured output that can be produced by the agent. + + :ivar name: The name of the structured output. Required. + :vartype name: str + :ivar description: A description of the output to emit. Used by the model to determine when to + emit the output. Required. + :vartype description: str + :ivar schema: The JSON schema for the structured output. Required. + :vartype schema: dict[str, any] + :ivar strict: Whether to enforce strict validation. Default ``true``. Required. + :vartype strict: bool + """ + + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the structured output. Required.""" + description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A description of the output to emit. Used by the model to determine when to emit the output. + Required.""" + schema: dict[str, Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The JSON schema for the structured output. Required.""" + strict: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether to enforce strict validation. Default ``true``. Required.""" + + @overload + def __init__( + self, + *, + name: str, + description: str, + schema: dict[str, Any], + strict: bool, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TaxonomyCategory(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Taxonomy category definition. + + :ivar id: Unique identifier of the taxonomy category. Required. + :vartype id: str + :ivar name: Name of the taxonomy category. Required. + :vartype name: str + :ivar description: Description of the taxonomy category. + :vartype description: str + :ivar risk_category: Risk category associated with this taxonomy category. Required. Known + values are: "HateUnfairness", "Violence", "Sexual", "SelfHarm", "ProtectedMaterial", + "CodeVulnerability", "UngroundedAttributes", "ProhibitedActions", "SensitiveDataLeakage", and + "TaskAdherence". + :vartype risk_category: str or ~azure.ai.projects.models.RiskCategory + :ivar sub_categories: List of taxonomy sub categories. Required. + :vartype sub_categories: list[~azure.ai.projects.models.TaxonomySubCategory] + :ivar properties: Additional properties for the taxonomy category. + :vartype properties: dict[str, str] + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Unique identifier of the taxonomy category. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Name of the taxonomy category. Required.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Description of the taxonomy category.""" + risk_category: Union[str, "_models.RiskCategory"] = rest_field( + name="riskCategory", visibility=["read", "create", "update", "delete", "query"] + ) + """Risk category associated with this taxonomy category. Required. Known values are: + \"HateUnfairness\", \"Violence\", \"Sexual\", \"SelfHarm\", \"ProtectedMaterial\", + \"CodeVulnerability\", \"UngroundedAttributes\", \"ProhibitedActions\", + \"SensitiveDataLeakage\", and \"TaskAdherence\".""" + sub_categories: list["_models.TaxonomySubCategory"] = rest_field( + name="subCategories", visibility=["read", "create", "update", "delete", "query"] + ) + """List of taxonomy sub categories. Required.""" + properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Additional properties for the taxonomy category.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + name: str, + risk_category: Union[str, "_models.RiskCategory"], + sub_categories: list["_models.TaxonomySubCategory"], + description: Optional[str] = None, + properties: Optional[dict[str, str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TaxonomySubCategory(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Taxonomy sub-category definition. + + :ivar id: Unique identifier of the taxonomy sub-category. Required. + :vartype id: str + :ivar name: Name of the taxonomy sub-category. Required. + :vartype name: str + :ivar description: Description of the taxonomy sub-category. + :vartype description: str + :ivar enabled: List of taxonomy items under this sub-category. Required. + :vartype enabled: bool + :ivar properties: Additional properties for the taxonomy sub-category. + :vartype properties: dict[str, str] + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Unique identifier of the taxonomy sub-category. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Name of the taxonomy sub-category. Required.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Description of the taxonomy sub-category.""" + enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """List of taxonomy items under this sub-category. Required.""" + properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Additional properties for the taxonomy sub-category.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + name: str, + enabled: bool, + description: Optional[str] = None, + properties: Optional[dict[str, str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyBinding(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A telephony binding owned by a voice agent. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TeamsPhoneExtensionTelephonyBinding, TwilioTelephonyBinding + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar provider: The telephony provider. Required. Known values are: "teams_phone_extension" and + "twilio". + :vartype provider: str or ~azure.ai.projects.models.TelephonyProvider + :ivar connection_name: The Foundry connection name for the telephony provider. Required. + :vartype connection_name: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + """ + + __mapping__: dict[str, _Model] = {} + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated binding identifier. Required.""" + provider: str = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) + """The telephony provider. Required. Known values are: \"teams_phone_extension\" and \"twilio\".""" + connection_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Foundry connection name for the telephony provider. Required.""" + label: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The optional display label for the binding.""" + status: Union[str, "_models.TelephonyBindingStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle status. Required. Known values are: \"active\" and \"suspended\".""" + incoming_call_url: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated webhook URL to configure with the telephony provider. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + provider: str, + connection_name: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TeamsPhoneExtensionTelephonyBinding( + TelephonyBinding, discriminator="teams_phone_extension" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A Microsoft Teams Phone Extension binding owned by a voice agent. + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar connection_name: The Foundry connection name for the telephony provider. Required. + :vartype connection_name: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + :ivar provider: The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone + Extension. + :vartype provider: str or ~azure.ai.projects.models.TEAMS_PHONE_EXTENSION + :ivar phone_number: The optional display phone number for the Teams resource account. + :vartype phone_number: str + :ivar resource_account_object_id: The Microsoft Teams resource-account object identifier as a + GUID. Required. + :vartype resource_account_object_id: str + """ + + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone Extension.""" + phone_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The optional display phone number for the Teams resource account.""" + resource_account_object_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Microsoft Teams resource-account object identifier as a GUID. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + connection_name: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + resource_account_object_id: str, + label: Optional[str] = None, + phone_number: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TEAMS_PHONE_EXTENSION # type: ignore + + +class TelephonyBindingListItem(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A telephony binding returned in a list, including its entity tag. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TeamsPhoneExtensionTelephonyBindingListItem, TwilioTelephonyBindingListItem + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar provider: The telephony provider. Required. Known values are: "teams_phone_extension" and + "twilio". + :vartype provider: str or ~azure.ai.projects.models.TelephonyProvider + :ivar connection_name: The Foundry connection name for the telephony provider. Required. + :vartype connection_name: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + :ivar etag: The entity tag to send in the ``If-Match`` header when updating or deleting this + binding. Required. + :vartype etag: str + """ + + __mapping__: dict[str, _Model] = {} + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated binding identifier. Required.""" + provider: str = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) + """The telephony provider. Required. Known values are: \"teams_phone_extension\" and \"twilio\".""" + connection_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Foundry connection name for the telephony provider. Required.""" + label: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The optional display label for the binding.""" + status: Union[str, "_models.TelephonyBindingStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle status. Required. Known values are: \"active\" and \"suspended\".""" + incoming_call_url: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated webhook URL to configure with the telephony provider. Required.""" + etag: str = rest_field(visibility=["read"]) + """The entity tag to send in the ``If-Match`` header when updating or deleting this binding. + Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + provider: str, + connection_name: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TeamsPhoneExtensionTelephonyBindingListItem( + TelephonyBindingListItem, discriminator="teams_phone_extension" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """A Microsoft Teams Phone Extension binding returned in a list, including its entity tag. + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar connection_name: The Foundry connection name for the telephony provider. Required. + :vartype connection_name: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + :ivar etag: The entity tag to send in the ``If-Match`` header when updating or deleting this + binding. Required. + :vartype etag: str + :ivar provider: The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone + Extension. + :vartype provider: str or ~azure.ai.projects.models.TEAMS_PHONE_EXTENSION + :ivar phone_number: The optional display phone number for the Teams resource account. + :vartype phone_number: str + :ivar resource_account_object_id: The Microsoft Teams resource-account object identifier as a + GUID. Required. + :vartype resource_account_object_id: str + """ + + provider: Literal[TelephonyProvider.TEAMS_PHONE_EXTENSION] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Microsoft Teams Phone Extension provider. Required. Microsoft Teams Phone Extension.""" + phone_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The optional display phone number for the Teams resource account.""" + resource_account_object_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Microsoft Teams resource-account object identifier as a GUID. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + connection_name: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + resource_account_object_id: str, + label: Optional[str] = None, + phone_number: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TEAMS_PHONE_EXTENSION # type: ignore + + +class TeamsTelephonyTransferDestination( + TelephonyTransferDestination, discriminator="teams" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A Microsoft Teams destination for a telephony transfer target. + + :ivar kind: The Microsoft Teams destination type. Required. A Microsoft Teams user or + resource-account destination. + :vartype kind: str or ~azure.ai.projects.models.TEAMS + :ivar value: The Microsoft Teams user or resource-account identifier. Required. + :vartype value: str + """ + + kind: Literal[TelephonyTransferDestinationKind.TEAMS] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Microsoft Teams destination type. Required. A Microsoft Teams user or resource-account + destination.""" + value: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Microsoft Teams user or resource-account identifier. Required.""" + + @overload + def __init__( + self, + *, + value: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind = TelephonyTransferDestinationKind.TEAMS # type: ignore + + +class TelemetryConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Customer-supplied telemetry configuration for exporting container logs, traces, and metrics. + + :ivar endpoints: Customer-supplied telemetry export endpoint configurations. Required. + :vartype endpoints: list[~azure.ai.projects.models.TelemetryEndpoint] + """ + + endpoints: list["_models.TelemetryEndpoint"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Customer-supplied telemetry export endpoint configurations. Required.""" + + @overload + def __init__( + self, + *, + endpoints: list["_models.TelemetryEndpoint"], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallJob(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A durable direct or campaign-created outbound call intent. + + :ivar destination: The phone destination to call. Required. + :vartype destination: ~azure.ai.projects.models.TelephonyOutboundDestination + :ivar connection_name: The Foundry connection name in the current project used to originate the + call. Its category selects Twilio or Azure Communication Services / Teams Phone Extension. No + inbound telephony binding is required. Required. + :vartype connection_name: str + :ivar source: The caller identity used to originate the call. For a Twilio connection, provide + an authorized E.164 phone number. For an Azure Communication Services / Teams Phone Extension + connection, provide the Teams Resource Account object ID. The identity type is inferred from + the connection category; originating does not change inbound routing. Required. + :vartype source: str + :ivar purpose: An optional customer-declared purpose for placing the call. + :vartype purpose: str + :ivar structured_inputs: Structured input values available to the agent and greeting for this + call. Agent-declared inputs are validated against their schemas; omitted optional inputs may + use their Agent-defined default values, while omitted required inputs are rejected. Additional + inputs remain available as dynamic template variables. + :vartype structured_inputs: dict[str, any] + :ivar schedule: The optional execution window. + :vartype schedule: ~azure.ai.projects.models.TelephonyCallJobSchedule + :ivar id: The service-generated call-job identifier. Required. + :vartype id: str + :ivar object: The object type. Always ``telephony.call_job``. Required. Default value is + "telephony.call_job". + :vartype object: str + :ivar agent_name: The name of the voice agent used at execution time. Required. + :vartype agent_name: str + :ivar status: The current call-job lifecycle status. Required. Known values are: "accepted", + "waiting_for_schedule", "queued", "dispatching", "in_progress", "waiting_for_retry", + "cancellation_requested", "completed", "blocked", "expired", "failed", and "cancelled". + :vartype status: str or ~azure.ai.projects.models.TelephonyCallJobStatus + :ivar cancellation: The recorded cancellation request, when cancellation was requested. + :vartype cancellation: ~azure.ai.projects.models.TelephonyCallJobCancellation + :ivar retry_policy: The frozen provider-attempt retry policy. Required. + :vartype retry_policy: ~azure.ai.projects.models.TelephonyOutboundRetryPolicy + :ivar attempt_count: The number of provider attempts created so far. Required. + :vartype attempt_count: int + :ivar next_attempt_at: The Unix timestamp in seconds at which the next retry becomes eligible. + :vartype next_attempt_at: ~datetime.datetime + :ivar terminal_reason: The stable service-generated reason for the overall outbound call job, + which can span multiple provider attempts, when available. Interpret this with ``status``: a + queued job can retain a temporary dispatch-deferral reason. Additional string codes may be + returned. Known values are: "no_answer", "no_answer_timeout", "answer_failed", + "bridge_cancelled", "bridge_failed", "voice_session_configuration_invalid", + "connection_project_mismatch", "outbound_connection_changed", + "outbound_connection_unavailable", "telephony_binding_invalid", "telephony_binding_not_found", + "telephony_binding_inactive", "telephony_binding_changed", "campaign_not_found", + "campaign_cancelled", "campaign_completed", "campaign_failed", + "origination_fence_not_recorded", "origination_reconciliation_timeout", + "cancellation_reconciliation_timeout", and + "provider_callback_timeout_cancellation_reconciliation_timeout". + :vartype terminal_reason: str or ~azure.ai.projects.models.TelephonyCallJobTerminalReason + :ivar revision: The monotonically increasing optimistic-concurrency revision. Required. + :vartype revision: int + :ivar created_at: The Unix timestamp in seconds when the call job was created. Required. + :vartype created_at: ~datetime.datetime + :ivar updated_at: The Unix timestamp in seconds when the call job was last updated. Required. + :vartype updated_at: ~datetime.datetime + """ + + destination: "_models.TelephonyOutboundDestination" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The phone destination to call. Required.""" + connection_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Foundry connection name in the current project used to originate the call. Its category + selects Twilio or Azure Communication Services / Teams Phone Extension. No inbound telephony + binding is required. Required.""" + source: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The caller identity used to originate the call. For a Twilio connection, provide an authorized + E.164 phone number. For an Azure Communication Services / Teams Phone Extension connection, + provide the Teams Resource Account object ID. The identity type is inferred from the connection + category; originating does not change inbound routing. Required.""" + purpose: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional customer-declared purpose for placing the call.""" + structured_inputs: Optional[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Structured input values available to the agent and greeting for this call. Agent-declared + inputs are validated against their schemas; omitted optional inputs may use their Agent-defined + default values, while omitted required inputs are rejected. Additional inputs remain available + as dynamic template variables.""" + schedule: Optional["_models.TelephonyCallJobSchedule"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The optional execution window.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated call-job identifier. Required.""" + object: Literal["telephony.call_job"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The object type. Always ``telephony.call_job``. Required. Default value is + \"telephony.call_job\".""" + agent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the voice agent used at execution time. Required.""" + status: Union[str, "_models.TelephonyCallJobStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The current call-job lifecycle status. Required. Known values are: \"accepted\", + \"waiting_for_schedule\", \"queued\", \"dispatching\", \"in_progress\", \"waiting_for_retry\", + \"cancellation_requested\", \"completed\", \"blocked\", \"expired\", \"failed\", and + \"cancelled\".""" + cancellation: Optional["_models.TelephonyCallJobCancellation"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The recorded cancellation request, when cancellation was requested.""" + retry_policy: "_models.TelephonyOutboundRetryPolicy" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The frozen provider-attempt retry policy. Required.""" + attempt_count: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The number of provider attempts created so far. Required.""" + next_attempt_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp in seconds at which the next retry becomes eligible.""" + terminal_reason: Optional[Union[str, "_models.TelephonyCallJobTerminalReason"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The stable service-generated reason for the overall outbound call job, which can span multiple + provider attempts, when available. Interpret this with ``status``: a queued job can retain a + temporary dispatch-deferral reason. Additional string codes may be returned. Known values are: + \"no_answer\", \"no_answer_timeout\", \"answer_failed\", \"bridge_cancelled\", + \"bridge_failed\", \"voice_session_configuration_invalid\", \"connection_project_mismatch\", + \"outbound_connection_changed\", \"outbound_connection_unavailable\", + \"telephony_binding_invalid\", \"telephony_binding_not_found\", \"telephony_binding_inactive\", + \"telephony_binding_changed\", \"campaign_not_found\", \"campaign_cancelled\", + \"campaign_completed\", \"campaign_failed\", \"origination_fence_not_recorded\", + \"origination_reconciliation_timeout\", \"cancellation_reconciliation_timeout\", and + \"provider_callback_timeout_cancellation_reconciliation_timeout\".""" + revision: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The monotonically increasing optimistic-concurrency revision. Required.""" + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp in seconds when the call job was created. Required.""" + updated_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp in seconds when the call job was last updated. Required.""" + + @overload + def __init__( + self, + *, + destination: "_models.TelephonyOutboundDestination", + connection_name: str, + source: str, + id: str, # pylint: disable=redefined-builtin + agent_name: str, + status: Union[str, "_models.TelephonyCallJobStatus"], + retry_policy: "_models.TelephonyOutboundRetryPolicy", + attempt_count: int, + revision: int, + created_at: datetime.datetime, + updated_at: datetime.datetime, + purpose: Optional[str] = None, + structured_inputs: Optional[dict[str, Any]] = None, + schedule: Optional["_models.TelephonyCallJobSchedule"] = None, + cancellation: Optional["_models.TelephonyCallJobCancellation"] = None, + next_attempt_at: Optional[datetime.datetime] = None, + terminal_reason: Optional[Union[str, "_models.TelephonyCallJobTerminalReason"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.object: Literal["telephony.call_job"] = "telephony.call_job" + + +class TelephonyCallJobCancellation(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A cancellation request recorded for an outbound call job. + + :ivar requested_by: The authenticated principal that requested cancellation. Required. + :vartype requested_by: str + :ivar mode: The cancellation mode applied to the call job. Required. + :vartype mode: str + :ivar requested_at: The Unix timestamp in seconds when cancellation was requested. Required. + :vartype requested_at: ~datetime.datetime + :ivar revision: The call-job revision at which cancellation was recorded. Required. + :vartype revision: int + """ + + requested_by: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The authenticated principal that requested cancellation. Required.""" + mode: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The cancellation mode applied to the call job. Required.""" + requested_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp in seconds when cancellation was requested. Required.""" + revision: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The call-job revision at which cancellation was recorded. Required.""" + + @overload + def __init__( + self, + *, + requested_by: str, + mode: str, + requested_at: datetime.datetime, + revision: int, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallJobSchedule(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The optional execution window for a direct outbound call. + + :ivar not_before: The earliest instant at which dispatch may begin. + :vartype not_before: ~datetime.datetime + :ivar expires_at: The instant after which the call job expires without dispatch. + :vartype expires_at: ~datetime.datetime + """ + + not_before: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The earliest instant at which dispatch may begin.""" + expires_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The instant after which the call job expires without dispatch.""" + + @overload + def __init__( + self, + *, + not_before: Optional[datetime.datetime] = None, + expires_at: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallLifecycleEvent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A bounded durable observation in the lifecycle of one telephony call. + + :ivar sequence: The service-assigned order of the event within the call record. Required. + :vartype sequence: int + :ivar name: The stable provider-neutral event name. Required. Known values are: + "telephony.webhook.received", "telephony.webhook.validation", "telephony.binding.resolve", + "telephony.provider.answer", "telephony.media.connect", "telephony.agent_session.connect", + "telephony.media.first_caller_audio", "telephony.media.first_agent_audio", + "telephony.call.transfer", "telephony.call.hangup", and "telephony.call.disconnect". + :vartype name: str or ~azure.ai.projects.models.TelephonyCallLifecycleEventName + :ivar source: The component that supplied the observation. Required. Known values are: + "gateway", "teams_phone_extension", "twilio", and "voice_agent". + :vartype source: str or ~azure.ai.projects.models.TelephonyCallLifecycleEventSource + :ivar outcome: The outcome of the observed lifecycle operation. Required. Known values are: + "observed", "started", "succeeded", "failed", "rejected", and "cancelled". + :vartype outcome: str or ~azure.ai.projects.models.TelephonyCallLifecycleEventOutcome + :ivar observed_at: The Unix timestamp (in seconds) for when the service observed the event. + Required. + :vartype observed_at: ~datetime.datetime + :ivar occurred_at: The Unix timestamp (in seconds) for when the event occurred according to the + provider. + :vartype occurred_at: ~datetime.datetime + :ivar timestamp_source: The source of the event timestamp. Required. Known values are: + "provider", "gateway", and "derived". + :vartype timestamp_source: str or ~azure.ai.projects.models.TelephonyCallTimestampSource + :ivar reason: A stable service-generated reason associated with this lifecycle event, not + necessarily the final outcome of the call. Additional string codes may be returned. Known + values are: "invalid_webhook_payload", "webhook_validation_failed", "binding_not_found", + "binding_suspended", "admission_rejected", "admission_check_failed", "route_agent_mismatch", + "invalid_binding_configuration", "credential_resolution_failed", "provider_resource_mismatch", + "endpoint_resolution_failed", "ingress_setup_failed", "live_call_conflict", + "live_call_persistence_failed", "answer_failed", "provider_disconnected", "provider_busy", + "provider_no_answer", "provider_cancelled", "provider_failed", "provider_stream_error", + "provider_stream_stopped", "agent_session_connect_failed", "media_stream_ended", + "bridge_cancelled", "bridge_failed", "managed_hangup", "managed_transfer", + "manage_hangup_failed", and "manage_transfer_failed". + :vartype reason: str or ~azure.ai.projects.models.TelephonyCallLifecycleEventReason + :ivar provider_event_id: The provider event identifier used for idempotency, when supplied. + :vartype provider_event_id: str + :ivar provider_sequence: The provider event sequence, when supplied. + :vartype provider_sequence: int + :ivar provider_status_code: The provider status code associated with the event. + :vartype provider_status_code: int + :ivar provider_sub_code: The provider subcode associated with the event. + :vartype provider_sub_code: int + """ + + sequence: int = rest_field(visibility=["read"]) + """The service-assigned order of the event within the call record. Required.""" + name: Union[str, "_models.TelephonyCallLifecycleEventName"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The stable provider-neutral event name. Required. Known values are: + \"telephony.webhook.received\", \"telephony.webhook.validation\", + \"telephony.binding.resolve\", \"telephony.provider.answer\", \"telephony.media.connect\", + \"telephony.agent_session.connect\", \"telephony.media.first_caller_audio\", + \"telephony.media.first_agent_audio\", \"telephony.call.transfer\", \"telephony.call.hangup\", + and \"telephony.call.disconnect\".""" + source: Union[str, "_models.TelephonyCallLifecycleEventSource"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The component that supplied the observation. Required. Known values are: \"gateway\", + \"teams_phone_extension\", \"twilio\", and \"voice_agent\".""" + outcome: Union[str, "_models.TelephonyCallLifecycleEventOutcome"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The outcome of the observed lifecycle operation. Required. Known values are: \"observed\", + \"started\", \"succeeded\", \"failed\", \"rejected\", and \"cancelled\".""" + observed_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the service observed the event. Required.""" + occurred_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the event occurred according to the provider.""" + timestamp_source: Union[str, "_models.TelephonyCallTimestampSource"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The source of the event timestamp. Required. Known values are: \"provider\", \"gateway\", and + \"derived\".""" + reason: Optional[Union[str, "_models.TelephonyCallLifecycleEventReason"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """A stable service-generated reason associated with this lifecycle event, not necessarily the + final outcome of the call. Additional string codes may be returned. Known values are: + \"invalid_webhook_payload\", \"webhook_validation_failed\", \"binding_not_found\", + \"binding_suspended\", \"admission_rejected\", \"admission_check_failed\", + \"route_agent_mismatch\", \"invalid_binding_configuration\", \"credential_resolution_failed\", + \"provider_resource_mismatch\", \"endpoint_resolution_failed\", \"ingress_setup_failed\", + \"live_call_conflict\", \"live_call_persistence_failed\", \"answer_failed\", + \"provider_disconnected\", \"provider_busy\", \"provider_no_answer\", \"provider_cancelled\", + \"provider_failed\", \"provider_stream_error\", \"provider_stream_stopped\", + \"agent_session_connect_failed\", \"media_stream_ended\", \"bridge_cancelled\", + \"bridge_failed\", \"managed_hangup\", \"managed_transfer\", \"manage_hangup_failed\", and + \"manage_transfer_failed\".""" + provider_event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider event identifier used for idempotency, when supplied.""" + provider_sequence: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider event sequence, when supplied.""" + provider_status_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider status code associated with the event.""" + provider_sub_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider subcode associated with the event.""" + + @overload + def __init__( + self, + *, + name: Union[str, "_models.TelephonyCallLifecycleEventName"], + source: Union[str, "_models.TelephonyCallLifecycleEventSource"], + outcome: Union[str, "_models.TelephonyCallLifecycleEventOutcome"], + observed_at: datetime.datetime, + timestamp_source: Union[str, "_models.TelephonyCallTimestampSource"], + occurred_at: Optional[datetime.datetime] = None, + reason: Optional[Union[str, "_models.TelephonyCallLifecycleEventReason"]] = None, + provider_event_id: Optional[str] = None, + provider_sequence: Optional[int] = None, + provider_status_code: Optional[int] = None, + provider_sub_code: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallRecord(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Detailed diagnostics for a durable inbound call to a voice agent. + + :ivar id: The service-generated call identifier. Required. + :vartype id: str + :ivar provider: The telephony provider. Required. Known values are: "teams_phone_extension" and + "twilio". + :vartype provider: str or ~azure.ai.projects.models.TelephonyProvider + :ivar provider_call_id: The provider-assigned call identifier, when available. + :vartype provider_call_id: str + :ivar caller_number: The caller's phone number, when supplied by the provider. + :vartype caller_number: str + :ivar provider_number: The Teams Phone Extension or Twilio number that received the call. + :vartype provider_number: str + :ivar status: The lifecycle status of the call. Required. Known values are: "in_progress", + "success", and "failed". + :vartype status: str or ~azure.ai.projects.models.TelephonyCallStatus + :ivar phase: The provider-neutral lifecycle phase reached by the call. Required. Known values + are: "received", "validated", "admitted", "answering", "answered", "media_connected", + "agent_session_ready", "bridging", "managing", "completed", "rejected", and "failed". + :vartype phase: str or ~azure.ai.projects.models.TelephonyCallPhase + :ivar started_at: The Unix timestamp (in seconds) for when the inbound webhook was received. + Required. + :vartype started_at: ~datetime.datetime + :ivar answered_at: The Unix timestamp (in seconds) for when the provider reported the call as + answered. + :vartype answered_at: ~datetime.datetime + :ivar media_connected_at: The Unix timestamp (in seconds) for when the provider media channel + connected. + :vartype media_connected_at: ~datetime.datetime + :ivar agent_session_ready_at: The Unix timestamp (in seconds) for when the voice-agent session + became ready. + :vartype agent_session_ready_at: ~datetime.datetime + :ivar ended_at: The Unix timestamp (in seconds) for when the call ended. + :vartype ended_at: ~datetime.datetime + :ivar duration_ms: The call duration. + :vartype duration_ms: ~datetime.timedelta + :ivar end_reason: The service-generated reason that this single call ended, rather than the + outcome of an overall outbound call job. Additional string codes may be returned. Known values + are: "invalid_webhook_payload", "webhook_validation_failed", "binding_not_found", + "binding_suspended", "admission_rejected", "admission_check_failed", "route_agent_mismatch", + "invalid_binding_configuration", "credential_resolution_failed", "provider_resource_mismatch", + "endpoint_resolution_failed", "ingress_setup_failed", "live_call_conflict", + "live_call_persistence_failed", "answer_failed", "provider_disconnected", "provider_busy", + "provider_no_answer", "provider_cancelled", "provider_failed", "provider_stream_error", + "provider_stream_stopped", "agent_session_connect_failed", "media_stream_ended", + "bridge_cancelled", "bridge_failed", "managed_hangup", "managed_transfer", + "manage_hangup_failed", and "manage_transfer_failed". + :vartype end_reason: str or ~azure.ai.projects.models.TelephonyCallEndReason + :ivar provider_status_code: The provider status code associated with the terminal result. + :vartype provider_status_code: int + :ivar provider_sub_code: The provider subcode associated with the terminal result. + :vartype provider_sub_code: int + :ivar provider_message: The provider message associated with the terminal result. + :vartype provider_message: str + :ivar timing: Detailed provider-neutral call timing. Required. + :vartype timing: ~azure.ai.projects.models.TelephonyCallTiming + :ivar trace: Correlation to the customer-facing Foundry trace. + :vartype trace: ~azure.ai.projects.models.TelephonyCallTrace + :ivar events: The lifecycle timeline. Required. + :vartype events: list[~azure.ai.projects.models.TelephonyCallLifecycleEvent] + :ivar events_truncated: Whether older lifecycle events were omitted from the timeline. + Required. + :vartype events_truncated: bool + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated call identifier. Required.""" + provider: Union[str, "_models.TelephonyProvider"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The telephony provider. Required. Known values are: \"teams_phone_extension\" and \"twilio\".""" + provider_call_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider-assigned call identifier, when available.""" + caller_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The caller's phone number, when supplied by the provider.""" + provider_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Teams Phone Extension or Twilio number that received the call.""" + status: Union[str, "_models.TelephonyCallStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle status of the call. Required. Known values are: \"in_progress\", \"success\", and + \"failed\".""" + phase: Union[str, "_models.TelephonyCallPhase"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The provider-neutral lifecycle phase reached by the call. Required. Known values are: + \"received\", \"validated\", \"admitted\", \"answering\", \"answered\", \"media_connected\", + \"agent_session_ready\", \"bridging\", \"managing\", \"completed\", \"rejected\", and + \"failed\".""" + started_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the inbound webhook was received. Required.""" + answered_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider reported the call as answered.""" + media_connected_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider media channel connected.""" + agent_session_ready_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the voice-agent session became ready.""" + ended_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the call ended.""" + duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The call duration.""" + end_reason: Optional[Union[str, "_models.TelephonyCallEndReason"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The service-generated reason that this single call ended, rather than the outcome of an overall + outbound call job. Additional string codes may be returned. Known values are: + \"invalid_webhook_payload\", \"webhook_validation_failed\", \"binding_not_found\", + \"binding_suspended\", \"admission_rejected\", \"admission_check_failed\", + \"route_agent_mismatch\", \"invalid_binding_configuration\", \"credential_resolution_failed\", + \"provider_resource_mismatch\", \"endpoint_resolution_failed\", \"ingress_setup_failed\", + \"live_call_conflict\", \"live_call_persistence_failed\", \"answer_failed\", + \"provider_disconnected\", \"provider_busy\", \"provider_no_answer\", \"provider_cancelled\", + \"provider_failed\", \"provider_stream_error\", \"provider_stream_stopped\", + \"agent_session_connect_failed\", \"media_stream_ended\", \"bridge_cancelled\", + \"bridge_failed\", \"managed_hangup\", \"managed_transfer\", \"manage_hangup_failed\", and + \"manage_transfer_failed\".""" + provider_status_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider status code associated with the terminal result.""" + provider_sub_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider subcode associated with the terminal result.""" + provider_message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider message associated with the terminal result.""" + timing: "_models.TelephonyCallTiming" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Detailed provider-neutral call timing. Required.""" + trace: Optional["_models.TelephonyCallTrace"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Correlation to the customer-facing Foundry trace.""" + events: list["_models.TelephonyCallLifecycleEvent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle timeline. Required.""" + events_truncated: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether older lifecycle events were omitted from the timeline. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + provider: Union[str, "_models.TelephonyProvider"], + status: Union[str, "_models.TelephonyCallStatus"], + phase: Union[str, "_models.TelephonyCallPhase"], + started_at: datetime.datetime, + timing: "_models.TelephonyCallTiming", + events: list["_models.TelephonyCallLifecycleEvent"], + events_truncated: bool, + provider_call_id: Optional[str] = None, + caller_number: Optional[str] = None, + provider_number: Optional[str] = None, + answered_at: Optional[datetime.datetime] = None, + media_connected_at: Optional[datetime.datetime] = None, + agent_session_ready_at: Optional[datetime.datetime] = None, + ended_at: Optional[datetime.datetime] = None, + duration_ms: Optional[datetime.timedelta] = None, + end_reason: Optional[Union[str, "_models.TelephonyCallEndReason"]] = None, + provider_status_code: Optional[int] = None, + provider_sub_code: Optional[int] = None, + provider_message: Optional[str] = None, + trace: Optional["_models.TelephonyCallTrace"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallSummary(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A summary of a durable inbound call to a voice agent. + + :ivar id: The service-generated call identifier. Required. + :vartype id: str + :ivar provider: The telephony provider. Required. Known values are: "teams_phone_extension" and + "twilio". + :vartype provider: str or ~azure.ai.projects.models.TelephonyProvider + :ivar provider_call_id: The provider-assigned call identifier, when available. + :vartype provider_call_id: str + :ivar caller_number: The caller's phone number, when supplied by the provider. + :vartype caller_number: str + :ivar provider_number: The Teams Phone Extension or Twilio number that received the call. + :vartype provider_number: str + :ivar status: The lifecycle status of the call. Required. Known values are: "in_progress", + "success", and "failed". + :vartype status: str or ~azure.ai.projects.models.TelephonyCallStatus + :ivar phase: The provider-neutral lifecycle phase reached by the call. Required. Known values + are: "received", "validated", "admitted", "answering", "answered", "media_connected", + "agent_session_ready", "bridging", "managing", "completed", "rejected", and "failed". + :vartype phase: str or ~azure.ai.projects.models.TelephonyCallPhase + :ivar started_at: The Unix timestamp (in seconds) for when the inbound webhook was received. + Required. + :vartype started_at: ~datetime.datetime + :ivar answered_at: The Unix timestamp (in seconds) for when the provider reported the call as + answered. + :vartype answered_at: ~datetime.datetime + :ivar media_connected_at: The Unix timestamp (in seconds) for when the provider media channel + connected. + :vartype media_connected_at: ~datetime.datetime + :ivar agent_session_ready_at: The Unix timestamp (in seconds) for when the voice-agent session + became ready. + :vartype agent_session_ready_at: ~datetime.datetime + :ivar ended_at: The Unix timestamp (in seconds) for when the call ended. + :vartype ended_at: ~datetime.datetime + :ivar duration_ms: The call duration. + :vartype duration_ms: ~datetime.timedelta + :ivar end_reason: The service-generated reason that this single call ended, rather than the + outcome of an overall outbound call job. Additional string codes may be returned. Known values + are: "invalid_webhook_payload", "webhook_validation_failed", "binding_not_found", + "binding_suspended", "admission_rejected", "admission_check_failed", "route_agent_mismatch", + "invalid_binding_configuration", "credential_resolution_failed", "provider_resource_mismatch", + "endpoint_resolution_failed", "ingress_setup_failed", "live_call_conflict", + "live_call_persistence_failed", "answer_failed", "provider_disconnected", "provider_busy", + "provider_no_answer", "provider_cancelled", "provider_failed", "provider_stream_error", + "provider_stream_stopped", "agent_session_connect_failed", "media_stream_ended", + "bridge_cancelled", "bridge_failed", "managed_hangup", "managed_transfer", + "manage_hangup_failed", and "manage_transfer_failed". + :vartype end_reason: str or ~azure.ai.projects.models.TelephonyCallEndReason + :ivar provider_status_code: The provider status code associated with the terminal result. + :vartype provider_status_code: int + :ivar provider_sub_code: The provider subcode associated with the terminal result. + :vartype provider_sub_code: int + :ivar provider_message: The provider message associated with the terminal result. + :vartype provider_message: str + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The service-generated call identifier. Required.""" + provider: Union[str, "_models.TelephonyProvider"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The telephony provider. Required. Known values are: \"teams_phone_extension\" and \"twilio\".""" + provider_call_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider-assigned call identifier, when available.""" + caller_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The caller's phone number, when supplied by the provider.""" + provider_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Teams Phone Extension or Twilio number that received the call.""" + status: Union[str, "_models.TelephonyCallStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle status of the call. Required. Known values are: \"in_progress\", \"success\", and + \"failed\".""" + phase: Union[str, "_models.TelephonyCallPhase"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The provider-neutral lifecycle phase reached by the call. Required. Known values are: + \"received\", \"validated\", \"admitted\", \"answering\", \"answered\", \"media_connected\", + \"agent_session_ready\", \"bridging\", \"managing\", \"completed\", \"rejected\", and + \"failed\".""" + started_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the inbound webhook was received. Required.""" + answered_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider reported the call as answered.""" + media_connected_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider media channel connected.""" + agent_session_ready_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the voice-agent session became ready.""" + ended_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the call ended.""" + duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The call duration.""" + end_reason: Optional[Union[str, "_models.TelephonyCallEndReason"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The service-generated reason that this single call ended, rather than the outcome of an overall + outbound call job. Additional string codes may be returned. Known values are: + \"invalid_webhook_payload\", \"webhook_validation_failed\", \"binding_not_found\", + \"binding_suspended\", \"admission_rejected\", \"admission_check_failed\", + \"route_agent_mismatch\", \"invalid_binding_configuration\", \"credential_resolution_failed\", + \"provider_resource_mismatch\", \"endpoint_resolution_failed\", \"ingress_setup_failed\", + \"live_call_conflict\", \"live_call_persistence_failed\", \"answer_failed\", + \"provider_disconnected\", \"provider_busy\", \"provider_no_answer\", \"provider_cancelled\", + \"provider_failed\", \"provider_stream_error\", \"provider_stream_stopped\", + \"agent_session_connect_failed\", \"media_stream_ended\", \"bridge_cancelled\", + \"bridge_failed\", \"managed_hangup\", \"managed_transfer\", \"manage_hangup_failed\", and + \"manage_transfer_failed\".""" + provider_status_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider status code associated with the terminal result.""" + provider_sub_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider subcode associated with the terminal result.""" + provider_message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The provider message associated with the terminal result.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + provider: Union[str, "_models.TelephonyProvider"], + status: Union[str, "_models.TelephonyCallStatus"], + phase: Union[str, "_models.TelephonyCallPhase"], + started_at: datetime.datetime, + provider_call_id: Optional[str] = None, + caller_number: Optional[str] = None, + provider_number: Optional[str] = None, + answered_at: Optional[datetime.datetime] = None, + media_connected_at: Optional[datetime.datetime] = None, + agent_session_ready_at: Optional[datetime.datetime] = None, + ended_at: Optional[datetime.datetime] = None, + duration_ms: Optional[datetime.timedelta] = None, + end_reason: Optional[Union[str, "_models.TelephonyCallEndReason"]] = None, + provider_status_code: Optional[int] = None, + provider_sub_code: Optional[int] = None, + provider_message: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallTiming(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Detailed provider-neutral timing for an inbound telephony call. + + :ivar received_at: The Unix timestamp (in seconds) for when the provider webhook was received. + :vartype received_at: ~datetime.datetime + :ivar validated_at: The Unix timestamp (in seconds) for when webhook validation completed. + :vartype validated_at: ~datetime.datetime + :ivar admitted_at: The Unix timestamp (in seconds) for when the call was admitted to an agent + binding. + :vartype admitted_at: ~datetime.datetime + :ivar answer_requested_at: The Unix timestamp (in seconds) for when the service requested that + the provider answer the call. + :vartype answer_requested_at: ~datetime.datetime + :ivar answered_at: The Unix timestamp (in seconds) for when the provider reported that the call + was answered. + :vartype answered_at: ~datetime.datetime + :ivar media_connected_at: The Unix timestamp (in seconds) for when the provider media channel + connected. + :vartype media_connected_at: ~datetime.datetime + :ivar agent_session_ready_at: The Unix timestamp (in seconds) for when the voice-agent session + became ready. + :vartype agent_session_ready_at: ~datetime.datetime + :ivar first_caller_audio_at: The Unix timestamp (in seconds) for when caller audio was first + observed. + :vartype first_caller_audio_at: ~datetime.datetime + :ivar first_agent_audio_at: The Unix timestamp (in seconds) for when agent audio was first + observed. + :vartype first_agent_audio_at: ~datetime.datetime + :ivar ended_at: The Unix timestamp (in seconds) for when the call reached a terminal state. + :vartype ended_at: ~datetime.datetime + :ivar duration_basis: The timestamp used as the basis for duration. Known values are: + "answered" and "received". + :vartype duration_basis: str or ~azure.ai.projects.models.TelephonyCallDurationBasis + :ivar timestamp_source: The primary source of the timing milestones. Individual lifecycle + events identify their own timestamp source separately. Required. Known values are: "provider", + "gateway", and "derived". + :vartype timestamp_source: str or ~azure.ai.projects.models.TelephonyCallTimestampSource + """ + + received_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider webhook was received.""" + validated_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when webhook validation completed.""" + admitted_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the call was admitted to an agent binding.""" + answer_requested_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the service requested that the provider answer the + call.""" + answered_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider reported that the call was answered.""" + media_connected_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the provider media channel connected.""" + agent_session_ready_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the voice-agent session became ready.""" + first_caller_audio_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when caller audio was first observed.""" + first_agent_audio_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when agent audio was first observed.""" + ended_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the call reached a terminal state.""" + duration_basis: Optional[Union[str, "_models.TelephonyCallDurationBasis"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The timestamp used as the basis for duration. Known values are: \"answered\" and \"received\".""" + timestamp_source: Union[str, "_models.TelephonyCallTimestampSource"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The primary source of the timing milestones. Individual lifecycle events identify their own + timestamp source separately. Required. Known values are: \"provider\", \"gateway\", and + \"derived\".""" + + @overload + def __init__( + self, + *, + timestamp_source: Union[str, "_models.TelephonyCallTimestampSource"], + received_at: Optional[datetime.datetime] = None, + validated_at: Optional[datetime.datetime] = None, + admitted_at: Optional[datetime.datetime] = None, + answer_requested_at: Optional[datetime.datetime] = None, + answered_at: Optional[datetime.datetime] = None, + media_connected_at: Optional[datetime.datetime] = None, + agent_session_ready_at: Optional[datetime.datetime] = None, + first_caller_audio_at: Optional[datetime.datetime] = None, + first_agent_audio_at: Optional[datetime.datetime] = None, + ended_at: Optional[datetime.datetime] = None, + duration_basis: Optional[Union[str, "_models.TelephonyCallDurationBasis"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyCallTrace(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Correlation from a durable telephony call record to its customer-facing Foundry trace. + + :ivar status: The trace availability status. Required. Known values are: "pending", "emitting", + "available", "not_recorded", "not_applicable", and "failed". + :vartype status: str or ~azure.ai.projects.models.TelephonyCallTraceStatus + :ivar trace_id: The W3C trace identifier, when a trace was recorded. + :vartype trace_id: str + :ivar root_span_id: The root span identifier, when a trace was recorded. + :vartype root_span_id: str + :ivar conversation_id: The voice-agent conversation identifier, when a conversation was + created. + :vartype conversation_id: str + :ivar mode: Whether the trace was emitted live or after the call ended. Known values are: + "live" and "post_call". + :vartype mode: str or ~azure.ai.projects.models.TelephonyCallTraceMode + """ + + status: Union[str, "_models.TelephonyCallTraceStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The trace availability status. Required. Known values are: \"pending\", \"emitting\", + \"available\", \"not_recorded\", \"not_applicable\", and \"failed\".""" + trace_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The W3C trace identifier, when a trace was recorded.""" + root_span_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The root span identifier, when a trace was recorded.""" + conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice-agent conversation identifier, when a conversation was created.""" + mode: Optional[Union[str, "_models.TelephonyCallTraceMode"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Whether the trace was emitted live or after the call ended. Known values are: \"live\" and + \"post_call\".""" + + @overload + def __init__( + self, + *, + status: Union[str, "_models.TelephonyCallTraceStatus"], + trace_id: Optional[str] = None, + root_span_id: Optional[str] = None, + conversation_id: Optional[str] = None, + mode: Optional[Union[str, "_models.TelephonyCallTraceMode"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyOutboundDestination(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The destination of an outbound call. + + :ivar type: The destination type. Only E.164 phone numbers are currently supported. Required. + "phone_number" + :vartype type: str or ~azure.ai.projects.models.TelephonyOutboundDestinationType + :ivar value: The destination E.164 phone number. Required. + :vartype value: str + """ + + type: Union[str, "_models.TelephonyOutboundDestinationType"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The destination type. Only E.164 phone numbers are currently supported. Required. + \"phone_number\"""" + value: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The destination E.164 phone number. Required.""" + + @overload + def __init__( + self, + *, + type: Union[str, "_models.TelephonyOutboundDestinationType"], + value: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyOutboundRetryPolicy(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The retry policy for one durable outbound call intent. ``max_attempts`` includes the first + attempt. Strategy-specific settings are defined by the derived policy. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TelephonyOutboundFixedIntervalRetryPolicy + + :ivar type: The retry strategy. Only fixed-interval retries are currently supported. Required. + "fixed_interval" + :vartype type: str or ~azure.ai.projects.models.TelephonyOutboundRetryPolicyType + :ivar max_attempts: The maximum number of provider attempts, including the first attempt. + Defaults to 1. + :vartype max_attempts: int + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The retry strategy. Only fixed-interval retries are currently supported. Required. + \"fixed_interval\"""" + max_attempts: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The maximum number of provider attempts, including the first attempt. Defaults to 1.""" + + @overload + def __init__( + self, + *, + type: str, + max_attempts: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyOutboundFixedIntervalRetryPolicy( + TelephonyOutboundRetryPolicy, discriminator="fixed_interval" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The frozen fixed-interval retry policy returned for an outbound call or campaign. + + :ivar max_attempts: The maximum number of provider attempts, including the first attempt. + Defaults to 1. + :vartype max_attempts: int + :ivar type: The fixed-interval retry strategy. Required. Retry after a fixed interval between + attempts. + :vartype type: str or ~azure.ai.projects.models.FIXED_INTERVAL + :ivar interval: The fixed delay in seconds between attempts. Required. + :vartype interval: ~datetime.timedelta + """ + + type: Literal[TelephonyOutboundRetryPolicyType.FIXED_INTERVAL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The fixed-interval retry strategy. Required. Retry after a fixed interval between attempts.""" + interval: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The fixed delay in seconds between attempts. Required.""" + + @overload + def __init__( + self, + *, + interval: datetime.timedelta, + max_attempts: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TelephonyOutboundRetryPolicyType.FIXED_INTERVAL # type: ignore + + +class TelephonyTransferTarget(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A named destination to which the voice agent may transfer a call. + + :ivar name: The unique name exposed to the voice agent for this transfer target. Required. + :vartype name: str + :ivar description: A description that helps the voice agent decide when to use this target. + Required. + :vartype description: str + :ivar destination: The provider-specific transfer destination. Required. + :vartype destination: ~azure.ai.projects.models.TelephonyTransferDestination + """ + + name: str = rest_field(visibility=["read", "create"]) + """The unique name exposed to the voice agent for this transfer target. Required.""" + description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A description that helps the voice agent decide when to use this target. Required.""" + destination: "_models.TelephonyTransferDestination" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The provider-specific transfer destination. Required.""" + + @overload + def __init__( + self, + *, + name: str, + description: str, + destination: "_models.TelephonyTransferDestination", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TelephonyTransferTargets(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The telephony transfer targets configured for one voice agent. + + :ivar transfer_targets: The complete set of destinations to which the voice agent may transfer + calls. An empty array clears all targets when replacing the configuration. Required. + :vartype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + """ + + transfer_targets: list["_models.TelephonyTransferTarget"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The complete set of destinations to which the voice agent may transfer calls. An empty array + clears all targets when replacing the configuration. Required.""" + + @overload + def __init__( + self, + *, + transfer_targets: list["_models.TelephonyTransferTarget"], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TextResponseFormat(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An object specifying the format that the model must output. Configuring ``{ "type": + "json_schema" }`` enables Structured Outputs, which ensures the model will match your supplied + JSON schema. Learn more in the `Structured Outputs guide `_. + The default format is ``{ "type": "text" }`` with no additional options. *Not recommended for + gpt-4o and newer models:** Setting to ``{ "type": "json_object" }`` enables the older JSON + mode, which ensures the message the model generates is valid JSON. Using ``json_schema`` is + preferred for models that support it. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + TextResponseFormatJsonObject, TextResponseFormatJsonSchema, TextResponseFormatText + + :ivar type: Required. Known values are: "text", "json_schema", and "json_object". + :vartype type: str or ~azure.ai.projects.models.TextResponseFormatConfigurationType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """Required. Known values are: \"text\", \"json_schema\", and \"json_object\".""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TextResponseFormatJsonObject(TextResponseFormat, discriminator="json_object"): + """JSON object. + + :ivar type: The type of response format being defined. Always ``json_object``. Required. + JSON_OBJECT. + :vartype type: str or ~azure.ai.projects.models.JSON_OBJECT + """ + + type: Literal[TextResponseFormatConfigurationType.JSON_OBJECT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of response format being defined. Always ``json_object``. Required. JSON_OBJECT.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TextResponseFormatConfigurationType.JSON_OBJECT # type: ignore + + +class TextResponseFormatJsonSchema( + TextResponseFormat, discriminator="json_schema" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """JSON schema. + + :ivar type: The type of response format being defined. Always ``json_schema``. Required. + JSON_SCHEMA. + :vartype type: str or ~azure.ai.projects.models.JSON_SCHEMA + :ivar description: A description of what the response format is for, used by the model to + determine how to respond in the format. + :vartype description: str + :ivar name: The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and + dashes, with a maximum length of 64. Required. + :vartype name: str + :ivar schema: Required. + :vartype schema: dict[str, any] + :ivar strict: + :vartype strict: bool + """ + + type: Literal[TextResponseFormatConfigurationType.JSON_SCHEMA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of response format being defined. Always ``json_schema``. Required. JSON_SCHEMA.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A description of what the response format is for, used by the model to determine how to respond + in the format.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with + a maximum length of 64. Required.""" + schema: dict[str, Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + strict: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + name: str, + schema: dict[str, Any], + description: Optional[str] = None, + strict: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TextResponseFormatConfigurationType.JSON_SCHEMA # type: ignore + + +class TextResponseFormatText(TextResponseFormat, discriminator="text"): + """Text. + + :ivar type: The type of response format being defined. Always ``text``. Required. TEXT. + :vartype type: str or ~azure.ai.projects.models.TEXT + """ + + type: Literal[TextResponseFormatConfigurationType.TEXT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of response format being defined. Always ``text``. Required. TEXT.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = TextResponseFormatConfigurationType.TEXT # type: ignore + + +class TimerRoutineTrigger( + RoutineTrigger, discriminator="timer" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A one-shot timer routine trigger. + + :ivar type: The trigger type. Required. A one-shot timer trigger. + :vartype type: str or ~azure.ai.projects.models.TIMER + :ivar at: The UTC date and time at which the timer fires. + :vartype at: ~datetime.datetime + """ + + type: Literal[RoutineTriggerType.TIMER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The trigger type. Required. A one-shot timer trigger.""" + at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The UTC date and time at which the timer fires.""" + + @overload + def __init__( + self, + *, + at: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RoutineTriggerType.TIMER # type: ignore + + +class ToolboxObject(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A toolbox that stores reusable tool definitions for agents. + + :ivar id: The unique identifier of the toolbox. Required. + :vartype id: str + :ivar name: The name of the toolbox. Required. + :vartype name: str + :ivar updated_at: The Unix timestamp (seconds) when the toolbox was last updated. This value + changes when a new toolbox version is created or the toolbox is updated. Required. + :vartype updated_at: ~datetime.datetime + :ivar versions: The versions associated with the toolbox. Required. + :vartype versions: ~azure.ai.projects.models.ToolboxVersions + :ivar default_version: The version identifier that the toolbox currently points to. Defaults to + the latest version. Can be changed via updateToolbox. Required. + :vartype default_version: str + """ + + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique identifier of the toolbox. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the toolbox. Required.""" + updated_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (seconds) when the toolbox was last updated. This value changes when a new + toolbox version is created or the toolbox is updated. Required.""" + versions: "_models.ToolboxVersions" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The versions associated with the toolbox. Required.""" + default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version identifier that the toolbox currently points to. Defaults to the latest version. + Can be changed via updateToolbox. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + name: str, + updated_at: datetime.datetime, + versions: "_models.ToolboxVersions", + default_version: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxPolicies(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Policy configuration for a toolbox, including content safety and other governance settings. + + :ivar rai_config: Responsible AI content filtering configuration. + :vartype rai_config: ~azure.ai.projects.models.RaiConfig + """ + + rai_config: Optional["_models.RaiConfig"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Responsible AI content filtering configuration.""" + + @overload + def __init__( + self, + *, + rai_config: Optional["_models.RaiConfig"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxSearchPreviewToolboxTool( + ToolboxTool, discriminator="toolbox_search_preview" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A toolbox search tool stored in a toolbox. + + :ivar name: Optional user-defined name for this tool or configuration. + :vartype name: str + :ivar description: Optional user-defined description for this tool or configuration. + :vartype description: str + :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all + default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names + are silently ignored at runtime. + :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] + :ivar type: The type of the tool. Always ``toolbox_search_preview``. Required. + TOOLBOX_SEARCH_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.TOOLBOX_SEARCH_PREVIEW + """ + + type: Literal[ToolboxToolType.TOOLBOX_SEARCH_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``toolbox_search_preview``. Required. TOOLBOX_SEARCH_PREVIEW.""" + + @overload + def __init__( + self, + *, + name: Optional[str] = None, + description: Optional[str] = None, + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolboxToolType.TOOLBOX_SEARCH_PREVIEW # type: ignore + + +class ToolboxShellEnvironment(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An execution environment for a shell tool stored in a toolbox. This environment model is scoped + to toolbox configuration and does not modify the OpenAI shell environment contract. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + ToolboxShellContainerAutoEnvironment, ToolboxShellContainerReferenceEnvironment + + :ivar type: The type of the shell execution environment. Required. Default value is None. + :vartype type: str + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The type of the shell execution environment. Required. Default value is None.""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxShellContainerAutoEnvironment( + ToolboxShellEnvironment, discriminator="container_auto" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """An automatically provisioned container environment for a shell tool stored in a toolbox. + + :ivar type: The type of the shell execution environment. Always ``container_auto``. Required. + Default value is "container_auto". + :vartype type: str + :ivar file_ids: An optional list of uploaded files to make available to your code. + :vartype file_ids: list[str] + :ivar memory_limit: Known values are: "1g", "4g", "16g", and "64g". + :vartype memory_limit: str or ~azure.ai.projects.models.ContainerMemoryLimit + :ivar skills: An optional list of skills referenced by id or inline data. + :vartype skills: list[~azure.ai.projects.models.ContainerSkill] + :ivar network_policy: The network access policy for the container. When omitted, the service + defaults to disabled outbound network access. + :vartype network_policy: ~azure.ai.projects.models.ToolboxShellNetworkPolicy + """ + + type: Literal["container_auto"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the shell execution environment. Always ``container_auto``. Required. Default value + is \"container_auto\".""" + file_ids: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional list of uploaded files to make available to your code.""" + memory_limit: Optional[Union[str, "_models.ContainerMemoryLimit"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Known values are: \"1g\", \"4g\", \"16g\", and \"64g\".""" + skills: Optional[list["_models.ContainerSkill"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """An optional list of skills referenced by id or inline data.""" + network_policy: Optional["_models.ToolboxShellNetworkPolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The network access policy for the container. When omitted, the service defaults to disabled + outbound network access.""" + + @overload + def __init__( + self, + *, + file_ids: Optional[list[str]] = None, + memory_limit: Optional[Union[str, "_models.ContainerMemoryLimit"]] = None, + skills: Optional[list["_models.ContainerSkill"]] = None, + network_policy: Optional["_models.ToolboxShellNetworkPolicy"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = "container_auto" # type: ignore + + +class ToolboxShellContainerReferenceEnvironment( + ToolboxShellEnvironment, discriminator="container_reference" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """An existing container environment for a shell tool stored in a toolbox. + + :ivar type: The type of the shell execution environment. Always ``container_reference``. + Required. Default value is "container_reference". + :vartype type: str + :ivar container_id: The ID of the referenced container. Required. + :vartype container_id: str + """ + + type: Literal["container_reference"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the shell execution environment. Always ``container_reference``. Required. Default + value is \"container_reference\".""" + container_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The ID of the referenced container. Required.""" + + @overload + def __init__( + self, + *, + container_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = "container_reference" # type: ignore + + +class ToolboxShellNetworkPolicy(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Network access policy for an automatically provisioned toolbox shell container. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + ToolboxShellNetworkPolicyDisabled + + :ivar type: The type of network access policy. Required. Default value is None. + :vartype type: str + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The type of network access policy. Required. Default value is None.""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxShellNetworkPolicyDisabled(ToolboxShellNetworkPolicy, discriminator="disabled"): + """A network policy that disables outbound access from a toolbox shell container. + + :ivar type: The type of network access policy. Always ``disabled``. Required. Default value is + "disabled". + :vartype type: str + """ + + type: Literal["disabled"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of network access policy. Always ``disabled``. Required. Default value is + \"disabled\".""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = "disabled" # type: ignore + + +class ToolboxSkill(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A skill source included in a toolbox. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + ToolboxSkillReference + + :ivar type: The type of skill source. Required. Default value is None. + :vartype type: str + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The type of skill source. Required. Default value is None.""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxSkillReference( + ToolboxSkill, discriminator="skill_reference" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A reference to an existing skill to include in a toolbox. + + :ivar type: The type of skill source. Required. Default value is "skill_reference". + :vartype type: str + :ivar name: The name of the skill. Required. + :vartype name: str + :ivar version: The version of the skill. If not specified, the skill's default version is used. + When a version is specified, the reference is pinned to that immutable version. + :vartype version: str + """ + + type: Literal["skill_reference"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of skill source. Required. Default value is \"skill_reference\".""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the skill. Required.""" + version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version of the skill. If not specified, the skill's default version is used. When a version + is specified, the reference is pinned to that immutable version.""" + + @overload + def __init__( + self, + *, + name: str, + version: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = "skill_reference" # type: ignore + + +class ToolboxVersionObject(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A specific version of a toolbox. + + :ivar metadata: Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. + + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Required. + :vartype metadata: dict[str, str] + :ivar id: The unique identifier of the toolbox version. Required. + :vartype id: str + :ivar name: The name of the toolbox. Required. + :vartype name: str + :ivar version: The version identifier of the toolbox. Toolbox versions are immutable and every + update creates a new version. Required. + :vartype version: str + :ivar description: A human-readable description of the toolbox. + :vartype description: str + :ivar created_at: The Unix timestamp (seconds) when the toolbox version was created. Required. + :vartype created_at: ~datetime.datetime + :ivar tools: The list of tools contained in this toolbox version. Required. + :vartype tools: list[~azure.ai.projects.models.ToolboxTool] + :ivar skills: The list of skill sources included in this toolbox version. + :vartype skills: list[~azure.ai.projects.models.ToolboxSkill] + :ivar policies: Policy configuration for the toolbox version. + :vartype policies: ~azure.ai.projects.models.ToolboxPolicies + """ + + metadata: dict[str, str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. + + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Required.""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique identifier of the toolbox version. Required.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the toolbox. Required.""" + version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version identifier of the toolbox. Toolbox versions are immutable and every update creates + a new version. Required.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable description of the toolbox.""" + created_at: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (seconds) when the toolbox version was created. Required.""" + tools: list["_models.ToolboxTool"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The list of tools contained in this toolbox version. Required.""" + skills: Optional[list["_models.ToolboxSkill"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The list of skill sources included in this toolbox version.""" + policies: Optional["_models.ToolboxPolicies"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Policy configuration for the toolbox version.""" + + @overload + def __init__( + self, + *, + metadata: dict[str, str], + id: str, # pylint: disable=redefined-builtin + name: str, + version: str, + created_at: datetime.datetime, + tools: list["_models.ToolboxTool"], + description: Optional[str] = None, + skills: Optional[list["_models.ToolboxSkill"]] = None, + policies: Optional["_models.ToolboxPolicies"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolboxVersions(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The versions associated with a toolbox. + + :ivar latest: The latest version of the toolbox. Required. + :vartype latest: ~azure.ai.projects.models.ToolboxVersionObject + """ + + latest: "_models.ToolboxVersionObject" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The latest version of the toolbox. Required.""" + + @overload + def __init__( + self, + *, + latest: "_models.ToolboxVersionObject", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolChoiceAllowed( + ToolChoiceParam, discriminator="allowed_tools" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Allowed tools. + + :ivar type: Allowed tool configuration type. Always ``allowed_tools``. Required. ALLOWED_TOOLS. + :vartype type: str or ~azure.ai.projects.models.ALLOWED_TOOLS + :ivar mode: Constrains the tools available to the model to a pre-defined set. ``auto`` allows + the model to pick from among the allowed tools and generate a message. ``required`` requires + the model to call one or more of the allowed tools. Required. Is either a Literal["auto"] type + or a Literal["required"] type. + :vartype mode: str or str + :ivar tools: Required. A list of tool definitions that the model should be allowed to call. For + the Responses API, the list of tool definitions might look like: + + .. code-block:: json + + [ + { "type": "function", "name": "get_weather" }, + { "type": "mcp", "server_label": "deepwiki" }, + { "type": "image_generation" } + ] + :vartype tools: list[dict[str, any]] + """ + + type: Literal[ToolChoiceParamType.ALLOWED_TOOLS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Allowed tool configuration type. Always ``allowed_tools``. Required. ALLOWED_TOOLS.""" + mode: Literal["auto", "required"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Constrains the tools available to the model to a pre-defined set. ``auto`` allows the model to + pick from among the allowed tools and generate a message. ``required`` requires the model to + call one or more of the allowed tools. Required. Is either a Literal[\"auto\"] type or a + Literal[\"required\"] type.""" + tools: list[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required. A list of tool definitions that the model should be allowed to call. For the + Responses API, the list of tool definitions might look like: + + .. code-block:: json + + [ + { \"type\": \"function\", \"name\": \"get_weather\" }, + { \"type\": \"mcp\", \"server_label\": \"deepwiki\" }, + { \"type\": \"image_generation\" } + ]""" + + @overload + def __init__( + self, + *, + mode: Literal["auto", "required"], + tools: list[dict[str, Any]], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.ALLOWED_TOOLS # type: ignore + + +class ToolChoiceCodeInterpreter(ToolChoiceParam, discriminator="code_interpreter"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. CODE_INTERPRETER. + :vartype type: str or ~azure.ai.projects.models.CODE_INTERPRETER + """ + + type: Literal[ToolChoiceParamType.CODE_INTERPRETER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. CODE_INTERPRETER.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.CODE_INTERPRETER # type: ignore + + +class ToolChoiceComputer(ToolChoiceParam, discriminator="computer"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. COMPUTER. + :vartype type: str or ~azure.ai.projects.models.COMPUTER + """ + + type: Literal[ToolChoiceParamType.COMPUTER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. COMPUTER.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.COMPUTER # type: ignore + + +class ToolChoiceComputerUse(ToolChoiceParam, discriminator="computer_use"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. COMPUTER_USE. + :vartype type: str or ~azure.ai.projects.models.COMPUTER_USE + """ + + type: Literal[ToolChoiceParamType.COMPUTER_USE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. COMPUTER_USE.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.COMPUTER_USE # type: ignore + + +class ToolChoiceComputerUsePreview(ToolChoiceParam, discriminator="computer_use_preview"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. COMPUTER_USE_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.COMPUTER_USE_PREVIEW + """ + + type: Literal[ToolChoiceParamType.COMPUTER_USE_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. COMPUTER_USE_PREVIEW.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.COMPUTER_USE_PREVIEW # type: ignore + + +class ToolChoiceCustom( + ToolChoiceParam, discriminator="custom" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Custom tool. + + :ivar type: For custom tool calling, the type is always ``custom``. Required. CUSTOM. + :vartype type: str or ~azure.ai.projects.models.CUSTOM + :ivar name: The name of the custom tool to call. Required. + :vartype name: str + """ + + type: Literal[ToolChoiceParamType.CUSTOM] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """For custom tool calling, the type is always ``custom``. Required. CUSTOM.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the custom tool to call. Required.""" + + @overload + def __init__( + self, + *, + name: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.CUSTOM # type: ignore + + +class ToolChoiceFileSearch(ToolChoiceParam, discriminator="file_search"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. FILE_SEARCH. + :vartype type: str or ~azure.ai.projects.models.FILE_SEARCH + """ + + type: Literal[ToolChoiceParamType.FILE_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. FILE_SEARCH.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.FILE_SEARCH # type: ignore + + +class ToolChoiceFunction( + ToolChoiceParam, discriminator="function" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Function tool. + + :ivar type: For function calling, the type is always ``function``. Required. FUNCTION. + :vartype type: str or ~azure.ai.projects.models.FUNCTION + :ivar name: The name of the function to call. Required. + :vartype name: str + """ + + type: Literal[ToolChoiceParamType.FUNCTION] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """For function calling, the type is always ``function``. Required. FUNCTION.""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the function to call. Required.""" + + @overload + def __init__( + self, + *, + name: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.FUNCTION # type: ignore + + +class ToolChoiceImageGeneration(ToolChoiceParam, discriminator="image_generation"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. IMAGE_GENERATION. + :vartype type: str or ~azure.ai.projects.models.IMAGE_GENERATION + """ + + type: Literal[ToolChoiceParamType.IMAGE_GENERATION] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. IMAGE_GENERATION.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.IMAGE_GENERATION # type: ignore + + +class ToolChoiceMCP( + ToolChoiceParam, discriminator="mcp" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """MCP tool. + + :ivar type: For MCP tools, the type is always ``mcp``. Required. MCP. + :vartype type: str or ~azure.ai.projects.models.MCP + :ivar server_label: The label of the MCP server to use. Required. + :vartype server_label: str + :ivar name: + :vartype name: str + """ + + type: Literal[ToolChoiceParamType.MCP] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """For MCP tools, the type is always ``mcp``. Required. MCP.""" + server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The label of the MCP server to use. Required.""" + name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + server_label: str, + name: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.MCP # type: ignore + + +class ToolChoiceWebSearchPreview(ToolChoiceParam, discriminator="web_search_preview"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. WEB_SEARCH_PREVIEW. + :vartype type: str or ~azure.ai.projects.models.WEB_SEARCH_PREVIEW + """ + + type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. WEB_SEARCH_PREVIEW.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.WEB_SEARCH_PREVIEW # type: ignore + + +class ToolChoiceWebSearchPreview20250311(ToolChoiceParam, discriminator="web_search_preview_2025_03_11"): + """Indicates that the model should use a built-in tool to generate a response. `Learn more about + built-in tools `_. + + :ivar type: Required. WEB_SEARCH_PREVIEW_2025_03_11. + :vartype type: str or ~azure.ai.projects.models.WEB_SEARCH_PREVIEW_2025_03_11 + """ + + type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. WEB_SEARCH_PREVIEW_2025_03_11.""" + + @overload + def __init__( + self, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11 # type: ignore + + +class ToolConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Per-tool configuration that controls tool visibility and search behavior. + + :ivar pin: When true, the tool is always included in agent context and visible in + ``tools/list``. When false (default), the tool is hidden from ``tools/list`` and only + discoverable via ``tool_search``. + :vartype pin: bool + :ivar additional_search_text: Additional text indexed for tool_search. Supplements the native + tool description to improve discoverability. Does not alter ``tools/list`` output. + :vartype additional_search_text: str + """ + + pin: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """When true, the tool is always included in agent context and visible in ``tools/list``. When + false (default), the tool is hidden from ``tools/list`` and only discoverable via + ``tool_search``.""" + additional_search_text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Additional text indexed for tool_search. Supplements the native tool description to improve + discoverability. Does not alter ``tools/list`` output.""" + + @overload + def __init__( + self, + *, + pin: Optional[bool] = None, + additional_search_text: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolDescription(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Description of a tool that can be used by an agent. + + :ivar name: The name of the tool. + :vartype name: str + :ivar description: A brief description of the tool's purpose. + :vartype description: str + """ + + name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the tool.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A brief description of the tool's purpose.""" + + @overload + def __init__( + self, + *, + name: Optional[str] = None, + description: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolProjectConnection(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A project connection resource. + + :ivar project_connection_id: A project connection in a ToolProjectConnectionList attached to + this tool. Required. + :vartype project_connection_id: str + """ + + project_connection_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A project connection in a ToolProjectConnectionList attached to this tool. Required.""" + + @overload + def __init__( + self, + *, + project_connection_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ToolSearchToolboxTool( + ToolboxTool, discriminator="toolbox_search" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A toolbox search tool stored in a toolbox. + + :ivar name: Optional user-defined name for this tool or configuration. + :vartype name: str + :ivar description: Optional user-defined description for this tool or configuration. + :vartype description: str + :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all + default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names + are silently ignored at runtime. + :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] + :ivar type: The type of the tool. Always ``toolbox_search``. Required. TOOLBOX_SEARCH. + :vartype type: str or ~azure.ai.projects.models.TOOLBOX_SEARCH + """ + + type: Literal[ToolboxToolType.TOOLBOX_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``toolbox_search``. Required. TOOLBOX_SEARCH.""" + + @overload + def __init__( + self, + *, + name: Optional[str] = None, + description: Optional[str] = None, + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolboxToolType.TOOLBOX_SEARCH # type: ignore + + +class ToolSearchToolParam( + Tool, discriminator="tool_search" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Tool search tool. + + :ivar type: The type of the tool. Always ``tool_search``. Required. TOOL_SEARCH. + :vartype type: str or ~azure.ai.projects.models.TOOL_SEARCH + :ivar execution: Whether tool search is executed by the server or by the client. Known values + are: "server" and "client". + :vartype execution: str or ~azure.ai.projects.models.ToolSearchExecutionType + :ivar description: + :vartype description: str + :ivar parameters: + :vartype parameters: ~azure.ai.projects.models.EmptyModelParam + """ + + type: Literal[ToolType.TOOL_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``tool_search``. Required. TOOL_SEARCH.""" + execution: Optional[Union[str, "_models.ToolSearchExecutionType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Whether tool search is executed by the server or by the client. Known values are: \"server\" + and \"client\".""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + parameters: Optional["_models.EmptyModelParam"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + + @overload + def __init__( + self, + *, + execution: Optional[Union[str, "_models.ToolSearchExecutionType"]] = None, + description: Optional[str] = None, + parameters: Optional["_models.EmptyModelParam"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = ToolType.TOOL_SEARCH # type: ignore + + +class ToolUseFineTuningDataGenerationJobOptions( + DataGenerationJobOptions, discriminator="tool_use" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The options for a data generation job with ToolUse type. Used only for fine-tuning scenarios. + + :ivar train_split: The proportion of the generated data to be used for training when the data + is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. + :vartype train_split: float + :ivar model_options: The LLM model options. + :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions + :ivar type: The data generation job type, which is ToolUse for this model. Required. Tool + calling conversation between user and agent. + :vartype type: str or ~azure.ai.projects.models.TOOL_USE + :ivar max_samples: Maximum number of samples to generate, up to service-defined limits. + Required. + :vartype max_samples: int + """ + + type: Literal[DataGenerationJobType.TOOL_USE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The data generation job type, which is ToolUse for this model. Required. Tool calling + conversation between user and agent.""" + max_samples: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Maximum number of samples to generate, up to service-defined limits. Required.""" + + @overload + def __init__( + self, + *, + max_samples: int, + train_split: Optional[float] = None, + model_options: Optional["_models.DataGenerationModelOptions"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = DataGenerationJobType.TOOL_USE # type: ignore + + +class TracesDataGenerationJobOptions( + DataGenerationJobOptions, discriminator="traces" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The options for a data generation job with Traces type. + + :ivar train_split: The proportion of the generated data to be used for training when the data + is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. + :vartype train_split: float + :ivar model_options: The LLM model options. + :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions + :ivar type: The data generation job type, which is Traces for this model. Required. Single turn + query and response from agent traces. + :vartype type: str or ~azure.ai.projects.models.TRACES + :ivar max_samples: Maximum number of samples to generate, up to service-defined limits. If + omitted, sampling is turned off. + :vartype max_samples: int + :ivar redact_private_content: Whether to redact private content from traces. When omitted or + set to true, private content is redacted. Set to false to opt out of redaction. + :vartype redact_private_content: bool + """ + + type: Literal[DataGenerationJobType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The data generation job type, which is Traces for this model. Required. Single turn query and + response from agent traces.""" + max_samples: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Maximum number of samples to generate, up to service-defined limits. If omitted, sampling is + turned off.""" + redact_private_content: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether to redact private content from traces. When omitted or set to true, private content is + redacted. Set to false to opt out of redaction.""" + + @overload + def __init__( + self, + *, + train_split: Optional[float] = None, + model_options: Optional["_models.DataGenerationModelOptions"] = None, + max_samples: Optional[int] = None, + redact_private_content: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = DataGenerationJobType.TRACES # type: ignore + + +class TracesDataGenerationJobSource( + DataGenerationJobSource, discriminator="traces" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Traces source for data generation jobs — conversation traces from Application Insights. + + :ivar description: Optional description of what this source represents — helps the pipeline + interpret its content (e.g., 'Company refund policy document' or 'Describes the agent's core + capabilities'). + :vartype description: str + :ivar type: The source type for this source, which is Traces. Required. Traces source — + conversation traces from Application Insights. + :vartype type: str or ~azure.ai.projects.models.TRACES + :ivar agent_id: The unique agent ID used to filter traces. Provide either ``agent_id`` or + ``agent_name`` — at least one is required. + :vartype agent_id: str + :ivar agent_name: The agent name to fetch traces for. Provide either ``agent_id`` or + ``agent_name`` — at least one is required. + :vartype agent_name: str + :ivar agent_version: The agent version. If not specified, traces for ALL versions of the agent + are included within the time window. + :vartype agent_version: str + :ivar start_time: Start of the time window (Unix timestamp in seconds) for fetching traces. + Required. + :vartype start_time: ~datetime.datetime + :ivar end_time: End of the time window (Unix timestamp in seconds). Defaults to current time. + :vartype end_time: ~datetime.datetime + :ivar trace_ids: Optional explicit list of trace IDs to include. + :vartype trace_ids: list[str] + """ + + type: Literal[DataGenerationJobSourceType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The source type for this source, which is Traces. Required. Traces source — conversation traces + from Application Insights.""" + agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique agent ID used to filter traces. Provide either ``agent_id`` or ``agent_name`` — at + least one is required.""" + agent_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent name to fetch traces for. Provide either ``agent_id`` or ``agent_name`` — at least + one is required.""" + agent_version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent version. If not specified, traces for ALL versions of the agent are included within + the time window.""" + start_time: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """Start of the time window (Unix timestamp in seconds) for fetching traces. Required.""" + end_time: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """End of the time window (Unix timestamp in seconds). Defaults to current time.""" + trace_ids: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional explicit list of trace IDs to include.""" + + @overload + def __init__( + self, + *, + start_time: datetime.datetime, + description: Optional[str] = None, + agent_id: Optional[str] = None, + agent_name: Optional[str] = None, + agent_version: Optional[str] = None, + end_time: Optional[datetime.datetime] = None, + trace_ids: Optional[list[str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = DataGenerationJobSourceType.TRACES # type: ignore + + +class TracesEvaluatorGenerationJobSource( + EvaluatorGenerationJobSource, discriminator="traces" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Traces source for evaluator generation jobs — conversation traces from Application Insights. + + :ivar description: Optional description of what this source represents — helps the pipeline + interpret its content (e.g., 'Company refund policy document' or 'Describes the agent's core + capabilities'). + :vartype description: str + :ivar type: The source type for this source, which is Traces. Required. Traces source — + conversation traces from Application Insights. + :vartype type: str or ~azure.ai.projects.models.TRACES + :ivar agent_id: The unique agent ID used to filter traces. Provide either ``agent_id`` or + ``agent_name`` — at least one is required. + :vartype agent_id: str + :ivar agent_name: The agent name to fetch traces for. Provide either ``agent_id`` or + ``agent_name`` — at least one is required. + :vartype agent_name: str + :ivar agent_version: The agent version. If not specified, traces for ALL versions of the agent + are included within the time window. + :vartype agent_version: str + :ivar start_time: Start of the time window (Unix timestamp in seconds) for fetching traces. + Required. + :vartype start_time: ~datetime.datetime + :ivar end_time: End of the time window (Unix timestamp in seconds). Defaults to current time. + :vartype end_time: ~datetime.datetime + """ + + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional description of what this source represents — helps the pipeline interpret its content + (e.g., 'Company refund policy document' or 'Describes the agent's core capabilities').""" + type: Literal[EvaluatorGenerationJobSourceType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The source type for this source, which is Traces. Required. Traces source — conversation traces + from Application Insights.""" + agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique agent ID used to filter traces. Provide either ``agent_id`` or ``agent_name`` — at + least one is required.""" + agent_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent name to fetch traces for. Provide either ``agent_id`` or ``agent_name`` — at least + one is required.""" + agent_version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent version. If not specified, traces for ALL versions of the agent are included within + the time window.""" + start_time: datetime.datetime = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """Start of the time window (Unix timestamp in seconds) for fetching traces. Required.""" + end_time: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """End of the time window (Unix timestamp in seconds). Defaults to current time.""" + + @overload + def __init__( + self, + *, + start_time: datetime.datetime, + description: Optional[str] = None, + agent_id: Optional[str] = None, + agent_name: Optional[str] = None, + agent_version: Optional[str] = None, + end_time: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = EvaluatorGenerationJobSourceType.TRACES # type: ignore + + +class TranscriptionLanguage(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A language detected in transcribed audio. + + :ivar code: The code of a language detected in the audio. Required. + :vartype code: str + """ + + code: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The code of a language detected in the audio. Required.""" + + @overload + def __init__( + self, + *, + code: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TranscriptTextUsageDuration( + CreateTranscriptionResponseJsonUsage, discriminator="duration" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Duration Usage. + + :ivar type: The type of the usage object. Always ``duration`` for this variant. Required. + DURATION. + :vartype type: str or ~azure.ai.projects.models.DURATION + :ivar seconds: Duration of the input audio in seconds. Required. + :vartype seconds: ~datetime.timedelta + """ + + type: Literal[CreateTranscriptionResponseJsonUsageType.DURATION] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the usage object. Always ``duration`` for this variant. Required. DURATION.""" + seconds: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """Duration of the input audio in seconds. Required.""" + + @overload + def __init__( + self, + *, + seconds: datetime.timedelta, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = CreateTranscriptionResponseJsonUsageType.DURATION # type: ignore + + +class TranscriptTextUsageTokens( + CreateTranscriptionResponseJsonUsage, discriminator="tokens" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Token Usage. + + :ivar type: The type of the usage object. Always ``tokens`` for this variant. Required. TOKENS. + :vartype type: str or ~azure.ai.projects.models.TOKENS + :ivar input_tokens: Number of input tokens billed for this request. Required. + :vartype input_tokens: int + :ivar input_token_details: Details about the input tokens billed for this request. + :vartype input_token_details: + ~azure.ai.projects.models.TranscriptTextUsageTokensInputTokenDetails + :ivar output_tokens: Number of output tokens generated. Required. + :vartype output_tokens: int + :ivar total_tokens: Total number of tokens used (input + output). Required. + :vartype total_tokens: int + """ + + type: Literal[CreateTranscriptionResponseJsonUsageType.TOKENS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the usage object. Always ``tokens`` for this variant. Required. TOKENS.""" + input_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Number of input tokens billed for this request. Required.""" + input_token_details: Optional["_models.TranscriptTextUsageTokensInputTokenDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Details about the input tokens billed for this request.""" + output_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Number of output tokens generated. Required.""" + total_tokens: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Total number of tokens used (input + output). Required.""" + + @overload + def __init__( + self, + *, + input_tokens: int, + output_tokens: int, + total_tokens: int, + input_token_details: Optional["_models.TranscriptTextUsageTokensInputTokenDetails"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = CreateTranscriptionResponseJsonUsageType.TOKENS # type: ignore + + +class TranscriptTextUsageTokensInputTokenDetails( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """TranscriptTextUsageTokensInputTokenDetails. + + :ivar text_tokens: + :vartype text_tokens: int + :ivar audio_tokens: + :vartype audio_tokens: int + """ + + text_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + audio_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + + @overload + def __init__( + self, + *, + text_tokens: Optional[int] = None, + audio_tokens: Optional[int] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class TwilioTelephonyBinding( + TelephonyBinding, discriminator="twilio" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A Twilio binding owned by a voice agent. + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar connection_name: The Foundry connection name for the telephony provider. Required. + :vartype connection_name: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + :ivar provider: The Twilio provider. Required. Twilio Programmable Voice. + :vartype provider: str or ~azure.ai.projects.models.TWILIO + :ivar phone_number: The Twilio E.164 phone number. Required. + :vartype phone_number: str + """ + + provider: Literal[TelephonyProvider.TWILIO] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Twilio provider. Required. Twilio Programmable Voice.""" + phone_number: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Twilio E.164 phone number. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + connection_name: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + phone_number: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TWILIO # type: ignore + + +class TwilioTelephonyBindingListItem( + TelephonyBindingListItem, discriminator="twilio" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A Twilio binding returned in a list, including its entity tag. + + :ivar id: The service-generated binding identifier. Required. + :vartype id: str + :ivar connection_name: The Foundry connection name for the telephony provider. Required. + :vartype connection_name: str + :ivar label: The optional display label for the binding. + :vartype label: str + :ivar status: The lifecycle status. Required. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar incoming_call_url: The service-generated webhook URL to configure with the telephony + provider. Required. + :vartype incoming_call_url: str + :ivar etag: The entity tag to send in the ``If-Match`` header when updating or deleting this + binding. Required. + :vartype etag: str + :ivar provider: The Twilio provider. Required. Twilio Programmable Voice. + :vartype provider: str or ~azure.ai.projects.models.TWILIO + :ivar phone_number: The Twilio E.164 phone number. Required. + :vartype phone_number: str + """ + + provider: Literal[TelephonyProvider.TWILIO] = rest_discriminator(name="provider", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The Twilio provider. Required. Twilio Programmable Voice.""" + phone_number: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Twilio E.164 phone number. Required.""" + + @overload + def __init__( + self, + *, + id: str, # pylint: disable=redefined-builtin + connection_name: str, + status: Union[str, "_models.TelephonyBindingStatus"], + incoming_call_url: str, + phone_number: str, + label: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.provider = TelephonyProvider.TWILIO # type: ignore + + +class UpdateModelVersionRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Request body for updating a model version. Only description and tags can be modified. + + :ivar description: The asset description text. + :vartype description: str + :ivar tags: Tag dictionary. Tags can be added, removed, and updated. + :vartype tags: dict[str, str] + """ + + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The asset description text.""" + tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Tag dictionary. Tags can be added, removed, and updated.""" + + @overload + def __init__( + self, + *, + description: Optional[str] = None, + tags: Optional[dict[str, str]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class UpdateTelephonyBindingRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The request to update an existing telephony binding. Every property is optional and the + binding's provider is immutable. + + :ivar status: The new lifecycle status. Known values are: "active" and "suspended". + :vartype status: str or ~azure.ai.projects.models.TelephonyBindingStatus + :ivar label: The replacement display label. Omit it to preserve the current value; use null to + clear it. + :vartype label: str + :ivar connection_name: The replacement Foundry connection name. This property is valid only for + a Teams Phone Extension binding; a Twilio binding's connection is immutable. + :vartype connection_name: str + :ivar phone_number: The replacement Teams Phone Extension display phone number. Omit it to + preserve the current value; use null to clear it. This property is valid only for a Teams Phone + Extension binding. + :vartype phone_number: str + """ + + status: Optional[Union[str, "_models.TelephonyBindingStatus"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The new lifecycle status. Known values are: \"active\" and \"suspended\".""" + label: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The replacement display label. Omit it to preserve the current value; use null to clear it.""" + connection_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The replacement Foundry connection name. This property is valid only for a Teams Phone + Extension binding; a Twilio binding's connection is immutable.""" + phone_number: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The replacement Teams Phone Extension display phone number. Omit it to preserve the current + value; use null to clear it. This property is valid only for a Teams Phone Extension binding.""" + + @overload + def __init__( + self, + *, + status: Optional[Union[str, "_models.TelephonyBindingStatus"]] = None, + label: Optional[str] = None, + connection_name: Optional[str] = None, + phone_number: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class UpdateToolboxRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """UpdateToolboxRequest. + + :ivar default_version: The version identifier that the toolbox should point to. When set, the + toolbox's default version will resolve to this version instead of the latest. Required. + :vartype default_version: str + """ + + default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version identifier that the toolbox should point to. When set, the toolbox's default + version will resolve to this version instead of the latest. Required.""" + + @overload + def __init__( + self, + *, + default_version: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class UserProfileMemoryItem( + MemoryItem, discriminator="user_profile" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A memory item specifically containing user profile information extracted from conversations, + such as preferences, interests, and personal details. + + :ivar memory_id: The unique ID of the memory item. Required. + :vartype memory_id: str + :ivar updated_at: The last update time of the memory item. Required. + :vartype updated_at: ~datetime.datetime + :ivar scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :vartype scope: str + :ivar content: The content of the memory. Required. + :vartype content: str + :ivar kind: The kind of the memory item. Required. User profile information extracted from + conversations. + :vartype kind: str or ~azure.ai.projects.models.USER_PROFILE + """ + + kind: Literal[MemoryItemKind.USER_PROFILE] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The kind of the memory item. Required. User profile information extracted from conversations.""" + + @overload + def __init__( + self, + *, + memory_id: str, + updated_at: datetime.datetime, + scope: str, + content: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.kind = MemoryItemKind.USER_PROFILE # type: ignore + + +class VersionIndicator(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Version indicator determining which agent version backs the session. + + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VersionRefIndicator + + :ivar type: The type of version indicator. Required. "version_ref" + :vartype type: str or ~azure.ai.projects.models.VersionIndicatorType + """ + + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The type of version indicator. Required. \"version_ref\"""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class VersionRefIndicator( + VersionIndicator, discriminator="version_ref" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Version indicator that references a specific agent version by name. + + :ivar type: Discriminator value for version_ref. Required. Direct reference to a specific agent + version. + :vartype type: str or ~azure.ai.projects.models.VERSION_REF + :ivar agent_version: The agent version identifier returned by the agent version APIs. Required. + :vartype agent_version: str + """ + + type: Literal[VersionIndicatorType.VERSION_REF] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Discriminator value for version_ref. Required. Direct reference to a specific agent version.""" + agent_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The agent version identifier returned by the agent version APIs. Required.""" + + @overload + def __init__( + self, + *, + agent_version: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = VersionIndicatorType.VERSION_REF # type: ignore + + +class VersionSelector(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """VersionSelector. + + :ivar version_selection_rules: Required. + :vartype version_selection_rules: list[~azure.ai.projects.models.VersionSelectionRule] + """ + + version_selection_rules: list["_models.VersionSelectionRule"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" + + @overload + def __init__( + self, + *, + version_selection_rules: list["_models.VersionSelectionRule"], + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class VoiceAgentAnimationConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Animation settings for a voice-agent session. + + :ivar model_name: The animation model name. + :vartype model_name: str + :ivar outputs: The requested animation output kinds. + :vartype outputs: list[str or ~azure.ai.projects.models.VoiceAgentAnimationOutputType] + """ + + model_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The animation model name.""" + outputs: Optional[list[Union[str, "_models.VoiceAgentAnimationOutputType"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The requested animation output kinds.""" + + @overload + def __init__( + self, + *, + model_name: Optional[str] = None, + outputs: Optional[list[Union[str, "_models.VoiceAgentAnimationOutputType"]]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class VoiceAgentAudioConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The audio configuration for a voice agent. These values are session defaults and may be + overridden when connecting. + + :ivar input: Input (microphone) audio configuration. + :vartype input: ~azure.ai.projects.models.VoiceAgentAudioInputConfig + :ivar output: Output (agent speech) audio configuration. + :vartype output: ~azure.ai.projects.models.VoiceAgentAudioOutputConfig + """ + + input: Optional["_models.VoiceAgentAudioInputConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Input (microphone) audio configuration.""" + output: Optional["_models.VoiceAgentAudioOutputConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Output (agent speech) audio configuration.""" + + @overload + def __init__( + self, + *, + input: Optional["_models.VoiceAgentAudioInputConfig"] = None, + output: Optional["_models.VoiceAgentAudioOutputConfig"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class VoiceAgentAudioInputConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Input audio configuration for a voice agent. + + :ivar format: The input audio format. + :vartype format: ~azure.ai.projects.models.RealtimeAudioFormats + :ivar noise_reduction: Input noise reduction. Set to null to disable. + :vartype noise_reduction: ~azure.ai.projects.models.VoiceAgentNoiseReduction + :ivar turn_detection: Turn (end-of-speech) detection. Server-side turn detection is enabled by + default; set to null to disable it, in which case the client must trigger responses manually. + :vartype turn_detection: ~azure.ai.projects.models.VoiceAgentTurnDetectionConfig + :ivar echo_cancellation: Optional server-side echo cancellation settings. + :vartype echo_cancellation: ~azure.ai.projects.models.VoiceAgentEchoCancellation + :ivar transcription: Asynchronous input-audio transcription. Set to null to disable + transcription. + :vartype transcription: ~azure.ai.projects.models.VoiceAgentInputTranscription + """ + + format: Optional["_models.RealtimeAudioFormats"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The input audio format.""" + noise_reduction: Optional["_models.VoiceAgentNoiseReduction"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The source path that created the routine attempt. Known values are: \"event_fire\", - \"manual_dispatch\", \"queued_dispatch\", \"schedule_delivery\", and \"timer_delivery\".""" - action_type: Optional[Union[str, "_models.RoutineActionType"]] = rest_field( + """Input noise reduction. Set to null to disable.""" + turn_detection: Optional["_models.VoiceAgentTurnDetectionConfig"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The action type dispatched for the routine attempt. Known values are: - \"invoke_agent_responses_api\" and \"invoke_agent_invocations_api\".""" - agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The project-scoped agent identifier recorded for the routine attempt.""" - agent_endpoint_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The legacy endpoint-scoped agent identifier recorded for the routine attempt.""" - conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The conversation identifier used by a responses API dispatch.""" - session_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The hosted-agent session identifier used by an invocations API dispatch.""" - triggered_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The logical trigger time recorded for the routine attempt.""" - scheduled_fire_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The scheduled fire time recorded for timer and schedule deliveries.""" - started_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + """Turn (end-of-speech) detection. Server-side turn detection is enabled by default; set to null + to disable it, in which case the client must trigger responses manually.""" + echo_cancellation: Optional["_models.VoiceAgentEchoCancellation"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """The time when the underlying run started.""" - ended_at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + """Optional server-side echo cancellation settings.""" + transcription: Optional["_models.VoiceAgentInputTranscription"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """The time when the underlying run reached a terminal state.""" - dispatch_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The dispatch identifier associated with the routine attempt.""" - action_correlation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The downstream action correlation identifier, when available.""" - response_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The downstream response or invocation identifier, when available.""" - task_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The workspace task identifier linked to the routine attempt, when available.""" - error_status_code: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The downstream error status code captured for a failed attempt, when available.""" - error_type: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The fully qualified error type captured for a failed attempt, when available.""" - error_message: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The truncated failure message captured for a failed attempt, when available.""" + """Asynchronous input-audio transcription. Set to null to disable transcription.""" @overload def __init__( self, *, - status: Optional["_unions.RoutineRunStatus"] = None, - phase: Optional[Union[str, "_models.RoutineRunPhase"]] = None, - trigger_type: Optional[Union[str, "_models.RoutineTriggerType"]] = None, - trigger_name: Optional[str] = None, - trigger_event_payload: Optional[dict[str, Any]] = None, - attempt_source: Optional[Union[str, "_models.RoutineAttemptSource"]] = None, - action_type: Optional[Union[str, "_models.RoutineActionType"]] = None, - agent_id: Optional[str] = None, - agent_endpoint_id: Optional[str] = None, - conversation_id: Optional[str] = None, - session_id: Optional[str] = None, - triggered_at: Optional[datetime.datetime] = None, - scheduled_fire_at: Optional[datetime.datetime] = None, - started_at: Optional[datetime.datetime] = None, - ended_at: Optional[datetime.datetime] = None, - dispatch_id: Optional[str] = None, - action_correlation_id: Optional[str] = None, - response_id: Optional[str] = None, - task_id: Optional[str] = None, - error_status_code: Optional[int] = None, - error_type: Optional[str] = None, - error_message: Optional[str] = None, + format: Optional["_models.RealtimeAudioFormats"] = None, + noise_reduction: Optional["_models.VoiceAgentNoiseReduction"] = None, + turn_detection: Optional["_models.VoiceAgentTurnDetectionConfig"] = None, + echo_cancellation: Optional["_models.VoiceAgentEchoCancellation"] = None, + transcription: Optional["_models.VoiceAgentInputTranscription"] = None, ) -> None: ... @overload @@ -14671,61 +25040,139 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class RubricBasedEvaluatorDefinition( - EvaluatorDefinition, discriminator="rubric" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Rubric-based evaluator definition — stores dimensions produced by the generate API. Used for - both quality and safety evaluators. +class VoiceAgentAudioOutputConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Output audio configuration for a voice agent. + Provider-specific fields are selected by ``voice_type``: - :ivar init_parameters: The JSON schema (Draft 2020-12) for the evaluator's input parameters. - This includes parameters like type, properties, required. - :vartype init_parameters: dict[str, any] - :ivar data_schema: The JSON schema (Draft 2020-12) for the evaluator's input data. This - includes parameters like type, properties, required. - :vartype data_schema: dict[str, any] - :ivar metrics: List of output metrics produced by this evaluator. - :vartype metrics: dict[str, ~azure.ai.projects.models.EvaluatorMetric] - :ivar type: Required. Rubric-based evaluator definition. Stores dimensions (the scoring - blueprint) for both quality and safety evaluators. Can be created via the generate API or - manually via createVersion. - :vartype type: str or ~azure.ai.projects.models.RUBRIC - :ivar dimensions: The set of dimensions — the scoring blueprint used by the LLM judge. Quality - evaluators include a non-editable residual dimension with id 'general_quality' - (always_applicable: true); safety evaluators include 'general_policy_compliance'. Both use the - same Dimension structure. Required. - :vartype dimensions: list[~azure.ai.projects.models.Dimension] - :ivar pass_threshold: Pass/fail threshold for the aggregate rubric score, on the same - normalized 0.0-1.0 scale as the emitted ``score``. When the runtime weighted average meets or - exceeds this value, the result is ``pass``. Defaults to 0.5 (equivalent to a raw 1-5 weighted - average of 3.0). The 'any dimension scored 1 → fail' rule still applies regardless of this - threshold. - :vartype pass_threshold: float + * `openai`: `voice` and `speed`. + * `azure-standard`: `voice`, `voice_locale`, `speed`, `voice_temperature`, `custom_lexicon_url`, + `custom_text_normalization_url`, `prefer_locales`, `style`, `pitch`, and `volume`. + * `azure-custom`: all `azure-standard` fields except `style`, plus `custom_voice_endpoint_id`. + * `azure-personal`: all `azure-standard` fields except `style`, plus `personal_voice_model`. + * `avatar-voice-sync`: all `azure-standard` fields except `voice` and `style`, plus `personal_voice_model`; the + voice name is derived from the avatar. + * `azure-realtime-native`: `voice` and `speed`. `format` and `output_audio_timestamp_types` apply to every voice + type. + + :ivar format: The output audio format. Applies to every ``voice_type`` and defaults to 24 kHz + PCM. + :vartype format: ~azure.ai.projects.models.RealtimeAudioFormats + :ivar voice: The voice name or identifier. Applies to ``openai``, ``azure-standard``, + ``azure-custom``, ``azure-personal``, and ``azure-realtime-native``. It does not apply to + ``avatar-voice-sync``, which derives the voice name from the avatar. + :vartype voice: str + :ivar voice_type: The voice implementation. Known values are: "openai", "azure-standard", + "azure-custom", "azure-personal", "avatar-voice-sync", and "azure-realtime-native". + :vartype voice_type: str or ~azure.ai.projects.models.VoiceType + :ivar voice_locale: The enforced BCP-47 output locale. Applies to ``azure-standard``, + ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``. + :vartype voice_locale: str + :ivar speed: The numeric output speed multiplier. Applies to all known ``voice_type`` values + and defaults to 1. + :vartype speed: float + :ivar voice_temperature: The voice variation temperature. Applies to ``azure-standard``, + ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``. + :vartype voice_temperature: float + :ivar custom_lexicon_url: The URL of a custom pronunciation lexicon. Applies to + ``azure-standard``, ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``. + :vartype custom_lexicon_url: str + :ivar custom_text_normalization_url: The URL of a custom text-normalization configuration. + Applies to ``azure-standard``, ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``. + :vartype custom_text_normalization_url: str + :ivar prefer_locales: Preferred BCP-47 locales for multilingual synthesis. Applies to + ``azure-standard``, ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``. + :vartype prefer_locales: list[str] + :ivar style: The voice speaking style. Applies only when ``voice_type`` is ``azure-standard``. + :vartype style: str + :ivar pitch: The voice pitch adjustment. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``. + :vartype pitch: str + :ivar volume: The voice volume adjustment. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``. + :vartype volume: str + :ivar custom_voice_endpoint_id: The Azure custom-voice deployment endpoint identifier. Applies + only when ``voice_type`` is ``azure-custom``. + :vartype custom_voice_endpoint_id: str + :ivar personal_voice_model: The Azure personal or avatar voice model. Applies only when + ``voice_type`` is ``azure-personal`` or ``avatar-voice-sync``. + :vartype personal_voice_model: str + :ivar output_audio_timestamp_types: Timestamp kinds to include with output audio. Applies to + every ``voice_type``. + :vartype output_audio_timestamp_types: list[str or + ~azure.ai.projects.models.VoiceAgentAudioTimestampType] """ - type: Literal[EvaluatorDefinitionType.RUBRIC] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. Rubric-based evaluator definition. Stores dimensions (the scoring blueprint) for both - quality and safety evaluators. Can be created via the generate API or manually via - createVersion.""" - dimensions: list["_models.Dimension"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The set of dimensions — the scoring blueprint used by the LLM judge. Quality evaluators include - a non-editable residual dimension with id 'general_quality' (always_applicable: true); safety - evaluators include 'general_policy_compliance'. Both use the same Dimension structure. - Required.""" - pass_threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Pass/fail threshold for the aggregate rubric score, on the same normalized 0.0-1.0 scale as the - emitted ``score``. When the runtime weighted average meets or exceeds this value, the result is - ``pass``. Defaults to 0.5 (equivalent to a raw 1-5 weighted average of 3.0). The 'any dimension - scored 1 → fail' rule still applies regardless of this threshold.""" + format: Optional["_models.RealtimeAudioFormats"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The output audio format. Applies to every ``voice_type`` and defaults to 24 kHz PCM.""" + voice: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice name or identifier. Applies to ``openai``, ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``azure-realtime-native``. It does not apply to ``avatar-voice-sync``, + which derives the voice name from the avatar.""" + voice_type: Optional[Union[str, "_models.VoiceType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The voice implementation. Known values are: \"openai\", \"azure-standard\", \"azure-custom\", + \"azure-personal\", \"avatar-voice-sync\", and \"azure-realtime-native\".""" + voice_locale: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The enforced BCP-47 output locale. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``.""" + speed: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The numeric output speed multiplier. Applies to all known ``voice_type`` values and defaults to + 1.""" + voice_temperature: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice variation temperature. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``.""" + custom_lexicon_url: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The URL of a custom pronunciation lexicon. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``.""" + custom_text_normalization_url: Optional[str] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The URL of a custom text-normalization configuration. Applies to ``azure-standard``, + ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``.""" + prefer_locales: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Preferred BCP-47 locales for multilingual synthesis. Applies to ``azure-standard``, + ``azure-custom``, ``azure-personal``, and ``avatar-voice-sync``.""" + style: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice speaking style. Applies only when ``voice_type`` is ``azure-standard``.""" + pitch: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice pitch adjustment. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``.""" + volume: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice volume adjustment. Applies to ``azure-standard``, ``azure-custom``, + ``azure-personal``, and ``avatar-voice-sync``.""" + custom_voice_endpoint_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Azure custom-voice deployment endpoint identifier. Applies only when ``voice_type`` is + ``azure-custom``.""" + personal_voice_model: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Azure personal or avatar voice model. Applies only when ``voice_type`` is + ``azure-personal`` or ``avatar-voice-sync``.""" + output_audio_timestamp_types: Optional[list[Union[str, "_models.VoiceAgentAudioTimestampType"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Timestamp kinds to include with output audio. Applies to every ``voice_type``.""" @overload def __init__( self, *, - dimensions: list["_models.Dimension"], - init_parameters: Optional[dict[str, Any]] = None, - data_schema: Optional[dict[str, Any]] = None, - metrics: Optional[dict[str, "_models.EvaluatorMetric"]] = None, - pass_threshold: Optional[float] = None, + format: Optional["_models.RealtimeAudioFormats"] = None, + voice: Optional[str] = None, + voice_type: Optional[Union[str, "_models.VoiceType"]] = None, + voice_locale: Optional[str] = None, + speed: Optional[float] = None, + voice_temperature: Optional[float] = None, + custom_lexicon_url: Optional[str] = None, + custom_text_normalization_url: Optional[str] = None, + prefer_locales: Optional[list[str]] = None, + style: Optional[str] = None, + pitch: Optional[str] = None, + volume: Optional[str] = None, + custom_voice_endpoint_id: Optional[str] = None, + personal_voice_model: Optional[str] = None, + output_audio_timestamp_types: Optional[list[Union[str, "_models.VoiceAgentAudioTimestampType"]]] = None, ) -> None: ... @overload @@ -14737,66 +25184,74 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = EvaluatorDefinitionType.RUBRIC # type: ignore -class RubricGenerationInputQualityWarning(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A non-fatal advisory produced during rubric evaluator generation when resolved inputs are - technically valid but likely too weak to produce a high-quality rubric. Read-only; - service-generated. Persisted with the terminal EvaluatorGenerationJob. +class VoiceAgentAvatarConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Avatar configuration for a voice agent. These values are session defaults and may be overridden + when connecting. - :ivar code: Stable searchable machine-readable warning code. Required. Known values are: - "empty_prompt", "short_prompt", "empty_agent_instructions", "short_agent_instructions", - "empty_dataset_content", "short_dataset_content", "low_trace_count", and - "insufficient_total_input". - :vartype code: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningCode - :ivar severity: Advisory severity. Initial values: ``warning``. Required. "warning" - :vartype severity: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningSeverity - :ivar message: Human-readable message suitable for direct SDK/CLI/UI display. Must not include - raw prompt, instruction, dataset, or trace text. Required. - :vartype message: str - :ivar source: Which source category the warning applies to. ``aggregate`` is used only for - cross-source warnings. Required. Known values are: "prompt", "agent", "dataset", and - "aggregate". - :vartype source: str or ~azure.ai.projects.models.RubricGenerationInputQualityWarningSource - :ivar source_index: Zero-based index into ``EvaluatorGenerationJob.inputs.sources`` when the - warning applies to a specific source. Omitted for aggregate warnings and for warnings not tied - to one source. - :vartype source_index: int + :ivar type: The avatar type. Required. Known values are: "video_avatar" and "photo_avatar". + :vartype type: str or ~azure.ai.projects.models.VoiceAgentAvatarType + :ivar character: The avatar character identifier, e.g. 'lisa'. Required. + :vartype character: str + :ivar style: The avatar style, e.g. 'casual-sitting'. + :vartype style: str + :ivar customized: Whether the avatar is a customer-customized avatar. Defaults to false. + :vartype customized: bool + :ivar output_protocol: The transport used to deliver the avatar video stream. Known values are: + "webrtc" and "websocket". + :vartype output_protocol: str or ~azure.ai.projects.models.VoiceAgentAvatarOutputProtocol + :ivar model: The avatar model identifier. + :vartype model: str + :ivar video: Avatar video encoder and presentation settings. + :vartype video: ~azure.ai.projects.models.VoiceAgentAvatarVideoParams + :ivar scene: Avatar placement and motion settings. + :vartype scene: ~azure.ai.projects.models.VoiceAgentAvatarScene + :ivar output_audit_audio: Whether audit audio is emitted with avatar output. Defaults to false. + :vartype output_audit_audio: bool """ - code: Union[str, "_models.RubricGenerationInputQualityWarningCode"] = rest_field( + type: Union[str, "_models.VoiceAgentAvatarType"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """Stable searchable machine-readable warning code. Required. Known values are: \"empty_prompt\", - \"short_prompt\", \"empty_agent_instructions\", \"short_agent_instructions\", - \"empty_dataset_content\", \"short_dataset_content\", \"low_trace_count\", and - \"insufficient_total_input\".""" - severity: Union[str, "_models.RubricGenerationInputQualityWarningSeverity"] = rest_field( + """The avatar type. Required. Known values are: \"video_avatar\" and \"photo_avatar\".""" + character: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The avatar character identifier, e.g. 'lisa'. Required.""" + style: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The avatar style, e.g. 'casual-sitting'.""" + customized: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the avatar is a customer-customized avatar. Defaults to false.""" + output_protocol: Optional[Union[str, "_models.VoiceAgentAvatarOutputProtocol"]] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """Advisory severity. Initial values: ``warning``. Required. \"warning\"""" - message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Human-readable message suitable for direct SDK/CLI/UI display. Must not include raw prompt, - instruction, dataset, or trace text. Required.""" - source: Union[str, "_models.RubricGenerationInputQualityWarningSource"] = rest_field( + """The transport used to deliver the avatar video stream. Known values are: \"webrtc\" and + \"websocket\".""" + model: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The avatar model identifier.""" + video: Optional["_models.VoiceAgentAvatarVideoParams"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """Which source category the warning applies to. ``aggregate`` is used only for cross-source - warnings. Required. Known values are: \"prompt\", \"agent\", \"dataset\", and \"aggregate\".""" - source_index: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Zero-based index into ``EvaluatorGenerationJob.inputs.sources`` when the warning applies to a - specific source. Omitted for aggregate warnings and for warnings not tied to one source.""" + """Avatar video encoder and presentation settings.""" + scene: Optional["_models.VoiceAgentAvatarScene"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Avatar placement and motion settings.""" + output_audit_audio: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether audit audio is emitted with avatar output. Defaults to false.""" @overload def __init__( self, *, - code: Union[str, "_models.RubricGenerationInputQualityWarningCode"], - severity: Union[str, "_models.RubricGenerationInputQualityWarningSeverity"], - message: str, - source: Union[str, "_models.RubricGenerationInputQualityWarningSource"], - source_index: Optional[int] = None, + type: Union[str, "_models.VoiceAgentAvatarType"], + character: str, + style: Optional[str] = None, + customized: Optional[bool] = None, + output_protocol: Optional[Union[str, "_models.VoiceAgentAvatarOutputProtocol"]] = None, + model: Optional[str] = None, + video: Optional["_models.VoiceAgentAvatarVideoParams"] = None, + scene: Optional["_models.VoiceAgentAvatarScene"] = None, + output_audit_audio: Optional[bool] = None, ) -> None: ... @overload @@ -14810,23 +25265,29 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SASCredentials(BaseCredentials, discriminator="SAS"): - """Shared Access Signature (SAS) credential definition. +class VoiceAgentAvatarIceServer(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An ICE server used for avatar WebRTC negotiation. - :ivar type: The credential type. Required. Shared Access Signature (SAS) credential. - :vartype type: str or ~azure.ai.projects.models.SAS - :ivar sas_token: SAS token. - :vartype sas_token: str + :ivar urls: Required. + :vartype urls: list[str] + :ivar username: + :vartype username: str + :ivar credential: + :vartype credential: str """ - type: Literal[CredentialType.SAS] = rest_discriminator(name="type", visibility=["read"]) # type: ignore - """The credential type. Required. Shared Access Signature (SAS) credential.""" - sas_token: Optional[str] = rest_field(name="SAS", visibility=["read"]) - """SAS token.""" + urls: list[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + username: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + credential: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, + *, + urls: list[str], + username: Optional[str] = None, + credential: Optional[str] = None, ) -> None: ... @overload @@ -14838,74 +25299,46 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = CredentialType.SAS # type: ignore -class Schedule(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Schedule model. +class VoiceAgentAvatarScene(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Avatar placement and motion settings. - :ivar schedule_id: Identifier of the schedule. Required. - :vartype schedule_id: str - :ivar display_name: Name of the schedule. - :vartype display_name: str - :ivar description: Description of the schedule. - :vartype description: str - :ivar enabled: Enabled status of the schedule. Required. - :vartype enabled: bool - :ivar provisioning_status: Provisioning status of the schedule. Known values are: "Creating", - "Updating", "Deleting", "Succeeded", and "Failed". - :vartype provisioning_status: str or ~azure.ai.projects.models.ScheduleProvisioningStatus - :ivar trigger: Trigger for the schedule. Required. - :vartype trigger: ~azure.ai.projects.models.Trigger - :ivar task: Task for the schedule. Required. - :vartype task: ~azure.ai.projects.models.ScheduleTask - :ivar tags: Schedule's tags. Unlike properties, tags are fully mutable. - :vartype tags: dict[str, str] - :ivar properties: Schedule's properties. Unlike tags, properties are add-only. Once added, a - property cannot be removed. - :vartype properties: dict[str, str] - :ivar system_data: System metadata for the resource. Required. - :vartype system_data: dict[str, str] + :ivar zoom: + :vartype zoom: float + :ivar position_x: + :vartype position_x: float + :ivar position_y: + :vartype position_y: float + :ivar rotation_x: + :vartype rotation_x: float + :ivar rotation_y: + :vartype rotation_y: float + :ivar rotation_z: + :vartype rotation_z: float + :ivar amplitude: + :vartype amplitude: float """ - schedule_id: str = rest_field(name="id", visibility=["read"]) - """Identifier of the schedule. Required.""" - display_name: Optional[str] = rest_field( - name="displayName", visibility=["read", "create", "update", "delete", "query"] - ) - """Name of the schedule.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Description of the schedule.""" - enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Enabled status of the schedule. Required.""" - provisioning_status: Optional[Union[str, "_models.ScheduleProvisioningStatus"]] = rest_field( - name="provisioningStatus", visibility=["read"] - ) - """Provisioning status of the schedule. Known values are: \"Creating\", \"Updating\", - \"Deleting\", \"Succeeded\", and \"Failed\".""" - trigger: "_models.Trigger" = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Trigger for the schedule. Required.""" - task: "_models.ScheduleTask" = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Task for the schedule. Required.""" - tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Schedule's tags. Unlike properties, tags are fully mutable.""" - properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Schedule's properties. Unlike tags, properties are add-only. Once added, a property cannot be - removed.""" - system_data: dict[str, str] = rest_field(name="systemData", visibility=["read"]) - """System metadata for the resource. Required.""" + zoom: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + position_x: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + position_y: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + rotation_x: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + rotation_y: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + rotation_z: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + amplitude: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, - *, - enabled: bool, - trigger: "_models.Trigger", - task: "_models.ScheduleTask", - display_name: Optional[str] = None, - description: Optional[str] = None, - tags: Optional[dict[str, str]] = None, - properties: Optional[dict[str, str]] = None, + *, + zoom: Optional[float] = None, + position_x: Optional[float] = None, + position_y: Optional[float] = None, + rotation_x: Optional[float] = None, + rotation_y: Optional[float] = None, + rotation_z: Optional[float] = None, + amplitude: Optional[float] = None, ) -> None: ... @overload @@ -14919,34 +25352,24 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class ScheduleRoutineTrigger( - RoutineTrigger, discriminator="schedule" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A recurring cron-based routine trigger. +class VoiceAgentAvatarVideoBackground(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The avatar video background. - :ivar type: The trigger type. Required. A recurring cron-based trigger. - :vartype type: str or ~azure.ai.projects.models.SCHEDULE - :ivar cron_expression: A 5-field cron expression. The service enforces a minimum interval of - five minutes by default. Required. - :vartype cron_expression: str - :ivar time_zone: An IANA or Windows time zone identifier for the schedule. Required. - :vartype time_zone: str + :ivar image_url: + :vartype image_url: str + :ivar color: + :vartype color: str """ - type: Literal[RoutineTriggerType.SCHEDULE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The trigger type. Required. A recurring cron-based trigger.""" - cron_expression: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A 5-field cron expression. The service enforces a minimum interval of five minutes by default. - Required.""" - time_zone: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """An IANA or Windows time zone identifier for the schedule. Required.""" + image_url: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + color: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, *, - cron_expression: str, - time_zone: str, + image_url: Optional[str] = None, + color: Optional[str] = None, ) -> None: ... @overload @@ -14958,47 +25381,28 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = RoutineTriggerType.SCHEDULE # type: ignore -class ScheduleRun(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Schedule run model. +class VoiceAgentAvatarVideoCrop(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The rectangular crop applied to avatar video. - :ivar run_id: Identifier of the schedule run. Required. - :vartype run_id: str - :ivar schedule_id: Identifier of the schedule. Required. - :vartype schedule_id: str - :ivar success: Trigger success status of the schedule run. Required. - :vartype success: bool - :ivar trigger_time: Trigger time of the schedule run. - :vartype trigger_time: ~datetime.datetime - :ivar error: Error information for the schedule run. - :vartype error: str - :ivar properties: Properties of the schedule run. Required. - :vartype properties: dict[str, str] + :ivar bottom_right: Required. + :vartype bottom_right: list[int] + :ivar top_left: Required. + :vartype top_left: list[int] """ - run_id: str = rest_field(name="id", visibility=["read"]) - """Identifier of the schedule run. Required.""" - schedule_id: str = rest_field(name="scheduleId", visibility=["read", "create", "update", "delete", "query"]) - """Identifier of the schedule. Required.""" - success: bool = rest_field(visibility=["read"]) - """Trigger success status of the schedule run. Required.""" - trigger_time: Optional[datetime.datetime] = rest_field( - name="triggerTime", visibility=["read", "create", "update", "delete", "query"], format="rfc3339" - ) - """Trigger time of the schedule run.""" - error: Optional[str] = rest_field(visibility=["read"]) - """Error information for the schedule run.""" - properties: dict[str, str] = rest_field(visibility=["read"]) - """Properties of the schedule run. Required.""" + bottom_right: list[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + top_left: list[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - schedule_id: str, - trigger_time: Optional[datetime.datetime] = None, + bottom_right: list[int], + top_left: list[int], ) -> None: ... @overload @@ -15012,26 +25416,43 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SessionConfiguration(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Session defaults applied to sessions created for a hosted agent version. +class VoiceAgentAvatarVideoParams(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Avatar video encoder and presentation settings. - :ivar idle_timeout_seconds: The idle duration, in seconds, before a session's sandbox is - suspended. Optional — when unset, the server default of 900 seconds is used. Must be between - 120 and 3600 seconds (inclusive). - :vartype idle_timeout_seconds: ~datetime.timedelta + :ivar bitrate: The target video bitrate in bits per second. + :vartype bitrate: int + :ivar crop: + :vartype crop: ~azure.ai.projects.models.VoiceAgentAvatarVideoCrop + :ivar resolution: + :vartype resolution: ~azure.ai.projects.models.VoiceAgentAvatarVideoResolution + :ivar background: + :vartype background: ~azure.ai.projects.models.VoiceAgentAvatarVideoBackground + :ivar gop_size: + :vartype gop_size: int """ - idle_timeout_seconds: Optional[datetime.timedelta] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + bitrate: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The target video bitrate in bits per second.""" + crop: Optional["_models.VoiceAgentAvatarVideoCrop"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """The idle duration, in seconds, before a session's sandbox is suspended. Optional — when unset, - the server default of 900 seconds is used. Must be between 120 and 3600 seconds (inclusive).""" + resolution: Optional["_models.VoiceAgentAvatarVideoResolution"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + background: Optional["_models.VoiceAgentAvatarVideoBackground"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + gop_size: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, *, - idle_timeout_seconds: Optional[datetime.timedelta] = None, + bitrate: Optional[int] = None, + crop: Optional["_models.VoiceAgentAvatarVideoCrop"] = None, + resolution: Optional["_models.VoiceAgentAvatarVideoResolution"] = None, + background: Optional["_models.VoiceAgentAvatarVideoBackground"] = None, + gop_size: Optional[int] = None, ) -> None: ... @overload @@ -15045,38 +25466,26 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SessionDirectoryEntry(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A single entry in a directory listing. +class VoiceAgentAvatarVideoResolution(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The avatar video resolution. - :ivar name: The name of the file or directory. Required. - :vartype name: str - :ivar size: The size in bytes (0 for directories). Required. - :vartype size: int - :ivar is_directory: Whether this entry is a directory. Required. - :vartype is_directory: bool - :ivar modified_time: The Unix timestamp (in seconds) when the file was last modified. Required. - :vartype modified_time: ~datetime.datetime + :ivar width: Required. + :vartype width: int + :ivar height: Required. + :vartype height: int """ - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the file or directory. Required.""" - size: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The size in bytes (0 for directories). Required.""" - is_directory: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Whether this entry is a directory. Required.""" - modified_time: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The Unix timestamp (in seconds) when the file was last modified. Required.""" + width: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + height: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - name: str, - size: int, - is_directory: bool, - modified_time: datetime.datetime, + width: int, + height: int, ) -> None: ... @overload @@ -15090,27 +25499,36 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SessionFileWriteResult(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Response from uploading a file to a session sandbox. +class VoiceAgentTurnDetectionConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Turn-detection configuration for a voice agent. - :ivar path: The path where the file was written, relative to the session home directory. - Required. - :vartype path: str - :ivar bytes_written: Number of bytes written. Required. - :vartype bytes_written: int + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VoiceAgentAzureSemanticVadTurnDetection, VoiceAgentAzureSemanticVadEnTurnDetection, + VoiceAgentAzureSemanticVadMultilingualTurnDetection, VoiceAgentSemanticVadTurnDetection, + VoiceAgentServerVadTurnDetection + + :ivar type: The turn-detection strategy. Required. Known values are: "server_vad", + "semantic_vad", "azure_semantic_vad", "azure_semantic_vad_en", and + "azure_semantic_vad_multilingual". + :vartype type: str or ~azure.ai.projects.models.VoiceAgentTurnDetectionType + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool """ - path: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The path where the file was written, relative to the session home directory. Required.""" - bytes_written: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Number of bytes written. Required.""" + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The turn-detection strategy. Required. Known values are: \"server_vad\", \"semantic_vad\", + \"azure_semantic_vad\", \"azure_semantic_vad_en\", and \"azure_semantic_vad_multilingual\".""" + auto_truncate: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the input audio buffer is truncated automatically when speech stops.""" @overload def __init__( self, *, - path: str, - bytes_written: int, + type: str, + auto_truncate: Optional[bool] = None, ) -> None: ... @overload @@ -15124,51 +25542,181 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SessionLogEvent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A single Server-Sent Event frame emitted by the hosted agent session log stream. - - Each frame contains an ``event`` field identifying the event type and a ``data`` - field carrying the payload as plain text. Although the current ``data`` payload - is JSON-formatted, its schema is not contractual — additional keys may appear - and the format may change over time. Clients should treat ``data`` as an - opaque string and optionally attempt JSON parsing. - - New event types may be added in the future. Clients should gracefully - ignore unrecognized event types. - - Wire format: +class VoiceAgentAzureSemanticVadEnTurnDetection( + VoiceAgentTurnDetectionConfig, discriminator="azure_semantic_vad_en" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """English-optimized Azure semantic voice activity detection. + + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + :ivar type: Required. English-optimized Azure semantic voice activity detection. + :vartype type: str or ~azure.ai.projects.models.AZURE_SEMANTIC_VAD_EN + :ivar threshold: Activation threshold for voice activity detection, from 0 to 1. + :vartype threshold: float + :ivar prefix_padding_ms: Audio to include before detected speech, in milliseconds. + :vartype prefix_padding_ms: ~datetime.timedelta + :ivar silence_duration_ms: Silence required to end speech detection, in milliseconds. + :vartype silence_duration_ms: ~datetime.timedelta + :ivar idle_timeout_ms: Maximum idle time before the detector ends the turn, in milliseconds. + :vartype idle_timeout_ms: ~datetime.timedelta + :ivar end_of_utterance_detection: Semantic end-of-utterance detection configuration. Set to + null to disable it. + :vartype end_of_utterance_detection: + ~azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection + :ivar speech_duration_ms: Minimum speech duration required to trigger detection, in + milliseconds. + :vartype speech_duration_ms: ~datetime.timedelta + :ivar remove_filler_words: Whether filler words are removed from transcription. + :vartype remove_filler_words: bool + :ivar create_response: Whether a response is created automatically when speech stops. + :vartype create_response: bool + :ivar interrupt_response: Whether user speech may interrupt the agent's response. + :vartype interrupt_response: bool + """ + + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_EN] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. English-optimized Azure semantic voice activity detection.""" + threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Activation threshold for voice activity detection, from 0 to 1.""" + prefix_padding_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Audio to include before detected speech, in milliseconds.""" + silence_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Silence required to end speech detection, in milliseconds.""" + idle_timeout_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Maximum idle time before the detector ends the turn, in milliseconds.""" + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Semantic end-of-utterance detection configuration. Set to null to disable it.""" + speech_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Minimum speech duration required to trigger detection, in milliseconds.""" + remove_filler_words: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether filler words are removed from transcription.""" + create_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether a response is created automatically when speech stops.""" + interrupt_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether user speech may interrupt the agent's response.""" - .. code-block:: + @overload + def __init__( + self, + *, + auto_truncate: Optional[bool] = None, + threshold: Optional[float] = None, + prefix_padding_ms: Optional[datetime.timedelta] = None, + silence_duration_ms: Optional[datetime.timedelta] = None, + idle_timeout_ms: Optional[datetime.timedelta] = None, + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = None, + speech_duration_ms: Optional[datetime.timedelta] = None, + remove_filler_words: Optional[bool] = None, + create_response: Optional[bool] = None, + interrupt_response: Optional[bool] = None, + ) -> None: ... - event: log - data: {"timestamp":"2026-03-10T09:33:17.121Z","stream":"stdout","message":"Starting server on port 18080"} + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ - event: log - data: {"timestamp":"2026-03-10T09:34:52.714Z","stream":"status","message":"Successfully connected to container"} + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_EN # type: ignore - :ivar event: The SSE event type. Currently ``log``, but additional event types may be added in - the future. Clients should ignore unrecognized event types. Required. "log" - :vartype event: str or ~azure.ai.projects.models.SessionLogEventType - :ivar data: The event payload as plain text. Currently JSON-formatted but the schema is not - contractual and may change. Required. - :vartype data: str - """ - event: Union[str, "_models.SessionLogEventType"] = rest_field( +class VoiceAgentAzureSemanticVadMultilingualTurnDetection( + VoiceAgentTurnDetectionConfig, discriminator="azure_semantic_vad_multilingual" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """Multilingual Azure semantic voice activity detection. + + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + :ivar type: Required. Multilingual Azure semantic voice activity detection. + :vartype type: str or ~azure.ai.projects.models.AZURE_SEMANTIC_VAD_MULTILINGUAL + :ivar threshold: Activation threshold for voice activity detection, from 0 to 1. + :vartype threshold: float + :ivar prefix_padding_ms: Audio to include before detected speech, in milliseconds. + :vartype prefix_padding_ms: ~datetime.timedelta + :ivar silence_duration_ms: Silence required to end speech detection, in milliseconds. + :vartype silence_duration_ms: ~datetime.timedelta + :ivar idle_timeout_ms: Maximum idle time before the detector ends the turn, in milliseconds. + :vartype idle_timeout_ms: ~datetime.timedelta + :ivar end_of_utterance_detection: Semantic end-of-utterance detection configuration. Set to + null to disable it. + :vartype end_of_utterance_detection: + ~azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection + :ivar speech_duration_ms: Minimum speech duration required to trigger detection, in + milliseconds. + :vartype speech_duration_ms: ~datetime.timedelta + :ivar remove_filler_words: Whether filler words are removed from transcription. + :vartype remove_filler_words: bool + :ivar create_response: Whether a response is created automatically when speech stops. + :vartype create_response: bool + :ivar interrupt_response: Whether user speech may interrupt the agent's response. + :vartype interrupt_response: bool + :ivar languages: BCP-47 language codes used for speech detection. + :vartype languages: list[str] + """ + + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_MULTILINGUAL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Multilingual Azure semantic voice activity detection.""" + threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Activation threshold for voice activity detection, from 0 to 1.""" + prefix_padding_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Audio to include before detected speech, in milliseconds.""" + silence_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Silence required to end speech detection, in milliseconds.""" + idle_timeout_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Maximum idle time before the detector ends the turn, in milliseconds.""" + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The SSE event type. Currently ``log``, but additional event types may be added in the future. - Clients should ignore unrecognized event types. Required. \"log\"""" - data: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The event payload as plain text. Currently JSON-formatted but the schema is not contractual and - may change. Required.""" + """Semantic end-of-utterance detection configuration. Set to null to disable it.""" + speech_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Minimum speech duration required to trigger detection, in milliseconds.""" + remove_filler_words: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether filler words are removed from transcription.""" + create_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether a response is created automatically when speech stops.""" + interrupt_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether user speech may interrupt the agent's response.""" + languages: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """BCP-47 language codes used for speech detection.""" @overload def __init__( self, *, - event: Union[str, "_models.SessionLogEventType"], - data: str, + auto_truncate: Optional[bool] = None, + threshold: Optional[float] = None, + prefix_padding_ms: Optional[datetime.timedelta] = None, + silence_duration_ms: Optional[datetime.timedelta] = None, + idle_timeout_ms: Optional[datetime.timedelta] = None, + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = None, + speech_duration_ms: Optional[datetime.timedelta] = None, + remove_filler_words: Optional[bool] = None, + create_response: Optional[bool] = None, + interrupt_response: Optional[bool] = None, + languages: Optional[list[str]] = None, ) -> None: ... @overload @@ -15180,27 +25728,92 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD_MULTILINGUAL # type: ignore -class SharepointGroundingToolParameters(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """The sharepoint grounding tool parameters. - - :ivar project_connections: The project connections attached to this tool. There can be a - maximum of 1 connection resource attached to the tool. - :vartype project_connections: list[~azure.ai.projects.models.ToolProjectConnection] - """ - - project_connections: Optional[list["_models.ToolProjectConnection"]] = rest_field( +class VoiceAgentAzureSemanticVadTurnDetection( + VoiceAgentTurnDetectionConfig, discriminator="azure_semantic_vad" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Azure semantic voice activity detection. + + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + :ivar type: Required. Azure semantic voice activity detection. + :vartype type: str or ~azure.ai.projects.models.AZURE_SEMANTIC_VAD + :ivar threshold: Activation threshold for voice activity detection, from 0 to 1. + :vartype threshold: float + :ivar prefix_padding_ms: Audio to include before detected speech, in milliseconds. + :vartype prefix_padding_ms: ~datetime.timedelta + :ivar silence_duration_ms: Silence required to end speech detection, in milliseconds. + :vartype silence_duration_ms: ~datetime.timedelta + :ivar idle_timeout_ms: Maximum idle time before the detector ends the turn, in milliseconds. + :vartype idle_timeout_ms: ~datetime.timedelta + :ivar end_of_utterance_detection: Semantic end-of-utterance detection configuration. Set to + null to disable it. + :vartype end_of_utterance_detection: + ~azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection + :ivar speech_duration_ms: Minimum speech duration required to trigger detection, in + milliseconds. + :vartype speech_duration_ms: ~datetime.timedelta + :ivar remove_filler_words: Whether filler words are removed from transcription. + :vartype remove_filler_words: bool + :ivar create_response: Whether a response is created automatically when speech stops. + :vartype create_response: bool + :ivar interrupt_response: Whether user speech may interrupt the agent's response. + :vartype interrupt_response: bool + :ivar languages: BCP-47 language codes used for speech detection. + :vartype languages: list[str] + """ + + type: Literal[VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Azure semantic voice activity detection.""" + threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Activation threshold for voice activity detection, from 0 to 1.""" + prefix_padding_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Audio to include before detected speech, in milliseconds.""" + silence_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Silence required to end speech detection, in milliseconds.""" + idle_timeout_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Maximum idle time before the detector ends the turn, in milliseconds.""" + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The project connections attached to this tool. There can be a maximum of 1 connection resource - attached to the tool.""" + """Semantic end-of-utterance detection configuration. Set to null to disable it.""" + speech_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Minimum speech duration required to trigger detection, in milliseconds.""" + remove_filler_words: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether filler words are removed from transcription.""" + create_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether a response is created automatically when speech stops.""" + interrupt_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether user speech may interrupt the agent's response.""" + languages: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """BCP-47 language codes used for speech detection.""" @overload def __init__( self, *, - project_connections: Optional[list["_models.ToolProjectConnection"]] = None, + auto_truncate: Optional[bool] = None, + threshold: Optional[float] = None, + prefix_padding_ms: Optional[datetime.timedelta] = None, + silence_duration_ms: Optional[datetime.timedelta] = None, + idle_timeout_ms: Optional[datetime.timedelta] = None, + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = None, + speech_duration_ms: Optional[datetime.timedelta] = None, + remove_filler_words: Optional[bool] = None, + create_response: Optional[bool] = None, + interrupt_response: Optional[bool] = None, + languages: Optional[list[str]] = None, ) -> None: ... @overload @@ -15212,34 +25825,44 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = VoiceAgentTurnDetectionType.AZURE_SEMANTIC_VAD # type: ignore -class SharepointPreviewTool( - Tool, discriminator="sharepoint_grounding_preview" +class VoiceAgentClientEventRtcCallSdpCreate( + RealtimeClientEvent, discriminator="rtc.call.sdp.create" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """The input definition information for a sharepoint tool as used to configure an agent. - - :ivar type: The object type, which is always 'sharepoint_grounding_preview'. Required. - SHAREPOINT_GROUNDING_PREVIEW. - :vartype type: str or ~azure.ai.projects.models.SHAREPOINT_GROUNDING_PREVIEW - :ivar sharepoint_grounding_preview: The sharepoint grounding tool parameters. Required. - :vartype sharepoint_grounding_preview: - ~azure.ai.projects.models.SharepointGroundingToolParameters - """ - - type: Literal[ToolType.SHAREPOINT_GROUNDING_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The object type, which is always 'sharepoint_grounding_preview'. Required. - SHAREPOINT_GROUNDING_PREVIEW.""" - sharepoint_grounding_preview: "_models.SharepointGroundingToolParameters" = rest_field( + """The ``rtc.call.sdp.create`` client event: begins WebRTC signaling with an SDP offer. + + :ivar type: The event type. Always ``rtc.call.sdp.create``. Required. RTC_CALL_SDP_CREATE. + :vartype type: str or ~azure.ai.projects.models.RTC_CALL_SDP_CREATE + :ivar event_id: An optional client-generated event identifier. + :vartype event_id: str + :ivar sdp_offer: The client's SDP offer for the WebRTC connection. Required. + :vartype sdp_offer: str + :ivar session: Optional session configuration. For an ``/agents`` endpoint the service rebuilds + it authoritatively from the persisted agent definition. + :vartype session: ~azure.ai.projects.models.VoiceAgentSessionUpdateConfig + """ + + type: Literal[RealtimeClientEventType.RTC_CALL_SDP_CREATE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``rtc.call.sdp.create``. Required. RTC_CALL_SDP_CREATE.""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional client-generated event identifier.""" + sdp_offer: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The client's SDP offer for the WebRTC connection. Required.""" + session: Optional["_models.VoiceAgentSessionUpdateConfig"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The sharepoint grounding tool parameters. Required.""" + """Optional session configuration. For an ``/agents`` endpoint the service rebuilds it + authoritatively from the persisted agent definition.""" @overload def __init__( self, *, - sharepoint_grounding_preview: "_models.SharepointGroundingToolParameters", + sdp_offer: str, + event_id: Optional[str] = None, + session: Optional["_models.VoiceAgentSessionUpdateConfig"] = None, ) -> None: ... @overload @@ -15251,52 +25874,36 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolType.SHAREPOINT_GROUNDING_PREVIEW # type: ignore - - -class ShellToolboxTool( - ToolboxTool, discriminator="shell" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A shell tool stored in a toolbox. This model is additive to toolbox configuration and does not - modify the OpenAI tool contract or existing toolbox tool definitions. - - :ivar name: Optional user-defined name for this tool or configuration. - :vartype name: str - :ivar description: Optional user-defined description for this tool or configuration. - :vartype description: str - :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all - default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names - are silently ignored at runtime. - :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] - :ivar type: The type of the tool. Always ``shell``. Required. SHELL. - :vartype type: str or ~azure.ai.projects.models.SHELL - :ivar allowed_callers: - :vartype allowed_callers: list[str or ~azure.ai.projects.models.CallableToolAllowedCaller] - :ivar environment: The environment in which shell commands are executed. Specify an - automatically provisioned container or an existing container. Required. - :vartype environment: ~azure.ai.projects.models.ToolboxShellEnvironment + self.type = RealtimeClientEventType.RTC_CALL_SDP_CREATE # type: ignore + + +class VoiceAgentClientEventSessionAvatarConnect( + RealtimeClientEvent, discriminator="session.avatar.connect" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.avatar.connect`` client event. + + :ivar type: The event type. Always ``session.avatar.connect``. Required. + SESSION_AVATAR_CONNECT. + :vartype type: str or ~azure.ai.projects.models.SESSION_AVATAR_CONNECT + :ivar event_id: An optional client-generated event identifier. + :vartype event_id: str + :ivar client_sdp: The client's SDP offer for avatar media negotiation. Required. + :vartype client_sdp: str """ - type: Literal[ToolboxToolType.SHELL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the tool. Always ``shell``. Required. SHELL.""" - allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - environment: "_models.ToolboxShellEnvironment" = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The environment in which shell commands are executed. Specify an automatically provisioned - container or an existing container. Required.""" + type: Literal[RealtimeClientEventType.SESSION_AVATAR_CONNECT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``session.avatar.connect``. Required. SESSION_AVATAR_CONNECT.""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional client-generated event identifier.""" + client_sdp: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The client's SDP offer for avatar media negotiation. Required.""" @overload def __init__( self, *, - environment: "_models.ToolboxShellEnvironment", - name: Optional[str] = None, - description: Optional[str] = None, - tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, - allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = None, + client_sdp: str, + event_id: Optional[str] = None, ) -> None: ... @overload @@ -15308,44 +25915,42 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolboxToolType.SHELL # type: ignore + self.type = RealtimeClientEventType.SESSION_AVATAR_CONNECT # type: ignore -class SimpleQnADataGenerationJobOptions( - DataGenerationJobOptions, discriminator="simple_qna" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """The options for a data generation job with SimpleQnA type. +class VoiceAgentClientEventSessionUpdate(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The ``session.update`` client event. - :ivar max_samples: Maximum number of samples to generate. Required. - :vartype max_samples: int - :ivar train_split: The proportion of the generated data to be used for training when the data - is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. - :vartype train_split: float - :ivar model_options: The LLM model options. - :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions - :ivar type: The data generation job type, which is SimpleQnA for this model. Required. Simple - question and answers between user and agent. - :vartype type: str or ~azure.ai.projects.models.SIMPLE_QNA - :ivar question_types: The question types to generate. Used only for fine-tuning scenarios. - :vartype question_types: list[str or ~azure.ai.projects.models.SimpleQnAFineTuningQuestionType] + :ivar event_id: Optional client-generated ID used to identify this event. This is an arbitrary + string that a client may assign. It will be passed back if there is an error with the event, + but the corresponding ``session.updated`` event will not include it. + :vartype event_id: str + :ivar type: The event type, must be ``session.update``. Required. SESSION_UPDATE. + :vartype type: str or ~azure.ai.projects.models.SESSION_UPDATE + :ivar session: The voice-agent session settings to update. Required. Is one of the following + types: VoiceAgentSessionUpdateConfig + :vartype session: ~azure.ai.projects.models.VoiceAgentSessionUpdateConfig """ - type: Literal[DataGenerationJobType.SIMPLE_QNA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The data generation job type, which is SimpleQnA for this model. Required. Simple question and - answers between user and agent.""" - question_types: Optional[list[Union[str, "_models.SimpleQnAFineTuningQuestionType"]]] = rest_field( + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional client-generated ID used to identify this event. This is an arbitrary string that a + client may assign. It will be passed back if there is an error with the event, but the + corresponding ``session.updated`` event will not include it.""" + type: Literal[RealtimeClientEventType.SESSION_UPDATE] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """The question types to generate. Used only for fine-tuning scenarios.""" + """The event type, must be ``session.update``. Required. SESSION_UPDATE.""" + session: "_unions.VoiceAgentSessionUpdate" = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice-agent session settings to update. Required. Is one of the following types: + VoiceAgentSessionUpdateConfig""" @overload def __init__( self, *, - max_samples: int, - train_split: Optional[float] = None, - model_options: Optional["_models.DataGenerationModelOptions"] = None, - question_types: Optional[list[Union[str, "_models.SimpleQnAFineTuningQuestionType"]]] = None, + type: Literal[RealtimeClientEventType.SESSION_UPDATE], + session: "_unions.VoiceAgentSessionUpdate", + event_id: Optional[str] = None, ) -> None: ... @overload @@ -15357,39 +25962,208 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = DataGenerationJobType.SIMPLE_QNA # type: ignore -class SimulationSeedDataGenerationJobOptions( - DataGenerationJobOptions, discriminator="simulation_seed" +class VoiceAgentDefinition( + AgentDefinition, discriminator="voice" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """The options for a task generation data generation job. Use with multiturn evaluation scenarios - and with prompt, file, or agent sources. Generated dataset rows include fields such as ``id``, - ``category``, ``test_case_description``, and ``desired_num_turns``. - - :ivar max_samples: Maximum number of samples to generate. Required. - :vartype max_samples: int - :ivar train_split: The proportion of the generated data to be used for training when the data - is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. - :vartype train_split: float - :ivar model_options: The LLM model options. - :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions - :ivar type: The data generation job type, which is SimulationSeed for this model. Required. - Simulation seed for evaluation scenarios. - :vartype type: str or ~azure.ai.projects.models.SIMULATION_SEED - """ + """The voice agent definition. Its configuration (model, instructions, audio, tools, and optional + avatar) drives a managed speech-to-speech experience. Establish realtime voice sessions through + ``GET /agents/{agent_name}/endpoint/protocols/voice``. Every create or update produces a new + immutable version. - type: Literal[DataGenerationJobType.SIMULATION_SEED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The data generation job type, which is SimulationSeed for this model. Required. Simulation seed - for evaluation scenarios.""" + :ivar rai_config: Configuration for Responsible AI (RAI) content filtering and safety features. + :vartype rai_config: ~azure.ai.projects.models.RaiConfig + :ivar kind: The kind discriminator for a voice agent definition. Always ``voice``. Required. + VOICE. + :vartype kind: str or ~azure.ai.projects.models.VOICE + :ivar model_type: How the model backing this voice agent is served. Required with ``model`` for + a model-backed voice agent and omitted when ``conversation_engine`` is provided. This is + independent of the architecture (realtime or cascaded), which the service derives from the + selected model. Known values are: "managed" and "self_deployed". + :vartype model_type: str or ~azure.ai.projects.models.VoiceModelType + :ivar model: The model to use for this agent. Required with ``model_type`` for a model-backed + voice agent and omitted when ``conversation_engine`` is provided. The model must support + realtime or cascaded voice. + :vartype model: str + :ivar conversation_engine: The engine that owns conversation handling for this voice agent. + Exactly one of this property and the model-backed configuration (``model_type`` with ``model``) + must be provided. When this property is provided, ``model_type``, ``model``, ``instructions``, + ``tools``, and ``tool_choice`` must be omitted, and ``greeting.tool_choice`` cannot be + ``required``, because the engine owns the conversation logic. The initial implementation + supports a hosted-agent engine. + :vartype conversation_engine: ~azure.ai.projects.models.VoiceConversationEngine + :ivar instructions: A system (or developer) message inserted into the model's context. Supports + template substitution via ``structured_inputs``, rendered per session before the live session + starts. + :vartype instructions: str + :ivar greeting: Optional session-start greeting. Template mode speaks exact rendered text; + LLM-generated mode asks the session model to author the opening response and may use configured + tools. + :vartype greeting: ~azure.ai.projects.models.VoiceAgentGreetingConfig + :ivar audio: The audio configuration, including input and output formats, voice, turn + detection, noise reduction, and transcription. These values are session defaults; a client may + override supported fields when connecting. + :vartype audio: ~azure.ai.projects.models.VoiceAgentAudioConfig + :ivar output_modalities: The output modalities the agent produces. Defaults to ``["audio"]``. + ``animation`` and ``avatar`` are available when an avatar is configured. + :vartype output_modalities: list[str or ~azure.ai.projects.models.VoiceOutputModality] + :ivar max_output_tokens: The maximum output-token count for one response. Is either a int type + or a Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar include: Additional fields to include in service outputs. + :vartype include: list[str or ~azure.ai.projects.models.VoiceAgentSessionIncludeOption] + :ivar interim_response: Interim-response settings for latency and tool execution. + :vartype interim_response: ~azure.ai.projects.models.VoiceAgentInterimResponseConfig + :ivar avatar: Optional avatar configuration. These values are session defaults and may be + overridden when connecting. + :vartype avatar: ~azure.ai.projects.models.VoiceAgentAvatarConfig + :ivar tools: The tools the voice agent may use. Supported tool kinds are ``function`` (executed + by the client), ``mcp``, ``system`` (service-managed session controls), and ``toolbox``. + Server-side tools such as ``web_search``, ``azure_ai_search``, and ``openapi`` are provided + through a toolbox rather than declared directly. + :vartype tools: list[~azure.ai.projects.models.VoiceAgentTool] + :ivar tool_choice: How the model chooses tools for generated responses. ``none`` prevents tool + calls, ``auto`` lets the model decide, ``required`` requires at least one tool call, and a + specific function or MCP tool can be selected with an object. Defaults to ``auto``. Is one of + the following types: Literal["none"], Literal["auto"], Literal["required"], ToolChoiceFunction, + ToolChoiceMCP + :vartype tool_choice: str or str or str or ~azure.ai.projects.models.ToolChoiceFunction or + ~azure.ai.projects.models.ToolChoiceMCP + :ivar parallel_tool_calls: Whether the model may call multiple tools in parallel. + :vartype parallel_tool_calls: bool + :ivar structured_inputs: Set of structured inputs that participate in prompt template + substitution, rendered per session before the live session starts. + :vartype structured_inputs: dict[str, ~azure.ai.projects.models.StructuredInputDefinition] + :ivar subagent_config: Optional configuration for sibling Foundry text agents that this voice + agent may consult as background specialists. + :vartype subagent_config: ~azure.ai.projects.models.VoiceAgentSubagentConfig + :ivar store: Whether conversations with this agent are persisted. A single, all-or-nothing + persistence switch that defaults to ``false`` (privacy-safe: off by default). When ``true``, + Foundry persists the full conversation — the transcript/event timeline and raw audio. When + ``false``, nothing is persisted and no conversation is surfaced. There is no separate + audio-logging control; audio is persisted only as part of this switch. Latency/performance + telemetry (e.g. time-to-first-audio, inter-token latency, interruption) is observability-only + (customer trace / App Insights) and is not part of the persisted conversation content. + :vartype store: bool + """ + + kind: Literal[AgentKind.VOICE] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The kind discriminator for a voice agent definition. Always ``voice``. Required. VOICE.""" + model_type: Optional[Union[str, "_models.VoiceModelType"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """How the model backing this voice agent is served. Required with ``model`` for a model-backed + voice agent and omitted when ``conversation_engine`` is provided. This is independent of the + architecture (realtime or cascaded), which the service derives from the selected model. Known + values are: \"managed\" and \"self_deployed\".""" + model: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The model to use for this agent. Required with ``model_type`` for a model-backed voice agent + and omitted when ``conversation_engine`` is provided. The model must support realtime or + cascaded voice.""" + conversation_engine: Optional["_models.VoiceConversationEngine"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The engine that owns conversation handling for this voice agent. Exactly one of this property + and the model-backed configuration (``model_type`` with ``model``) must be provided. When this + property is provided, ``model_type``, ``model``, ``instructions``, ``tools``, and + ``tool_choice`` must be omitted, and ``greeting.tool_choice`` cannot be ``required``, because + the engine owns the conversation logic. The initial implementation supports a hosted-agent + engine.""" + instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A system (or developer) message inserted into the model's context. Supports template + substitution via ``structured_inputs``, rendered per session before the live session starts.""" + greeting: Optional["_models.VoiceAgentGreetingConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional session-start greeting. Template mode speaks exact rendered text; LLM-generated mode + asks the session model to author the opening response and may use configured tools.""" + audio: Optional["_models.VoiceAgentAudioConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio configuration, including input and output formats, voice, turn detection, noise + reduction, and transcription. These values are session defaults; a client may override + supported fields when connecting.""" + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The output modalities the agent produces. Defaults to ``[\"audio\"]``. ``animation`` and + ``avatar`` are available when an avatar is configured.""" + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The maximum output-token count for one response. Is either a int type or a Literal[\"inf\"] + type.""" + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Additional fields to include in service outputs.""" + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Interim-response settings for latency and tool execution.""" + avatar: Optional["_models.VoiceAgentAvatarConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional avatar configuration. These values are session defaults and may be overridden when + connecting.""" + tools: Optional[list["_models.VoiceAgentTool"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The tools the voice agent may use. Supported tool kinds are ``function`` (executed by the + client), ``mcp``, ``system`` (service-managed session controls), and ``toolbox``. Server-side + tools such as ``web_search``, ``azure_ai_search``, and ``openapi`` are provided through a + toolbox rather than declared directly.""" + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """How the model chooses tools for generated responses. ``none`` prevents tool calls, ``auto`` + lets the model decide, ``required`` requires at least one tool call, and a specific function or + MCP tool can be selected with an object. Defaults to ``auto``. Is one of the following types: + Literal[\"none\"], Literal[\"auto\"], Literal[\"required\"], ToolChoiceFunction, ToolChoiceMCP""" + parallel_tool_calls: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the model may call multiple tools in parallel.""" + structured_inputs: Optional[dict[str, "_models.StructuredInputDefinition"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Set of structured inputs that participate in prompt template substitution, rendered per session + before the live session starts.""" + subagent_config: Optional["_models.VoiceAgentSubagentConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Optional configuration for sibling Foundry text agents that this voice agent may consult as + background specialists.""" + store: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether conversations with this agent are persisted. A single, all-or-nothing persistence + switch that defaults to ``false`` (privacy-safe: off by default). When ``true``, Foundry + persists the full conversation — the transcript/event timeline and raw audio. When ``false``, + nothing is persisted and no conversation is surfaced. There is no separate audio-logging + control; audio is persisted only as part of this switch. Latency/performance telemetry (e.g. + time-to-first-audio, inter-token latency, interruption) is observability-only (customer trace / + App Insights) and is not part of the persisted conversation content.""" @overload def __init__( self, *, - max_samples: int, - train_split: Optional[float] = None, - model_options: Optional["_models.DataGenerationModelOptions"] = None, + rai_config: Optional["_models.RaiConfig"] = None, + model_type: Optional[Union[str, "_models.VoiceModelType"]] = None, + model: Optional[str] = None, + conversation_engine: Optional["_models.VoiceConversationEngine"] = None, + instructions: Optional[str] = None, + greeting: Optional["_models.VoiceAgentGreetingConfig"] = None, + audio: Optional["_models.VoiceAgentAudioConfig"] = None, + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = None, + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = None, + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = None, + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = None, + avatar: Optional["_models.VoiceAgentAvatarConfig"] = None, + tools: Optional[list["_models.VoiceAgentTool"]] = None, + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = None, + parallel_tool_calls: Optional[bool] = None, + structured_inputs: Optional[dict[str, "_models.StructuredInputDefinition"]] = None, + subagent_config: Optional["_models.VoiceAgentSubagentConfig"] = None, + store: Optional[bool] = None, ) -> None: ... @overload @@ -15401,52 +26175,42 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = DataGenerationJobType.SIMULATION_SEED # type: ignore - + self.kind = AgentKind.VOICE # type: ignore -class SkillDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A skill resource. - :ivar id: The unique identifier of the skill. Required. - :vartype id: str - :ivar name: The unique name of the skill. Required. - :vartype name: str - :ivar description: A human-readable description of the skill. Required. - :vartype description: str - :ivar created_at: The Unix timestamp (seconds) when the skill was created. Required. - :vartype created_at: ~datetime.datetime - :ivar default_version: The default version for the skill. Can be changed via updateSkill. - Required. - :vartype default_version: str - :ivar latest_version: The latest version for the skill. Required. - :vartype latest_version: str - """ +class VoiceAgentEchoCancellation(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Server-side echo cancellation settings for input audio. - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique identifier of the skill. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique name of the skill. Required.""" - description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of the skill. Required.""" - created_at: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + :ivar type: The echo cancellation implementation. Always ``server_echo_cancellation``. + Required. Default value is "server_echo_cancellation". + :vartype type: str + :ivar reference_source: Whether reference audio comes from server playback or a client-provided + channel. Known values are: "server" and "client". + :vartype reference_source: str or + ~azure.ai.projects.models.VoiceAgentEchoCancellationReferenceSource + :ivar channels: The number of input channels. Use two interleaved channels when + ``reference_source`` is ``client``. + :vartype channels: int + """ + + type: Literal["server_echo_cancellation"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The echo cancellation implementation. Always ``server_echo_cancellation``. Required. Default + value is \"server_echo_cancellation\".""" + reference_source: Optional[Union[str, "_models.VoiceAgentEchoCancellationReferenceSource"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """The Unix timestamp (seconds) when the skill was created. Required.""" - default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The default version for the skill. Can be changed via updateSkill. Required.""" - latest_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The latest version for the skill. Required.""" + """Whether reference audio comes from server playback or a client-provided channel. Known values + are: \"server\" and \"client\".""" + channels: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The number of input channels. Use two interleaved channels when ``reference_source`` is + ``client``.""" @overload def __init__( self, *, - id: str, # pylint: disable=redefined-builtin - name: str, - description: str, - created_at: datetime.datetime, - default_version: str, - latest_version: str, + reference_source: Optional[Union[str, "_models.VoiceAgentEchoCancellationReferenceSource"]] = None, + channels: Optional[int] = None, ) -> None: ... @overload @@ -15458,52 +26222,28 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type: Literal["server_echo_cancellation"] = "server_echo_cancellation" -class SkillInlineContent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Inline content for defining a simple skill without uploading files. Follows the agentskills.io - SKILL.md specification. +class VoiceAgentTool(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A tool usable by a voice agent. - :ivar description: A human-readable description of what the skill does and when to use it. - Required. - :vartype description: str - :ivar instructions: The skill instructions in markdown format. This is the body content of the - SKILL.md file. Required. - :vartype instructions: str - :ivar license: License name or reference to a bundled license file. - :vartype license: str - :ivar compatibility: Environment requirements or compatibility notes for the skill. - :vartype compatibility: str - :ivar metadata: Arbitrary key-value metadata for additional properties. - :vartype metadata: dict[str, str] - :ivar allowed_tools: List of pre-approved tools the skill may use. Experimental. - :vartype allowed_tools: list[str] + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VoiceAgentFunctionTool, VoiceAgentMcpTool, VoiceAgentSystemTool, VoiceAgentToolboxTool + + :ivar type: The tool kind. Required. Default value is None. + :vartype type: str """ - description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of what the skill does and when to use it. Required.""" - instructions: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The skill instructions in markdown format. This is the body content of the SKILL.md file. - Required.""" - license: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """License name or reference to a bundled license file.""" - compatibility: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Environment requirements or compatibility notes for the skill.""" - metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Arbitrary key-value metadata for additional properties.""" - allowed_tools: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """List of pre-approved tools the skill may use. Experimental.""" + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The tool kind. Required. Default value is None.""" @overload def __init__( self, *, - description: str, - instructions: str, - license: Optional[str] = None, - compatibility: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, - allowed_tools: Optional[list[str]] = None, + type: str, ) -> None: ... @overload @@ -15517,32 +26257,39 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SkillReferenceParam( - ContainerSkill, discriminator="skill_reference" +class VoiceAgentSystemTool( + VoiceAgentTool, discriminator="system" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """SkillReferenceParam. + """A service-managed control that acts on the active voice session without customer code or + external authentication. - :ivar type: References a skill created with the /v1/skills endpoint. Required. SKILL_REFERENCE. - :vartype type: str or ~azure.ai.projects.models.SKILL_REFERENCE - :ivar skill_id: The ID of the referenced skill. Required. - :vartype skill_id: str - :ivar version: Optional skill version. Use a positive integer or 'latest'. Omit for default. - :vartype version: str + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VoiceAgentEndConversationSystemTool + + :ivar type: The type of the tool. Always ``system``. Required. Default value is "system". + :vartype type: str + :ivar name: The service-managed control action. Known values are stable; additional values may + be added over time. Required. "end_conversation" + :vartype name: str or ~azure.ai.projects.models.VoiceAgentSystemToolName + :ivar description: An optional description of the system tool. + :vartype description: str """ - type: Literal[ContainerSkillType.SKILL_REFERENCE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """References a skill created with the /v1/skills endpoint. Required. SKILL_REFERENCE.""" - skill_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The ID of the referenced skill. Required.""" - version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Optional skill version. Use a positive integer or 'latest'. Omit for default.""" + __mapping__: dict[str, _Model] = {} + type: Literal["system"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``system``. Required. Default value is \"system\".""" + name: str = rest_discriminator(name="name", visibility=["read", "create", "update", "delete", "query"]) + """The service-managed control action. Known values are stable; additional values may be added + over time. Required. \"end_conversation\"""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional description of the system tool.""" @overload def __init__( self, *, - skill_id: str, - version: Optional[str] = None, + name: str, + description: Optional[str] = None, ) -> None: ... @overload @@ -15554,51 +26301,33 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ContainerSkillType.SKILL_REFERENCE # type: ignore + self.type = "system" # type: ignore -class SkillVersion(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A specific version of a skill. +class VoiceAgentEndConversationSystemTool( + VoiceAgentSystemTool, discriminator="end_conversation" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A service-managed control that ends the active conversation. - :ivar id: The unique identifier of the skill version. Required. - :vartype id: str - :ivar skill_id: The identifier of the parent skill. Required. - :vartype skill_id: str - :ivar name: The name of the skill version. Required. - :vartype name: str - :ivar version: The version identifier. Skill versions are immutable. Required. - :vartype version: str - :ivar description: A human-readable description of the skill version. Required. + :ivar type: The type of the tool. Always ``system``. Required. Default value is "system". + :vartype type: str + :ivar description: An optional description of the system tool. :vartype description: str - :ivar created_at: The Unix timestamp (seconds) when the skill version was created. Required. - :vartype created_at: ~datetime.datetime + :ivar name: The service-managed control action. Always ``end_conversation``. Required. Ends the + active conversation. + :vartype name: str or ~azure.ai.projects.models.END_CONVERSATION """ - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique identifier of the skill version. Required.""" - skill_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The identifier of the parent skill. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the skill version. Required.""" - version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The version identifier. Skill versions are immutable. Required.""" - description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of the skill version. Required.""" - created_at: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The Unix timestamp (seconds) when the skill version was created. Required.""" + __mapping__: dict[str, _Model] = {} + name: Literal[VoiceAgentSystemToolName.END_CONVERSATION] = rest_discriminator(name="name", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The service-managed control action. Always ``end_conversation``. Required. Ends the active + conversation.""" @overload def __init__( self, *, - id: str, # pylint: disable=redefined-builtin - skill_id: str, - name: str, - version: str, - description: str, - created_at: datetime.datetime, + description: Optional[str] = None, ) -> None: ... @overload @@ -15609,39 +26338,47 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: """ def __init__(self, *args: Any, **kwargs: Any) -> None: - super().__init__(*args, **kwargs) - - -class ToolChoiceParam(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """How the model should select which tool (or tools) to use when generating a response. See the - ``tools`` parameter to see how to specify which tools the model can call. + super().__init__(*args, **kwargs) + self.name = VoiceAgentSystemToolName.END_CONVERSATION # type: ignore - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - ToolChoiceAllowed, SpecificApplyPatchParam, ToolChoiceCodeInterpreter, ToolChoiceComputer, - ToolChoiceComputerUse, ToolChoiceComputerUsePreview, ToolChoiceCustom, ToolChoiceFileSearch, - ToolChoiceFunction, ToolChoiceImageGeneration, ToolChoiceMCP, - SpecificProgrammaticToolCallingParam, SpecificFunctionShellParam, ToolChoiceWebSearchPreview, - ToolChoiceWebSearchPreview20250311 - :ivar type: Required. Known values are: "allowed_tools", "function", "mcp", "custom", - "programmatic_tool_calling", "apply_patch", "shell", "file_search", "web_search_preview", - "computer_use_preview", "web_search_preview_2025_03_11", "image_generation", - "code_interpreter", "computer", and "computer_use". - :vartype type: str or ~azure.ai.projects.models.ToolChoiceParamType +class VoiceAgentEndOfUtteranceDetection(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Semantic end-of-utterance detection configuration. + + :ivar model: The semantic detection model. Required. Known values are: "semantic_detection_v1", + "semantic_detection_v1_en", "semantic_detection_v1_multilingual", and + "smart_end_of_turn_detection". + :vartype model: str or ~azure.ai.projects.models.VoiceAgentEndOfUtteranceDetectionModel + :ivar threshold_level: The sensitivity threshold. Known values are: "low", "medium", "high", + and "default". + :vartype threshold_level: str or + ~azure.ai.projects.models.VoiceAgentEndOfUtteranceThresholdLevel + :ivar timeout_ms: The detection timeout in milliseconds. + :vartype timeout_ms: ~datetime.timedelta """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """Required. Known values are: \"allowed_tools\", \"function\", \"mcp\", \"custom\", - \"programmatic_tool_calling\", \"apply_patch\", \"shell\", \"file_search\", - \"web_search_preview\", \"computer_use_preview\", \"web_search_preview_2025_03_11\", - \"image_generation\", \"code_interpreter\", \"computer\", and \"computer_use\".""" + model: Union[str, "_models.VoiceAgentEndOfUtteranceDetectionModel"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The semantic detection model. Required. Known values are: \"semantic_detection_v1\", + \"semantic_detection_v1_en\", \"semantic_detection_v1_multilingual\", and + \"smart_end_of_turn_detection\".""" + threshold_level: Optional[Union[str, "_models.VoiceAgentEndOfUtteranceThresholdLevel"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The sensitivity threshold. Known values are: \"low\", \"medium\", \"high\", and \"default\".""" + timeout_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The detection timeout in milliseconds.""" @overload def __init__( self, *, - type: str, + model: Union[str, "_models.VoiceAgentEndOfUtteranceDetectionModel"], + threshold_level: Optional[Union[str, "_models.VoiceAgentEndOfUtteranceThresholdLevel"]] = None, + timeout_ms: Optional[datetime.timedelta] = None, ) -> None: ... @overload @@ -15655,19 +26392,41 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SpecificApplyPatchParam(ToolChoiceParam, discriminator="apply_patch"): - """Specific apply patch tool choice. +class VoiceAgentFunctionTool( + VoiceAgentTool, discriminator="function" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A native function tool executed by the client. - :ivar type: The tool to call. Always ``apply_patch``. Required. APPLY_PATCH. - :vartype type: str or ~azure.ai.projects.models.APPLY_PATCH + :ivar description: The description of the function, including guidance on when and how to call + it, and guidance about what to tell the user when calling (if anything). + :vartype description: str + :ivar parameters: Parameters of the function in JSON Schema. + :vartype parameters: ~azure.ai.projects.models.RealtimeFunctionToolParameters + :ivar type: Required. Default value is "function". + :vartype type: str + :ivar name: The function name. Required. + :vartype name: str """ - type: Literal[ToolChoiceParamType.APPLY_PATCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The tool to call. Always ``apply_patch``. Required. APPLY_PATCH.""" + description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The description of the function, including guidance on when and how to call it, and guidance + about what to tell the user when calling (if anything).""" + parameters: Optional["_models.RealtimeFunctionToolParameters"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Parameters of the function in JSON Schema.""" + type: Literal["function"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"function\".""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The function name. Required.""" @overload def __init__( self, + *, + name: str, + description: Optional[str] = None, + parameters: Optional["_models.RealtimeFunctionToolParameters"] = None, ) -> None: ... @overload @@ -15679,22 +26438,28 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.APPLY_PATCH # type: ignore + self.type = "function" # type: ignore -class SpecificFunctionShellParam(ToolChoiceParam, discriminator="shell"): - """Specific shell tool choice. +class VoiceAgentGreetingConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Session-start greeting configuration for a voice agent. - :ivar type: The tool to call. Always ``shell``. Required. SHELL. - :vartype type: str or ~azure.ai.projects.models.SHELL + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VoiceAgentLlmGeneratedGreetingConfig, VoiceAgentTemplateGreetingConfig + + :ivar type: The greeting mode. Required. Default value is None. + :vartype type: str """ - type: Literal[ToolChoiceParamType.SHELL] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The tool to call. Always ``shell``. Required. SHELL.""" + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The greeting mode. Required. Default value is None.""" @overload def __init__( self, + *, + type: str, ) -> None: ... @overload @@ -15706,23 +26471,93 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.SHELL # type: ignore -class SpecificProgrammaticToolCallingParam(ToolChoiceParam, discriminator="programmatic_tool_calling"): - """SpecificProgrammaticToolCallingParam. +class VoiceAgentInputTranscription(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Asynchronous input-audio transcription configuration. Extends the OpenAI Realtime transcription + options with the Azure and MAI transcription models, custom speech models, and phrase hints. - :ivar type: The tool to call. Always ``programmatic_tool_calling``. Required. - PROGRAMMATIC_TOOL_CALLING. - :vartype type: str or ~azure.ai.projects.models.PROGRAMMATIC_TOOL_CALLING + :ivar language: The language of the input audio. Supplying the input language in `ISO-639-1 + `_ (e.g. ``en``) format will improve + accuracy and latency. + :vartype language: str + :ivar languages: Possible languages of the input audio, in `ISO-639-1 + `_ format. Supported by + ``gpt-transcribe`` and ``gpt-live-transcribe``. + :vartype languages: list[str] + :ivar keywords: Words or phrases to guide transcription of the input audio. Supported by + ``gpt-transcribe`` and ``gpt-live-transcribe``. + :vartype keywords: list[str] + :ivar prompt: An optional text to guide the model's style or continue a previous audio segment. + For ``whisper-1``, the `prompt is a list of keywords `_. + For ``gpt-4o-transcribe`` models (excluding ``gpt-4o-transcribe-diarize``), the prompt is a + free text string, for example "expect words related to technology". Prompt is not supported + with ``gpt-realtime-whisper`` in GA Realtime sessions. + :vartype prompt: str + :ivar delay: Controls how long the model waits before emitting transcription text. Higher + values can improve transcription accuracy at the cost of latency. Only supported with + ``gpt-realtime-whisper`` in GA Realtime sessions. Is one of the following types: + Literal["minimal"], Literal["low"], Literal["medium"], Literal["high"], Literal["xhigh"] + :vartype delay: str or str or str or str or str + :ivar model: The transcription model identifier. Configure customer custom speech deployments + in ``custom_speech``. Required. Known values are: "whisper-1", "gpt-realtime-whisper", + "gpt-4o-transcribe", "gpt-4o-mini-transcribe", "gpt-4o-transcribe-diarize", "gpt-transcribe", + "gpt-live-transcribe", "mai-transcribe", and "azure-speech". + :vartype model: str or ~azure.ai.projects.models.VoiceAgentInputTranscriptionModel + :ivar custom_speech: Optional customer custom speech deployment configuration, keyed by locale. + :vartype custom_speech: dict[str, str] + :ivar phrase_list: Optional phrase hints that bias recognition toward domain terms. + :vartype phrase_list: list[str] """ - type: Literal[ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The tool to call. Always ``programmatic_tool_calling``. Required. PROGRAMMATIC_TOOL_CALLING.""" + language: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The language of the input audio. Supplying the input language in `ISO-639-1 + `_ (e.g. ``en``) format will improve + accuracy and latency.""" + languages: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Possible languages of the input audio, in `ISO-639-1 + `_ format. Supported by + ``gpt-transcribe`` and ``gpt-live-transcribe``.""" + keywords: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Words or phrases to guide transcription of the input audio. Supported by ``gpt-transcribe`` and + ``gpt-live-transcribe``.""" + prompt: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional text to guide the model's style or continue a previous audio segment. For + ``whisper-1``, the `prompt is a list of keywords `_. For + ``gpt-4o-transcribe`` models (excluding ``gpt-4o-transcribe-diarize``), the prompt is a free + text string, for example \"expect words related to technology\". Prompt is not supported with + ``gpt-realtime-whisper`` in GA Realtime sessions.""" + delay: Optional[Literal["minimal", "low", "medium", "high", "xhigh"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Controls how long the model waits before emitting transcription text. Higher values can improve + transcription accuracy at the cost of latency. Only supported with ``gpt-realtime-whisper`` in + GA Realtime sessions. Is one of the following types: Literal[\"minimal\"], Literal[\"low\"], + Literal[\"medium\"], Literal[\"high\"], Literal[\"xhigh\"]""" + model: Union[str, "_models.VoiceAgentInputTranscriptionModel"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The transcription model identifier. Configure customer custom speech deployments in + ``custom_speech``. Required. Known values are: \"whisper-1\", \"gpt-realtime-whisper\", + \"gpt-4o-transcribe\", \"gpt-4o-mini-transcribe\", \"gpt-4o-transcribe-diarize\", + \"gpt-transcribe\", \"gpt-live-transcribe\", \"mai-transcribe\", and \"azure-speech\".""" + custom_speech: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional customer custom speech deployment configuration, keyed by locale.""" + phrase_list: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional phrase hints that bias recognition toward domain terms.""" @overload def __init__( self, + *, + model: Union[str, "_models.VoiceAgentInputTranscriptionModel"], + language: Optional[str] = None, + languages: Optional[list[str]] = None, + keywords: Optional[list[str]] = None, + prompt: Optional[str] = None, + delay: Optional[Literal["minimal", "low", "medium", "high", "xhigh"]] = None, + custom_speech: Optional[dict[str, str]] = None, + phrase_list: Optional[list[str]] = None, ) -> None: ... @overload @@ -15734,42 +26569,41 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.PROGRAMMATIC_TOOL_CALLING # type: ignore -class StructuredInputDefinition(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """An structured input that can participate in prompt template substitutions and tool argument - binding. +class VoiceAgentInterimResponseConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Fields shared by interim-response configurations. - :ivar description: A human-readable description of the input. - :vartype description: str - :ivar default_value: The default value for the input if no run-time value is provided. - :vartype default_value: any - :ivar schema: The JSON schema for the structured input (optional). - :vartype schema: dict[str, any] - :ivar required: Whether the input property is required when the agent is invoked. The service - defaults to ``false`` if a value is not specified by the caller. - :vartype required: bool + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VoiceAgentLlmInterimResponseConfig, VoiceAgentStaticInterimResponseConfig + + :ivar type: The interim-response implementation. Required. Default value is None. + :vartype type: str + :ivar triggers: Conditions that may trigger one interim response. + :vartype triggers: list[str or ~azure.ai.projects.models.VoiceAgentInterimResponseTrigger] + :ivar latency_threshold_ms: The latency threshold in milliseconds. + :vartype latency_threshold_ms: ~datetime.timedelta """ - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of the input.""" - default_value: Optional[Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The default value for the input if no run-time value is provided.""" - schema: Optional[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The JSON schema for the structured input (optional).""" - required: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Whether the input property is required when the agent is invoked. The service defaults to - ``false`` if a value is not specified by the caller.""" + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The interim-response implementation. Required. Default value is None.""" + triggers: Optional[list[Union[str, "_models.VoiceAgentInterimResponseTrigger"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Conditions that may trigger one interim response.""" + latency_threshold_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The latency threshold in milliseconds.""" @overload def __init__( self, *, - description: Optional[str] = None, - default_value: Optional[Any] = None, - schema: Optional[dict[str, Any]] = None, - required: Optional[bool] = None, + type: str, + triggers: Optional[list[Union[str, "_models.VoiceAgentInterimResponseTrigger"]]] = None, + latency_threshold_ms: Optional[datetime.timedelta] = None, ) -> None: ... @overload @@ -15783,38 +26617,39 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class StructuredOutputDefinition(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A structured output that can be produced by the agent. +class VoiceAgentLlmGeneratedGreetingConfig( + VoiceAgentGreetingConfig, discriminator="llm_generated" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A greeting authored by the session model from a scoped opening-turn prompt. - :ivar name: The name of the structured output. Required. - :vartype name: str - :ivar description: A description of the output to emit. Used by the model to determine when to - emit the output. Required. - :vartype description: str - :ivar schema: The JSON schema for the structured output. Required. - :vartype schema: dict[str, any] - :ivar strict: Whether to enforce strict validation. Default ``true``. Required. - :vartype strict: bool + :ivar type: Required. Default value is "llm_generated". + :vartype type: str + :ivar prompt: The Handlebars prompt that guides the opening turn. Required. + :vartype prompt: str + :ivar tool_choice: The tool-selection policy for the opening response. Defaults to ``none``. Is + one of the following types: Literal["none"], Literal["auto"], Literal["required"], + ToolChoiceFunction, ToolChoiceMCP + :vartype tool_choice: str or str or str or ~azure.ai.projects.models.ToolChoiceFunction or + ~azure.ai.projects.models.ToolChoiceMCP """ - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the structured output. Required.""" - description: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A description of the output to emit. Used by the model to determine when to emit the output. - Required.""" - schema: dict[str, Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The JSON schema for the structured output. Required.""" - strict: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Whether to enforce strict validation. Default ``true``. Required.""" + type: Literal["llm_generated"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"llm_generated\".""" + prompt: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Handlebars prompt that guides the opening turn. Required.""" + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The tool-selection policy for the opening response. Defaults to ``none``. Is one of the + following types: Literal[\"none\"], Literal[\"auto\"], Literal[\"required\"], + ToolChoiceFunction, ToolChoiceMCP""" @overload def __init__( self, *, - name: str, - description: str, - schema: dict[str, Any], - strict: bool, + prompt: str, + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = None, ) -> None: ... @overload @@ -15826,58 +26661,46 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "llm_generated" # type: ignore -class TaxonomyCategory(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Taxonomy category definition. +class VoiceAgentLlmInterimResponseConfig( + VoiceAgentInterimResponseConfig, discriminator="llm_interim_response" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """An interim response generated by a language model. - :ivar id: Unique identifier of the taxonomy category. Required. - :vartype id: str - :ivar name: Name of the taxonomy category. Required. - :vartype name: str - :ivar description: Description of the taxonomy category. - :vartype description: str - :ivar risk_category: Risk category associated with this taxonomy category. Required. Known - values are: "HateUnfairness", "Violence", "Sexual", "SelfHarm", "ProtectedMaterial", - "CodeVulnerability", "UngroundedAttributes", "ProhibitedActions", "SensitiveDataLeakage", and - "TaskAdherence". - :vartype risk_category: str or ~azure.ai.projects.models.RiskCategory - :ivar sub_categories: List of taxonomy sub categories. Required. - :vartype sub_categories: list[~azure.ai.projects.models.TaxonomySubCategory] - :ivar properties: Additional properties for the taxonomy category. - :vartype properties: dict[str, str] + :ivar triggers: Conditions that may trigger one interim response. + :vartype triggers: list[str or ~azure.ai.projects.models.VoiceAgentInterimResponseTrigger] + :ivar latency_threshold_ms: The latency threshold in milliseconds. + :vartype latency_threshold_ms: ~datetime.timedelta + :ivar type: Required. Default value is "llm_interim_response". + :vartype type: str + :ivar model: The model used to generate interim responses. + :vartype model: str + :ivar instructions: Optional instructions for generating interim responses. + :vartype instructions: str + :ivar max_completion_tokens: The maximum completion-token count for an interim response. + :vartype max_completion_tokens: int """ - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Unique identifier of the taxonomy category. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Name of the taxonomy category. Required.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Description of the taxonomy category.""" - risk_category: Union[str, "_models.RiskCategory"] = rest_field( - name="riskCategory", visibility=["read", "create", "update", "delete", "query"] - ) - """Risk category associated with this taxonomy category. Required. Known values are: - \"HateUnfairness\", \"Violence\", \"Sexual\", \"SelfHarm\", \"ProtectedMaterial\", - \"CodeVulnerability\", \"UngroundedAttributes\", \"ProhibitedActions\", - \"SensitiveDataLeakage\", and \"TaskAdherence\".""" - sub_categories: list["_models.TaxonomySubCategory"] = rest_field( - name="subCategories", visibility=["read", "create", "update", "delete", "query"] - ) - """List of taxonomy sub categories. Required.""" - properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Additional properties for the taxonomy category.""" + type: Literal["llm_interim_response"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"llm_interim_response\".""" + model: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The model used to generate interim responses.""" + instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional instructions for generating interim responses.""" + max_completion_tokens: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The maximum completion-token count for an interim response.""" @overload def __init__( self, *, - id: str, # pylint: disable=redefined-builtin - name: str, - risk_category: Union[str, "_models.RiskCategory"], - sub_categories: list["_models.TaxonomySubCategory"], - description: Optional[str] = None, - properties: Optional[dict[str, str]] = None, + triggers: Optional[list[Union[str, "_models.VoiceAgentInterimResponseTrigger"]]] = None, + latency_threshold_ms: Optional[datetime.timedelta] = None, + model: Optional[str] = None, + instructions: Optional[str] = None, + max_completion_tokens: Optional[int] = None, ) -> None: ... @overload @@ -15889,43 +26712,104 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "llm_interim_response" # type: ignore -class TaxonomySubCategory(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Taxonomy sub-category definition. +class VoiceAgentMcpTool( + VoiceAgentTool, discriminator="mcp" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """An MCP tool available to a voice agent. - :ivar id: Unique identifier of the taxonomy sub-category. Required. - :vartype id: str - :ivar name: Name of the taxonomy sub-category. Required. - :vartype name: str - :ivar description: Description of the taxonomy sub-category. - :vartype description: str - :ivar enabled: List of taxonomy items under this sub-category. Required. - :vartype enabled: bool - :ivar properties: Additional properties for the taxonomy sub-category. - :vartype properties: dict[str, str] + :ivar server_label: A label for this MCP server, used to identify it in tool calls. Required. + :vartype server_label: str + :ivar authorization: An OAuth access token that can be used with a remote MCP server, either + with a custom MCP server URL or a service connector. Your application must handle the OAuth + authorization flow and provide the token here. + :vartype authorization: str + :ivar server_description: Optional description of the MCP server, used to provide more context. + :vartype server_description: str + :ivar headers: + :vartype headers: dict[str, str] + :ivar allowed_tools: Is either a [str] type or a MCPToolFilter type. + :vartype allowed_tools: list[str] or ~azure.ai.projects.models.MCPToolFilter + :ivar allowed_callers: + :vartype allowed_callers: list[str or ~azure.ai.projects.models.CallableToolAllowedCaller] + :ivar require_approval: Is one of the following types: MCPToolRequireApproval, + Literal["always"], Literal["never"] + :vartype require_approval: ~azure.ai.projects.models.MCPToolRequireApproval or str or str + :ivar defer_loading: Whether this MCP tool is deferred and discovered via tool search. + :vartype defer_loading: bool + :ivar project_connection_id: The connection ID in the project for the MCP server. The + connection stores authentication and other connection details needed to connect to the MCP + server. + :vartype project_connection_id: str + :ivar tool_configs: Deprecated. This property is deprecated and will be removed in a future + version. + :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] + :ivar type: Required. Default value is "mcp". + :vartype type: str + :ivar server_url: The URL for the MCP server. + :vartype server_url: str + :ivar response_scheduling: When the MCP invocation creates a follow-up response. Defaults to + ``when_idle``. Known values are: "silent", "when_idle", "interrupt", and "skip_if_busy". + :vartype response_scheduling: str or ~azure.ai.projects.models.VoiceAgentToolResponseScheduling """ - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Unique identifier of the taxonomy sub-category. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Name of the taxonomy sub-category. Required.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Description of the taxonomy sub-category.""" - enabled: bool = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """List of taxonomy items under this sub-category. Required.""" - properties: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Additional properties for the taxonomy sub-category.""" + server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A label for this MCP server, used to identify it in tool calls. Required.""" + authorization: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An OAuth access token that can be used with a remote MCP server, either with a custom MCP + server URL or a service connector. Your application must handle the OAuth authorization flow + and provide the token here.""" + server_description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Optional description of the MCP server, used to provide more context.""" + headers: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + allowed_tools: Optional[Union[list[str], "_models.MCPToolFilter"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Is either a [str] type or a MCPToolFilter type.""" + allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + require_approval: Optional[Union["_models.MCPToolRequireApproval", Literal["always"], Literal["never"]]] = ( + rest_field(visibility=["read", "create", "update", "delete", "query"]) + ) + """Is one of the following types: MCPToolRequireApproval, Literal[\"always\"], Literal[\"never\"]""" + defer_loading: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether this MCP tool is deferred and discovered via tool search.""" + project_connection_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The connection ID in the project for the MCP server. The connection stores authentication and + other connection details needed to connect to the MCP server.""" + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Deprecated. This property is deprecated and will be removed in a future version.""" + type: Literal["mcp"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"mcp\".""" + server_url: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The URL for the MCP server.""" + response_scheduling: Optional[Union[str, "_models.VoiceAgentToolResponseScheduling"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """When the MCP invocation creates a follow-up response. Defaults to ``when_idle``. Known values + are: \"silent\", \"when_idle\", \"interrupt\", and \"skip_if_busy\".""" @overload def __init__( self, *, - id: str, # pylint: disable=redefined-builtin - name: str, - enabled: bool, - description: Optional[str] = None, - properties: Optional[dict[str, str]] = None, + server_label: str, + authorization: Optional[str] = None, + server_description: Optional[str] = None, + headers: Optional[dict[str, str]] = None, + allowed_tools: Optional[Union[list[str], "_models.MCPToolFilter"]] = None, + allowed_callers: Optional[list[Union[str, "_models.CallableToolAllowedCaller"]]] = None, + require_approval: Optional[Union["_models.MCPToolRequireApproval", Literal["always"], Literal["never"]]] = None, + defer_loading: Optional[bool] = None, + project_connection_id: Optional[str] = None, + tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + server_url: Optional[str] = None, + response_scheduling: Optional[Union[str, "_models.VoiceAgentToolResponseScheduling"]] = None, ) -> None: ... @overload @@ -15937,25 +26821,28 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "mcp" # type: ignore -class TelemetryConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Customer-supplied telemetry configuration for exporting container logs, traces, and metrics. +class VoiceAgentNoiseReduction(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Input audio noise reduction configuration. - :ivar endpoints: Customer-supplied telemetry export endpoint configurations. Required. - :vartype endpoints: list[~azure.ai.projects.models.TelemetryEndpoint] + :ivar type: The noise reduction mode. Required. Known values are: "near_field", "far_field", + and "azure_deep_noise_suppression". + :vartype type: str or ~azure.ai.projects.models.VoiceAgentNoiseReductionType """ - endpoints: list["_models.TelemetryEndpoint"] = rest_field( + type: Union[str, "_models.VoiceAgentNoiseReductionType"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """Customer-supplied telemetry export endpoint configurations. Required.""" + """The noise reduction mode. Required. Known values are: \"near_field\", \"far_field\", and + \"azure_deep_noise_suppression\".""" @overload def __init__( self, *, - endpoints: list["_models.TelemetryEndpoint"], + type: Union[str, "_models.VoiceAgentNoiseReductionType"], ) -> None: ... @overload @@ -15969,31 +26856,98 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class TextResponseFormat(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """An object specifying the format that the model must output. Configuring ``{ "type": - "json_schema" }`` enables Structured Outputs, which ensures the model will match your supplied - JSON schema. Learn more in the `Structured Outputs guide `_. - The default format is ``{ "type": "text" }`` with no additional options. *Not recommended for - gpt-4o and newer models:** Setting to ``{ "type": "json_object" }`` enables the older JSON - mode, which ensures the message the model generates is valid JSON. Using ``json_schema`` is - preferred for models that support it. - - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - TextResponseFormatJsonObject, TextResponseFormatJsonSchema, TextResponseFormatText - - :ivar type: Required. Known values are: "text", "json_schema", and "json_object". - :vartype type: str or ~azure.ai.projects.models.TextResponseFormatConfigurationType - """ +class VoiceAgentRealtimeResponseBase(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Properties shared by realtime responses returned by the voice-agent service. - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """Required. Known values are: \"text\", \"json_schema\", and \"json_object\".""" + :ivar id: The unique ID of the response, will look like ``resp_1234``. + :vartype id: str + :ivar object: The object type, must be ``realtime.response``. Default value is + "realtime.response". + :vartype object: str + :ivar status: The final status of the response (``completed``, ``cancelled``, ``failed``, or + ``incomplete``, ``in_progress``). Is one of the following types: Literal["completed"], + Literal["cancelled"], Literal["failed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str or str or str + :ivar status_details: Additional details about the status. + :vartype status_details: ~azure.ai.projects.models.RealtimeResponseStatusDetails + :ivar metadata: + :vartype metadata: ~azure.ai.projects.models.Metadata + :ivar usage: Usage statistics for the Response, this will correspond to billing. A Realtime API + session will maintain a conversation context and append new Items to the Conversation, thus + output from previous turns (text and audio tokens) will become the input for later turns. + :vartype usage: ~azure.ai.projects.models.RealtimeResponseUsage + :ivar conversation_id: Which conversation the response is added to, determined by the + ``conversation`` field in the ``response.create`` event. If ``auto``, the response will be + added to the default conversation and the value of ``conversation_id`` will be an id like + ``conv_1234``. If ``none``, the response will not be added to any conversation and the value of + ``conversation_id`` will be ``null``. If responses are being triggered automatically by VAD the + response will be added to the default conversation. + :vartype conversation_id: str + :ivar output_modalities: The set of modalities the model used to respond, currently the only + possible values are ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text + transcript. Setting the output to mode ``text`` will disable audio output from the model. + :vartype output_modalities: list[str or str] + :ivar max_output_tokens: Maximum number of output tokens for a single assistant response, + inclusive of tool calls, that was used in this response. Is either a int type or a + Literal["inf"] type. + :vartype max_output_tokens: int or str + """ + + id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique ID of the response, will look like ``resp_1234``.""" + object: Optional[Literal["realtime.response"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The object type, must be ``realtime.response``. Default value is \"realtime.response\".""" + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The final status of the response (``completed``, ``cancelled``, ``failed``, or ``incomplete``, + ``in_progress``). Is one of the following types: Literal[\"completed\"], + Literal[\"cancelled\"], Literal[\"failed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + status_details: Optional["_models.RealtimeResponseStatusDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Additional details about the status.""" + metadata: Optional["_models.Metadata"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + usage: Optional["_models.RealtimeResponseUsage"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Usage statistics for the Response, this will correspond to billing. A Realtime API session will + maintain a conversation context and append new Items to the Conversation, thus output from + previous turns (text and audio tokens) will become the input for later turns.""" + conversation_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Which conversation the response is added to, determined by the ``conversation`` field in the + ``response.create`` event. If ``auto``, the response will be added to the default conversation + and the value of ``conversation_id`` will be an id like ``conv_1234``. If ``none``, the + response will not be added to any conversation and the value of ``conversation_id`` will be + ``null``. If responses are being triggered automatically by VAD the response will be added to + the default conversation.""" + output_modalities: Optional[list[Literal["text", "audio"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The set of modalities the model used to respond, currently the only possible values are + ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text transcript. Setting the + output to mode ``text`` will disable audio output from the model.""" + max_output_tokens: Optional[Union[int, Literal["inf"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Maximum number of output tokens for a single assistant response, inclusive of tool calls, that + was used in this response. Is either a int type or a Literal[\"inf\"] type.""" @overload def __init__( self, *, - type: str, + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.response"]] = None, + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = None, + status_details: Optional["_models.RealtimeResponseStatusDetails"] = None, + metadata: Optional["_models.Metadata"] = None, + usage: Optional["_models.RealtimeResponseUsage"] = None, + conversation_id: Optional[str] = None, + output_modalities: Optional[list[Literal["text", "audio"]]] = None, + max_output_tokens: Optional[Union[int, Literal["inf"]]] = None, ) -> None: ... @overload @@ -16007,20 +26961,76 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class TextResponseFormatJsonObject(TextResponseFormat, discriminator="json_object"): - """JSON object. - - :ivar type: The type of response format being defined. Always ``json_object``. Required. - JSON_OBJECT. - :vartype type: str or ~azure.ai.projects.models.JSON_OBJECT - """ +class VoiceAgentRealtimeResponse( + VoiceAgentRealtimeResponseBase +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A live realtime response returned by the voice-agent service in both ``response.created`` and + ``response.done`` events. - type: Literal[TextResponseFormatConfigurationType.JSON_OBJECT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of response format being defined. Always ``json_object``. Required. JSON_OBJECT.""" + :ivar id: The unique ID of the response, will look like ``resp_1234``. + :vartype id: str + :ivar object: The object type, must be ``realtime.response``. Default value is + "realtime.response". + :vartype object: str + :ivar status: The final status of the response (``completed``, ``cancelled``, ``failed``, or + ``incomplete``, ``in_progress``). Is one of the following types: Literal["completed"], + Literal["cancelled"], Literal["failed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str or str or str + :ivar status_details: Additional details about the status. + :vartype status_details: ~azure.ai.projects.models.RealtimeResponseStatusDetails + :ivar metadata: + :vartype metadata: ~azure.ai.projects.models.Metadata + :ivar usage: Usage statistics for the Response, this will correspond to billing. A Realtime API + session will maintain a conversation context and append new Items to the Conversation, thus + output from previous turns (text and audio tokens) will become the input for later turns. + :vartype usage: ~azure.ai.projects.models.RealtimeResponseUsage + :ivar conversation_id: Which conversation the response is added to, determined by the + ``conversation`` field in the ``response.create`` event. If ``auto``, the response will be + added to the default conversation and the value of ``conversation_id`` will be an id like + ``conv_1234``. If ``none``, the response will not be added to any conversation and the value of + ``conversation_id`` will be ``null``. If responses are being triggered automatically by VAD the + response will be added to the default conversation. + :vartype conversation_id: str + :ivar output_modalities: The set of modalities the model used to respond, currently the only + possible values are ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text + transcript. Setting the output to mode ``text`` will disable audio output from the model. + :vartype output_modalities: list[str or str] + :ivar max_output_tokens: Maximum number of output tokens for a single assistant response, + inclusive of tool calls, that was used in this response. Is either a int type or a + Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar audio: The audio configuration used by the live response, including flat voice provider, + locale, and format fields under ``output``. + :vartype audio: ~azure.ai.projects.models.VoiceResponseAudio + :ivar output: The items produced by the live response. + :vartype output: list[~azure.ai.projects.models.RealtimeConversationItem] + """ + + audio: Optional["_models.VoiceResponseAudio"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio configuration used by the live response, including flat voice provider, locale, and + format fields under ``output``.""" + output: Optional[list["_models.RealtimeConversationItem"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The items produced by the live response.""" @overload def __init__( self, + *, + id: Optional[str] = None, # pylint: disable=redefined-builtin + object: Optional[Literal["realtime.response"]] = None, + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = None, + status_details: Optional["_models.RealtimeResponseStatusDetails"] = None, + metadata: Optional["_models.Metadata"] = None, + usage: Optional["_models.RealtimeResponseUsage"] = None, + conversation_id: Optional[str] = None, + output_modalities: Optional[list[Literal["text", "audio"]]] = None, + max_output_tokens: Optional[Union[int, Literal["inf"]]] = None, + audio: Optional["_models.VoiceResponseAudio"] = None, + output: Optional[list["_models.RealtimeConversationItem"]] = None, ) -> None: ... @overload @@ -16032,49 +27042,140 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = TextResponseFormatConfigurationType.JSON_OBJECT # type: ignore -class TextResponseFormatJsonSchema( - TextResponseFormat, discriminator="json_schema" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """JSON schema. +class VoiceAgentResponseCreateParams(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Parameters accepted by a voice-agent ``response.create`` event. - :ivar type: The type of response format being defined. Always ``json_schema``. Required. - JSON_SCHEMA. - :vartype type: str or ~azure.ai.projects.models.JSON_SCHEMA - :ivar description: A description of what the response format is for, used by the model to - determine how to respond in the format. - :vartype description: str - :ivar name: The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and - dashes, with a maximum length of 64. Required. - :vartype name: str - :ivar schema: Required. - :vartype schema: dict[str, any] - :ivar strict: - :vartype strict: bool + :ivar instructions: The default system instructions (i.e. system message) prepended to model + calls. This field allows the client to guide the model on desired responses. The model can be + instructed on response content and format, (e.g. "be extremely succinct", "act friendly", "here + are examples of good responses") and on audio behavior (e.g. "talk quickly", "inject emotion + into your voice", "laugh frequently"). The instructions are not guaranteed to be followed by + the model, but they provide guidance to the model on the desired behavior. Note that the server + sets default instructions which will be used if this field is not set and are visible in the + ``session.created`` event at the start of the session. + :vartype instructions: str + :ivar tools: Tools available to the model. + :vartype tools: list[~azure.ai.projects.models.RealtimeFunctionTool or + ~azure.ai.projects.models.MCPTool] + :ivar tool_choice: How the model chooses tools. Provide one of the string modes or force a + specific function/MCP tool. Is one of the following types: Union[str, + "_models.ToolChoiceOptions"], ToolChoiceFunction, ToolChoiceMCP + :vartype tool_choice: str or ~azure.ai.projects.models.ToolChoiceOptions or + ~azure.ai.projects.models.ToolChoiceFunction or ~azure.ai.projects.models.ToolChoiceMCP + :ivar parallel_tool_calls: Whether the model may call multiple tools in parallel. Only + supported by reasoning Realtime models such as ``gpt-realtime-2``. + :vartype parallel_tool_calls: bool + :ivar reasoning: + :vartype reasoning: ~azure.ai.projects.models.RealtimeReasoning + :ivar max_output_tokens: Maximum number of output tokens for a single assistant response, + inclusive of tool calls. Provide an integer between 1 and 4096 to limit output tokens, or + ``inf`` for the maximum available tokens for a given model. Defaults to ``inf``. Is either a + int type or a Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar conversation: Controls which conversation the response is added to. Currently supports + ``auto`` and ``none``, with ``auto`` as the default value. The ``auto`` value means that the + contents of the response will be added to the default conversation. Set this to ``none`` to + create an out-of-band response which will not add items to default conversation. Is one of the + following types: Literal["auto"], Literal["none"], str + :vartype conversation: str or str or str + :ivar metadata: + :vartype metadata: ~azure.ai.projects.models.Metadata + :ivar output_modalities: Modalities that the response may return. + :vartype output_modalities: list[str or ~azure.ai.projects.models.VoiceOutputModality] + :ivar audio: Response-specific audio settings. + :vartype audio: ~azure.ai.projects.models.PickPropertiesVoiceAgentAudioConfig + :ivar input: Conversation items used as inline response input. + :vartype input: list[~azure.ai.projects.models.RealtimeConversationItem] + :ivar pre_generated_assistant_message: A pre-generated assistant message used to begin the + response. + :vartype pre_generated_assistant_message: ~azure.ai.projects.models.RealtimeConversationItem + :ivar interim_response: Interim-response settings for this response. + :vartype interim_response: ~azure.ai.projects.models.VoiceAgentInterimResponseConfig """ - type: Literal[TextResponseFormatConfigurationType.JSON_SCHEMA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of response format being defined. Always ``json_schema``. Required. JSON_SCHEMA.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A description of what the response format is for, used by the model to determine how to respond - in the format.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with - a maximum length of 64. Required.""" - schema: dict[str, Any] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Required.""" - strict: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The default system instructions (i.e. system message) prepended to model calls. This field + allows the client to guide the model on desired responses. The model can be instructed on + response content and format, (e.g. \"be extremely succinct\", \"act friendly\", \"here are + examples of good responses\") and on audio behavior (e.g. \"talk quickly\", \"inject emotion + into your voice\", \"laugh frequently\"). The instructions are not guaranteed to be followed by + the model, but they provide guidance to the model on the desired behavior. Note that the server + sets default instructions which will be used if this field is not set and are visible in the + ``session.created`` event at the start of the session.""" + tools: Optional[list[Union["_models.RealtimeFunctionTool", "_models.MCPTool"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Tools available to the model.""" + tool_choice: Optional[ + Union[str, "_models.ToolChoiceOptions", "_models.ToolChoiceFunction", "_models.ToolChoiceMCP"] + ] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """How the model chooses tools. Provide one of the string modes or force a specific function/MCP + tool. Is one of the following types: Union[str, \"_models.ToolChoiceOptions\"], + ToolChoiceFunction, ToolChoiceMCP""" + parallel_tool_calls: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the model may call multiple tools in parallel. Only supported by reasoning Realtime + models such as ``gpt-realtime-2``.""" + reasoning: Optional["_models.RealtimeReasoning"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + max_output_tokens: Optional[Union[int, Literal["inf"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Maximum number of output tokens for a single assistant response, inclusive of tool calls. + Provide an integer between 1 and 4096 to limit output tokens, or ``inf`` for the maximum + available tokens for a given model. Defaults to ``inf``. Is either a int type or a + Literal[\"inf\"] type.""" + conversation: Optional[Union[Literal["auto"], Literal["none"], str]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Controls which conversation the response is added to. Currently supports ``auto`` and ``none``, + with ``auto`` as the default value. The ``auto`` value means that the contents of the response + will be added to the default conversation. Set this to ``none`` to create an out-of-band + response which will not add items to default conversation. Is one of the following types: + Literal[\"auto\"], Literal[\"none\"], str""" + metadata: Optional["_models.Metadata"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Modalities that the response may return.""" + audio: Optional["_models.PickPropertiesVoiceAgentAudioConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Response-specific audio settings.""" + input: Optional[list["_models.RealtimeConversationItem"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Conversation items used as inline response input.""" + pre_generated_assistant_message: Optional["_models.RealtimeConversationItem"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """A pre-generated assistant message used to begin the response.""" + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Interim-response settings for this response.""" @overload def __init__( self, *, - name: str, - schema: dict[str, Any], - description: Optional[str] = None, - strict: Optional[bool] = None, + instructions: Optional[str] = None, + tools: Optional[list[Union["_models.RealtimeFunctionTool", "_models.MCPTool"]]] = None, + tool_choice: Optional[ + Union[str, "_models.ToolChoiceOptions", "_models.ToolChoiceFunction", "_models.ToolChoiceMCP"] + ] = None, + parallel_tool_calls: Optional[bool] = None, + reasoning: Optional["_models.RealtimeReasoning"] = None, + max_output_tokens: Optional[Union[int, Literal["inf"]]] = None, + conversation: Optional[Union[Literal["auto"], Literal["none"], str]] = None, + metadata: Optional["_models.Metadata"] = None, + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = None, + audio: Optional["_models.PickPropertiesVoiceAgentAudioConfig"] = None, + input: Optional[list["_models.RealtimeConversationItem"]] = None, + pre_generated_assistant_message: Optional["_models.RealtimeConversationItem"] = None, + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = None, ) -> None: ... @overload @@ -16086,22 +27187,38 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = TextResponseFormatConfigurationType.JSON_SCHEMA # type: ignore -class TextResponseFormatText(TextResponseFormat, discriminator="text"): - """Text. +class VoiceAgentRtcCallErrorDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Details of a WebRTC signaling error. - :ivar type: The type of response format being defined. Always ``text``. Required. TEXT. - :vartype type: str or ~azure.ai.projects.models.TEXT + :ivar type: The error category, following the VoiceLive wire contract: + ``invalid_request_error`` for a client-side signaling fault (for example, a malformed SDP + offer) or ``server_error`` for a service-side failure. Additional categories may be added over + time. Required. + :vartype type: str + :ivar code: A machine-readable error code, when available. + :vartype code: str + :ivar message: A human-readable error message. Required. + :vartype message: str """ - type: Literal[TextResponseFormatConfigurationType.TEXT] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of response format being defined. Always ``text``. Required. TEXT.""" + type: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The error category, following the VoiceLive wire contract: ``invalid_request_error`` for a + client-side signaling fault (for example, a malformed SDP offer) or ``server_error`` for a + service-side failure. Additional categories may be added over time. Required.""" + code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A machine-readable error code, when available.""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A human-readable error message. Required.""" @overload def __init__( self, + *, + type: str, + message: str, + code: Optional[str] = None, ) -> None: ... @overload @@ -16113,32 +27230,45 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = TextResponseFormatConfigurationType.TEXT # type: ignore -class TimerRoutineTrigger( - RoutineTrigger, discriminator="timer" +class VoiceAgentSemanticVadTurnDetection( + VoiceAgentTurnDetectionConfig, discriminator="semantic_vad" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """A one-shot timer routine trigger. + """OpenAI semantic VAD turn-detection settings. - :ivar type: The trigger type. Required. A one-shot timer trigger. - :vartype type: str or ~azure.ai.projects.models.TIMER - :ivar at: The UTC date and time at which the timer fires. - :vartype at: ~datetime.datetime + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + :ivar eagerness: Is one of the following types: Literal["low"], Literal["medium"], + Literal["high"], Literal["auto"] + :vartype eagerness: str or str or str or str + :ivar create_response: + :vartype create_response: bool + :ivar interrupt_response: + :vartype interrupt_response: bool + :ivar type: Required. Semantic voice activity detection. + :vartype type: str or ~azure.ai.projects.models.SEMANTIC_VAD """ - type: Literal[RoutineTriggerType.TIMER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The trigger type. Required. A one-shot timer trigger.""" - at: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + eagerness: Optional[Literal["low", "medium", "high", "auto"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """The UTC date and time at which the timer fires.""" + """Is one of the following types: Literal[\"low\"], Literal[\"medium\"], Literal[\"high\"], + Literal[\"auto\"]""" + create_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + interrupt_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + type: Literal[VoiceAgentTurnDetectionType.SEMANTIC_VAD] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Semantic voice activity detection.""" @overload def __init__( self, *, - at: Optional[datetime.datetime] = None, + auto_truncate: Optional[bool] = None, + eagerness: Optional[Literal["low", "medium", "high", "auto"]] = None, + create_response: Optional[bool] = None, + interrupt_response: Optional[bool] = None, ) -> None: ... @overload @@ -16150,36 +27280,60 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = RoutineTriggerType.TIMER # type: ignore + self.type = VoiceAgentTurnDetectionType.SEMANTIC_VAD # type: ignore -class ToolboxObject(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A toolbox that stores reusable tool definitions for agents. - - :ivar id: The unique identifier of the toolbox. Required. - :vartype id: str - :ivar name: The name of the toolbox. Required. - :vartype name: str - :ivar default_version: The version identifier that the toolbox currently points to. Defaults to - the latest version. Can be changed via updateToolbox. Required. - :vartype default_version: str - """ +class VoiceAgentServerEventResponseAnimationBlendshapesDelta( + RealtimeServerEvent, discriminator="response.animation_blendshapes.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.animation_blendshapes.delta`` server event. - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique identifier of the toolbox. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the toolbox. Required.""" - default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The version identifier that the toolbox currently points to. Defaults to the latest version. - Can be changed via updateToolbox. Required.""" + :ivar type: Required. RESPONSE_ANIMATION_BLENDSHAPES_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_ANIMATION_BLENDSHAPES_DELTA + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar content_index: Required. + :vartype content_index: int + :ivar frames: Animation frames as numeric blendshape weights. Required. + :vartype frames: list[list[float]] + :ivar frame_index: The index of the first frame in this delta. Required. + :vartype frame_index: int + """ + + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_ANIMATION_BLENDSHAPES_DELTA.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + frames: list[list[float]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Animation frames as numeric blendshape weights. Required.""" + frame_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The index of the first frame in this delta. Required.""" @overload def __init__( self, *, - id: str, # pylint: disable=redefined-builtin - name: str, - default_version: str, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + frames: list[list[float]], + frame_index: int, ) -> None: ... @overload @@ -16191,64 +27345,112 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DELTA # type: ignore -class ToolboxPolicies(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Policy configuration for a toolbox, including content safety and other governance settings. +class VoiceAgentServerEventResponseAnimationBlendshapesDone( + RealtimeServerEvent, discriminator="response.animation_blendshapes.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.animation_blendshapes.done`` server event. - :ivar rai_config: Responsible AI content filtering configuration. - :vartype rai_config: ~azure.ai.projects.models.RaiConfig + :ivar type: Required. RESPONSE_ANIMATION_BLENDSHAPES_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_ANIMATION_BLENDSHAPES_DONE + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int """ - rai_config: Optional["_models.RaiConfig"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Responsible AI content filtering configuration.""" + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_ANIMATION_BLENDSHAPES_DONE.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - rai_config: Optional["_models.RaiConfig"] = None, + event_id: str, + response_id: str, + item_id: str, + output_index: int, ) -> None: ... @overload - def __init__(self, mapping: Mapping[str, Any]) -> None: - """ - :param mapping: raw JSON to initialize the model. - :type mapping: Mapping[str, Any] - """ - - def __init__(self, *args: Any, **kwargs: Any) -> None: - super().__init__(*args, **kwargs) - - -class ToolboxSearchPreviewToolboxTool( - ToolboxTool, discriminator="toolbox_search_preview" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A toolbox search tool stored in a toolbox. - - :ivar name: Optional user-defined name for this tool or configuration. - :vartype name: str - :ivar description: Optional user-defined description for this tool or configuration. - :vartype description: str - :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all - default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names - are silently ignored at runtime. - :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] - :ivar type: The type of the tool. Always ``toolbox_search_preview``. Required. - TOOLBOX_SEARCH_PREVIEW. - :vartype type: str or ~azure.ai.projects.models.TOOLBOX_SEARCH_PREVIEW - """ + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ - type: Literal[ToolboxToolType.TOOLBOX_SEARCH_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the tool. Always ``toolbox_search_preview``. Required. TOOLBOX_SEARCH_PREVIEW.""" + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_ANIMATION_BLENDSHAPES_DONE # type: ignore + + +class VoiceAgentServerEventResponseAnimationVisemeDelta( + RealtimeServerEvent, discriminator="response.animation_viseme.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.animation_viseme.delta`` server event. + + :ivar type: Required. RESPONSE_ANIMATION_VISEME_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_ANIMATION_VISEME_DELTA + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar content_index: Required. + :vartype content_index: int + :ivar audio_offset_ms: Required. + :vartype audio_offset_ms: ~datetime.timedelta + :ivar viseme_id: Required. + :vartype viseme_id: int + """ + + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_ANIMATION_VISEME_DELTA.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + audio_offset_ms: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Required.""" + viseme_id: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - name: Optional[str] = None, - description: Optional[str] = None, - tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + audio_offset_ms: datetime.timedelta, + viseme_id: int, ) -> None: ... @overload @@ -16260,29 +27462,50 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolboxToolType.TOOLBOX_SEARCH_PREVIEW # type: ignore - + self.type = RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DELTA # type: ignore -class ToolboxShellEnvironment(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """An execution environment for a shell tool stored in a toolbox. This environment model is scoped - to toolbox configuration and does not modify the OpenAI shell environment contract. - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - ToolboxShellContainerAutoEnvironment, ToolboxShellContainerReferenceEnvironment +class VoiceAgentServerEventResponseAnimationVisemeDone( + RealtimeServerEvent, discriminator="response.animation_viseme.done" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.animation_viseme.done`` server event. - :ivar type: The type of the shell execution environment. Required. Default value is None. - :vartype type: str + :ivar type: Required. RESPONSE_ANIMATION_VISEME_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_ANIMATION_VISEME_DONE + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar content_index: Required. + :vartype content_index: int """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """The type of the shell execution environment. Required. Default value is None.""" + type: Literal[RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_ANIMATION_VISEME_DONE.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - type: str, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, ) -> None: ... @overload @@ -16294,54 +27517,73 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_ANIMATION_VISEME_DONE # type: ignore -class ToolboxShellContainerAutoEnvironment( - ToolboxShellEnvironment, discriminator="container_auto" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """An automatically provisioned container environment for a shell tool stored in a toolbox. +class VoiceAgentServerEventResponseAudioTimestampDelta( + RealtimeServerEvent, discriminator="response.audio_timestamp.delta" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``response.audio_timestamp.delta`` server event. - :ivar type: The type of the shell execution environment. Always ``container_auto``. Required. - Default value is "container_auto". - :vartype type: str - :ivar file_ids: An optional list of uploaded files to make available to your code. - :vartype file_ids: list[str] - :ivar memory_limit: Known values are: "1g", "4g", "16g", and "64g". - :vartype memory_limit: str or ~azure.ai.projects.models.ContainerMemoryLimit - :ivar skills: An optional list of skills referenced by id or inline data. - :vartype skills: list[~azure.ai.projects.models.ContainerSkill] - :ivar network_policy: The network access policy for the container. When omitted, the service - defaults to disabled outbound network access. - :vartype network_policy: ~azure.ai.projects.models.ToolboxShellNetworkPolicy + :ivar type: Required. RESPONSE_AUDIO_TIMESTAMP_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_AUDIO_TIMESTAMP_DELTA + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar content_index: Required. + :vartype content_index: int + :ivar audio_offset_ms: Required. + :vartype audio_offset_ms: ~datetime.timedelta + :ivar audio_duration_ms: Required. + :vartype audio_duration_ms: ~datetime.timedelta + :ivar text: Required. + :vartype text: str + :ivar timestamp_type: Required. Default value is "word". + :vartype timestamp_type: str """ - type: Literal["container_auto"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the shell execution environment. Always ``container_auto``. Required. Default value - is \"container_auto\".""" - file_ids: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """An optional list of uploaded files to make available to your code.""" - memory_limit: Optional[Union[str, "_models.ContainerMemoryLimit"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Known values are: \"1g\", \"4g\", \"16g\", and \"64g\".""" - skills: Optional[list["_models.ContainerSkill"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] + type: Literal[RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_AUDIO_TIMESTAMP_DELTA.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + audio_offset_ms: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" ) - """An optional list of skills referenced by id or inline data.""" - network_policy: Optional["_models.ToolboxShellNetworkPolicy"] = rest_field( - visibility=["read", "create", "update", "delete", "query"] + """Required.""" + audio_duration_ms: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" ) - """The network access policy for the container. When omitted, the service defaults to disabled - outbound network access.""" + """Required.""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + timestamp_type: Literal["word"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required. Default value is \"word\".""" @overload def __init__( self, *, - file_ids: Optional[list[str]] = None, - memory_limit: Optional[Union[str, "_models.ContainerMemoryLimit"]] = None, - skills: Optional[list["_models.ContainerSkill"]] = None, - network_policy: Optional["_models.ToolboxShellNetworkPolicy"] = None, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, + audio_offset_ms: datetime.timedelta, + audio_duration_ms: datetime.timedelta, + text: str, ) -> None: ... @overload @@ -16353,32 +27595,51 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = "container_auto" # type: ignore + self.type = RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DELTA # type: ignore + self.timestamp_type: Literal["word"] = "word" -class ToolboxShellContainerReferenceEnvironment( - ToolboxShellEnvironment, discriminator="container_reference" +class VoiceAgentServerEventResponseAudioTimestampDone( + RealtimeServerEvent, discriminator="response.audio_timestamp.done" ): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only - """An existing container environment for a shell tool stored in a toolbox. + """The ``response.audio_timestamp.done`` server event. - :ivar type: The type of the shell execution environment. Always ``container_reference``. - Required. Default value is "container_reference". - :vartype type: str - :ivar container_id: The ID of the referenced container. Required. - :vartype container_id: str + :ivar type: Required. RESPONSE_AUDIO_TIMESTAMP_DONE. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_AUDIO_TIMESTAMP_DONE + :ivar event_id: Required. + :vartype event_id: str + :ivar response_id: Required. + :vartype response_id: str + :ivar item_id: Required. + :vartype item_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar content_index: Required. + :vartype content_index: int """ - type: Literal["container_reference"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the shell execution environment. Always ``container_reference``. Required. Default - value is \"container_reference\".""" - container_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The ID of the referenced container. Required.""" + type: Literal[RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DONE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_AUDIO_TIMESTAMP_DONE.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + response_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + content_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" @overload def __init__( self, *, - container_id: str, + event_id: str, + response_id: str, + item_id: str, + output_index: int, + content_index: int, ) -> None: ... @overload @@ -16390,28 +27651,45 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = "container_reference" # type: ignore - + self.type = RealtimeServerEventType.RESPONSE_AUDIO_TIMESTAMP_DONE # type: ignore -class ToolboxShellNetworkPolicy(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Network access policy for an automatically provisioned toolbox shell container. - - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - ToolboxShellNetworkPolicyDisabled - - :ivar type: The type of network access policy. Required. Default value is None. - :vartype type: str - """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """The type of network access policy. Required. Default value is None.""" +class VoiceAgentServerEventResponseVideoDelta( + RealtimeServerEvent, discriminator="response.video.delta" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The ``response.video.delta`` server event. + + :ivar type: Required. RESPONSE_VIDEO_DELTA. + :vartype type: str or ~azure.ai.projects.models.RESPONSE_VIDEO_DELTA + :ivar event_id: Required. + :vartype event_id: str + :ivar output_index: Required. + :vartype output_index: int + :ivar codec: Required. + :vartype codec: str + :ivar delta: The base64-encoded video frame data. Required. + :vartype delta: str + """ + + type: Literal[RealtimeServerEventType.RESPONSE_VIDEO_DELTA] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. RESPONSE_VIDEO_DELTA.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + output_index: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + codec: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + delta: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The base64-encoded video frame data. Required.""" @overload def __init__( self, *, - type: str, + event_id: str, + output_index: int, + codec: str, + delta: str, ) -> None: ... @overload @@ -16423,23 +27701,47 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RESPONSE_VIDEO_DELTA # type: ignore -class ToolboxShellNetworkPolicyDisabled(ToolboxShellNetworkPolicy, discriminator="disabled"): - """A network policy that disables outbound access from a toolbox shell container. - - :ivar type: The type of network access policy. Always ``disabled``. Required. Default value is - "disabled". - :vartype type: str - """ - - type: Literal["disabled"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of network access policy. Always ``disabled``. Required. Default value is - \"disabled\".""" +class VoiceAgentServerEventRtcCallError( + RealtimeServerEvent, discriminator="rtc.call.error" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The ``rtc.call.error`` server event: a WebRTC signaling failure. + + :ivar type: The event type. Always ``rtc.call.error``. Required. RTC_CALL_ERROR. + :vartype type: str or ~azure.ai.projects.models.RTC_CALL_ERROR + :ivar event_id: An optional server-generated event identifier. + :vartype event_id: str + :ivar operation: The signaling operation that failed, when known. + :vartype operation: str + :ivar rtc_call_id: The identifier of the WebRTC call, when known. + :vartype rtc_call_id: str + :ivar error: The error detail. Required. + :vartype error: ~azure.ai.projects.models.VoiceAgentRtcCallErrorDetails + """ + + type: Literal[RealtimeServerEventType.RTC_CALL_ERROR] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``rtc.call.error``. Required. RTC_CALL_ERROR.""" + event_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """An optional server-generated event identifier.""" + operation: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The signaling operation that failed, when known.""" + rtc_call_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the WebRTC call, when known.""" + error: "_models.VoiceAgentRtcCallErrorDetails" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The error detail. Required.""" @overload def __init__( self, + *, + error: "_models.VoiceAgentRtcCallErrorDetails", + event_id: Optional[str] = None, + operation: Optional[str] = None, + rtc_call_id: Optional[str] = None, ) -> None: ... @overload @@ -16451,28 +27753,40 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = "disabled" # type: ignore - + self.type = RealtimeServerEventType.RTC_CALL_ERROR # type: ignore -class ToolboxSkill(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A skill source included in a toolbox. - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - ToolboxSkillReference +class VoiceAgentServerEventRtcCallSdpCreated( + RealtimeServerEvent, discriminator="rtc.call.sdp.created" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The ``rtc.call.sdp.created`` server event: the SDP answer that completes WebRTC negotiation. - :ivar type: The type of skill source. Required. Default value is None. - :vartype type: str + :ivar type: The event type. Always ``rtc.call.sdp.created``. Required. RTC_CALL_SDP_CREATED. + :vartype type: str or ~azure.ai.projects.models.RTC_CALL_SDP_CREATED + :ivar event_id: The server-generated event identifier. Required. + :vartype event_id: str + :ivar rtc_call_id: The identifier of the established WebRTC call. Required. + :vartype rtc_call_id: str + :ivar sdp_answer: The server's SDP answer for the WebRTC connection. Required. + :vartype sdp_answer: str """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """The type of skill source. Required. Default value is None.""" + type: Literal[RealtimeServerEventType.RTC_CALL_SDP_CREATED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``rtc.call.sdp.created``. Required. RTC_CALL_SDP_CREATED.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server-generated event identifier. Required.""" + rtc_call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the established WebRTC call. Required.""" + sdp_answer: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server's SDP answer for the WebRTC connection. Required.""" @overload def __init__( self, *, - type: str, + event_id: str, + rtc_call_id: str, + sdp_answer: str, ) -> None: ... @overload @@ -16484,36 +27798,35 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.RTC_CALL_SDP_CREATED # type: ignore -class ToolboxSkillReference( - ToolboxSkill, discriminator="skill_reference" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A reference to an existing skill to include in a toolbox. +class VoiceAgentServerEventSessionAvatarConnecting( + RealtimeServerEvent, discriminator="session.avatar.connecting" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.avatar.connecting`` server event. - :ivar type: The type of skill source. Required. Default value is "skill_reference". - :vartype type: str - :ivar name: The name of the skill. Required. - :vartype name: str - :ivar version: The version of the skill. If not specified, the skill's default version is used. - When a version is specified, the reference is pinned to that immutable version. - :vartype version: str + :ivar type: Required. SESSION_AVATAR_CONNECTING. + :vartype type: str or ~azure.ai.projects.models.SESSION_AVATAR_CONNECTING + :ivar event_id: Required. + :vartype event_id: str + :ivar server_sdp: The server's SDP answer for avatar media negotiation. Required. + :vartype server_sdp: str """ - type: Literal["skill_reference"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of skill source. Required. Default value is \"skill_reference\".""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the skill. Required.""" - version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The version of the skill. If not specified, the skill's default version is used. When a version - is specified, the reference is pinned to that immutable version.""" + type: Literal[RealtimeServerEventType.SESSION_AVATAR_CONNECTING] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. SESSION_AVATAR_CONNECTING.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + server_sdp: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server's SDP answer for avatar media negotiation. Required.""" @overload def __init__( self, *, - name: str, - version: Optional[str] = None, + event_id: str, + server_sdp: str, ) -> None: ... @overload @@ -16525,82 +27838,34 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = "skill_reference" # type: ignore + self.type = RealtimeServerEventType.SESSION_AVATAR_CONNECTING # type: ignore -class ToolboxVersionObject(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A specific version of a toolbox. - - :ivar metadata: Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. +class VoiceAgentServerEventSessionAvatarSwitchToIdle( + RealtimeServerEvent, discriminator="session.avatar.switch_to_idle" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.avatar.switch_to_idle`` server event. - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Required. - :vartype metadata: dict[str, str] - :ivar id: The unique identifier of the toolbox version. Required. - :vartype id: str - :ivar name: The name of the toolbox. Required. - :vartype name: str - :ivar version: The version identifier of the toolbox. Toolbox versions are immutable and every - update creates a new version. Required. - :vartype version: str - :ivar description: A human-readable description of the toolbox. - :vartype description: str - :ivar created_at: The Unix timestamp (seconds) when the toolbox version was created. Required. - :vartype created_at: ~datetime.datetime - :ivar tools: The list of tools contained in this toolbox version. Required. - :vartype tools: list[~azure.ai.projects.models.ToolboxTool] - :ivar skills: The list of skill sources included in this toolbox version. - :vartype skills: list[~azure.ai.projects.models.ToolboxSkill] - :ivar policies: Policy configuration for the toolbox version. - :vartype policies: ~azure.ai.projects.models.ToolboxPolicies + :ivar type: Required. SESSION_AVATAR_SWITCH_TO_IDLE. + :vartype type: str or ~azure.ai.projects.models.SESSION_AVATAR_SWITCH_TO_IDLE + :ivar event_id: Required. + :vartype event_id: str + :ivar turn_id: + :vartype turn_id: str """ - metadata: dict[str, str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. - - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Required.""" - id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique identifier of the toolbox version. Required.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the toolbox. Required.""" - version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The version identifier of the toolbox. Toolbox versions are immutable and every update creates - a new version. Required.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A human-readable description of the toolbox.""" - created_at: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" - ) - """The Unix timestamp (seconds) when the toolbox version was created. Required.""" - tools: list["_models.ToolboxTool"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The list of tools contained in this toolbox version. Required.""" - skills: Optional[list["_models.ToolboxSkill"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """The list of skill sources included in this toolbox version.""" - policies: Optional["_models.ToolboxPolicies"] = rest_field( - visibility=["read", "create", "update", "delete", "query"] - ) - """Policy configuration for the toolbox version.""" + type: Literal[RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_IDLE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. SESSION_AVATAR_SWITCH_TO_IDLE.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + turn_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, - *, - metadata: dict[str, str], - id: str, # pylint: disable=redefined-builtin - name: str, - version: str, - created_at: datetime.datetime, - tools: list["_models.ToolboxTool"], - description: Optional[str] = None, - skills: Optional[list["_models.ToolboxSkill"]] = None, - policies: Optional["_models.ToolboxPolicies"] = None, + *, + event_id: str, + turn_id: Optional[str] = None, ) -> None: ... @overload @@ -16612,58 +27877,34 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_IDLE # type: ignore -class ToolChoiceAllowed( - ToolChoiceParam, discriminator="allowed_tools" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Allowed tools. - - :ivar type: Allowed tool configuration type. Always ``allowed_tools``. Required. ALLOWED_TOOLS. - :vartype type: str or ~azure.ai.projects.models.ALLOWED_TOOLS - :ivar mode: Constrains the tools available to the model to a pre-defined set. ``auto`` allows - the model to pick from among the allowed tools and generate a message. ``required`` requires - the model to call one or more of the allowed tools. Required. Is either a Literal["auto"] type - or a Literal["required"] type. - :vartype mode: str or str - :ivar tools: Required. A list of tool definitions that the model should be allowed to call. For - the Responses API, the list of tool definitions might look like: - - .. code-block:: json +class VoiceAgentServerEventSessionAvatarSwitchToSpeaking( + RealtimeServerEvent, discriminator="session.avatar.switch_to_speaking" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.avatar.switch_to_speaking`` server event. - [ - { "type": "function", "name": "get_weather" }, - { "type": "mcp", "server_label": "deepwiki" }, - { "type": "image_generation" } - ] - :vartype tools: list[dict[str, any]] + :ivar type: Required. SESSION_AVATAR_SWITCH_TO_SPEAKING. + :vartype type: str or ~azure.ai.projects.models.SESSION_AVATAR_SWITCH_TO_SPEAKING + :ivar event_id: Required. + :vartype event_id: str + :ivar turn_id: + :vartype turn_id: str """ - type: Literal[ToolChoiceParamType.ALLOWED_TOOLS] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Allowed tool configuration type. Always ``allowed_tools``. Required. ALLOWED_TOOLS.""" - mode: Literal["auto", "required"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Constrains the tools available to the model to a pre-defined set. ``auto`` allows the model to - pick from among the allowed tools and generate a message. ``required`` requires the model to - call one or more of the allowed tools. Required. Is either a Literal[\"auto\"] type or a - Literal[\"required\"] type.""" - tools: list[dict[str, Any]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Required. A list of tool definitions that the model should be allowed to call. For the - Responses API, the list of tool definitions might look like: - - .. code-block:: json - - [ - { \"type\": \"function\", \"name\": \"get_weather\" }, - { \"type\": \"mcp\", \"server_label\": \"deepwiki\" }, - { \"type\": \"image_generation\" } - ]""" + type: Literal[RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_SPEAKING] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. SESSION_AVATAR_SWITCH_TO_SPEAKING.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + turn_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, *, - mode: Literal["auto", "required"], - tools: list[dict[str, Any]], + event_id: str, + turn_id: Optional[str] = None, ) -> None: ... @overload @@ -16675,23 +27916,55 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.ALLOWED_TOOLS # type: ignore - - -class ToolChoiceCodeInterpreter(ToolChoiceParam, discriminator="code_interpreter"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. + self.type = RealtimeServerEventType.SESSION_AVATAR_SWITCH_TO_SPEAKING # type: ignore - :ivar type: Required. CODE_INTERPRETER. - :vartype type: str or ~azure.ai.projects.models.CODE_INTERPRETER - """ - type: Literal[ToolChoiceParamType.CODE_INTERPRETER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. CODE_INTERPRETER.""" +class VoiceAgentServerEventSessionSubagentAborted( + RealtimeServerEvent, discriminator="session.subagent.aborted" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.subagent.aborted`` server event. + + :ivar type: The event type. Always ``session.subagent.aborted``. Required. + SESSION_SUBAGENT_ABORTED. + :vartype type: str or ~azure.ai.projects.models.SESSION_SUBAGENT_ABORTED + :ivar event_id: The server-generated event identifier. Required. + :vartype event_id: str + :ivar consultation_id: The identifier of the subagent consultation. Required. + :vartype consultation_id: str + :ivar call_id: The identifier of the function call that initiated the consultation. Required. + :vartype call_id: str + :ivar subagent_name: The name of the consulted subagent. Required. + :vartype subagent_name: str + :ivar reason: The reason the consultation was aborted. Required. Known values are: + "unknown_target", "timeout", "cancelled", "stopped_by_user", "superseded", and "failed". + :vartype reason: str or ~azure.ai.projects.models.VoiceAgentSubagentAbortReason + """ + + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_ABORTED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``session.subagent.aborted``. Required. SESSION_SUBAGENT_ABORTED.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server-generated event identifier. Required.""" + consultation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the subagent consultation. Required.""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the function call that initiated the consultation. Required.""" + subagent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the consulted subagent. Required.""" + reason: Union[str, "_models.VoiceAgentSubagentAbortReason"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The reason the consultation was aborted. Required. Known values are: \"unknown_target\", + \"timeout\", \"cancelled\", \"stopped_by_user\", \"superseded\", and \"failed\".""" @overload def __init__( self, + *, + event_id: str, + consultation_id: str, + call_id: str, + subagent_name: str, + reason: Union[str, "_models.VoiceAgentSubagentAbortReason"], ) -> None: ... @overload @@ -16703,23 +27976,46 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.CODE_INTERPRETER # type: ignore + self.type = RealtimeServerEventType.SESSION_SUBAGENT_ABORTED # type: ignore -class ToolChoiceComputer(ToolChoiceParam, discriminator="computer"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentServerEventSessionSubagentCompleted( + RealtimeServerEvent, discriminator="session.subagent.completed" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.subagent.completed`` server event. - :ivar type: Required. COMPUTER. - :vartype type: str or ~azure.ai.projects.models.COMPUTER + :ivar type: The event type. Always ``session.subagent.completed``. Required. + SESSION_SUBAGENT_COMPLETED. + :vartype type: str or ~azure.ai.projects.models.SESSION_SUBAGENT_COMPLETED + :ivar event_id: The server-generated event identifier. Required. + :vartype event_id: str + :ivar consultation_id: The identifier of the subagent consultation. Required. + :vartype consultation_id: str + :ivar call_id: The identifier of the function call that initiated the consultation. Required. + :vartype call_id: str + :ivar subagent_name: The name of the consulted subagent. Required. + :vartype subagent_name: str """ - type: Literal[ToolChoiceParamType.COMPUTER] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. COMPUTER.""" + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_COMPLETED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``session.subagent.completed``. Required. SESSION_SUBAGENT_COMPLETED.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server-generated event identifier. Required.""" + consultation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the subagent consultation. Required.""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the function call that initiated the consultation. Required.""" + subagent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the consulted subagent. Required.""" @overload def __init__( self, + *, + event_id: str, + consultation_id: str, + call_id: str, + subagent_name: str, ) -> None: ... @overload @@ -16731,23 +28027,46 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.COMPUTER # type: ignore + self.type = RealtimeServerEventType.SESSION_SUBAGENT_COMPLETED # type: ignore -class ToolChoiceComputerUse(ToolChoiceParam, discriminator="computer_use"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentServerEventSessionSubagentStarted( + RealtimeServerEvent, discriminator="session.subagent.started" +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only + """The ``session.subagent.started`` server event. - :ivar type: Required. COMPUTER_USE. - :vartype type: str or ~azure.ai.projects.models.COMPUTER_USE + :ivar type: The event type. Always ``session.subagent.started``. Required. + SESSION_SUBAGENT_STARTED. + :vartype type: str or ~azure.ai.projects.models.SESSION_SUBAGENT_STARTED + :ivar event_id: The server-generated event identifier. Required. + :vartype event_id: str + :ivar consultation_id: The identifier of the subagent consultation. Required. + :vartype consultation_id: str + :ivar call_id: The identifier of the function call that initiated the consultation. Required. + :vartype call_id: str + :ivar subagent_name: The name of the consulted subagent. Required. + :vartype subagent_name: str """ - type: Literal[ToolChoiceParamType.COMPUTER_USE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. COMPUTER_USE.""" + type: Literal[RealtimeServerEventType.SESSION_SUBAGENT_STARTED] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The event type. Always ``session.subagent.started``. Required. SESSION_SUBAGENT_STARTED.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The server-generated event identifier. Required.""" + consultation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the subagent consultation. Required.""" + call_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The identifier of the function call that initiated the consultation. Required.""" + subagent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the consulted subagent. Required.""" @overload def __init__( self, + *, + event_id: str, + consultation_id: str, + call_id: str, + subagent_name: str, ) -> None: ... @overload @@ -16759,23 +28078,37 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.COMPUTER_USE # type: ignore + self.type = RealtimeServerEventType.SESSION_SUBAGENT_STARTED # type: ignore -class ToolChoiceComputerUsePreview(ToolChoiceParam, discriminator="computer_use_preview"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentServerEventWarning( + RealtimeServerEvent, discriminator="warning" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """The ``warning`` server event. - :ivar type: Required. COMPUTER_USE_PREVIEW. - :vartype type: str or ~azure.ai.projects.models.COMPUTER_USE_PREVIEW + :ivar type: Required. WARNING. + :vartype type: str or ~azure.ai.projects.models.WARNING + :ivar event_id: Required. + :vartype event_id: str + :ivar warning: Required. + :vartype warning: ~azure.ai.projects.models.VoiceAgentServerEventWarningDetails """ - type: Literal[ToolChoiceParamType.COMPUTER_USE_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. COMPUTER_USE_PREVIEW.""" + type: Literal[RealtimeServerEventType.WARNING] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. WARNING.""" + event_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + warning: "_models.VoiceAgentServerEventWarningDetails" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Required.""" @overload def __init__( self, + *, + event_id: str, + warning: "_models.VoiceAgentServerEventWarningDetails", ) -> None: ... @overload @@ -16787,30 +28120,32 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.COMPUTER_USE_PREVIEW # type: ignore + self.type = RealtimeServerEventType.WARNING # type: ignore -class ToolChoiceCustom( - ToolChoiceParam, discriminator="custom" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Custom tool. +class VoiceAgentServerEventWarningDetails(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Details of a non-fatal warning. - :ivar type: For custom tool calling, the type is always ``custom``. Required. CUSTOM. - :vartype type: str or ~azure.ai.projects.models.CUSTOM - :ivar name: The name of the custom tool to call. Required. - :vartype name: str + :ivar message: Required. + :vartype message: str + :ivar code: + :vartype code: str + :ivar param: + :vartype param: str """ - type: Literal[ToolChoiceParamType.CUSTOM] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """For custom tool calling, the type is always ``custom``. Required. CUSTOM.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the custom tool to call. Required.""" + message: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Required.""" + code: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + param: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) @overload def __init__( self, *, - name: str, + message: str, + code: Optional[str] = None, + param: Optional[str] = None, ) -> None: ... @overload @@ -16822,23 +28157,69 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.CUSTOM # type: ignore -class ToolChoiceFileSearch(ToolChoiceParam, discriminator="file_search"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentServerVadTurnDetection( + VoiceAgentTurnDetectionConfig, discriminator="server_vad" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """Server-side voice activity detection. - :ivar type: Required. FILE_SEARCH. - :vartype type: str or ~azure.ai.projects.models.FILE_SEARCH + :ivar auto_truncate: Whether the input audio buffer is truncated automatically when speech + stops. + :vartype auto_truncate: bool + :ivar threshold: + :vartype threshold: float + :ivar prefix_padding_ms: + :vartype prefix_padding_ms: int + :ivar silence_duration_ms: + :vartype silence_duration_ms: int + :ivar create_response: + :vartype create_response: bool + :ivar interrupt_response: + :vartype interrupt_response: bool + :ivar idle_timeout_ms: + :vartype idle_timeout_ms: int + :ivar type: Required. Server-side voice activity detection. + :vartype type: str or ~azure.ai.projects.models.SERVER_VAD + :ivar speech_duration_ms: Minimum speech duration required to trigger detection, in + milliseconds. + :vartype speech_duration_ms: ~datetime.timedelta + :ivar end_of_utterance_detection: Semantic end-of-utterance detection configuration. Set to + null to disable it. + :vartype end_of_utterance_detection: + ~azure.ai.projects.models.VoiceAgentEndOfUtteranceDetection """ - type: Literal[ToolChoiceParamType.FILE_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. FILE_SEARCH.""" + threshold: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + prefix_padding_ms: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + silence_duration_ms: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + create_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + interrupt_response: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + idle_timeout_ms: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + type: Literal[VoiceAgentTurnDetectionType.SERVER_VAD] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Server-side voice activity detection.""" + speech_duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """Minimum speech duration required to trigger detection, in milliseconds.""" + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Semantic end-of-utterance detection configuration. Set to null to disable it.""" @overload def __init__( self, + *, + auto_truncate: Optional[bool] = None, + threshold: Optional[float] = None, + prefix_padding_ms: Optional[int] = None, + silence_duration_ms: Optional[int] = None, + create_response: Optional[bool] = None, + interrupt_response: Optional[bool] = None, + idle_timeout_ms: Optional[int] = None, + speech_duration_ms: Optional[datetime.timedelta] = None, + end_of_utterance_detection: Optional["_models.VoiceAgentEndOfUtteranceDetection"] = None, ) -> None: ... @overload @@ -16850,30 +28231,55 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.FILE_SEARCH # type: ignore + self.type = VoiceAgentTurnDetectionType.SERVER_VAD # type: ignore -class ToolChoiceFunction( - ToolChoiceParam, discriminator="function" +class VoiceAgentSessionAvatarConfig( + VoiceAgentAvatarConfig ): # pylint: disable=docstring-keyword-should-match-keyword-only - """Function tool. - - :ivar type: For function calling, the type is always ``function``. Required. FUNCTION. - :vartype type: str or ~azure.ai.projects.models.FUNCTION - :ivar name: The name of the function to call. Required. - :vartype name: str + """Avatar settings accepted by the stable voice-agent WebSocket contract. + + :ivar type: The avatar type. Required. Known values are: "video_avatar" and "photo_avatar". + :vartype type: str or ~azure.ai.projects.models.VoiceAgentAvatarType + :ivar character: The avatar character identifier, e.g. 'lisa'. Required. + :vartype character: str + :ivar style: The avatar style, e.g. 'casual-sitting'. + :vartype style: str + :ivar customized: Whether the avatar is a customer-customized avatar. Defaults to false. + :vartype customized: bool + :ivar output_protocol: The transport used to deliver the avatar video stream. Known values are: + "webrtc" and "websocket". + :vartype output_protocol: str or ~azure.ai.projects.models.VoiceAgentAvatarOutputProtocol + :ivar model: The avatar model identifier. + :vartype model: str + :ivar video: Avatar video encoder and presentation settings. + :vartype video: ~azure.ai.projects.models.VoiceAgentAvatarVideoParams + :ivar scene: Avatar placement and motion settings. + :vartype scene: ~azure.ai.projects.models.VoiceAgentAvatarScene + :ivar output_audit_audio: Whether audit audio is emitted with avatar output. Defaults to false. + :vartype output_audit_audio: bool + :ivar ice_servers: + :vartype ice_servers: list[~azure.ai.projects.models.VoiceAgentAvatarIceServer] """ - type: Literal[ToolChoiceParamType.FUNCTION] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """For function calling, the type is always ``function``. Required. FUNCTION.""" - name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the function to call. Required.""" + ice_servers: Optional[list["_models.VoiceAgentAvatarIceServer"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) @overload def __init__( self, *, - name: str, + type: Union[str, "_models.VoiceAgentAvatarType"], + character: str, + style: Optional[str] = None, + customized: Optional[bool] = None, + output_protocol: Optional[Union[str, "_models.VoiceAgentAvatarOutputProtocol"]] = None, + model: Optional[str] = None, + video: Optional["_models.VoiceAgentAvatarVideoParams"] = None, + scene: Optional["_models.VoiceAgentAvatarScene"] = None, + output_audit_audio: Optional[bool] = None, + ice_servers: Optional[list["_models.VoiceAgentAvatarIceServer"]] = None, ) -> None: ... @overload @@ -16885,23 +28291,146 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.FUNCTION # type: ignore -class ToolChoiceImageGeneration(ToolChoiceParam, discriminator="image_generation"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentSessionResponseConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The effective stable realtime session settings returned by the voice-agent service. - :ivar type: Required. IMAGE_GENERATION. - :vartype type: str or ~azure.ai.projects.models.IMAGE_GENERATION + :ivar type: The session type. Always ``realtime``. Required. Default value is "realtime". + :vartype type: str + :ivar instructions: Instructions applied throughout the session. + :vartype instructions: str + :ivar temperature: The sampling temperature for compatible cascaded pipelines. + :vartype temperature: float + :ivar max_output_tokens: The maximum output-token count for one response. Is either a int type + or a Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar output_modalities: The output modalities enabled for the session. + :vartype output_modalities: list[str or ~azure.ai.projects.models.VoiceOutputModality] + :ivar audio: The input- and output-audio settings for the session. + :vartype audio: ~azure.ai.projects.models.VoiceAgentAudioConfig + :ivar avatar: The avatar settings for the session. + :vartype avatar: ~azure.ai.projects.models.VoiceAgentSessionAvatarConfig + :ivar animation: Animation settings for the session. + :vartype animation: ~azure.ai.projects.models.VoiceAgentAnimationConfig + :ivar tools: Tools available to the session. + :vartype tools: list[~azure.ai.projects.models.VoiceAgentTool] + :ivar tool_choice: Tool-selection behavior for the session. Is one of the following types: + Literal["none"], Literal["auto"], Literal["required"], ToolChoiceFunction, ToolChoiceMCP + :vartype tool_choice: str or str or str or ~azure.ai.projects.models.ToolChoiceFunction or + ~azure.ai.projects.models.ToolChoiceMCP + :ivar reasoning: Reasoning settings for compatible realtime models. + :vartype reasoning: ~azure.ai.projects.models.RealtimeReasoning + :ivar parallel_tool_calls: Whether the model may call multiple tools in parallel. + :vartype parallel_tool_calls: bool + :ivar include: Additional fields to include in service outputs. + :vartype include: list[str or ~azure.ai.projects.models.VoiceAgentSessionIncludeOption] + :ivar metadata: Up to 16 string key-value pairs attached to the session. + :vartype metadata: dict[str, str] + :ivar interim_response: Interim-response settings for latency and tool execution. + :vartype interim_response: ~azure.ai.projects.models.VoiceAgentInterimResponseConfig + :ivar greeting: A proactive assistant greeting started after session configuration. + :vartype greeting: ~azure.ai.projects.models.VoiceAgentGreetingConfig + :ivar object: The object type. Always ``realtime.session``. Required. Default value is + "realtime.session". + :vartype object: str + :ivar id: The session identifier. Required. + :vartype id: str + :ivar model: The selected model. Required. + :vartype model: str + :ivar expires_at: The session expiration time as a Unix timestamp in seconds. + :vartype expires_at: ~datetime.datetime """ - type: Literal[ToolChoiceParamType.IMAGE_GENERATION] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. IMAGE_GENERATION.""" + type: Literal["realtime"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The session type. Always ``realtime``. Required. Default value is \"realtime\".""" + instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Instructions applied throughout the session.""" + temperature: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sampling temperature for compatible cascaded pipelines.""" + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The maximum output-token count for one response. Is either a int type or a Literal[\"inf\"] + type.""" + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The output modalities enabled for the session.""" + audio: Optional["_models.VoiceAgentAudioConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The input- and output-audio settings for the session.""" + avatar: Optional["_models.VoiceAgentSessionAvatarConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The avatar settings for the session.""" + animation: Optional["_models.VoiceAgentAnimationConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Animation settings for the session.""" + tools: Optional[list["_models.VoiceAgentTool"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Tools available to the session.""" + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Tool-selection behavior for the session. Is one of the following types: Literal[\"none\"], + Literal[\"auto\"], Literal[\"required\"], ToolChoiceFunction, ToolChoiceMCP""" + reasoning: Optional["_models.RealtimeReasoning"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Reasoning settings for compatible realtime models.""" + parallel_tool_calls: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the model may call multiple tools in parallel.""" + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Additional fields to include in service outputs.""" + metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Up to 16 string key-value pairs attached to the session.""" + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Interim-response settings for latency and tool execution.""" + greeting: Optional["_models.VoiceAgentGreetingConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """A proactive assistant greeting started after session configuration.""" + object: Literal["realtime.session"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The object type. Always ``realtime.session``. Required. Default value is \"realtime.session\".""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The session identifier. Required.""" + model: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The selected model. Required.""" + expires_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The session expiration time as a Unix timestamp in seconds.""" @overload def __init__( self, + *, + id: str, # pylint: disable=redefined-builtin + model: str, + instructions: Optional[str] = None, + temperature: Optional[float] = None, + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = None, + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = None, + audio: Optional["_models.VoiceAgentAudioConfig"] = None, + avatar: Optional["_models.VoiceAgentSessionAvatarConfig"] = None, + animation: Optional["_models.VoiceAgentAnimationConfig"] = None, + tools: Optional[list["_models.VoiceAgentTool"]] = None, + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = None, + reasoning: Optional["_models.RealtimeReasoning"] = None, + parallel_tool_calls: Optional[bool] = None, + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = None, + metadata: Optional[dict[str, str]] = None, + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = None, + greeting: Optional["_models.VoiceAgentGreetingConfig"] = None, + expires_at: Optional[datetime.datetime] = None, ) -> None: ... @overload @@ -16913,34 +28442,126 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.IMAGE_GENERATION # type: ignore + self.type: Literal["realtime"] = "realtime" + self.object: Literal["realtime.session"] = "realtime.session" -class ToolChoiceMCP( - ToolChoiceParam, discriminator="mcp" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """MCP tool. +class VoiceAgentSessionUpdateConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The stable realtime session settings accepted in a ``session.update`` client event. - :ivar type: For MCP tools, the type is always ``mcp``. Required. MCP. - :vartype type: str or ~azure.ai.projects.models.MCP - :ivar server_label: The label of the MCP server to use. Required. - :vartype server_label: str - :ivar name: - :vartype name: str + :ivar type: The session type. Always ``realtime``. Required. Default value is "realtime". + :vartype type: str + :ivar instructions: Instructions applied throughout the session. + :vartype instructions: str + :ivar temperature: The sampling temperature for compatible cascaded pipelines. + :vartype temperature: float + :ivar max_output_tokens: The maximum output-token count for one response. Is either a int type + or a Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar output_modalities: The output modalities enabled for the session. + :vartype output_modalities: list[str or ~azure.ai.projects.models.VoiceOutputModality] + :ivar audio: The input- and output-audio settings for the session. + :vartype audio: ~azure.ai.projects.models.VoiceAgentAudioConfig + :ivar avatar: The avatar settings for the session. + :vartype avatar: ~azure.ai.projects.models.VoiceAgentSessionAvatarConfig + :ivar animation: Animation settings for the session. + :vartype animation: ~azure.ai.projects.models.VoiceAgentAnimationConfig + :ivar tools: Tools available to the session. + :vartype tools: list[~azure.ai.projects.models.VoiceAgentTool] + :ivar tool_choice: Tool-selection behavior for the session. Is one of the following types: + Literal["none"], Literal["auto"], Literal["required"], ToolChoiceFunction, ToolChoiceMCP + :vartype tool_choice: str or str or str or ~azure.ai.projects.models.ToolChoiceFunction or + ~azure.ai.projects.models.ToolChoiceMCP + :ivar reasoning: Reasoning settings for compatible realtime models. + :vartype reasoning: ~azure.ai.projects.models.RealtimeReasoning + :ivar parallel_tool_calls: Whether the model may call multiple tools in parallel. + :vartype parallel_tool_calls: bool + :ivar include: Additional fields to include in service outputs. + :vartype include: list[str or ~azure.ai.projects.models.VoiceAgentSessionIncludeOption] + :ivar metadata: Up to 16 string key-value pairs attached to the session. + :vartype metadata: dict[str, str] + :ivar interim_response: Interim-response settings for latency and tool execution. + :vartype interim_response: ~azure.ai.projects.models.VoiceAgentInterimResponseConfig + :ivar greeting: A proactive assistant greeting started after session configuration. + :vartype greeting: ~azure.ai.projects.models.VoiceAgentGreetingConfig """ - type: Literal[ToolChoiceParamType.MCP] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """For MCP tools, the type is always ``mcp``. Required. MCP.""" - server_label: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The label of the MCP server to use. Required.""" - name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + type: Literal["realtime"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The session type. Always ``realtime``. Required. Default value is \"realtime\".""" + instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Instructions applied throughout the session.""" + temperature: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sampling temperature for compatible cascaded pipelines.""" + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The maximum output-token count for one response. Is either a int type or a Literal[\"inf\"] + type.""" + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The output modalities enabled for the session.""" + audio: Optional["_models.VoiceAgentAudioConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The input- and output-audio settings for the session.""" + avatar: Optional["_models.VoiceAgentSessionAvatarConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The avatar settings for the session.""" + animation: Optional["_models.VoiceAgentAnimationConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Animation settings for the session.""" + tools: Optional[list["_models.VoiceAgentTool"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Tools available to the session.""" + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Tool-selection behavior for the session. Is one of the following types: Literal[\"none\"], + Literal[\"auto\"], Literal[\"required\"], ToolChoiceFunction, ToolChoiceMCP""" + reasoning: Optional["_models.RealtimeReasoning"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Reasoning settings for compatible realtime models.""" + parallel_tool_calls: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the model may call multiple tools in parallel.""" + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Additional fields to include in service outputs.""" + metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Up to 16 string key-value pairs attached to the session.""" + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Interim-response settings for latency and tool execution.""" + greeting: Optional["_models.VoiceAgentGreetingConfig"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """A proactive assistant greeting started after session configuration.""" @overload def __init__( self, *, - server_label: str, - name: Optional[str] = None, + instructions: Optional[str] = None, + temperature: Optional[float] = None, + max_output_tokens: Optional["_unions.VoiceAgentMaxOutputTokens"] = None, + output_modalities: Optional[list[Union[str, "_models.VoiceOutputModality"]]] = None, + audio: Optional["_models.VoiceAgentAudioConfig"] = None, + avatar: Optional["_models.VoiceAgentSessionAvatarConfig"] = None, + animation: Optional["_models.VoiceAgentAnimationConfig"] = None, + tools: Optional[list["_models.VoiceAgentTool"]] = None, + tool_choice: Optional["_unions.VoiceAgentToolChoice"] = None, + reasoning: Optional["_models.RealtimeReasoning"] = None, + parallel_tool_calls: Optional[bool] = None, + include: Optional[list[Union[str, "_models.VoiceAgentSessionIncludeOption"]]] = None, + metadata: Optional[dict[str, str]] = None, + interim_response: Optional["_models.VoiceAgentInterimResponseConfig"] = None, + greeting: Optional["_models.VoiceAgentGreetingConfig"] = None, ) -> None: ... @overload @@ -16952,23 +28573,36 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.MCP # type: ignore + self.type: Literal["realtime"] = "realtime" -class ToolChoiceWebSearchPreview(ToolChoiceParam, discriminator="web_search_preview"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentStaticInterimResponseConfig( + VoiceAgentInterimResponseConfig, discriminator="static_interim_response" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A static interim response selected from configured text. - :ivar type: Required. WEB_SEARCH_PREVIEW. - :vartype type: str or ~azure.ai.projects.models.WEB_SEARCH_PREVIEW + :ivar triggers: Conditions that may trigger one interim response. + :vartype triggers: list[str or ~azure.ai.projects.models.VoiceAgentInterimResponseTrigger] + :ivar latency_threshold_ms: The latency threshold in milliseconds. + :vartype latency_threshold_ms: ~datetime.timedelta + :ivar type: Required. Default value is "static_interim_response". + :vartype type: str + :ivar texts: Candidate text values for the interim response. + :vartype texts: list[str] """ - type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. WEB_SEARCH_PREVIEW.""" + type: Literal["static_interim_response"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"static_interim_response\".""" + texts: Optional[list[str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Candidate text values for the interim response.""" @overload def __init__( self, + *, + triggers: Optional[list[Union[str, "_models.VoiceAgentInterimResponseTrigger"]]] = None, + latency_threshold_ms: Optional[datetime.timedelta] = None, + texts: Optional[list[str]] = None, ) -> None: ... @overload @@ -16980,23 +28614,56 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.WEB_SEARCH_PREVIEW # type: ignore + self.type = "static_interim_response" # type: ignore -class ToolChoiceWebSearchPreview20250311(ToolChoiceParam, discriminator="web_search_preview_2025_03_11"): - """Indicates that the model should use a built-in tool to generate a response. `Learn more about - built-in tools `_. +class VoiceAgentSubagent(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A sibling Foundry text agent that a voice agent may consult as a background specialist. - :ivar type: Required. WEB_SEARCH_PREVIEW_2025_03_11. - :vartype type: str or ~azure.ai.projects.models.WEB_SEARCH_PREVIEW_2025_03_11 + :ivar agent_name: The name of the subagent. The subagent must be in the same project as the + voice agent. Required. + :vartype agent_name: str + :ivar agent_version: The version of the subagent. When omitted, the active version is used. + :vartype agent_version: str + :ivar agent_capabilities: A description of the subagent's capabilities, used by the voice agent + to decide whether to forward a query. Required. + :vartype agent_capabilities: str + :ivar response_policy: Policy for acknowledging forwarded requests and filling gaps while + waiting for this subagent's response. + :vartype response_policy: ~azure.ai.projects.models.VoiceAgentSubagentResponsePolicy + :ivar invoke_timeout_seconds: The wall-clock timeout, in seconds, for each invocation of this + subagent. When omitted, the service timeout is used. + :vartype invoke_timeout_seconds: ~datetime.timedelta """ - type: Literal[ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Required. WEB_SEARCH_PREVIEW_2025_03_11.""" + agent_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the subagent. The subagent must be in the same project as the voice agent. + Required.""" + agent_version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The version of the subagent. When omitted, the active version is used.""" + agent_capabilities: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A description of the subagent's capabilities, used by the voice agent to decide whether to + forward a query. Required.""" + response_policy: Optional["_models.VoiceAgentSubagentResponsePolicy"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Policy for acknowledging forwarded requests and filling gaps while waiting for this subagent's + response.""" + invoke_timeout_seconds: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The wall-clock timeout, in seconds, for each invocation of this subagent. When omitted, the + service timeout is used.""" @overload def __init__( self, + *, + agent_name: str, + agent_capabilities: str, + agent_version: Optional[str] = None, + response_policy: Optional["_models.VoiceAgentSubagentResponsePolicy"] = None, + invoke_timeout_seconds: Optional[datetime.timedelta] = None, ) -> None: ... @overload @@ -17008,35 +28675,27 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolChoiceParamType.WEB_SEARCH_PREVIEW_2025_03_11 # type: ignore -class ToolConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Per-tool configuration that controls tool visibility and search behavior. +class VoiceAgentSubagentConfig(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Configuration for sibling Foundry text agents that a voice agent may consult. - :ivar pin: When true, the tool is always included in agent context and visible in - ``tools/list``. When false (default), the tool is hidden from ``tools/list`` and only - discoverable via ``tool_search``. - :vartype pin: bool - :ivar additional_search_text: Additional text indexed for tool_search. Supplements the native - tool description to improve discoverability. Does not alter ``tools/list`` output. - :vartype additional_search_text: str + :ivar subagents: The sibling Foundry text agents, in the same project, that this voice agent + may consult. Required. + :vartype subagents: list[~azure.ai.projects.models.VoiceAgentSubagent] """ - pin: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """When true, the tool is always included in agent context and visible in ``tools/list``. When - false (default), the tool is hidden from ``tools/list`` and only discoverable via - ``tool_search``.""" - additional_search_text: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Additional text indexed for tool_search. Supplements the native tool description to improve - discoverability. Does not alter ``tools/list`` output.""" + subagents: list["_models.VoiceAgentSubagent"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The sibling Foundry text agents, in the same project, that this voice agent may consult. + Required.""" @overload def __init__( self, *, - pin: Optional[bool] = None, - additional_search_text: Optional[str] = None, + subagents: list["_models.VoiceAgentSubagent"], ) -> None: ... @overload @@ -17050,26 +28709,63 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class ToolDescription(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Description of a tool that can be used by an agent. +class VoiceAgentSubagentResponsePolicy(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Policy for delivering responses while a voice agent waits for a subagent. - :ivar name: The name of the tool. - :vartype name: str - :ivar description: A brief description of the tool's purpose. - :vartype description: str + :ivar immediate_ack: Whether the voice agent provides an immediate acknowledgement before + forwarding a request to a subagent. + :vartype immediate_ack: bool + :ivar gap_filling_interval: The number of seconds without subagent content or user input before + the voice agent provides a gap-filling response. + :vartype gap_filling_interval: ~datetime.timedelta + :ivar ack_instructions: Instructions used to generate the immediate acknowledgement. + :vartype ack_instructions: str + :ivar gap_filling_instructions: Instructions used to generate gap-filling speech while waiting + for progress. + :vartype gap_filling_instructions: str + :ivar enable_delta_progress: Whether progress updates are emitted incrementally instead of only + when the subagent invocation completes. Defaults to ``false``. + :vartype enable_delta_progress: bool + :ivar progress_instructions: Instructions used to summarize streamed subagent progress for + speech. + :vartype progress_instructions: str + :ivar progress_update_interval: The minimum number of seconds between spoken progress updates. + :vartype progress_update_interval: ~datetime.timedelta """ - name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The name of the tool.""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A brief description of the tool's purpose.""" + immediate_ack: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether the voice agent provides an immediate acknowledgement before forwarding a request to a + subagent.""" + gap_filling_interval: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The number of seconds without subagent content or user input before the voice agent provides a + gap-filling response.""" + ack_instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Instructions used to generate the immediate acknowledgement.""" + gap_filling_instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Instructions used to generate gap-filling speech while waiting for progress.""" + enable_delta_progress: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Whether progress updates are emitted incrementally instead of only when the subagent invocation + completes. Defaults to ``false``.""" + progress_instructions: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """Instructions used to summarize streamed subagent progress for speech.""" + progress_update_interval: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-seconds-int" + ) + """The minimum number of seconds between spoken progress updates.""" @overload def __init__( self, *, - name: Optional[str] = None, - description: Optional[str] = None, + immediate_ack: Optional[bool] = None, + gap_filling_interval: Optional[datetime.timedelta] = None, + ack_instructions: Optional[str] = None, + gap_filling_instructions: Optional[str] = None, + enable_delta_progress: Optional[bool] = None, + progress_instructions: Optional[str] = None, + progress_update_interval: Optional[datetime.timedelta] = None, ) -> None: ... @overload @@ -17083,22 +28779,28 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class ToolProjectConnection(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """A project connection resource. +class VoiceAgentTemplateGreetingConfig( + VoiceAgentGreetingConfig, discriminator="template" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A deterministic greeting rendered with the voice agent's structured inputs and synthesized + without model-authored generation. - :ivar project_connection_id: A project connection in a ToolProjectConnectionList attached to - this tool. Required. - :vartype project_connection_id: str + :ivar type: Required. Default value is "template". + :vartype type: str + :ivar text: The Handlebars text template spoken at session start. Required. + :vartype text: str """ - project_connection_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """A project connection in a ToolProjectConnectionList attached to this tool. Required.""" + type: Literal["template"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Required. Default value is \"template\".""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The Handlebars text template spoken at session start. Required.""" @overload def __init__( self, *, - project_connection_id: str, + text: str, ) -> None: ... @overload @@ -17110,35 +28812,45 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "template" # type: ignore -class ToolSearchToolboxTool( - ToolboxTool, discriminator="toolbox_search" +class VoiceAgentToolboxTool( + VoiceAgentTool, discriminator="toolbox" ): # pylint: disable=docstring-keyword-should-match-keyword-only - """A toolbox search tool stored in a toolbox. - - :ivar name: Optional user-defined name for this tool or configuration. - :vartype name: str - :ivar description: Optional user-defined description for this tool or configuration. - :vartype description: str - :ivar tool_configs: Per-tool configuration map. Keys are tool names or ``*`` (catch-all - default). Resolution order: exact tool name match takes priority over ``*``. Unknown tool names - are silently ignored at runtime. - :vartype tool_configs: dict[str, ~azure.ai.projects.models.ToolConfig] - :ivar type: The type of the tool. Always ``toolbox_search``. Required. TOOLBOX_SEARCH. - :vartype type: str or ~azure.ai.projects.models.TOOLBOX_SEARCH - """ + """A reference to a Foundry toolbox, which is a versioned bundle of tools executed through its MCP + endpoint. - type: Literal[ToolboxToolType.TOOLBOX_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the tool. Always ``toolbox_search``. Required. TOOLBOX_SEARCH.""" + :ivar type: The type of the tool. Always ``toolbox``. Required. Default value is "toolbox". + :vartype type: str + :ivar toolbox_name: The name of the toolbox to attach. Required. + :vartype toolbox_name: str + :ivar toolbox_version: The immutable version of the toolbox to attach. Required. + :vartype toolbox_version: str + :ivar response_scheduling: When the toolbox invocation creates a follow-up response. Defaults + to ``when_idle``. Known values are: "silent", "when_idle", "interrupt", and "skip_if_busy". + :vartype response_scheduling: str or ~azure.ai.projects.models.VoiceAgentToolResponseScheduling + """ + + type: Literal["toolbox"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """The type of the tool. Always ``toolbox``. Required. Default value is \"toolbox\".""" + toolbox_name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The name of the toolbox to attach. Required.""" + toolbox_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The immutable version of the toolbox to attach. Required.""" + response_scheduling: Optional[Union[str, "_models.VoiceAgentToolResponseScheduling"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """When the toolbox invocation creates a follow-up response. Defaults to ``when_idle``. Known + values are: \"silent\", \"when_idle\", \"interrupt\", and \"skip_if_busy\".""" @overload def __init__( self, *, - name: Optional[str] = None, - description: Optional[str] = None, - tool_configs: Optional[dict[str, "_models.ToolConfig"]] = None, + toolbox_name: str, + toolbox_version: str, + response_scheduling: Optional[Union[str, "_models.VoiceAgentToolResponseScheduling"]] = None, ) -> None: ... @overload @@ -17150,44 +28862,56 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolboxToolType.TOOLBOX_SEARCH # type: ignore + self.type = "toolbox" # type: ignore -class ToolSearchToolParam( - Tool, discriminator="tool_search" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Tool search tool. +class VoiceAgentTranscriptionPhrase(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A transcribed phrase with timing information. - :ivar type: The type of the tool. Always ``tool_search``. Required. TOOL_SEARCH. - :vartype type: str or ~azure.ai.projects.models.TOOL_SEARCH - :ivar execution: Whether tool search is executed by the server or by the client. Known values - are: "server" and "client". - :vartype execution: str or ~azure.ai.projects.models.ToolSearchExecutionType - :ivar description: - :vartype description: str - :ivar parameters: - :vartype parameters: ~azure.ai.projects.models.EmptyModelParam + :ivar offset_milliseconds: The phrase offset from the beginning of the audio, in milliseconds. + Required. + :vartype offset_milliseconds: ~datetime.timedelta + :ivar duration_milliseconds: The phrase duration in milliseconds. Required. + :vartype duration_milliseconds: ~datetime.timedelta + :ivar text: The transcribed phrase text. Required. + :vartype text: str + :ivar words: Word-level timing details, when available. + :vartype words: list[~azure.ai.projects.models.VoiceAgentTranscriptionWord] + :ivar locale: The detected locale. + :vartype locale: str + :ivar confidence: The transcription confidence score. + :vartype confidence: float """ - type: Literal[ToolType.TOOL_SEARCH] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The type of the tool. Always ``tool_search``. Required. TOOL_SEARCH.""" - execution: Optional[Union[str, "_models.ToolSearchExecutionType"]] = rest_field( - visibility=["read", "create", "update", "delete", "query"] + offset_milliseconds: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" ) - """Whether tool search is executed by the server or by the client. Known values are: \"server\" - and \"client\".""" - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - parameters: Optional["_models.EmptyModelParam"] = rest_field( + """The phrase offset from the beginning of the audio, in milliseconds. Required.""" + duration_milliseconds: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The phrase duration in milliseconds. Required.""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The transcribed phrase text. Required.""" + words: Optional[list["_models.VoiceAgentTranscriptionWord"]] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) + """Word-level timing details, when available.""" + locale: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The detected locale.""" + confidence: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The transcription confidence score.""" @overload def __init__( self, *, - execution: Optional[Union[str, "_models.ToolSearchExecutionType"]] = None, - description: Optional[str] = None, - parameters: Optional["_models.EmptyModelParam"] = None, + offset_milliseconds: datetime.timedelta, + duration_milliseconds: datetime.timedelta, + text: str, + words: Optional[list["_models.VoiceAgentTranscriptionWord"]] = None, + locale: Optional[str] = None, + confidence: Optional[float] = None, ) -> None: ... @overload @@ -17199,37 +28923,38 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = ToolType.TOOL_SEARCH # type: ignore -class ToolUseFineTuningDataGenerationJobOptions( - DataGenerationJobOptions, discriminator="tool_use" -): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only - """The options for a data generation job with ToolUse type. Used only for fine-tuning scenarios. +class VoiceAgentTranscriptionWord(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A time-stamped word in an input-audio transcription. - :ivar max_samples: Maximum number of samples to generate. Required. - :vartype max_samples: int - :ivar train_split: The proportion of the generated data to be used for training when the data - is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. - :vartype train_split: float - :ivar model_options: The LLM model options. - :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions - :ivar type: The data generation job type, which is ToolUse for this model. Required. Tool - calling conversation between user and agent. - :vartype type: str or ~azure.ai.projects.models.TOOL_USE + :ivar text: The transcribed word text. Required. + :vartype text: str + :ivar offset_milliseconds: The word offset from the beginning of the audio, in milliseconds. + Required. + :vartype offset_milliseconds: ~datetime.timedelta + :ivar duration_milliseconds: The word duration in milliseconds. Required. + :vartype duration_milliseconds: ~datetime.timedelta """ - type: Literal[DataGenerationJobType.TOOL_USE] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The data generation job type, which is ToolUse for this model. Required. Tool calling - conversation between user and agent.""" + text: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The transcribed word text. Required.""" + offset_milliseconds: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The word offset from the beginning of the audio, in milliseconds. Required.""" + duration_milliseconds: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The word duration in milliseconds. Required.""" @overload def __init__( self, *, - max_samples: int, - train_split: Optional[float] = None, - model_options: Optional["_models.DataGenerationModelOptions"] = None, + text: str, + offset_milliseconds: datetime.timedelta, + duration_milliseconds: datetime.timedelta, ) -> None: ... @overload @@ -17241,44 +28966,87 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = DataGenerationJobType.TOOL_USE # type: ignore -class TracesDataGenerationJobOptions( - DataGenerationJobOptions, discriminator="traces" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """The options for a data generation job with Traces type. +class VoiceAudioItem(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Metadata for a single conversation item's audio segment. For bring-your-own-storage (BYOS), the + response includes ``blob_uri``, a direct customer-storage URI without a SAS token, that the + customer accesses with their own credentials. For Foundry-managed storage, ``blob_uri`` is + absent and the bytes are streamed through the item's ``/audio/content`` route. - :ivar max_samples: Maximum number of samples to generate. Required. - :vartype max_samples: int - :ivar train_split: The proportion of the generated data to be used for training when the data - is used for fine-tuning. The rest will be used for validation. Value should be between 0 and 1. - :vartype train_split: float - :ivar model_options: The LLM model options. - :vartype model_options: ~azure.ai.projects.models.DataGenerationModelOptions - :ivar type: The data generation job type, which is Traces for this model. Required. Single turn - query and response from agent traces. - :vartype type: str or ~azure.ai.projects.models.TRACES - :ivar redact_private_content: Whether to redact private content from traces. When omitted or - set to true, private content is redacted. Set to false to opt out of redaction. - :vartype redact_private_content: bool + :ivar conversation_id: The id of the conversation the item belongs to. Required. + :vartype conversation_id: str + :ivar item_id: The id of the item this audio belongs to. Required. + :vartype item_id: str + :ivar role: The role the audio belongs to. Known values are: "user" and "agent". + :vartype role: str or ~azure.ai.projects.models.VoiceAudioRole + :ivar format: The container format of the audio. "wav" + :vartype format: str or ~azure.ai.projects.models.VoiceAudioContainerFormat + :ivar codec: The audio codec. Known values are: "pcm16", "pcmu", and "pcma". + :vartype codec: str or ~azure.ai.projects.models.VoiceAudioCodec + :ivar sample_rate: The sample rate in Hz. + :vartype sample_rate: int + :ivar channels: The number of audio channels. + :vartype channels: int + :ivar start_offset_ms: The offset from the session start at which this segment begins. + :vartype start_offset_ms: ~datetime.timedelta + :ivar duration_ms: The duration of the audio segment. + :vartype duration_ms: ~datetime.timedelta + :ivar blob_uri: For bring-your-own-storage (BYOS) recordings only: the URI of the recording in + the customer's own storage, without a SAS token. The customer downloads it using their own + storage credentials. Absent for Foundry-managed storage, where the bytes are streamed via the + item's ``/audio/content`` route instead. + :vartype blob_uri: str """ - type: Literal[DataGenerationJobType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The data generation job type, which is Traces for this model. Required. Single turn query and - response from agent traces.""" - redact_private_content: Optional[bool] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Whether to redact private content from traces. When omitted or set to true, private content is - redacted. Set to false to opt out of redaction.""" + conversation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the conversation the item belongs to. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the item this audio belongs to. Required.""" + role: Optional[Union[str, "_models.VoiceAudioRole"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The role the audio belongs to. Known values are: \"user\" and \"agent\".""" + format: Optional[Union[str, "_models.VoiceAudioContainerFormat"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The container format of the audio. \"wav\"""" + codec: Optional[Union[str, "_models.VoiceAudioCodec"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio codec. Known values are: \"pcm16\", \"pcmu\", and \"pcma\".""" + sample_rate: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sample rate in Hz.""" + channels: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The number of audio channels.""" + start_offset_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The offset from the session start at which this segment begins.""" + duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The duration of the audio segment.""" + blob_uri: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """For bring-your-own-storage (BYOS) recordings only: the URI of the recording in the customer's + own storage, without a SAS token. The customer downloads it using their own storage + credentials. Absent for Foundry-managed storage, where the bytes are streamed via the item's + ``/audio/content`` route instead.""" @overload def __init__( self, *, - max_samples: int, - train_split: Optional[float] = None, - model_options: Optional["_models.DataGenerationModelOptions"] = None, - redact_private_content: Optional[bool] = None, + conversation_id: str, + item_id: str, + role: Optional[Union[str, "_models.VoiceAudioRole"]] = None, + format: Optional[Union[str, "_models.VoiceAudioContainerFormat"]] = None, + codec: Optional[Union[str, "_models.VoiceAudioCodec"]] = None, + sample_rate: Optional[int] = None, + channels: Optional[int] = None, + start_offset_ms: Optional[datetime.timedelta] = None, + duration_ms: Optional[datetime.timedelta] = None, + blob_uri: Optional[str] = None, ) -> None: ... @overload @@ -17290,68 +29058,83 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = DataGenerationJobType.TRACES # type: ignore -class TracesDataGenerationJobSource( - DataGenerationJobSource, discriminator="traces" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Traces source for data generation jobs — conversation traces from Application Insights. +class VoiceConversation(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """A persisted voice conversation. The Foundry envelope that owns a voice agent's stored + transcript, responses, per-turn metrics, and audio. It is the parent, retention, and delete + boundary: deleting it cascades to its responses, items, metrics, and audio. When finalization + fails, any partial persisted responses, items, and item audio remain readable. - :ivar description: Optional description of what this source represents — helps the pipeline - interpret its content (e.g., 'Company refund policy document' or 'Describes the agent's core - capabilities'). - :vartype description: str - :ivar type: The source type for this source, which is Traces. Required. Traces source — - conversation traces from Application Insights. - :vartype type: str or ~azure.ai.projects.models.TRACES - :ivar agent_id: The unique agent ID used to filter traces. Provide either ``agent_id`` or - ``agent_name`` — at least one is required. - :vartype agent_id: str - :ivar agent_name: The agent name to fetch traces for. Provide either ``agent_id`` or - ``agent_name`` — at least one is required. - :vartype agent_name: str - :ivar agent_version: The agent version. If not specified, traces for ALL versions of the agent - are included within the time window. - :vartype agent_version: str - :ivar start_time: Start of the time window (Unix timestamp in seconds) for fetching traces. + :ivar id: The unique id of the conversation. Required. + :vartype id: str + :ivar object: The object type. Always ``voice.conversation``. Required. Default value is + "voice.conversation". + :vartype object: str + :ivar status: The lifecycle status of the conversation. Required. Known values are: + "in_progress", "completed", and "failed". + :vartype status: str or ~azure.ai.projects.models.VoiceConversationStatus + :ivar created_at: The Unix timestamp (in seconds) for when the conversation was created. Required. - :vartype start_time: ~datetime.datetime - :ivar end_time: End of the time window (Unix timestamp in seconds). Defaults to current time. - :vartype end_time: ~datetime.datetime + :vartype created_at: ~datetime.datetime + :ivar completed_at: The Unix timestamp (in seconds) for when session and persistence + finalization reached the terminal ``completed`` or ``failed`` status. Absent while ``status`` + is ``in_progress``. + :vartype completed_at: ~datetime.datetime + :ivar metadata: A set of key-value pairs attached to the conversation. + :vartype metadata: dict[str, str] + :ivar usage: Final aggregate token usage across all responses in this conversation. Absent + while ``status`` is ``in_progress`` and populated after successful ``completed`` finalization; + it may be absent when ``status`` is ``failed``, and values are not guaranteed to be reported + incrementally. + :vartype usage: ~azure.ai.projects.models.RealtimeResponseUsage + :ivar last_error: The terminal error that prevented persistence finalization. Present only when + ``status`` is ``failed``. + :vartype last_error: ~azure.ai.projects.models.ApiError """ - type: Literal[DataGenerationJobSourceType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The source type for this source, which is Traces. Required. Traces source — conversation traces - from Application Insights.""" - agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique agent ID used to filter traces. Provide either ``agent_id`` or ``agent_name`` — at - least one is required.""" - agent_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The agent name to fetch traces for. Provide either ``agent_id`` or ``agent_name`` — at least - one is required.""" - agent_version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The agent version. If not specified, traces for ALL versions of the agent are included within - the time window.""" - start_time: datetime.datetime = rest_field( + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique id of the conversation. Required.""" + object: Literal["voice.conversation"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The object type. Always ``voice.conversation``. Required. Default value is + \"voice.conversation\".""" + status: Union[str, "_models.VoiceConversationStatus"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The lifecycle status of the conversation. Required. Known values are: \"in_progress\", + \"completed\", and \"failed\".""" + created_at: datetime.datetime = rest_field( visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" ) - """Start of the time window (Unix timestamp in seconds) for fetching traces. Required.""" - end_time: Optional[datetime.datetime] = rest_field( + """The Unix timestamp (in seconds) for when the conversation was created. Required.""" + completed_at: Optional[datetime.datetime] = rest_field( visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" ) - """End of the time window (Unix timestamp in seconds). Defaults to current time.""" + """The Unix timestamp (in seconds) for when session and persistence finalization reached the + terminal ``completed`` or ``failed`` status. Absent while ``status`` is ``in_progress``.""" + metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A set of key-value pairs attached to the conversation.""" + usage: Optional["_models.RealtimeResponseUsage"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Final aggregate token usage across all responses in this conversation. Absent while ``status`` + is ``in_progress`` and populated after successful ``completed`` finalization; it may be absent + when ``status`` is ``failed``, and values are not guaranteed to be reported incrementally.""" + last_error: Optional["_models.ApiError"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The terminal error that prevented persistence finalization. Present only when ``status`` is + ``failed``.""" @overload def __init__( self, *, - start_time: datetime.datetime, - description: Optional[str] = None, - agent_id: Optional[str] = None, - agent_name: Optional[str] = None, - agent_version: Optional[str] = None, - end_time: Optional[datetime.datetime] = None, + id: str, # pylint: disable=redefined-builtin + status: Union[str, "_models.VoiceConversationStatus"], + created_at: datetime.datetime, + completed_at: Optional[datetime.datetime] = None, + metadata: Optional[dict[str, str]] = None, + usage: Optional["_models.RealtimeResponseUsage"] = None, + last_error: Optional["_models.ApiError"] = None, ) -> None: ... @overload @@ -17363,71 +29146,120 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = DataGenerationJobSourceType.TRACES # type: ignore + self.object: Literal["voice.conversation"] = "voice.conversation" -class TracesEvaluatorGenerationJobSource( - EvaluatorGenerationJobSource, discriminator="traces" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Traces source for evaluator generation jobs — conversation traces from Application Insights. +class VoiceConversationEngine(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """An engine that owns conversation handling for a voice agent. - :ivar description: Optional description of what this source represents — helps the pipeline - interpret its content (e.g., 'Company refund policy document' or 'Describes the agent's core - capabilities'). - :vartype description: str - :ivar type: The source type for this source, which is Traces. Required. Traces source — - conversation traces from Application Insights. - :vartype type: str or ~azure.ai.projects.models.TRACES - :ivar agent_id: The unique agent ID used to filter traces. Provide either ``agent_id`` or - ``agent_name`` — at least one is required. - :vartype agent_id: str - :ivar agent_name: The agent name to fetch traces for. Provide either ``agent_id`` or - ``agent_name`` — at least one is required. - :vartype agent_name: str - :ivar agent_version: The agent version. If not specified, traces for ALL versions of the agent - are included within the time window. - :vartype agent_version: str - :ivar start_time: Start of the time window (Unix timestamp in seconds) for fetching traces. - Required. - :vartype start_time: ~datetime.datetime - :ivar end_time: End of the time window (Unix timestamp in seconds). Defaults to current time. - :vartype end_time: ~datetime.datetime + You probably want to use the sub-classes and not this class directly. Known sub-classes are: + VoiceHostedAgentConversationEngine + + :ivar type: The conversation engine type. Required. Default value is None. + :vartype type: str """ - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Optional description of what this source represents — helps the pipeline interpret its content - (e.g., 'Company refund policy document' or 'Describes the agent's core capabilities').""" - type: Literal[EvaluatorGenerationJobSourceType.TRACES] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The source type for this source, which is Traces. Required. Traces source — conversation traces - from Application Insights.""" - agent_id: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The unique agent ID used to filter traces. Provide either ``agent_id`` or ``agent_name`` — at - least one is required.""" - agent_name: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The agent name to fetch traces for. Provide either ``agent_id`` or ``agent_name`` — at least - one is required.""" - agent_version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The agent version. If not specified, traces for ALL versions of the agent are included within - the time window.""" - start_time: datetime.datetime = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + __mapping__: dict[str, _Model] = {} + type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) + """The conversation engine type. Required. Default value is None.""" + + @overload + def __init__( + self, + *, + type: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class VoiceGeneratedAudioItem(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Metadata for a conversation item's generated audio. For bring-your-own-storage (BYOS), the + response includes ``blob_uri``, a direct customer-storage URI without a SAS token, that the + customer accesses with their own credentials. For Foundry-managed storage, ``blob_uri`` is + absent and the bytes are streamed through the item's ``/audio/generated/content`` route. + + :ivar conversation_id: The id of the conversation the item belongs to. Required. + :vartype conversation_id: str + :ivar item_id: The id of the item this audio belongs to. Required. + :vartype item_id: str + :ivar role: The role the audio belongs to. Known values are: "user" and "agent". + :vartype role: str or ~azure.ai.projects.models.VoiceAudioRole + :ivar format: The container format of the audio. "wav" + :vartype format: str or ~azure.ai.projects.models.VoiceAudioContainerFormat + :ivar codec: The audio codec. Known values are: "pcm16", "pcmu", and "pcma". + :vartype codec: str or ~azure.ai.projects.models.VoiceAudioCodec + :ivar sample_rate: The sample rate in Hz. + :vartype sample_rate: int + :ivar channels: The number of audio channels. + :vartype channels: int + :ivar start_offset_ms: The offset from the session start at which this segment begins. + :vartype start_offset_ms: ~datetime.timedelta + :ivar duration_ms: The duration of the audio segment. + :vartype duration_ms: ~datetime.timedelta + :ivar blob_uri: For bring-your-own-storage (BYOS) recordings only: the URI of the generated + audio in the customer's own storage, without a SAS token. The customer downloads it using their + own storage credentials. Absent for Foundry-managed storage, where the bytes are streamed via + the item's ``/audio/generated/content`` route instead. + :vartype blob_uri: str + """ + + conversation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the conversation the item belongs to. Required.""" + item_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the item this audio belongs to. Required.""" + role: Optional[Union[str, "_models.VoiceAudioRole"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """Start of the time window (Unix timestamp in seconds) for fetching traces. Required.""" - end_time: Optional[datetime.datetime] = rest_field( - visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + """The role the audio belongs to. Known values are: \"user\" and \"agent\".""" + format: Optional[Union[str, "_models.VoiceAudioContainerFormat"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] ) - """End of the time window (Unix timestamp in seconds). Defaults to current time.""" + """The container format of the audio. \"wav\"""" + codec: Optional[Union[str, "_models.VoiceAudioCodec"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio codec. Known values are: \"pcm16\", \"pcmu\", and \"pcma\".""" + sample_rate: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sample rate in Hz.""" + channels: Optional[int] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The number of audio channels.""" + start_offset_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The offset from the session start at which this segment begins.""" + duration_ms: Optional[datetime.timedelta] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The duration of the audio segment.""" + blob_uri: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """For bring-your-own-storage (BYOS) recordings only: the URI of the generated audio in the + customer's own storage, without a SAS token. The customer downloads it using their own storage + credentials. Absent for Foundry-managed storage, where the bytes are streamed via the item's + ``/audio/generated/content`` route instead.""" @overload def __init__( self, *, - start_time: datetime.datetime, - description: Optional[str] = None, - agent_id: Optional[str] = None, - agent_name: Optional[str] = None, - agent_version: Optional[str] = None, - end_time: Optional[datetime.datetime] = None, + conversation_id: str, + item_id: str, + role: Optional[Union[str, "_models.VoiceAudioRole"]] = None, + format: Optional[Union[str, "_models.VoiceAudioContainerFormat"]] = None, + codec: Optional[Union[str, "_models.VoiceAudioCodec"]] = None, + sample_rate: Optional[int] = None, + channels: Optional[int] = None, + start_offset_ms: Optional[datetime.timedelta] = None, + duration_ms: Optional[datetime.timedelta] = None, + blob_uri: Optional[str] = None, ) -> None: ... @overload @@ -17439,29 +29271,43 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = EvaluatorGenerationJobSourceType.TRACES # type: ignore -class UpdateModelVersionRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Request body for updating a model version. Only description and tags can be modified. +class VoiceHostedAgentConversationEngine( + VoiceConversationEngine, discriminator="hosted_agent" +): # pylint: disable=docstring-keyword-should-match-keyword-only + """A closed reference to the hosted text agent that owns conversation handling for a voice agent. + The hosted agent is resolved within the same project and must support the ``invocations_ws`` + protocol, Voice Live compatibility, and Bridge Protocol 1.0. - :ivar description: The asset description text. - :vartype description: str - :ivar tags: Tag dictionary. Tags can be added, removed, and updated. - :vartype tags: dict[str, str] + :ivar type: Selects a hosted Foundry agent as the conversation engine. Required. Default value + is "hosted_agent". + :vartype type: str + :ivar name: The non-empty DNS-like name of the target hosted text agent in the same project. + Required. + :vartype name: str + :ivar version: The target agent version. Omit this property to select the latest version when + the voice session starts. When supplied, use a positive integer or + ``draft-{positive-unix-timestamp}`` whose numeric component fits in a signed 64-bit integer. + :vartype version: str """ - description: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The asset description text.""" - tags: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """Tag dictionary. Tags can be added, removed, and updated.""" + type: Literal["hosted_agent"] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore + """Selects a hosted Foundry agent as the conversation engine. Required. Default value is + \"hosted_agent\".""" + name: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The non-empty DNS-like name of the target hosted text agent in the same project. Required.""" + version: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The target agent version. Omit this property to select the latest version when the voice + session starts. When supplied, use a positive integer or ``draft-{positive-unix-timestamp}`` + whose numeric component fits in a signed 64-bit integer.""" @overload def __init__( self, *, - description: Optional[str] = None, - tags: Optional[dict[str, str]] = None, + name: str, + version: Optional[str] = None, ) -> None: ... @overload @@ -17473,25 +29319,73 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + self.type = "hosted_agent" # type: ignore -class UpdateToolboxRequest(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """UpdateToolboxRequest. +class VoiceRecording(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Metadata for the merged, whole-call stereo recording of a voice conversation (user audio on the + left channel, agent audio on the right). Built once from the per-turn segments after the + session ends and durably cached. The common metadata (format, sample rate, channels, channel + layout, duration) is returned for both Foundry-managed and bring-your-own-storage (BYOS) + recordings. For BYOS the response also includes ``blob_uri``, the URI of the recording in the + customer's own storage (no SAS token), which the customer downloads using their own storage + credentials. For Foundry-managed storage ``blob_uri`` is absent and the bytes are streamed via + the ``/audio/content`` route instead. - :ivar default_version: The version identifier that the toolbox should point to. When set, the - toolbox's default version will resolve to this version instead of the latest. Required. - :vartype default_version: str + :ivar conversation_id: The id of the conversation this recording belongs to. Required. + :vartype conversation_id: str + :ivar format: The container format of the recording. Required. "wav" + :vartype format: str or ~azure.ai.projects.models.VoiceAudioContainerFormat + :ivar sample_rate: The sample rate of the recording in Hz, e.g. 24000. Required. + :vartype sample_rate: int + :ivar channels: The number of audio channels. The merged recording is stereo (``2``). Required. + :vartype channels: int + :ivar channel_layout: The role assigned to each stereo channel. Required. + :vartype channel_layout: ~azure.ai.projects.models.VoiceRecordingChannelLayout + :ivar duration_ms: The total duration of the recording. Required. + :vartype duration_ms: ~datetime.timedelta + :ivar blob_uri: For bring-your-own-storage (BYOS) recordings only: the URI of the recording in + the customer's own storage, without a SAS token. The customer downloads it using their own + storage credentials. Absent for Foundry-managed storage, where the bytes are streamed via the + ``/audio/content`` route instead. + :vartype blob_uri: str """ - default_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The version identifier that the toolbox should point to. When set, the toolbox's default - version will resolve to this version instead of the latest. Required.""" + conversation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the conversation this recording belongs to. Required.""" + format: Union[str, "_models.VoiceAudioContainerFormat"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The container format of the recording. Required. \"wav\"""" + sample_rate: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sample rate of the recording in Hz, e.g. 24000. Required.""" + channels: int = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The number of audio channels. The merged recording is stereo (``2``). Required.""" + channel_layout: "_models.VoiceRecordingChannelLayout" = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The role assigned to each stereo channel. Required.""" + duration_ms: datetime.timedelta = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="duration-milliseconds-int" + ) + """The total duration of the recording. Required.""" + blob_uri: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """For bring-your-own-storage (BYOS) recordings only: the URI of the recording in the customer's + own storage, without a SAS token. The customer downloads it using their own storage + credentials. Absent for Foundry-managed storage, where the bytes are streamed via the + ``/audio/content`` route instead.""" @overload def __init__( self, *, - default_version: str, + conversation_id: str, + format: Union[str, "_models.VoiceAudioContainerFormat"], + sample_rate: int, + channels: int, + channel_layout: "_models.VoiceRecordingChannelLayout", + duration_ms: datetime.timedelta, + blob_uri: Optional[str] = None, ) -> None: ... @overload @@ -17505,37 +29399,96 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class UserProfileMemoryItem( - MemoryItem, discriminator="user_profile" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """A memory item specifically containing user profile information extracted from conversations, - such as preferences, interests, and personal details. +class VoiceRecordingChannelLayout(_Model): # pylint: disable=docstring-missing-param + """The role assigned to each channel of a merged stereo voice recording. - :ivar memory_id: The unique ID of the memory item. Required. - :vartype memory_id: str - :ivar updated_at: The last update time of the memory item. Required. - :vartype updated_at: ~datetime.datetime - :ivar scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :vartype scope: str - :ivar content: The content of the memory. Required. - :vartype content: str - :ivar kind: The kind of the memory item. Required. User profile information extracted from - conversations. - :vartype kind: str or ~azure.ai.projects.models.USER_PROFILE + :ivar left: The role carried on the left channel. Always ``user``. Required. Default value is + "user". + :vartype left: str + :ivar right: The role carried on the right channel. Always ``agent``. Required. Default value + is "agent". + :vartype right: str """ - kind: Literal[MemoryItemKind.USER_PROFILE] = rest_discriminator(name="kind", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """The kind of the memory item. Required. User profile information extracted from conversations.""" + left: Literal["user"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The role carried on the left channel. Always ``user``. Required. Default value is \"user\".""" + right: Literal["agent"] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The role carried on the right channel. Always ``agent``. Required. Default value is \"agent\".""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.left: Literal["user"] = "user" + self.right: Literal["agent"] = "agent" + + +class VoiceResponseBase(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Properties shared by persisted voice responses. + + :ivar object: The object type, must be ``realtime.response``. Default value is + "realtime.response". + :vartype object: str + :ivar status: The final status of the response (``completed``, ``cancelled``, ``failed``, or + ``incomplete``, ``in_progress``). Is one of the following types: Literal["completed"], + Literal["cancelled"], Literal["failed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str or str or str + :ivar status_details: Additional details about the status. + :vartype status_details: ~azure.ai.projects.models.RealtimeResponseStatusDetails + :ivar usage: Usage statistics for the Response, this will correspond to billing. A Realtime API + session will maintain a conversation context and append new Items to the Conversation, thus + output from previous turns (text and audio tokens) will become the input for later turns. + :vartype usage: ~azure.ai.projects.models.RealtimeResponseUsage + :ivar output_modalities: The set of modalities the model used to respond, currently the only + possible values are ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text + transcript. Setting the output to mode ``text`` will disable audio output from the model. + :vartype output_modalities: list[str or str] + :ivar max_output_tokens: Maximum number of output tokens for a single assistant response, + inclusive of tool calls, that was used in this response. Is either a int type or a + Literal["inf"] type. + :vartype max_output_tokens: int or str + """ + + object: Optional[Literal["realtime.response"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The object type, must be ``realtime.response``. Default value is \"realtime.response\".""" + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The final status of the response (``completed``, ``cancelled``, ``failed``, or ``incomplete``, + ``in_progress``). Is one of the following types: Literal[\"completed\"], + Literal[\"cancelled\"], Literal[\"failed\"], Literal[\"incomplete\"], Literal[\"in_progress\"]""" + status_details: Optional["_models.RealtimeResponseStatusDetails"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Additional details about the status.""" + usage: Optional["_models.RealtimeResponseUsage"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Usage statistics for the Response, this will correspond to billing. A Realtime API session will + maintain a conversation context and append new Items to the Conversation, thus output from + previous turns (text and audio tokens) will become the input for later turns.""" + output_modalities: Optional[list[Literal["text", "audio"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The set of modalities the model used to respond, currently the only possible values are + ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text transcript. Setting the + output to mode ``text`` will disable audio output from the model.""" + max_output_tokens: Optional[Union[int, Literal["inf"]]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """Maximum number of output tokens for a single assistant response, inclusive of tool calls, that + was used in this response. Is either a int type or a Literal[\"inf\"] type.""" @overload def __init__( self, *, - memory_id: str, - updated_at: datetime.datetime, - scope: str, - content: str, + object: Optional[Literal["realtime.response"]] = None, + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = None, + status_details: Optional["_models.RealtimeResponseStatusDetails"] = None, + usage: Optional["_models.RealtimeResponseUsage"] = None, + output_modalities: Optional[list[Literal["text", "audio"]]] = None, + max_output_tokens: Optional[Union[int, Literal["inf"]]] = None, ) -> None: ... @overload @@ -17547,28 +29500,105 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.kind = MemoryItemKind.USER_PROFILE # type: ignore - -class VersionIndicator(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """Version indicator determining which agent version backs the session. - You probably want to use the sub-classes and not this class directly. Known sub-classes are: - VersionRefIndicator +class VoiceResponse(VoiceResponseBase): # pylint: disable=docstring-keyword-should-match-keyword-only + """A persisted voice response representing one model inference turn within a conversation. In list + results the ``output`` projection may be omitted; retrieve the full response (``GET + .../responses/{response_id}``) or the paged response-items route (``GET + .../responses/{response_id}/items``) for its output items. ``created_at``/``completed_at`` are + Foundry durable ordering extensions. - :ivar type: The type of version indicator. Required. "version_ref" - :vartype type: str or ~azure.ai.projects.models.VersionIndicatorType + :ivar object: The object type, must be ``realtime.response``. Default value is + "realtime.response". + :vartype object: str + :ivar status: The final status of the response (``completed``, ``cancelled``, ``failed``, or + ``incomplete``, ``in_progress``). Is one of the following types: Literal["completed"], + Literal["cancelled"], Literal["failed"], Literal["incomplete"], Literal["in_progress"] + :vartype status: str or str or str or str or str + :ivar status_details: Additional details about the status. + :vartype status_details: ~azure.ai.projects.models.RealtimeResponseStatusDetails + :ivar usage: Usage statistics for the Response, this will correspond to billing. A Realtime API + session will maintain a conversation context and append new Items to the Conversation, thus + output from previous turns (text and audio tokens) will become the input for later turns. + :vartype usage: ~azure.ai.projects.models.RealtimeResponseUsage + :ivar output_modalities: The set of modalities the model used to respond, currently the only + possible values are ``[\\"audio\\"]``, ``[\\"text\\"]``. Audio output always include a text + transcript. Setting the output to mode ``text`` will disable audio output from the model. + :vartype output_modalities: list[str or str] + :ivar max_output_tokens: Maximum number of output tokens for a single assistant response, + inclusive of tool calls, that was used in this response. Is either a int type or a + Literal["inf"] type. + :vartype max_output_tokens: int or str + :ivar id: The unique id of the response. Required. + :vartype id: str + :ivar output: The output items produced by the response. May be omitted in list results; + retrieve the full response (GET .../responses/{response_id}) or use the paged response-items + route (GET .../responses/{response_id}/items) for its output items. Each item's ``response_id`` + also links it back to this response in the conversation-level items list. + :vartype output: list[~azure.ai.projects.models.RealtimeConversationItem] + :ivar conversation_id: The id of the conversation this response belongs to. Required. + :vartype conversation_id: str + :ivar audio: The audio configuration used for the response, including the voice and audio + format used for output. + :vartype audio: ~azure.ai.projects.models.VoiceResponseAudio + :ivar metadata: A set of key-value pairs attached to the response. + :vartype metadata: dict[str, str] + :ivar temperature: The sampling temperature used for the response. + :vartype temperature: float + :ivar created_at: The Unix timestamp (in seconds) for when the response was created. + :vartype created_at: ~datetime.datetime + :ivar completed_at: The Unix timestamp (in seconds) for when the response completed. + :vartype completed_at: ~datetime.datetime """ - __mapping__: dict[str, _Model] = {} - type: str = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) - """The type of version indicator. Required. \"version_ref\"""" + id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The unique id of the response. Required.""" + output: Optional[list["_models.RealtimeConversationItem"]] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The output items produced by the response. May be omitted in list results; retrieve the full + response (GET .../responses/{response_id}) or use the paged response-items route (GET + .../responses/{response_id}/items) for its output items. Each item's ``response_id`` also links + it back to this response in the conversation-level items list.""" + conversation_id: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The id of the conversation this response belongs to. Required.""" + audio: Optional["_models.VoiceResponseAudio"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio configuration used for the response, including the voice and audio format used for + output.""" + metadata: Optional[dict[str, str]] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """A set of key-value pairs attached to the response.""" + temperature: Optional[float] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The sampling temperature used for the response.""" + created_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the response was created.""" + completed_at: Optional[datetime.datetime] = rest_field( + visibility=["read", "create", "update", "delete", "query"], format="unix-timestamp" + ) + """The Unix timestamp (in seconds) for when the response completed.""" @overload def __init__( self, *, - type: str, + id: str, # pylint: disable=redefined-builtin + conversation_id: str, + object: Optional[Literal["realtime.response"]] = None, + status: Optional[Literal["completed", "cancelled", "failed", "incomplete", "in_progress"]] = None, + status_details: Optional["_models.RealtimeResponseStatusDetails"] = None, + usage: Optional["_models.RealtimeResponseUsage"] = None, + output_modalities: Optional[list[Literal["text", "audio"]]] = None, + max_output_tokens: Optional[Union[int, Literal["inf"]]] = None, + output: Optional[list["_models.RealtimeConversationItem"]] = None, + audio: Optional["_models.VoiceResponseAudio"] = None, + metadata: Optional[dict[str, str]] = None, + temperature: Optional[float] = None, + created_at: Optional[datetime.datetime] = None, + completed_at: Optional[datetime.datetime] = None, ) -> None: ... @overload @@ -17582,28 +29612,23 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class VersionRefIndicator( - VersionIndicator, discriminator="version_ref" -): # pylint: disable=docstring-keyword-should-match-keyword-only - """Version indicator that references a specific agent version by name. +class VoiceResponseAudio(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """Audio configuration for a response. Follows the OpenAI Realtime GA ``audio`` object shape. - :ivar type: Discriminator value for version_ref. Required. Direct reference to a specific agent - version. - :vartype type: str or ~azure.ai.projects.models.VERSION_REF - :ivar agent_version: The agent version identifier returned by the agent version APIs. Required. - :vartype agent_version: str + :ivar output: The audio output configuration used for the response. + :vartype output: ~azure.ai.projects.models.VoiceResponseAudioOutput """ - type: Literal[VersionIndicatorType.VERSION_REF] = rest_discriminator(name="type", visibility=["read", "create", "update", "delete", "query"]) # type: ignore - """Discriminator value for version_ref. Required. Direct reference to a specific agent version.""" - agent_version: str = rest_field(visibility=["read", "create", "update", "delete", "query"]) - """The agent version identifier returned by the agent version APIs. Required.""" + output: Optional["_models.VoiceResponseAudioOutput"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio output configuration used for the response.""" @overload def __init__( self, *, - agent_version: str, + output: Optional["_models.VoiceResponseAudioOutput"] = None, ) -> None: ... @overload @@ -17615,26 +29640,47 @@ def __init__(self, mapping: Mapping[str, Any]) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) - self.type = VersionIndicatorType.VERSION_REF # type: ignore -class VersionSelector(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only - """VersionSelector. +class VoiceResponseAudioOutput(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only + """The flat response audio-output projection, with optional ``voice``, ``voice_type``, + ``voice_locale``, and ``format`` fields. - :ivar version_selection_rules: Required. - :vartype version_selection_rules: list[~azure.ai.projects.models.VersionSelectionRule] + :ivar voice: The voice name used for the response's audio output. + :vartype voice: str + :ivar voice_type: The extensible provider/type of the voice used for the response's audio + output. Known values are: "openai", "azure-standard", "azure-custom", "azure-personal", + "avatar-voice-sync", and "azure-realtime-native". + :vartype voice_type: str or ~azure.ai.projects.models.VoiceType + :ivar voice_locale: The BCP-47 locale of the voice used for the response's audio output. + :vartype voice_locale: str + :ivar format: The audio format used for the response's audio output. + :vartype format: ~azure.ai.projects.models.RealtimeAudioFormats """ - version_selection_rules: list["_models.VersionSelectionRule"] = rest_field( + voice: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The voice name used for the response's audio output.""" + voice_type: Optional[Union[str, "_models.VoiceType"]] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) - """Required.""" + """The extensible provider/type of the voice used for the response's audio output. Known values + are: \"openai\", \"azure-standard\", \"azure-custom\", \"azure-personal\", + \"avatar-voice-sync\", and \"azure-realtime-native\".""" + voice_locale: Optional[str] = rest_field(visibility=["read", "create", "update", "delete", "query"]) + """The BCP-47 locale of the voice used for the response's audio output.""" + format: Optional["_models.RealtimeAudioFormats"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The audio format used for the response's audio output.""" @overload def __init__( self, *, - version_selection_rules: list["_models.VersionSelectionRule"], + voice: Optional[str] = None, + voice_type: Optional[Union[str, "_models.VoiceType"]] = None, + voice_locale: Optional[str] = None, + format: Optional["_models.RealtimeAudioFormats"] = None, ) -> None: ... @overload diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_patch.py b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_patch.py index b3c41b694c6a..75f0f3489461 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/models/_patch.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/models/_patch.py @@ -57,6 +57,10 @@ _AgentDefinitionOptInKeys.WORKFLOW_AGENTS_V1_PREVIEW.value, _AgentDefinitionOptInKeys.EXTERNAL_AGENTS_V1_PREVIEW.value, _AgentDefinitionOptInKeys.DRAFT_AGENTS_V1_PREVIEW.value, + _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value, + _AgentDefinitionOptInKeys.DIGITAL_WORKER_V1_PREVIEW.value, + _AgentDefinitionOptInKeys.GITHUB_COPILOT_V1_PREVIEW.value, + _AgentDefinitionOptInKeys.SKILLS_V1_PREVIEW.value, _FoundryFeaturesOptInKeys.AGENTS_OPTIMIZATION_V2_PREVIEW.value, _FoundryFeaturesOptInKeys.MODEL_ROUTER_CONTROLS_V1_PREVIEW.value, ] @@ -73,6 +77,7 @@ "routines": _FoundryFeaturesOptInKeys.ROUTINES_V2_PREVIEW.value, "schedules": _FoundryFeaturesOptInKeys.SCHEDULES_V1_PREVIEW.value, "skills": _FoundryFeaturesOptInKeys.SKILLS_V1_PREVIEW.value, + "voice_agents": _AgentDefinitionOptInKeys.VOICE_AGENTS_V1_PREVIEW.value, "datasets": _FoundryFeaturesOptInKeys.DATA_GENERATION_JOBS_V1_PREVIEW.value, "agents": _AGENT_OPERATION_FEATURE_HEADERS, } diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_operations.py b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_operations.py index c48934cf5f7f..5231c3482fd0 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_operations.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_operations.py @@ -1,4 +1,4 @@ -# pylint: disable=too-many-lines +# pylint: disable=line-too-long,useless-suppression,too-many-lines # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -10,11 +10,11 @@ import datetime from io import IOBase import json -from typing import Any, Callable, IO, Iterator, Literal, Optional, TypeVar, Union, cast, overload +from typing import Any, Callable, IO, Iterator, Literal, Optional, TYPE_CHECKING, TypeVar, Union, cast, overload import urllib.parse import uuid -from azure.core import PipelineClient +from azure.core import MatchConditions, PipelineClient from azure.core.exceptions import ( ClientAuthenticationError, HttpResponseError, @@ -37,8 +37,10 @@ from .._configuration import AIProjectClientConfiguration from .._utils.model_base import Model as _Model, SdkJSONEncoder, _deserialize, _failsafe_deserialize from .._utils.serialization import Deserializer, Serializer -from .._utils.utils import prepare_multipart_form_data +from .._utils.utils import prep_if_match, prep_if_none_match, prepare_multipart_form_data +if TYPE_CHECKING: + from .. import _unions JSON = MutableMapping[str, Any] _Unset: Any = object() T = TypeVar("T") @@ -1449,6 +1451,34 @@ def build_toolboxes_get_version_request(name: str, version: str, **kwargs: Any) return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) +def build_toolboxes_invoke_latest_toolbox_mcp_request( # pylint: disable=name-too-long + name: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: str = kwargs.pop("content_type") + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "*/*") + + # Construct URL + _url = "/toolboxes/{name}:invoke_mcp" + path_format_arguments = { + "name": _SERIALIZER.url("name", name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["content-type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + def build_toolboxes_update_request(name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -1513,6 +1543,166 @@ def build_toolboxes_delete_version_request(name: str, version: str, **kwargs: An return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) +def build_beta_agents_create_from_prompt_request(**kwargs: Any) -> HttpRequest: # pylint: disable=name-too-long + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents:generate" + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_agents_create_optimization_job_request( # pylint: disable=name-too-long + *, operation_id: Optional[str] = None, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agent_optimization_jobs" + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if operation_id is not None: + _headers["Operation-Id"] = _SERIALIZER.header("operation_id", operation_id, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_agents_get_optimization_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agent_optimization_jobs/{jobId}" + path_format_arguments = { + "jobId": _SERIALIZER.url("job_id", job_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_agents_list_optimization_jobs_request( # pylint: disable=name-too-long + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + status: Optional[Union[str, _models.JobStatus]] = None, + agent_name: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agent_optimization_jobs" + + # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + if status is not None: + _params["status"] = _SERIALIZER.query("status", status, "str") + if agent_name is not None: + _params["agent_name"] = _SERIALIZER.query("agent_name", agent_name, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_agents_cancel_optimization_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agent_optimization_jobs/{jobId}:cancel" + path_format_arguments = { + "jobId": _SERIALIZER.url("job_id", job_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_agents_delete_optimization_job_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/agent_optimization_jobs/{jobId}" + path_format_arguments = { + "jobId": _SERIALIZER.url("job_id", job_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + + def build_beta_agent_insight_monitors_list_request( # pylint: disable=name-too-long *, after: Optional[str] = None, @@ -3944,34 +4134,48 @@ def build_beta_datasets_delete_generation_job_request( # pylint: disable=name-t return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -def build_beta_agents_create_optimization_job_request( # pylint: disable=name-too-long - *, operation_id: Optional[str] = None, **kwargs: Any +def build_beta_voice_agents_conversations_list_request( # pylint: disable=name-too-long + agent_name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_optimization_jobs" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if operation_id is not None: - _headers["Operation-Id"] = _SERIALIZER.header("operation_id", operation_id, "str") - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agents_get_optimization_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any +def build_beta_voice_agents_conversations_get_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -3980,9 +4184,10 @@ def build_beta_agents_get_optimization_job_request( # pylint: disable=name-too- accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_optimization_jobs/{jobId}" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -3996,14 +4201,35 @@ def build_beta_agents_get_optimization_job_request( # pylint: disable=name-too- return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agents_list_optimization_jobs_request( # pylint: disable=name-too-long +def build_beta_voice_agents_conversations_delete_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, **kwargs: Any +) -> HttpRequest: + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + + +def build_beta_voice_agents_conversations_list_responses_request( # pylint: disable=name-too-long + agent_name: str, + conversation_id: str, *, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, after: Optional[str] = None, before: Optional[str] = None, - status: Optional[Union[str, _models.JobStatus]] = None, - agent_name: Optional[str] = None, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) @@ -4013,7 +4239,13 @@ def build_beta_agents_list_optimization_jobs_request( # pylint: disable=name-to accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_optimization_jobs" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/responses" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters if limit is not None: @@ -4024,10 +4256,6 @@ def build_beta_agents_list_optimization_jobs_request( # pylint: disable=name-to _params["after"] = _SERIALIZER.query("after", after, "str") if before is not None: _params["before"] = _SERIALIZER.query("before", before, "str") - if status is not None: - _params["status"] = _SERIALIZER.query("status", status, "str") - if agent_name is not None: - _params["agent_name"] = _SERIALIZER.query("agent_name", agent_name, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -4036,8 +4264,8 @@ def build_beta_agents_list_optimization_jobs_request( # pylint: disable=name-to return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agents_cancel_optimization_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any +def build_beta_voice_agents_conversations_get_response_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, response_id: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) @@ -4046,9 +4274,11 @@ def build_beta_agents_cancel_optimization_job_request( # pylint: disable=name-t accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/agent_optimization_jobs/{jobId}:cancel" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/responses/{response_id}" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "response_id": _SERIALIZER.url("response_id", response_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -4059,862 +4289,803 @@ def build_beta_agents_cancel_optimization_job_request( # pylint: disable=name-t # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_beta_agents_delete_optimization_job_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any +def build_beta_voice_agents_conversations_list_response_items_request( # pylint: disable=name-too-long + agent_name: str, + conversation_id: str, + response_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any ) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + # Construct URL - _url = "/agent_optimization_jobs/{jobId}" + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/responses/{response_id}/items" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "response_id": _SERIALIZER.url("response_id", response_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -class BetaOperations: # pylint: disable=docstring-missing-param,too-many-instance-attributes - """ - .. warning:: - **DO NOT** instantiate this class directly. - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`beta` attribute. - """ +def build_beta_voice_agents_conversations_list_items_request( # pylint: disable=name-too-long + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - self.agent_insight_monitors = BetaAgentInsightMonitorsOperations( - self._client, self._config, self._serialize, self._deserialize - ) - self.evaluation_taxonomies = BetaEvaluationTaxonomiesOperations( - self._client, self._config, self._serialize, self._deserialize - ) - self.evaluators = BetaEvaluatorsOperations(self._client, self._config, self._serialize, self._deserialize) - self.insights = BetaInsightsOperations(self._client, self._config, self._serialize, self._deserialize) - self.memory_stores = BetaMemoryStoresOperations(self._client, self._config, self._serialize, self._deserialize) - self.models = BetaModelsOperations(self._client, self._config, self._serialize, self._deserialize) - self.red_teams = BetaRedTeamsOperations(self._client, self._config, self._serialize, self._deserialize) - self.routines = BetaRoutinesOperations(self._client, self._config, self._serialize, self._deserialize) - self.schedules = BetaSchedulesOperations(self._client, self._config, self._serialize, self._deserialize) - self.skills = BetaSkillsOperations(self._client, self._config, self._serialize, self._deserialize) - self.datasets = BetaDatasetsOperations(self._client, self._config, self._serialize, self._deserialize) - self.agents = BetaAgentsOperations(self._client, self._config, self._serialize, self._deserialize) + # Construct URL + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + } + _url: str = _url.format(**path_format_arguments) # type: ignore -class AgentsOperations: # pylint: disable=docstring-missing-param,too-many-public-methods - """ - .. warning:: - **DO NOT** instantiate this class directly. + # Construct parameters + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`agents` attribute. - """ + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - @distributed_trace - def get(self, agent_name: str, **kwargs: Any) -> _models.AgentDetails: - """Get an agent. - Retrieves an agent definition by its unique name. +def build_beta_voice_agents_conversations_get_item_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, item_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - :param agent_name: The name of the agent to retrieve. Required. - :type agent_name: str - :return: AgentDetails. The AgentDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + # Construct URL + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "item_id": _SERIALIZER.url("item_id", item_id, "str"), + } - cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) + _url: str = _url.format(**path_format_arguments) # type: ignore - _request = build_agents_get_request( - agent_name=agent_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - response = pipeline_response.http_response + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentDetails, response.json()) +def build_beta_voice_agents_conversations_get_audio_item_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, item_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - return deserialized # type: ignore + # Construct URL + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "item_id": _SERIALIZER.url("item_id", item_id, "str"), + } - @distributed_trace - def delete(self, agent_name: str, *, force: Optional[bool] = None, **kwargs: Any) -> _models.DeleteAgentResponse: - """Delete an agent. + _url: str = _url.format(**path_format_arguments) # type: ignore - Deletes an agent. For hosted agents, if any version has active sessions, the request is - rejected with HTTP 409 unless ``force`` is set to true. When force is true, all associated - sessions are cascade-deleted along with the agent and its versions. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - :param agent_name: The name of the agent to delete. Required. - :type agent_name: str - :keyword force: For Hosted Agents, if ``true``, force-deletes the agent even if its versions - have active sessions, cascading deletion to all associated sessions. The service defaults to - ``false`` if a value is not specified by the caller. This value is not relevant for other Agent - types. Default value is None. - :paramtype force: bool - :return: DeleteAgentResponse. The DeleteAgentResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DeleteAgentResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - cls: ClsType[_models.DeleteAgentResponse] = kwargs.pop("cls", None) - _request = build_agents_delete_request( - agent_name=agent_name, - force=force, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) +def build_beta_voice_agents_conversations_download_audio_item_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, item_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "audio/wav") - response = pipeline_response.http_response + # Construct URL + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/content" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "item_id": _SERIALIZER.url("item_id", item_id, "str"), + } - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + _url: str = _url.format(**path_format_arguments) # type: ignore - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.DeleteAgentResponse, response.json()) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return deserialized # type: ignore + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - @distributed_trace - def list( - self, - *, - kind: Optional[Union[str, _models.AgentKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> ItemPaged["_models.AgentDetails"]: - """List agents. - Returns a paged collection of agent resources. +def build_beta_voice_agents_conversations_get_generated_audio_item_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, item_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - :keyword kind: Filter agents by kind. If not provided, all agents are returned. Known values - are: "prompt", "hosted", "workflow", and "external". Default value is None. - :paramtype kind: str or ~azure.ai.projects.models.AgentKind - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of AgentDetails - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentDetails] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - cls: ClsType[List[_models.AgentDetails]] = kwargs.pop("cls", None) + # Construct URL + _url = ( + "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated" + ) + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "item_id": _SERIALIZER.url("item_id", item_id, "str"), + } - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + _url: str = _url.format(**path_format_arguments) # type: ignore - def prepare_request(_continuation_token=None): + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _request = build_agents_list_request( - kind=kind, - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.AgentDetails], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response +def build_beta_voice_agents_conversations_download_generated_audio_item_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, item_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "audio/wav") - return pipeline_response + # Construct URL + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated/content" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + "item_id": _SERIALIZER.url("item_id", item_id, "str"), + } - return ItemPaged(get_next, extract_data) + _url: str = _url.format(**path_format_arguments) # type: ignore - @overload - def create_version( - self, - agent_name: str, - *, - definition: _models.AgentDefinition, - content_type: str = "application/json", - metadata: Optional[dict[str, str]] = None, - description: Optional[str] = None, - blueprint_reference: Optional[_models.AgentBlueprintReference] = None, - digital_worker_type: Optional[Union[str, _models.DigitalWorkerType]] = None, - draft: Optional[bool] = None, - **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Creates a new version for the specified agent and returns the created version resource. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :keyword definition: The agent definition. This can be a prompt, workflow, hosted, external, or - voice agent definition. Required. - :paramtype definition: ~azure.ai.projects.models.AgentDefinition - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Default value is None. - :paramtype metadata: dict[str, str] - :keyword description: A human-readable description of the agent. Default value is None. - :paramtype description: str - :keyword blueprint_reference: The blueprint reference for the agent. Default value is None. - :paramtype blueprint_reference: ~azure.ai.projects.models.AgentBlueprintReference - :keyword digital_worker_type: (Preview) The type of digital worker (previously known as - ``autopilot``). If omitted, it is not a digital worker. "m365" Default value is None. - :paramtype digital_worker_type: str or ~azure.ai.projects.models.DigitalWorkerType - :keyword draft: (Preview) Whether this agent version is a draft (candidate) rather than a - release. The service defaults to ``false`` if a value is not specified by the caller. Draft - versions are recorded but excluded from default 'latest' resolution and are not auto-promoted. - Default value is None. - :paramtype draft: bool - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ +def build_beta_voice_agents_conversations_get_audio_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - @overload - def create_version( - self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - Creates a new version for the specified agent and returns the created version resource. + # Construct URL + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/audio" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + } - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + _url: str = _url.format(**path_format_arguments) # type: ignore - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - @overload - def create_version( - self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - Creates a new version for the specified agent and returns the created version resource. + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ +def build_beta_voice_agents_conversations_download_audio_request( # pylint: disable=name-too-long + agent_name: str, conversation_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - @distributed_trace - def create_version( - self, - agent_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - definition: _models.AgentDefinition = _Unset, - metadata: Optional[dict[str, str]] = None, - description: Optional[str] = None, - blueprint_reference: Optional[_models.AgentBlueprintReference] = None, - digital_worker_type: Optional[Union[str, _models.DigitalWorkerType]] = None, - draft: Optional[bool] = None, - **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "audio/wav") - Creates a new version for the specified agent and returns the created version resource. + # Construct URL + _url = "/agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/audio/content" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "conversation_id": _SERIALIZER.url("conversation_id", conversation_id, "str"), + } - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + _url: str = _url.format(**path_format_arguments) # type: ignore - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword definition: The agent definition. This can be a prompt, workflow, hosted, external, or - voice agent definition. Required. - :paramtype definition: ~azure.ai.projects.models.AgentDefinition - :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Default value is None. - :paramtype metadata: dict[str, str] - :keyword description: A human-readable description of the agent. Default value is None. - :paramtype description: str - :keyword blueprint_reference: The blueprint reference for the agent. Default value is None. - :paramtype blueprint_reference: ~azure.ai.projects.models.AgentBlueprintReference - :keyword digital_worker_type: (Preview) The type of digital worker (previously known as - ``autopilot``). If omitted, it is not a digital worker. "m365" Default value is None. - :paramtype digital_worker_type: str or ~azure.ai.projects.models.DigitalWorkerType - :keyword draft: (Preview) Whether this agent version is a draft (candidate) rather than a - release. The service defaults to ``false`` if a value is not specified by the caller. Draft - versions are recorded but excluded from default 'latest' resolution and are not auto-promoted. - Default value is None. - :paramtype draft: bool - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) - if body is _Unset: - if definition is _Unset: - raise TypeError("missing required argument: definition") - body = { - "blueprint_reference": blueprint_reference, - "definition": definition, - "description": description, - "digital_worker_type": digital_worker_type, - "draft": draft, - "metadata": metadata, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore +def build_beta_voice_agents_telephony_create_binding_request( # pylint: disable=name-too-long + agent_name: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _request = build_agents_create_version_request( - agent_name=agent_name, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + # Construct URL + _url = "/agents/{agent_name}/telephony/bindings" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if "Repeatability-Request-ID" not in _headers: + _headers["Repeatability-Request-ID"] = str(uuid.uuid4()) + if "Repeatability-First-Sent" not in _headers: + _headers["Repeatability-First-Sent"] = _SERIALIZER.serialize_data( + datetime.datetime.now(datetime.timezone.utc), "rfc-1123" ) + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - response = pipeline_response.http_response + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentVersionDetails, response.json()) +def build_beta_voice_agents_telephony_list_bindings_request( # pylint: disable=name-too-long + agent_name: str, + *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyBindingStatus]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - return deserialized # type: ignore + # Construct URL + _url = "/agents/{agent_name}/telephony/bindings" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + } - @overload - def create_version_from_manifest( - self, - agent_name: str, - *, - manifest_id: str, - parameter_values: dict[str, Any], - content_type: str = "application/json", - metadata: Optional[dict[str, str]] = None, - description: Optional[str] = None, - **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version from manifest. + _url: str = _url.format(**path_format_arguments) # type: ignore - Imports the provided manifest to create a new version for the specified agent. + # Construct parameters + if provider is not None: + _params["provider"] = _SERIALIZER.query("provider", provider, "str") + if status is not None: + _params["status"] = _SERIALIZER.query("status", status, "str") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :keyword manifest_id: The manifest ID to import the agent version from. Required. - :paramtype manifest_id: str - :keyword parameter_values: The inputs to the manifest that will result in a fully materialized - Agent. Required. - :paramtype parameter_values: dict[str, any] - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Default value is None. - :paramtype metadata: dict[str, str] - :keyword description: A human-readable description of the agent. Default value is None. - :paramtype description: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - @overload - def create_version_from_manifest( - self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version from manifest. +def build_beta_voice_agents_telephony_get_binding_request( # pylint: disable=name-too-long + agent_name: str, binding_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - Imports the provided manifest to create a new version for the specified agent. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + # Construct URL + _url = "/agents/{agent_name}/telephony/bindings/{binding_id}" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "binding_id": _SERIALIZER.url("binding_id", binding_id, "str"), + } - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + _url: str = _url.format(**path_format_arguments) # type: ignore - @overload - def create_version_from_manifest( - self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version from manifest. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Imports the provided manifest to create a new version for the specified agent. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - @distributed_trace - def create_version_from_manifest( - self, - agent_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - manifest_id: str = _Unset, - parameter_values: dict[str, Any] = _Unset, - metadata: Optional[dict[str, str]] = None, - description: Optional[str] = None, - **kwargs: Any - ) -> _models.AgentVersionDetails: - """Create an agent version from manifest. +def build_beta_voice_agents_telephony_update_binding_request( # pylint: disable=name-too-long + agent_name: str, binding_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - Imports the provided manifest to create a new version for the specified agent. + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - :param agent_name: The unique name that identifies the agent. Name can be used to - retrieve/update/delete the agent. + # Construct URL + _url = "/agents/{agent_name}/telephony/bindings/{binding_id}" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "binding_id": _SERIALIZER.url("binding_id", binding_id, "str"), + } - * Must start and end with alphanumeric characters, - * Can contain hyphens in the middle - * Must not exceed 63 characters. Required. - :type agent_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword manifest_id: The manifest ID to import the agent version from. Required. - :paramtype manifest_id: str - :keyword parameter_values: The inputs to the manifest that will result in a fully materialized - Agent. Required. - :paramtype parameter_values: dict[str, any] - :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be - useful for storing additional information about the object in a structured - format, and querying for objects via API or the dashboard. + _url: str = _url.format(**path_format_arguments) # type: ignore - Keys are strings with a maximum length of 64 characters. Values are strings - with a maximum length of 512 characters. Default value is None. - :paramtype metadata: dict[str, str] - :keyword description: A human-readable description of the agent. Default value is None. - :paramtype description: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + if_match = prep_if_match(etag, match_condition) + if if_match is not None: + _headers["If-Match"] = _SERIALIZER.header("if_match", if_match, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) + return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) - if body is _Unset: - if manifest_id is _Unset: - raise TypeError("missing required argument: manifest_id") - if parameter_values is _Unset: - raise TypeError("missing required argument: parameter_values") - body = { - "description": description, - "manifest_id": manifest_id, - "metadata": metadata, - "parameter_values": parameter_values, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_agents_create_version_from_manifest_request( - agent_name=agent_name, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) +def build_beta_voice_agents_telephony_delete_binding_request( # pylint: disable=name-too-long + agent_name: str, binding_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + # Construct URL + _url = "/agents/{agent_name}/telephony/bindings/{binding_id}" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "binding_id": _SERIALIZER.url("binding_id", binding_id, "str"), + } - response = pipeline_response.http_response + _url: str = _url.format(**path_format_arguments) # type: ignore - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentVersionDetails, response.json()) + # Construct headers + if_match = prep_if_match(etag, match_condition) + if if_match is not None: + _headers["If-Match"] = _SERIALIZER.header("if_match", if_match, "str") - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) - return deserialized # type: ignore - @distributed_trace - def get_version(self, agent_name: str, agent_version: str, **kwargs: Any) -> _models.AgentVersionDetails: - """Get an agent version. +def build_beta_voice_agents_telephony_list_calls_request( # pylint: disable=name-too-long + agent_name: str, + *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyCallStatus]] = None, + started_after_time: Optional[datetime.datetime] = None, + started_before_time: Optional[datetime.datetime] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + after: Optional[str] = None, + before: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - Retrieves the specified version of an agent by its agent name and version identifier. + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - :param agent_name: The name of the agent to retrieve. Required. - :type agent_name: str - :param agent_version: The version of the agent to retrieve. Required. - :type agent_version: str - :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentVersionDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + # Construct URL + _url = "/agents/{agent_name}/telephony/calls" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + } - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + _url: str = _url.format(**path_format_arguments) # type: ignore - cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) + # Construct parameters + if provider is not None: + _params["provider"] = _SERIALIZER.query("provider", provider, "str") + if status is not None: + _params["status"] = _SERIALIZER.query("status", status, "str") + if started_after_time is not None: + _params["started_after"] = _SERIALIZER.query("started_after_time", started_after_time, "unix-time") + if started_before_time is not None: + _params["started_before"] = _SERIALIZER.query("started_before_time", started_before_time, "unix-time") + if limit is not None: + _params["limit"] = _SERIALIZER.query("limit", limit, "int") + if order is not None: + _params["order"] = _SERIALIZER.query("order", order, "str") + if after is not None: + _params["after"] = _SERIALIZER.query("after", after, "str") + if before is not None: + _params["before"] = _SERIALIZER.query("before", before, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _request = build_agents_get_version_request( - agent_name=agent_name, - agent_version=agent_version, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) - response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) +def build_beta_voice_agents_telephony_get_call_request( # pylint: disable=name-too-long + agent_name: str, call_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentVersionDetails, response.json()) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + # Construct URL + _url = "/agents/{agent_name}/telephony/calls/{call_id}" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "call_id": _SERIALIZER.url("call_id", call_id, "str"), + } - return deserialized # type: ignore + _url: str = _url.format(**path_format_arguments) # type: ignore - @distributed_trace - def delete_version( - self, agent_name: str, agent_version: str, *, force: Optional[bool] = None, **kwargs: Any - ) -> _models.DeleteAgentVersionResponse: - """Delete an agent version. + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - Deletes a specific version of an agent. For hosted agents, if the version has active sessions, - the request is rejected with HTTP 409 unless ``force`` is set to true. When force is true, all - sessions associated with this version are cascade-deleted. + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - :param agent_name: The name of the agent to delete. Required. - :type agent_name: str - :param agent_version: The version of the agent to delete. Required. - :type agent_version: str - :keyword force: For Hosted Agents, if ``true``, force-deletes the version even if it has active - sessions, cascading deletion to all associated sessions. The service defaults to ``false`` if a - value is not specified by the caller. This value is not relevant for other Agent types. Default - value is None. - :paramtype force: bool - :return: DeleteAgentVersionResponse. The DeleteAgentVersionResponse is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.DeleteAgentVersionResponse + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_voice_agents_telephony_transfer_call_request( # pylint: disable=name-too-long + agent_name: str, call_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents/{agent_name}/telephony/calls/{call_id}:transfer" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "call_id": _SERIALIZER.url("call_id", call_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_voice_agents_telephony_end_call_request( # pylint: disable=name-too-long + agent_name: str, call_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents/{agent_name}/telephony/calls/{call_id}:end" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "call_id": _SERIALIZER.url("call_id", call_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_voice_agents_telephony_get_transfer_targets_request( # pylint: disable=name-too-long + agent_name: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents/{agent_name}/telephony/transfer_targets" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_voice_agents_telephony_replace_transfer_targets_request( # pylint: disable=name-too-long + agent_name: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents/{agent_name}/telephony/transfer_targets" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if_match = prep_if_match(etag, match_condition) + if if_match is not None: + _headers["If-Match"] = _SERIALIZER.header("if_match", if_match, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_voice_agents_telephony_create_call_job_request( # pylint: disable=name-too-long + agent_name: str, *, idempotency_key: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents/{agent_name}/telephony/call_jobs" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Idempotency-Key"] = _SERIALIZER.header("idempotency_key", idempotency_key, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_voice_agents_telephony_get_call_job_request( # pylint: disable=name-too-long + agent_name: str, call_job_id: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents/{agent_name}/telephony/call_jobs/{call_job_id}" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "call_job_id": _SERIALIZER.url("call_job_id", call_job_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_beta_voice_agents_telephony_cancel_call_job_request( # pylint: disable=name-too-long + agent_name: str, call_job_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "v1")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/agents/{agent_name}/telephony/call_jobs/{call_job_id}:cancel" + path_format_arguments = { + "agent_name": _SERIALIZER.url("agent_name", agent_name, "str"), + "call_job_id": _SERIALIZER.url("call_job_id", call_job_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if_match = prep_if_match(etag, match_condition) + if if_match is not None: + _headers["If-Match"] = _SERIALIZER.header("if_match", if_match, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +class BetaOperations: # pylint: disable=docstring-missing-param,too-many-instance-attributes + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`beta` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + self.voice_agents = BetaVoiceAgentsOperations(self._client, self._config, self._serialize, self._deserialize) + self.agents = BetaAgentsOperations(self._client, self._config, self._serialize, self._deserialize) + self.agent_insight_monitors = BetaAgentInsightMonitorsOperations( + self._client, self._config, self._serialize, self._deserialize + ) + self.evaluation_taxonomies = BetaEvaluationTaxonomiesOperations( + self._client, self._config, self._serialize, self._deserialize + ) + self.evaluators = BetaEvaluatorsOperations(self._client, self._config, self._serialize, self._deserialize) + self.insights = BetaInsightsOperations(self._client, self._config, self._serialize, self._deserialize) + self.memory_stores = BetaMemoryStoresOperations(self._client, self._config, self._serialize, self._deserialize) + self.models = BetaModelsOperations(self._client, self._config, self._serialize, self._deserialize) + self.red_teams = BetaRedTeamsOperations(self._client, self._config, self._serialize, self._deserialize) + self.routines = BetaRoutinesOperations(self._client, self._config, self._serialize, self._deserialize) + self.schedules = BetaSchedulesOperations(self._client, self._config, self._serialize, self._deserialize) + self.skills = BetaSkillsOperations(self._client, self._config, self._serialize, self._deserialize) + self.datasets = BetaDatasetsOperations(self._client, self._config, self._serialize, self._deserialize) + + +class AgentsOperations: # pylint: disable=docstring-missing-param,too-many-public-methods + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`agents` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def get(self, agent_name: str, **kwargs: Any) -> _models.AgentDetails: + """Get an agent. + + Retrieves an agent definition by its unique name. + + :param agent_name: The name of the agent to retrieve. Required. + :type agent_name: str + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -4928,12 +5099,10 @@ def delete_version( _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DeleteAgentVersionResponse] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) - _request = build_agents_delete_version_request( + _request = build_agents_get_request( agent_name=agent_name, - agent_version=agent_version, - force=force, api_version=self._config.api_version, headers=_headers, params=_params, @@ -4967,7 +5136,7 @@ def delete_version( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DeleteAgentVersionResponse, response.json()) + deserialized = _deserialize(_models.AgentDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -4975,22 +5144,97 @@ def delete_version( return deserialized # type: ignore @distributed_trace - def list_versions( - self, - agent_name: str, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - include_drafts: Optional[bool] = None, - **kwargs: Any - ) -> ItemPaged["_models.AgentVersionDetails"]: - """List agent versions. - - Returns a paged collection of versions for the specified agent. + def delete(self, agent_name: str, *, force: Optional[bool] = None, **kwargs: Any) -> _models.DeleteAgentResponse: + """Delete an agent. - :param agent_name: The name of the agent to retrieve versions for. Required. + Deletes an agent. For hosted agents, if any version has active sessions, the request is + rejected with HTTP 409 unless ``force`` is set to true. When force is true, all associated + sessions are cascade-deleted along with the agent and its versions. + + :param agent_name: The name of the agent to delete. Required. :type agent_name: str + :keyword force: For Hosted Agents, if ``true``, force-deletes the agent even if its versions + have active sessions, cascading deletion to all associated sessions. The service defaults to + ``false`` if a value is not specified by the caller. This value is not relevant for other Agent + types. Default value is None. + :paramtype force: bool + :return: DeleteAgentResponse. The DeleteAgentResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DeleteAgentResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.DeleteAgentResponse] = kwargs.pop("cls", None) + + _request = build_agents_delete_request( + agent_name=agent_name, + force=force, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DeleteAgentResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + kind: Optional[Union[str, _models.AgentKind]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.AgentDetails"]: + """List agents. + + Returns a paged collection of agent resources. + + :keyword kind: Filter agents by kind. If not provided, all agents are returned. Known values + are: "prompt", "hosted", "workflow", "external", and "voice". Default value is None. + :paramtype kind: str or ~azure.ai.projects.models.AgentKind :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20. Default value is None. @@ -5005,18 +5249,14 @@ def list_versions( subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. :paramtype before: str - :keyword include_drafts: (Preview) Whether to include draft versions in the listing. The - service defaults to ``false`` if a value is not specified by the caller (only non-draft - versions are returned). Default value is None. - :paramtype include_drafts: bool - :return: An iterator like instance of AgentVersionDetails - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentVersionDetails] + :return: An iterator like instance of AgentDetails + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentDetails] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.AgentVersionDetails]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.AgentDetails]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -5028,13 +5268,12 @@ def list_versions( def prepare_request(_continuation_token=None): - _request = build_agents_list_versions_request( - agent_name=agent_name, + _request = build_agents_list_request( + kind=kind, limit=limit, order=order, after=_continuation_token, before=before, - include_drafts=include_drafts, api_version=self._config.api_version, headers=_headers, params=_params, @@ -5048,7 +5287,7 @@ def prepare_request(_continuation_token=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.AgentVersionDetails], + List[_models.AgentDetails], deserialized.get("data", []), ) if cls: @@ -5077,124 +5316,197 @@ def get_next(_continuation_token=None): return ItemPaged(get_next, extract_data) @overload - def update_details( + def create_version( self, agent_name: str, *, - content_type: str = "application/merge-patch+json", - agent_endpoint: Optional[_models.AgentEndpointConfig] = None, - agent_card: Optional[_models.AgentCard] = None, + definition: _models.AgentDefinition, + content_type: str = "application/json", + metadata: Optional[dict[str, str]] = None, + description: Optional[str] = None, + blueprint_reference: Optional[_models.AgentBlueprintReference] = None, + digital_worker_type: Optional[Union[str, _models.DigitalWorkerType]] = None, + draft: Optional[bool] = None, **kwargs: Any - ) -> _models.AgentDetails: - """Update an agent endpoint. + ) -> _models.AgentVersionDetails: + """Create an agent version. - Applies a merge-patch update to the specified agent endpoint configuration. + Creates a new version for the specified agent and returns the created version resource. - :param agent_name: The name of the agent to retrieve. Required. + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. :type agent_name: str + :keyword definition: The agent definition. This can be a prompt, workflow, hosted, external, or + voice agent definition. Required. + :paramtype definition: ~azure.ai.projects.models.AgentDefinition :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :keyword agent_endpoint: The endpoint configuration for the agent. Default value is None. - :paramtype agent_endpoint: ~azure.ai.projects.models.AgentEndpointConfig - :keyword agent_card: Optional agent card for the agent. Default value is None. - :paramtype agent_card: ~azure.ai.projects.models.AgentCard - :return: AgentDetails. The AgentDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentDetails + :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. + + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Default value is None. + :paramtype metadata: dict[str, str] + :keyword description: A human-readable description of the agent. Default value is None. + :paramtype description: str + :keyword blueprint_reference: The blueprint reference for the agent. Default value is None. + :paramtype blueprint_reference: ~azure.ai.projects.models.AgentBlueprintReference + :keyword digital_worker_type: (Preview) The type of digital worker (previously known as + ``autopilot``). If omitted, it is not a digital worker. "m365" Default value is None. + :paramtype digital_worker_type: str or ~azure.ai.projects.models.DigitalWorkerType + :keyword draft: (Preview) Whether this agent version is a draft (candidate) rather than a + release. The service defaults to ``false`` if a value is not specified by the caller. Draft + versions are recorded but excluded from default 'latest' resolution and are not auto-promoted. + Default value is None. + :paramtype draft: bool + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update_details( - self, agent_name: str, body: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.AgentDetails: - """Update an agent endpoint. + def create_version( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentVersionDetails: + """Create an agent version. - Applies a merge-patch update to the specified agent endpoint configuration. + Creates a new version for the specified agent and returns the created version resource. - :param agent_name: The name of the agent to retrieve. Required. + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. :type agent_name: str :param body: Required. :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: AgentDetails. The AgentDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentDetails + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update_details( - self, agent_name: str, body: IO[bytes], *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.AgentDetails: - """Update an agent endpoint. + def create_version( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentVersionDetails: + """Create an agent version. - Applies a merge-patch update to the specified agent endpoint configuration. + Creates a new version for the specified agent and returns the created version resource. - :param agent_name: The name of the agent to retrieve. Required. + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. :type agent_name: str :param body: Required. :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: AgentDetails. The AgentDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentDetails + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def update_details( + def create_version( self, agent_name: str, body: Union[JSON, IO[bytes]] = _Unset, *, - agent_endpoint: Optional[_models.AgentEndpointConfig] = None, - agent_card: Optional[_models.AgentCard] = None, + definition: _models.AgentDefinition = _Unset, + metadata: Optional[dict[str, str]] = None, + description: Optional[str] = None, + blueprint_reference: Optional[_models.AgentBlueprintReference] = None, + digital_worker_type: Optional[Union[str, _models.DigitalWorkerType]] = None, + draft: Optional[bool] = None, **kwargs: Any - ) -> _models.AgentDetails: - """Update an agent endpoint. + ) -> _models.AgentVersionDetails: + """Create an agent version. - Applies a merge-patch update to the specified agent endpoint configuration. + Creates a new version for the specified agent and returns the created version resource. - :param agent_name: The name of the agent to retrieve. Required. + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. :type agent_name: str :param body: Is either a JSON type or a IO[bytes] type. Required. :type body: JSON or IO[bytes] - :keyword agent_endpoint: The endpoint configuration for the agent. Default value is None. - :paramtype agent_endpoint: ~azure.ai.projects.models.AgentEndpointConfig - :keyword agent_card: Optional agent card for the agent. Default value is None. - :paramtype agent_card: ~azure.ai.projects.models.AgentCard - :return: AgentDetails. The AgentDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + :keyword definition: The agent definition. This can be a prompt, workflow, hosted, external, or + voice agent definition. Required. + :paramtype definition: ~azure.ai.projects.models.AgentDefinition + :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Default value is None. + :paramtype metadata: dict[str, str] + :keyword description: A human-readable description of the agent. Default value is None. + :paramtype description: str + :keyword blueprint_reference: The blueprint reference for the agent. Default value is None. + :paramtype blueprint_reference: ~azure.ai.projects.models.AgentBlueprintReference + :keyword digital_worker_type: (Preview) The type of digital worker (previously known as + ``autopilot``). If omitted, it is not a digital worker. "m365" Default value is None. + :paramtype digital_worker_type: str or ~azure.ai.projects.models.DigitalWorkerType + :keyword draft: (Preview) Whether this agent version is a draft (candidate) rather than a + release. The service defaults to ``false`` if a value is not specified by the caller. Draft + versions are recorded but excluded from default 'latest' resolution and are not auto-promoted. + Default value is None. + :paramtype draft: bool + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) if body is _Unset: - body = {"agent_card": agent_card, "agent_endpoint": agent_endpoint} + if definition is _Unset: + raise TypeError("missing required argument: definition") + body = { + "blueprint_reference": blueprint_reference, + "definition": definition, + "description": description, + "digital_worker_type": digital_worker_type, + "draft": draft, + "metadata": metadata, + } body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/merge-patch+json" + content_type = content_type or "application/json" _content = None if isinstance(body, (IOBase, bytes)): _content = body else: _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_agents_update_details_request( + _request = build_agents_create_version_request( agent_name=agent_name, content_type=content_type, api_version=self._config.api_version, @@ -5231,7 +5543,7 @@ def update_details( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentDetails, response.json()) + deserialized = _deserialize(_models.AgentVersionDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -5239,34 +5551,115 @@ def update_details( return deserialized # type: ignore @overload - def _create_version_from_code( + def create_version_from_manifest( self, agent_name: str, - content: _models._models._CreateAgentVersionFromCodeContent, *, - code_zip_sha256: str, + manifest_id: str, + parameter_values: dict[str, Any], + content_type: str = "application/json", + metadata: Optional[dict[str, str]] = None, + description: Optional[str] = None, **kwargs: Any - ) -> _models.AgentVersionDetails: ... + ) -> _models.AgentVersionDetails: + """Create an agent version from manifest. + + Imports the provided manifest to create a new version for the specified agent. + + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. + :type agent_name: str + :keyword manifest_id: The manifest ID to import the agent version from. Required. + :paramtype manifest_id: str + :keyword parameter_values: The inputs to the manifest that will result in a fully materialized + Agent. Required. + :paramtype parameter_values: dict[str, any] + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. + + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Default value is None. + :paramtype metadata: dict[str, str] + :keyword description: A human-readable description of the agent. Default value is None. + :paramtype description: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + @overload - def _create_version_from_code( - self, agent_name: str, content: JSON, *, code_zip_sha256: str, **kwargs: Any - ) -> _models.AgentVersionDetails: ... + def create_version_from_manifest( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentVersionDetails: + """Create an agent version from manifest. + + Imports the provided manifest to create a new version for the specified agent. + + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_version_from_manifest( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentVersionDetails: + """Create an agent version from manifest. + + Imports the provided manifest to create a new version for the specified agent. + + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def _create_version_from_code( + def create_version_from_manifest( self, agent_name: str, - content: Union[_models._models._CreateAgentVersionFromCodeContent, JSON], + body: Union[JSON, IO[bytes]] = _Unset, *, - code_zip_sha256: str, + manifest_id: str = _Unset, + parameter_values: dict[str, Any] = _Unset, + metadata: Optional[dict[str, str]] = None, + description: Optional[str] = None, **kwargs: Any ) -> _models.AgentVersionDetails: - """Create an agent version from code. + """Create an agent version from manifest. - Creates a new agent version from code. Uploads the code zip and creates a new version for an - existing agent. The SHA-256 hex digest of the zip is provided in the ``x-ms-code-zip-sha256`` - header for integrity and dedup. The request body is multipart/form-data with a JSON metadata - part and a binary code part (part order is irrelevant). Maximum upload size is 250 MB. + Imports the provided manifest to create a new version for the specified agent. :param agent_name: The unique name that identifies the agent. Name can be used to retrieve/update/delete the agent. @@ -5275,12 +5668,22 @@ def _create_version_from_code( * Can contain hyphens in the middle * Must not exceed 63 characters. Required. :type agent_name: str - :param content: The content multipart request content. Is either a - _CreateAgentVersionFromCodeContent type or a JSON type. Required. - :type content: ~azure.ai.projects.models._models._CreateAgentVersionFromCodeContent or JSON - :keyword code_zip_sha256: SHA-256 hex digest of the uploaded code zip. Used for change - detection (dedup) and integrity verification. Required. - :paramtype code_zip_sha256: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword manifest_id: The manifest ID to import the agent version from. Required. + :paramtype manifest_id: str + :keyword parameter_values: The inputs to the manifest that will result in a fully materialized + Agent. Required. + :paramtype parameter_values: dict[str, any] + :keyword metadata: Set of 16 key-value pairs that can be attached to an object. This can be + useful for storing additional information about the object in a structured + format, and querying for objects via API or the dashboard. + + Keys are strings with a maximum length of 64 characters. Values are strings + with a maximum length of 512 characters. Default value is None. + :paramtype metadata: dict[str, str] + :keyword description: A human-readable description of the agent. Default value is None. + :paramtype description: str :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping :rtype: ~azure.ai.projects.models.AgentVersionDetails :raises ~azure.core.exceptions.HttpResponseError: @@ -5293,21 +5696,36 @@ def _create_version_from_code( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) - _body = content.as_dict() if isinstance(content, _Model) else content - _file_fields: list[str] = ["code"] - _data_fields: list[str] = ["metadata"] - _files = prepare_multipart_form_data(_body, _file_fields, _data_fields) + if body is _Unset: + if manifest_id is _Unset: + raise TypeError("missing required argument: manifest_id") + if parameter_values is _Unset: + raise TypeError("missing required argument: parameter_values") + body = { + "description": description, + "manifest_id": manifest_id, + "metadata": metadata, + "parameter_values": parameter_values, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_agents_create_version_from_code_request( + _request = build_agents_create_version_from_manifest_request( agent_name=agent_name, - code_zip_sha256=code_zip_sha256, + content_type=content_type, api_version=self._config.api_version, - files=_files, + content=_content, headers=_headers, params=_params, ) @@ -5348,25 +5766,17 @@ def _create_version_from_code( return deserialized # type: ignore @distributed_trace - def download_code(self, agent_name: str, *, agent_version: Optional[str] = None, **kwargs: Any) -> Iterator[bytes]: - """Download agent code. - - Downloads the code zip for a code-based hosted agent. - Returns the previously-uploaded zip (``application/zip``). - - If ``agent_version`` is supplied, returns that version's code zip; otherwise - returns the latest version's code zip. + def get_version(self, agent_name: str, agent_version: str, **kwargs: Any) -> _models.AgentVersionDetails: + """Get an agent version. - The SHA-256 digest of the returned bytes matches the ``content_hash`` on the - resolved version's ``code_configuration``. + Retrieves the specified version of an agent by its agent name and version identifier. - :param agent_name: The name of the agent. Required. + :param agent_name: The name of the agent to retrieve. Required. :type agent_name: str - :keyword agent_version: The version of the agent whose code zip should be downloaded. - If omitted, the latest version's code zip is returned. Default value is None. - :paramtype agent_version: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :param agent_version: The version of the agent to retrieve. Required. + :type agent_version: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -5380,9 +5790,9 @@ def download_code(self, agent_name: str, *, agent_version: Optional[str] = None, _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) - _request = build_agents_download_code_request( + _request = build_agents_get_version_request( agent_name=agent_name, agent_version=agent_version, api_version=self._config.api_version, @@ -5395,7 +5805,7 @@ def download_code(self, agent_name: str, *, agent_version: Optional[str] = None, _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -5415,29 +5825,38 @@ def download_code(self, agent_name: str, *, agent_version: Optional[str] = None, ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["x-ms-agent-version"] = self._deserialize("str", response.headers.get("x-ms-agent-version")) - response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentVersionDetails, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @distributed_trace - def enable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Enable an agent. - - Enables the specified agent, allowing it to accept new sessions and process requests. This - operation is idempotent — enabling an already-enabled agent returns success with no side - effects. + def delete_version( + self, agent_name: str, agent_version: str, *, force: Optional[bool] = None, **kwargs: Any + ) -> _models.DeleteAgentVersionResponse: + """Delete an agent version. - :param agent_name: The name of the agent to enable. Required. + Deletes a specific version of an agent. For hosted agents, if the version has active sessions, + the request is rejected with HTTP 409 unless ``force`` is set to true. When force is true, all + sessions associated with this version are cascade-deleted. + + :param agent_name: The name of the agent to delete. Required. :type agent_name: str - :return: None - :rtype: None + :param agent_version: The version of the agent to delete. Required. + :type agent_version: str + :keyword force: For Hosted Agents, if ``true``, force-deletes the version even if it has active + sessions, cascading deletion to all associated sessions. The service defaults to ``false`` if a + value is not specified by the caller. This value is not relevant for other Agent types. Default + value is None. + :paramtype force: bool + :return: DeleteAgentVersionResponse. The DeleteAgentVersionResponse is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.DeleteAgentVersionResponse :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -5451,10 +5870,12 @@ def enable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inc _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.DeleteAgentVersionResponse] = kwargs.pop("cls", None) - _request = build_agents_enable_request( + _request = build_agents_delete_version_request( agent_name=agent_name, + agent_version=agent_version, + force=force, api_version=self._config.api_version, headers=_headers, params=_params, @@ -5464,14 +5885,20 @@ def enable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inc } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -5479,24 +5906,60 @@ def enable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inc ) raise HttpResponseError(response=response, model=error) + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DeleteAgentVersionResponse, response.json()) + if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace - def disable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Disable an agent. + def list_versions( + self, + agent_name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + include_drafts: Optional[bool] = None, + **kwargs: Any + ) -> ItemPaged["_models.AgentVersionDetails"]: + """List agent versions. - Disables the specified agent, preventing it from accepting new sessions or processing requests. - Existing active sessions are allowed to drain gracefully but no new sessions can be created. - This operation is idempotent — disabling an already-disabled agent returns success with no side - effects. + Returns a paged collection of versions for the specified agent. - :param agent_name: The name of the agent to disable. Required. + :param agent_name: The name of the agent to retrieve versions for. Required. :type agent_name: str - :return: None - :rtype: None + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :keyword include_drafts: (Preview) Whether to include draft versions in the listing. The + service defaults to ``false`` if a value is not specified by the caller (only non-draft + versions are returned). Default value is None. + :paramtype include_drafts: bool + :return: An iterator like instance of AgentVersionDetails + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentVersionDetails] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.AgentVersionDetails]] = kwargs.pop("cls", None) + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -5505,142 +5968,148 @@ def disable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=in } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[None] = kwargs.pop("cls", None) + def prepare_request(_continuation_token=None): - _request = build_agents_disable_request( - agent_name=agent_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _request = build_agents_list_versions_request( + agent_name=agent_name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + include_drafts=include_drafts, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.AgentVersionDetails], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) - response = pipeline_response.http_response + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) - raise HttpResponseError(response=response, model=error) + response = pipeline_response.http_response - if cls: - return cls(pipeline_response, None, {}) # type: ignore + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) @overload - def create_session( + def update_details( self, agent_name: str, *, - version_indicator: _models.VersionIndicator, - content_type: str = "application/json", - agent_session_id: Optional[str] = None, + content_type: str = "application/merge-patch+json", + agent_endpoint: Optional[_models.AgentEndpointConfig] = None, + agent_card: Optional[_models.AgentCard] = None, **kwargs: Any - ) -> _models.AgentSessionResource: - """Create a session. + ) -> _models.AgentDetails: + """Update an agent endpoint. - Creates a new session for an agent endpoint. The endpoint resolves the backing agent version - from ``version_indicator`` and enforces session ownership using the provided user identity for - session-mutating operations. + Applies a merge-patch update to the specified agent endpoint configuration. - :param agent_name: The name of the agent to create a session for. Required. + :param agent_name: The name of the agent to retrieve. Required. :type agent_name: str - :keyword version_indicator: Determines which agent version backs the session. Required. - :paramtype version_indicator: ~azure.ai.projects.models.VersionIndicator :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :keyword agent_session_id: Optional caller-provided session ID. If specified, it must be unique - within the agent endpoint. Auto-generated if omitted. Default value is None. - :paramtype agent_session_id: str - :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentSessionResource + :keyword agent_endpoint: The endpoint configuration for the agent. Default value is None. + :paramtype agent_endpoint: ~azure.ai.projects.models.AgentEndpointConfig + :keyword agent_card: Optional agent card for the agent. Default value is None. + :paramtype agent_card: ~azure.ai.projects.models.AgentCard + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create_session( - self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentSessionResource: - """Create a session. + def update_details( + self, agent_name: str, body: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.AgentDetails: + """Update an agent endpoint. - Creates a new session for an agent endpoint. The endpoint resolves the backing agent version - from ``version_indicator`` and enforces session ownership using the provided user identity for - session-mutating operations. + Applies a merge-patch update to the specified agent endpoint configuration. - :param agent_name: The name of the agent to create a session for. Required. + :param agent_name: The name of the agent to retrieve. Required. :type agent_name: str :param body: Required. :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentSessionResource + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create_session( - self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentSessionResource: - """Create a session. + def update_details( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.AgentDetails: + """Update an agent endpoint. - Creates a new session for an agent endpoint. The endpoint resolves the backing agent version - from ``version_indicator`` and enforces session ownership using the provided user identity for - session-mutating operations. + Applies a merge-patch update to the specified agent endpoint configuration. - :param agent_name: The name of the agent to create a session for. Required. + :param agent_name: The name of the agent to retrieve. Required. :type agent_name: str :param body: Required. :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentSessionResource + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def create_session( + def update_details( self, agent_name: str, body: Union[JSON, IO[bytes]] = _Unset, *, - version_indicator: _models.VersionIndicator = _Unset, - agent_session_id: Optional[str] = None, + agent_endpoint: Optional[_models.AgentEndpointConfig] = None, + agent_card: Optional[_models.AgentCard] = None, **kwargs: Any - ) -> _models.AgentSessionResource: - """Create a session. + ) -> _models.AgentDetails: + """Update an agent endpoint. - Creates a new session for an agent endpoint. The endpoint resolves the backing agent version - from ``version_indicator`` and enforces session ownership using the provided user identity for - session-mutating operations. + Applies a merge-patch update to the specified agent endpoint configuration. - :param agent_name: The name of the agent to create a session for. Required. + :param agent_name: The name of the agent to retrieve. Required. :type agent_name: str :param body: Is either a JSON type or a IO[bytes] type. Required. :type body: JSON or IO[bytes] - :keyword version_indicator: Determines which agent version backs the session. Required. - :paramtype version_indicator: ~azure.ai.projects.models.VersionIndicator - :keyword agent_session_id: Optional caller-provided session ID. If specified, it must be unique - within the agent endpoint. Auto-generated if omitted. Default value is None. - :paramtype agent_session_id: str - :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentSessionResource + :keyword agent_endpoint: The endpoint configuration for the agent. Default value is None. + :paramtype agent_endpoint: ~azure.ai.projects.models.AgentEndpointConfig + :keyword agent_card: Optional agent card for the agent. Default value is None. + :paramtype agent_card: ~azure.ai.projects.models.AgentCard + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -5655,21 +6124,19 @@ def create_session( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentSessionResource] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) if body is _Unset: - if version_indicator is _Unset: - raise TypeError("missing required argument: version_indicator") - body = {"agent_session_id": agent_session_id, "version_indicator": version_indicator} + body = {"agent_card": agent_card, "agent_endpoint": agent_endpoint} body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" + content_type = content_type or "application/merge-patch+json" _content = None if isinstance(body, (IOBase, bytes)): _content = body else: _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_agents_create_session_request( + _request = build_agents_update_details_request( agent_name=agent_name, content_type=content_type, api_version=self._config.api_version, @@ -5690,7 +6157,7 @@ def create_session( response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket @@ -5706,25 +6173,58 @@ def create_session( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentSessionResource, response.json()) + deserialized = _deserialize(_models.AgentDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + @overload + def _create_version_from_code( + self, + agent_name: str, + content: _models._models._CreateAgentVersionFromCodeContent, + *, + code_zip_sha256: str, + **kwargs: Any + ) -> _models.AgentVersionDetails: ... + @overload + def _create_version_from_code( + self, agent_name: str, content: JSON, *, code_zip_sha256: str, **kwargs: Any + ) -> _models.AgentVersionDetails: ... + @distributed_trace - def get_session(self, agent_name: str, session_id: str, **kwargs: Any) -> _models.AgentSessionResource: - """Get a session. + def _create_version_from_code( + self, + agent_name: str, + content: Union[_models._models._CreateAgentVersionFromCodeContent, JSON], + *, + code_zip_sha256: str, + **kwargs: Any + ) -> _models.AgentVersionDetails: + """Create an agent version from code. - Retrieves the details of a hosted agent session by agent name and session identifier. + Creates a new agent version from code. Uploads the code zip and creates a new version for an + existing agent. The SHA-256 hex digest of the zip is provided in the ``x-ms-code-zip-sha256`` + header for integrity and dedup. The request body is multipart/form-data with a JSON metadata + part and a binary code part (part order is irrelevant). Maximum upload size is 250 MB. - :param agent_name: The name of the agent. Required. + :param agent_name: The unique name that identifies the agent. Name can be used to + retrieve/update/delete the agent. + + * Must start and end with alphanumeric characters, + * Can contain hyphens in the middle + * Must not exceed 63 characters. Required. :type agent_name: str - :param session_id: The session identifier. Required. - :type session_id: str - :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentSessionResource + :param content: The content multipart request content. Is either a + _CreateAgentVersionFromCodeContent type or a JSON type. Required. + :type content: ~azure.ai.projects.models._models._CreateAgentVersionFromCodeContent or JSON + :keyword code_zip_sha256: SHA-256 hex digest of the uploaded code zip. Used for change + detection (dedup) and integrity verification. Required. + :paramtype code_zip_sha256: str + :return: AgentVersionDetails. The AgentVersionDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentVersionDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -5738,12 +6238,18 @@ def get_session(self, agent_name: str, session_id: str, **kwargs: Any) -> _model _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentSessionResource] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentVersionDetails] = kwargs.pop("cls", None) - _request = build_agents_get_session_request( + _body = content.as_dict() if isinstance(content, _Model) else content + _file_fields: list[str] = ["code"] + _data_fields: list[str] = ["metadata"] + _files = prepare_multipart_form_data(_body, _file_fields, _data_fields) + + _request = build_agents_create_version_from_code_request( agent_name=agent_name, - session_id=session_id, + code_zip_sha256=code_zip_sha256, api_version=self._config.api_version, + files=_files, headers=_headers, params=_params, ) @@ -5776,7 +6282,7 @@ def get_session(self, agent_name: str, session_id: str, **kwargs: Any) -> _model if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentSessionResource, response.json()) + deserialized = _deserialize(_models.AgentVersionDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -5784,20 +6290,25 @@ def get_session(self, agent_name: str, session_id: str, **kwargs: Any) -> _model return deserialized # type: ignore @distributed_trace - def delete_session( # pylint: disable=inconsistent-return-statements - self, agent_name: str, session_id: str, **kwargs: Any - ) -> None: - """Delete a session. + def download_code(self, agent_name: str, *, agent_version: Optional[str] = None, **kwargs: Any) -> Iterator[bytes]: + """Download agent code. - Deletes a session synchronously. Returns 204 No Content when the session is deleted or does not - exist. + Downloads the code zip for a code-based hosted agent. + Returns the previously-uploaded zip (``application/zip``). + + If ``agent_version`` is supplied, returns that version's code zip; otherwise + returns the latest version's code zip. + + The SHA-256 digest of the returned bytes matches the ``content_hash`` on the + resolved version's ``code_configuration``. :param agent_name: The name of the agent. Required. :type agent_name: str - :param session_id: The session identifier. Required. - :type session_id: str - :return: None - :rtype: None + :keyword agent_version: The version of the agent whose code zip should be downloaded. + If omitted, the latest version's code zip is returned. Default value is None. + :paramtype agent_version: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -5811,11 +6322,11 @@ def delete_session( # pylint: disable=inconsistent-return-statements _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_agents_delete_session_request( + _request = build_agents_download_code_request( agent_name=agent_name, - session_id=session_id, + agent_version=agent_version, api_version=self._config.api_version, headers=_headers, params=_params, @@ -5825,14 +6336,20 @@ def delete_session( # pylint: disable=inconsistent-return-statements } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -5840,22 +6357,27 @@ def delete_session( # pylint: disable=inconsistent-return-statements ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["x-ms-agent-version"] = self._deserialize("str", response.headers.get("x-ms-agent-version")) + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore @distributed_trace - def stop_session( # pylint: disable=inconsistent-return-statements - self, agent_name: str, session_id: str, **kwargs: Any - ) -> None: - """Stop a session. + def enable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Enable an agent. - Terminates the specified hosted agent session and returns 204 No Content when the request - succeeds. + Enables the specified agent, allowing it to accept new sessions and process requests. This + operation is idempotent — enabling an already-enabled agent returns success with no side + effects. - :param agent_name: The name of the agent. Required. + :param agent_name: The name of the agent to enable. Required. :type agent_name: str - :param session_id: The session identifier. Required. - :type session_id: str :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -5873,9 +6395,8 @@ def stop_session( # pylint: disable=inconsistent-return-statements cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_agents_stop_session_request( + _request = build_agents_enable_request( agent_name=agent_name, - session_id=session_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -5904,44 +6425,20 @@ def stop_session( # pylint: disable=inconsistent-return-statements return cls(pipeline_response, None, {}) # type: ignore @distributed_trace - def list_sessions( - self, - agent_name: str, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> ItemPaged["_models.AgentSessionResource"]: - """List sessions for an agent. + def disable(self, agent_name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Disable an agent. - Returns a paged collection of sessions associated with the specified agent endpoint. + Disables the specified agent, preventing it from accepting new sessions or processing requests. + Existing active sessions are allowed to drain gracefully but no new sessions can be created. + This operation is idempotent — disabling an already-disabled agent returns success with no side + effects. - :param agent_name: The name of the agent. Required. + :param agent_name: The name of the agent to disable. Required. :type agent_name: str - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of AgentSessionResource - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentSessionResource] + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.AgentSessionResource]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -5950,96 +6447,226 @@ def list_sessions( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - _request = build_agents_list_sessions_request( - agent_name=agent_name, - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request + cls: ClsType[None] = kwargs.pop("cls", None) - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.AgentSessionResource], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + _request = build_agents_disable_request( + agent_name=agent_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + response = pipeline_response.http_response - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - return pipeline_response + if cls: + return cls(pipeline_response, None, {}) # type: ignore - return ItemPaged(get_next, extract_data) + @overload + def create_session( + self, + agent_name: str, + *, + version_indicator: _models.VersionIndicator, + content_type: str = "application/json", + agent_session_id: Optional[str] = None, + **kwargs: Any + ) -> _models.AgentSessionResource: + """Create a session. + + Creates a new session for an agent endpoint. The endpoint resolves the backing agent version + from ``version_indicator`` and enforces session ownership using the provided user identity for + session-mutating operations. + + :param agent_name: The name of the agent to create a session for. Required. + :type agent_name: str + :keyword version_indicator: Determines which agent version backs the session. Required. + :paramtype version_indicator: ~azure.ai.projects.models.VersionIndicator + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword agent_session_id: Optional caller-provided session ID. If specified, it must be unique + within the agent endpoint. Auto-generated if omitted. Default value is None. + :paramtype agent_session_id: str + :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentSessionResource + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_session( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentSessionResource: + """Create a session. + + Creates a new session for an agent endpoint. The endpoint resolves the backing agent version + from ``version_indicator`` and enforces session ownership using the provided user identity for + session-mutating operations. + + :param agent_name: The name of the agent to create a session for. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentSessionResource + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_session( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentSessionResource: + """Create a session. + + Creates a new session for an agent endpoint. The endpoint resolves the backing agent version + from ``version_indicator`` and enforces session ownership using the provided user identity for + session-mutating operations. + + :param agent_name: The name of the agent to create a session for. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentSessionResource + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def get_session_log_stream( - self, agent_name: str, agent_version: str, session_id: str, **kwargs: Any - ) -> _models.SessionLogEvent: - """Stream console logs for a hosted agent session. + def create_session( + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + version_indicator: _models.VersionIndicator = _Unset, + agent_session_id: Optional[str] = None, + **kwargs: Any + ) -> _models.AgentSessionResource: + """Create a session. - Streams console logs (stdout / stderr) for a specific hosted agent session - as a Server-Sent Events (SSE) stream. + Creates a new session for an agent endpoint. The endpoint resolves the backing agent version + from ``version_indicator`` and enforces session ownership using the provided user identity for + session-mutating operations. - Each SSE frame contains: + :param agent_name: The name of the agent to create a session for. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword version_indicator: Determines which agent version backs the session. Required. + :paramtype version_indicator: ~azure.ai.projects.models.VersionIndicator + :keyword agent_session_id: Optional caller-provided session ID. If specified, it must be unique + within the agent endpoint. Auto-generated if omitted. Default value is None. + :paramtype agent_session_id: str + :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentSessionResource + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - * `event`: always `"log"` - * `data`: a plain-text log line (currently JSON-formatted, but the schema is not contractual and may include additional keys or change format over time; clients should treat it as an opaque string) + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - Example SSE frames: + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentSessionResource] = kwargs.pop("cls", None) - .. code-block:: + if body is _Unset: + if version_indicator is _Unset: + raise TypeError("missing required argument: version_indicator") + body = {"agent_session_id": agent_session_id, "version_indicator": version_indicator} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - event: log - data: {"timestamp":"2026-03-10T09:33:17.121Z","stream":"stdout","message":"Starting FoundryCBAgent server on port 8088"} + _request = build_agents_create_session_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - event: log - data: {"timestamp":"2026-03-10T09:33:17.130Z","stream":"stderr","message":"INFO: Application startup complete."} + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - event: log - data: {"timestamp":"2026-03-10T09:34:52.714Z","stream":"status","message":"Successfully connected to container"} + response = pipeline_response.http_response - event: log - data: {"timestamp":"2026-03-10T09:35:52.714Z","stream":"status","message":"No logs since last 60 seconds"} + if response.status_code not in [201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - The stream remains open until the client disconnects or the server - terminates the connection. Clients should handle reconnection as needed. + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentSessionResource, response.json()) - :param agent_name: The name of the hosted agent. Required. + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def get_session(self, agent_name: str, session_id: str, **kwargs: Any) -> _models.AgentSessionResource: + """Get a session. + + Retrieves the details of a hosted agent session by agent name and session identifier. + + :param agent_name: The name of the agent. Required. :type agent_name: str - :param agent_version: The version of the agent. Required. - :type agent_version: str - :param session_id: The session ID (maps to an ADC sandbox). Required. + :param session_id: The session identifier. Required. :type session_id: str - :return: SessionLogEvent. The SessionLogEvent is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionLogEvent + :return: AgentSessionResource. The AgentSessionResource is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentSessionResource :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -6053,11 +6680,10 @@ def get_session_log_stream( _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.SessionLogEvent] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentSessionResource] = kwargs.pop("cls", None) - _request = build_agents_get_session_log_stream_request( + _request = build_agents_get_session_request( agent_name=agent_name, - agent_version=agent_version, session_id=session_id, api_version=self._config.api_version, headers=_headers, @@ -6069,7 +6695,7 @@ def get_session_log_stream( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -6089,287 +6715,175 @@ def get_session_log_stream( ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.SessionLogEvent, response.text()) + deserialized = _deserialize(_models.AgentSessionResource, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - def publish_to_microsoft365( - self, - agent_name: str, - *, - publish_scope: Union[str, _models.Microsoft365PublishScope], - content_type: str = "application/json", - agent_display_name: Optional[str] = None, - bot_service_arm_id: Optional[str] = None, - publish_as_autopilot: Optional[bool] = None, - access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, - optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, - can_respond_without_mention: Optional[bool] = None, - app_version: Optional[str] = None, - short_description: Optional[str] = None, - full_description: Optional[str] = None, - developer_name: Optional[str] = None, - developer_website_url: Optional[str] = None, - privacy_url: Optional[str] = None, - terms_of_use_url: Optional[str] = None, - color_icon_base64: Optional[str] = None, - outline_icon_base64: Optional[str] = None, - **kwargs: Any - ) -> _models.Microsoft365PublishResult: - """Publish an agent to Microsoft 365. + @distributed_trace + def delete_session( # pylint: disable=inconsistent-return-statements + self, agent_name: str, session_id: str, **kwargs: Any + ) -> None: + """Delete a session. - Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title - and Teams app ids. + Deletes a session synchronously. Returns 204 No Content when the session is deleted or does not + exist. - :param agent_name: The name of the agent to publish. Required. + :param agent_name: The name of the agent. Required. :type agent_name: str - :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", - "Shared", and "Tenant". Required. - :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword agent_display_name: Display name used as the published Teams app name. When omitted, - the agent name from the route is - used. Default value is None. - :paramtype agent_display_name: str - :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in - Microsoft Teams. Required for - workspaces on the default bot-based Teams backend; optional for workspaces on the API-based - backend. - Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. - :paramtype bot_service_arm_id: str - :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital - worker) agent: the bot id is taken from - the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. - Default value is None. - :paramtype publish_as_autopilot: bool - :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when - publishing as an autopilot agent. - An empty list clears the existing boundaries. When omitted, the existing boundaries are left - unchanged. Default value is None. - :paramtype access_boundaries: list[str or - ~azure.ai.projects.models.ActivityProtocolAccessBoundary] - :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to - the autopilot blueprint. May only be - supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default - permission set is used. Mandatory platform permissions are always granted and are not affected - by - this value. Default value is None. - :paramtype optional_permission_scopes: - list[~azure.ai.projects.models.Microsoft365PermissionScopes] - :keyword can_respond_without_mention: Controls how the published agent responds to Teams - messages: when true it responds to all messages - on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing - Teams - message-notification setting is left unchanged. Default value is None. - :paramtype can_respond_without_mention: bool - :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May - contain only digits and - periods, must not start with ``0``, and must end with a digit. When omitted, a platform - default is - used. Default value is None. - :paramtype app_version: str - :keyword short_description: Short, one-line description shown in the Teams app listing. Default - value is None. - :paramtype short_description: str - :keyword full_description: Full description shown on the Teams app details page. Default value - is None. - :paramtype full_description: str - :keyword developer_name: Display name of the developer / publisher shown in the Teams app - listing. Default value is None. - :paramtype developer_name: str - :keyword developer_website_url: Developer / publisher website URL shown in the Teams app - listing. Must be an https URL. Default value is None. - :paramtype developer_website_url: str - :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or - https URL. Default value is None. - :paramtype privacy_url: str - :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is - None. - :paramtype terms_of_use_url: str - :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in - the Teams app package. Must be a - 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When - omitted, the - platform default color icon is used. Default value is None. - :paramtype color_icon_base64: str - :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams - app package. Must be a 32x32 PNG. - Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value - is None. - :paramtype outline_icon_base64: str - :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :param session_id: The session identifier. Required. + :type session_id: str + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - @overload - def publish_to_microsoft365( - self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Microsoft365PublishResult: - """Publish an agent to Microsoft 365. + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title - and Teams app ids. + cls: ClsType[None] = kwargs.pop("cls", None) - :param agent_name: The name of the agent to publish. Required. - :type agent_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.Microsoft365PublishResult - :raises ~azure.core.exceptions.HttpResponseError: - """ + _request = build_agents_delete_session_request( + agent_name=agent_name, + session_id=session_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - @overload - def publish_to_microsoft365( - self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Microsoft365PublishResult: - """Publish an agent to Microsoft 365. + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title - and Teams app ids. + response = pipeline_response.http_response - :param agent_name: The name of the agent to publish. Required. + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace + def stop_session( # pylint: disable=inconsistent-return-statements + self, agent_name: str, session_id: str, **kwargs: Any + ) -> None: + """Stop a session. + + Terminates the specified hosted agent session and returns 204 No Content when the request + succeeds. + + :param agent_name: The name of the agent. Required. :type agent_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :param session_id: The session identifier. Required. + :type session_id: str + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_agents_stop_session_request( + agent_name=agent_name, + session_id=session_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore @distributed_trace - def publish_to_microsoft365( # pylint: disable=too-many-locals + def list_sessions( self, agent_name: str, - body: Union[JSON, IO[bytes]] = _Unset, *, - publish_scope: Union[str, _models.Microsoft365PublishScope] = _Unset, - agent_display_name: Optional[str] = None, - bot_service_arm_id: Optional[str] = None, - publish_as_autopilot: Optional[bool] = None, - access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, - optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, - can_respond_without_mention: Optional[bool] = None, - app_version: Optional[str] = None, - short_description: Optional[str] = None, - full_description: Optional[str] = None, - developer_name: Optional[str] = None, - developer_website_url: Optional[str] = None, - privacy_url: Optional[str] = None, - terms_of_use_url: Optional[str] = None, - color_icon_base64: Optional[str] = None, - outline_icon_base64: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> _models.Microsoft365PublishResult: - """Publish an agent to Microsoft 365. + ) -> ItemPaged["_models.AgentSessionResource"]: + """List sessions for an agent. - Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title - and Teams app ids. + Returns a paged collection of sessions associated with the specified agent endpoint. - :param agent_name: The name of the agent to publish. Required. + :param agent_name: The name of the agent. Required. :type agent_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", - "Shared", and "Tenant". Required. - :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope - :keyword agent_display_name: Display name used as the published Teams app name. When omitted, - the agent name from the route is - used. Default value is None. - :paramtype agent_display_name: str - :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in - Microsoft Teams. Required for - workspaces on the default bot-based Teams backend; optional for workspaces on the API-based - backend. - Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. - :paramtype bot_service_arm_id: str - :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital - worker) agent: the bot id is taken from - the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. - :paramtype publish_as_autopilot: bool - :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when - publishing as an autopilot agent. - An empty list clears the existing boundaries. When omitted, the existing boundaries are left - unchanged. Default value is None. - :paramtype access_boundaries: list[str or - ~azure.ai.projects.models.ActivityProtocolAccessBoundary] - :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to - the autopilot blueprint. May only be - supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default - permission set is used. Mandatory platform permissions are always granted and are not affected - by - this value. Default value is None. - :paramtype optional_permission_scopes: - list[~azure.ai.projects.models.Microsoft365PermissionScopes] - :keyword can_respond_without_mention: Controls how the published agent responds to Teams - messages: when true it responds to all messages - on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing - Teams - message-notification setting is left unchanged. Default value is None. - :paramtype can_respond_without_mention: bool - :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May - contain only digits and - periods, must not start with ``0``, and must end with a digit. When omitted, a platform - default is - used. Default value is None. - :paramtype app_version: str - :keyword short_description: Short, one-line description shown in the Teams app listing. Default - value is None. - :paramtype short_description: str - :keyword full_description: Full description shown on the Teams app details page. Default value - is None. - :paramtype full_description: str - :keyword developer_name: Display name of the developer / publisher shown in the Teams app - listing. Default value is None. - :paramtype developer_name: str - :keyword developer_website_url: Developer / publisher website URL shown in the Teams app - listing. Must be an https URL. Default value is None. - :paramtype developer_website_url: str - :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or - https URL. Default value is None. - :paramtype privacy_url: str - :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is - None. - :paramtype terms_of_use_url: str - :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in - the Teams app package. Must be a - 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When - omitted, the - platform default color icon is used. Default value is None. - :paramtype color_icon_base64: str - :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams - app package. Must be a 32x32 PNG. - Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value - is None. - :paramtype outline_icon_base64: str - :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :paramtype before: str + :return: An iterator like instance of AgentSessionResource + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentSessionResource] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.AgentSessionResource]] = kwargs.pop("cls", None) + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -6378,46 +6892,116 @@ def publish_to_microsoft365( # pylint: disable=too-many-locals } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Microsoft365PublishResult] = kwargs.pop("cls", None) + def prepare_request(_continuation_token=None): - if body is _Unset: - if publish_scope is _Unset: - raise TypeError("missing required argument: publish_scope") - body = { - "accessBoundaries": access_boundaries, - "agentDisplayName": agent_display_name, - "appVersion": app_version, - "botServiceArmId": bot_service_arm_id, - "canRespondWithoutMention": can_respond_without_mention, - "colorIconBase64": color_icon_base64, - "developerName": developer_name, - "developerWebsiteUrl": developer_website_url, - "fullDescription": full_description, - "optionalPermissionScopes": optional_permission_scopes, - "outlineIconBase64": outline_icon_base64, - "privacyUrl": privacy_url, - "publishAsAutopilot": publish_as_autopilot, - "publishScope": publish_scope, - "shortDescription": short_description, - "termsOfUseUrl": terms_of_use_url, + _request = build_agents_list_sessions_request( + agent_name=agent_name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - _request = build_agents_publish_to_microsoft365_request( + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.AgentSessionResource], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def get_session_log_stream( + self, agent_name: str, agent_version: str, session_id: str, **kwargs: Any + ) -> _models.SessionLogEvent: + """Stream console logs for a hosted agent session. + + Streams console logs (stdout / stderr) for a specific hosted agent session + as a Server-Sent Events (SSE) stream. + + Each SSE frame contains: + + * `event`: always `"log"` + * `data`: a plain-text log line (currently JSON-formatted, but the schema is not contractual and may include additional keys or change format over time; clients should treat it as an opaque string) + + Example SSE frames: + + .. code-block:: + + event: log + data: {"timestamp":"2026-03-10T09:33:17.121Z","stream":"stdout","message":"Starting FoundryCBAgent server on port 8088"} + + event: log + data: {"timestamp":"2026-03-10T09:33:17.130Z","stream":"stderr","message":"INFO: Application startup complete."} + + event: log + data: {"timestamp":"2026-03-10T09:34:52.714Z","stream":"status","message":"Successfully connected to container"} + + event: log + data: {"timestamp":"2026-03-10T09:35:52.714Z","stream":"status","message":"No logs since last 60 seconds"} + + The stream remains open until the client disconnects or the server + terminates the connection. Clients should handle reconnection as needed. + + :param agent_name: The name of the hosted agent. Required. + :type agent_name: str + :param agent_version: The version of the agent. Required. + :type agent_version: str + :param session_id: The session ID (maps to an ADC sandbox). Required. + :type session_id: str + :return: SessionLogEvent. The SessionLogEvent is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionLogEvent + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.SessionLogEvent] = kwargs.pop("cls", None) + + _request = build_agents_get_session_log_stream_request( agent_name=agent_name, - content_type=content_type, + agent_version=agent_version, + session_id=session_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -6427,7 +7011,7 @@ def publish_to_microsoft365( # pylint: disable=too-many-locals _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = True pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -6447,18 +7031,21 @@ def publish_to_microsoft365( # pylint: disable=too-many-locals ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Microsoft365PublishResult, response.json()) + deserialized = _deserialize(_models.SessionLogEvent, response.text()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @overload - def get_microsoft365_package( + def publish_to_microsoft365( self, agent_name: str, *, @@ -6480,13 +7067,13 @@ def get_microsoft365_package( color_icon_base64: Optional[str] = None, outline_icon_base64: Optional[str] = None, **kwargs: Any - ) -> Iterator[bytes]: - """Generate a Microsoft 365 app package. + ) -> _models.Microsoft365PublishResult: + """Publish an agent to Microsoft 365. - Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish - request, without publishing it. Returns the app package as ``application/zip``. + Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title + and Teams app ids. - :param agent_name: The name of the agent to generate the app package for. Required. + :param agent_name: The name of the agent to publish. Required. :type agent_name: str :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", "Shared", and "Tenant". Required. @@ -6564,55 +7151,58 @@ def get_microsoft365_package( Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value is None. :paramtype outline_icon_base64: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.Microsoft365PublishResult :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def get_microsoft365_package( + def publish_to_microsoft365( self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> Iterator[bytes]: - """Generate a Microsoft 365 app package. + ) -> _models.Microsoft365PublishResult: + """Publish an agent to Microsoft 365. - Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish - request, without publishing it. Returns the app package as ``application/zip``. + Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title + and Teams app ids. - :param agent_name: The name of the agent to generate the app package for. Required. + :param agent_name: The name of the agent to publish. Required. :type agent_name: str :param body: Required. :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.Microsoft365PublishResult :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def get_microsoft365_package( + def publish_to_microsoft365( self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> Iterator[bytes]: - """Generate a Microsoft 365 app package. + ) -> _models.Microsoft365PublishResult: + """Publish an agent to Microsoft 365. - Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish - request, without publishing it. Returns the app package as ``application/zip``. + Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title + and Teams app ids. - :param agent_name: The name of the agent to generate the app package for. Required. + :param agent_name: The name of the agent to publish. Required. :type agent_name: str :param body: Required. :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.Microsoft365PublishResult :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def get_microsoft365_package( # pylint: disable=too-many-locals + def publish_to_microsoft365( # pylint: disable=too-many-locals self, agent_name: str, body: Union[JSON, IO[bytes]] = _Unset, @@ -6634,6 +7224,204 @@ def get_microsoft365_package( # pylint: disable=too-many-locals color_icon_base64: Optional[str] = None, outline_icon_base64: Optional[str] = None, **kwargs: Any + ) -> _models.Microsoft365PublishResult: + """Publish an agent to Microsoft 365. + + Publishes a Foundry agent to Microsoft 365 / Microsoft Teams and returns the published title + and Teams app ids. + + :param agent_name: The name of the agent to publish. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", + "Shared", and "Tenant". Required. + :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope + :keyword agent_display_name: Display name used as the published Teams app name. When omitted, + the agent name from the route is + used. Default value is None. + :paramtype agent_display_name: str + :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in + Microsoft Teams. Required for + workspaces on the default bot-based Teams backend; optional for workspaces on the API-based + backend. + Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. + :paramtype bot_service_arm_id: str + :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital + worker) agent: the bot id is taken from + the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. + Default value is None. + :paramtype publish_as_autopilot: bool + :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when + publishing as an autopilot agent. + An empty list clears the existing boundaries. When omitted, the existing boundaries are left + unchanged. Default value is None. + :paramtype access_boundaries: list[str or + ~azure.ai.projects.models.ActivityProtocolAccessBoundary] + :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to + the autopilot blueprint. May only be + supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default + permission set is used. Mandatory platform permissions are always granted and are not affected + by + this value. Default value is None. + :paramtype optional_permission_scopes: + list[~azure.ai.projects.models.Microsoft365PermissionScopes] + :keyword can_respond_without_mention: Controls how the published agent responds to Teams + messages: when true it responds to all messages + on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing + Teams + message-notification setting is left unchanged. Default value is None. + :paramtype can_respond_without_mention: bool + :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May + contain only digits and + periods, must not start with ``0``, and must end with a digit. When omitted, a platform + default is + used. Default value is None. + :paramtype app_version: str + :keyword short_description: Short, one-line description shown in the Teams app listing. Default + value is None. + :paramtype short_description: str + :keyword full_description: Full description shown on the Teams app details page. Default value + is None. + :paramtype full_description: str + :keyword developer_name: Display name of the developer / publisher shown in the Teams app + listing. Default value is None. + :paramtype developer_name: str + :keyword developer_website_url: Developer / publisher website URL shown in the Teams app + listing. Must be an https URL. Default value is None. + :paramtype developer_website_url: str + :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or + https URL. Default value is None. + :paramtype privacy_url: str + :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is + None. + :paramtype terms_of_use_url: str + :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in + the Teams app package. Must be a + 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When + omitted, the + platform default color icon is used. Default value is None. + :paramtype color_icon_base64: str + :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams + app package. Must be a 32x32 PNG. + Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value + is None. + :paramtype outline_icon_base64: str + :return: Microsoft365PublishResult. The Microsoft365PublishResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.Microsoft365PublishResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.Microsoft365PublishResult] = kwargs.pop("cls", None) + + if body is _Unset: + if publish_scope is _Unset: + raise TypeError("missing required argument: publish_scope") + body = { + "accessBoundaries": access_boundaries, + "agentDisplayName": agent_display_name, + "appVersion": app_version, + "botServiceArmId": bot_service_arm_id, + "canRespondWithoutMention": can_respond_without_mention, + "colorIconBase64": color_icon_base64, + "developerName": developer_name, + "developerWebsiteUrl": developer_website_url, + "fullDescription": full_description, + "optionalPermissionScopes": optional_permission_scopes, + "outlineIconBase64": outline_icon_base64, + "privacyUrl": privacy_url, + "publishAsAutopilot": publish_as_autopilot, + "publishScope": publish_scope, + "shortDescription": short_description, + "termsOfUseUrl": terms_of_use_url, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_publish_to_microsoft365_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Microsoft365PublishResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def get_microsoft365_package( + self, + agent_name: str, + *, + publish_scope: Union[str, _models.Microsoft365PublishScope], + content_type: str = "application/json", + agent_display_name: Optional[str] = None, + bot_service_arm_id: Optional[str] = None, + publish_as_autopilot: Optional[bool] = None, + access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, + optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, + can_respond_without_mention: Optional[bool] = None, + app_version: Optional[str] = None, + short_description: Optional[str] = None, + full_description: Optional[str] = None, + developer_name: Optional[str] = None, + developer_website_url: Optional[str] = None, + privacy_url: Optional[str] = None, + terms_of_use_url: Optional[str] = None, + color_icon_base64: Optional[str] = None, + outline_icon_base64: Optional[str] = None, + **kwargs: Any ) -> Iterator[bytes]: """Generate a Microsoft 365 app package. @@ -6642,11 +7430,12 @@ def get_microsoft365_package( # pylint: disable=too-many-locals :param agent_name: The name of the agent to generate the app package for. Required. :type agent_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", "Shared", and "Tenant". Required. :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str :keyword agent_display_name: Display name used as the published Teams app name. When omitted, the agent name from the route is used. Default value is None. @@ -6721,6 +7510,3170 @@ def get_microsoft365_package( # pylint: disable=too-many-locals :rtype: Iterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ + + @overload + def get_microsoft365_package( + self, agent_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> Iterator[bytes]: + """Generate a Microsoft 365 app package. + + Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish + request, without publishing it. Returns the app package as ``application/zip``. + + :param agent_name: The name of the agent to generate the app package for. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def get_microsoft365_package( + self, agent_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> Iterator[bytes]: + """Generate a Microsoft 365 app package. + + Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish + request, without publishing it. Returns the app package as ``application/zip``. + + :param agent_name: The name of the agent to generate the app package for. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def get_microsoft365_package( # pylint: disable=too-many-locals + self, + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + publish_scope: Union[str, _models.Microsoft365PublishScope] = _Unset, + agent_display_name: Optional[str] = None, + bot_service_arm_id: Optional[str] = None, + publish_as_autopilot: Optional[bool] = None, + access_boundaries: Optional[List[Union[str, _models.ActivityProtocolAccessBoundary]]] = None, + optional_permission_scopes: Optional[List[_models.Microsoft365PermissionScopes]] = None, + can_respond_without_mention: Optional[bool] = None, + app_version: Optional[str] = None, + short_description: Optional[str] = None, + full_description: Optional[str] = None, + developer_name: Optional[str] = None, + developer_website_url: Optional[str] = None, + privacy_url: Optional[str] = None, + terms_of_use_url: Optional[str] = None, + color_icon_base64: Optional[str] = None, + outline_icon_base64: Optional[str] = None, + **kwargs: Any + ) -> Iterator[bytes]: + """Generate a Microsoft 365 app package. + + Generates the Microsoft Teams app package (zip) for a Foundry agent from the supplied publish + request, without publishing it. Returns the app package as ``application/zip``. + + :param agent_name: The name of the agent to generate the app package for. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword publish_scope: Publish scope for the Teams app. Known values are: "Personal", + "Shared", and "Tenant". Required. + :paramtype publish_scope: str or ~azure.ai.projects.models.Microsoft365PublishScope + :keyword agent_display_name: Display name used as the published Teams app name. When omitted, + the agent name from the route is + used. Default value is None. + :paramtype agent_display_name: str + :keyword bot_service_arm_id: ARM resource id of the Azure Bot Service that fronts this agent in + Microsoft Teams. Required for + workspaces on the default bot-based Teams backend; optional for workspaces on the API-based + backend. + Must not be supplied when ``publishAsAutopilot`` is true. Default value is None. + :paramtype bot_service_arm_id: str + :keyword publish_as_autopilot: When true, the agent is published as an autopilot (digital + worker) agent: the bot id is taken from + the agent's blueprint identity and the generated Teams manifest is marked as a digital worker. + Default value is None. + :paramtype publish_as_autopilot: bool + :keyword access_boundaries: Activity-protocol access boundaries to apply to the agent when + publishing as an autopilot agent. + An empty list clears the existing boundaries. When omitted, the existing boundaries are left + unchanged. Default value is None. + :paramtype access_boundaries: list[str or + ~azure.ai.projects.models.ActivityProtocolAccessBoundary] + :keyword optional_permission_scopes: Exact selection of delegated permission scopes to grant to + the autopilot blueprint. May only be + supplied when ``publishAsAutopilot`` is true. When omitted or empty, the platform's default + permission set is used. Mandatory platform permissions are always granted and are not affected + by + this value. Default value is None. + :paramtype optional_permission_scopes: + list[~azure.ai.projects.models.Microsoft365PermissionScopes] + :keyword can_respond_without_mention: Controls how the published agent responds to Teams + messages: when true it responds to all messages + on its surfaces, when false only when it is at-mentioned. When omitted, the agent's existing + Teams + message-notification setting is left unchanged. Default value is None. + :paramtype can_respond_without_mention: bool + :keyword app_version: App version (for example ``1.2.3``) written into the Teams manifest. May + contain only digits and + periods, must not start with ``0``, and must end with a digit. When omitted, a platform + default is + used. Default value is None. + :paramtype app_version: str + :keyword short_description: Short, one-line description shown in the Teams app listing. Default + value is None. + :paramtype short_description: str + :keyword full_description: Full description shown on the Teams app details page. Default value + is None. + :paramtype full_description: str + :keyword developer_name: Display name of the developer / publisher shown in the Teams app + listing. Default value is None. + :paramtype developer_name: str + :keyword developer_website_url: Developer / publisher website URL shown in the Teams app + listing. Must be an https URL. Default value is None. + :paramtype developer_website_url: str + :keyword privacy_url: Privacy policy URL shown in the Teams app listing. Must be an http or + https URL. Default value is None. + :paramtype privacy_url: str + :keyword terms_of_use_url: Terms-of-use URL shown in the Teams app listing. Default value is + None. + :paramtype terms_of_use_url: str + :keyword color_icon_base64: Optional base64-encoded PNG used as the color (full-bleed) icon in + the Teams app package. Must be a + 192x192 PNG (perfect square, no border or rounded corners). Max 1 MB after decode. When + omitted, the + platform default color icon is used. Default value is None. + :paramtype color_icon_base64: str + :keyword outline_icon_base64: Optional base64-encoded PNG used as the outline icon in the Teams + app package. Must be a 32x32 PNG. + Max 1 MB after decode. When omitted, the platform default outline icon is used. Default value + is None. + :paramtype outline_icon_base64: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + + if body is _Unset: + if publish_scope is _Unset: + raise TypeError("missing required argument: publish_scope") + body = { + "accessBoundaries": access_boundaries, + "agentDisplayName": agent_display_name, + "appVersion": app_version, + "botServiceArmId": bot_service_arm_id, + "canRespondWithoutMention": can_respond_without_mention, + "colorIconBase64": color_icon_base64, + "developerName": developer_name, + "developerWebsiteUrl": developer_website_url, + "fullDescription": full_description, + "optionalPermissionScopes": optional_permission_scopes, + "outlineIconBase64": outline_icon_base64, + "privacyUrl": privacy_url, + "publishAsAutopilot": publish_as_autopilot, + "publishScope": publish_scope, + "shortDescription": short_description, + "termsOfUseUrl": terms_of_use_url, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_agents_get_microsoft365_package_request( + agent_name=agent_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def get_microsoft365_publish_defaults( + self, agent_name: str, *, publish_as_digital_worker: Optional[bool] = None, **kwargs: Any + ) -> _models.Microsoft365PublishDefaults: + """Get Microsoft 365 publish defaults. + + Returns default and previously-published values used to pre-populate a Microsoft 365 publish + request for a Foundry agent. + + :param agent_name: The name of the agent to get publish defaults for. Required. + :type agent_name: str + :keyword publish_as_digital_worker: When true, returns defaults for publishing the agent as an + autopilot (digital worker) agent. Default value is None. + :paramtype publish_as_digital_worker: bool + :return: Microsoft365PublishDefaults. The Microsoft365PublishDefaults is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.Microsoft365PublishDefaults + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Microsoft365PublishDefaults] = kwargs.pop("cls", None) + + _request = build_agents_get_microsoft365_publish_defaults_request( + agent_name=agent_name, + publish_as_digital_worker=publish_as_digital_worker, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Microsoft365PublishDefaults, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def upload_session_file( + self, + agent_name: str, + session_id: str, + content: bytes, + *, + path: str, + content_type: str = "application/octet-stream", + **kwargs: Any + ) -> _models.SessionFileWriteResult: + """Upload a session file. + + Uploads binary file content to the specified path in the session sandbox. The service stores + the file relative to the session home directory and rejects payloads larger than 50 MB. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :param content: Required. + :type content: bytes + :keyword path: The destination file path within the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/octet-stream". + :paramtype content_type: str + :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def upload_session_file( + self, + agent_name: str, + session_id: str, + content: IO[bytes], + *, + path: str, + content_type: str = "application/octet-stream", + **kwargs: Any + ) -> _models.SessionFileWriteResult: + """Upload a session file. + + Uploads binary file content to the specified path in the session sandbox. The service stores + the file relative to the session home directory and rejects payloads larger than 50 MB. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :param content: Required. + :type content: IO[bytes] + :keyword path: The destination file path within the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/octet-stream". + :paramtype content_type: str + :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def upload_session_file( + self, agent_name: str, session_id: str, content: Union[bytes, IO[bytes]], *, path: str, **kwargs: Any + ) -> _models.SessionFileWriteResult: + """Upload a session file. + + Uploads binary file content to the specified path in the session sandbox. The service stores + the file relative to the session home directory and rejects payloads larger than 50 MB. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :param content: Is either a bytes type or a IO[bytes] type. Required. + :type content: bytes or IO[bytes] + :keyword path: The destination file path within the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SessionFileWriteResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.SessionFileWriteResult] = kwargs.pop("cls", None) + + content_type = content_type or "application/octet-stream" + _content = content + + _request = build_agents_upload_session_file_request( + agent_name=agent_name, + session_id=session_id, + path=path, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.SessionFileWriteResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def download_session_file(self, agent_name: str, session_id: str, *, path: str, **kwargs: Any) -> Iterator[bytes]: + """Download a session file. + + Downloads the file at the specified sandbox path as a binary stream. The path is resolved + relative to the session home directory. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :keyword path: The file path to download from the sandbox, relative to the session home + directory. Required. + :paramtype path: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + + _request = build_agents_download_session_file_request( + agent_name=agent_name, + session_id=session_id, + path=path, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list_session_files( + self, + agent_name: str, + session_id: str, + *, + path: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.SessionDirectoryEntry"]: + """List session files. + + Returns files and directories at the specified path in the session sandbox. The response + includes only the immediate children of the target directory and defaults to the session home + directory when no path is supplied. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :keyword path: The directory path to list, relative to the session home directory. Defaults to + the home directory if not provided. Default value is None. + :paramtype path: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of SessionDirectoryEntry + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.SessionDirectoryEntry] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.SessionDirectoryEntry]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_agents_list_session_files_request( + agent_name=agent_name, + session_id=session_id, + path=path, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.SessionDirectoryEntry], + deserialized.get("entries", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def delete_session_file( # pylint: disable=inconsistent-return-statements + self, agent_name: str, session_id: str, *, path: str, recursive: Optional[bool] = None, **kwargs: Any + ) -> None: + """Delete a session file. + + Deletes the specified file or directory from the session sandbox. When ``recursive`` is false, + deleting a non-empty directory returns 409 Conflict. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param session_id: The session ID. Required. + :type session_id: str + :keyword path: The file or directory path to delete, relative to the session home directory. + Required. + :paramtype path: str + :keyword recursive: Whether to recursively delete directory contents. The service defaults to + ``false`` if a value is not specified by the caller. Default value is None. + :paramtype recursive: bool + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_agents_delete_session_file_request( + agent_name=agent_name, + session_id=session_id, + path=path, + recursive=recursive, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + +class EvaluationRulesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`evaluation_rules` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: + """Get an evaluation rule. + + Retrieves the specified evaluation rule and its configuration. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) + + _request = build_evaluation_rules_get_request( + id=id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.EvaluationRule, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def delete(self, id: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete an evaluation rule. + + Removes the specified evaluation rule from the project. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_evaluation_rules_delete_request( + id=id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @overload + def create_or_update( + self, id: str, evaluation_rule: _models.EvaluationRule, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. + + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Required. + :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_or_update( + self, id: str, evaluation_rule: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. + + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Required. + :type evaluation_rule: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_or_update( + self, id: str, evaluation_rule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. + + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Required. + :type evaluation_rule: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_or_update( + self, id: str, evaluation_rule: Union[_models.EvaluationRule, JSON, IO[bytes]], **kwargs: Any + ) -> _models.EvaluationRule: + """Create or update an evaluation rule. + + Creates a new evaluation rule, or replaces the existing rule when the identifier matches. + + :param id: Unique identifier for the evaluation rule. Required. + :type id: str + :param evaluation_rule: Evaluation rule resource. Is one of the following types: + EvaluationRule, JSON, IO[bytes] Required. + :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule or JSON or IO[bytes] + :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationRule + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(evaluation_rule, (IOBase, bytes)): + _content = evaluation_rule + else: + _content = json.dumps(evaluation_rule, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_evaluation_rules_create_or_update_request( + id=id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.EvaluationRule, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + action_type: Optional[Union[str, _models.EvaluationRuleActionType]] = None, + agent_name: Optional[str] = None, + enabled: Optional[bool] = None, + **kwargs: Any + ) -> ItemPaged["_models.EvaluationRule"]: + """List evaluation rules. + + Returns the evaluation rules configured for the project, optionally filtered by action type, + agent name, or enabled state. + + :keyword action_type: Filter by the type of evaluation rule. Known values are: + "continuousEvaluation" and "humanEvaluationPreview". Default value is None. + :paramtype action_type: str or ~azure.ai.projects.models.EvaluationRuleActionType + :keyword agent_name: Filter by the agent name. Default value is None. + :paramtype agent_name: str + :keyword enabled: Filter by the enabled status. Default value is None. + :paramtype enabled: bool + :return: An iterator like instance of EvaluationRule + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluationRule] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.EvaluationRule]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_evaluation_rules_list_request( + action_type=action_type, + agent_name=agent_name, + enabled=enabled, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.EvaluationRule], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + +class ConnectionsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`connections` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def _get(self, name: str, **kwargs: Any) -> _models.Connection: + """Get a connection. + + Retrieves the specified connection and its configuration details without including credential + values. + + :param name: The friendly name of the connection, provided by the user. Required. + :type name: str + :return: Connection. The Connection is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Connection + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + + _request = build_connections_get_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers["x-ms-client-request-id"] = self._deserialize( + "str", response.headers.get("x-ms-client-request-id") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Connection, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Connection: + """Get a connection with credentials. + + Retrieves the specified connection together with its credential values. + + :param name: The friendly name of the connection, provided by the user. Required. + :type name: str + :return: Connection. The Connection is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Connection + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + + _request = build_connections_get_with_credentials_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers["x-ms-client-request-id"] = self._deserialize( + "str", response.headers.get("x-ms-client-request-id") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Connection, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + connection_type: Optional[Union[str, _models.ConnectionType]] = None, + default_connection: Optional[bool] = None, + **kwargs: Any + ) -> ItemPaged["_models.Connection"]: + """List connections. + + Returns the connections available in the current project, optionally filtered by type or + default status. + + :keyword connection_type: Lists connections of this specific type. Known values are: + "AzureOpenAI", "AzureBlob", "AzureStorageAccount", "CognitiveSearch", "CosmosDB", "ApiKey", + "AppConfig", "AppInsights", "CustomKeys", and "RemoteTool_Preview". Default value is None. + :paramtype connection_type: str or ~azure.ai.projects.models.ConnectionType + :keyword default_connection: Lists connections that are default connections. Default value is + None. + :paramtype default_connection: bool + :return: An iterator like instance of Connection + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Connection] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Connection]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_connections_list_request( + connection_type=connection_type, + default_connection=default_connection, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Connection], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + +class DatasetsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`datasets` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.DatasetVersion"]: + """List versions. + + List all versions of the given DatasetVersion. + + :param name: The name of the resource. Required. + :type name: str + :return: An iterator like instance of DatasetVersion + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.DatasetVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_datasets_list_versions_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.DatasetVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def list(self, **kwargs: Any) -> ItemPaged["_models.DatasetVersion"]: + """List latest versions. + + List the latest version of each DatasetVersion. + + :return: An iterator like instance of DatasetVersion + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.DatasetVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_datasets_list_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.DatasetVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVersion: + """Get a version. + + Get the specific version of the DatasetVersion. The service returns 404 Not Found error if the + DatasetVersion does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to retrieve. Required. + :type version: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) + + _request = build_datasets_get_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DatasetVersion, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete a version. + + Delete the specific version of the DatasetVersion. The service returns 204 No Content if the + DatasetVersion was deleted successfully or if the DatasetVersion does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the DatasetVersion to delete. Required. + :type version: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_datasets_delete_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @overload + def create_or_update( + self, + name: str, + version: str, + dataset_version: _models.DatasetVersion, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Required. + :type dataset_version: ~azure.ai.projects.models.DatasetVersion + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_or_update( + self, + name: str, + version: str, + dataset_version: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Required. + :type dataset_version: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_or_update( + self, + name: str, + version: str, + dataset_version: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Required. + :type dataset_version: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_or_update( + self, name: str, version: str, dataset_version: Union[_models.DatasetVersion, JSON, IO[bytes]], **kwargs: Any + ) -> _models.DatasetVersion: + """Create or update a version. + + Create a new or update an existing DatasetVersion with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to create or update. Required. + :type version: str + :param dataset_version: The DatasetVersion to create or update. Is one of the following types: + DatasetVersion, JSON, IO[bytes] Required. + :type dataset_version: ~azure.ai.projects.models.DatasetVersion or JSON or IO[bytes] + :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) + + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(dataset_version, (IOBase, bytes)): + _content = dataset_version + else: + _content = json.dumps(dataset_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_datasets_create_or_update_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DatasetVersion, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: _models.PendingUploadRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: Union[_models.PendingUploadRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Is one of the following + types: PendingUploadRequest, JSON, IO[bytes] Required. + :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest or JSON or + IO[bytes] + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.PendingUploadResponse] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(pending_upload_request, (IOBase, bytes)): + _content = pending_upload_request + else: + _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_datasets_pending_upload_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.PendingUploadResponse, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def get_credentials(self, name: str, version: str, **kwargs: Any) -> _models.DatasetCredential: + """Get dataset credentials. + + Retrieves the SAS credential to access the storage account associated with a dataset version. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the DatasetVersion to operate on. Required. + :type version: str + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) + + _request = build_datasets_get_credentials_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DatasetCredential, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +class DeploymentsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`deployments` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def get(self, name: str, **kwargs: Any) -> _models.Deployment: + """Get a deployment. + + Retrieves a deployed model. + + :param name: Name of the deployment. Required. + :type name: str + :return: Deployment. The Deployment is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Deployment + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Deployment] = kwargs.pop("cls", None) + + _request = build_deployments_get_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers["x-ms-client-request-id"] = self._deserialize( + "str", response.headers.get("x-ms-client-request-id") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Deployment, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + model_publisher: Optional[str] = None, + model_name: Optional[str] = None, + deployment_type: Optional[Union[str, _models.DeploymentType]] = None, + **kwargs: Any + ) -> ItemPaged["_models.Deployment"]: + """List deployments. + + Returns the deployed models available in the current project, optionally filtered by publisher, + model name, or deployment type. + + :keyword model_publisher: Model publisher to filter models by. Default value is None. + :paramtype model_publisher: str + :keyword model_name: Model name (the publisher specific name) to filter models by. Default + value is None. + :paramtype model_name: str + :keyword deployment_type: Type of deployment to filter list by. "ModelDeployment" Default value + is None. + :paramtype deployment_type: str or ~azure.ai.projects.models.DeploymentType + :return: An iterator like instance of Deployment + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Deployment] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Deployment]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_deployments_list_request( + model_publisher=model_publisher, + model_name=model_name, + deployment_type=deployment_type, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Deployment], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + +class IndexesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`indexes` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.Index"]: + """List versions. + + List all versions of the given Index. + + :param name: The name of the resource. Required. + :type name: str + :return: An iterator like instance of Index + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Index] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_indexes_list_versions_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Index], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def list(self, **kwargs: Any) -> ItemPaged["_models.Index"]: + """List latest versions. + + List the latest version of each Index. + + :return: An iterator like instance of Index + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Index] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_indexes_list_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Index], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: + """Get a version. + + Get the specific version of the Index. The service returns 404 Not Found error if the Index + does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to retrieve. Required. + :type version: str + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Index] = kwargs.pop("cls", None) + + _request = build_indexes_get_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Index, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete a version. + + Delete the specific version of the Index. The service returns 204 No Content if the Index was + deleted successfully or if the Index does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the Index to delete. Required. + :type version: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_indexes_delete_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @overload + def create_or_update( + self, + name: str, + version: str, + index: _models.Index, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.Index: + """Create or update a version. + + Create a new or update an existing Index with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Required. + :type index: ~azure.ai.projects.models.Index + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_or_update( + self, name: str, version: str, index: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.Index: + """Create or update a version. + + Create a new or update an existing Index with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Required. + :type index: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_or_update( + self, + name: str, + version: str, + index: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.Index: + """Create or update a version. + + Create a new or update an existing Index with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Required. + :type index: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_or_update( + self, name: str, version: str, index: Union[_models.Index, JSON, IO[bytes]], **kwargs: Any + ) -> _models.Index: + """Create or update a version. + + Create a new or update an existing Index with the given version id. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the Index to create or update. Required. + :type version: str + :param index: The Index to create or update. Is one of the following types: Index, JSON, + IO[bytes] Required. + :type index: ~azure.ai.projects.models.Index or JSON or IO[bytes] + :return: Index. The Index is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Index + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.Index] = kwargs.pop("cls", None) + + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(index, (IOBase, bytes)): + _content = index + else: + _content = json.dumps(index, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_indexes_create_or_update_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200, 201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Index, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +class ToolboxesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`toolboxes` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @overload + def create_version( + self, + name: str, + *, + tools: List[_models.ToolboxTool], + content_type: str = "application/json", + description: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + skills: Optional[List[_models.ToolboxSkill]] = None, + policies: Optional[_models.ToolboxPolicies] = None, + **kwargs: Any + ) -> _models.ToolboxVersionObject: + """Create a new version of a toolbox. + + Creates a new toolbox version, provisioning the toolbox itself if it does not already exist. + + :param name: The name of the toolbox. If the toolbox does not exist, it will be created. + Required. + :type name: str + :keyword tools: The list of tools to include in this version. Required. + :paramtype tools: list[~azure.ai.projects.models.ToolboxTool] + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword description: A human-readable description of the toolbox. Default value is None. + :paramtype description: str + :keyword metadata: Arbitrary key-value metadata to associate with the toolbox. Default value is + None. + :paramtype metadata: dict[str, str] + :keyword skills: The list of skill sources to include in this version. A skill reference + specifies a skill name and optionally a version. If version is omitted, the skill's default + version is used. Default value is None. + :paramtype skills: list[~azure.ai.projects.models.ToolboxSkill] + :keyword policies: Policy configuration for this toolbox version. Default value is None. + :paramtype policies: ~azure.ai.projects.models.ToolboxPolicies + :return: ToolboxVersionObject. The ToolboxVersionObject is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ToolboxVersionObject + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_version( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.ToolboxVersionObject: + """Create a new version of a toolbox. + + Creates a new toolbox version, provisioning the toolbox itself if it does not already exist. + + :param name: The name of the toolbox. If the toolbox does not exist, it will be created. + Required. + :type name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: ToolboxVersionObject. The ToolboxVersionObject is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ToolboxVersionObject + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_version( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.ToolboxVersionObject: + """Create a new version of a toolbox. + + Creates a new toolbox version, provisioning the toolbox itself if it does not already exist. + + :param name: The name of the toolbox. If the toolbox does not exist, it will be created. + Required. + :type name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: ToolboxVersionObject. The ToolboxVersionObject is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ToolboxVersionObject + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_version( + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + tools: List[_models.ToolboxTool] = _Unset, + description: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + skills: Optional[List[_models.ToolboxSkill]] = None, + policies: Optional[_models.ToolboxPolicies] = None, + **kwargs: Any + ) -> _models.ToolboxVersionObject: + """Create a new version of a toolbox. + + Creates a new toolbox version, provisioning the toolbox itself if it does not already exist. + + :param name: The name of the toolbox. If the toolbox does not exist, it will be created. + Required. + :type name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword tools: The list of tools to include in this version. Required. + :paramtype tools: list[~azure.ai.projects.models.ToolboxTool] + :keyword description: A human-readable description of the toolbox. Default value is None. + :paramtype description: str + :keyword metadata: Arbitrary key-value metadata to associate with the toolbox. Default value is + None. + :paramtype metadata: dict[str, str] + :keyword skills: The list of skill sources to include in this version. A skill reference + specifies a skill name and optionally a version. If version is omitted, the skill's default + version is used. Default value is None. + :paramtype skills: list[~azure.ai.projects.models.ToolboxSkill] + :keyword policies: Policy configuration for this toolbox version. Default value is None. + :paramtype policies: ~azure.ai.projects.models.ToolboxPolicies + :return: ToolboxVersionObject. The ToolboxVersionObject is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ToolboxVersionObject + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.ToolboxVersionObject] = kwargs.pop("cls", None) + + if body is _Unset: + if tools is _Unset: + raise TypeError("missing required argument: tools") + body = { + "description": description, + "metadata": metadata, + "policies": policies, + "skills": skills, + "tools": tools, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_toolboxes_create_version_request( + name=name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.ToolboxVersionObject, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def get(self, name: str, **kwargs: Any) -> _models.ToolboxObject: + """Retrieve a toolbox. + + Retrieves the specified toolbox and its current configuration. + + :param name: The name of the toolbox to retrieve. Required. + :type name: str + :return: ToolboxObject. The ToolboxObject is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ToolboxObject + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.ToolboxObject] = kwargs.pop("cls", None) + + _request = build_toolboxes_get_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.ToolboxObject, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.ToolboxObject"]: + """List toolboxes. + + Returns the toolboxes available in the current project. + + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of ToolboxObject + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.ToolboxObject] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ToolboxObject]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_toolboxes_list_request( + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ToolboxObject], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def list_versions( + self, + name: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.ToolboxVersionObject"]: + """List toolbox versions. + + Returns the available versions for the specified toolbox. + + :param name: The name of the toolbox to list versions for. Required. + :type name: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of ToolboxVersionObject + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.ToolboxVersionObject] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ToolboxVersionObject]] = kwargs.pop("cls", None) + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -6729,102 +10682,67 @@ def get_microsoft365_package( # pylint: disable=too-many-locals } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + def prepare_request(_continuation_token=None): - if body is _Unset: - if publish_scope is _Unset: - raise TypeError("missing required argument: publish_scope") - body = { - "accessBoundaries": access_boundaries, - "agentDisplayName": agent_display_name, - "appVersion": app_version, - "botServiceArmId": bot_service_arm_id, - "canRespondWithoutMention": can_respond_without_mention, - "colorIconBase64": color_icon_base64, - "developerName": developer_name, - "developerWebsiteUrl": developer_website_url, - "fullDescription": full_description, - "optionalPermissionScopes": optional_permission_scopes, - "outlineIconBase64": outline_icon_base64, - "privacyUrl": privacy_url, - "publishAsAutopilot": publish_as_autopilot, - "publishScope": publish_scope, - "shortDescription": short_description, - "termsOfUseUrl": terms_of_use_url, + _request = build_toolboxes_list_versions_request( + name=name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - - _request = build_agents_get_microsoft365_package_request( - agent_name=agent_name, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ToolboxVersionObject], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) - response = pipeline_response.http_response + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) - raise HttpResponseError(response=response, model=error) - - response_headers = {} - response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + response = pipeline_response.http_response - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return pipeline_response - return deserialized # type: ignore + return ItemPaged(get_next, extract_data) @distributed_trace - def get_microsoft365_publish_defaults( - self, agent_name: str, *, publish_as_digital_worker: Optional[bool] = None, **kwargs: Any - ) -> _models.Microsoft365PublishDefaults: - """Get Microsoft 365 publish defaults. + def get_version(self, name: str, version: str, **kwargs: Any) -> _models.ToolboxVersionObject: + """Retrieve a specific version of a toolbox. - Returns default and previously-published values used to pre-populate a Microsoft 365 publish - request for a Foundry agent. + Retrieves the specified version of a toolbox by name and version identifier. - :param agent_name: The name of the agent to get publish defaults for. Required. - :type agent_name: str - :keyword publish_as_digital_worker: When true, returns defaults for publishing the agent as an - autopilot (digital worker) agent. Default value is None. - :paramtype publish_as_digital_worker: bool - :return: Microsoft365PublishDefaults. The Microsoft365PublishDefaults is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.Microsoft365PublishDefaults + :param name: The name of the toolbox. Required. + :type name: str + :param version: The version identifier to retrieve. Required. + :type version: str + :return: ToolboxVersionObject. The ToolboxVersionObject is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ToolboxVersionObject :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -6838,11 +10756,11 @@ def get_microsoft365_publish_defaults( _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Microsoft365PublishDefaults] = kwargs.pop("cls", None) + cls: ClsType[_models.ToolboxVersionObject] = kwargs.pop("cls", None) - _request = build_agents_get_microsoft365_publish_defaults_request( - agent_name=agent_name, - publish_as_digital_worker=publish_as_digital_worker, + _request = build_toolboxes_get_version_request( + name=name, + version=version, api_version=self._config.api_version, headers=_headers, params=_params, @@ -6876,99 +10794,25 @@ def get_microsoft365_publish_defaults( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Microsoft365PublishDefaults, response.json()) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - @overload - def upload_session_file( - self, - agent_name: str, - session_id: str, - content: bytes, - *, - path: str, - content_type: str = "application/octet-stream", - **kwargs: Any - ) -> _models.SessionFileWriteResult: - """Upload a session file. - - Uploads binary file content to the specified path in the session sandbox. The service stores - the file relative to the session home directory and rejects payloads larger than 50 MB. - - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :param content: Required. - :type content: bytes - :keyword path: The destination file path within the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/octet-stream". - :paramtype content_type: str - :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionFileWriteResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def upload_session_file( - self, - agent_name: str, - session_id: str, - content: IO[bytes], - *, - path: str, - content_type: str = "application/octet-stream", - **kwargs: Any - ) -> _models.SessionFileWriteResult: - """Upload a session file. - - Uploads binary file content to the specified path in the session sandbox. The service stores - the file relative to the session home directory and rejects payloads larger than 50 MB. - - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :param content: Required. - :type content: IO[bytes] - :keyword path: The destination file path within the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/octet-stream". - :paramtype content_type: str - :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionFileWriteResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @distributed_trace - def upload_session_file( - self, agent_name: str, session_id: str, content: Union[bytes, IO[bytes]], *, path: str, **kwargs: Any - ) -> _models.SessionFileWriteResult: - """Upload a session file. - - Uploads binary file content to the specified path in the session sandbox. The service stores - the file relative to the session home directory and rejects payloads larger than 50 MB. - - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :param content: Is either a bytes type or a IO[bytes] type. Required. - :type content: bytes or IO[bytes] - :keyword path: The destination file path within the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :return: SessionFileWriteResult. The SessionFileWriteResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SessionFileWriteResult + deserialized = _deserialize(_models.ToolboxVersionObject, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def invoke_latest_toolbox_mcp(self, name: str, request: dict[str, Any], **kwargs: Any) -> Any: + """Invoke the latest toolbox version through MCP. + + Invokes the latest version of the specified toolbox through its MCP endpoint. + + :param name: The name of the toolbox. Required. + :type name: str + :param request: The MCP request body. Required. + :type request: dict[str, any] + :return: any + :rtype: any :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -6979,19 +10823,16 @@ def upload_session_file( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SessionFileWriteResult] = kwargs.pop("cls", None) + content_type: str = kwargs.pop("content_type") + cls: ClsType[Any] = kwargs.pop("cls", None) - content_type = content_type or "application/octet-stream" - _content = content + _content = request - _request = build_agents_upload_session_file_request( - agent_name=agent_name, - session_id=session_id, - path=path, + _request = build_toolboxes_invoke_latest_toolbox_mcp_request( + name=name, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -7011,7 +10852,7 @@ def upload_session_file( response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket @@ -7024,32 +10865,97 @@ def upload_session_file( ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["content-type"] = self._deserialize("str", response.headers.get("content-type")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.SessionFileWriteResult, response.json()) + deserialized = _deserialize(Any, response.text()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore + @overload + def update( + self, name: str, *, default_version: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.ToolboxObject: + """Update a toolbox to point to a specific version. + + Updates the toolbox's default version pointer to the specified version. + + :param name: The name of the toolbox to update. Required. + :type name: str + :keyword default_version: The version identifier that the toolbox should point to. When set, + the toolbox's default version will resolve to this version instead of the latest. Required. + :paramtype default_version: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: ToolboxObject. The ToolboxObject is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ToolboxObject + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def update( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.ToolboxObject: + """Update a toolbox to point to a specific version. + + Updates the toolbox's default version pointer to the specified version. + + :param name: The name of the toolbox to update. Required. + :type name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: ToolboxObject. The ToolboxObject is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ToolboxObject + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def update( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.ToolboxObject: + """Update a toolbox to point to a specific version. + + Updates the toolbox's default version pointer to the specified version. + + :param name: The name of the toolbox to update. Required. + :type name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: ToolboxObject. The ToolboxObject is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ToolboxObject + :raises ~azure.core.exceptions.HttpResponseError: + """ + @distributed_trace - def download_session_file(self, agent_name: str, session_id: str, *, path: str, **kwargs: Any) -> Iterator[bytes]: - """Download a session file. + def update( + self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, default_version: str = _Unset, **kwargs: Any + ) -> _models.ToolboxObject: + """Update a toolbox to point to a specific version. - Downloads the file at the specified sandbox path as a binary stream. The path is resolved - relative to the session home directory. + Updates the toolbox's default version pointer to the specified version. - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :keyword path: The file path to download from the sandbox, relative to the session home - directory. Required. - :paramtype path: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :param name: The name of the toolbox to update. Required. + :type name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword default_version: The version identifier that the toolbox should point to. When set, + the toolbox's default version will resolve to this version instead of the latest. Required. + :paramtype default_version: str + :return: ToolboxObject. The ToolboxObject is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ToolboxObject :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7060,16 +10966,29 @@ def download_session_file(self, agent_name: str, session_id: str, *, path: str, } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.ToolboxObject] = kwargs.pop("cls", None) - _request = build_agents_download_session_file_request( - agent_name=agent_name, - session_id=session_id, - path=path, + if body is _Unset: + if default_version is _Unset: + raise TypeError("missing required argument: default_version") + body = {"default_version": default_version} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_toolboxes_update_request( + name=name, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -7079,7 +10998,7 @@ def download_session_file(self, agent_name: str, session_id: str, *, path: str, _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -7099,7 +11018,10 @@ def download_session_file(self, agent_name: str, session_id: str, *, path: str, ) raise HttpResponseError(response=response, model=error) - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.ToolboxObject, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -7107,53 +11029,17 @@ def download_session_file(self, agent_name: str, session_id: str, *, path: str, return deserialized # type: ignore @distributed_trace - def list_session_files( - self, - agent_name: str, - session_id: str, - *, - path: Optional[str] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> ItemPaged["_models.SessionDirectoryEntry"]: - """List session files. + def delete(self, name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete a toolbox. - Returns files and directories at the specified path in the session sandbox. The response - includes only the immediate children of the target directory and defaults to the session home - directory when no path is supplied. + Removes the specified toolbox along with all of its versions. - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :keyword path: The directory path to list, relative to the session home directory. Defaults to - the home directory if not provided. Default value is None. - :paramtype path: str - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of SessionDirectoryEntry - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.SessionDirectoryEntry] + :param name: The name of the toolbox to delete. Required. + :type name: str + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.SessionDirectoryEntry]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -7162,76 +11048,52 @@ def list_session_files( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): - - _request = build_agents_list_session_files_request( - agent_name=agent_name, - session_id=session_id, - path=path, - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request - - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.SessionDirectoryEntry], - deserialized.get("entries", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) - - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + cls: ClsType[None] = kwargs.pop("cls", None) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + _request = build_toolboxes_delete_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - return pipeline_response + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - return ItemPaged(get_next, extract_data) + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore @distributed_trace - def delete_session_file( # pylint: disable=inconsistent-return-statements - self, agent_name: str, session_id: str, *, path: str, recursive: Optional[bool] = None, **kwargs: Any + def delete_version( # pylint: disable=inconsistent-return-statements + self, name: str, version: str, **kwargs: Any ) -> None: - """Delete a session file. + """Delete a specific version of a toolbox. - Deletes the specified file or directory from the session sandbox. When ``recursive`` is false, - deleting a non-empty directory returns 409 Conflict. + Removes the specified version of a toolbox. - :param agent_name: The name of the agent. Required. - :type agent_name: str - :param session_id: The session ID. Required. - :type session_id: str - :keyword path: The file or directory path to delete, relative to the session home directory. - Required. - :paramtype path: str - :keyword recursive: Whether to recursively delete directory contents. The service defaults to - ``false`` if a value is not specified by the caller. Default value is None. - :paramtype recursive: bool + :param name: The name of the toolbox. Required. + :type name: str + :param version: The version identifier to delete. Required. + :type version: str :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -7249,11 +11111,9 @@ def delete_session_file( # pylint: disable=inconsistent-return-statements cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_agents_delete_session_file_request( - agent_name=agent_name, - session_id=session_id, - path=path, - recursive=recursive, + _request = build_toolboxes_delete_version_request( + name=name, + version=version, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7282,14 +11142,39 @@ def delete_session_file( # pylint: disable=inconsistent-return-statements return cls(pipeline_response, None, {}) # type: ignore -class EvaluationRulesOperations: # pylint: disable=docstring-missing-param +class BetaVoiceAgentsOperations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. Instead, you should access the following operations through :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`evaluation_rules` attribute. + :attr:`voice_agents` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + self.conversations = BetaVoiceAgentsConversationsOperations( + self._client, self._config, self._serialize, self._deserialize + ) + self.telephony = BetaVoiceAgentsTelephonyOperations( + self._client, self._config, self._serialize, self._deserialize + ) + + +class BetaAgentsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`agents` attribute. """ def __init__(self, *args, **kwargs) -> None: @@ -7300,15 +11185,17 @@ def __init__(self, *args, **kwargs) -> None: self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") @distributed_trace - def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: - """Get an evaluation rule. + def create_from_prompt(self, body: "_unions.GenerateAgentRequest", **kwargs: Any) -> _models.AgentDetails: + """Generate an agent. - Retrieves the specified evaluation rule and its configuration. + Generates and creates an agent from kind-specific high-level inputs. The generated definition + remains fully editable through the standard agent versioning operations. - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule + :param body: The kind-specific inputs for generating and creating an agent. Is one of the + following types: GenerateVoiceAgentRequest Required. + :type body: ~azure.ai.projects.models.GenerateVoiceAgentRequest + :return: AgentDetails. The AgentDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7319,14 +11206,19 @@ def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentDetails] = kwargs.pop("cls", None) - _request = build_evaluation_rules_get_request( - id=id, + content_type = content_type or "application/json" + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_agents_create_from_prompt_request( + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -7350,145 +11242,29 @@ def get(self, id: str, **kwargs: Any) -> _models.EvaluationRule: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluationRule, response.json()) + deserialized = _deserialize(_models.AgentDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def delete(self, id: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete an evaluation rule. - - Removes the specified evaluation rule from the project. - - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[None] = kwargs.pop("cls", None) - - _request = build_evaluation_rules_delete_request( - id=id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if cls: - return cls(pipeline_response, None, {}) # type: ignore - - @overload - def create_or_update( - self, id: str, evaluation_rule: _models.EvaluationRule, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. - - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. - - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Required. - :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create_or_update( - self, id: str, evaluation_rule: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. - - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. - - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Required. - :type evaluation_rule: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create_or_update( - self, id: str, evaluation_rule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. - - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. - - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Required. - :type evaluation_rule: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @distributed_trace - def create_or_update( - self, id: str, evaluation_rule: Union[_models.EvaluationRule, JSON, IO[bytes]], **kwargs: Any - ) -> _models.EvaluationRule: - """Create or update an evaluation rule. - - Creates a new evaluation rule, or replaces the existing rule when the identifier matches. - - :param id: Unique identifier for the evaluation rule. Required. - :type id: str - :param evaluation_rule: Evaluation rule resource. Is one of the following types: - EvaluationRule, JSON, IO[bytes] Required. - :type evaluation_rule: ~azure.ai.projects.models.EvaluationRule or JSON or IO[bytes] - :return: EvaluationRule. The EvaluationRule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationRule - :raises ~azure.core.exceptions.HttpResponseError: - """ + def _create_optimization_job_initial( + self, + job: Union[_models.AgentOptimizationJob, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> Iterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -7501,17 +11277,17 @@ def create_or_update( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluationRule] = kwargs.pop("cls", None) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None - if isinstance(evaluation_rule, (IOBase, bytes)): - _content = evaluation_rule + if isinstance(job, (IOBase, bytes)): + _content = job else: - _content = json.dumps(evaluation_rule, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_evaluation_rules_create_or_update_request( - id=id, + _request = build_beta_agents_create_optimization_job_request( + operation_id=operation_id, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -7524,169 +11300,206 @@ def create_or_update( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = True pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200, 201]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [201]: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.EvaluationRule, response.json()) + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace - def list( + @overload + def begin_create_optimization_job( self, + job: _models.AgentOptimizationJob, *, - action_type: Optional[Union[str, _models.EvaluationRuleActionType]] = None, - agent_name: Optional[str] = None, - enabled: Optional[bool] = None, + operation_id: Optional[str] = None, + content_type: str = "application/json", **kwargs: Any - ) -> ItemPaged["_models.EvaluationRule"]: - """List evaluation rules. + ) -> LROPoller[_models.AgentOptimizationJobResult]: + """Create an agent optimization job. - Returns the evaluation rules configured for the project, optionally filtered by action type, - agent name, or enabled state. + Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent + retry. - :keyword action_type: Filter by the type of evaluation rule. Known values are: - "continuousEvaluation" and "humanEvaluationPreview". Default value is None. - :paramtype action_type: str or ~azure.ai.projects.models.EvaluationRuleActionType - :keyword agent_name: Filter by the agent name. Default value is None. - :paramtype agent_name: str - :keyword enabled: Filter by the enabled status. Default value is None. - :paramtype enabled: bool - :return: An iterator like instance of EvaluationRule - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluationRule] + :param job: The job to create. Required. + :type job: ~azure.ai.projects.models.AgentOptimizationJob + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns AgentOptimizationJobResult. The + AgentOptimizationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.EvaluationRule]] = kwargs.pop("cls", None) - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: + @overload + def begin_create_optimization_job( + self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.AgentOptimizationJobResult]: + """Create an agent optimization job. - _request = build_evaluation_rules_list_request( - action_type=action_type, - agent_name=agent_name, - enabled=enabled, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent + retry. - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + :param job: The job to create. Required. + :type job: JSON + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns AgentOptimizationJobResult. The + AgentOptimizationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ - return _request + @overload + def begin_create_optimization_job( + self, + job: IO[bytes], + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.AgentOptimizationJobResult]: + """Create an agent optimization job. - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.EvaluationRule], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent + retry. - def get_next(next_link=None): - _request = prepare_request(next_link) + :param job: The job to create. Required. + :type job: IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns AgentOptimizationJobResult. The + AgentOptimizationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + @distributed_trace + def begin_create_optimization_job( + self, + job: Union[_models.AgentOptimizationJob, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> LROPoller[_models.AgentOptimizationJobResult]: + """Create an agent optimization job. - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent + retry. - return pipeline_response + :param job: The job to create. Is one of the following types: AgentOptimizationJob, JSON, + IO[bytes] Required. + :type job: ~azure.ai.projects.models.AgentOptimizationJob or JSON or IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :return: An instance of LROPoller that returns AgentOptimizationJobResult. The + AgentOptimizationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - return ItemPaged(get_next, extract_data) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentOptimizationJobResult] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._create_optimization_job_initial( + job=job, + operation_id=operation_id, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) -class ConnectionsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + deserialized = _deserialize(_models.AgentOptimizationJobResult, response.json().get("result", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`connections` attribute. - """ + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) + else: + polling_method = polling + if cont_token: + return LROPoller[_models.AgentOptimizationJobResult].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.AgentOptimizationJobResult]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) @distributed_trace - def _get(self, name: str, **kwargs: Any) -> _models.Connection: - """Get a connection. + def get_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOptimizationJob: + """Get an agent optimization job. - Retrieves the specified connection and its configuration details without including credential - values. + Retrieves an optimization job by its identifier. - :param name: The friendly name of the connection, provided by the user. Required. - :type name: str - :return: Connection. The Connection is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Connection + :param job_id: The ID of the job. Required. + :type job_id: str + :return: AgentOptimizationJob. The AgentOptimizationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentOptimizationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7700,10 +11513,10 @@ def _get(self, name: str, **kwargs: Any) -> _models.Connection: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentOptimizationJob] = kwargs.pop("cls", None) - _request = build_connections_get_request( - name=name, + _request = build_beta_agents_get_optimization_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7728,17 +11541,19 @@ def _get(self, name: str, **kwargs: Any) -> _models.Connection: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["x-ms-client-request-id"] = self._deserialize( - "str", response.headers.get("x-ms-client-request-id") - ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Connection, response.json()) + deserialized = _deserialize(_models.AgentOptimizationJob, response.json()) if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore @@ -7746,15 +11561,117 @@ def _get(self, name: str, **kwargs: Any) -> _models.Connection: return deserialized # type: ignore @distributed_trace - def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Connection: - """Get a connection with credentials. + def list_optimization_jobs( + self, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + status: Optional[Union[str, _models.JobStatus]] = None, + agent_name: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.AgentOptimizationJobListItem"]: + """List agent optimization jobs. - Retrieves the specified connection together with its credential values. + Lists optimization jobs with cursor pagination and optional status or agent name filters. - :param name: The friendly name of the connection, provided by the user. Required. - :type name: str - :return: Connection. The Connection is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Connection + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :keyword status: Filter to jobs in this lifecycle state. Known values are: "queued", + "in_progress", "succeeded", "failed", and "cancelled". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.JobStatus + :keyword agent_name: Filter to jobs targeting this agent name. Default value is None. + :paramtype agent_name: str + :return: An iterator like instance of AgentOptimizationJobListItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentOptimizationJobListItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.AgentOptimizationJobListItem]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_beta_agents_list_optimization_jobs_request( + limit=limit, + order=order, + after=_continuation_token, + before=before, + status=status, + agent_name=agent_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.AgentOptimizationJobListItem], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) + + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def cancel_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOptimizationJob: + """Cancel an agent optimization job. + + Requests cancellation of a running or queued job and returns an error if the job is already in + a terminal state. + + :param job_id: The ID of the job to cancel. Required. + :type job_id: str + :return: AgentOptimizationJob. The AgentOptimizationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentOptimizationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -7768,10 +11685,10 @@ def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Connection: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Connection] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentOptimizationJob] = kwargs.pop("cls", None) - _request = build_connections_get_with_credentials_request( - name=name, + _request = build_beta_agents_cancel_optimization_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -7796,138 +11713,87 @@ def _get_with_credentials(self, name: str, **kwargs: Any) -> _models.Connection: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - response_headers = {} - response_headers["x-ms-client-request-id"] = self._deserialize( - "str", response.headers.get("x-ms-client-request-id") - ) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Connection, response.json()) + deserialized = _deserialize(_models.AgentOptimizationJob, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - - return deserialized # type: ignore - - @distributed_trace - def list( - self, - *, - connection_type: Optional[Union[str, _models.ConnectionType]] = None, - default_connection: Optional[bool] = None, - **kwargs: Any - ) -> ItemPaged["_models.Connection"]: - """List connections. - - Returns the connections available in the current project, optionally filtered by type or - default status. - - :keyword connection_type: Lists connections of this specific type. Known values are: - "AzureOpenAI", "AzureBlob", "AzureStorageAccount", "CognitiveSearch", "CosmosDB", "ApiKey", - "AppConfig", "AppInsights", "CustomKeys", and "RemoteTool_Preview". Default value is None. - :paramtype connection_type: str or ~azure.ai.projects.models.ConnectionType - :keyword default_connection: Lists connections that are default connections. Default value is - None. - :paramtype default_connection: bool - :return: An iterator like instance of Connection - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Connection] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.Connection]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_connections_list_request( - connection_type=connection_type, - default_connection=default_connection, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + return cls(pipeline_response, deserialized, {}) # type: ignore - return _request + return deserialized # type: ignore - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Connection], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + @distributed_trace + def delete_optimization_job( # pylint: disable=inconsistent-return-statements + self, job_id: str, **kwargs: Any + ) -> None: + """Delete an agent optimization job. - def get_next(next_link=None): - _request = prepare_request(next_link) + Deletes the job and its candidate artifacts, canceling the job first if it is non-terminal. - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + :param job_id: The ID of the job to delete. Required. + :type job_id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - return pipeline_response + cls: ClsType[None] = kwargs.pop("cls", None) - return ItemPaged(get_next, extract_data) + _request = build_beta_agents_delete_optimization_job_request( + job_id=job_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) -class DatasetsOperations: # pylint: disable=docstring-missing-param + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + +class BetaAgentInsightMonitorsOperations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. Instead, you should access the following operations through :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`datasets` attribute. + :attr:`agent_insight_monitors` attribute. """ def __init__(self, *args, **kwargs) -> None: @@ -7938,21 +11804,35 @@ def __init__(self, *args, **kwargs) -> None: self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") @distributed_trace - def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.DatasetVersion"]: - """List versions. - - List all versions of the given DatasetVersion. + def list( + self, + *, + before: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + agent_name: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.AgentInsightMonitorListItem"]: + """List Agent Insights monitors, optionally filtered by agent name. - :param name: The name of the resource. Required. - :type name: str - :return: An iterator like instance of DatasetVersion - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.DatasetVersion] + :keyword before: A cursor that identifies the first item in the next page. Default value is + None. + :paramtype before: str + :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" + and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword agent_name: Filter monitors by agent name. Default value is None. + :paramtype agent_name: str + :return: An iterator like instance of AgentInsightMonitorListItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentInsightMonitorListItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.AgentInsightMonitorListItem]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -7962,59 +11842,36 @@ def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.DatasetV } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_datasets_list_versions_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + def prepare_request(_continuation_token=None): + _request = build_beta_agent_insight_monitors_list_request( + after=_continuation_token, + before=before, + limit=limit, + order=order, + agent_name=agent_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.DatasetVersion], - deserialized.get("value", []), + List[_models.AgentInsightMonitorListItem], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + return deserialized.get("last_id") or None, iter(list_of_elem) - def get_next(next_link=None): - _request = prepare_request(next_link) + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -8024,115 +11881,75 @@ def get_next(next_link=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) return pipeline_response return ItemPaged(get_next, extract_data) - @distributed_trace - def list(self, **kwargs: Any) -> ItemPaged["_models.DatasetVersion"]: - """List latest versions. - - List the latest version of each DatasetVersion. - - :return: An iterator like instance of DatasetVersion - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.DatasetVersion] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.DatasetVersion]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_datasets_list_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.DatasetVersion], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + @overload + def create( + self, monitor: _models.AgentInsightMonitorCreate, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Create an Agent Insights monitor for an agent. - def get_next(next_link=None): - _request = prepare_request(next_link) + :param monitor: The monitor to create. Required. + :type monitor: ~azure.ai.projects.models.AgentInsightMonitorCreate + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :raises ~azure.core.exceptions.HttpResponseError: + """ - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + @overload + def create( + self, monitor: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Create an Agent Insights monitor for an agent. - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + :param monitor: The monitor to create. Required. + :type monitor: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :raises ~azure.core.exceptions.HttpResponseError: + """ - return pipeline_response + @overload + def create( + self, monitor: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Create an Agent Insights monitor for an agent. - return ItemPaged(get_next, extract_data) + :param monitor: The monitor to create. Required. + :type monitor: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVersion: - """Get a version. - - Get the specific version of the DatasetVersion. The service returns 404 Not Found error if the - DatasetVersion does not exist. + def create( + self, monitor: Union[_models.AgentInsightMonitorCreate, JSON, IO[bytes]], **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Create an Agent Insights monitor for an agent. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to retrieve. Required. - :type version: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion + :param monitor: The monitor to create. Is one of the following types: + AgentInsightMonitorCreate, JSON, IO[bytes] Required. + :type monitor: ~azure.ai.projects.models.AgentInsightMonitorCreate or JSON or IO[bytes] + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8143,15 +11960,23 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVersion: } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) - _request = build_datasets_get_request( - name=name, - version=version, + content_type = content_type or "application/json" + _content = None + if isinstance(monitor, (IOBase, bytes)): + _content = monitor + else: + _content = json.dumps(monitor, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_agent_insight_monitors_create_request( + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -8168,38 +11993,40 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.DatasetVersion: response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [201]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DatasetVersion, response.json()) + deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace - def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete a version. - - Delete the specific version of the DatasetVersion. The service returns 204 No Content if the - DatasetVersion was deleted successfully or if the DatasetVersion does not exist. + def get(self, monitor_id: str, **kwargs: Any) -> _models.AgentInsightMonitor: + """Get an Agent Insights monitor. - :param name: The name of the resource. Required. - :type name: str - :param version: The version of the DatasetVersion to delete. Required. - :type version: str - :return: None - :rtype: None + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8213,11 +12040,10 @@ def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: dis _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) - _request = build_datasets_delete_request( - name=name, - version=version, + _request = build_beta_agent_insight_monitors_get_request( + monitor_id=monitor_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -8227,121 +12053,45 @@ def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: dis } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if cls: - return cls(pipeline_response, None, {}) # type: ignore - - @overload - def create_or_update( - self, - name: str, - version: str, - dataset_version: _models.DatasetVersion, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. - - Create a new or update an existing DatasetVersion with the given version id. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Required. - :type dataset_version: ~azure.ai.projects.models.DatasetVersion - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create_or_update( - self, - name: str, - version: str, - dataset_version: JSON, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. - - Create a new or update an existing DatasetVersion with the given version id. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Required. - :type dataset_version: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - @overload - def create_or_update( - self, - name: str, - version: str, - dataset_version: IO[bytes], - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) - Create a new or update an existing DatasetVersion with the given version id. + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Required. - :type dataset_version: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ + return deserialized # type: ignore @distributed_trace - def create_or_update( - self, name: str, version: str, dataset_version: Union[_models.DatasetVersion, JSON, IO[bytes]], **kwargs: Any - ) -> _models.DatasetVersion: - """Create or update a version. - - Create a new or update an existing DatasetVersion with the given version id. + def delete(self, monitor_id: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete an Agent Insights monitor and all of its runs, insights, and state. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to create or update. Required. - :type version: str - :param dataset_version: The DatasetVersion to create or update. Is one of the following types: - DatasetVersion, JSON, IO[bytes] Required. - :type dataset_version: ~azure.ai.projects.models.DatasetVersion or JSON or IO[bytes] - :return: DatasetVersion. The DatasetVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetVersion + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8352,25 +12102,14 @@ def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DatasetVersion] = kwargs.pop("cls", None) - - content_type = content_type or "application/merge-patch+json" - _content = None - if isinstance(dataset_version, (IOBase, bytes)): - _content = dataset_version - else: - _content = json.dumps(dataset_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_datasets_create_or_update_request( - name=name, - version=version, - content_type=content_type, + _request = build_beta_agent_insight_monitors_delete_request( + monitor_id=monitor_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -8379,139 +12118,96 @@ def create_or_update( } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200, 201]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.DatasetVersion, response.json()) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + return cls(pipeline_response, None, {}) # type: ignore @overload - def pending_upload( + def update( self, - name: str, - version: str, - pending_upload_request: _models.PendingUploadRequest, + monitor_id: str, + monitor: _models.AgentInsightMonitorUpdate, *, - content_type: str = "application/json", + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified dataset version. + ) -> _models.AgentInsightMonitor: + """Update an Agent Insights monitor. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param monitor: The monitor fields to update. Required. + :type monitor: ~azure.ai.projects.models.AgentInsightMonitorUpdate :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def pending_upload( - self, - name: str, - version: str, - pending_upload_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified dataset version. + def update( + self, monitor_id: str, monitor: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Update an Agent Insights monitor. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: JSON + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param monitor: The monitor fields to update. Required. + :type monitor: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def pending_upload( - self, - name: str, - version: str, - pending_upload_request: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified dataset version. + def update( + self, monitor_id: str, monitor: IO[bytes], *, content_type: str = "application/merge-patch+json", **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Update an Agent Insights monitor. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: IO[bytes] + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param monitor: The monitor fields to update. Required. + :type monitor: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def pending_upload( - self, - name: str, - version: str, - pending_upload_request: Union[_models.PendingUploadRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified dataset version. + def update( + self, monitor_id: str, monitor: Union[_models.AgentInsightMonitorUpdate, JSON, IO[bytes]], **kwargs: Any + ) -> _models.AgentInsightMonitor: + """Update an Agent Insights monitor. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Is one of the following - types: PendingUploadRequest, JSON, IO[bytes] Required. - :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest or JSON or - IO[bytes] - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param monitor: The monitor fields to update. Is one of the following types: + AgentInsightMonitorUpdate, JSON, IO[bytes] Required. + :type monitor: ~azure.ai.projects.models.AgentInsightMonitorUpdate or JSON or IO[bytes] + :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightMonitor :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8526,18 +12222,17 @@ def pending_upload( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.PendingUploadResponse] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) - content_type = content_type or "application/json" + content_type = content_type or "application/merge-patch+json" _content = None - if isinstance(pending_upload_request, (IOBase, bytes)): - _content = pending_upload_request + if isinstance(monitor, (IOBase, bytes)): + _content = monitor else: - _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(monitor, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_datasets_pending_upload_request( - name=name, - version=version, + _request = build_beta_agent_insight_monitors_update_request( + monitor_id=monitor_id, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -8564,12 +12259,16 @@ def pending_upload( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.PendingUploadResponse, response.json()) + deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -8577,17 +12276,13 @@ def pending_upload( return deserialized # type: ignore @distributed_trace - def get_credentials(self, name: str, version: str, **kwargs: Any) -> _models.DatasetCredential: - """Get dataset credentials. - - Retrieves the SAS credential to access the storage account associated with a dataset version. + def reset(self, monitor_id: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Reset an Agent Insights monitor's overview, checkpoint, and active insight state. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the DatasetVersion to operate on. Required. - :type version: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -8601,11 +12296,10 @@ def get_credentials(self, name: str, version: str, **kwargs: Any) -> _models.Dat _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_datasets_get_credentials_request( - name=name, - version=version, + _request = build_beta_agent_insight_monitors_reset_request( + monitor_id=monitor_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -8615,63 +12309,32 @@ def get_credentials(self, name: str, version: str, **kwargs: Any) -> _models.Dat } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.DatasetCredential, response.json()) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - -class DeploymentsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`deployments` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - - @distributed_trace - def get(self, name: str, **kwargs: Any) -> _models.Deployment: - """Get a deployment. + response = pipeline_response.http_response - Retrieves a deployed model. + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - :param name: Name of the deployment. Required. - :type name: str - :return: Deployment. The Deployment is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Deployment - :raises ~azure.core.exceptions.HttpResponseError: - """ + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + def _create_run_initial( + self, + monitor_id: str, + run: Union[_models.AgentInsightRunCreate, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> Iterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -8680,14 +12343,25 @@ def get(self, name: str, **kwargs: Any) -> _models.Deployment: } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Deployment] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_deployments_get_request( - name=name, + content_type = content_type or "application/json" + _content = None + if isinstance(run, (IOBase, bytes)): + _content = run + else: + _content = json.dumps(run, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_agent_insight_monitors_create_run_request( + monitor_id=monitor_id, + operation_id=operation_id, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -8697,271 +12371,243 @@ def get(self, name: str, **kwargs: Any) -> _models.Deployment: _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = True pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [201]: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["x-ms-client-request-id"] = self._deserialize( - "str", response.headers.get("x-ms-client-request-id") - ) + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Deployment, response.json()) + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace - def list( + @overload + def begin_create_run( self, + monitor_id: str, + run: _models.AgentInsightRunCreate, *, - model_publisher: Optional[str] = None, - model_name: Optional[str] = None, - deployment_type: Optional[Union[str, _models.DeploymentType]] = None, + operation_id: Optional[str] = None, + content_type: str = "application/json", **kwargs: Any - ) -> ItemPaged["_models.Deployment"]: - """List deployments. - - Returns the deployed models available in the current project, optionally filtered by publisher, - model name, or deployment type. + ) -> LROPoller[_models.AgentInsightRunResult]: + """Start an Agent Insights run for a monitor. - :keyword model_publisher: Model publisher to filter models by. Default value is None. - :paramtype model_publisher: str - :keyword model_name: Model name (the publisher specific name) to filter models by. Default - value is None. - :paramtype model_name: str - :keyword deployment_type: Type of deployment to filter list by. "ModelDeployment" Default value - is None. - :paramtype deployment_type: str or ~azure.ai.projects.models.DeploymentType - :return: An iterator like instance of Deployment - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Deployment] + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. + Required. + :type run: ~azure.ai.projects.models.AgentInsightRunCreate + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns AgentInsightRunResult. The AgentInsightRunResult + is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentInsightRunResult] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.Deployment]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_deployments_list_request( - model_publisher=model_publisher, - model_name=model_name, - deployment_type=deployment_type, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Deployment], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) - - def get_next(next_link=None): - _request = prepare_request(next_link) - - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - return pipeline_response - - return ItemPaged(get_next, extract_data) + @overload + def begin_create_run( + self, + monitor_id: str, + run: JSON, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.AgentInsightRunResult]: + """Start an Agent Insights run for a monitor. -class IndexesOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. + Required. + :type run: JSON + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns AgentInsightRunResult. The AgentInsightRunResult + is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentInsightRunResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`indexes` attribute. - """ + @overload + def begin_create_run( + self, + monitor_id: str, + run: IO[bytes], + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.AgentInsightRunResult]: + """Start an Agent Insights run for a monitor. - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. + Required. + :type run: IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns AgentInsightRunResult. The AgentInsightRunResult + is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentInsightRunResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.Index"]: - """List versions. - - List all versions of the given Index. + def begin_create_run( + self, + monitor_id: str, + run: Union[_models.AgentInsightRunCreate, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> LROPoller[_models.AgentInsightRunResult]: + """Start an Agent Insights run for a monitor. - :param name: The name of the resource. Required. - :type name: str - :return: An iterator like instance of Index - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Index] + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. Is + one of the following types: AgentInsightRunCreate, JSON, IO[bytes] Required. + :type run: ~azure.ai.projects.models.AgentInsightRunCreate or JSON or IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :return: An instance of LROPoller that returns AgentInsightRunResult. The AgentInsightRunResult + is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentInsightRunResult] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_indexes_list_versions_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Index], - deserialized.get("value", []), + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.AgentInsightRunResult] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._create_run_initial( + monitor_id=monitor_id, + run=run, + operation_id=operation_id, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) - - def get_next(next_link=None): - _request = prepare_request(next_link) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + def get_long_running_output(pipeline_response): + response_headers = {} response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + deserialized = _deserialize(_models.AgentInsightRunResult, response.json().get("result", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - return pipeline_response + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } - return ItemPaged(get_next, extract_data) + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) + else: + polling_method = polling + if cont_token: + return LROPoller[_models.AgentInsightRunResult].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.AgentInsightRunResult]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) @distributed_trace - def list(self, **kwargs: Any) -> ItemPaged["_models.Index"]: - """List latest versions. - - List the latest version of each Index. + def list_runs( + self, + monitor_id: str, + *, + before: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + status: Optional[Union[str, _models.JobStatus]] = None, + trigger: Optional[Union[str, _models.AgentInsightRunTrigger]] = None, + **kwargs: Any + ) -> ItemPaged["_models.AgentInsightRun"]: + """List Agent Insights runs for a monitor. - :return: An iterator like instance of Index - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Index] + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :keyword before: A cursor that identifies the first item in the next page. Default value is + None. + :paramtype before: str + :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" + and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword status: Filter runs by status. Known values are: "queued", "in_progress", "succeeded", + "failed", and "cancelled". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.JobStatus + :keyword trigger: Filter runs by trigger. Known values are: "on_demand" and "scheduled". + Default value is None. + :paramtype trigger: str or ~azure.ai.projects.models.AgentInsightRunTrigger + :return: An iterator like instance of AgentInsightRun + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentInsightRun] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.Index]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.AgentInsightRun]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -8971,58 +12617,38 @@ def list(self, **kwargs: Any) -> ItemPaged["_models.Index"]: } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_indexes_list_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + def prepare_request(_continuation_token=None): + _request = build_beta_agent_insight_monitors_list_runs_request( + monitor_id=monitor_id, + after=_continuation_token, + before=before, + limit=limit, + order=order, + status=status, + trigger=trigger, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.Index], - deserialized.get("value", []), + List[_models.AgentInsightRun], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + return deserialized.get("last_id") or None, iter(list_of_elem) - def get_next(next_link=None): - _request = prepare_request(next_link) + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -9032,25 +12658,26 @@ def get_next(next_link=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) return pipeline_response return ItemPaged(get_next, extract_data) @distributed_trace - def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: - """Get a version. - - Get the specific version of the Index. The service returns 404 Not Found error if the Index - does not exist. + def get_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models.AgentInsightRun: + """Get an Agent Insights run. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to retrieve. Required. - :type version: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run_id: The identifier of the run. Required. + :type run_id: str + :return: AgentInsightRun. The AgentInsightRun is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightRun :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9064,11 +12691,11 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Index] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentInsightRun] = kwargs.pop("cls", None) - _request = build_indexes_get_request( - name=name, - version=version, + _request = build_beta_agent_insight_monitors_get_run_request( + monitor_id=monitor_id, + run_id=run_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -9093,12 +12720,16 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Index, response.json()) + deserialized = _deserialize(_models.AgentInsightRun, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -9106,18 +12737,15 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.Index: return deserialized # type: ignore @distributed_trace - def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete a version. - - Delete the specific version of the Index. The service returns 204 No Content if the Index was - deleted successfully or if the Index does not exist. + def cancel_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models.AgentInsightRun: + """Cancel an Agent Insights run. - :param name: The name of the resource. Required. - :type name: str - :param version: The version of the Index to delete. Required. - :type version: str - :return: None - :rtype: None + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param run_id: The identifier of the run. Required. + :type run_id: str + :return: AgentInsightRun. The AgentInsightRun is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsightRun :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9131,11 +12759,11 @@ def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: dis _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.AgentInsightRun] = kwargs.pop("cls", None) - _request = build_indexes_delete_request( - name=name, - version=version, + _request = build_beta_agent_insight_monitors_cancel_run_request( + monitor_id=monitor_id, + run_id=run_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -9145,115 +12773,159 @@ def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: dis } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.AgentInsightRun, response.json()) if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore - @overload - def create_or_update( + return deserialized # type: ignore + + @distributed_trace + def list_insights( self, - name: str, - version: str, - index: _models.Index, + monitor_id: str, *, - content_type: str = "application/merge-patch+json", + before: Optional[str] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + category: Optional[str] = None, + severity: Optional[Union[str, _models.AgentInsightSeverity]] = None, + status: Optional[Union[str, _models.AgentInsightStatus]] = None, + include_details: Optional[bool] = None, **kwargs: Any - ) -> _models.Index: - """Create or update a version. - - Create a new or update an existing Index with the given version id. + ) -> ItemPaged["_models.AgentInsight"]: + """List current insights for an Agent Insights monitor. - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Required. - :type index: ~azure.ai.projects.models.Index - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :keyword before: A cursor that identifies the first item in the next page. Default value is + None. + :paramtype before: str + :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" + and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword category: Filter insights by category. Default value is None. + :paramtype category: str + :keyword severity: Filter insights by severity. Known values are: "high", "medium", and "low". + Default value is None. + :paramtype severity: str or ~azure.ai.projects.models.AgentInsightSeverity + :keyword status: Filter insights by lifecycle status. Known values are: "active", "resolved", + and "ignored". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.AgentInsightStatus + :keyword include_details: Whether to include expanded insight details such as evidence and run + links in the response. Defaults to false. Default value is None. + :paramtype include_details: bool + :return: An iterator like instance of AgentInsight + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentInsight] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @overload - def create_or_update( - self, name: str, version: str, index: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.Index: - """Create or update a version. + cls: ClsType[List[_models.AgentInsight]] = kwargs.pop("cls", None) - Create a new or update an existing Index with the given version id. + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Required. - :type index: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index - :raises ~azure.core.exceptions.HttpResponseError: - """ + def prepare_request(_continuation_token=None): - @overload - def create_or_update( - self, - name: str, - version: str, - index: IO[bytes], - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.Index: - """Create or update a version. + _request = build_beta_agent_insight_monitors_list_insights_request( + monitor_id=monitor_id, + after=_continuation_token, + before=before, + limit=limit, + order=order, + category=category, + severity=severity, + status=status, + include_details=include_details, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - Create a new or update an existing Index with the given version id. + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.AgentInsight], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Required. - :type index: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index - :raises ~azure.core.exceptions.HttpResponseError: - """ + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - @distributed_trace - def create_or_update( - self, name: str, version: str, index: Union[_models.Index, JSON, IO[bytes]], **kwargs: Any - ) -> _models.Index: - """Create or update a version. + return pipeline_response - Create a new or update an existing Index with the given version id. + return ItemPaged(get_next, extract_data) - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the Index to create or update. Required. - :type version: str - :param index: The Index to create or update. Is one of the following types: Index, JSON, - IO[bytes] Required. - :type index: ~azure.ai.projects.models.Index or JSON or IO[bytes] - :return: Index. The Index is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Index + @distributed_trace + def get_insight( + self, monitor_id: str, insight_id: str, *, include_details: Optional[bool] = None, **kwargs: Any + ) -> _models.AgentInsight: + """Get a full insight for an Agent Insights monitor. + + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param insight_id: The identifier of the insight. Required. + :type insight_id: str + :keyword include_details: Whether to include expanded insight details such as evidence and run + links in the response. Defaults to false. Default value is None. + :paramtype include_details: bool + :return: AgentInsight. The AgentInsight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsight :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9264,25 +12936,16 @@ def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Index] = kwargs.pop("cls", None) - - content_type = content_type or "application/merge-patch+json" - _content = None - if isinstance(index, (IOBase, bytes)): - _content = index - else: - _content = json.dumps(index, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.AgentInsight] = kwargs.pop("cls", None) - _request = build_indexes_create_or_update_request( - name=name, - version=version, - content_type=content_type, + _request = build_beta_agent_insight_monitors_get_insight_request( + monitor_id=monitor_id, + insight_id=insight_id, + include_details=include_details, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -9299,163 +12962,126 @@ def create_or_update( response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Index, response.json()) + deserialized = _deserialize(_models.AgentInsight, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - -class ToolboxesOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`toolboxes` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @overload - def create_version( + def update_insight( self, - name: str, + monitor_id: str, + insight_id: str, + update: _models.AgentInsightUpdate, *, - tools: List[_models.ToolboxTool], - content_type: str = "application/json", - description: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, - skills: Optional[List[_models.ToolboxSkill]] = None, - policies: Optional[_models.ToolboxPolicies] = None, + content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.ToolboxVersionObject: - """Create a new version of a toolbox. - - Creates a new toolbox version, provisioning the toolbox itself if it does not already exist. + ) -> _models.AgentInsight: + """Update the lifecycle status of an insight. - :param name: The name of the toolbox. If the toolbox does not exist, it will be created. - Required. - :type name: str - :keyword tools: The list of tools to include in this version. Required. - :paramtype tools: list[~azure.ai.projects.models.ToolboxTool] + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param insight_id: The identifier of the insight. Required. + :type insight_id: str + :param update: The insight fields to update. Required. + :type update: ~azure.ai.projects.models.AgentInsightUpdate :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :keyword description: A human-readable description of the toolbox. Default value is None. - :paramtype description: str - :keyword metadata: Arbitrary key-value metadata to associate with the toolbox. Default value is - None. - :paramtype metadata: dict[str, str] - :keyword skills: The list of skill sources to include in this version. A skill reference - specifies a skill name and optionally a version. If version is omitted, the skill's default - version is used. Default value is None. - :paramtype skills: list[~azure.ai.projects.models.ToolboxSkill] - :keyword policies: Policy configuration for this toolbox version. Default value is None. - :paramtype policies: ~azure.ai.projects.models.ToolboxPolicies - :return: ToolboxVersionObject. The ToolboxVersionObject is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ToolboxVersionObject + :return: AgentInsight. The AgentInsight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsight :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create_version( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.ToolboxVersionObject: - """Create a new version of a toolbox. - - Creates a new toolbox version, provisioning the toolbox itself if it does not already exist. + def update_insight( + self, + monitor_id: str, + insight_id: str, + update: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.AgentInsight: + """Update the lifecycle status of an insight. - :param name: The name of the toolbox. If the toolbox does not exist, it will be created. - Required. - :type name: str - :param body: Required. - :type body: JSON + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param insight_id: The identifier of the insight. Required. + :type insight_id: str + :param update: The insight fields to update. Required. + :type update: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: ToolboxVersionObject. The ToolboxVersionObject is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ToolboxVersionObject + :return: AgentInsight. The AgentInsight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsight :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create_version( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.ToolboxVersionObject: - """Create a new version of a toolbox. - - Creates a new toolbox version, provisioning the toolbox itself if it does not already exist. + def update_insight( + self, + monitor_id: str, + insight_id: str, + update: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.AgentInsight: + """Update the lifecycle status of an insight. - :param name: The name of the toolbox. If the toolbox does not exist, it will be created. - Required. - :type name: str - :param body: Required. - :type body: IO[bytes] + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param insight_id: The identifier of the insight. Required. + :type insight_id: str + :param update: The insight fields to update. Required. + :type update: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: ToolboxVersionObject. The ToolboxVersionObject is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ToolboxVersionObject + :return: AgentInsight. The AgentInsight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsight :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def create_version( + def update_insight( self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - tools: List[_models.ToolboxTool] = _Unset, - description: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, - skills: Optional[List[_models.ToolboxSkill]] = None, - policies: Optional[_models.ToolboxPolicies] = None, + monitor_id: str, + insight_id: str, + update: Union[_models.AgentInsightUpdate, JSON, IO[bytes]], **kwargs: Any - ) -> _models.ToolboxVersionObject: - """Create a new version of a toolbox. - - Creates a new toolbox version, provisioning the toolbox itself if it does not already exist. + ) -> _models.AgentInsight: + """Update the lifecycle status of an insight. - :param name: The name of the toolbox. If the toolbox does not exist, it will be created. - Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword tools: The list of tools to include in this version. Required. - :paramtype tools: list[~azure.ai.projects.models.ToolboxTool] - :keyword description: A human-readable description of the toolbox. Default value is None. - :paramtype description: str - :keyword metadata: Arbitrary key-value metadata to associate with the toolbox. Default value is - None. - :paramtype metadata: dict[str, str] - :keyword skills: The list of skill sources to include in this version. A skill reference - specifies a skill name and optionally a version. If version is omitted, the skill's default - version is used. Default value is None. - :paramtype skills: list[~azure.ai.projects.models.ToolboxSkill] - :keyword policies: Policy configuration for this toolbox version. Default value is None. - :paramtype policies: ~azure.ai.projects.models.ToolboxPolicies - :return: ToolboxVersionObject. The ToolboxVersionObject is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ToolboxVersionObject + :param monitor_id: The identifier of the monitor. Required. + :type monitor_id: str + :param insight_id: The identifier of the insight. Required. + :type insight_id: str + :param update: The insight fields to update. Is one of the following types: AgentInsightUpdate, + JSON, IO[bytes] Required. + :type update: ~azure.ai.projects.models.AgentInsightUpdate or JSON or IO[bytes] + :return: AgentInsight. The AgentInsight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.AgentInsight :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9470,28 +13096,18 @@ def create_version( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.ToolboxVersionObject] = kwargs.pop("cls", None) - - if body is _Unset: - if tools is _Unset: - raise TypeError("missing required argument: tools") - body = { - "description": description, - "metadata": metadata, - "policies": policies, - "skills": skills, - "tools": tools, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" + cls: ClsType[_models.AgentInsight] = kwargs.pop("cls", None) + + content_type = content_type or "application/merge-patch+json" _content = None - if isinstance(body, (IOBase, bytes)): - _content = body + if isinstance(update, (IOBase, bytes)): + _content = update else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(update, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_toolboxes_create_version_request( - name=name, + _request = build_beta_agent_insight_monitors_update_insight_request( + monitor_id=monitor_id, + insight_id=insight_id, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -9527,23 +13143,41 @@ def create_version( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.ToolboxVersionObject, response.json()) + deserialized = _deserialize(_models.AgentInsight, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + +class BetaEvaluationTaxonomiesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`evaluation_taxonomies` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @distributed_trace - def get(self, name: str, **kwargs: Any) -> _models.ToolboxObject: - """Retrieve a toolbox. + def get(self, name: str, **kwargs: Any) -> _models.EvaluationTaxonomy: + """Get an evaluation taxonomy. - Retrieves the specified toolbox and its current configuration. + Retrieves the specified evaluation taxonomy. - :param name: The name of the toolbox to retrieve. Required. + :param name: The name of the resource. Required. :type name: str - :return: ToolboxObject. The ToolboxObject is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ToolboxObject + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9557,9 +13191,9 @@ def get(self, name: str, **kwargs: Any) -> _models.ToolboxObject: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.ToolboxObject] = kwargs.pop("cls", None) + cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) - _request = build_toolboxes_get_request( + _request = build_beta_evaluation_taxonomies_get_request( name=name, api_version=self._config.api_version, headers=_headers, @@ -9585,16 +13219,12 @@ def get(self, name: str, **kwargs: Any) -> _models.ToolboxObject: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.ToolboxObject, response.json()) + deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -9603,39 +13233,25 @@ def get(self, name: str, **kwargs: Any) -> _models.ToolboxObject: @distributed_trace def list( - self, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> ItemPaged["_models.ToolboxObject"]: - """List toolboxes. + self, *, input_name: Optional[str] = None, input_type: Optional[str] = None, **kwargs: Any + ) -> ItemPaged["_models.EvaluationTaxonomy"]: + """List evaluation taxonomies. - Returns the toolboxes available in the current project. + Returns the evaluation taxonomies available in the project, optionally filtered by input name + or input type. - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of ToolboxObject - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.ToolboxObject] + :keyword input_name: Filter by the evaluation input name. Default value is None. + :paramtype input_name: str + :keyword input_type: Filter by taxonomy input type. Default value is None. + :paramtype input_type: str + :return: An iterator like instance of EvaluationTaxonomy + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluationTaxonomy] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.ToolboxObject]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.EvaluationTaxonomy]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -9645,131 +13261,60 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): - - _request = build_toolboxes_list_request( - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request - - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.ToolboxObject], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) - - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) - - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + def prepare_request(next_link=None): + if not next_link: - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, + _request = build_beta_evaluation_taxonomies_list_request( + input_name=input_name, + input_type=input_type, + api_version=self._config.api_version, + headers=_headers, + params=_params, ) - raise HttpResponseError(response=response, model=error) - - return pipeline_response - - return ItemPaged(get_next, extract_data) - - @distributed_trace - def list_versions( - self, - name: str, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> ItemPaged["_models.ToolboxVersionObject"]: - """List toolbox versions. - - Returns the available versions for the specified toolbox. - - :param name: The name of the toolbox to list versions for. Required. - :type name: str - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of ToolboxVersionObject - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.ToolboxVersionObject] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.ToolboxVersionObject]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - def prepare_request(_continuation_token=None): + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _request = build_toolboxes_list_versions_request( - name=name, - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.ToolboxVersionObject], - deserialized.get("data", []), + List[_models.EvaluationTaxonomy], + deserialized.get("value", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + return deserialized.get("nextLink") or None, iter(list_of_elem) - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + def get_next(next_link=None): + _request = prepare_request(next_link) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -9777,30 +13322,24 @@ def get_next(_continuation_token=None): ) response = pipeline_response.http_response - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) return pipeline_response return ItemPaged(get_next, extract_data) @distributed_trace - def get_version(self, name: str, version: str, **kwargs: Any) -> _models.ToolboxVersionObject: - """Retrieve a specific version of a toolbox. + def delete(self, name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete an evaluation taxonomy. - Retrieves the specified version of a toolbox by name and version identifier. + Removes the specified evaluation taxonomy from the project. - :param name: The name of the toolbox. Required. + :param name: The name of the resource. Required. :type name: str - :param version: The version identifier to retrieve. Required. - :type version: str - :return: ToolboxVersionObject. The ToolboxVersionObject is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ToolboxVersionObject + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9814,11 +13353,10 @@ def get_version(self, name: str, version: str, **kwargs: Any) -> _models.Toolbox _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.ToolboxVersionObject] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_toolboxes_get_version_request( + _request = build_beta_evaluation_taxonomies_delete_request( name=name, - version=version, api_version=self._config.api_version, headers=_headers, params=_params, @@ -9828,115 +13366,95 @@ def get_version(self, name: str, version: str, **kwargs: Any) -> _models.Toolbox } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.ToolboxVersionObject, response.json()) + raise HttpResponseError(response=response) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + return cls(pipeline_response, None, {}) # type: ignore @overload - def update( - self, name: str, *, default_version: str, content_type: str = "application/json", **kwargs: Any - ) -> _models.ToolboxObject: - """Update a toolbox to point to a specific version. + def create( + self, name: str, taxonomy: _models.EvaluationTaxonomy, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Create an evaluation taxonomy. - Updates the toolbox's default version pointer to the specified version. + Creates or replaces the specified evaluation taxonomy with the provided definition. - :param name: The name of the toolbox to update. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :keyword default_version: The version identifier that the toolbox should point to. When set, - the toolbox's default version will resolve to this version instead of the latest. Required. - :paramtype default_version: str + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: ToolboxObject. The ToolboxObject is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ToolboxObject + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.ToolboxObject: - """Update a toolbox to point to a specific version. + def create( + self, name: str, taxonomy: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Create an evaluation taxonomy. - Updates the toolbox's default version pointer to the specified version. + Creates or replaces the specified evaluation taxonomy with the provided definition. - :param name: The name of the toolbox to update. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param body: Required. - :type body: JSON + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: ToolboxObject. The ToolboxObject is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ToolboxObject + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.ToolboxObject: - """Update a toolbox to point to a specific version. + def create( + self, name: str, taxonomy: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Create an evaluation taxonomy. - Updates the toolbox's default version pointer to the specified version. + Creates or replaces the specified evaluation taxonomy with the provided definition. - :param name: The name of the toolbox to update. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param body: Required. - :type body: IO[bytes] + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: ToolboxObject. The ToolboxObject is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ToolboxObject + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def update( - self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, default_version: str = _Unset, **kwargs: Any - ) -> _models.ToolboxObject: - """Update a toolbox to point to a specific version. + def create( + self, name: str, taxonomy: Union[_models.EvaluationTaxonomy, JSON, IO[bytes]], **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Create an evaluation taxonomy. - Updates the toolbox's default version pointer to the specified version. + Creates or replaces the specified evaluation taxonomy with the provided definition. - :param name: The name of the toolbox to update. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword default_version: The version identifier that the toolbox should point to. When set, - the toolbox's default version will resolve to this version instead of the latest. Required. - :paramtype default_version: str - :return: ToolboxObject. The ToolboxObject is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ToolboxObject + :param taxonomy: The evaluation taxonomy. Is one of the following types: EvaluationTaxonomy, + JSON, IO[bytes] Required. + :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy or JSON or IO[bytes] + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -9951,21 +13469,16 @@ def update( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.ToolboxObject] = kwargs.pop("cls", None) + cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) - if body is _Unset: - if default_version is _Unset: - raise TypeError("missing required argument: default_version") - body = {"default_version": default_version} - body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(body, (IOBase, bytes)): - _content = body + if isinstance(taxonomy, (IOBase, bytes)): + _content = taxonomy else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(taxonomy, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_toolboxes_update_request( + _request = build_beta_evaluation_taxonomies_create_request( name=name, content_type=content_type, api_version=self._config.api_version, @@ -9986,97 +13499,100 @@ def update( response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [200, 201]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.ToolboxObject, response.json()) + deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def delete(self, name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete a toolbox. + @overload + def update( + self, name: str, taxonomy: _models.EvaluationTaxonomy, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Update an evaluation taxonomy. - Removes the specified toolbox along with all of its versions. + Modifies the specified evaluation taxonomy with the provided changes. - :param name: The name of the toolbox to delete. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :return: None - :rtype: None + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + @overload + def update( + self, name: str, taxonomy: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Update an evaluation taxonomy. - _request = build_toolboxes_delete_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + Modifies the specified evaluation taxonomy with the provided changes. - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + :param name: The name of the evaluation taxonomy. Required. + :type name: str + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :raises ~azure.core.exceptions.HttpResponseError: + """ - response = pipeline_response.http_response + @overload + def update( + self, name: str, taxonomy: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Update an evaluation taxonomy. - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + Modifies the specified evaluation taxonomy with the provided changes. - if cls: - return cls(pipeline_response, None, {}) # type: ignore + :param name: The name of the evaluation taxonomy. Required. + :type name: str + :param taxonomy: The evaluation taxonomy. Required. + :type taxonomy: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def delete_version( # pylint: disable=inconsistent-return-statements - self, name: str, version: str, **kwargs: Any - ) -> None: - """Delete a specific version of a toolbox. + def update( + self, name: str, taxonomy: Union[_models.EvaluationTaxonomy, JSON, IO[bytes]], **kwargs: Any + ) -> _models.EvaluationTaxonomy: + """Update an evaluation taxonomy. - Removes the specified version of a toolbox. + Modifies the specified evaluation taxonomy with the provided changes. - :param name: The name of the toolbox. Required. + :param name: The name of the evaluation taxonomy. Required. :type name: str - :param version: The version identifier to delete. Required. - :type version: str - :return: None - :rtype: None + :param taxonomy: The evaluation taxonomy. Is one of the following types: EvaluationTaxonomy, + JSON, IO[bytes] Required. + :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy or JSON or IO[bytes] + :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluationTaxonomy :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -10087,15 +13603,24 @@ def delete_version( # pylint: disable=inconsistent-return-statements } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) - _request = build_toolboxes_delete_version_request( + content_type = content_type or "application/json" + _content = None + if isinstance(taxonomy, (IOBase, bytes)): + _content = taxonomy + else: + _content = json.dumps(taxonomy, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_evaluation_taxonomies_update_request( name=name, - version=version, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -10104,33 +13629,42 @@ def delete_version( # pylint: disable=inconsistent-return-statements } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore + return deserialized # type: ignore -class BetaAgentInsightMonitorsOperations: # pylint: disable=docstring-missing-param + +class BetaEvaluatorsOperations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. Instead, you should access the following operations through :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`agent_insight_monitors` attribute. + :attr:`evaluators` attribute. """ def __init__(self, *args, **kwargs) -> None: @@ -10141,35 +13675,35 @@ def __init__(self, *args, **kwargs) -> None: self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") @distributed_trace - def list( + def list_versions( self, + name: str, *, - before: Optional[str] = None, + type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - agent_name: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.AgentInsightMonitorListItem"]: - """List Agent Insights monitors, optionally filtered by agent name. + ) -> ItemPaged["_models.EvaluatorVersion"]: + """List evaluator versions. - :keyword before: A cursor that identifies the first item in the next page. Default value is - None. - :paramtype before: str - :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. + Returns the available versions for the specified evaluator. + + :param name: The name of the resource. Required. + :type name: str + :keyword type: Filter evaluators by type. Possible values: 'all', 'custom', 'builtin'. Is one + of the following types: Literal["builtin"], Literal["custom"], Literal["all"], str Default + value is None. + :paramtype type: str or str or str or str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. Default value is None. :paramtype limit: int - :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" - and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword agent_name: Filter monitors by agent name. Default value is None. - :paramtype agent_name: str - :return: An iterator like instance of AgentInsightMonitorListItem - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentInsightMonitorListItem] + :return: An iterator like instance of EvaluatorVersion + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluatorVersion] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.AgentInsightMonitorListItem]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.EvaluatorVersion]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -10179,36 +13713,61 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_evaluators_list_versions_request( + name=name, + type=type, + limit=limit, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _request = build_beta_agent_insight_monitors_list_request( - after=_continuation_token, - before=before, - limit=limit, - order=order, - agent_name=agent_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.AgentInsightMonitorListItem], - deserialized.get("data", []), + List[_models.EvaluatorVersion], + deserialized.get("value", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + return deserialized.get("nextLink") or None, iter(list_of_elem) - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + def get_next(next_link=None): + _request = prepare_request(next_link) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -10218,75 +13777,129 @@ def get_next(_continuation_token=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) return pipeline_response return ItemPaged(get_next, extract_data) - @overload - def create( - self, monitor: _models.AgentInsightMonitorCreate, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Create an Agent Insights monitor for an agent. + @distributed_trace + def list( + self, + *, + type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, + limit: Optional[int] = None, + **kwargs: Any + ) -> ItemPaged["_models.EvaluatorVersion"]: + """List latest evaluator versions. + + Lists the latest version of each evaluator. + + :keyword type: Filter evaluators by type. Possible values: 'all', 'custom', 'builtin'. Is one + of the following types: Literal["builtin"], Literal["custom"], Literal["all"], str Default + value is None. + :paramtype type: str or str or str or str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. Default value is None. + :paramtype limit: int + :return: An iterator like instance of EvaluatorVersion + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluatorVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.EvaluatorVersion]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_evaluators_list_request( + type=type, + limit=limit, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.EvaluatorVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) - :param monitor: The monitor to create. Required. - :type monitor: ~azure.ai.projects.models.AgentInsightMonitorCreate - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor - :raises ~azure.core.exceptions.HttpResponseError: - """ + def get_next(next_link=None): + _request = prepare_request(next_link) - @overload - def create( - self, monitor: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Create an Agent Insights monitor for an agent. + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response - :param monitor: The monitor to create. Required. - :type monitor: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor - :raises ~azure.core.exceptions.HttpResponseError: - """ + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) - @overload - def create( - self, monitor: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Create an Agent Insights monitor for an agent. + return pipeline_response - :param monitor: The monitor to create. Required. - :type monitor: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor - :raises ~azure.core.exceptions.HttpResponseError: - """ + return ItemPaged(get_next, extract_data) @distributed_trace - def create( - self, monitor: Union[_models.AgentInsightMonitorCreate, JSON, IO[bytes]], **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Create an Agent Insights monitor for an agent. + def get_version(self, name: str, version: str, **kwargs: Any) -> _models.EvaluatorVersion: + """Get an evaluator version. - :param monitor: The monitor to create. Is one of the following types: - AgentInsightMonitorCreate, JSON, IO[bytes] Required. - :type monitor: ~azure.ai.projects.models.AgentInsightMonitorCreate or JSON or IO[bytes] - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor + Retrieves the specified evaluator version, returning 404 if it does not exist. + + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to retrieve. Required. + :type version: str + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -10297,23 +13910,15 @@ def create( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(monitor, (IOBase, bytes)): - _content = monitor - else: - _content = json.dumps(monitor, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_create_request( - content_type=content_type, + _request = build_beta_evaluators_get_version_request( + name=name, + version=version, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -10330,40 +13935,39 @@ def create( response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - response_headers = {} - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) + deserialized = _deserialize(_models.EvaluatorVersion, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @distributed_trace - def get(self, monitor_id: str, **kwargs: Any) -> _models.AgentInsightMonitor: - """Get an Agent Insights monitor. + def delete_version( # pylint: disable=inconsistent-return-statements + self, name: str, version: str, **kwargs: Any + ) -> None: + """Delete an evaluator version. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor + Removes the specified evaluator version. Returns 204 whether the version existed or not. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the EvaluatorVersion to delete. Required. + :type version: str + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -10377,10 +13981,11 @@ def get(self, monitor_id: str, **kwargs: Any) -> _models.AgentInsightMonitor: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_get_request( - monitor_id=monitor_id, + _request = build_beta_evaluators_delete_version_request( + name=name, + version=version, api_version=self._config.api_version, headers=_headers, params=_params, @@ -10390,45 +13995,100 @@ def get(self, monitor_id: str, **kwargs: Any) -> _models.AgentInsightMonitor: } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) + raise HttpResponseError(response=response) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, None, {}) # type: ignore - return deserialized # type: ignore + @overload + def create_version( + self, + name: str, + evaluator_version: _models.EvaluatorVersion, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.EvaluatorVersion: + """Create an evaluator version. + + Creates a new evaluator version with an auto-incremented version identifier. + + :param name: The name of the resource. Required. + :type name: str + :param evaluator_version: Required. + :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_version( + self, name: str, evaluator_version: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluatorVersion: + """Create an evaluator version. + + Creates a new evaluator version with an auto-incremented version identifier. + + :param name: The name of the resource. Required. + :type name: str + :param evaluator_version: Required. + :type evaluator_version: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_version( + self, name: str, evaluator_version: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluatorVersion: + """Create an evaluator version. + + Creates a new evaluator version with an auto-incremented version identifier. + + :param name: The name of the resource. Required. + :type name: str + :param evaluator_version: Required. + :type evaluator_version: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def delete(self, monitor_id: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete an Agent Insights monitor and all of its runs, insights, and state. + def create_version( + self, name: str, evaluator_version: Union[_models.EvaluatorVersion, JSON, IO[bytes]], **kwargs: Any + ) -> _models.EvaluatorVersion: + """Create an evaluator version. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :return: None - :rtype: None + Creates a new evaluator version with an auto-incremented version identifier. + + :param name: The name of the resource. Required. + :type name: str + :param evaluator_version: Is one of the following types: EvaluatorVersion, JSON, IO[bytes] + Required. + :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion or JSON or IO[bytes] + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -10439,14 +14099,24 @@ def delete(self, monitor_id: str, **kwargs: Any) -> None: # pylint: disable=inc } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_delete_request( - monitor_id=monitor_id, + content_type = content_type or "application/json" + _content = None + if isinstance(evaluator_version, (IOBase, bytes)): + _content = evaluator_version + else: + _content = json.dumps(evaluator_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_evaluators_create_version_request( + name=name, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -10455,96 +14125,132 @@ def delete(self, monitor_id: str, **kwargs: Any) -> None: # pylint: disable=inc } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.EvaluatorVersion, response.json()) if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @overload - def update( + def update_version( self, - monitor_id: str, - monitor: _models.AgentInsightMonitorUpdate, + name: str, + version: str, + evaluator_version: _models.EvaluatorVersion, *, - content_type: str = "application/merge-patch+json", + content_type: str = "application/json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Update an Agent Insights monitor. + ) -> _models.EvaluatorVersion: + """Update an evaluator version. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param monitor: The monitor fields to update. Required. - :type monitor: ~azure.ai.projects.models.AgentInsightMonitorUpdate + Updates the specified evaluator version in place. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the EvaluatorVersion to update. Required. + :type version: str + :param evaluator_version: Evaluator resource. Required. + :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update( - self, monitor_id: str, monitor: JSON, *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Update an Agent Insights monitor. + def update_version( + self, name: str, version: str, evaluator_version: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.EvaluatorVersion: + """Update an evaluator version. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param monitor: The monitor fields to update. Required. - :type monitor: JSON + Updates the specified evaluator version in place. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the EvaluatorVersion to update. Required. + :type version: str + :param evaluator_version: Evaluator resource. Required. + :type evaluator_version: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update( - self, monitor_id: str, monitor: IO[bytes], *, content_type: str = "application/merge-patch+json", **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Update an Agent Insights monitor. + def update_version( + self, + name: str, + version: str, + evaluator_version: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.EvaluatorVersion: + """Update an evaluator version. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param monitor: The monitor fields to update. Required. - :type monitor: IO[bytes] + Updates the specified evaluator version in place. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the EvaluatorVersion to update. Required. + :type version: str + :param evaluator_version: Evaluator resource. Required. + :type evaluator_version: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def update( - self, monitor_id: str, monitor: Union[_models.AgentInsightMonitorUpdate, JSON, IO[bytes]], **kwargs: Any - ) -> _models.AgentInsightMonitor: - """Update an Agent Insights monitor. + def update_version( + self, + name: str, + version: str, + evaluator_version: Union[_models.EvaluatorVersion, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.EvaluatorVersion: + """Update an evaluator version. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param monitor: The monitor fields to update. Is one of the following types: - AgentInsightMonitorUpdate, JSON, IO[bytes] Required. - :type monitor: ~azure.ai.projects.models.AgentInsightMonitorUpdate or JSON or IO[bytes] - :return: AgentInsightMonitor. The AgentInsightMonitor is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightMonitor + Updates the specified evaluator version in place. + + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the EvaluatorVersion to update. Required. + :type version: str + :param evaluator_version: Evaluator resource. Is one of the following types: EvaluatorVersion, + JSON, IO[bytes] Required. + :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion or JSON or IO[bytes] + :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -10559,17 +14265,18 @@ def update( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentInsightMonitor] = kwargs.pop("cls", None) + cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) - content_type = content_type or "application/merge-patch+json" + content_type = content_type or "application/json" _content = None - if isinstance(monitor, (IOBase, bytes)): - _content = monitor + if isinstance(evaluator_version, (IOBase, bytes)): + _content = evaluator_version else: - _content = json.dumps(monitor, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(evaluator_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_agent_insight_monitors_update_request( - monitor_id=monitor_id, + _request = build_beta_evaluators_update_version_request( + name=name, + version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -10596,82 +14303,130 @@ def update( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentInsightMonitor, response.json()) + deserialized = _deserialize(_models.EvaluatorVersion, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def reset(self, monitor_id: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Reset an Agent Insights monitor's overview, checkpoint, and active insight state. + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: _models.PendingUploadRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :return: None - :rtype: None + Initiates a new pending upload or retrieves an existing one for the specified evaluator + version. + + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. - _request = build_beta_agent_insight_monitors_reset_request( - monitor_id=monitor_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + Initiates a new pending upload or retrieves an existing one for the specified evaluator + version. - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ - response = pipeline_response.http_response + @overload + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.PendingUploadResponse: + """Start a pending upload. - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + Initiates a new pending upload or retrieves an existing one for the specified evaluator + version. - if cls: - return cls(pipeline_response, None, {}) # type: ignore + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Required. + :type pending_upload_request: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ - def _create_run_initial( + @distributed_trace + def pending_upload( self, - monitor_id: str, - run: Union[_models.AgentInsightRunCreate, JSON, IO[bytes]], - *, - operation_id: Optional[str] = None, + name: str, + version: str, + pending_upload_request: Union[_models.PendingUploadRequest, JSON, IO[bytes]], **kwargs: Any - ) -> Iterator[bytes]: + ) -> _models.PendingUploadResponse: + """Start a pending upload. + + Initiates a new pending upload or retrieves an existing one for the specified evaluator + version. + + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param pending_upload_request: The pending upload request parameters. Is one of the following + types: PendingUploadRequest, JSON, IO[bytes] Required. + :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest or JSON or + IO[bytes] + :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.PendingUploadResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -10684,18 +14439,18 @@ def _create_run_initial( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + cls: ClsType[_models.PendingUploadResponse] = kwargs.pop("cls", None) content_type = content_type or "application/json" _content = None - if isinstance(run, (IOBase, bytes)): - _content = run + if isinstance(pending_upload_request, (IOBase, bytes)): + _content = pending_upload_request else: - _content = json.dumps(run, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_agent_insight_monitors_create_run_request( - monitor_id=monitor_id, - operation_id=operation_id, + _request = build_beta_evaluators_pending_upload_request( + name=name, + version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -10708,18 +14463,19 @@ def _create_run_initial( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -10727,225 +14483,201 @@ def _create_run_initial( ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.PendingUploadResponse, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @overload - def begin_create_run( + def get_credentials( self, - monitor_id: str, - run: _models.AgentInsightRunCreate, + name: str, + version: str, + credential_request: _models.EvaluatorCredentialRequest, *, - operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.AgentInsightRunResult]: - """Start an Agent Insights run for a monitor. + ) -> _models.DatasetCredential: + """Get evaluator credentials. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. - Required. - :type run: ~azure.ai.projects.models.AgentInsightRunCreate - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + Retrieves SAS credentials for accessing the storage account associated with the specified + evaluator version. + + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param credential_request: The credential request parameters. Required. + :type credential_request: ~azure.ai.projects.models.EvaluatorCredentialRequest :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns AgentInsightRunResult. The AgentInsightRunResult - is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentInsightRunResult] + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_create_run( + def get_credentials( self, - monitor_id: str, - run: JSON, + name: str, + version: str, + credential_request: JSON, *, - operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.AgentInsightRunResult]: - """Start an Agent Insights run for a monitor. + ) -> _models.DatasetCredential: + """Get evaluator credentials. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. - Required. - :type run: JSON - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + Retrieves SAS credentials for accessing the storage account associated with the specified + evaluator version. + + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param credential_request: The credential request parameters. Required. + :type credential_request: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns AgentInsightRunResult. The AgentInsightRunResult - is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentInsightRunResult] + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_create_run( + def get_credentials( self, - monitor_id: str, - run: IO[bytes], + name: str, + version: str, + credential_request: IO[bytes], *, - operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.AgentInsightRunResult]: - """Start an Agent Insights run for a monitor. + ) -> _models.DatasetCredential: + """Get evaluator credentials. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. - Required. - :type run: IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + Retrieves SAS credentials for accessing the storage account associated with the specified + evaluator version. + + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param credential_request: The credential request parameters. Required. + :type credential_request: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns AgentInsightRunResult. The AgentInsightRunResult - is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentInsightRunResult] + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def begin_create_run( + def get_credentials( self, - monitor_id: str, - run: Union[_models.AgentInsightRunCreate, JSON, IO[bytes]], - *, - operation_id: Optional[str] = None, + name: str, + version: str, + credential_request: Union[_models.EvaluatorCredentialRequest, JSON, IO[bytes]], **kwargs: Any - ) -> LROPoller[_models.AgentInsightRunResult]: - """Start an Agent Insights run for a monitor. + ) -> _models.DatasetCredential: + """Get evaluator credentials. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param run: Run inputs. Send an empty object to use the default 168-hour lookback window. Is - one of the following types: AgentInsightRunCreate, JSON, IO[bytes] Required. - :type run: ~azure.ai.projects.models.AgentInsightRunCreate or JSON or IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :return: An instance of LROPoller that returns AgentInsightRunResult. The AgentInsightRunResult - is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentInsightRunResult] + Retrieves SAS credentials for accessing the storage account associated with the specified + evaluator version. + + :param name: The name path parameter. Required. + :type name: str + :param version: The specific version id of the EvaluatorVersion to operate on. Required. + :type version: str + :param credential_request: The credential request parameters. Is one of the following types: + EvaluatorCredentialRequest, JSON, IO[bytes] Required. + :type credential_request: ~azure.ai.projects.models.EvaluatorCredentialRequest or JSON or + IO[bytes] + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentInsightRunResult] = kwargs.pop("cls", None) - polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = self._create_run_initial( - monitor_id=monitor_id, - run=run, - operation_id=operation_id, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - raw_result.http_response.read() # type: ignore - kwargs.pop("error_map", None) + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Operation-Location"] = self._deserialize( - "str", response.headers.get("Operation-Location") - ) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - deserialized = _deserialize(_models.AgentInsightRunResult, response.json().get("result", {})) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(credential_request, (IOBase, bytes)): + _content = credential_request + else: + _content = json.dumps(credential_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _request = build_beta_evaluators_get_credentials_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - if polling is True: - polling_method: PollingMethod = cast( - PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - elif polling is False: - polling_method = cast(PollingMethod, NoPolling()) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - polling_method = polling - if cont_token: - return LROPoller[_models.AgentInsightRunResult].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return LROPoller[_models.AgentInsightRunResult]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) + deserialized = _deserialize(_models.DatasetCredential, response.json()) - @distributed_trace - def list_runs( + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + def _create_generation_job_initial( self, - monitor_id: str, + job: Union[_models.EvaluatorGenerationJob, JSON, IO[bytes]], *, - before: Optional[str] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - status: Optional[Union[str, _models.JobStatus]] = None, - trigger: Optional[Union[str, _models.AgentInsightRunTrigger]] = None, + operation_id: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.AgentInsightRun"]: - """List Agent Insights runs for a monitor. - - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :keyword before: A cursor that identifies the first item in the next page. Default value is - None. - :paramtype before: str - :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" - and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword status: Filter runs by status. Known values are: "queued", "in_progress", "succeeded", - "failed", and "cancelled". Default value is None. - :paramtype status: str or ~azure.ai.projects.models.JobStatus - :keyword trigger: Filter runs by trigger. Known values are: "on_demand" and "scheduled". - Default value is None. - :paramtype trigger: str or ~azure.ai.projects.models.AgentInsightRunTrigger - :return: An iterator like instance of AgentInsightRun - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentInsightRun] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.AgentInsightRun]] = kwargs.pop("cls", None) - + ) -> Iterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -10954,135 +14686,233 @@ def list_runs( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - _request = build_beta_agent_insight_monitors_list_runs_request( - monitor_id=monitor_id, - after=_continuation_token, - before=before, - limit=limit, - order=order, - status=status, - trigger=trigger, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.AgentInsightRun], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + content_type = content_type or "application/json" + _content = None + if isinstance(job, (IOBase, bytes)): + _content = job + else: + _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + _request = build_beta_evaluators_create_generation_job_request( + operation_id=operation_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + _decompress = kwargs.pop("decompress", True) + _stream = True + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [201]: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response + raise HttpResponseError(response=response, model=error) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + def begin_create_generation_job( + self, + job: _models.EvaluatorGenerationJob, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.EvaluatorVersion]: + """Create an evaluator generation job. + + Creates an evaluator generation job. The service generates rubric-based evaluator definitions + from the provided source materials asynchronously. + + :param job: The job to create. Required. + :type job: ~azure.ai.projects.models.EvaluatorGenerationJob + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns EvaluatorVersion. The EvaluatorVersion is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.EvaluatorVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def begin_create_generation_job( + self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.EvaluatorVersion]: + """Create an evaluator generation job. + + Creates an evaluator generation job. The service generates rubric-based evaluator definitions + from the provided source materials asynchronously. + + :param job: The job to create. Required. + :type job: JSON + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns EvaluatorVersion. The EvaluatorVersion is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.EvaluatorVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ - return pipeline_response + @overload + def begin_create_generation_job( + self, + job: IO[bytes], + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.EvaluatorVersion]: + """Create an evaluator generation job. - return ItemPaged(get_next, extract_data) + Creates an evaluator generation job. The service generates rubric-based evaluator definitions + from the provided source materials asynchronously. + + :param job: The job to create. Required. + :type job: IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns EvaluatorVersion. The EvaluatorVersion is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.EvaluatorVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def get_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models.AgentInsightRun: - """Get an Agent Insights run. + def begin_create_generation_job( + self, + job: Union[_models.EvaluatorGenerationJob, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> LROPoller[_models.EvaluatorVersion]: + """Create an evaluator generation job. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param run_id: The identifier of the run. Required. - :type run_id: str - :return: AgentInsightRun. The AgentInsightRun is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightRun + Creates an evaluator generation job. The service generates rubric-based evaluator definitions + from the provided source materials asynchronously. + + :param job: The job to create. Is one of the following types: EvaluatorGenerationJob, JSON, + IO[bytes] Required. + :type job: ~azure.ai.projects.models.EvaluatorGenerationJob or JSON or IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :return: An instance of LROPoller that returns EvaluatorVersion. The EvaluatorVersion is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.EvaluatorVersion] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentInsightRun] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._create_generation_job_initial( + job=job, + operation_id=operation_id, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = _deserialize(_models.EvaluatorVersion, response.json().get("result", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - _request = build_beta_agent_insight_monitors_get_run_request( - monitor_id=monitor_id, - run_id=run_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) ) - raise HttpResponseError(response=response, model=error) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) else: - deserialized = _deserialize(_models.AgentInsightRun, response.json()) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + polling_method = polling + if cont_token: + return LROPoller[_models.EvaluatorVersion].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.EvaluatorVersion]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) @distributed_trace - def cancel_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models.AgentInsightRun: - """Cancel an Agent Insights run. + def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.EvaluatorGenerationJob: + """Get an evaluator generation job. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param run_id: The identifier of the run. Required. - :type run_id: str - :return: AgentInsightRun. The AgentInsightRun is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsightRun + Gets the details of an evaluator generation job by its ID. + + :param job_id: The ID of the job. Required. + :type job_id: str + :return: EvaluatorGenerationJob. The EvaluatorGenerationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorGenerationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -11096,11 +14926,10 @@ def cancel_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models.Age _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentInsightRun] = kwargs.pop("cls", None) + cls: ClsType[_models.EvaluatorGenerationJob] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_cancel_run_request( - monitor_id=monitor_id, - run_id=run_id, + _request = build_beta_evaluators_get_generation_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -11131,61 +14960,56 @@ def cancel_run(self, monitor_id: str, run_id: str, **kwargs: Any) -> _models.Age ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentInsightRun, response.json()) + deserialized = _deserialize(_models.EvaluatorGenerationJob, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace - def list_insights( + def list_generation_jobs( self, - monitor_id: str, *, - before: Optional[str] = None, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, - category: Optional[str] = None, - severity: Optional[Union[str, _models.AgentInsightSeverity]] = None, - status: Optional[Union[str, _models.AgentInsightStatus]] = None, - include_details: Optional[bool] = None, + before: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.AgentInsight"]: - """List current insights for an Agent Insights monitor. + ) -> ItemPaged["_models.EvaluatorGenerationJob"]: + """List evaluator generation jobs. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :keyword before: A cursor that identifies the first item in the next page. Default value is - None. - :paramtype before: str - :keyword limit: The maximum number of items to return. Defaults to 20. Default value is None. + Returns a list of evaluator generation jobs. The List API has up to a few seconds of + propagation delay, so a recently created job may not appear immediately; use the Get evaluator + generation job API with the job ID to retrieve a specific job without delay. + + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. :paramtype limit: int - :keyword order: Sort order by creation time. Defaults to descending. Known values are: "asc" - and "desc". Default value is None. + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword category: Filter insights by category. Default value is None. - :paramtype category: str - :keyword severity: Filter insights by severity. Known values are: "high", "medium", and "low". + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. - :paramtype severity: str or ~azure.ai.projects.models.AgentInsightSeverity - :keyword status: Filter insights by lifecycle status. Known values are: "active", "resolved", - and "ignored". Default value is None. - :paramtype status: str or ~azure.ai.projects.models.AgentInsightStatus - :keyword include_details: Whether to include expanded insight details such as evidence and run - links in the response. Defaults to false. Default value is None. - :paramtype include_details: bool - :return: An iterator like instance of AgentInsight - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentInsight] + :paramtype before: str + :return: An iterator like instance of EvaluatorGenerationJob + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluatorGenerationJob] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.AgentInsight]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.EvaluatorGenerationJob]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -11197,16 +15021,11 @@ def list_insights( def prepare_request(_continuation_token=None): - _request = build_beta_agent_insight_monitors_list_insights_request( - monitor_id=monitor_id, - after=_continuation_token, - before=before, + _request = build_beta_evaluators_list_generation_jobs_request( limit=limit, order=order, - category=category, - severity=severity, - status=status, - include_details=include_details, + after=_continuation_token, + before=before, api_version=self._config.api_version, headers=_headers, params=_params, @@ -11220,7 +15039,7 @@ def prepare_request(_continuation_token=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.AgentInsight], + List[_models.EvaluatorGenerationJob], deserialized.get("data", []), ) if cls: @@ -11249,20 +15068,15 @@ def get_next(_continuation_token=None): return ItemPaged(get_next, extract_data) @distributed_trace - def get_insight( - self, monitor_id: str, insight_id: str, *, include_details: Optional[bool] = None, **kwargs: Any - ) -> _models.AgentInsight: - """Get a full insight for an Agent Insights monitor. + def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.EvaluatorGenerationJob: + """Cancel an evaluator generation job. + + Cancels an evaluator generation job by its ID. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param insight_id: The identifier of the insight. Required. - :type insight_id: str - :keyword include_details: Whether to include expanded insight details such as evidence and run - links in the response. Defaults to false. Default value is None. - :paramtype include_details: bool - :return: AgentInsight. The AgentInsight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsight + :param job_id: The ID of the job to cancel. Required. + :type job_id: str + :return: EvaluatorGenerationJob. The EvaluatorGenerationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.EvaluatorGenerationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -11276,12 +15090,10 @@ def get_insight( _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentInsight] = kwargs.pop("cls", None) + cls: ClsType[_models.EvaluatorGenerationJob] = kwargs.pop("cls", None) - _request = build_beta_agent_insight_monitors_get_insight_request( - monitor_id=monitor_id, - insight_id=insight_id, - include_details=include_details, + _request = build_beta_evaluators_cancel_generation_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -11315,110 +15127,152 @@ def get_insight( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentInsight, response.json()) + deserialized = _deserialize(_models.EvaluatorGenerationJob, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + @distributed_trace + def delete_generation_job( # pylint: disable=inconsistent-return-statements + self, job_id: str, **kwargs: Any + ) -> None: + """Delete an evaluator generation job. + + Deletes an evaluator generation job by its ID. Deletes the job record only; the generated + evaluator (if any) is preserved. + + :param job_id: The ID of the job to delete. Required. + :type job_id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_beta_evaluators_delete_generation_job_request( + job_id=job_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + +class BetaInsightsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`insights` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @overload - def update_insight( - self, - monitor_id: str, - insight_id: str, - update: _models.AgentInsightUpdate, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.AgentInsight: - """Update the lifecycle status of an insight. + def generate( + self, insight: _models.Insight, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Insight: + """Generate insights. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param insight_id: The identifier of the insight. Required. - :type insight_id: str - :param update: The insight fields to update. Required. - :type update: ~azure.ai.projects.models.AgentInsightUpdate + Generates an insights report from the provided evaluation configuration. + + :param insight: Complete evaluation configuration including data source, evaluators, and result + settings. Required. + :type insight: ~azure.ai.projects.models.Insight :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: AgentInsight. The AgentInsight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsight + :return: Insight. The Insight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Insight :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update_insight( - self, - monitor_id: str, - insight_id: str, - update: JSON, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.AgentInsight: - """Update the lifecycle status of an insight. + def generate(self, insight: JSON, *, content_type: str = "application/json", **kwargs: Any) -> _models.Insight: + """Generate insights. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param insight_id: The identifier of the insight. Required. - :type insight_id: str - :param update: The insight fields to update. Required. - :type update: JSON + Generates an insights report from the provided evaluation configuration. + + :param insight: Complete evaluation configuration including data source, evaluators, and result + settings. Required. + :type insight: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: AgentInsight. The AgentInsight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsight + :return: Insight. The Insight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Insight :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update_insight( - self, - monitor_id: str, - insight_id: str, - update: IO[bytes], - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.AgentInsight: - """Update the lifecycle status of an insight. + def generate(self, insight: IO[bytes], *, content_type: str = "application/json", **kwargs: Any) -> _models.Insight: + """Generate insights. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param insight_id: The identifier of the insight. Required. - :type insight_id: str - :param update: The insight fields to update. Required. - :type update: IO[bytes] + Generates an insights report from the provided evaluation configuration. + + :param insight: Complete evaluation configuration including data source, evaluators, and result + settings. Required. + :type insight: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". + Default value is "application/json". :paramtype content_type: str - :return: AgentInsight. The AgentInsight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsight + :return: Insight. The Insight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Insight :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def update_insight( - self, - monitor_id: str, - insight_id: str, - update: Union[_models.AgentInsightUpdate, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.AgentInsight: - """Update the lifecycle status of an insight. + def generate(self, insight: Union[_models.Insight, JSON, IO[bytes]], **kwargs: Any) -> _models.Insight: + """Generate insights. - :param monitor_id: The identifier of the monitor. Required. - :type monitor_id: str - :param insight_id: The identifier of the insight. Required. - :type insight_id: str - :param update: The insight fields to update. Is one of the following types: AgentInsightUpdate, - JSON, IO[bytes] Required. - :type update: ~azure.ai.projects.models.AgentInsightUpdate or JSON or IO[bytes] - :return: AgentInsight. The AgentInsight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentInsight + Generates an insights report from the provided evaluation configuration. + + :param insight: Complete evaluation configuration including data source, evaluators, and result + settings. Is one of the following types: Insight, JSON, IO[bytes] Required. + :type insight: ~azure.ai.projects.models.Insight or JSON or IO[bytes] + :return: Insight. The Insight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Insight :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -11433,18 +15287,16 @@ def update_insight( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentInsight] = kwargs.pop("cls", None) + cls: ClsType[_models.Insight] = kwargs.pop("cls", None) - content_type = content_type or "application/merge-patch+json" + content_type = content_type or "application/json" _content = None - if isinstance(update, (IOBase, bytes)): - _content = update + if isinstance(insight, (IOBase, bytes)): + _content = insight else: - _content = json.dumps(update, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(insight, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_agent_insight_monitors_update_insight_request( - monitor_id=monitor_id, - insight_id=insight_id, + _request = build_beta_insights_generate_request( content_type=content_type, api_version=self._config.api_version, content=_content, @@ -11464,7 +15316,7 @@ def update_insight( response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [201]: if _stream: try: response.read() # Load the body in memory and close the socket @@ -11480,41 +15332,26 @@ def update_insight( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentInsight, response.json()) + deserialized = _deserialize(_models.Insight, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - -class BetaEvaluationTaxonomiesOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`evaluation_taxonomies` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace - def get(self, name: str, **kwargs: Any) -> _models.EvaluationTaxonomy: - """Get an evaluation taxonomy. + def get(self, insight_id: str, *, include_coordinates: Optional[bool] = None, **kwargs: Any) -> _models.Insight: + """Get an insight. - Retrieves the specified evaluation taxonomy. + Retrieves the specified insight report and its results. - :param name: The name of the resource. Required. - :type name: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :param insight_id: The unique identifier for the insights report. Required. + :type insight_id: str + :keyword include_coordinates: Whether to include coordinates for visualization in the response. + Defaults to false. Default value is None. + :paramtype include_coordinates: bool + :return: Insight. The Insight is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Insight :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -11528,10 +15365,11 @@ def get(self, name: str, **kwargs: Any) -> _models.EvaluationTaxonomy: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) + cls: ClsType[_models.Insight] = kwargs.pop("cls", None) - _request = build_beta_evaluation_taxonomies_get_request( - name=name, + _request = build_beta_insights_get_request( + insight_id=insight_id, + include_coordinates=include_coordinates, api_version=self._config.api_version, headers=_headers, params=_params, @@ -11556,12 +15394,16 @@ def get(self, name: str, **kwargs: Any) -> _models.EvaluationTaxonomy: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) + deserialized = _deserialize(_models.Insight, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -11570,25 +15412,39 @@ def get(self, name: str, **kwargs: Any) -> _models.EvaluationTaxonomy: @distributed_trace def list( - self, *, input_name: Optional[str] = None, input_type: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.EvaluationTaxonomy"]: - """List evaluation taxonomies. + self, + *, + type: Optional[Union[str, _models.InsightType]] = None, + eval_id: Optional[str] = None, + run_id: Optional[str] = None, + agent_name: Optional[str] = None, + include_coordinates: Optional[bool] = None, + **kwargs: Any + ) -> ItemPaged["_models.Insight"]: + """List insights. - Returns the evaluation taxonomies available in the project, optionally filtered by input name - or input type. + Returns insights in reverse chronological order, with the most recent entries first. - :keyword input_name: Filter by the evaluation input name. Default value is None. - :paramtype input_name: str - :keyword input_type: Filter by taxonomy input type. Default value is None. - :paramtype input_type: str - :return: An iterator like instance of EvaluationTaxonomy - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluationTaxonomy] + :keyword type: Filter by the type of analysis. Known values are: "EvaluationRunClusterInsight", + "AgentClusterInsight", and "EvaluationComparison". Default value is None. + :paramtype type: str or ~azure.ai.projects.models.InsightType + :keyword eval_id: Filter by the evaluation ID. Default value is None. + :paramtype eval_id: str + :keyword run_id: Filter by the evaluation run ID. Default value is None. + :paramtype run_id: str + :keyword agent_name: Filter by the agent name. Default value is None. + :paramtype agent_name: str + :keyword include_coordinates: Whether to include coordinates for visualization in the response. + Defaults to false. Default value is None. + :paramtype include_coordinates: bool + :return: An iterator like instance of Insight + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Insight] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.EvaluationTaxonomy]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.Insight]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -11601,9 +15457,12 @@ def list( def prepare_request(next_link=None): if not next_link: - _request = build_beta_evaluation_taxonomies_list_request( - input_name=input_name, - input_type=input_type, + _request = build_beta_insights_list_request( + type=type, + eval_id=eval_id, + run_id=run_id, + agent_name=agent_name, + include_coordinates=include_coordinates, api_version=self._config.api_version, headers=_headers, params=_params, @@ -11643,7 +15502,7 @@ def prepare_request(next_link=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.EvaluationTaxonomy], + List[_models.Insight], deserialized.get("value", []), ) if cls: @@ -11661,137 +15520,130 @@ def get_next(next_link=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) return pipeline_response return ItemPaged(get_next, extract_data) - @distributed_trace - def delete(self, name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete an evaluation taxonomy. - - Removes the specified evaluation taxonomy from the project. - - :param name: The name of the resource. Required. - :type name: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[None] = kwargs.pop("cls", None) - - _request = build_beta_evaluation_taxonomies_delete_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response +class BetaMemoryStoresOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`memory_stores` attribute. + """ - if cls: - return cls(pipeline_response, None, {}) # type: ignore + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") @overload def create( - self, name: str, taxonomy: _models.EvaluationTaxonomy, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Create an evaluation taxonomy. + self, + *, + name: str, + definition: _models.MemoryStoreDefinition, + content_type: str = "application/json", + description: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Create a memory store. - Creates or replaces the specified evaluation taxonomy with the provided definition. + Creates a memory store resource with the provided configuration. - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy + :keyword name: The name of the memory store. Required. + :paramtype name: str + :keyword definition: The memory store definition. Required. + :paramtype definition: ~azure.ai.projects.models.MemoryStoreDefinition :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :keyword description: A human-readable description of the memory store. Default value is None. + :paramtype description: str + :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default + value is None. + :paramtype metadata: dict[str, str] + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload def create( - self, name: str, taxonomy: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Create an evaluation taxonomy. + self, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Create a memory store. - Creates or replaces the specified evaluation taxonomy with the provided definition. + Creates a memory store resource with the provided configuration. - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: JSON + :param body: Required. + :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload def create( - self, name: str, taxonomy: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Create an evaluation taxonomy. + self, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Create a memory store. - Creates or replaces the specified evaluation taxonomy with the provided definition. + Creates a memory store resource with the provided configuration. - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: IO[bytes] + :param body: Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace def create( - self, name: str, taxonomy: Union[_models.EvaluationTaxonomy, JSON, IO[bytes]], **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Create an evaluation taxonomy. + self, + body: Union[JSON, IO[bytes]] = _Unset, + *, + name: str = _Unset, + definition: _models.MemoryStoreDefinition = _Unset, + description: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Create a memory store. - Creates or replaces the specified evaluation taxonomy with the provided definition. + Creates a memory store resource with the provided configuration. - :param name: The name of the evaluation taxonomy. Required. - :type name: str - :param taxonomy: The evaluation taxonomy. Is one of the following types: EvaluationTaxonomy, - JSON, IO[bytes] Required. - :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy or JSON or IO[bytes] - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword name: The name of the memory store. Required. + :paramtype name: str + :keyword definition: The memory store definition. Required. + :paramtype definition: ~azure.ai.projects.models.MemoryStoreDefinition + :keyword description: A human-readable description of the memory store. Default value is None. + :paramtype description: str + :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default + value is None. + :paramtype metadata: dict[str, str] + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -11806,17 +15658,23 @@ def create( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) + cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) + if body is _Unset: + if name is _Unset: + raise TypeError("missing required argument: name") + if definition is _Unset: + raise TypeError("missing required argument: definition") + body = {"definition": definition, "description": description, "metadata": metadata, "name": name} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(taxonomy, (IOBase, bytes)): - _content = taxonomy + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(taxonomy, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_evaluation_taxonomies_create_request( - name=name, + _request = build_beta_memory_stores_create_request( content_type=content_type, api_version=self._config.api_version, content=_content, @@ -11836,19 +15694,23 @@ def create( response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) + deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -11857,79 +15719,98 @@ def create( @overload def update( - self, name: str, taxonomy: _models.EvaluationTaxonomy, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Update an evaluation taxonomy. + self, + name: str, + *, + content_type: str = "application/json", + description: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Update a memory store. - Modifies the specified evaluation taxonomy with the provided changes. + Updates the specified memory store with the supplied configuration changes. - :param name: The name of the evaluation taxonomy. Required. + :param name: The name of the memory store to update. Required. :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :keyword description: A human-readable description of the memory store. Default value is None. + :paramtype description: str + :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default + value is None. + :paramtype metadata: dict[str, str] + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload def update( - self, name: str, taxonomy: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Update an evaluation taxonomy. + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Update a memory store. - Modifies the specified evaluation taxonomy with the provided changes. + Updates the specified memory store with the supplied configuration changes. - :param name: The name of the evaluation taxonomy. Required. + :param name: The name of the memory store to update. Required. :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: JSON + :param body: Required. + :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @overload def update( - self, name: str, taxonomy: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Update an evaluation taxonomy. + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Update a memory store. - Modifies the specified evaluation taxonomy with the provided changes. + Updates the specified memory store with the supplied configuration changes. - :param name: The name of the evaluation taxonomy. Required. + :param name: The name of the memory store to update. Required. :type name: str - :param taxonomy: The evaluation taxonomy. Required. - :type taxonomy: IO[bytes] + :param body: Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace def update( - self, name: str, taxonomy: Union[_models.EvaluationTaxonomy, JSON, IO[bytes]], **kwargs: Any - ) -> _models.EvaluationTaxonomy: - """Update an evaluation taxonomy. + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + description: Optional[str] = None, + metadata: Optional[dict[str, str]] = None, + **kwargs: Any + ) -> _models.MemoryStoreDetails: + """Update a memory store. - Modifies the specified evaluation taxonomy with the provided changes. + Updates the specified memory store with the supplied configuration changes. - :param name: The name of the evaluation taxonomy. Required. + :param name: The name of the memory store to update. Required. :type name: str - :param taxonomy: The evaluation taxonomy. Is one of the following types: EvaluationTaxonomy, - JSON, IO[bytes] Required. - :type taxonomy: ~azure.ai.projects.models.EvaluationTaxonomy or JSON or IO[bytes] - :return: EvaluationTaxonomy. The EvaluationTaxonomy is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluationTaxonomy + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword description: A human-readable description of the memory store. Default value is None. + :paramtype description: str + :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default + value is None. + :paramtype metadata: dict[str, str] + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -11944,16 +15825,19 @@ def update( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluationTaxonomy] = kwargs.pop("cls", None) + cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) + if body is _Unset: + body = {"description": description, "metadata": metadata} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(taxonomy, (IOBase, bytes)): - _content = taxonomy + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(taxonomy, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_evaluation_taxonomies_update_request( + _request = build_beta_memory_stores_update_request( name=name, content_type=content_type, api_version=self._config.api_version, @@ -11981,67 +15865,34 @@ def update( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluationTaxonomy, response.json()) + deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - -class BetaEvaluatorsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`evaluators` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace - def list_versions( - self, - name: str, - *, - type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, - limit: Optional[int] = None, - **kwargs: Any - ) -> ItemPaged["_models.EvaluatorVersion"]: - """List evaluator versions. + def get(self, name: str, **kwargs: Any) -> _models.MemoryStoreDetails: + """Get a memory store. - Returns the available versions for the specified evaluator. + Retrieves the specified memory store and its current configuration. - :param name: The name of the resource. Required. + :param name: The name of the memory store to retrieve. Required. :type name: str - :keyword type: Filter evaluators by type. Possible values: 'all', 'custom', 'builtin'. Is one - of the following types: Literal["builtin"], Literal["custom"], Literal["all"], str Default - value is None. - :paramtype type: str or str or str or str - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the default is 20. Default value is None. - :paramtype limit: int - :return: An iterator like instance of EvaluatorVersion - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluatorVersion] + :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDetails :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.EvaluatorVersion]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -12050,103 +15901,88 @@ def list_versions( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_evaluators_list_versions_request( - name=name, - type=type, - limit=limit, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) - return _request + _request = build_beta_memory_stores_get_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.EvaluatorVersion], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - def get_next(next_link=None): - _request = prepare_request(next_link) + response = pipeline_response.http_response - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response + raise HttpResponseError(response=response, model=error) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) - return pipeline_response + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore - return ItemPaged(get_next, extract_data) + return deserialized # type: ignore @distributed_trace def list( self, *, - type: Optional[Union[Literal["builtin"], Literal["custom"], Literal["all"], str]] = None, limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.EvaluatorVersion"]: - """List latest evaluator versions. + ) -> ItemPaged["_models.MemoryStoreDetails"]: + """List memory stores. - Lists the latest version of each evaluator. + Returns the memory stores available to the caller. - :keyword type: Filter evaluators by type. Possible values: 'all', 'custom', 'builtin'. Is one - of the following types: Literal["builtin"], Literal["custom"], Literal["all"], str Default - value is None. - :paramtype type: str or str or str or str :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the default is 20. Default value is None. + 100, and the + default is 20. Default value is None. :paramtype limit: int - :return: An iterator like instance of EvaluatorVersion - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluatorVersion] + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of MemoryStoreDetails + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.MemoryStoreDetails] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.EvaluatorVersion]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.MemoryStoreDetails]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -12156,60 +15992,35 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_evaluators_list_request( - type=type, - limit=limit, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + def prepare_request(_continuation_token=None): + _request = build_beta_memory_stores_list_request( + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.EvaluatorVersion], - deserialized.get("value", []), + List[_models.MemoryStoreDetails], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + return deserialized.get("last_id") or None, iter(list_of_elem) - def get_next(next_link=None): - _request = prepare_request(next_link) + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -12219,24 +16030,26 @@ def get_next(next_link=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) return pipeline_response return ItemPaged(get_next, extract_data) @distributed_trace - def get_version(self, name: str, version: str, **kwargs: Any) -> _models.EvaluatorVersion: - """Get an evaluator version. + def delete(self, name: str, **kwargs: Any) -> _models.DeleteMemoryStoreResult: + """Delete a memory store. - Retrieves the specified evaluator version, returning 404 if it does not exist. + Deletes the specified memory store. - :param name: The name of the resource. Required. + :param name: The name of the memory store to delete. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to retrieve. Required. - :type version: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :return: DeleteMemoryStoreResult. The DeleteMemoryStoreResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DeleteMemoryStoreResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -12250,12 +16063,136 @@ def get_version(self, name: str, version: str, **kwargs: Any) -> _models.Evaluat _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) + cls: ClsType[_models.DeleteMemoryStoreResult] = kwargs.pop("cls", None) + + _request = build_beta_memory_stores_delete_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DeleteMemoryStoreResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def _search_memories( + self, + name: str, + *, + scope: str, + content_type: str = "application/json", + items: Optional[List[dict[str, Any]]] = None, + previous_search_id: Optional[str] = None, + options: Optional[_models.MemorySearchOptions] = None, + **kwargs: Any + ) -> _models.MemoryStoreSearchResult: ... + @overload + def _search_memories( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreSearchResult: ... + @overload + def _search_memories( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreSearchResult: ... + + @distributed_trace + def _search_memories( + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + scope: str = _Unset, + items: Optional[List[dict[str, Any]]] = None, + previous_search_id: Optional[str] = None, + options: Optional[_models.MemorySearchOptions] = None, + **kwargs: Any + ) -> _models.MemoryStoreSearchResult: + """Search memories. + + Searches the specified memory store for memories relevant to the provided conversation context. + + :param name: The name of the memory store to search. Required. + :type name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword items: Items for which to search for relevant memories. Default value is None. + :paramtype items: list[dict[str, any]] + :keyword previous_search_id: The unique ID of the previous search request, enabling incremental + memory search from where the last operation left off. Default value is None. + :paramtype previous_search_id: str + :keyword options: Memory search options. Default value is None. + :paramtype options: ~azure.ai.projects.models.MemorySearchOptions + :return: MemoryStoreSearchResult. The MemoryStoreSearchResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreSearchResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.MemoryStoreSearchResult] = kwargs.pop("cls", None) + + if body is _Unset: + if scope is _Unset: + raise TypeError("missing required argument: scope") + body = {"items": items, "options": options, "previous_search_id": previous_search_id, "scope": scope} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_evaluators_get_version_request( + _request = build_beta_memory_stores_search_memories_request( name=name, - version=version, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -12279,34 +16216,33 @@ def get_version(self, name: str, version: str, **kwargs: Any) -> _models.Evaluat except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluatorVersion, response.json()) + deserialized = _deserialize(_models.MemoryStoreSearchResult, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def delete_version( # pylint: disable=inconsistent-return-statements - self, name: str, version: str, **kwargs: Any - ) -> None: - """Delete an evaluator version. - - Removes the specified evaluator version. Returns 204 whether the version existed or not. - - :param name: The name of the resource. Required. - :type name: str - :param version: The version of the EvaluatorVersion to delete. Required. - :type version: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ + def _update_memories_initial( + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + scope: str = _Unset, + items: Optional[List[dict[str, Any]]] = None, + previous_update_id: Optional[str] = None, + update_delay: Optional[int] = None, + **kwargs: Any + ) -> Iterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -12315,15 +16251,34 @@ def delete_version( # pylint: disable=inconsistent-return-statements } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_beta_evaluators_delete_version_request( + if body is _Unset: + if scope is _Unset: + raise TypeError("missing required argument: scope") + body = { + "items": items, + "previous_update_id": previous_update_id, + "scope": scope, + "update_delay": update_delay, + } + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_memory_stores_update_memories_request( name=name, - version=version, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -12332,262 +16287,240 @@ def delete_version( # pylint: disable=inconsistent-return-statements } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = True pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [202]: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore @overload - def create_version( + def _begin_update_memories( self, name: str, - evaluator_version: _models.EvaluatorVersion, *, + scope: str, content_type: str = "application/json", + items: Optional[List[dict[str, Any]]] = None, + previous_update_id: Optional[str] = None, + update_delay: Optional[int] = None, **kwargs: Any - ) -> _models.EvaluatorVersion: - """Create an evaluator version. - - Creates a new evaluator version with an auto-incremented version identifier. - - :param name: The name of the resource. Required. - :type name: str - :param evaluator_version: Required. - :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - + ) -> LROPoller[_models.MemoryStoreUpdateCompletedResult]: ... @overload - def create_version( - self, name: str, evaluator_version: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluatorVersion: - """Create an evaluator version. - - Creates a new evaluator version with an auto-incremented version identifier. - - :param name: The name of the resource. Required. - :type name: str - :param evaluator_version: Required. - :type evaluator_version: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - + def _begin_update_memories( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.MemoryStoreUpdateCompletedResult]: ... @overload - def create_version( - self, name: str, evaluator_version: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluatorVersion: - """Create an evaluator version. - - Creates a new evaluator version with an auto-incremented version identifier. - - :param name: The name of the resource. Required. - :type name: str - :param evaluator_version: Required. - :type evaluator_version: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ + def _begin_update_memories( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.MemoryStoreUpdateCompletedResult]: ... @distributed_trace - def create_version( - self, name: str, evaluator_version: Union[_models.EvaluatorVersion, JSON, IO[bytes]], **kwargs: Any - ) -> _models.EvaluatorVersion: - """Create an evaluator version. + def _begin_update_memories( + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + scope: str = _Unset, + items: Optional[List[dict[str, Any]]] = None, + previous_update_id: Optional[str] = None, + update_delay: Optional[int] = None, + **kwargs: Any + ) -> LROPoller[_models.MemoryStoreUpdateCompletedResult]: + """Update memories. - Creates a new evaluator version with an auto-incremented version identifier. + Starts an update that writes conversation memories into the specified memory store. The + operation returns a long-running status location for polling the update result. - :param name: The name of the resource. Required. + :param name: The name of the memory store to update. Required. :type name: str - :param evaluator_version: Is one of the following types: EvaluatorVersion, JSON, IO[bytes] + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. Required. - :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion or JSON or IO[bytes] - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :paramtype scope: str + :keyword items: Conversation items to be stored in memory. Default value is None. + :paramtype items: list[dict[str, any]] + :keyword previous_update_id: The unique ID of the previous update request, enabling incremental + memory updates from where the last operation left off. Default value is None. + :paramtype previous_update_id: str + :keyword update_delay: Timeout period before processing the memory update in seconds. + If a new update request is received during this period, it will cancel the current request and + reset the timeout. + Set to 0 to immediately trigger the update without delay. + Defaults to 300 (5 minutes). Default value is None. + :paramtype update_delay: int + :return: An instance of LROPoller that returns MemoryStoreUpdateCompletedResult. The + MemoryStoreUpdateCompletedResult is compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.ai.projects.models.MemoryStoreUpdateCompletedResult] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) + cls: ClsType[_models.MemoryStoreUpdateCompletedResult] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._update_memories_initial( + name=name, + body=body, + scope=scope, + items=items, + previous_update_id=previous_update_id, + update_delay=update_delay, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) - content_type = content_type or "application/json" - _content = None - if isinstance(evaluator_version, (IOBase, bytes)): - _content = evaluator_version - else: - _content = json.dumps(evaluator_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + + deserialized = _deserialize(_models.MemoryStoreUpdateCompletedResult, response.json().get("result", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - _request = build_beta_evaluators_create_version_request( - name=name, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [201]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) else: - deserialized = _deserialize(_models.EvaluatorVersion, response.json()) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + polling_method = polling + if cont_token: + return LROPoller[_models.MemoryStoreUpdateCompletedResult].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.MemoryStoreUpdateCompletedResult]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) @overload - def update_version( - self, - name: str, - version: str, - evaluator_version: _models.EvaluatorVersion, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.EvaluatorVersion: - """Update an evaluator version. + def delete_scope( + self, name: str, *, scope: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDeleteScopeResult: + """Delete memories by scope. - Updates the specified evaluator version in place. + Deletes all memories in the specified memory store that are associated with the provided scope. - :param name: The name of the resource. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The version of the EvaluatorVersion to update. Required. - :type version: str - :param evaluator_version: Evaluator resource. Required. - :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion + :keyword scope: The namespace that logically groups and isolates memories to delete, such as a + user ID. Required. + :paramtype scope: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update_version( - self, name: str, version: str, evaluator_version: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.EvaluatorVersion: - """Update an evaluator version. + def delete_scope( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDeleteScopeResult: + """Delete memories by scope. - Updates the specified evaluator version in place. + Deletes all memories in the specified memory store that are associated with the provided scope. - :param name: The name of the resource. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The version of the EvaluatorVersion to update. Required. - :type version: str - :param evaluator_version: Evaluator resource. Required. - :type evaluator_version: JSON + :param body: Required. + :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update_version( - self, - name: str, - version: str, - evaluator_version: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.EvaluatorVersion: - """Update an evaluator version. + def delete_scope( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryStoreDeleteScopeResult: + """Delete memories by scope. - Updates the specified evaluator version in place. + Deletes all memories in the specified memory store that are associated with the provided scope. - :param name: The name of the resource. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The version of the EvaluatorVersion to update. Required. - :type version: str - :param evaluator_version: Evaluator resource. Required. - :type evaluator_version: IO[bytes] + :param body: Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def update_version( - self, - name: str, - version: str, - evaluator_version: Union[_models.EvaluatorVersion, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.EvaluatorVersion: - """Update an evaluator version. + def delete_scope( + self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, scope: str = _Unset, **kwargs: Any + ) -> _models.MemoryStoreDeleteScopeResult: + """Delete memories by scope. - Updates the specified evaluator version in place. + Deletes all memories in the specified memory store that are associated with the provided scope. - :param name: The name of the resource. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The version of the EvaluatorVersion to update. Required. - :type version: str - :param evaluator_version: Evaluator resource. Is one of the following types: EvaluatorVersion, - JSON, IO[bytes] Required. - :type evaluator_version: ~azure.ai.projects.models.EvaluatorVersion or JSON or IO[bytes] - :return: EvaluatorVersion. The EvaluatorVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorVersion + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword scope: The namespace that logically groups and isolates memories to delete, such as a + user ID. Required. + :paramtype scope: str + :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -12602,18 +16535,22 @@ def update_version( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) + cls: ClsType[_models.MemoryStoreDeleteScopeResult] = kwargs.pop("cls", None) + if body is _Unset: + if scope is _Unset: + raise TypeError("missing required argument: scope") + body = {"scope": scope} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(evaluator_version, (IOBase, bytes)): - _content = evaluator_version + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(evaluator_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_evaluators_update_version_request( + _request = build_beta_memory_stores_delete_scope_request( name=name, - version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -12640,12 +16577,16 @@ def update_version( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluatorVersion, response.json()) + deserialized = _deserialize(_models.MemoryStoreDeleteScopeResult, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -12653,115 +16594,107 @@ def update_version( return deserialized # type: ignore @overload - def pending_upload( + def create_memory( self, name: str, - version: str, - pending_upload_request: _models.PendingUploadRequest, *, + scope: str, + content: str, + kind: Union[str, _models.MemoryItemKind], content_type: str = "application/json", **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. + ) -> _models.MemoryItem: + """Create a memory item. - Initiates a new pending upload or retrieves an existing one for the specified evaluator - version. + Creates a memory item in the specified memory store. - :param name: The name path parameter. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword content: The content of the memory. Required. + :paramtype content: str + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Required. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def pending_upload( - self, - name: str, - version: str, - pending_upload_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. + def create_memory( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryItem: + """Create a memory item. - Initiates a new pending upload or retrieves an existing one for the specified evaluator - version. + Creates a memory item in the specified memory store. - :param name: The name path parameter. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: JSON + :param body: Required. + :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def pending_upload( - self, - name: str, - version: str, - pending_upload_request: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. + def create_memory( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryItem: + """Create a memory item. - Initiates a new pending upload or retrieves an existing one for the specified evaluator - version. + Creates a memory item in the specified memory store. - :param name: The name path parameter. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Required. - :type pending_upload_request: IO[bytes] + :param body: Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def pending_upload( + def create_memory( self, name: str, - version: str, - pending_upload_request: Union[_models.PendingUploadRequest, JSON, IO[bytes]], + body: Union[JSON, IO[bytes]] = _Unset, + *, + scope: str = _Unset, + content: str = _Unset, + kind: Union[str, _models.MemoryItemKind] = _Unset, **kwargs: Any - ) -> _models.PendingUploadResponse: - """Start a pending upload. + ) -> _models.MemoryItem: + """Create a memory item. - Initiates a new pending upload or retrieves an existing one for the specified evaluator - version. + Creates a memory item in the specified memory store. - :param name: The name path parameter. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param pending_upload_request: The pending upload request parameters. Is one of the following - types: PendingUploadRequest, JSON, IO[bytes] Required. - :type pending_upload_request: ~azure.ai.projects.models.PendingUploadRequest or JSON or - IO[bytes] - :return: PendingUploadResponse. The PendingUploadResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.PendingUploadResponse + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword content: The content of the memory. Required. + :paramtype content: str + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Required. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -12776,18 +16709,26 @@ def pending_upload( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.PendingUploadResponse] = kwargs.pop("cls", None) + cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) + if body is _Unset: + if scope is _Unset: + raise TypeError("missing required argument: scope") + if content is _Unset: + raise TypeError("missing required argument: content") + if kind is _Unset: + raise TypeError("missing required argument: kind") + body = {"content": content, "kind": kind, "scope": scope} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(pending_upload_request, (IOBase, bytes)): - _content = pending_upload_request + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_evaluators_pending_upload_request( + _request = build_beta_memory_stores_create_memory_request( name=name, - version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -12823,7 +16764,7 @@ def pending_upload( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.PendingUploadResponse, response.json()) + deserialized = _deserialize(_models.MemoryItem, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -12831,115 +16772,89 @@ def pending_upload( return deserialized # type: ignore @overload - def get_credentials( - self, - name: str, - version: str, - credential_request: _models.EvaluatorCredentialRequest, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.DatasetCredential: - """Get evaluator credentials. + def update_memory( + self, name: str, memory_id: str, *, content: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryItem: + """Update a memory item. - Retrieves SAS credentials for accessing the storage account associated with the specified - evaluator version. + Updates the specified memory item in the memory store. - :param name: The name path parameter. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param credential_request: The credential request parameters. Required. - :type credential_request: ~azure.ai.projects.models.EvaluatorCredentialRequest + :param memory_id: The ID of the memory item to update. Required. + :type memory_id: str + :keyword content: The updated content of the memory. Required. + :paramtype content: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def get_credentials( - self, - name: str, - version: str, - credential_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.DatasetCredential: - """Get evaluator credentials. + def update_memory( + self, name: str, memory_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryItem: + """Update a memory item. - Retrieves SAS credentials for accessing the storage account associated with the specified - evaluator version. + Updates the specified memory item in the memory store. - :param name: The name path parameter. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param credential_request: The credential request parameters. Required. - :type credential_request: JSON + :param memory_id: The ID of the memory item to update. Required. + :type memory_id: str + :param body: Required. + :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def get_credentials( - self, - name: str, - version: str, - credential_request: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.DatasetCredential: - """Get evaluator credentials. + def update_memory( + self, name: str, memory_id: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.MemoryItem: + """Update a memory item. - Retrieves SAS credentials for accessing the storage account associated with the specified - evaluator version. + Updates the specified memory item in the memory store. - :param name: The name path parameter. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param credential_request: The credential request parameters. Required. - :type credential_request: IO[bytes] + :param memory_id: The ID of the memory item to update. Required. + :type memory_id: str + :param body: Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def get_credentials( - self, - name: str, - version: str, - credential_request: Union[_models.EvaluatorCredentialRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.DatasetCredential: - """Get evaluator credentials. + def update_memory( + self, name: str, memory_id: str, body: Union[JSON, IO[bytes]] = _Unset, *, content: str = _Unset, **kwargs: Any + ) -> _models.MemoryItem: + """Update a memory item. - Retrieves SAS credentials for accessing the storage account associated with the specified - evaluator version. + Updates the specified memory item in the memory store. - :param name: The name path parameter. Required. + :param name: The name of the memory store. Required. :type name: str - :param version: The specific version id of the EvaluatorVersion to operate on. Required. - :type version: str - :param credential_request: The credential request parameters. Is one of the following types: - EvaluatorCredentialRequest, JSON, IO[bytes] Required. - :type credential_request: ~azure.ai.projects.models.EvaluatorCredentialRequest or JSON or - IO[bytes] - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :param memory_id: The ID of the memory item to update. Required. + :type memory_id: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword content: The updated content of the memory. Required. + :paramtype content: str + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -12954,18 +16869,23 @@ def get_credentials( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) + cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) + if body is _Unset: + if content is _Unset: + raise TypeError("missing required argument: content") + body = {"content": content} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(credential_request, (IOBase, bytes)): - _content = credential_request + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(credential_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_evaluators_get_credentials_request( + _request = build_beta_memory_stores_update_memory_request( name=name, - version=version, + memory_id=memory_id, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -13001,20 +16921,27 @@ def get_credentials( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DatasetCredential, response.json()) + deserialized = _deserialize(_models.MemoryItem, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - def _create_generation_job_initial( - self, - job: Union[_models.EvaluatorGenerationJob, JSON, IO[bytes]], - *, - operation_id: Optional[str] = None, - **kwargs: Any - ) -> Iterator[bytes]: + @distributed_trace + def get_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models.MemoryItem: + """Get a memory item. + + Retrieves the specified memory item from the memory store. + + :param name: The name of the memory store. Required. + :type name: str + :param memory_id: The ID of the memory item to retrieve. Required. + :type memory_id: str + :return: MemoryItem. The MemoryItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.MemoryItem + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -13023,24 +16950,15 @@ def _create_generation_job_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(job, (IOBase, bytes)): - _content = job - else: - _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) - _request = build_beta_evaluators_create_generation_job_request( - operation_id=operation_id, - content_type=content_type, + _request = build_beta_memory_stores_get_memory_request( + name=name, + memory_id=memory_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -13050,18 +16968,19 @@ def _create_generation_job_initial( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -13069,187 +16988,289 @@ def _create_generation_job_initial( ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.MemoryItem, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @overload - def begin_create_generation_job( + def list_memories( self, - job: _models.EvaluatorGenerationJob, + name: str, *, - operation_id: Optional[str] = None, + scope: str, + kind: Optional[Union[str, _models.MemoryItemKind]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.EvaluatorVersion]: - """Create an evaluator generation job. + ) -> ItemPaged["_models.MemoryItem"]: + """List memory items. - Creates an evaluator generation job. The service generates rubric-based evaluator definitions - from the provided source materials asynchronously. + Returns memory items from the specified memory store. - :param job: The job to create. Required. - :type job: ~azure.ai.projects.models.EvaluatorGenerationJob - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param name: The name of the memory store. Required. + :type name: str + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Default value is None. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns EvaluatorVersion. The EvaluatorVersion is - compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.EvaluatorVersion] + :return: An iterator like instance of MemoryItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.MemoryItem] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_create_generation_job( - self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.EvaluatorVersion]: - """Create an evaluator generation job. + def list_memories( + self, + name: str, + body: JSON, + *, + kind: Optional[Union[str, _models.MemoryItemKind]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> ItemPaged["_models.MemoryItem"]: + """List memory items. - Creates an evaluator generation job. The service generates rubric-based evaluator definitions - from the provided source materials asynchronously. + Returns memory items from the specified memory store. - :param job: The job to create. Required. - :type job: JSON - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param name: The name of the memory store. Required. + :type name: str + :param body: Required. + :type body: JSON + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Default value is None. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns EvaluatorVersion. The EvaluatorVersion is - compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.EvaluatorVersion] + :return: An iterator like instance of MemoryItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.MemoryItem] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_create_generation_job( + def list_memories( self, - job: IO[bytes], + name: str, + body: IO[bytes], *, - operation_id: Optional[str] = None, + kind: Optional[Union[str, _models.MemoryItemKind]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.EvaluatorVersion]: - """Create an evaluator generation job. + ) -> ItemPaged["_models.MemoryItem"]: + """List memory items. - Creates an evaluator generation job. The service generates rubric-based evaluator definitions - from the provided source materials asynchronously. + Returns memory items from the specified memory store. - :param job: The job to create. Required. - :type job: IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param name: The name of the memory store. Required. + :type name: str + :param body: Required. + :type body: IO[bytes] + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Default value is None. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns EvaluatorVersion. The EvaluatorVersion is - compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.EvaluatorVersion] + :return: An iterator like instance of MemoryItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.MemoryItem] :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def begin_create_generation_job( + def list_memories( self, - job: Union[_models.EvaluatorGenerationJob, JSON, IO[bytes]], + name: str, + body: Union[JSON, IO[bytes]] = _Unset, *, - operation_id: Optional[str] = None, + scope: str = _Unset, + kind: Optional[Union[str, _models.MemoryItemKind]] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> LROPoller[_models.EvaluatorVersion]: - """Create an evaluator generation job. + ) -> ItemPaged["_models.MemoryItem"]: + """List memory items. - Creates an evaluator generation job. The service generates rubric-based evaluator definitions - from the provided source materials asynchronously. + Returns memory items from the specified memory store. - :param job: The job to create. Is one of the following types: EvaluatorGenerationJob, JSON, - IO[bytes] Required. - :type job: ~azure.ai.projects.models.EvaluatorGenerationJob or JSON or IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :return: An instance of LROPoller that returns EvaluatorVersion. The EvaluatorVersion is - compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.EvaluatorVersion] + :param name: The name of the memory store. Required. + :type name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. + Required. + :paramtype scope: str + :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", + and "procedural". Default value is None. + :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of MemoryItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.MemoryItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.EvaluatorVersion] = kwargs.pop("cls", None) - polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = self._create_generation_job_initial( - job=job, - operation_id=operation_id, + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.MemoryItem]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + if body is _Unset: + if scope is _Unset: + raise TypeError("missing required argument: scope") + body = {"scope": scope} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + def prepare_request(_continuation_token=None): + + _request = build_beta_memory_stores_list_memories_request( + name=name, + kind=kind, + limit=limit, + order=order, + after=_continuation_token, + before=before, content_type=content_type, - cls=lambda x, y, z: x, + api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, - **kwargs ) - raw_result.http_response.read() # type: ignore - kwargs.pop("error_map", None) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Operation-Location"] = self._deserialize( - "str", response.headers.get("Operation-Location") + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.MemoryItem], + deserialized.get("data", []), ) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = _deserialize(_models.EvaluatorVersion, response.json().get("result", {})) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - if polling is True: - polling_method: PollingMethod = cast( - PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) - ) - elif polling is False: - polling_method = cast(PollingMethod, NoPolling()) - else: - polling_method = polling - if cont_token: - return LROPoller[_models.EvaluatorVersion].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) - return LROPoller[_models.EvaluatorVersion]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) @distributed_trace - def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.EvaluatorGenerationJob: - """Get an evaluator generation job. + def delete_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models.DeleteMemoryResult: + """Delete a memory item. - Gets the details of an evaluator generation job by its ID. + Deletes the specified memory item from the memory store. - :param job_id: The ID of the job. Required. - :type job_id: str - :return: EvaluatorGenerationJob. The EvaluatorGenerationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorGenerationJob + :param name: The name of the memory store. Required. + :type name: str + :param memory_id: The ID of the memory item to delete. Required. + :type memory_id: str + :return: DeleteMemoryResult. The DeleteMemoryResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DeleteMemoryResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -13263,10 +17284,11 @@ def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.EvaluatorGen _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.EvaluatorGenerationJob] = kwargs.pop("cls", None) + cls: ClsType[_models.DeleteMemoryResult] = kwargs.pop("cls", None) - _request = build_beta_evaluators_get_generation_job_request( - job_id=job_id, + _request = build_beta_memory_stores_delete_memory_request( + name=name, + memory_id=memory_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -13297,56 +17319,141 @@ def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.EvaluatorGen ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluatorGenerationJob, response.json()) + deserialized = _deserialize(_models.DeleteMemoryResult, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + +class BetaModelsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`models` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @distributed_trace - def list_generation_jobs( - self, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> ItemPaged["_models.EvaluatorGenerationJob"]: - """List evaluator generation jobs. + def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.ModelVersion"]: + """List versions. - Returns a list of evaluator generation jobs. The List API has up to a few seconds of - propagation delay, so a recently created job may not appear immediately; use the Get evaluator - generation job API with the job ID to retrieve a specific job without delay. + List all versions of the given ModelVersion. - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of EvaluatorGenerationJob - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.EvaluatorGenerationJob] + :param name: The name of the resource. Required. + :type name: str + :return: An iterator like instance of ModelVersion + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.ModelVersion] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ModelVersion]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_models_list_versions_request( + name=name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ModelVersion], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def list(self, **kwargs: Any) -> ItemPaged["_models.ModelVersion"]: + """List latest versions. + + List the latest version of each ModelVersion. + + :return: An iterator like instance of ModelVersion + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.ModelVersion] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.EvaluatorGenerationJob]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.ModelVersion]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -13356,35 +17463,58 @@ def list_generation_jobs( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_models_list_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _request = build_beta_evaluators_list_generation_jobs_request( - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.EvaluatorGenerationJob], - deserialized.get("data", []), + List[_models.ModelVersion], + deserialized.get("value", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + return deserialized.get("nextLink") or None, iter(list_of_elem) - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + def get_next(next_link=None): + _request = prepare_request(next_link) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -13394,26 +17524,24 @@ def get_next(_continuation_token=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) return pipeline_response return ItemPaged(get_next, extract_data) @distributed_trace - def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.EvaluatorGenerationJob: - """Cancel an evaluator generation job. + def get(self, name: str, version: str, **kwargs: Any) -> _models.ModelVersion: + """Get a model version. - Cancels an evaluator generation job by its ID. + Retrieves the specified model version, returning 404 if it does not exist. - :param job_id: The ID of the job to cancel. Required. - :type job_id: str - :return: EvaluatorGenerationJob. The EvaluatorGenerationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.EvaluatorGenerationJob + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the ModelVersion to retrieve. Required. + :type version: str + :return: ModelVersion. The ModelVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ModelVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -13427,10 +17555,11 @@ def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.Evaluator _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.EvaluatorGenerationJob] = kwargs.pop("cls", None) + cls: ClsType[_models.ModelVersion] = kwargs.pop("cls", None) - _request = build_beta_evaluators_cancel_generation_job_request( - job_id=job_id, + _request = build_beta_models_get_request( + name=name, + version=version, api_version=self._config.api_version, headers=_headers, params=_params, @@ -13455,16 +17584,12 @@ def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.Evaluator except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.EvaluatorGenerationJob, response.json()) + deserialized = _deserialize(_models.ModelVersion, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -13472,16 +17597,15 @@ def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.Evaluator return deserialized # type: ignore @distributed_trace - def delete_generation_job( # pylint: disable=inconsistent-return-statements - self, job_id: str, **kwargs: Any - ) -> None: - """Delete an evaluator generation job. + def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete a model version. - Deletes an evaluator generation job by its ID. Deletes the job record only; the generated - evaluator (if any) is preserved. + Removes the specified model version. Returns 200 whether the version existed or not. - :param job_id: The ID of the job to delete. Required. - :type job_id: str + :param name: The name of the resource. Required. + :type name: str + :param version: The version of the ModelVersion to delete. Required. + :type version: str :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -13499,8 +17623,9 @@ def delete_generation_job( # pylint: disable=inconsistent-return-statements cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_evaluators_delete_generation_job_request( - job_id=job_id, + _request = build_beta_models_delete_request( + name=name, + version=version, api_version=self._config.api_version, headers=_headers, params=_params, @@ -13517,99 +17642,123 @@ def delete_generation_job( # pylint: disable=inconsistent-return-statements response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if cls: return cls(pipeline_response, None, {}) # type: ignore - -class BetaInsightsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`insights` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @overload - def generate( - self, insight: _models.Insight, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Insight: - """Generate insights. + def update( + self, + name: str, + version: str, + model_version_update: _models.UpdateModelVersionRequest, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.ModelVersion: + """Update a model version. - Generates an insights report from the provided evaluation configuration. + Updates an existing model version identified by its version ID. - :param insight: Complete evaluation configuration including data source, evaluators, and result - settings. Required. - :type insight: ~azure.ai.projects.models.Insight + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the UpdateModelVersionRequest to create or update. + Required. + :type version: str + :param model_version_update: The UpdateModelVersionRequest to create or update. Required. + :type model_version_update: ~azure.ai.projects.models.UpdateModelVersionRequest :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: Insight. The Insight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Insight + :return: ModelVersion. The ModelVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ModelVersion :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def generate(self, insight: JSON, *, content_type: str = "application/json", **kwargs: Any) -> _models.Insight: - """Generate insights. + def update( + self, + name: str, + version: str, + model_version_update: JSON, + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.ModelVersion: + """Update a model version. - Generates an insights report from the provided evaluation configuration. + Updates an existing model version identified by its version ID. - :param insight: Complete evaluation configuration including data source, evaluators, and result - settings. Required. - :type insight: JSON + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the UpdateModelVersionRequest to create or update. + Required. + :type version: str + :param model_version_update: The UpdateModelVersionRequest to create or update. Required. + :type model_version_update: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: Insight. The Insight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Insight + :return: ModelVersion. The ModelVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ModelVersion :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def generate(self, insight: IO[bytes], *, content_type: str = "application/json", **kwargs: Any) -> _models.Insight: - """Generate insights. + def update( + self, + name: str, + version: str, + model_version_update: IO[bytes], + *, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.ModelVersion: + """Update a model version. - Generates an insights report from the provided evaluation configuration. + Updates an existing model version identified by its version ID. - :param insight: Complete evaluation configuration including data source, evaluators, and result - settings. Required. - :type insight: IO[bytes] + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the UpdateModelVersionRequest to create or update. + Required. + :type version: str + :param model_version_update: The UpdateModelVersionRequest to create or update. Required. + :type model_version_update: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". + Default value is "application/merge-patch+json". :paramtype content_type: str - :return: Insight. The Insight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Insight + :return: ModelVersion. The ModelVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ModelVersion :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def generate(self, insight: Union[_models.Insight, JSON, IO[bytes]], **kwargs: Any) -> _models.Insight: - """Generate insights. + def update( + self, + name: str, + version: str, + model_version_update: Union[_models.UpdateModelVersionRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.ModelVersion: + """Update a model version. - Generates an insights report from the provided evaluation configuration. + Updates an existing model version identified by its version ID. - :param insight: Complete evaluation configuration including data source, evaluators, and result - settings. Is one of the following types: Insight, JSON, IO[bytes] Required. - :type insight: ~azure.ai.projects.models.Insight or JSON or IO[bytes] - :return: Insight. The Insight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Insight + :param name: The name of the resource. Required. + :type name: str + :param version: The specific version id of the UpdateModelVersionRequest to create or update. + Required. + :type version: str + :param model_version_update: The UpdateModelVersionRequest to create or update. Is one of the + following types: UpdateModelVersionRequest, JSON, IO[bytes] Required. + :type model_version_update: ~azure.ai.projects.models.UpdateModelVersionRequest or JSON or + IO[bytes] + :return: ModelVersion. The ModelVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ModelVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -13624,16 +17773,18 @@ def generate(self, insight: Union[_models.Insight, JSON, IO[bytes]], **kwargs: A _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Insight] = kwargs.pop("cls", None) + cls: ClsType[_models.ModelVersion] = kwargs.pop("cls", None) - content_type = content_type or "application/json" + content_type = content_type or "application/merge-patch+json" _content = None - if isinstance(insight, (IOBase, bytes)): - _content = insight + if isinstance(model_version_update, (IOBase, bytes)): + _content = model_version_update else: - _content = json.dumps(insight, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(model_version_update, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_insights_generate_request( + _request = build_beta_models_update_request( + name=name, + version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -13653,334 +17804,301 @@ def generate(self, insight: Union[_models.Insight, JSON, IO[bytes]], **kwargs: A response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200, 201]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Insight, response.json()) + deserialized = _deserialize(_models.ModelVersion, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def get(self, insight_id: str, *, include_coordinates: Optional[bool] = None, **kwargs: Any) -> _models.Insight: - """Get an insight. + @overload + def pending_create_version( + self, + name: str, + version: str, + model_version: _models.ModelVersion, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.CreateAsyncResponse: + """Create a model version async. - Retrieves the specified insight report and its results. + Creates a model version asynchronously with blob content validation. Returns 202 Accepted with + a location header for polling the operation status. - :param insight_id: The unique identifier for the insights report. Required. - :type insight_id: str - :keyword include_coordinates: Whether to include coordinates for visualization in the response. - Defaults to false. Default value is None. - :paramtype include_coordinates: bool - :return: Insight. The Insight is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Insight + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param model_version: Model version to create. Required. + :type model_version: ~azure.ai.projects.models.ModelVersion + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.CreateAsyncResponse :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models.Insight] = kwargs.pop("cls", None) - - _request = build_beta_insights_get_request( - insight_id=insight_id, - include_coordinates=include_coordinates, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Insight, response.json()) + @overload + def pending_create_version( + self, name: str, version: str, model_version: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.CreateAsyncResponse: + """Create a model version async. - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + Creates a model version asynchronously with blob content validation. Returns 202 Accepted with + a location header for polling the operation status. - return deserialized # type: ignore + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param model_version: Model version to create. Required. + :type model_version: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ - @distributed_trace - def list( + @overload + def pending_create_version( self, + name: str, + version: str, + model_version: IO[bytes], *, - type: Optional[Union[str, _models.InsightType]] = None, - eval_id: Optional[str] = None, - run_id: Optional[str] = None, - agent_name: Optional[str] = None, - include_coordinates: Optional[bool] = None, + content_type: str = "application/json", **kwargs: Any - ) -> ItemPaged["_models.Insight"]: - """List insights. + ) -> _models.CreateAsyncResponse: + """Create a model version async. - Returns insights in reverse chronological order, with the most recent entries first. + Creates a model version asynchronously with blob content validation. Returns 202 Accepted with + a location header for polling the operation status. - :keyword type: Filter by the type of analysis. Known values are: "EvaluationRunClusterInsight", - "AgentClusterInsight", and "EvaluationComparison". Default value is None. - :paramtype type: str or ~azure.ai.projects.models.InsightType - :keyword eval_id: Filter by the evaluation ID. Default value is None. - :paramtype eval_id: str - :keyword run_id: Filter by the evaluation run ID. Default value is None. - :paramtype run_id: str - :keyword agent_name: Filter by the agent name. Default value is None. - :paramtype agent_name: str - :keyword include_coordinates: Whether to include coordinates for visualization in the response. - Defaults to false. Default value is None. - :paramtype include_coordinates: bool - :return: An iterator like instance of Insight - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Insight] + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param model_version: Model version to create. Required. + :type model_version: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.CreateAsyncResponse :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.Insight]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: + @distributed_trace + def pending_create_version( + self, name: str, version: str, model_version: Union[_models.ModelVersion, JSON, IO[bytes]], **kwargs: Any + ) -> _models.CreateAsyncResponse: + """Create a model version async. - _request = build_beta_insights_list_request( - type=type, - eval_id=eval_id, - run_id=run_id, - agent_name=agent_name, - include_coordinates=include_coordinates, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + Creates a model version asynchronously with blob content validation. Returns 202 Accepted with + a location header for polling the operation status. - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param model_version: Model version to create. Is one of the following types: ModelVersion, + JSON, IO[bytes] Required. + :type model_version: ~azure.ai.projects.models.ModelVersion or JSON or IO[bytes] + :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - return _request + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Insight], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.CreateAsyncResponse] = kwargs.pop("cls", None) - def get_next(next_link=None): - _request = prepare_request(next_link) + content_type = content_type or "application/json" + _content = None + if isinstance(model_version, (IOBase, bytes)): + _content = model_version + else: + _content = json.dumps(model_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + _request = build_beta_models_pending_create_version_request( + name=name, + version=version, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - return pipeline_response + response = pipeline_response.http_response - return ItemPaged(get_next, extract_data) + if response.status_code not in [202]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + response_headers = {} + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) -class BetaMemoryStoresOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.CreateAsyncResponse, response.json()) - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`memory_stores` attribute. - """ + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + return deserialized # type: ignore @overload - def create( + def pending_upload( self, - *, name: str, - definition: _models.MemoryStoreDefinition, + version: str, + pending_upload_request: _models.ModelPendingUploadRequest, + *, content_type: str = "application/json", - description: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Create a memory store. + ) -> _models.ModelPendingUploadResponse: + """Start a pending upload. - Creates a memory store resource with the provided configuration. + Initiates a new pending upload or retrieves an existing one for the specified model version. - :keyword name: The name of the memory store. Required. - :paramtype name: str - :keyword definition: The memory store definition. Required. - :paramtype definition: ~azure.ai.projects.models.MemoryStoreDefinition + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param pending_upload_request: The pending upload request request body. Required. + :type pending_upload_request: ~azure.ai.projects.models.ModelPendingUploadRequest :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword description: A human-readable description of the memory store. Default value is None. - :paramtype description: str - :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default - value is None. - :paramtype metadata: dict[str, str] - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create( - self, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Create a memory store. + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ModelPendingUploadResponse: + """Start a pending upload. - Creates a memory store resource with the provided configuration. + Initiates a new pending upload or retrieves an existing one for the specified model version. - :param body: Required. - :type body: JSON + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param pending_upload_request: The pending upload request request body. Required. + :type pending_upload_request: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create( - self, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Create a memory store. + def pending_upload( + self, + name: str, + version: str, + pending_upload_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.ModelPendingUploadResponse: + """Start a pending upload. - Creates a memory store resource with the provided configuration. + Initiates a new pending upload or retrieves an existing one for the specified model version. - :param body: Required. - :type body: IO[bytes] + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param pending_upload_request: The pending upload request request body. Required. + :type pending_upload_request: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def create( + def pending_upload( self, - body: Union[JSON, IO[bytes]] = _Unset, - *, - name: str = _Unset, - definition: _models.MemoryStoreDefinition = _Unset, - description: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, + name: str, + version: str, + pending_upload_request: Union[_models.ModelPendingUploadRequest, JSON, IO[bytes]], **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Create a memory store. + ) -> _models.ModelPendingUploadResponse: + """Start a pending upload. - Creates a memory store resource with the provided configuration. + Initiates a new pending upload or retrieves an existing one for the specified model version. - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword name: The name of the memory store. Required. - :paramtype name: str - :keyword definition: The memory store definition. Required. - :paramtype definition: ~azure.ai.projects.models.MemoryStoreDefinition - :keyword description: A human-readable description of the memory store. Default value is None. - :paramtype description: str - :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default - value is None. - :paramtype metadata: dict[str, str] - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :param name: Name of the model. Required. + :type name: str + :param version: Version of the model. Required. + :type version: str + :param pending_upload_request: The pending upload request request body. Is one of the following + types: ModelPendingUploadRequest, JSON, IO[bytes] Required. + :type pending_upload_request: ~azure.ai.projects.models.ModelPendingUploadRequest or JSON or + IO[bytes] + :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -13995,23 +18113,18 @@ def create( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) + cls: ClsType[_models.ModelPendingUploadResponse] = kwargs.pop("cls", None) - if body is _Unset: - if name is _Unset: - raise TypeError("missing required argument: name") - if definition is _Unset: - raise TypeError("missing required argument: definition") - body = {"definition": definition, "description": description, "metadata": metadata, "name": name} - body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(body, (IOBase, bytes)): - _content = body + if isinstance(pending_upload_request, (IOBase, bytes)): + _content = pending_upload_request else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_memory_stores_create_request( + _request = build_beta_models_pending_upload_request( + name=name, + version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -14038,16 +18151,12 @@ def create( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) + deserialized = _deserialize(_models.ModelPendingUploadResponse, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -14055,99 +18164,110 @@ def create( return deserialized # type: ignore @overload - def update( + def get_credentials( self, name: str, + version: str, + credential_request: _models.ModelCredentialRequest, *, content_type: str = "application/json", - description: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Update a memory store. + ) -> _models.DatasetCredential: + """Get model asset credentials. - Updates the specified memory store with the supplied configuration changes. + Retrieves temporary credentials for accessing the storage backing the specified model version. - :param name: The name of the memory store to update. Required. + :param name: Name of the model. Required. :type name: str + :param version: Version of the model. Required. + :type version: str + :param credential_request: The credential request request body. Required. + :type credential_request: ~azure.ai.projects.models.ModelCredentialRequest :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :keyword description: A human-readable description of the memory store. Default value is None. - :paramtype description: str - :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default - value is None. - :paramtype metadata: dict[str, str] - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Update a memory store. + def get_credentials( + self, + name: str, + version: str, + credential_request: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.DatasetCredential: + """Get model asset credentials. - Updates the specified memory store with the supplied configuration changes. + Retrieves temporary credentials for accessing the storage backing the specified model version. - :param name: The name of the memory store to update. Required. + :param name: Name of the model. Required. :type name: str - :param body: Required. - :type body: JSON + :param version: Version of the model. Required. + :type version: str + :param credential_request: The credential request request body. Required. + :type credential_request: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Update a memory store. + def get_credentials( + self, + name: str, + version: str, + credential_request: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.DatasetCredential: + """Get model asset credentials. - Updates the specified memory store with the supplied configuration changes. + Retrieves temporary credentials for accessing the storage backing the specified model version. - :param name: The name of the memory store to update. Required. + :param name: Name of the model. Required. :type name: str - :param body: Required. - :type body: IO[bytes] + :param version: Version of the model. Required. + :type version: str + :param credential_request: The credential request request body. Required. + :type credential_request: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def update( + def get_credentials( self, name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - description: Optional[str] = None, - metadata: Optional[dict[str, str]] = None, + version: str, + credential_request: Union[_models.ModelCredentialRequest, JSON, IO[bytes]], **kwargs: Any - ) -> _models.MemoryStoreDetails: - """Update a memory store. + ) -> _models.DatasetCredential: + """Get model asset credentials. - Updates the specified memory store with the supplied configuration changes. + Retrieves temporary credentials for accessing the storage backing the specified model version. - :param name: The name of the memory store to update. Required. + :param name: Name of the model. Required. :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword description: A human-readable description of the memory store. Default value is None. - :paramtype description: str - :keyword metadata: Arbitrary key-value metadata to associate with the memory store. Default - value is None. - :paramtype metadata: dict[str, str] - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :param version: Version of the model. Required. + :type version: str + :param credential_request: The credential request request body. Is one of the following types: + ModelCredentialRequest, JSON, IO[bytes] Required. + :type credential_request: ~azure.ai.projects.models.ModelCredentialRequest or JSON or IO[bytes] + :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DatasetCredential :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14162,20 +18282,18 @@ def update( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) + cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) - if body is _Unset: - body = {"description": description, "metadata": metadata} - body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(body, (IOBase, bytes)): - _content = body + if isinstance(credential_request, (IOBase, bytes)): + _content = credential_request else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(credential_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_memory_stores_update_request( + _request = build_beta_models_get_credentials_request( name=name, + version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -14202,32 +18320,46 @@ def update( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) + deserialized = _deserialize(_models.DatasetCredential, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + +class BetaRedTeamsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`red_teams` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @distributed_trace - def get(self, name: str, **kwargs: Any) -> _models.MemoryStoreDetails: - """Get a memory store. + def get(self, name: str, **kwargs: Any) -> _models.RedTeam: + """Get a redteam. - Retrieves the specified memory store and its current configuration. + Retrieves the specified redteam and its configuration. - :param name: The name of the memory store to retrieve. Required. + :param name: Identifier of the red team run. Required. :type name: str - :return: MemoryStoreDetails. The MemoryStoreDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDetails + :return: RedTeam. The RedTeam is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.RedTeam :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14241,9 +18373,9 @@ def get(self, name: str, **kwargs: Any) -> _models.MemoryStoreDetails: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.MemoryStoreDetails] = kwargs.pop("cls", None) + cls: ClsType[_models.RedTeam] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_get_request( + _request = build_beta_red_teams_get_request( name=name, api_version=self._config.api_version, headers=_headers, @@ -14269,16 +18401,12 @@ def get(self, name: str, **kwargs: Any) -> _models.MemoryStoreDetails: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryStoreDetails, response.json()) + deserialized = _deserialize(_models.RedTeam, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -14286,40 +18414,19 @@ def get(self, name: str, **kwargs: Any) -> _models.MemoryStoreDetails: return deserialized # type: ignore @distributed_trace - def list( - self, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> ItemPaged["_models.MemoryStoreDetails"]: - """List memory stores. + def list(self, **kwargs: Any) -> ItemPaged["_models.RedTeam"]: + """List redteams. - Returns the memory stores available to the caller. + Returns the redteams available in the current project. - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of MemoryStoreDetails - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.MemoryStoreDetails] + :return: An iterator like instance of RedTeam + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.RedTeam] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.MemoryStoreDetails]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.RedTeam]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -14329,35 +18436,58 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_red_teams_list_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _request = build_beta_memory_stores_list_request( - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.MemoryStoreDetails], - deserialized.get("data", []), + List[_models.RedTeam], + deserialized.get("value", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + return deserialized.get("nextLink") or None, iter(list_of_elem) - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + def get_next(next_link=None): + _request = prepare_request(next_link) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -14367,26 +18497,73 @@ def get_next(_continuation_token=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) return pipeline_response return ItemPaged(get_next, extract_data) + @overload + def create( + self, red_team: _models.RedTeam, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.RedTeam: + """Create a redteam run. + + Submits a new redteam run for execution with the provided configuration. + + :param red_team: Redteam to be run. Required. + :type red_team: ~azure.ai.projects.models.RedTeam + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: RedTeam. The RedTeam is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.RedTeam + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create(self, red_team: JSON, *, content_type: str = "application/json", **kwargs: Any) -> _models.RedTeam: + """Create a redteam run. + + Submits a new redteam run for execution with the provided configuration. + + :param red_team: Redteam to be run. Required. + :type red_team: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: RedTeam. The RedTeam is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.RedTeam + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create(self, red_team: IO[bytes], *, content_type: str = "application/json", **kwargs: Any) -> _models.RedTeam: + """Create a redteam run. + + Submits a new redteam run for execution with the provided configuration. + + :param red_team: Redteam to be run. Required. + :type red_team: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: RedTeam. The RedTeam is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.RedTeam + :raises ~azure.core.exceptions.HttpResponseError: + """ + @distributed_trace - def delete(self, name: str, **kwargs: Any) -> _models.DeleteMemoryStoreResult: - """Delete a memory store. + def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwargs: Any) -> _models.RedTeam: + """Create a redteam run. - Deletes the specified memory store. + Submits a new redteam run for execution with the provided configuration. - :param name: The name of the memory store to delete. Required. - :type name: str - :return: DeleteMemoryStoreResult. The DeleteMemoryStoreResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DeleteMemoryStoreResult + :param red_team: Redteam to be run. Is one of the following types: RedTeam, JSON, IO[bytes] + Required. + :type red_team: ~azure.ai.projects.models.RedTeam or JSON or IO[bytes] + :return: RedTeam. The RedTeam is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.RedTeam :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14397,14 +18574,23 @@ def delete(self, name: str, **kwargs: Any) -> _models.DeleteMemoryStoreResult: } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DeleteMemoryStoreResult] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RedTeam] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_delete_request( - name=name, + content_type = content_type or "application/json" + _content = None + if isinstance(red_team, (IOBase, bytes)): + _content = red_team + else: + _content = json.dumps(red_team, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_red_teams_create_request( + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -14421,7 +18607,7 @@ def delete(self, name: str, **kwargs: Any) -> _models.DeleteMemoryStoreResult: response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [201]: if _stream: try: response.read() # Load the body in memory and close the socket @@ -14437,66 +18623,145 @@ def delete(self, name: str, **kwargs: Any) -> _models.DeleteMemoryStoreResult: if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DeleteMemoryStoreResult, response.json()) + deserialized = _deserialize(_models.RedTeam, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + +class BetaRoutinesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`routines` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @overload - def _search_memories( + def create_or_update( self, - name: str, + routine_name: str, *, - scope: str, content_type: str = "application/json", - items: Optional[List[dict[str, Any]]] = None, - previous_search_id: Optional[str] = None, - options: Optional[_models.MemorySearchOptions] = None, + description: Optional[str] = None, + enabled: Optional[bool] = None, + triggers: Optional[dict[str, _models.RoutineTrigger]] = None, + action: Optional[_models.RoutineAction] = None, + authorization: Optional[_models.RoutineAuthorization] = None, **kwargs: Any - ) -> _models.MemoryStoreSearchResult: ... + ) -> _models.Routine: + """Create or update a routine. + + Creates a new routine or replaces an existing routine with the supplied definition. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :keyword description: A human-readable description of the routine. Default value is None. + :paramtype description: str + :keyword enabled: Whether the routine is enabled. Default value is None. + :paramtype enabled: bool + :keyword triggers: The triggers configured for the routine. In v1, exactly one trigger entry is + supported. Default value is None. + :paramtype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] + :keyword action: The action executed when the routine fires. Default value is None. + :paramtype action: ~azure.ai.projects.models.RoutineAction + :keyword authorization: Optional authorization configuration for dispatching a newly created + routine. Ignored when updating an existing routine. Default value is None. + :paramtype authorization: ~azure.ai.projects.models.RoutineAuthorization + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ + @overload - def _search_memories( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreSearchResult: ... + def create_or_update( + self, routine_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Routine: + """Create or update a routine. + + Creates a new routine or replaces an existing routine with the supplied definition. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ + @overload - def _search_memories( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreSearchResult: ... + def create_or_update( + self, routine_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Routine: + """Create or update a routine. + + Creates a new routine or replaces an existing routine with the supplied definition. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def _search_memories( + def create_or_update( self, - name: str, + routine_name: str, body: Union[JSON, IO[bytes]] = _Unset, *, - scope: str = _Unset, - items: Optional[List[dict[str, Any]]] = None, - previous_search_id: Optional[str] = None, - options: Optional[_models.MemorySearchOptions] = None, + description: Optional[str] = None, + enabled: Optional[bool] = None, + triggers: Optional[dict[str, _models.RoutineTrigger]] = None, + action: Optional[_models.RoutineAction] = None, + authorization: Optional[_models.RoutineAuthorization] = None, **kwargs: Any - ) -> _models.MemoryStoreSearchResult: - """Search memories. + ) -> _models.Routine: + """Create or update a routine. - Searches the specified memory store for memories relevant to the provided conversation context. + Creates a new routine or replaces an existing routine with the supplied definition. - :param name: The name of the memory store to search. Required. - :type name: str + :param routine_name: The unique name of the routine. Required. + :type routine_name: str :param body: Is either a JSON type or a IO[bytes] type. Required. :type body: JSON or IO[bytes] - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword items: Items for which to search for relevant memories. Default value is None. - :paramtype items: list[dict[str, any]] - :keyword previous_search_id: The unique ID of the previous search request, enabling incremental - memory search from where the last operation left off. Default value is None. - :paramtype previous_search_id: str - :keyword options: Memory search options. Default value is None. - :paramtype options: ~azure.ai.projects.models.MemorySearchOptions - :return: MemoryStoreSearchResult. The MemoryStoreSearchResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreSearchResult + :keyword description: A human-readable description of the routine. Default value is None. + :paramtype description: str + :keyword enabled: Whether the routine is enabled. Default value is None. + :paramtype enabled: bool + :keyword triggers: The triggers configured for the routine. In v1, exactly one trigger entry is + supported. Default value is None. + :paramtype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] + :keyword action: The action executed when the routine fires. Default value is None. + :paramtype action: ~azure.ai.projects.models.RoutineAction + :keyword authorization: Optional authorization configuration for dispatching a newly created + routine. Ignored when updating an existing routine. Default value is None. + :paramtype authorization: ~azure.ai.projects.models.RoutineAuthorization + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -14511,12 +18776,16 @@ def _search_memories( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryStoreSearchResult] = kwargs.pop("cls", None) + cls: ClsType[_models.Routine] = kwargs.pop("cls", None) if body is _Unset: - if scope is _Unset: - raise TypeError("missing required argument: scope") - body = {"items": items, "options": options, "previous_search_id": previous_search_id, "scope": scope} + body = { + "action": action, + "authorization": authorization, + "description": description, + "enabled": enabled, + "triggers": triggers, + } body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None @@ -14525,8 +18794,8 @@ def _search_memories( else: _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_memory_stores_search_memories_request( - name=name, + _request = build_beta_routines_create_or_update_request( + routine_name=routine_name, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -14562,24 +18831,25 @@ def _search_memories( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryStoreSearchResult, response.json()) + deserialized = _deserialize(_models.Routine, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - def _update_memories_initial( - self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - scope: str = _Unset, - items: Optional[List[dict[str, Any]]] = None, - previous_update_id: Optional[str] = None, - update_delay: Optional[int] = None, - **kwargs: Any - ) -> Iterator[bytes]: + @distributed_trace + def get(self, routine_name: str, **kwargs: Any) -> _models.Routine: + """Get a routine. + + Retrieves the specified routine and its current configuration. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -14588,34 +18858,14 @@ def _update_memories_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - - if body is _Unset: - if scope is _Unset: - raise TypeError("missing required argument: scope") - body = { - "items": items, - "previous_update_id": previous_update_id, - "scope": scope, - "update_delay": update_delay, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.Routine] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_update_memories_request( - name=name, - content_type=content_type, + _request = build_beta_routines_get_request( + routine_name=routine_name, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -14625,18 +18875,19 @@ def _update_memories_initial( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [202]: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -14644,222 +18895,182 @@ def _update_memories_initial( ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Routine, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - def _begin_update_memories( - self, - name: str, - *, - scope: str, - content_type: str = "application/json", - items: Optional[List[dict[str, Any]]] = None, - previous_update_id: Optional[str] = None, - update_delay: Optional[int] = None, - **kwargs: Any - ) -> LROPoller[_models.MemoryStoreUpdateCompletedResult]: ... - @overload - def _begin_update_memories( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.MemoryStoreUpdateCompletedResult]: ... - @overload - def _begin_update_memories( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.MemoryStoreUpdateCompletedResult]: ... - @distributed_trace - def _begin_update_memories( - self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - scope: str = _Unset, - items: Optional[List[dict[str, Any]]] = None, - previous_update_id: Optional[str] = None, - update_delay: Optional[int] = None, - **kwargs: Any - ) -> LROPoller[_models.MemoryStoreUpdateCompletedResult]: - """Update memories. + def enable(self, routine_name: str, **kwargs: Any) -> _models.Routine: + """Enable a routine. - Starts an update that writes conversation memories into the specified memory store. The - operation returns a long-running status location for polling the update result. + Enables the specified routine so it can be dispatched. - :param name: The name of the memory store to update. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword items: Conversation items to be stored in memory. Default value is None. - :paramtype items: list[dict[str, any]] - :keyword previous_update_id: The unique ID of the previous update request, enabling incremental - memory updates from where the last operation left off. Default value is None. - :paramtype previous_update_id: str - :keyword update_delay: Timeout period before processing the memory update in seconds. - If a new update request is received during this period, it will cancel the current request and - reset the timeout. - Set to 0 to immediately trigger the update without delay. - Defaults to 300 (5 minutes). Default value is None. - :paramtype update_delay: int - :return: An instance of LROPoller that returns MemoryStoreUpdateCompletedResult. The - MemoryStoreUpdateCompletedResult is compatible with MutableMapping - :rtype: - ~azure.core.polling.LROPoller[~azure.ai.projects.models.MemoryStoreUpdateCompletedResult] + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryStoreUpdateCompletedResult] = kwargs.pop("cls", None) - polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = self._update_memories_initial( - name=name, - body=body, - scope=scope, - items=items, - previous_update_id=previous_update_id, - update_delay=update_delay, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - raw_result.http_response.read() # type: ignore - kwargs.pop("error_map", None) + cls: ClsType[_models.Routine] = kwargs.pop("cls", None) - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Operation-Location"] = self._deserialize( - "str", response.headers.get("Operation-Location") + _request = build_beta_routines_enable_request( + routine_name=routine_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Routine, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def disable(self, routine_name: str, **kwargs: Any) -> _models.Routine: + """Disable a routine. + + Disables the specified routine so it no longer runs. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :return: Routine. The Routine is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Routine + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - deserialized = _deserialize(_models.MemoryStoreUpdateCompletedResult, response.json().get("result", {})) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + _request = build_beta_routines_disable_request( + routine_name=routine_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) path_format_arguments = { "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - if polling is True: - polling_method: PollingMethod = cast( - PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) - ) - elif polling is False: - polling_method = cast(PollingMethod, NoPolling()) - else: - polling_method = polling - if cont_token: - return LROPoller[_models.MemoryStoreUpdateCompletedResult].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return LROPoller[_models.MemoryStoreUpdateCompletedResult]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs ) - @overload - def delete_scope( - self, name: str, *, scope: str, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDeleteScopeResult: - """Delete memories by scope. - - Deletes all memories in the specified memory store that are associated with the provided scope. + response = pipeline_response.http_response - :param name: The name of the memory store. Required. - :type name: str - :keyword scope: The namespace that logically groups and isolates memories to delete, such as a - user ID. Required. - :paramtype scope: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult - :raises ~azure.core.exceptions.HttpResponseError: - """ + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - @overload - def delete_scope( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDeleteScopeResult: - """Delete memories by scope. + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Routine, response.json()) - Deletes all memories in the specified memory store that are associated with the provided scope. + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore - :param name: The name of the memory store. Required. - :type name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult - :raises ~azure.core.exceptions.HttpResponseError: - """ + return deserialized # type: ignore - @overload - def delete_scope( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryStoreDeleteScopeResult: - """Delete memories by scope. + @distributed_trace + def list( + self, + *, + limit: Optional[int] = None, + after: Optional[str] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + **kwargs: Any + ) -> ItemPaged["_models.Routine"]: + """List routines. - Deletes all memories in the specified memory store that are associated with the provided scope. + Returns the routines available in the current project. - :param name: The name of the memory store. Required. - :type name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult + :keyword limit: The maximum number of routines to return. Default value is None. + :paramtype limit: int + :keyword after: An opaque continuation token identifying where to resume the list. Prefer + following the ``next_link`` returned by the previous response, which embeds this value. Default + value is None. + :paramtype after: str + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :return: An iterator like instance of Routine + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Routine] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @distributed_trace - def delete_scope( - self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, scope: str = _Unset, **kwargs: Any - ) -> _models.MemoryStoreDeleteScopeResult: - """Delete memories by scope. - - Deletes all memories in the specified memory store that are associated with the provided scope. + cls: ClsType[List[_models.Routine]] = kwargs.pop("cls", None) - :param name: The name of the memory store. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword scope: The namespace that logically groups and isolates memories to delete, such as a - user ID. Required. - :paramtype scope: str - :return: MemoryStoreDeleteScopeResult. The MemoryStoreDeleteScopeResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.MemoryStoreDeleteScopeResult - :raises ~azure.core.exceptions.HttpResponseError: - """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -14868,29 +19079,108 @@ def delete_scope( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + def prepare_request(next_link=None): + if not next_link: - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryStoreDeleteScopeResult] = kwargs.pop("cls", None) + _request = build_beta_routines_list_request( + limit=limit, + after=after, + order=order, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - if body is _Unset: - if scope is _Unset: - raise TypeError("missing required argument: scope") - body = {"scope": scope} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Routine], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("next_link") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + def delete(self, routine_name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete a routine. + + Deletes the specified routine. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - _request = build_beta_memory_stores_delete_scope_request( - name=name, - content_type=content_type, + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_beta_routines_delete_request( + routine_name=routine_name, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -14899,20 +19189,14 @@ def delete_scope( } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -14920,118 +19204,220 @@ def delete_scope( ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.MemoryStoreDeleteScopeResult, response.json()) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, None, {}) # type: ignore - return deserialized # type: ignore + @distributed_trace + def list_runs( + self, + routine_name: str, + *, + filter: Optional[str] = None, + limit: Optional[int] = None, + after: Optional[str] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + **kwargs: Any + ) -> ItemPaged["_models.RoutineRun"]: + """List prior runs for a routine. + + Returns prior runs recorded for the specified routine. + + :param routine_name: The unique name of the routine. Required. + :type routine_name: str + :keyword filter: An optional MLflow search-runs filter expression applied within the routine's + experiment. Default value is None. + :paramtype filter: str + :keyword limit: The maximum number of runs to return. Default value is None. + :paramtype limit: int + :keyword after: An opaque continuation token identifying where to resume the list. Prefer + following the ``next_link`` returned by the previous response, which embeds this value. Default + value is None. + :paramtype after: str + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :return: An iterator like instance of RoutineRun + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.RoutineRun] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RoutineRun]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_routines_list_runs_request( + routine_name=routine_name, + filter=filter, + limit=limit, + after=after, + order=order, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.RoutineRun], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("next_link") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) @overload - def create_memory( + def dispatch( self, - name: str, + routine_name: str, *, - scope: str, - content: str, - kind: Union[str, _models.MemoryItemKind], content_type: str = "application/json", + payload: Optional[_models.RoutineDispatchPayload] = None, **kwargs: Any - ) -> _models.MemoryItem: - """Create a memory item. + ) -> _models.DispatchRoutineResult: + """Queue an asynchronous routine dispatch. - Creates a memory item in the specified memory store. + Queues an asynchronous dispatch for the specified routine. - :param name: The name of the memory store. Required. - :type name: str - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword content: The content of the memory. Required. - :paramtype content: str - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Required. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind + :param routine_name: The unique name of the routine. Required. + :type routine_name: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :keyword payload: A direct action-input override sent downstream when testing a routine. + Default value is None. + :paramtype payload: ~azure.ai.projects.models.RoutineDispatchPayload + :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DispatchRoutineResult :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create_memory( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryItem: - """Create a memory item. + def dispatch( + self, routine_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.DispatchRoutineResult: + """Queue an asynchronous routine dispatch. - Creates a memory item in the specified memory store. + Queues an asynchronous dispatch for the specified routine. - :param name: The name of the memory store. Required. - :type name: str + :param routine_name: The unique name of the routine. Required. + :type routine_name: str :param body: Required. :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DispatchRoutineResult :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create_memory( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryItem: - """Create a memory item. + def dispatch( + self, routine_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.DispatchRoutineResult: + """Queue an asynchronous routine dispatch. - Creates a memory item in the specified memory store. + Queues an asynchronous dispatch for the specified routine. - :param name: The name of the memory store. Required. - :type name: str + :param routine_name: The unique name of the routine. Required. + :type routine_name: str :param body: Required. :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DispatchRoutineResult :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def create_memory( + def dispatch( self, - name: str, + routine_name: str, body: Union[JSON, IO[bytes]] = _Unset, *, - scope: str = _Unset, - content: str = _Unset, - kind: Union[str, _models.MemoryItemKind] = _Unset, + payload: Optional[_models.RoutineDispatchPayload] = None, **kwargs: Any - ) -> _models.MemoryItem: - """Create a memory item. + ) -> _models.DispatchRoutineResult: + """Queue an asynchronous routine dispatch. - Creates a memory item in the specified memory store. + Queues an asynchronous dispatch for the specified routine. - :param name: The name of the memory store. Required. - :type name: str + :param routine_name: The unique name of the routine. Required. + :type routine_name: str :param body: Is either a JSON type or a IO[bytes] type. Required. :type body: JSON or IO[bytes] - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword content: The content of the memory. Required. - :paramtype content: str - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Required. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :keyword payload: A direct action-input override sent downstream when testing a routine. + Default value is None. + :paramtype payload: ~azure.ai.projects.models.RoutineDispatchPayload + :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DispatchRoutineResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -15046,16 +19432,10 @@ def create_memory( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) + cls: ClsType[_models.DispatchRoutineResult] = kwargs.pop("cls", None) if body is _Unset: - if scope is _Unset: - raise TypeError("missing required argument: scope") - if content is _Unset: - raise TypeError("missing required argument: content") - if kind is _Unset: - raise TypeError("missing required argument: kind") - body = {"content": content, "kind": kind, "scope": scope} + body = {"payload": payload} body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None @@ -15064,8 +19444,8 @@ def create_memory( else: _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_memory_stores_create_memory_request( - name=name, + _request = build_beta_routines_dispatch_request( + routine_name=routine_name, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -15101,97 +19481,322 @@ def create_memory( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryItem, response.json()) + deserialized = _deserialize(_models.DispatchRoutineResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + +class BetaSchedulesOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`schedules` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def delete(self, schedule_id: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements + """Delete a schedule. + + Deletes the specified schedule resource. + + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :return: None + :rtype: None + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_beta_schedules_delete_request( + schedule_id=schedule_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace + def get(self, schedule_id: str, **kwargs: Any) -> _models.Schedule: + """Get a schedule. + + Retrieves the specified schedule resource. + + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :return: Schedule. The Schedule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Schedule + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.Schedule] = kwargs.pop("cls", None) + + _request = build_beta_schedules_get_request( + schedule_id=schedule_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.Schedule, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore + @distributed_trace + def list( + self, + *, + type: Optional[Union[str, _models.ScheduleTaskType]] = None, + enabled: Optional[bool] = None, + **kwargs: Any + ) -> ItemPaged["_models.Schedule"]: + """List schedules. + + Returns schedules that match the supplied type and enabled filters. + + :keyword type: Filter by the type of schedule. Known values are: "Evaluation" and "Insight". + Default value is None. + :paramtype type: str or ~azure.ai.projects.models.ScheduleTaskType + :keyword enabled: Filter by the enabled status. Default value is None. + :paramtype enabled: bool + :return: An iterator like instance of Schedule + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Schedule] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.Schedule]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_schedules_list_request( + type=type, + enabled=enabled, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.Schedule], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + @overload - def update_memory( - self, name: str, memory_id: str, *, content: str, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryItem: - """Update a memory item. + def create_or_update( + self, schedule_id: str, schedule: _models.Schedule, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Schedule: + """Create or update a schedule. - Updates the specified memory item in the memory store. + Creates a new schedule or updates an existing schedule with the supplied definition. - :param name: The name of the memory store. Required. - :type name: str - :param memory_id: The ID of the memory item to update. Required. - :type memory_id: str - :keyword content: The updated content of the memory. Required. - :paramtype content: str + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :param schedule: The resource instance. Required. + :type schedule: ~azure.ai.projects.models.Schedule :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :return: Schedule. The Schedule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Schedule :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update_memory( - self, name: str, memory_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryItem: - """Update a memory item. + def create_or_update( + self, schedule_id: str, schedule: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Schedule: + """Create or update a schedule. - Updates the specified memory item in the memory store. + Creates a new schedule or updates an existing schedule with the supplied definition. - :param name: The name of the memory store. Required. - :type name: str - :param memory_id: The ID of the memory item to update. Required. - :type memory_id: str - :param body: Required. - :type body: JSON + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :param schedule: The resource instance. Required. + :type schedule: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :return: Schedule. The Schedule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Schedule :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def update_memory( - self, name: str, memory_id: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.MemoryItem: - """Update a memory item. + def create_or_update( + self, schedule_id: str, schedule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Schedule: + """Create or update a schedule. - Updates the specified memory item in the memory store. + Creates a new schedule or updates an existing schedule with the supplied definition. - :param name: The name of the memory store. Required. - :type name: str - :param memory_id: The ID of the memory item to update. Required. - :type memory_id: str - :param body: Required. - :type body: IO[bytes] + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :param schedule: The resource instance. Required. + :type schedule: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :return: Schedule. The Schedule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Schedule :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def update_memory( - self, name: str, memory_id: str, body: Union[JSON, IO[bytes]] = _Unset, *, content: str = _Unset, **kwargs: Any - ) -> _models.MemoryItem: - """Update a memory item. + def create_or_update( + self, schedule_id: str, schedule: Union[_models.Schedule, JSON, IO[bytes]], **kwargs: Any + ) -> _models.Schedule: + """Create or update a schedule. - Updates the specified memory item in the memory store. + Creates a new schedule or updates an existing schedule with the supplied definition. - :param name: The name of the memory store. Required. - :type name: str - :param memory_id: The ID of the memory item to update. Required. - :type memory_id: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword content: The updated content of the memory. Required. - :paramtype content: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :param schedule: The resource instance. Is one of the following types: Schedule, JSON, + IO[bytes] Required. + :type schedule: ~azure.ai.projects.models.Schedule or JSON or IO[bytes] + :return: Schedule. The Schedule is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.Schedule :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -15206,23 +19811,17 @@ def update_memory( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) + cls: ClsType[_models.Schedule] = kwargs.pop("cls", None) - if body is _Unset: - if content is _Unset: - raise TypeError("missing required argument: content") - body = {"content": content} - body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(body, (IOBase, bytes)): - _content = body + if isinstance(schedule, (IOBase, bytes)): + _content = schedule else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(schedule, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_memory_stores_update_memory_request( - name=name, - memory_id=memory_id, + _request = build_beta_schedules_create_or_update_request( + schedule_id=schedule_id, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -15242,23 +19841,19 @@ def update_memory( response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [200, 201]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.MemoryItem, response.json()) + deserialized = _deserialize(_models.Schedule, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -15266,264 +19861,103 @@ def update_memory( return deserialized # type: ignore @distributed_trace - def get_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models.MemoryItem: - """Get a memory item. - - Retrieves the specified memory item from the memory store. - - :param name: The name of the memory store. Required. - :type name: str - :param memory_id: The ID of the memory item to retrieve. Required. - :type memory_id: str - :return: MemoryItem. The MemoryItem is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.MemoryItem - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models.MemoryItem] = kwargs.pop("cls", None) - - _request = build_beta_memory_stores_get_memory_request( - name=name, - memory_id=memory_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.MemoryItem, response.json()) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - @overload - def list_memories( - self, - name: str, - *, - scope: str, - kind: Optional[Union[str, _models.MemoryItemKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> ItemPaged["_models.MemoryItem"]: - """List memory items. - - Returns memory items from the specified memory store. - - :param name: The name of the memory store. Required. - :type name: str - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Default value is None. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: An iterator like instance of MemoryItem - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.MemoryItem] - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def list_memories( - self, - name: str, - body: JSON, - *, - kind: Optional[Union[str, _models.MemoryItemKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> ItemPaged["_models.MemoryItem"]: - """List memory items. + def get_run(self, schedule_id: str, run_id: str, **kwargs: Any) -> _models.ScheduleRun: + """Get a schedule run. - Returns memory items from the specified memory store. + Retrieves the specified run for a schedule. - :param name: The name of the memory store. Required. - :type name: str - :param body: Required. - :type body: JSON - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Default value is None. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: An iterator like instance of MemoryItem - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.MemoryItem] + :param schedule_id: The unique identifier of the schedule. Required. + :type schedule_id: str + :param run_id: The unique identifier of the schedule run. Required. + :type run_id: str + :return: ScheduleRun. The ScheduleRun is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.ScheduleRun :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - @overload - def list_memories( - self, - name: str, - body: IO[bytes], - *, - kind: Optional[Union[str, _models.MemoryItemKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> ItemPaged["_models.MemoryItem"]: - """List memory items. + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - Returns memory items from the specified memory store. + cls: ClsType[_models.ScheduleRun] = kwargs.pop("cls", None) - :param name: The name of the memory store. Required. - :type name: str - :param body: Required. - :type body: IO[bytes] - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Default value is None. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: An iterator like instance of MemoryItem - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.MemoryItem] - :raises ~azure.core.exceptions.HttpResponseError: - """ + _request = build_beta_schedules_get_run_request( + schedule_id=schedule_id, + run_id=run_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.ScheduleRun, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace - def list_memories( + def list_runs( self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, + schedule_id: str, *, - scope: str = _Unset, - kind: Optional[Union[str, _models.MemoryItemKind]] = None, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, + type: Optional[Union[str, _models.ScheduleTaskType]] = None, + enabled: Optional[bool] = None, **kwargs: Any - ) -> ItemPaged["_models.MemoryItem"]: - """List memory items. + ) -> ItemPaged["_models.ScheduleRun"]: + """List schedule runs. - Returns memory items from the specified memory store. + Returns schedule runs that match the supplied filters. - :param name: The name of the memory store. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword scope: The namespace that logically groups and isolates memories, such as a user ID. - Required. - :paramtype scope: str - :keyword kind: The kind of the memory item. Known values are: "user_profile", "chat_summary", - and "procedural". Default value is None. - :paramtype kind: str or ~azure.ai.projects.models.MemoryItemKind - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. + :param schedule_id: Identifier of the schedule. Required. + :type schedule_id: str + :keyword type: Filter by the type of schedule. Known values are: "Evaluation" and "Insight". Default value is None. - :paramtype before: str - :return: An iterator like instance of MemoryItem - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.MemoryItem] + :paramtype type: str or ~azure.ai.projects.models.ScheduleTaskType + :keyword enabled: Filter by the enabled status. Default value is None. + :paramtype enabled: bool + :return: An iterator like instance of ScheduleRun + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.ScheduleRun] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[List[_models.MemoryItem]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.ScheduleRun]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -15532,51 +19966,62 @@ def list_memories( 304: ResourceNotModifiedError, } error_map.update(kwargs.pop("error_map", {}) or {}) - if body is _Unset: - if scope is _Unset: - raise TypeError("missing required argument: scope") - body = {"scope": scope} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - def prepare_request(_continuation_token=None): + def prepare_request(next_link=None): + if not next_link: + + _request = build_beta_schedules_list_runs_request( + schedule_id=schedule_id, + type=type, + enabled=enabled, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.endpoint", self._config.endpoint, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _request = build_beta_memory_stores_list_memories_request( - name=name, - kind=kind, - limit=limit, - order=order, - after=_continuation_token, - before=before, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.MemoryItem], - deserialized.get("data", []), + list_of_elem = _deserialize( + List[_models.ScheduleRun], + deserialized.get("value", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + return deserialized.get("nextLink") or None, iter(list_of_elem) - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + def get_next(next_link=None): + _request = prepare_request(next_link) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -15586,28 +20031,40 @@ def get_next(_continuation_token=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response) return pipeline_response return ItemPaged(get_next, extract_data) + +class BetaSkillsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`skills` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @distributed_trace - def delete_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models.DeleteMemoryResult: - """Delete a memory item. + def get(self, name: str, **kwargs: Any) -> _models.SkillDetails: + """Retrieve a skill. - Deletes the specified memory item from the memory store. + Retrieves the specified skill and its current configuration. - :param name: The name of the memory store. Required. + :param name: The unique name of the skill. Required. :type name: str - :param memory_id: The ID of the memory item to delete. Required. - :type memory_id: str - :return: DeleteMemoryResult. The DeleteMemoryResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DeleteMemoryResult + :return: SkillDetails. The SkillDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -15621,11 +20078,10 @@ def delete_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models.Del _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DeleteMemoryResult] = kwargs.pop("cls", None) + cls: ClsType[_models.SkillDetails] = kwargs.pop("cls", None) - _request = build_beta_memory_stores_delete_memory_request( + _request = build_beta_skills_get_request( name=name, - memory_id=memory_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -15659,47 +20115,48 @@ def delete_memory(self, name: str, memory_id: str, **kwargs: Any) -> _models.Del if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DeleteMemoryResult, response.json()) + deserialized = _deserialize(_models.SkillDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - -class BetaModelsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`models` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace - def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.ModelVersion"]: - """List versions. + def list( + self, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.SkillDetails"]: + """List skills. - List all versions of the given ModelVersion. + Returns the skills available in the current project. - :param name: The name of the resource. Required. - :type name: str - :return: An iterator like instance of ModelVersion - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.ModelVersion] + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of SkillDetails + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.SkillDetails] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.ModelVersion]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.SkillDetails]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -15709,59 +20166,35 @@ def list_versions(self, name: str, **kwargs: Any) -> ItemPaged["_models.ModelVer } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_models_list_versions_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + def prepare_request(_continuation_token=None): + _request = build_beta_skills_list_request( + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.ModelVersion], - deserialized.get("value", []), + List[_models.SkillDetails], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + return deserialized.get("last_id") or None, iter(list_of_elem) - def get_next(next_link=None): - _request = prepare_request(next_link) + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -15771,114 +20204,94 @@ def get_next(next_link=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) return pipeline_response return ItemPaged(get_next, extract_data) - @distributed_trace - def list(self, **kwargs: Any) -> ItemPaged["_models.ModelVersion"]: - """List latest versions. - - List the latest version of each ModelVersion. - - :return: An iterator like instance of ModelVersion - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.ModelVersion] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.ModelVersion]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_models_list_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + @overload + def update( + self, name: str, *, default_version: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.SkillDetails: + """Update a skill. - return _request + Modifies the specified skill's configuration. - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.ModelVersion], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + :param name: The name of the skill to update. Required. + :type name: str + :keyword default_version: The version identifier that the skill should point to. When set, the + skill's default version will resolve to this version instead of the latest. Required. + :paramtype default_version: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: SkillDetails. The SkillDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ - def get_next(next_link=None): - _request = prepare_request(next_link) + @overload + def update( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.SkillDetails: + """Update a skill. - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + Modifies the specified skill's configuration. - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + :param name: The name of the skill to update. Required. + :type name: str + :param body: Required. + :type body: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: SkillDetails. The SkillDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ - return pipeline_response + @overload + def update( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.SkillDetails: + """Update a skill. - return ItemPaged(get_next, extract_data) + Modifies the specified skill's configuration. + + :param name: The name of the skill to update. Required. + :type name: str + :param body: Required. + :type body: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: SkillDetails. The SkillDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillDetails + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def get(self, name: str, version: str, **kwargs: Any) -> _models.ModelVersion: - """Get a model version. + def update( + self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, default_version: str = _Unset, **kwargs: Any + ) -> _models.SkillDetails: + """Update a skill. - Retrieves the specified model version, returning 404 if it does not exist. + Modifies the specified skill's configuration. - :param name: The name of the resource. Required. + :param name: The name of the skill to update. Required. :type name: str - :param version: The specific version id of the ModelVersion to retrieve. Required. - :type version: str - :return: ModelVersion. The ModelVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ModelVersion + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword default_version: The version identifier that the skill should point to. When set, the + skill's default version will resolve to this version instead of the latest. Required. + :paramtype default_version: str + :return: SkillDetails. The SkillDetails is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillDetails :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -15889,15 +20302,29 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.ModelVersion: } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.ModelVersion] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.SkillDetails] = kwargs.pop("cls", None) - _request = build_beta_models_get_request( + if body is _Unset: + if default_version is _Unset: + raise TypeError("missing required argument: default_version") + body = {"default_version": default_version} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_skills_update_request( name=name, - version=version, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -15921,12 +20348,16 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.ModelVersion: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.ModelVersion, response.json()) + deserialized = _deserialize(_models.SkillDetails, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -15934,168 +20365,15 @@ def get(self, name: str, version: str, **kwargs: Any) -> _models.ModelVersion: return deserialized # type: ignore @distributed_trace - def delete(self, name: str, version: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete a model version. - - Removes the specified model version. Returns 200 whether the version existed or not. - - :param name: The name of the resource. Required. - :type name: str - :param version: The version of the ModelVersion to delete. Required. - :type version: str - :return: None - :rtype: None - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[None] = kwargs.pop("cls", None) - - _request = build_beta_models_delete_request( - name=name, - version=version, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if cls: - return cls(pipeline_response, None, {}) # type: ignore - - @overload - def update( - self, - name: str, - version: str, - model_version_update: _models.UpdateModelVersionRequest, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.ModelVersion: - """Update a model version. - - Updates an existing model version identified by its version ID. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the UpdateModelVersionRequest to create or update. - Required. - :type version: str - :param model_version_update: The UpdateModelVersionRequest to create or update. Required. - :type model_version_update: ~azure.ai.projects.models.UpdateModelVersionRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: ModelVersion. The ModelVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ModelVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def update( - self, - name: str, - version: str, - model_version_update: JSON, - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.ModelVersion: - """Update a model version. - - Updates an existing model version identified by its version ID. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the UpdateModelVersionRequest to create or update. - Required. - :type version: str - :param model_version_update: The UpdateModelVersionRequest to create or update. Required. - :type model_version_update: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: ModelVersion. The ModelVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ModelVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def update( - self, - name: str, - version: str, - model_version_update: IO[bytes], - *, - content_type: str = "application/merge-patch+json", - **kwargs: Any - ) -> _models.ModelVersion: - """Update a model version. - - Updates an existing model version identified by its version ID. - - :param name: The name of the resource. Required. - :type name: str - :param version: The specific version id of the UpdateModelVersionRequest to create or update. - Required. - :type version: str - :param model_version_update: The UpdateModelVersionRequest to create or update. Required. - :type model_version_update: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/merge-patch+json". - :paramtype content_type: str - :return: ModelVersion. The ModelVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ModelVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @distributed_trace - def update( - self, - name: str, - version: str, - model_version_update: Union[_models.UpdateModelVersionRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.ModelVersion: - """Update a model version. + def delete(self, name: str, **kwargs: Any) -> _models.DeleteSkillResult: + """Delete a skill. - Updates an existing model version identified by its version ID. + Removes the specified skill and its associated versions. - :param name: The name of the resource. Required. + :param name: The unique name of the skill. Required. :type name: str - :param version: The specific version id of the UpdateModelVersionRequest to create or update. - Required. - :type version: str - :param model_version_update: The UpdateModelVersionRequest to create or update. Is one of the - following types: UpdateModelVersionRequest, JSON, IO[bytes] Required. - :type model_version_update: ~azure.ai.projects.models.UpdateModelVersionRequest or JSON or - IO[bytes] - :return: ModelVersion. The ModelVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ModelVersion + :return: DeleteSkillResult. The DeleteSkillResult is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DeleteSkillResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -16106,25 +20384,14 @@ def update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.ModelVersion] = kwargs.pop("cls", None) - - content_type = content_type or "application/merge-patch+json" - _content = None - if isinstance(model_version_update, (IOBase, bytes)): - _content = model_version_update - else: - _content = json.dumps(model_version_update, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.DeleteSkillResult] = kwargs.pop("cls", None) - _request = build_beta_models_update_request( + _request = build_beta_skills_delete_request( name=name, - version=version, - content_type=content_type, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -16141,19 +20408,23 @@ def update( response = pipeline_response.http_response - if response.status_code not in [200, 201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.ModelVersion, response.json()) + deserialized = _deserialize(_models.DeleteSkillResult, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -16161,104 +20432,99 @@ def update( return deserialized # type: ignore @overload - def pending_create_version( + def create( self, name: str, - version: str, - model_version: _models.ModelVersion, *, content_type: str = "application/json", + inline_content: Optional[_models.SkillInlineContent] = None, + default: Optional[bool] = None, **kwargs: Any - ) -> _models.CreateAsyncResponse: - """Create a model version async. + ) -> _models.SkillVersion: + """Create a new version of a skill. - Creates a model version asynchronously with blob content validation. Returns 202 Accepted with - a location header for polling the operation status. + Creates a new version of a skill. If the skill does not exist, it will be created. - :param name: Name of the model. Required. + :param name: The name of the skill. If the skill does not exist, it will be created. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param model_version: Model version to create. Required. - :type model_version: ~azure.ai.projects.models.ModelVersion :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :keyword inline_content: Inline skill content for simple skills without file uploads. + Foundry-specific extension. Default value is None. + :paramtype inline_content: ~azure.ai.projects.models.SkillInlineContent + :keyword default: Whether to set this version as the default. Default value is None. + :paramtype default: bool + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def pending_create_version( - self, name: str, version: str, model_version: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.CreateAsyncResponse: - """Create a model version async. + def create( + self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.SkillVersion: + """Create a new version of a skill. - Creates a model version asynchronously with blob content validation. Returns 202 Accepted with - a location header for polling the operation status. + Creates a new version of a skill. If the skill does not exist, it will be created. - :param name: Name of the model. Required. + :param name: The name of the skill. If the skill does not exist, it will be created. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param model_version: Model version to create. Required. - :type model_version: JSON + :param body: Required. + :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def pending_create_version( - self, - name: str, - version: str, - model_version: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.CreateAsyncResponse: - """Create a model version async. + def create( + self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.SkillVersion: + """Create a new version of a skill. - Creates a model version asynchronously with blob content validation. Returns 202 Accepted with - a location header for polling the operation status. + Creates a new version of a skill. If the skill does not exist, it will be created. - :param name: Name of the model. Required. + :param name: The name of the skill. If the skill does not exist, it will be created. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param model_version: Model version to create. Required. - :type model_version: IO[bytes] + :param body: Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def pending_create_version( - self, name: str, version: str, model_version: Union[_models.ModelVersion, JSON, IO[bytes]], **kwargs: Any - ) -> _models.CreateAsyncResponse: - """Create a model version async. + def create( + self, + name: str, + body: Union[JSON, IO[bytes]] = _Unset, + *, + inline_content: Optional[_models.SkillInlineContent] = None, + default: Optional[bool] = None, + **kwargs: Any + ) -> _models.SkillVersion: + """Create a new version of a skill. - Creates a model version asynchronously with blob content validation. Returns 202 Accepted with - a location header for polling the operation status. + Creates a new version of a skill. If the skill does not exist, it will be created. - :param name: Name of the model. Required. + :param name: The name of the skill. If the skill does not exist, it will be created. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param model_version: Model version to create. Is one of the following types: ModelVersion, - JSON, IO[bytes] Required. - :type model_version: ~azure.ai.projects.models.ModelVersion or JSON or IO[bytes] - :return: CreateAsyncResponse. The CreateAsyncResponse is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.CreateAsyncResponse + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword inline_content: Inline skill content for simple skills without file uploads. + Foundry-specific extension. Default value is None. + :paramtype inline_content: ~azure.ai.projects.models.SkillInlineContent + :keyword default: Whether to set this version as the default. Default value is None. + :paramtype default: bool + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -16273,18 +20539,20 @@ def pending_create_version( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.CreateAsyncResponse] = kwargs.pop("cls", None) + cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) + if body is _Unset: + body = {"default": default, "inline_content": inline_content} + body = {k: v for k, v in body.items() if v is not None} content_type = content_type or "application/json" _content = None - if isinstance(model_version, (IOBase, bytes)): - _content = model_version + if isinstance(body, (IOBase, bytes)): + _content = body else: - _content = json.dumps(model_version, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_models_pending_create_version_request( + _request = build_beta_skills_create_request( name=name, - version=version, content_type=content_type, api_version=self._config.api_version, content=_content, @@ -16304,138 +20572,76 @@ def pending_create_version( response = pipeline_response.http_response - if response.status_code not in [202]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - response_headers = {} - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.CreateAsyncResponse, response.json()) + deserialized = _deserialize(_models.SkillVersion, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @overload - def pending_upload( - self, - name: str, - version: str, - pending_upload_request: _models.ModelPendingUploadRequest, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.ModelPendingUploadResponse: - """Start a pending upload. - - Initiates a new pending upload or retrieves an existing one for the specified model version. - - :param name: Name of the model. Required. - :type name: str - :param version: Version of the model. Required. - :type version: str - :param pending_upload_request: The pending upload request request body. Required. - :type pending_upload_request: ~azure.ai.projects.models.ModelPendingUploadRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def pending_upload( - self, - name: str, - version: str, - pending_upload_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.ModelPendingUploadResponse: - """Start a pending upload. + def create_from_files( + self, name: str, content: _models.CreateSkillVersionFromFilesBody, **kwargs: Any + ) -> _models.SkillVersion: + """Create a skill version from uploaded files. - Initiates a new pending upload or retrieves an existing one for the specified model version. + Creates a new version of a skill from uploaded files via multipart form data. - :param name: Name of the model. Required. + :param name: The name of the skill. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param pending_upload_request: The pending upload request request body. Required. - :type pending_upload_request: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def pending_upload( - self, - name: str, - version: str, - pending_upload_request: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.ModelPendingUploadResponse: - """Start a pending upload. + :param content: The multipart request content. Required. + :type content: ~azure.ai.projects.models.CreateSkillVersionFromFilesBody + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion + :raises ~azure.core.exceptions.HttpResponseError: + """ - Initiates a new pending upload or retrieves an existing one for the specified model version. + @overload + def create_from_files(self, name: str, content: JSON, **kwargs: Any) -> _models.SkillVersion: + """Create a skill version from uploaded files. - :param name: Name of the model. Required. + Creates a new version of a skill from uploaded files via multipart form data. + + :param name: The name of the skill. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param pending_upload_request: The pending upload request request body. Required. - :type pending_upload_request: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse + :param content: The multipart request content. Required. + :type content: JSON + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def pending_upload( - self, - name: str, - version: str, - pending_upload_request: Union[_models.ModelPendingUploadRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.ModelPendingUploadResponse: - """Start a pending upload. + def create_from_files( + self, name: str, content: Union[_models.CreateSkillVersionFromFilesBody, JSON], **kwargs: Any + ) -> _models.SkillVersion: + """Create a skill version from uploaded files. - Initiates a new pending upload or retrieves an existing one for the specified model version. + Creates a new version of a skill from uploaded files via multipart form data. - :param name: Name of the model. Required. + :param name: The name of the skill. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param pending_upload_request: The pending upload request request body. Is one of the following - types: ModelPendingUploadRequest, JSON, IO[bytes] Required. - :type pending_upload_request: ~azure.ai.projects.models.ModelPendingUploadRequest or JSON or - IO[bytes] - :return: ModelPendingUploadResponse. The ModelPendingUploadResponse is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.ModelPendingUploadResponse + :param content: The multipart request content. Is either a CreateSkillVersionFromFilesBody type + or a JSON type. Required. + :type content: ~azure.ai.projects.models.CreateSkillVersionFromFilesBody or JSON + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -16446,25 +20652,20 @@ def pending_upload( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.ModelPendingUploadResponse] = kwargs.pop("cls", None) + cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) - content_type = content_type or "application/json" - _content = None - if isinstance(pending_upload_request, (IOBase, bytes)): - _content = pending_upload_request - else: - _content = json.dumps(pending_upload_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _body = content.as_dict() if isinstance(content, _Model) else content + _file_fields: list[str] = ["files"] + _data_fields: list[str] = ["default"] + _files = prepare_multipart_form_data(_body, _file_fields, _data_fields) - _request = build_beta_models_pending_upload_request( + _request = build_beta_skills_create_from_files_request( name=name, - version=version, - content_type=content_type, api_version=self._config.api_version, - content=_content, + files=_files, headers=_headers, params=_params, ) @@ -16488,123 +20689,130 @@ def pending_upload( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.ModelPendingUploadResponse, response.json()) + deserialized = _deserialize(_models.SkillVersion, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - def get_credentials( + @distributed_trace + def list_versions( self, name: str, - version: str, - credential_request: _models.ModelCredentialRequest, *, - content_type: str = "application/json", + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> _models.DatasetCredential: - """Get model asset credentials. + ) -> ItemPaged["_models.SkillVersion"]: + """List skill versions. - Retrieves temporary credentials for accessing the storage backing the specified model version. + Returns the available versions for the specified skill. - :param name: Name of the model. Required. + :param name: The name of the skill to list versions for. Required. :type name: str - :param version: Version of the model. Required. - :type version: str - :param credential_request: The credential request request body. Required. - :type credential_request: ~azure.ai.projects.models.ModelCredentialRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of SkillVersion + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.SkillVersion] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @overload - def get_credentials( - self, - name: str, - version: str, - credential_request: JSON, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.DatasetCredential: - """Get model asset credentials. + cls: ClsType[List[_models.SkillVersion]] = kwargs.pop("cls", None) - Retrieves temporary credentials for accessing the storage backing the specified model version. + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - :param name: Name of the model. Required. - :type name: str - :param version: Version of the model. Required. - :type version: str - :param credential_request: The credential request request body. Required. - :type credential_request: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential - :raises ~azure.core.exceptions.HttpResponseError: - """ + def prepare_request(_continuation_token=None): - @overload - def get_credentials( - self, - name: str, - version: str, - credential_request: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.DatasetCredential: - """Get model asset credentials. + _request = build_beta_skills_list_versions_request( + name=name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - Retrieves temporary credentials for accessing the storage backing the specified model version. + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.SkillVersion], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) - :param name: Name of the model. Required. - :type name: str - :param version: Version of the model. Required. - :type version: str - :param credential_request: The credential request request body. Required. - :type credential_request: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential - :raises ~azure.core.exceptions.HttpResponseError: - """ + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) @distributed_trace - def get_credentials( - self, - name: str, - version: str, - credential_request: Union[_models.ModelCredentialRequest, JSON, IO[bytes]], - **kwargs: Any - ) -> _models.DatasetCredential: - """Get model asset credentials. + def get_version(self, name: str, version: str, **kwargs: Any) -> _models.SkillVersion: + """Retrieve a specific version of a skill. - Retrieves temporary credentials for accessing the storage backing the specified model version. + Retrieves the specified version of a skill by name and version identifier. - :param name: Name of the model. Required. - :type name: str - :param version: Version of the model. Required. - :type version: str - :param credential_request: The credential request request body. Is one of the following types: - ModelCredentialRequest, JSON, IO[bytes] Required. - :type credential_request: ~azure.ai.projects.models.ModelCredentialRequest or JSON or IO[bytes] - :return: DatasetCredential. The DatasetCredential is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DatasetCredential + :param name: The name of the skill. Required. + :type name: str + :param version: The version identifier to retrieve. Required. + :type version: str + :return: SkillVersion. The SkillVersion is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.SkillVersion :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -16615,25 +20823,15 @@ def get_credentials( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DatasetCredential] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(credential_request, (IOBase, bytes)): - _content = credential_request - else: - _content = json.dumps(credential_request, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) - _request = build_beta_models_get_credentials_request( + _request = build_beta_skills_get_version_request( name=name, version=version, - content_type=content_type, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -16657,46 +20855,32 @@ def get_credentials( except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DatasetCredential, response.json()) + deserialized = _deserialize(_models.SkillVersion, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - -class BetaRedTeamsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`red_teams` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace - def get(self, name: str, **kwargs: Any) -> _models.RedTeam: - """Get a redteam. + def download(self, name: str, **kwargs: Any) -> Iterator[bytes]: + """Download the zip content for the default version of a skill. - Retrieves the specified redteam and its configuration. + Downloads the zip content for the default version of a skill. - :param name: Identifier of the red team run. Required. + :param name: The name of the skill. Required. :type name: str - :return: RedTeam. The RedTeam is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.RedTeam + :return: Iterator[bytes] + :rtype: Iterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -16710,9 +20894,9 @@ def get(self, name: str, **kwargs: Any) -> _models.RedTeam: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.RedTeam] = kwargs.pop("cls", None) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_beta_red_teams_get_request( + _request = build_beta_skills_download_request( name=name, api_version=self._config.api_version, headers=_headers, @@ -16724,7 +20908,7 @@ def get(self, name: str, **kwargs: Any) -> _models.RedTeam: _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -16738,33 +20922,36 @@ def get(self, name: str, **kwargs: Any) -> _models.RedTeam: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.RedTeam, response.json()) + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace - def list(self, **kwargs: Any) -> ItemPaged["_models.RedTeam"]: - """List redteams. + def download_version(self, name: str, version: str, **kwargs: Any) -> Iterator[bytes]: + """Download the zip content for a specific version of a skill. - Returns the redteams available in the current project. + Downloads the zip content for a specific version of a skill. - :return: An iterator like instance of RedTeam - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.RedTeam] + :param name: The name of the skill. Required. + :type name: str + :param version: The version to download content for. Required. + :type version: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.RedTeam]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -16773,134 +20960,67 @@ def list(self, **kwargs: Any) -> ItemPaged["_models.RedTeam"]: } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_red_teams_list_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - return _request + _request = build_beta_skills_download_version_request( + name=name, + version=version, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.RedTeam], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - def get_next(next_link=None): - _request = prepare_request(next_link) + response = pipeline_response.http_response - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - return pipeline_response - - return ItemPaged(get_next, extract_data) - - @overload - def create( - self, red_team: _models.RedTeam, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RedTeam: - """Create a redteam run. - - Submits a new redteam run for execution with the provided configuration. - - :param red_team: Redteam to be run. Required. - :type red_team: ~azure.ai.projects.models.RedTeam - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RedTeam. The RedTeam is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.RedTeam - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create(self, red_team: JSON, *, content_type: str = "application/json", **kwargs: Any) -> _models.RedTeam: - """Create a redteam run. - - Submits a new redteam run for execution with the provided configuration. + raise HttpResponseError(response=response, model=error) - :param red_team: Redteam to be run. Required. - :type red_team: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: RedTeam. The RedTeam is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.RedTeam - :raises ~azure.core.exceptions.HttpResponseError: - """ + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - @overload - def create(self, red_team: IO[bytes], *, content_type: str = "application/json", **kwargs: Any) -> _models.RedTeam: - """Create a redteam run. + deserialized = response.iter_bytes() if _decompress else response.iter_raw() - Submits a new redteam run for execution with the provided configuration. + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore - :param red_team: Redteam to be run. Required. - :type red_team: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: RedTeam. The RedTeam is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.RedTeam - :raises ~azure.core.exceptions.HttpResponseError: - """ + return deserialized # type: ignore @distributed_trace - def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwargs: Any) -> _models.RedTeam: - """Create a redteam run. - - Submits a new redteam run for execution with the provided configuration. + def delete_version(self, name: str, version: str, **kwargs: Any) -> _models.DeleteSkillVersionResult: + """Delete a specific version of a skill. - :param red_team: Redteam to be run. Is one of the following types: RedTeam, JSON, IO[bytes] - Required. - :type red_team: ~azure.ai.projects.models.RedTeam or JSON or IO[bytes] - :return: RedTeam. The RedTeam is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.RedTeam + Removes the specified version of a skill. + + :param name: The name of the skill. Required. + :type name: str + :param version: The version identifier to delete. Required. + :type version: str + :return: DeleteSkillVersionResult. The DeleteSkillVersionResult is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.DeleteSkillVersionResult :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -16911,23 +21031,15 @@ def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwargs: An } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RedTeam] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(red_team, (IOBase, bytes)): - _content = red_team - else: - _content = json.dumps(red_team, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.DeleteSkillVersionResult] = kwargs.pop("cls", None) - _request = build_beta_red_teams_create_request( - content_type=content_type, + _request = build_beta_skills_delete_version_request( + name=name, + version=version, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -16944,7 +21056,7 @@ def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwargs: An response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: try: response.read() # Load the body in memory and close the socket @@ -16960,7 +21072,7 @@ def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwargs: An if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.RedTeam, response.json()) + deserialized = _deserialize(_models.DeleteSkillVersionResult, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -16968,14 +21080,14 @@ def create(self, red_team: Union[_models.RedTeam, JSON, IO[bytes]], **kwargs: An return deserialized # type: ignore -class BetaRoutinesOperations: # pylint: disable=docstring-missing-param +class BetaDatasetsOperations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. Instead, you should access the following operations through :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`routines` attribute. + :attr:`datasets` attribute. """ def __init__(self, *args, **kwargs) -> None: @@ -16985,120 +21097,16 @@ def __init__(self, *args, **kwargs) -> None: self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @overload - def create_or_update( - self, - routine_name: str, - *, - content_type: str = "application/json", - description: Optional[str] = None, - enabled: Optional[bool] = None, - triggers: Optional[dict[str, _models.RoutineTrigger]] = None, - action: Optional[_models.RoutineAction] = None, - authorization: Optional[_models.RoutineAuthorization] = None, - **kwargs: Any - ) -> _models.Routine: - """Create or update a routine. - - Creates a new routine or replaces an existing routine with the supplied definition. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword description: A human-readable description of the routine. Default value is None. - :paramtype description: str - :keyword enabled: Whether the routine is enabled. Default value is None. - :paramtype enabled: bool - :keyword triggers: The triggers configured for the routine. In v1, exactly one trigger entry is - supported. Default value is None. - :paramtype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] - :keyword action: The action executed when the routine fires. Default value is None. - :paramtype action: ~azure.ai.projects.models.RoutineAction - :keyword authorization: Optional authorization configuration for dispatching a newly created - routine. Ignored when updating an existing routine. Default value is None. - :paramtype authorization: ~azure.ai.projects.models.RoutineAuthorization - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create_or_update( - self, routine_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Routine: - """Create or update a routine. - - Creates a new routine or replaces an existing routine with the supplied definition. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create_or_update( - self, routine_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Routine: - """Create or update a routine. - - Creates a new routine or replaces an existing routine with the supplied definition. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine - :raises ~azure.core.exceptions.HttpResponseError: - """ - @distributed_trace - def create_or_update( - self, - routine_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - description: Optional[str] = None, - enabled: Optional[bool] = None, - triggers: Optional[dict[str, _models.RoutineTrigger]] = None, - action: Optional[_models.RoutineAction] = None, - authorization: Optional[_models.RoutineAuthorization] = None, - **kwargs: Any - ) -> _models.Routine: - """Create or update a routine. + def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerationJob: + """Get a data generation job. - Creates a new routine or replaces an existing routine with the supplied definition. + Retrieves the specified data generation job and its current status. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword description: A human-readable description of the routine. Default value is None. - :paramtype description: str - :keyword enabled: Whether the routine is enabled. Default value is None. - :paramtype enabled: bool - :keyword triggers: The triggers configured for the routine. In v1, exactly one trigger entry is - supported. Default value is None. - :paramtype triggers: dict[str, ~azure.ai.projects.models.RoutineTrigger] - :keyword action: The action executed when the routine fires. Default value is None. - :paramtype action: ~azure.ai.projects.models.RoutineAction - :keyword authorization: Optional authorization configuration for dispatching a newly created - routine. Ignored when updating an existing routine. Default value is None. - :paramtype authorization: ~azure.ai.projects.models.RoutineAuthorization - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine + :param job_id: The ID of the job. Required. + :type job_id: str + :return: DataGenerationJob. The DataGenerationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DataGenerationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -17109,33 +21117,14 @@ def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Routine] = kwargs.pop("cls", None) - - if body is _Unset: - body = { - "action": action, - "authorization": authorization, - "description": description, - "enabled": enabled, - "triggers": triggers, - } - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.DataGenerationJob] = kwargs.pop("cls", None) - _request = build_beta_routines_create_or_update_request( - routine_name=routine_name, - content_type=content_type, + _request = build_beta_datasets_get_generation_job_request( + job_id=job_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -17163,30 +21152,120 @@ def create_or_update( _models.ApiErrorResponse, response, ) - raise HttpResponseError(response=response, model=error) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.DataGenerationJob, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list_generation_jobs( + self, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.DataGenerationJob"]: + """List data generation jobs. + + Returns a list of data generation jobs. + + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of DataGenerationJob + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.DataGenerationJob] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.DataGenerationJob]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_beta_datasets_list_generation_jobs_request( + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.DataGenerationJob], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Routine, response.json()) + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response - return deserialized # type: ignore + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - @distributed_trace - def get(self, routine_name: str, **kwargs: Any) -> _models.Routine: - """Get a routine. + return pipeline_response - Retrieves the specified routine and its current configuration. + return ItemPaged(get_next, extract_data) - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine - :raises ~azure.core.exceptions.HttpResponseError: - """ + def _create_generation_job_initial( + self, + job: Union[_models.DataGenerationJob, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> Iterator[bytes]: error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -17195,14 +21274,24 @@ def get(self, routine_name: str, **kwargs: Any) -> _models.Routine: } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_beta_routines_get_request( - routine_name=routine_name, + content_type = content_type or "application/json" + _content = None + if isinstance(job, (IOBase, bytes)): + _content = job + else: + _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_datasets_create_generation_job_request( + operation_id=operation_id, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -17212,19 +21301,18 @@ def get(self, routine_name: str, **kwargs: Any) -> _models.Routine: _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = True pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [201]: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -17232,93 +21320,183 @@ def get(self, routine_name: str, **kwargs: Any) -> _models.Routine: ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Routine, response.json()) + response_headers = {} + response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace - def enable(self, routine_name: str, **kwargs: Any) -> _models.Routine: - """Enable a routine. + @overload + def begin_create_generation_job( + self, + job: _models.DataGenerationJob, + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.DataGenerationJobResult]: + """Create a data generation job. - Enables the specified routine so it can be dispatched. + Submits a new data generation job for asynchronous execution. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine + :param job: The job to create. Required. + :type job: ~azure.ai.projects.models.DataGenerationJob + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns DataGenerationJobResult. The + DataGenerationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.DataGenerationJobResult] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + @overload + def begin_create_generation_job( + self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.DataGenerationJobResult]: + """Create a data generation job. - cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + Submits a new data generation job for asynchronous execution. - _request = build_beta_routines_enable_request( - routine_name=routine_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + :param job: The job to create. Required. + :type job: JSON + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns DataGenerationJobResult. The + DataGenerationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + @overload + def begin_create_generation_job( + self, + job: IO[bytes], + *, + operation_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.DataGenerationJobResult]: + """Create a data generation job. - response = pipeline_response.http_response + Submits a new data generation job for asynchronous execution. - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, + :param job: The job to create. Required. + :type job: IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns DataGenerationJobResult. The + DataGenerationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def begin_create_generation_job( + self, + job: Union[_models.DataGenerationJob, JSON, IO[bytes]], + *, + operation_id: Optional[str] = None, + **kwargs: Any + ) -> LROPoller[_models.DataGenerationJobResult]: + """Create a data generation job. + + Submits a new data generation job for asynchronous execution. + + :param job: The job to create. Is one of the following types: DataGenerationJob, JSON, + IO[bytes] Required. + :type job: ~azure.ai.projects.models.DataGenerationJob or JSON or IO[bytes] + :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the + server creates the job unconditionally. Default value is None. + :paramtype operation_id: str + :return: An instance of LROPoller that returns DataGenerationJobResult. The + DataGenerationJobResult is compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.DataGenerationJobResult] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._create_generation_job_initial( + job=job, + operation_id=operation_id, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs ) - raise HttpResponseError(response=response, model=error) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Routine, response.json()) + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Operation-Location"] = self._deserialize( + "str", response.headers.get("Operation-Location") + ) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + + deserialized = _deserialize(_models.DataGenerationJobResult, response.json().get("result", {})) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } - return deserialized # type: ignore + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) + else: + polling_method = polling + if cont_token: + return LROPoller[_models.DataGenerationJobResult].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.DataGenerationJobResult]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) @distributed_trace - def disable(self, routine_name: str, **kwargs: Any) -> _models.Routine: - """Disable a routine. + def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerationJob: + """Cancel a data generation job. - Disables the specified routine so it no longer runs. + Cancels the specified data generation job if it is still in progress. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :return: Routine. The Routine is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Routine + :param job_id: The ID of the job to cancel. Required. + :type job_id: str + :return: DataGenerationJob. The DataGenerationJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.DataGenerationJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -17332,10 +21510,10 @@ def disable(self, routine_name: str, **kwargs: Any) -> _models.Routine: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Routine] = kwargs.pop("cls", None) + cls: ClsType[_models.DataGenerationJob] = kwargs.pop("cls", None) - _request = build_beta_routines_disable_request( - routine_name=routine_name, + _request = build_beta_datasets_cancel_generation_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -17369,7 +21547,7 @@ def disable(self, routine_name: str, **kwargs: Any) -> _models.Routine: if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Routine, response.json()) + deserialized = _deserialize(_models.DataGenerationJob, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -17377,127 +21555,15 @@ def disable(self, routine_name: str, **kwargs: Any) -> _models.Routine: return deserialized # type: ignore @distributed_trace - def list( - self, - *, - limit: Optional[int] = None, - after: Optional[str] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - **kwargs: Any - ) -> ItemPaged["_models.Routine"]: - """List routines. - - Returns the routines available in the current project. - - :keyword limit: The maximum number of routines to return. Default value is None. - :paramtype limit: int - :keyword after: An opaque continuation token identifying where to resume the list. Prefer - following the ``next_link`` returned by the previous response, which embeds this value. Default - value is None. - :paramtype after: str - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :return: An iterator like instance of Routine - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Routine] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.Routine]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_routines_list_request( - limit=limit, - after=after, - order=order, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.Routine], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("next_link") or None, iter(list_of_elem) - - def get_next(next_link=None): - _request = prepare_request(next_link) - - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - return pipeline_response - - return ItemPaged(get_next, extract_data) - - @distributed_trace - def delete(self, routine_name: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete a routine. + def delete_generation_job( # pylint: disable=inconsistent-return-statements + self, job_id: str, **kwargs: Any + ) -> None: + """Delete a data generation job. - Deletes the specified routine. + Removes the specified data generation job and its associated output. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str + :param job_id: The ID of the job to delete. Required. + :type job_id: str :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -17515,8 +21581,8 @@ def delete(self, routine_name: str, **kwargs: Any) -> None: # pylint: disable=i cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_routines_delete_request( - routine_name=routine_name, + _request = build_beta_datasets_delete_generation_job_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -17544,110 +21610,103 @@ def delete(self, routine_name: str, **kwargs: Any) -> None: # pylint: disable=i if cls: return cls(pipeline_response, None, {}) # type: ignore + +class BetaVoiceAgentsConversationsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`conversations` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @distributed_trace - def list_runs( + def list( self, - routine_name: str, + agent_name: str, *, - filter: Optional[str] = None, limit: Optional[int] = None, - after: Optional[str] = None, order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.RoutineRun"]: - """List prior runs for a routine. + ) -> ItemPaged["_models.VoiceConversation"]: + """List voice agent conversations. - Returns prior runs recorded for the specified routine. + Returns the conversations persisted for the specified voice agent endpoint. Conversations are + present when the session's effective ``store`` setting is ``true``, whether inherited from the + agent definition or enabled by the WebSocket session override. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :keyword filter: An optional MLflow search-runs filter expression applied within the routine's - experiment. Default value is None. - :paramtype filter: str - :keyword limit: The maximum number of runs to return. Default value is None. + :param agent_name: The name of the agent. Required. + :type agent_name: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. :paramtype limit: int - :keyword after: An opaque continuation token identifying where to resume the list. Prefer - following the ``next_link`` returned by the previous response, which embeds this value. Default - value is None. - :paramtype after: str :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for ascending order and``desc`` for descending order. Known values are: "asc" and "desc". Default value is None. :paramtype order: str or ~azure.ai.projects.models.PageOrder - :return: An iterator like instance of RoutineRun - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.RoutineRun] + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceConversation + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.VoiceConversation] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.RoutineRun]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.VoiceConversation]] = kwargs.pop("cls", None) error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_routines_list_runs_request( - routine_name=routine_name, - filter=filter, - limit=limit, - after=after, - order=order, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + def prepare_request(_continuation_token=None): + _request = build_beta_voice_agents_conversations_list_request( + agent_name=agent_name, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.RoutineRun], + List[_models.VoiceConversation], deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("next_link") or None, iter(list_of_elem) + return deserialized.get("last_id") or None, iter(list_of_elem) - def get_next(next_link=None): - _request = prepare_request(next_link) + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -17667,94 +21726,19 @@ def get_next(next_link=None): return ItemPaged(get_next, extract_data) - @overload - def dispatch( - self, - routine_name: str, - *, - content_type: str = "application/json", - payload: Optional[_models.RoutineDispatchPayload] = None, - **kwargs: Any - ) -> _models.DispatchRoutineResult: - """Queue an asynchronous routine dispatch. - - Queues an asynchronous dispatch for the specified routine. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword payload: A direct action-input override sent downstream when testing a routine. - Default value is None. - :paramtype payload: ~azure.ai.projects.models.RoutineDispatchPayload - :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DispatchRoutineResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def dispatch( - self, routine_name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.DispatchRoutineResult: - """Queue an asynchronous routine dispatch. - - Queues an asynchronous dispatch for the specified routine. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DispatchRoutineResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def dispatch( - self, routine_name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.DispatchRoutineResult: - """Queue an asynchronous routine dispatch. - - Queues an asynchronous dispatch for the specified routine. - - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DispatchRoutineResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - @distributed_trace - def dispatch( - self, - routine_name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - payload: Optional[_models.RoutineDispatchPayload] = None, - **kwargs: Any - ) -> _models.DispatchRoutineResult: - """Queue an asynchronous routine dispatch. + def get(self, agent_name: str, conversation_id: str, **kwargs: Any) -> _models.VoiceConversation: + """Get a voice agent conversation. - Queues an asynchronous dispatch for the specified routine. + Retrieves a single conversation recorded for the specified voice agent endpoint by its id. + Returns ``404`` when the conversation was not persisted (``store = false``) or does not exist. - :param routine_name: The unique name of the routine. Required. - :type routine_name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword payload: A direct action-input override sent downstream when testing a routine. - Default value is None. - :paramtype payload: ~azure.ai.projects.models.RoutineDispatchPayload - :return: DispatchRoutineResult. The DispatchRoutineResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DispatchRoutineResult + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to retrieve. Required. + :type conversation_id: str + :return: VoiceConversation. The VoiceConversation is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceConversation :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -17765,27 +21749,15 @@ def dispatch( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DispatchRoutineResult] = kwargs.pop("cls", None) - - if body is _Unset: - body = {"payload": payload} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.VoiceConversation] = kwargs.pop("cls", None) - _request = build_beta_routines_dispatch_request( - routine_name=routine_name, - content_type=content_type, + _request = build_beta_voice_agents_conversations_get_request( + agent_name=agent_name, + conversation_id=conversation_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -17818,39 +21790,26 @@ def dispatch( if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DispatchRoutineResult, response.json()) + deserialized = _deserialize(_models.VoiceConversation, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - -class BetaSchedulesOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`schedules` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - @distributed_trace - def delete(self, schedule_id: str, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements - """Delete a schedule. + def delete( # pylint: disable=inconsistent-return-statements + self, agent_name: str, conversation_id: str, **kwargs: Any + ) -> None: + """Delete a voice agent conversation. - Deletes the specified schedule resource. + Deletes a conversation and all of its stored data — responses, items, and any audio (cascade). + This is the customer's explicit data-deletion control for voice conversations. - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation to delete. Required. + :type conversation_id: str :return: None :rtype: None :raises ~azure.core.exceptions.HttpResponseError: @@ -17866,43 +21825,159 @@ def delete(self, schedule_id: str, **kwargs: Any) -> None: # pylint: disable=in _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) + + _request = build_beta_voice_agents_conversations_delete_request( + agent_name=agent_name, + conversation_id=conversation_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) # type: ignore + + @distributed_trace + def list_responses( + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.VoiceResponse"]: + """List responses in a voice agent conversation. + + Returns a paged collection of the responses (model inference turns) recorded for the specified + conversation. The per-response ``output`` projection may be omitted here; use the + response-items route for the canonical paged output. Returns ``404`` when the conversation was + not persisted (``store = false``). + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose responses are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of VoiceResponse + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.VoiceResponse] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.VoiceResponse]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(_continuation_token=None): + + _request = build_beta_voice_agents_conversations_list_responses_request( + agent_name=agent_name, + conversation_id=conversation_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.VoiceResponse], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) - _request = build_beta_schedules_delete_request( - schedule_id=schedule_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response - response = pipeline_response.http_response + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if response.status_code not in [204]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + return pipeline_response - if cls: - return cls(pipeline_response, None, {}) # type: ignore + return ItemPaged(get_next, extract_data) @distributed_trace - def get(self, schedule_id: str, **kwargs: Any) -> _models.Schedule: - """Get a schedule. + def get_response( + self, agent_name: str, conversation_id: str, response_id: str, **kwargs: Any + ) -> _models.VoiceResponse: + """Get a voice agent conversation response. - Retrieves the specified schedule resource. + Retrieves a single response from the specified conversation by its id, including its ``output`` + items, ``usage``, and status. Returns ``404`` when the conversation or response was not + persisted (``store = false``). - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :return: Schedule. The Schedule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Schedule + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response to retrieve. Required. + :type response_id: str + :return: VoiceResponse. The VoiceResponse is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceResponse :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -17916,10 +21991,12 @@ def get(self, schedule_id: str, **kwargs: Any) -> _models.Schedule: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Schedule] = kwargs.pop("cls", None) + cls: ClsType[_models.VoiceResponse] = kwargs.pop("cls", None) - _request = build_beta_schedules_get_request( - schedule_id=schedule_id, + _request = build_beta_voice_agents_conversations_get_response_request( + agent_name=agent_name, + conversation_id=conversation_id, + response_id=response_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -17944,12 +22021,16 @@ def get(self, schedule_id: str, **kwargs: Any) -> _models.Schedule: except (StreamConsumedError, StreamClosedError): pass map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.Schedule, response.json()) + deserialized = _deserialize(_models.VoiceResponse, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -17957,30 +22038,52 @@ def get(self, schedule_id: str, **kwargs: Any) -> _models.Schedule: return deserialized # type: ignore @distributed_trace - def list( + def list_response_items( self, + agent_name: str, + conversation_id: str, + response_id: str, *, - type: Optional[Union[str, _models.ScheduleTaskType]] = None, - enabled: Optional[bool] = None, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.Schedule"]: - """List schedules. + ) -> ItemPaged["_models.RealtimeConversationItem"]: + """List items produced by a voice agent conversation response. - Returns schedules that match the supplied type and enabled filters. + Returns a paged collection of the output items produced by a specific response (the response's + output projection). For the complete ordered conversation history — including user input and + client-created tool outputs — use the conversation items route instead. Returns ``404`` when + the conversation or response was not persisted (``store = false``). - :keyword type: Filter by the type of schedule. Known values are: "Evaluation" and "Insight". + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the response. Required. + :type conversation_id: str + :param response_id: The id of the response whose output items are listed. Required. + :type response_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. - :paramtype type: str or ~azure.ai.projects.models.ScheduleTaskType - :keyword enabled: Filter by the enabled status. Default value is None. - :paramtype enabled: bool - :return: An iterator like instance of Schedule - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.Schedule] + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.RealtimeConversationItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.Schedule]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.RealtimeConversationItem]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -17990,60 +22093,38 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_schedules_list_request( - type=type, - enabled=enabled, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + def prepare_request(_continuation_token=None): + _request = build_beta_voice_agents_conversations_list_response_items_request( + agent_name=agent_name, + conversation_id=conversation_id, + response_id=response_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) return _request def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.Schedule], - deserialized.get("value", []), + List[_models.RealtimeConversationItem], + deserialized.get("data", []), ) if cls: list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) + return deserialized.get("last_id") or None, iter(list_of_elem) - def get_next(next_link=None): - _request = prepare_request(next_link) + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access @@ -18053,89 +22134,60 @@ def get_next(next_link=None): if response.status_code not in [200]: map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) return pipeline_response return ItemPaged(get_next, extract_data) - @overload - def create_or_update( - self, schedule_id: str, schedule: _models.Schedule, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Schedule: - """Create or update a schedule. - - Creates a new schedule or updates an existing schedule with the supplied definition. - - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :param schedule: The resource instance. Required. - :type schedule: ~azure.ai.projects.models.Schedule - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: Schedule. The Schedule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Schedule - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create_or_update( - self, schedule_id: str, schedule: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Schedule: - """Create or update a schedule. - - Creates a new schedule or updates an existing schedule with the supplied definition. - - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :param schedule: The resource instance. Required. - :type schedule: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: Schedule. The Schedule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Schedule - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create_or_update( - self, schedule_id: str, schedule: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.Schedule: - """Create or update a schedule. + @distributed_trace + def list_items( + self, + agent_name: str, + conversation_id: str, + *, + limit: Optional[int] = None, + order: Optional[Union[str, _models.PageOrder]] = None, + before: Optional[str] = None, + **kwargs: Any + ) -> ItemPaged["_models.RealtimeConversationItem"]: + """List items in a voice agent conversation. - Creates a new schedule or updates an existing schedule with the supplied definition. + Returns a paged collection of items — the complete ordered conversation history, including user + input, assistant output, and client-created tool outputs (transcripts + tool events). Returns + ``404`` when the conversation was not persisted (``store = false``). - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :param schedule: The resource instance. Required. - :type schedule: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: Schedule. The Schedule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Schedule + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose items are listed. Required. + :type conversation_id: str + :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the + default is 20. Default value is None. + :paramtype limit: int + :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for + ascending order and``desc`` + for descending order. Known values are: "asc" and "desc". Default value is None. + :paramtype order: str or ~azure.ai.projects.models.PageOrder + :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your + place in the list. + For instance, if you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page of the list. + Default value is None. + :paramtype before: str + :return: An iterator like instance of RealtimeConversationItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.RealtimeConversationItem] :raises ~azure.core.exceptions.HttpResponseError: """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - @distributed_trace - def create_or_update( - self, schedule_id: str, schedule: Union[_models.Schedule, JSON, IO[bytes]], **kwargs: Any - ) -> _models.Schedule: - """Create or update a schedule. - - Creates a new schedule or updates an existing schedule with the supplied definition. + cls: ClsType[List[_models.RealtimeConversationItem]] = kwargs.pop("cls", None) - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :param schedule: The resource instance. Is one of the following types: Schedule, JSON, - IO[bytes] Required. - :type schedule: ~azure.ai.projects.models.Schedule or JSON or IO[bytes] - :return: Schedule. The Schedule is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.Schedule - :raises ~azure.core.exceptions.HttpResponseError: - """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -18144,71 +22196,77 @@ def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Schedule] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(schedule, (IOBase, bytes)): - _content = schedule - else: - _content = json.dumps(schedule, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + def prepare_request(_continuation_token=None): - _request = build_beta_schedules_create_or_update_request( - schedule_id=schedule_id, - content_type=content_type, - api_version=self._config.api_version, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _request = build_beta_voice_agents_conversations_list_items_request( + agent_name=agent_name, + conversation_id=conversation_id, + limit=limit, + order=order, + after=_continuation_token, + before=before, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + return _request - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.RealtimeConversationItem], + deserialized.get("data", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("last_id") or None, iter(list_of_elem) - response = pipeline_response.http_response + def get_next(_continuation_token=None): + _request = prepare_request(_continuation_token) - if response.status_code not in [200, 201]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.Schedule, response.json()) + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return pipeline_response - return deserialized # type: ignore + return ItemPaged(get_next, extract_data) @distributed_trace - def get_run(self, schedule_id: str, run_id: str, **kwargs: Any) -> _models.ScheduleRun: - """Get a schedule run. + def get_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.RealtimeConversationItem: + """Get a voice agent conversation item. - Retrieves the specified run for a schedule. + Retrieves a single item from the specified conversation by its id, including its transcript. An + ``input_audio``/``output_audio`` content part indicates that audio is available for the item; + the canonical per-item audio metadata is the ``/items/{item_id}/audio`` resource, and the bytes + are streamed by ``/items/{item_id}/audio/content``. Returns ``404`` when the conversation or + item was not persisted (``store = false``). - :param schedule_id: The unique identifier of the schedule. Required. - :type schedule_id: str - :param run_id: The unique identifier of the schedule run. Required. - :type run_id: str - :return: ScheduleRun. The ScheduleRun is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.ScheduleRun + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item to retrieve. Required. + :type item_id: str + :return: RealtimeConversationItem. The RealtimeConversationItem is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.RealtimeConversationItem :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -18222,11 +22280,12 @@ def get_run(self, schedule_id: str, run_id: str, **kwargs: Any) -> _models.Sched _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.ScheduleRun] = kwargs.pop("cls", None) + cls: ClsType[_models.RealtimeConversationItem] = kwargs.pop("cls", None) - _request = build_beta_schedules_get_run_request( - schedule_id=schedule_id, - run_id=run_id, + _request = build_beta_voice_agents_conversations_get_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -18260,148 +22319,35 @@ def get_run(self, schedule_id: str, run_id: str, **kwargs: Any) -> _models.Sched if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.ScheduleRun, response.json()) + deserialized = _deserialize(_models.RealtimeConversationItem, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def list_runs( - self, - schedule_id: str, - *, - type: Optional[Union[str, _models.ScheduleTaskType]] = None, - enabled: Optional[bool] = None, - **kwargs: Any - ) -> ItemPaged["_models.ScheduleRun"]: - """List schedule runs. - - Returns schedule runs that match the supplied filters. - - :param schedule_id: Identifier of the schedule. Required. - :type schedule_id: str - :keyword type: Filter by the type of schedule. Known values are: "Evaluation" and "Insight". - Default value is None. - :paramtype type: str or ~azure.ai.projects.models.ScheduleTaskType - :keyword enabled: Filter by the enabled status. Default value is None. - :paramtype enabled: bool - :return: An iterator like instance of ScheduleRun - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.ScheduleRun] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.ScheduleRun]] = kwargs.pop("cls", None) - - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_beta_schedules_list_runs_request( - schedule_id=schedule_id, - type=type, - enabled=enabled, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", - urllib.parse.urljoin(next_link, _parsed_next_link.path), - headers=_headers, - params=_next_request_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url( - "self._config.endpoint", self._config.endpoint, "str", skip_quote=True - ), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.ScheduleRun], - deserialized.get("value", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("nextLink") or None, iter(list_of_elem) - - def get_next(next_link=None): - _request = prepare_request(next_link) - - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - return pipeline_response - - return ItemPaged(get_next, extract_data) - - -class BetaSkillsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`skills` attribute. - """ - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") - - @distributed_trace - def get(self, name: str, **kwargs: Any) -> _models.SkillDetails: - """Retrieve a skill. - - Retrieves the specified skill and its current configuration. - - :param name: The unique name of the skill. Required. - :type name: str - :return: SkillDetails. The SkillDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillDetails + @distributed_trace + def get_audio_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceAudioItem: + """Get a voice agent conversation item's audio metadata. + + Returns metadata for a single conversation item's audio segment, including the common playback + facts (role, format/codec, sample rate, channels, offset, duration) for both Foundry-managed + and bring-your-own-storage (BYOS) recordings; for BYOS the response additionally includes + ``blob_uri``, the URI of the recording in the customer's own storage (no SAS) that the customer + downloads with their own credentials. Requires the conversation to have persisted audio + (``store = true``); returns ``404`` when the conversation, item, or its audio was not + persisted. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio metadata is retrieved. Required. + :type item_id: str + :return: VoiceAudioItem. The VoiceAudioItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceAudioItem :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -18415,10 +22361,12 @@ def get(self, name: str, **kwargs: Any) -> _models.SkillDetails: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.SkillDetails] = kwargs.pop("cls", None) + cls: ClsType[_models.VoiceAudioItem] = kwargs.pop("cls", None) - _request = build_beta_skills_get_request( - name=name, + _request = build_beta_voice_agents_conversations_get_audio_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -18452,7 +22400,7 @@ def get(self, name: str, **kwargs: Any) -> _models.SkillDetails: if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.SkillDetails, response.json()) + deserialized = _deserialize(_models.VoiceAudioItem, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -18460,41 +22408,28 @@ def get(self, name: str, **kwargs: Any) -> _models.SkillDetails: return deserialized # type: ignore @distributed_trace - def list( - self, - *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - **kwargs: Any - ) -> ItemPaged["_models.SkillDetails"]: - """List skills. + def download_audio_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> Iterator[bytes]: + """Stream a voice agent conversation item's audio. - Returns the skills available in the current project. + Streams a single conversation item's audio as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the item's ``/audio`` + metadata route — so this route returns ``409 Conflict`` for BYOS recordings. Returns ``404`` + when the conversation, item, or its audio was not persisted (``store = false``). - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :return: An iterator like instance of SkillDetails - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.SkillDetails] + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose audio is streamed. Required. + :type item_id: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[List[_models.SkillDetails]] = kwargs.pop("cls", None) - error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -18503,132 +22438,157 @@ def list( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - _request = build_beta_skills_list_request( - limit=limit, - order=order, - after=_continuation_token, - before=before, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.SkillDetails], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + _request = build_beta_voice_agents_conversations_download_audio_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", True) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response + raise HttpResponseError(response=response, model=error) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - return pipeline_response + deserialized = response.iter_bytes() if _decompress else response.iter_raw() - return ItemPaged(get_next, extract_data) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore - @overload - def update( - self, name: str, *, default_version: str, content_type: str = "application/json", **kwargs: Any - ) -> _models.SkillDetails: - """Update a skill. + return deserialized # type: ignore - Modifies the specified skill's configuration. + @distributed_trace + def get_generated_audio_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> _models.VoiceGeneratedAudioItem: + """Get a voice agent conversation item's generated audio metadata. - :param name: The name of the skill to update. Required. - :type name: str - :keyword default_version: The version identifier that the skill should point to. When set, the - skill's default version will resolve to this version instead of the latest. Required. - :paramtype default_version: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: SkillDetails. The SkillDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillDetails + Returns metadata for a conversation item's generated audio. This subordinate artifact is + separate from the canonical heard-audio segment and exists only when playback was interrupted + and the service rendered more audio than the listener heard, including when the response ends + as cancelled. Returns ``404`` when the conversation or item was not persisted, or when no + generated audio exists beyond the heard segment. + + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio metadata is retrieved. + Required. + :type item_id: str + :return: VoiceGeneratedAudioItem. The VoiceGeneratedAudioItem is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceGeneratedAudioItem :raises ~azure.core.exceptions.HttpResponseError: """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - @overload - def update( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.SkillDetails: - """Update a skill. + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - Modifies the specified skill's configuration. + cls: ClsType[_models.VoiceGeneratedAudioItem] = kwargs.pop("cls", None) - :param name: The name of the skill to update. Required. - :type name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: SkillDetails. The SkillDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + _request = build_beta_voice_agents_conversations_get_generated_audio_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - @overload - def update( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.SkillDetails: - """Update a skill. + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - Modifies the specified skill's configuration. + response = pipeline_response.http_response - :param name: The name of the skill to update. Required. - :type name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: SkillDetails. The SkillDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillDetails - :raises ~azure.core.exceptions.HttpResponseError: - """ + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.VoiceGeneratedAudioItem, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore @distributed_trace - def update( - self, name: str, body: Union[JSON, IO[bytes]] = _Unset, *, default_version: str = _Unset, **kwargs: Any - ) -> _models.SkillDetails: - """Update a skill. + def download_generated_audio_item( + self, agent_name: str, conversation_id: str, item_id: str, **kwargs: Any + ) -> Iterator[bytes]: + """Stream a voice agent conversation item's generated audio. - Modifies the specified skill's configuration. + Streams a conversation item's generated audio as a WAV (``audio/wav``) byte stream through the + service. This subordinate artifact exists only when playback was interrupted and the service + rendered more audio than the listener heard, including when the response ends as cancelled. + This route serves Foundry-managed storage only. For bring-your-own-storage (BYOS) recordings + the bytes are not proxied, so this route returns ``409 Conflict``. Returns ``404`` when the + conversation or item was not persisted, or when no generated audio exists beyond the heard + segment. - :param name: The name of the skill to update. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword default_version: The version identifier that the skill should point to. When set, the - skill's default version will resolve to this version instead of the latest. Required. - :paramtype default_version: str - :return: SkillDetails. The SkillDetails is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillDetails + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation that contains the item. Required. + :type conversation_id: str + :param item_id: The id of the conversation item whose generated audio is streamed. Required. + :type item_id: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -18639,29 +22599,16 @@ def update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SkillDetails] = kwargs.pop("cls", None) - - if body is _Unset: - if default_version is _Unset: - raise TypeError("missing required argument: default_version") - body = {"default_version": default_version} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - _request = build_beta_skills_update_request( - name=name, - content_type=content_type, + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + + _request = build_beta_voice_agents_conversations_download_generated_audio_item_request( + agent_name=agent_name, + conversation_id=conversation_id, + item_id=item_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -18671,7 +22618,7 @@ def update( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -18691,26 +22638,40 @@ def update( ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.SkillDetails, response.json()) + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace - def delete(self, name: str, **kwargs: Any) -> _models.DeleteSkillResult: - """Delete a skill. - - Removes the specified skill and its associated versions. + def get_audio(self, agent_name: str, conversation_id: str, **kwargs: Any) -> _models.VoiceRecording: + """Get a voice agent conversation's merged recording metadata. + + Returns metadata for the whole-call merged stereo recording (user audio on the left channel, + agent audio on the right). The common metadata (format, sample rate, channels, channel layout, + duration) is returned for both Foundry-managed and bring-your-own-storage (BYOS) recordings; + for BYOS the response additionally includes ``blob_uri``, the URI of the recording in the + customer's own storage (no SAS) that the customer downloads with their own credentials. The + recording is built once from the per-turn segments after persistence finalization succeeds. + While the conversation is ``in_progress``, this route returns retriable ``409 Conflict`` with + ``error.code = recording_not_ready`` and a ``Retry-After`` header when retry guidance is + available. When the conversation is ``failed``, it returns terminal ``409 Conflict`` with + ``error.code = recording_unavailable``. For a ``completed`` conversation, metadata is available + subject to the existing BYOS behavior. Requires the conversation to have persisted audio + (``store = true``); otherwise returns ``404``. - :param name: The unique name of the skill. Required. - :type name: str - :return: DeleteSkillResult. The DeleteSkillResult is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DeleteSkillResult + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording metadata is + retrieved. Required. + :type conversation_id: str + :return: VoiceRecording. The VoiceRecording is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.VoiceRecording :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -18724,10 +22685,11 @@ def delete(self, name: str, **kwargs: Any) -> _models.DeleteSkillResult: _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DeleteSkillResult] = kwargs.pop("cls", None) + cls: ClsType[_models.VoiceRecording] = kwargs.pop("cls", None) - _request = build_beta_skills_delete_request( - name=name, + _request = build_beta_voice_agents_conversations_get_audio_request( + agent_name=agent_name, + conversation_id=conversation_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -18761,107 +22723,35 @@ def delete(self, name: str, **kwargs: Any) -> _models.DeleteSkillResult: if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DeleteSkillResult, response.json()) + deserialized = _deserialize(_models.VoiceRecording, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @overload - def create( - self, - name: str, - *, - content_type: str = "application/json", - inline_content: Optional[_models.SkillInlineContent] = None, - default: Optional[bool] = None, - **kwargs: Any - ) -> _models.SkillVersion: - """Create a new version of a skill. - - Creates a new version of a skill. If the skill does not exist, it will be created. - - :param name: The name of the skill. If the skill does not exist, it will be created. Required. - :type name: str - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :keyword inline_content: Inline skill content for simple skills without file uploads. - Foundry-specific extension. Default value is None. - :paramtype inline_content: ~azure.ai.projects.models.SkillInlineContent - :keyword default: Whether to set this version as the default. Default value is None. - :paramtype default: bool - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create( - self, name: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.SkillVersion: - """Create a new version of a skill. - - Creates a new version of a skill. If the skill does not exist, it will be created. - - :param name: The name of the skill. If the skill does not exist, it will be created. Required. - :type name: str - :param body: Required. - :type body: JSON - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def create( - self, name: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any - ) -> _models.SkillVersion: - """Create a new version of a skill. - - Creates a new version of a skill. If the skill does not exist, it will be created. - - :param name: The name of the skill. If the skill does not exist, it will be created. Required. - :type name: str - :param body: Required. - :type body: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion - :raises ~azure.core.exceptions.HttpResponseError: - """ - @distributed_trace - def create( - self, - name: str, - body: Union[JSON, IO[bytes]] = _Unset, - *, - inline_content: Optional[_models.SkillInlineContent] = None, - default: Optional[bool] = None, - **kwargs: Any - ) -> _models.SkillVersion: - """Create a new version of a skill. - - Creates a new version of a skill. If the skill does not exist, it will be created. + def download_audio(self, agent_name: str, conversation_id: str, **kwargs: Any) -> Iterator[bytes]: + """Stream a voice agent conversation's merged recording. + + Streams the whole-call merged stereo recording as a WAV (``audio/wav``) byte stream through the + service (no SAS URL). This route serves Foundry-managed storage only. For + bring-your-own-storage (BYOS) recordings the bytes are not proxied — the caller must download + directly from customer storage using the ``blob_uri`` returned by the metadata route — so this + route returns ``409 Conflict`` for BYOS recordings. While the conversation is ``in_progress``, + this route returns retriable ``409 Conflict`` with ``error.code = recording_not_ready`` and a + ``Retry-After`` header when retry guidance is available. When the conversation is ``failed``, + it returns terminal ``409 Conflict`` with ``error.code = recording_unavailable``. For a + ``completed`` conversation, content is available subject to the existing BYOS behavior. A + conversation without persisted audio (``store = false``) returns ``404``. - :param name: The name of the skill. If the skill does not exist, it will be created. Required. - :type name: str - :param body: Is either a JSON type or a IO[bytes] type. Required. - :type body: JSON or IO[bytes] - :keyword inline_content: Inline skill content for simple skills without file uploads. - Foundry-specific extension. Default value is None. - :paramtype inline_content: ~azure.ai.projects.models.SkillInlineContent - :keyword default: Whether to set this version as the default. Default value is None. - :paramtype default: bool - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion + :param agent_name: The name of the agent. Required. + :type agent_name: str + :param conversation_id: The id of the conversation whose merged recording is streamed. + Required. + :type conversation_id: str + :return: Iterator[bytes] + :rtype: Iterator[bytes] :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -18872,27 +22762,15 @@ def create( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) - - if body is _Unset: - body = {"default": default, "inline_content": inline_content} - body = {k: v for k, v in body.items() if v is not None} - content_type = content_type or "application/json" - _content = None - if isinstance(body, (IOBase, bytes)): - _content = body - else: - _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_beta_skills_create_request( - name=name, - content_type=content_type, + _request = build_beta_voice_agents_conversations_download_audio_request( + agent_name=agent_name, + conversation_id=conversation_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -18902,7 +22780,7 @@ def create( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = kwargs.pop("stream", True) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -18922,63 +22800,118 @@ def create( ) raise HttpResponseError(response=response, model=error) - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.SkillVersion, response.json()) + response_headers = {} + response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) + + deserialized = response.iter_bytes() if _decompress else response.iter_raw() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore + +class BetaVoiceAgentsTelephonyOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s + :attr:`telephony` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @overload - def create_from_files( - self, name: str, content: _models.CreateSkillVersionFromFilesBody, **kwargs: Any - ) -> _models.SkillVersion: - """Create a skill version from uploaded files. + def create_binding( + self, + agent_name: str, + telephony_binding: _models.CreateTelephonyBindingRequest, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. - Creates a new version of a skill from uploaded files via multipart form data. + Creates a telephony binding for the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param content: The multipart request content. Required. - :type content: ~azure.ai.projects.models.CreateSkillVersionFromFilesBody - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param telephony_binding: The provider-specific binding to create. Required. + :type telephony_binding: ~azure.ai.projects.models.CreateTelephonyBindingRequest + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create_from_files(self, name: str, content: JSON, **kwargs: Any) -> _models.SkillVersion: - """Create a skill version from uploaded files. + def create_binding( + self, agent_name: str, telephony_binding: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. - Creates a new version of a skill from uploaded files via multipart form data. + Creates a telephony binding for the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param content: The multipart request content. Required. - :type content: JSON - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param telephony_binding: The provider-specific binding to create. Required. + :type telephony_binding: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_binding( + self, agent_name: str, telephony_binding: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. + + Creates a telephony binding for the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param telephony_binding: The provider-specific binding to create. Required. + :type telephony_binding: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def create_from_files( - self, name: str, content: Union[_models.CreateSkillVersionFromFilesBody, JSON], **kwargs: Any - ) -> _models.SkillVersion: - """Create a skill version from uploaded files. + def create_binding( + self, + agent_name: str, + telephony_binding: Union[_models.CreateTelephonyBindingRequest, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.TelephonyBinding: + """Create an agent telephony binding. - Creates a new version of a skill from uploaded files via multipart form data. + Creates a telephony binding for the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param content: The multipart request content. Is either a CreateSkillVersionFromFilesBody type - or a JSON type. Required. - :type content: ~azure.ai.projects.models.CreateSkillVersionFromFilesBody or JSON - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param telephony_binding: The provider-specific binding to create. Is one of the following + types: CreateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type telephony_binding: ~azure.ai.projects.models.CreateTelephonyBindingRequest or JSON or + IO[bytes] + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -18989,20 +22922,24 @@ def create_from_files( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) - _body = content.as_dict() if isinstance(content, _Model) else content - _file_fields: list[str] = ["files"] - _data_fields: list[str] = ["default"] - _files = prepare_multipart_form_data(_body, _file_fields, _data_fields) + content_type = content_type or "application/json" + _content = None + if isinstance(telephony_binding, (IOBase, bytes)): + _content = telephony_binding + else: + _content = json.dumps(telephony_binding, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_beta_skills_create_from_files_request( - name=name, + _request = build_beta_voice_agents_telephony_create_binding_request( + agent_name=agent_name, + content_type=content_type, api_version=self._config.api_version, - files=_files, + content=_content, headers=_headers, params=_params, ) @@ -19019,7 +22956,7 @@ def create_from_files( response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [201]: if _stream: try: response.read() # Load the body in memory and close the socket @@ -19032,32 +22969,43 @@ def create_from_files( ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.SkillVersion, response.json()) + deserialized = _deserialize(_models.TelephonyBinding, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace - def list_versions( + def list_bindings( self, - name: str, + agent_name: str, *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyBindingStatus]] = None, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, before: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.SkillVersion"]: - """List skill versions. + ) -> ItemPaged["_models.TelephonyBindingListItem"]: + """List agent telephony bindings. - Returns the available versions for the specified skill. + Returns the telephony bindings owned by the voice agent named in the path. - :param name: The name of the skill to list versions for. Required. - :type name: str + :param agent_name: The name of the voice agent whose bindings are listed. Required. + :type agent_name: str + :keyword provider: Filters bindings by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters bindings by lifecycle status. Known values are: "active" and + "suspended". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyBindingStatus :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20. Default value is None. @@ -19072,14 +23020,14 @@ def list_versions( subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. :paramtype before: str - :return: An iterator like instance of SkillVersion - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.SkillVersion] + :return: An iterator like instance of TelephonyBindingListItem + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.TelephonyBindingListItem] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.SkillVersion]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.TelephonyBindingListItem]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -19091,8 +23039,10 @@ def list_versions( def prepare_request(_continuation_token=None): - _request = build_beta_skills_list_versions_request( - name=name, + _request = build_beta_voice_agents_telephony_list_bindings_request( + agent_name=agent_name, + provider=provider, + status=status, limit=limit, order=order, after=_continuation_token, @@ -19110,7 +23060,7 @@ def prepare_request(_continuation_token=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.SkillVersion], + List[_models.TelephonyBindingListItem], deserialized.get("data", []), ) if cls: @@ -19139,17 +23089,17 @@ def get_next(_continuation_token=None): return ItemPaged(get_next, extract_data) @distributed_trace - def get_version(self, name: str, version: str, **kwargs: Any) -> _models.SkillVersion: - """Retrieve a specific version of a skill. + def get_binding(self, agent_name: str, binding_id: str, **kwargs: Any) -> _models.TelephonyBinding: + """Get an agent telephony binding. - Retrieves the specified version of a skill by name and version identifier. + Retrieves a telephony binding owned by the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param version: The version identifier to retrieve. Required. - :type version: str - :return: SkillVersion. The SkillVersion is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.SkillVersion + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -19163,11 +23113,11 @@ def get_version(self, name: str, version: str, **kwargs: Any) -> _models.SkillVe _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.SkillVersion] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) - _request = build_beta_skills_get_version_request( - name=name, - version=version, + _request = build_beta_voice_agents_telephony_get_binding_request( + agent_name=agent_name, + binding_id=binding_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -19198,166 +23148,149 @@ def get_version(self, name: str, version: str, **kwargs: Any) -> _models.SkillVe ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.SkillVersion, response.json()) + deserialized = _deserialize(_models.TelephonyBinding, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace - def download(self, name: str, **kwargs: Any) -> Iterator[bytes]: - """Download the zip content for the default version of a skill. + @overload + def update_binding( + self, + agent_name: str, + binding_id: str, + body: _models.UpdateTelephonyBindingRequest, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. - Downloads the zip content for the default version of a skill. + Updates a telephony binding owned by the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - - _request = build_beta_skills_download_request( - name=name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - response_headers = {} - response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized # type: ignore - - @distributed_trace - def download_version(self, name: str, version: str, **kwargs: Any) -> Iterator[bytes]: - """Download the zip content for a specific version of a skill. + @overload + def update_binding( + self, + agent_name: str, + binding_id: str, + body: JSON, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. - Downloads the zip content for a specific version of a skill. + Updates a telephony binding owned by the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param version: The version to download content for. Required. - :type version: str - :return: Iterator[bytes] - :rtype: Iterator[bytes] + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ - error_map: MutableMapping = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - - _request = build_beta_skills_download_version_request( - name=name, - version=version, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", True) - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) - - response_headers = {} - response_headers["Content-Type"] = self._deserialize("str", response.headers.get("Content-Type")) - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + @overload + def update_binding( + self, + agent_name: str, + binding_id: str, + body: IO[bytes], + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/merge-patch+json", + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + Updates a telephony binding owned by the voice agent named in the path. - return deserialized # type: ignore + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/merge-patch+json". + :paramtype content_type: str + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def delete_version(self, name: str, version: str, **kwargs: Any) -> _models.DeleteSkillVersionResult: - """Delete a specific version of a skill. + def update_binding( + self, + agent_name: str, + binding_id: str, + body: Union[_models.UpdateTelephonyBindingRequest, JSON, IO[bytes]], + *, + etag: str, + match_condition: MatchConditions, + **kwargs: Any + ) -> _models.TelephonyBinding: + """Update an agent telephony binding. - Removes the specified version of a skill. + Updates a telephony binding owned by the voice agent named in the path. - :param name: The name of the skill. Required. - :type name: str - :param version: The version identifier to delete. Required. - :type version: str - :return: DeleteSkillVersionResult. The DeleteSkillVersionResult is compatible with - MutableMapping - :rtype: ~azure.ai.projects.models.DeleteSkillVersionResult + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :param body: The binding properties to update. Is one of the following types: + UpdateTelephonyBindingRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.UpdateTelephonyBindingRequest or JSON or IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyBinding. The TelephonyBinding is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyBinding :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -19368,15 +23301,27 @@ def delete_version(self, name: str, version: str, **kwargs: Any) -> _models.Dele } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DeleteSkillVersionResult] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyBinding] = kwargs.pop("cls", None) - _request = build_beta_skills_delete_version_request( - name=name, - version=version, + content_type = content_type or "application/merge-patch+json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_voice_agents_telephony_update_binding_request( + agent_name=agent_name, + binding_id=binding_id, + etag=etag, + match_condition=match_condition, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -19406,44 +23351,37 @@ def delete_version(self, name: str, version: str, **kwargs: Any) -> _models.Dele ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DeleteSkillVersionResult, response.json()) + deserialized = _deserialize(_models.TelephonyBinding, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - -class BetaDatasetsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`datasets` attribute. - """ + return cls(pipeline_response, deserialized, response_headers) # type: ignore - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + return deserialized # type: ignore @distributed_trace - def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerationJob: - """Get a data generation job. + def delete_binding( # pylint: disable=inconsistent-return-statements + self, agent_name: str, binding_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any + ) -> None: + """Delete an agent telephony binding. - Retrieves the specified data generation job and its current status. + Deletes a telephony binding owned by the voice agent named in the path. - :param job_id: The ID of the job. Required. - :type job_id: str - :return: DataGenerationJob. The DataGenerationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DataGenerationJob + :param agent_name: The name of the voice agent that owns the binding. Required. + :type agent_name: str + :param binding_id: The service-generated binding identifier. Required. + :type binding_id: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: None + :rtype: None :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -19457,10 +23395,13 @@ def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerati _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DataGenerationJob] = kwargs.pop("cls", None) + cls: ClsType[None] = kwargs.pop("cls", None) - _request = build_beta_datasets_get_generation_job_request( - job_id=job_id, + _request = build_beta_voice_agents_telephony_delete_binding_request( + agent_name=agent_name, + binding_id=binding_id, + etag=etag, + match_condition=match_condition, api_version=self._config.api_version, headers=_headers, params=_params, @@ -19470,20 +23411,14 @@ def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerati } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _decompress = kwargs.pop("decompress", True) - _stream = kwargs.pop("stream", False) + _stream = False pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [204]: map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -19491,32 +23426,41 @@ def get_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerati ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - - if _stream: - deserialized = response.iter_bytes() if _decompress else response.iter_raw() - else: - deserialized = _deserialize(_models.DataGenerationJob, response.json()) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - - return deserialized # type: ignore + return cls(pipeline_response, None, {}) # type: ignore @distributed_trace - def list_generation_jobs( + def list_calls( self, + agent_name: str, *, + provider: Optional[Union[str, _models.TelephonyProvider]] = None, + status: Optional[Union[str, _models.TelephonyCallStatus]] = None, + started_after_time: Optional[datetime.datetime] = None, + started_before_time: Optional[datetime.datetime] = None, limit: Optional[int] = None, order: Optional[Union[str, _models.PageOrder]] = None, before: Optional[str] = None, **kwargs: Any - ) -> ItemPaged["_models.DataGenerationJob"]: - """List data generation jobs. + ) -> ItemPaged["_models.TelephonyCallSummary"]: + """List agent telephony calls. - Returns a list of data generation jobs. + Returns the durable inbound call history for the voice agent named in the path. + :param agent_name: The name of the voice agent whose calls are listed. Required. + :type agent_name: str + :keyword provider: Filters calls by provider. Known values are: "teams_phone_extension" and + "twilio". Default value is None. + :paramtype provider: str or ~azure.ai.projects.models.TelephonyProvider + :keyword status: Filters calls by lifecycle status. Known values are: "in_progress", "success", + and "failed". Default value is None. + :paramtype status: str or ~azure.ai.projects.models.TelephonyCallStatus + :keyword started_after_time: Includes calls that started at or after this Unix timestamp in + seconds. Default value is None. + :paramtype started_after_time: ~datetime.datetime + :keyword started_before_time: Includes calls that started at or before this Unix timestamp in + seconds. Default value is None. + :paramtype started_before_time: ~datetime.datetime :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20. Default value is None. @@ -19531,14 +23475,14 @@ def list_generation_jobs( subsequent call can include before=obj_foo in order to fetch the previous page of the list. Default value is None. :paramtype before: str - :return: An iterator like instance of DataGenerationJob - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.DataGenerationJob] + :return: An iterator like instance of TelephonyCallSummary + :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.TelephonyCallSummary] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.DataGenerationJob]] = kwargs.pop("cls", None) + cls: ClsType[List[_models.TelephonyCallSummary]] = kwargs.pop("cls", None) error_map: MutableMapping = { 401: ClientAuthenticationError, @@ -19550,7 +23494,12 @@ def list_generation_jobs( def prepare_request(_continuation_token=None): - _request = build_beta_datasets_list_generation_jobs_request( + _request = build_beta_voice_agents_telephony_list_calls_request( + agent_name=agent_name, + provider=provider, + status=status, + started_after_time=started_after_time, + started_before_time=started_before_time, limit=limit, order=order, after=_continuation_token, @@ -19568,7 +23517,7 @@ def prepare_request(_continuation_token=None): def extract_data(pipeline_response): deserialized = pipeline_response.http_response.json() list_of_elem = _deserialize( - List[_models.DataGenerationJob], + List[_models.TelephonyCallSummary], deserialized.get("data", []), ) if cls: @@ -19596,13 +23545,20 @@ def get_next(_continuation_token=None): return ItemPaged(get_next, extract_data) - def _create_generation_job_initial( - self, - job: Union[_models.DataGenerationJob, JSON, IO[bytes]], - *, - operation_id: Optional[str] = None, - **kwargs: Any - ) -> Iterator[bytes]: + @distributed_trace + def get_call(self, agent_name: str, call_id: str, **kwargs: Any) -> _models.TelephonyCallRecord: + """Get an agent telephony call. + + Retrieves a durable inbound call record owned by the voice agent named in the path. + + :param agent_name: The name of the voice agent that owns the call record. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -19611,24 +23567,15 @@ def _create_generation_job_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(job, (IOBase, bytes)): - _content = job - else: - _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) - _request = build_beta_datasets_create_generation_job_request( - operation_id=operation_id, - content_type=content_type, + _request = build_beta_voice_agents_telephony_get_call_request( + agent_name=agent_name, + call_id=call_id, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -19638,18 +23585,19 @@ def _create_generation_job_initial( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -19657,183 +23605,106 @@ def _create_generation_job_initial( ) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @overload - def begin_create_generation_job( - self, - job: _models.DataGenerationJob, - *, - operation_id: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> LROPoller[_models.DataGenerationJobResult]: - """Create a data generation job. + def transfer_call( + self, agent_name: str, call_id: str, *, target: str, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. - Submits a new data generation job for asynchronous execution. + Transfers an active inbound call to a configured target for the voice agent named in the path. - :param job: The job to create. Required. - :type job: ~azure.ai.projects.models.DataGenerationJob - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns DataGenerationJobResult. The - DataGenerationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_create_generation_job( - self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.DataGenerationJobResult]: - """Create a data generation job. + def transfer_call( + self, agent_name: str, call_id: str, body: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. - Submits a new data generation job for asynchronous execution. + Transfers an active inbound call to a configured target for the voice agent named in the path. - :param job: The job to create. Required. - :type job: JSON - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: JSON :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns DataGenerationJobResult. The - DataGenerationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_create_generation_job( - self, - job: IO[bytes], - *, - operation_id: Optional[str] = None, - content_type: str = "application/json", - **kwargs: Any - ) -> LROPoller[_models.DataGenerationJobResult]: - """Create a data generation job. + def transfer_call( + self, agent_name: str, call_id: str, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. - Submits a new data generation job for asynchronous execution. + Transfers an active inbound call to a configured target for the voice agent named in the path. - :param job: The job to create. Required. - :type job: IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Required. + :type body: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns DataGenerationJobResult. The - DataGenerationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.DataGenerationJobResult] + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def begin_create_generation_job( + def transfer_call( self, - job: Union[_models.DataGenerationJob, JSON, IO[bytes]], + agent_name: str, + call_id: str, + body: Union[JSON, IO[bytes]] = _Unset, *, - operation_id: Optional[str] = None, + target: str = _Unset, **kwargs: Any - ) -> LROPoller[_models.DataGenerationJobResult]: - """Create a data generation job. - - Submits a new data generation job for asynchronous execution. - - :param job: The job to create. Is one of the following types: DataGenerationJob, JSON, - IO[bytes] Required. - :type job: ~azure.ai.projects.models.DataGenerationJob or JSON or IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :return: An instance of LROPoller that returns DataGenerationJobResult. The - DataGenerationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.DataGenerationJobResult] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.DataGenerationJobResult] = kwargs.pop("cls", None) - polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = self._create_generation_job_initial( - job=job, - operation_id=operation_id, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - raw_result.http_response.read() # type: ignore - kwargs.pop("error_map", None) - - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Operation-Location"] = self._deserialize( - "str", response.headers.get("Operation-Location") - ) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = _deserialize(_models.DataGenerationJobResult, response.json().get("result", {})) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized - - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } + ) -> _models.TelephonyCallRecord: + """Transfer an active agent telephony call. - if polling is True: - polling_method: PollingMethod = cast( - PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) - ) - elif polling is False: - polling_method = cast(PollingMethod, NoPolling()) - else: - polling_method = polling - if cont_token: - return LROPoller[_models.DataGenerationJobResult].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return LROPoller[_models.DataGenerationJobResult]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) - - @distributed_trace - def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGenerationJob: - """Cancel a data generation job. - - Cancels the specified data generation job if it is still in progress. + Transfers an active inbound call to a configured target for the voice agent named in the path. - :param job_id: The ID of the job to cancel. Required. - :type job_id: str - :return: DataGenerationJob. The DataGenerationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.DataGenerationJob + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword target: The name of a transfer target configured for the voice agent. Required. + :paramtype target: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -19844,14 +23715,30 @@ def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGener } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.DataGenerationJob] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) - _request = build_beta_datasets_cancel_generation_job_request( - job_id=job_id, + if body is _Unset: + if target is _Unset: + raise TypeError("missing required argument: target") + body = {"target": target} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_voice_agents_telephony_transfer_call_request( + agent_name=agent_name, + call_id=call_id, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -19884,7 +23771,7 @@ def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGener if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.DataGenerationJob, response.json()) + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -19892,17 +23779,17 @@ def cancel_generation_job(self, job_id: str, **kwargs: Any) -> _models.DataGener return deserialized # type: ignore @distributed_trace - def delete_generation_job( # pylint: disable=inconsistent-return-statements - self, job_id: str, **kwargs: Any - ) -> None: - """Delete a data generation job. + def end_call(self, agent_name: str, call_id: str, **kwargs: Any) -> _models.TelephonyCallRecord: + """End an active agent telephony call. - Removes the specified data generation job and its associated output. + Ends an active inbound call owned by the voice agent named in the path. - :param job_id: The ID of the job to delete. Required. - :type job_id: str - :return: None - :rtype: None + :param agent_name: The name of the voice agent that owns the active call. Required. + :type agent_name: str + :param call_id: The service-generated call identifier. Required. + :type call_id: str + :return: TelephonyCallRecord. The TelephonyCallRecord is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallRecord :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -19916,10 +23803,11 @@ def delete_generation_job( # pylint: disable=inconsistent-return-statements _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCallRecord] = kwargs.pop("cls", None) - _request = build_beta_datasets_delete_generation_job_request( - job_id=job_id, + _request = build_beta_voice_agents_telephony_end_call_request( + agent_name=agent_name, + call_id=call_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -19929,14 +23817,20 @@ def delete_generation_job( # pylint: disable=inconsistent-return-statements } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -19944,34 +23838,29 @@ def delete_generation_job( # pylint: disable=inconsistent-return-statements ) raise HttpResponseError(response=response, model=error) - if cls: - return cls(pipeline_response, None, {}) # type: ignore + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallRecord, response.json()) + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore -class BetaAgentsOperations: # pylint: disable=docstring-missing-param - """ - .. warning:: - **DO NOT** instantiate this class directly. + return deserialized # type: ignore - Instead, you should access the following operations through - :class:`~azure.ai.projects.AIProjectClient`'s - :attr:`agents` attribute. - """ + @distributed_trace + def get_transfer_targets(self, agent_name: str, **kwargs: Any) -> _models.TelephonyTransferTargets: + """Get agent telephony transfer targets. - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") - self._config: AIProjectClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + Returns all transfer targets configured for the voice agent named in the path. - def _create_optimization_job_initial( - self, - job: Union[_models.AgentOptimizationJob, JSON, IO[bytes]], - *, - operation_id: Optional[str] = None, - **kwargs: Any - ) -> Iterator[bytes]: + :param agent_name: The name of the voice agent whose transfer targets are retrieved. Required. + :type agent_name: str + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -19980,24 +23869,14 @@ def _create_optimization_job_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _content = None - if isinstance(job, (IOBase, bytes)): - _content = job - else: - _content = json.dumps(job, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + cls: ClsType[_models.TelephonyTransferTargets] = kwargs.pop("cls", None) - _request = build_beta_agents_create_optimization_job_request( - operation_id=operation_id, - content_type=content_type, + _request = build_beta_voice_agents_telephony_get_transfer_targets_request( + agent_name=agent_name, api_version=self._config.api_version, - content=_content, headers=_headers, params=_params, ) @@ -20007,18 +23886,19 @@ def _create_optimization_job_initial( _request.url = self._client.format_url(_request.url, **path_format_arguments) _decompress = kwargs.pop("decompress", True) - _stream = True + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: - try: - response.read() # Load the body in memory and close the socket - except (StreamConsumedError, StreamClosedError): - pass + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -20027,10 +23907,12 @@ def _create_optimization_job_initial( raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location")) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) - deserialized = response.iter_bytes() if _decompress else response.iter_raw() + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyTransferTargets, response.json()) if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore @@ -20038,175 +23920,131 @@ def _create_optimization_job_initial( return deserialized # type: ignore @overload - def begin_create_optimization_job( + def replace_transfer_targets( self, - job: _models.AgentOptimizationJob, + agent_name: str, *, - operation_id: Optional[str] = None, + etag: str, + match_condition: MatchConditions, + transfer_targets: List[_models.TelephonyTransferTarget], content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.AgentOptimizationJobResult]: - """Create an agent optimization job. + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent - retry. + Replaces all transfer targets configured for the voice agent named in the path. - :param job: The job to create. Required. - :type job: ~azure.ai.projects.models.AgentOptimizationJob - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns AgentOptimizationJobResult. The - AgentOptimizationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_create_optimization_job( - self, job: JSON, *, operation_id: Optional[str] = None, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.AgentOptimizationJobResult]: - """Create an agent optimization job. + def replace_transfer_targets( + self, + agent_name: str, + body: JSON, + *, + etag: str, + match_condition: MatchConditions, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent - retry. + Replaces all transfer targets configured for the voice agent named in the path. - :param job: The job to create. Required. - :type job: JSON - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: JSON + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns AgentOptimizationJobResult. The - AgentOptimizationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_create_optimization_job( + def replace_transfer_targets( self, - job: IO[bytes], + agent_name: str, + body: IO[bytes], *, - operation_id: Optional[str] = None, + etag: str, + match_condition: MatchConditions, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.AgentOptimizationJobResult]: - """Create an agent optimization job. + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent - retry. + Replaces all transfer targets configured for the voice agent named in the path. - :param job: The job to create. Required. - :type job: IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Required. + :type body: IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns AgentOptimizationJobResult. The - AgentOptimizationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def begin_create_optimization_job( + def replace_transfer_targets( self, - job: Union[_models.AgentOptimizationJob, JSON, IO[bytes]], + agent_name: str, + body: Union[JSON, IO[bytes]] = _Unset, *, - operation_id: Optional[str] = None, + etag: str, + match_condition: MatchConditions, + transfer_targets: List[_models.TelephonyTransferTarget] = _Unset, **kwargs: Any - ) -> LROPoller[_models.AgentOptimizationJobResult]: - """Create an agent optimization job. - - Creates an optimization job and returns the queued job. Honors ``Operation-Id`` for idempotent - retry. - - :param job: The job to create. Is one of the following types: AgentOptimizationJob, JSON, - IO[bytes] Required. - :type job: ~azure.ai.projects.models.AgentOptimizationJob or JSON or IO[bytes] - :keyword operation_id: Client-generated unique ID for idempotent retries. When absent, the - server creates the job unconditionally. Default value is None. - :paramtype operation_id: str - :return: An instance of LROPoller that returns AgentOptimizationJobResult. The - AgentOptimizationJobResult is compatible with MutableMapping - :rtype: ~azure.core.polling.LROPoller[~azure.ai.projects.models.AgentOptimizationJobResult] - :raises ~azure.core.exceptions.HttpResponseError: - """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.AgentOptimizationJobResult] = kwargs.pop("cls", None) - polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = self._create_optimization_job_initial( - job=job, - operation_id=operation_id, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - raw_result.http_response.read() # type: ignore - kwargs.pop("error_map", None) - - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Operation-Location"] = self._deserialize( - "str", response.headers.get("Operation-Location") - ) - response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) - - deserialized = _deserialize(_models.AgentOptimizationJobResult, response.json().get("result", {})) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized - - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - - if polling is True: - polling_method: PollingMethod = cast( - PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) - ) - elif polling is False: - polling_method = cast(PollingMethod, NoPolling()) - else: - polling_method = polling - if cont_token: - return LROPoller[_models.AgentOptimizationJobResult].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return LROPoller[_models.AgentOptimizationJobResult]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) - - @distributed_trace - def get_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOptimizationJob: - """Get an agent optimization job. + ) -> _models.TelephonyTransferTargets: + """Replace agent telephony transfer targets. - Retrieves an optimization job by its identifier. + Replaces all transfer targets configured for the voice agent named in the path. - :param job_id: The ID of the job. Required. - :type job_id: str - :return: AgentOptimizationJob. The AgentOptimizationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentOptimizationJob + :param agent_name: The name of the voice agent whose transfer targets are replaced. Required. + :type agent_name: str + :param body: Is either a JSON type or a IO[bytes] type. Required. + :type body: JSON or IO[bytes] + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :keyword transfer_targets: The complete set of destinations to which the voice agent may + transfer calls. An empty array clears all targets when replacing the configuration. Required. + :paramtype transfer_targets: list[~azure.ai.projects.models.TelephonyTransferTarget] + :return: TelephonyTransferTargets. The TelephonyTransferTargets is compatible with + MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyTransferTargets :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -20217,14 +24055,31 @@ def get_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOptim } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentOptimizationJob] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyTransferTargets] = kwargs.pop("cls", None) - _request = build_beta_agents_get_optimization_job_request( - job_id=job_id, + if body is _Unset: + if transfer_targets is _Unset: + raise TypeError("missing required argument: transfer_targets") + body = {"transfer_targets": transfer_targets} + body = {k: v for k, v in body.items() if v is not None} + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_beta_voice_agents_telephony_replace_transfer_targets_request( + agent_name=agent_name, + etag=etag, + match_condition=match_condition, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) @@ -20255,61 +24110,134 @@ def get_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOptim raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentOptimizationJob, response.json()) + deserialized = _deserialize(_models.TelephonyTransferTargets, response.json()) if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace - def list_optimization_jobs( + @overload + def create_call_job( self, + agent_name: str, + body: _models.CreateTelephonyCallJobRequest, *, - limit: Optional[int] = None, - order: Optional[Union[str, _models.PageOrder]] = None, - before: Optional[str] = None, - status: Optional[Union[str, _models.JobStatus]] = None, - agent_name: Optional[str] = None, + idempotency_key: str, + content_type: str = "application/json", **kwargs: Any - ) -> ItemPaged["_models.AgentOptimizationJobListItem"]: - """List agent optimization jobs. + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. - Lists optimization jobs with cursor pagination and optional status or agent name filters. + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. - :keyword limit: A limit on the number of objects to be returned. Limit can range between 1 and - 100, and the - default is 20. Default value is None. - :paramtype limit: int - :keyword order: Sort order by the ``created_at`` timestamp of the objects. ``asc`` for - ascending order and``desc`` - for descending order. Known values are: "asc" and "desc". Default value is None. - :paramtype order: str or ~azure.ai.projects.models.PageOrder - :keyword before: A cursor for use in pagination. ``before`` is an object ID that defines your - place in the list. - For instance, if you make a list request and receive 100 objects, ending with obj_foo, your - subsequent call can include before=obj_foo in order to fetch the previous page of the list. - Default value is None. - :paramtype before: str - :keyword status: Filter to jobs in this lifecycle state. Known values are: "queued", - "in_progress", "succeeded", "failed", and "cancelled". Default value is None. - :paramtype status: str or ~azure.ai.projects.models.JobStatus - :keyword agent_name: Filter to jobs targeting this agent name. Default value is None. - :paramtype agent_name: str - :return: An iterator like instance of AgentOptimizationJobListItem - :rtype: ~azure.core.paging.ItemPaged[~azure.ai.projects.models.AgentOptimizationJobListItem] + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCallJobRequest + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - cls: ClsType[List[_models.AgentOptimizationJobListItem]] = kwargs.pop("cls", None) + @overload + def create_call_job( + self, + agent_name: str, + body: JSON, + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. + + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. + + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: JSON + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create_call_job( + self, + agent_name: str, + body: IO[bytes], + *, + idempotency_key: str, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. + + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. + + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Required. + :type body: IO[bytes] + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create_call_job( + self, + agent_name: str, + body: Union[_models.CreateTelephonyCallJobRequest, JSON, IO[bytes]], + *, + idempotency_key: str, + **kwargs: Any + ) -> _models.TelephonyCallJob: + """Create an outbound telephony call job. + + Creates one durable direct outbound call job. The latest agent definition is resolved when each + attempt executes. + :param agent_name: The name of the voice agent that executes the call. Required. + :type agent_name: str + :param body: The direct outbound call to create. Is one of the following types: + CreateTelephonyCallJobRequest, JSON, IO[bytes] Required. + :type body: ~azure.ai.projects.models.CreateTelephonyCallJobRequest or JSON or IO[bytes] + :keyword idempotency_key: A customer-generated idempotency key. Reusing it with an equivalent + request returns the same call job. Required. + :paramtype idempotency_key: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob + :raises ~azure.core.exceptions.HttpResponseError: + """ error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, @@ -20318,67 +24246,81 @@ def list_optimization_jobs( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(_continuation_token=None): + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} - _request = build_beta_agents_list_optimization_jobs_request( - limit=limit, - order=order, - after=_continuation_token, - before=before, - status=status, - agent_name=agent_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - return _request + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) - def extract_data(pipeline_response): - deserialized = pipeline_response.http_response.json() - list_of_elem = _deserialize( - List[_models.AgentOptimizationJobListItem], - deserialized.get("data", []), - ) - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.get("last_id") or None, iter(list_of_elem) + content_type = content_type or "application/json" + _content = None + if isinstance(body, (IOBase, bytes)): + _content = body + else: + _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - def get_next(_continuation_token=None): - _request = prepare_request(_continuation_token) + _request = build_beta_voice_agents_telephony_create_call_job_request( + agent_name=agent_name, + idempotency_key=idempotency_key, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ApiErrorResponse, + response, ) - response = pipeline_response.http_response + raise HttpResponseError(response=response, model=error) - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = _failsafe_deserialize( - _models.ApiErrorResponse, - response, - ) - raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + response_headers["Retry-After"] = self._deserialize("duration-seconds-int", response.headers.get("Retry-After")) - return pipeline_response + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) - return ItemPaged(get_next, extract_data) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore @distributed_trace - def cancel_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOptimizationJob: - """Cancel an agent optimization job. + def get_call_job(self, agent_name: str, call_job_id: str, **kwargs: Any) -> _models.TelephonyCallJob: + """Get an outbound telephony call job. - Requests cancellation of a running or queued job and returns an error if the job is already in - a terminal state. + Retrieves a durable direct or campaign-created outbound call job. - :param job_id: The ID of the job to cancel. Required. - :type job_id: str - :return: AgentOptimizationJob. The AgentOptimizationJob is compatible with MutableMapping - :rtype: ~azure.ai.projects.models.AgentOptimizationJob + :param agent_name: Required. + :type agent_name: str + :param call_job_id: Required. + :type call_job_id: str + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -20392,10 +24334,11 @@ def cancel_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOp _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.AgentOptimizationJob] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) - _request = build_beta_agents_cancel_optimization_job_request( - job_id=job_id, + _request = build_beta_voice_agents_telephony_get_call_job_request( + agent_name=agent_name, + call_job_id=call_job_id, api_version=self._config.api_version, headers=_headers, params=_params, @@ -20426,28 +24369,37 @@ def cancel_optimization_job(self, job_id: str, **kwargs: Any) -> _models.AgentOp ) raise HttpResponseError(response=response, model=error) + response_headers = {} + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + if _stream: deserialized = response.iter_bytes() if _decompress else response.iter_raw() else: - deserialized = _deserialize(_models.AgentOptimizationJob, response.json()) + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @distributed_trace - def delete_optimization_job( # pylint: disable=inconsistent-return-statements - self, job_id: str, **kwargs: Any - ) -> None: - """Delete an agent optimization job. + def cancel_call_job( + self, agent_name: str, call_job_id: str, *, etag: str, match_condition: MatchConditions, **kwargs: Any + ) -> _models.TelephonyCallJob: + """Cancel an outbound telephony call job. - Deletes the job and its candidate artifacts, canceling the job first if it is non-terminal. + Requests cancellation of a durable outbound call job. A connected call is allowed to finish. - :param job_id: The ID of the job to delete. Required. - :type job_id: str - :return: None - :rtype: None + :param agent_name: Required. + :type agent_name: str + :param call_job_id: Required. + :type call_job_id: str + :keyword etag: check if resource is changed. Set None to skip checking etag. Required. + :paramtype etag: str + :keyword match_condition: The match condition to use upon the etag. Required. + :paramtype match_condition: ~azure.core.MatchConditions + :return: TelephonyCallJob. The TelephonyCallJob is compatible with MutableMapping + :rtype: ~azure.ai.projects.models.TelephonyCallJob :raises ~azure.core.exceptions.HttpResponseError: """ error_map: MutableMapping = { @@ -20461,10 +24413,13 @@ def delete_optimization_job( # pylint: disable=inconsistent-return-statements _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[None] = kwargs.pop("cls", None) + cls: ClsType[_models.TelephonyCallJob] = kwargs.pop("cls", None) - _request = build_beta_agents_delete_optimization_job_request( - job_id=job_id, + _request = build_beta_voice_agents_telephony_cancel_call_job_request( + agent_name=agent_name, + call_job_id=call_job_id, + etag=etag, + match_condition=match_condition, api_version=self._config.api_version, headers=_headers, params=_params, @@ -20474,14 +24429,20 @@ def delete_optimization_job( # pylint: disable=inconsistent-return-statements } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _decompress = kwargs.pop("decompress", True) + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [204]: + if response.status_code not in [200, 202]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) error = _failsafe_deserialize( _models.ApiErrorResponse, @@ -20489,5 +24450,23 @@ def delete_optimization_job( # pylint: disable=inconsistent-return-statements ) raise HttpResponseError(response=response, model=error) + response_headers = {} + if response.status_code == 200: + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + if response.status_code == 202: + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + response_headers["Location"] = self._deserialize("str", response.headers.get("Location")) + response_headers["Retry-After"] = self._deserialize( + "duration-seconds-int", response.headers.get("Retry-After") + ) + + if _stream: + deserialized = response.iter_bytes() if _decompress else response.iter_raw() + else: + deserialized = _deserialize(_models.TelephonyCallJob, response.json()) + if cls: - return cls(pipeline_response, None, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore diff --git a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch.py b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch.py index 4231ea89f96a..a7dc22dac3a3 100644 --- a/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch.py +++ b/sdk/ai/azure-ai-projects/azure/ai/projects/operations/_patch.py @@ -12,6 +12,14 @@ import inspect from typing import Any, Callable, List from ..models._patch import _FOUNDRY_FEATURES_HEADER_NAME, _BETA_OPERATION_FEATURE_HEADERS, _has_header_case_insensitive +from .._realtime import ( + BetaRealtime, + BetaRealtimeConnection, + BetaRealtimeConnectionManager, + ClientEvent, + ConversationItem, + ServerEvent, +) from ._patch_agents import AgentsOperations, BetaAgentsOperations from ._patch_agent_insights import BetaAgentInsightMonitorsOperations from ._patch_datasets import BetaDatasetsOperations, DatasetsOperations @@ -29,6 +37,9 @@ BetaRoutinesOperations, BetaSchedulesOperations, BetaSkillsOperations, + BetaVoiceAgentsConversationsOperations, + BetaVoiceAgentsOperations as GeneratedBetaVoiceAgentsOperations, + BetaVoiceAgentsTelephonyOperations, ) @@ -51,13 +62,38 @@ class _OperationMethodHeaderProxy: """Proxy that injects the Foundry-Features header into public operation method calls.""" def __init__(self, operation: Any, foundry_features_value: str): + """Wrap an operation and its nested operation groups with the same header value. + + For example, ``.beta.voice_agents`` stores ``conversations`` and ``telephony`` as nested + operation groups. Wrapping them with the parent proxy ensures every call under + ``.beta.voice_agents.conversations`` and ``.beta.voice_agents.telephony`` receives the + ``Foundry-Features: VoiceAgents=V1Preview`` header. + """ object.__setattr__(self, "_operation", operation) object.__setattr__(self, "_foundry_features_value", foundry_features_value) + for name, attribute in vars(operation).items(): + # Generated operation groups share these fields; ordinary public attributes do not. + if ( + not name.startswith("_") + and not isinstance(attribute, _OperationMethodHeaderProxy) + and hasattr(attribute, "_client") + and hasattr(attribute, "_config") + ): + setattr(operation, name, _OperationMethodHeaderProxy(attribute, foundry_features_value)) def __getattr__(self, name: str) -> Any: attribute = getattr(self._operation, name) - if name.startswith("_") or not callable(attribute) or not _method_accepts_keyword_headers(attribute): + if name.startswith("_"): + return attribute + if not callable(attribute): + if isinstance(attribute, _OperationMethodHeaderProxy): + return attribute + # Also wrap an operation group that was assigned after this proxy was initialized. + if hasattr(attribute, "_client") and hasattr(attribute, "_config"): + return _OperationMethodHeaderProxy(attribute, self._foundry_features_value) + return attribute + if not _method_accepts_keyword_headers(attribute): return attribute @wraps(attribute) @@ -85,6 +121,31 @@ def __setattr__(self, name: str, value: Any) -> None: setattr(self._operation, name, value) +class BetaVoiceAgentsOperations(GeneratedBetaVoiceAgentsOperations): + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.ai.projects.AIProjectClient`'s :attr:`beta` attribute's + :attr:`~azure.ai.projects.operations.BetaOperations.voice_agents` attribute. + """ + + conversations: BetaVoiceAgentsConversationsOperations + """:class:`~azure.ai.projects.operations.BetaVoiceAgentsConversationsOperations` operations""" + telephony: BetaVoiceAgentsTelephonyOperations + """:class:`~azure.ai.projects.operations.BetaVoiceAgentsTelephonyOperations` operations""" + realtime: BetaRealtime + """:class:`~azure.ai.projects.operations.BetaRealtime` operations""" + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + # The generator does not emit realtime operations at all, since azure-core's HTTP + # pipeline has no way to keep a WebSocket upgrade's resulting socket alive. Add our + # hand-written client, which manages a real, long-lived connection, in its place. + self.realtime = BetaRealtime(self) + + class BetaOperations(GeneratedBetaOperations): """ .. warning:: @@ -119,6 +180,8 @@ class BetaOperations(GeneratedBetaOperations): """:class:`~azure.ai.projects.operations.BetaSkillsOperations` operations""" datasets: BetaDatasetsOperations """:class:`~azure.ai.projects.operations.BetaDatasetsOperations` operations""" + voice_agents: BetaVoiceAgentsOperations + """:class:`~azure.ai.projects.operations.BetaVoiceAgentsOperations` operations""" def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) @@ -136,6 +199,8 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: self.agent_insight_monitors = BetaAgentInsightMonitorsOperations( self._client, self._config, self._serialize, self._deserialize ) + # Replace with patched class that wires up the hand-written realtime client + self.voice_agents = BetaVoiceAgentsOperations(self._client, self._config, self._serialize, self._deserialize) for property_name, foundry_features_value in _BETA_OPERATION_FEATURE_HEADERS.items(): setattr( @@ -160,9 +225,18 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: "BetaRoutinesOperations", "BetaSchedulesOperations", "BetaSkillsOperations", + "BetaVoiceAgentsConversationsOperations", + "BetaVoiceAgentsOperations", + "BetaVoiceAgentsTelephonyOperations", + "ClientEvent", "ConnectionsOperations", + "ConversationItem", "DatasetsOperations", "EvaluationRulesOperations", + "BetaRealtime", + "BetaRealtimeConnection", + "BetaRealtimeConnectionManager", + "ServerEvent", "TelemetryOperations", ] # Add all objects you want publicly available to users at this package level diff --git a/sdk/ai/azure-ai-projects/dev_requirements.txt b/sdk/ai/azure-ai-projects/dev_requirements.txt index 6641c1e8f14a..a8928e8a7c9b 100644 --- a/sdk/ai/azure-ai-projects/dev_requirements.txt +++ b/sdk/ai/azure-ai-projects/dev_requirements.txt @@ -14,6 +14,7 @@ azure-monitor-query jsonref opentelemetry-sdk python-dotenv +websockets>=13.0 black # Can't include those, because they are not supported in Python 3.9. Samples that use these package # cannot be run as pytest, because the pipeline will fail on Python 3.9 jobs. diff --git a/sdk/ai/azure-ai-projects/GeneratePublicMethods.ps1 b/sdk/ai/azure-ai-projects/docs/GeneratePublicMethodsDoc.ps1 similarity index 84% rename from sdk/ai/azure-ai-projects/GeneratePublicMethods.ps1 rename to sdk/ai/azure-ai-projects/docs/GeneratePublicMethodsDoc.ps1 index 938e257ed608..b1d3017632f5 100644 --- a/sdk/ai/azure-ai-projects/GeneratePublicMethods.ps1 +++ b/sdk/ai/azure-ai-projects/docs/GeneratePublicMethodsDoc.ps1 @@ -4,11 +4,11 @@ [CmdletBinding()] param( [string]$PythonExecutable = "python", - [string]$OutputPath = (Join-Path $PSScriptRoot "docs\public-methods.md") + [string]$OutputPath = (Join-Path $PSScriptRoot "public-methods.md") ) $ErrorActionPreference = "Stop" -$packageRoot = $PSScriptRoot +$packageRoot = Split-Path -Parent $PSScriptRoot $temporaryScript = Join-Path ([System.IO.Path]::GetTempPath()) ("generate-public-methods-{0}.py" -f [guid]::NewGuid()) $pythonScript = @' @@ -54,24 +54,50 @@ def unwrap_operation(value: Any) -> Any: return getattr(value, "_operation", value) -def operation_instances(container: Any, *, exclude: set[str] | None = None) -> dict[str, Any]: +# Hand-written sub-client classes that don't follow the generated *Operations naming +# convention but are still part of the public surface and should be discovered/counted the +# same way, e.g. `beta.voice_agents.realtime` (`BetaRealtime`/`AsyncBetaRealtime`). +_HANDWRITTEN_SUBCLIENT_CLASS_NAMES = {"BetaRealtime", "AsyncBetaRealtime"} + + +def _is_operation_group(value: Any) -> bool: + class_name = type(value).__name__ + return class_name.endswith("Operations") or class_name in _HANDWRITTEN_SUBCLIENT_CLASS_NAMES + + +def operation_instances( + container: Any, + *, + exclude: set[str] | None = None, + prefix: str = "", +) -> dict[str, Any]: excluded = exclude or set() operations: dict[str, Any] = {} for name, value in vars(container).items(): if name.startswith("_") or name in excluded: continue operation = unwrap_operation(value) - if type(operation).__name__.endswith("Operations"): - operations[name] = operation + if _is_operation_group(operation): + operation_name = f"{prefix}.{name}" if prefix else name + nested_operations = operation_instances(operation, prefix=operation_name) + if public_methods(operation) or not nested_operations: + operations[operation_name] = operation + operations.update(nested_operations) return operations +# Filenames that are fully code-generated from TypeSpec; any other source file backing a +# method (including hand-written modules that aren't named `_patch*.py`, e.g. `_realtime.py`) +# counts as handwritten. +_GENERATED_SOURCE_FILENAMES = {"_operations.py", "_client.py"} + + def is_handwritten_method(cls: type[Any], name: str) -> bool: owner = next((base for base in cls.__mro__ if name in vars(base)), None) if owner is None: raise RuntimeError(f"Unable to find the class that defines {cls.__name__}.{name}") source_path = inspect.getsourcefile(owner) - return source_path is not None and "_patch" in Path(source_path).name + return source_path is not None and Path(source_path).name not in _GENERATED_SOURCE_FILENAMES def public_methods(instance: Any) -> dict[str, bool]: @@ -155,7 +181,7 @@ try: lines = [ "# Public AIProjectClient methods", "", - "", + "", "", "This document lists all public methods available on `AIProjectClient` and its sub-clients. " "Overload methods are not counted. Only synchronous methods are counted (but each one has an " diff --git a/sdk/ai/azure-ai-projects/docs/public-methods.md b/sdk/ai/azure-ai-projects/docs/public-methods.md index c057b80a9581..cfa378105a34 100644 --- a/sdk/ai/azure-ai-projects/docs/public-methods.md +++ b/sdk/ai/azure-ai-projects/docs/public-methods.md @@ -1,16 +1,16 @@ # Public AIProjectClient methods - + This document lists all public methods available on `AIProjectClient` and its sub-clients. Overload methods are not counted. Only synchronous methods are counted (but each one has an equivalent asynchronous method). ## Summary -There are a total of 157 unique public methods: +There are a total of 188 unique public methods: - 5 stable methods on the client -- 58 stable methods on top-level sub-clients -- 94 beta methods on nested beta sub-clients +- 59 stable methods on top-level sub-clients +- 124 beta methods on nested beta sub-clients ### Top-level sub-clients (stable operations) @@ -23,14 +23,14 @@ There are a total of 157 unique public methods: | `evaluation_rules` | EvaluationRulesOperations | 4 | | `indexes` | IndexesOperations | 5 | | `telemetry` | TelemetryOperations | 1 | -| `toolboxes` | ToolboxesOperations | 8 | +| `toolboxes` | ToolboxesOperations | 9 | ### Nested sub-clients (beta operations) | Subclient | Class Name | Methods Count | | --- | --- | --- | | `beta.agent_insight_monitors` | BetaAgentInsightMonitorsOperations | 13 | -| `beta.agents` | BetaAgentsOperations | 5 | +| `beta.agents` | BetaAgentsOperations | 6 | | `beta.datasets` | BetaDatasetsOperations | 5 | | `beta.evaluation_taxonomies` | BetaEvaluationTaxonomiesOperations | 5 | | `beta.evaluators` | BetaEvaluatorsOperations | 13 | @@ -41,6 +41,9 @@ There are a total of 157 unique public methods: | `beta.routines` | BetaRoutinesOperations | 8 | | `beta.schedules` | BetaSchedulesOperations | 6 | | `beta.skills` | BetaSkillsOperations | 11 | +| `beta.voice_agents.conversations` | BetaVoiceAgentsConversationsOperations | 14 | +| `beta.voice_agents.realtime` | BetaRealtime | 1 | +| `beta.voice_agents.telephony` | BetaVoiceAgentsTelephonyOperations | 14 | ## Stable methods on the client @@ -121,6 +124,7 @@ Alphabetically sorted. An asterisk at the end of the method name means it is a h .toolboxes.delete_version .toolboxes.get .toolboxes.get_version +.toolboxes.invoke_latest_toolbox_mcp .toolboxes.list .toolboxes.list_versions .toolboxes.update @@ -147,6 +151,7 @@ Alphabetically sorted. An asterisk at the end of the method name means it is a h .beta.agents.begin_create_optimization_job* .beta.agents.cancel_optimization_job +.beta.agents.create_from_prompt .beta.agents.delete_optimization_job .beta.agents.get_optimization_job .beta.agents.list_optimization_jobs @@ -236,4 +241,36 @@ Alphabetically sorted. An asterisk at the end of the method name means it is a h .beta.skills.list .beta.skills.list_versions .beta.skills.update + +.beta.voice_agents.conversations.delete +.beta.voice_agents.conversations.download_audio +.beta.voice_agents.conversations.download_audio_item +.beta.voice_agents.conversations.download_generated_audio_item +.beta.voice_agents.conversations.get +.beta.voice_agents.conversations.get_audio +.beta.voice_agents.conversations.get_audio_item +.beta.voice_agents.conversations.get_generated_audio_item +.beta.voice_agents.conversations.get_item +.beta.voice_agents.conversations.get_response +.beta.voice_agents.conversations.list +.beta.voice_agents.conversations.list_items +.beta.voice_agents.conversations.list_response_items +.beta.voice_agents.conversations.list_responses + +.beta.voice_agents.realtime.connect* + +.beta.voice_agents.telephony.cancel_call_job +.beta.voice_agents.telephony.create_binding +.beta.voice_agents.telephony.create_call_job +.beta.voice_agents.telephony.delete_binding +.beta.voice_agents.telephony.end_call +.beta.voice_agents.telephony.get_binding +.beta.voice_agents.telephony.get_call +.beta.voice_agents.telephony.get_call_job +.beta.voice_agents.telephony.get_transfer_targets +.beta.voice_agents.telephony.list_bindings +.beta.voice_agents.telephony.list_calls +.beta.voice_agents.telephony.replace_transfer_targets +.beta.voice_agents.telephony.transfer_call +.beta.voice_agents.telephony.update_binding ``` diff --git a/sdk/ai/azure-ai-projects/pyproject.toml b/sdk/ai/azure-ai-projects/pyproject.toml index dea352a19763..a59e849f31fb 100644 --- a/sdk/ai/azure-ai-projects/pyproject.toml +++ b/sdk/ai/azure-ai-projects/pyproject.toml @@ -42,6 +42,12 @@ dynamic = [ "version", "readme" ] +[project.optional-dependencies] +voice = [ + "websockets>=13.0", + "aiohttp>=3.9.0,<4.0.0", +] + [project.urls] repository = "https://aka.ms/azsdk/azure-ai-projects-v2/python/code" diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic.py new file mode 100644 index 000000000000..da9fcb765e0a --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic.py @@ -0,0 +1,109 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates the voice-agent management lifecycle using the + synchronous AIProjectClient: creating a voice agent, retrieving it, + listing the voice agents in the project, and deleting it. + + Voice agents are exposed through `project_client.agents` with + `kind="voice"`, the same surface used for prompt, workflow, hosted, and + external agents. + +USAGE: + python sample_voice_agent_basic.py + + Before running the sample: + + pip install "azure-ai-projects>=2.7.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview + page of your Microsoft Foundry portal. + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not + set, defaults to "MyVoiceAgent". +""" + +import os +from dotenv import load_dotenv +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + AgentKind, + VoiceAgentDefinition, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceModelType, + VoiceOutputModality, + VoiceType, +) + +load_dotenv() + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" +agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "MyVoiceAgent" + +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, +): + created_versions = [] + try: + definition = VoiceAgentDefinition( + # `managed` uses a service-hosted model; use `self_deployed` with a Foundry + # deployment name to bring your own model. + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Keep replies short and natural.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type=VoiceType.AZURE_STANDARD), + ), + output_modalities=[VoiceOutputModality.AUDIO], + # Persist conversations so the transcript and audio can be read back later + # (see sample_voice_agent_read_conversation.py). Defaults to False, which stores nothing. + store=True, + ) + + created_version = project_client.agents.create_version(agent_name=agent_name, definition=definition) + created_versions.append(created_version) + print(f"Created voice agent '{agent_name}', version: {created_version.version}") + + agent = project_client.agents.get(agent_name=agent_name) + print(f"Retrieved voice agent: {agent.name} (state={agent.state})") + + print("Voice agents in this project:") + for item in project_client.agents.list(kind=AgentKind.VOICE): + print(f" - {item.name}") + + # Each update produces a new immutable version. + updated_version = project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Always greet the caller warmly.", + audio=definition.audio, + output_modalities=definition.output_modalities, + store=definition.store, + ), + description="Updated instructions.", + ) + created_versions.append(updated_version) + print(f"Updated voice agent to version: {updated_version.version}") + + # Disable the agent so its endpoint rejects new requests, then re-enable it. + project_client.agents.disable(agent_name=agent_name) + print("Disabled voice agent") + project_client.agents.enable(agent_name=agent_name) + print("Enabled voice agent") + finally: + for version in reversed(created_versions): + project_client.agents.delete_version(agent_name=agent_name, agent_version=version.version) + print(f"Deleted voice agent version: {version.version}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic_async.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic_async.py new file mode 100644 index 000000000000..26b4a2e58ca1 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_basic_async.py @@ -0,0 +1,75 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates the voice-agent management lifecycle using the + asynchronous AIProjectClient: creating a voice agent, retrieving it, + listing the voice agents in the project, and deleting it. + +USAGE: + python sample_voice_agent_basic_async.py + + Before running the sample: + + pip install "azure-ai-projects>=2.7.0" aiohttp python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview + page of your Microsoft Foundry portal. + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not + set, defaults to "MyVoiceAgentAsync". +""" + +import asyncio +import os +from dotenv import load_dotenv +from azure.identity.aio import DefaultAzureCredential +from azure.ai.projects.aio import AIProjectClient +from azure.ai.projects.models import AgentKind, VoiceAgentDefinition, VoiceModelType + +load_dotenv() + + +async def main() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "MyVoiceAgentAsync" + + async with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + created_version = None + try: + created_version = await project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Keep replies short and natural.", + # Persist conversations so they can be read back later. Defaults to False. + store=True, + ), + ) + print(f"Created voice agent '{agent_name}', version: {created_version.version}") + + agent = await project_client.agents.get(agent_name=agent_name) + print(f"Retrieved voice agent: {agent.name}") + + print("Voice agents in this project:") + async for item in project_client.agents.list(kind=AgentKind.VOICE): + print(f" - {item.name}") + finally: + if created_version is not None: + await project_client.agents.delete_version(agent_name=agent_name, agent_version=created_version.version) + print(f"Deleted voice agent version: {created_version.version}") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_generate.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_generate.py new file mode 100644 index 000000000000..7b42328d5490 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_generate.py @@ -0,0 +1,67 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates guided authoring: generating and creating a voice + agent through `create_from_prompt` with `kind="voice"`. + The service creates a voice agent with a service-selected starter definition, + which is fully editable afterward through the standard create_version/update flow. + +USAGE: + python sample_voice_agent_generate.py + + Before running the sample: + + pip install "azure-ai-projects>=2.7.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not + set, defaults to "MyGeneratedVoiceAgent". +""" + +import os +import sys +from dotenv import load_dotenv +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import AgentKind, GenerateVoiceAgentRequest + +load_dotenv() + + +def _safe_print(text: str) -> None: + """Print text that may contain characters the current console can't display. + + The instructions below are model-generated and can contain characters (curly + quotes, em-dashes, etc.) outside some legacy, non-Unicode console encodings + (for example when stdout is piped/redirected on Windows). Rather than crashing + with UnicodeEncodeError, fall back to replacing just the unsupported characters; + a real interactive UTF-8 console prints unaffected. + """ + try: + print(text) + except UnicodeEncodeError: + encoding = sys.stdout.encoding or "ascii" + print(text.encode(encoding, errors="replace").decode(encoding)) + + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "MyGeneratedVoiceAgent" + +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, +): + agent = project_client.beta.agents.create_from_prompt( + GenerateVoiceAgentRequest(kind=AgentKind.VOICE, name=agent_name) + ) + print(f"Generated voice agent: {agent.name}") + _safe_print(f"Instructions:\n{agent.versions.latest.definition.instructions}") # type: ignore[attr-defined] + + project_client.agents.delete(agent_name=agent.name) + print(f"Deleted voice agent: {agent.name}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_audio_conversation_async.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_audio_conversation_async.py new file mode 100644 index 000000000000..e1c380c2f54c --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_audio_conversation_async.py @@ -0,0 +1,482 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + End-to-end hands-free, bidirectional voice conversation using the + ``client.beta.voice_agents.realtime`` namespace added on top of the generated + azure-ai-projects client (see ``azure.ai.projects.aio.operations.AsyncBetaRealtime``). + This mirrors the ergonomics of the OpenAI Python realtime client. + + 1. Create a voice agent with conversation persistence enabled + (`store=True`) so the conversation can be read back afterward. + 2. Stream live mic audio and let the agent's server-side VAD detect your + turns: your speech is transcribed, the agent replies through the + speakers, and talking over it barges in. + 3. Fetch the persisted conversation back by id. + 4. Delete the agent created for this sample. + + Capture and playback use non-blocking pyaudio callbacks; reply audio is + sequence-numbered so a barge-in can skip whatever is still queued. The + agent owns turn detection and noise suppression server-side. Use a headset + to avoid echo. + + Mic audio is sent as base64 PCM16; the reply arrives as typed + ``response.output_audio.*`` events, decoded to PCM16, mono, 24 kHz. + Requires ``aiohttp`` and ``pyaudio``. + + pip install "azure-ai-projects[voice]>=2.7.0" azure-identity pyaudio + +USAGE: + python sample_voice_agent_live_audio_conversation_async.py + + Environment variables: + 1) FOUNDRY_PROJECT_ENDPOINT (required) - Foundry project endpoint: + https://.services.ai.azure.com/api/projects/ + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the agent created by this + sample. Defaults to "sample-live-audio-conversation-agent-async". + + Runs until you press Ctrl-C. Authenticates with DefaultAzureCredential, so + sign in first (e.g. `az login`). +""" + +import asyncio +import concurrent.futures +import os +import queue +import sys +from typing import Any, Final, Optional + +from dotenv import load_dotenv +from azure.core.exceptions import HttpResponseError +from azure.identity.aio import DefaultAzureCredential + +# AsyncBetaRealtimeConnection is re-exported dynamically via aio/operations/_patch.py's `__all__`; +# pylint's static import resolution cannot trace that, but the symbol is valid (verified by +# Pyright/mypy). +from azure.ai.projects.aio.operations import AsyncBetaRealtimeConnection # pylint: disable=no-name-in-module +from azure.ai.projects.aio import AIProjectClient +from azure.ai.projects.models import ( + RealtimeServerEventConversationItemInputAudioTranscriptionCompleted, + RealtimeServerEventInputAudioBufferSpeechStarted, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseCreated, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + RealtimeServerEventError, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceModelType, + VoiceOutputModality, + VoiceType, +) + +load_dotenv() + + +def _safe_print(text: str) -> None: + """Print text that may contain characters the current console can't display. + + The agent's replies below are model-generated and can contain characters (curly + quotes, em-dashes, etc.) outside some legacy, non-Unicode console encodings + (for example when stdout is piped/redirected on Windows). Rather than crashing + with UnicodeEncodeError, fall back to replacing just the unsupported characters; + a real interactive UTF-8 console prints unaffected. + """ + try: + print(text) + except UnicodeEncodeError: + encoding = sys.stdout.encoding or "ascii" + print(text.encode(encoding, errors="replace").decode(encoding)) + + +# Audio is streamed both ways as PCM16, mono, 24 kHz. +_SAMPLE_RATE: Final = 24000 + +# pyaudio callback buffer size (~50 ms of PCM16 audio per callback). +_CHUNK_SAMPLES: Final = 1200 + +try: + import pyaudio # type: ignore[import-not-found] +except ImportError: # pragma: no cover - required audio dependency + pyaudio: Any = None # type: ignore[no-redef] + + +def _format_size(num_bytes: int) -> str: + """Format a byte count as a human-readable string. + + :param num_bytes: The size in bytes. + :type num_bytes: int + :return: A string like "12345 bytes (12.1 KB)" or "2097152 bytes (2.00 MB)". + :rtype: str + """ + if num_bytes < 1024: + return f"{num_bytes} bytes" + if num_bytes < 1024 * 1024: + return f"{num_bytes} bytes ({num_bytes / 1024:.1f} KB)" + return f"{num_bytes} bytes ({num_bytes / (1024 * 1024):.2f} MB)" + + +class _AudioProcessor: # pylint: disable=too-many-instance-attributes + """Real-time mic capture and speaker playback via non-blocking pyaudio callbacks. + + * Capture appends each raw PCM16 frame to the input buffer (the realtime + client base64-encodes it). + * Playback pulls sequence-numbered PCM16 from a queue, always returning the + exact sample count pyaudio asked for (a wrong size corrupts audio). + * ``skip_pending_audio`` bumps a base sequence number so audio queued before + a barge-in is dropped, stopping playback the instant the user speaks. + """ + + def __init__(self, connection: "AsyncBetaRealtimeConnection") -> None: + self._conn = connection + self._loop: Optional[asyncio.AbstractEventLoop] = None + self._audio = pyaudio.PyAudio() + + # Playback with sequence numbers for interrupt handling. + self._playback_queue: "queue.Queue[tuple[int, Optional[bytes]]]" = queue.Queue() + self._playback_base = 0 + self._next_seq = 0 + self._output_bytes = 0 + + # Bounds capture backpressure to a single in-flight send (see start_capture). + self._pending_send: "Optional[concurrent.futures.Future[None]]" = None + self._dropped_frames = 0 + # Only counts bytes actually handed to input_audio_buffer.append() -- frames dropped + # above due to backpressure are never sent, so they must not be counted here. + self._input_bytes = 0 + + self._input_stream = None + self._output_stream = None + + # -- capture ----------------------------------------------------------- + + def start_capture(self) -> None: + """Start streaming microphone audio to the service via a callback.""" + if self._input_stream is not None: + return + self._loop = asyncio.get_running_loop() + + def _capture_callback(in_data, _frame_count, _time_info, _status): + # Runs on a pyaudio thread: hand the frame to the event loop to append. Each call + # schedules a coroutine on the loop via a thread-safe handoff; if sending falls + # behind real-time capture (for example, network backpressure on the WebSocket), + # unconditionally scheduling a new one every callback would let pending sends + # accumulate without bound. Instead, only keep at most one in flight and drop + # (skip sending) this frame if the previous send hasn't completed yet. + assert self._loop is not None + if self._pending_send is not None and not self._pending_send.done(): + self._dropped_frames += 1 + return (None, pyaudio.paContinue) + self._input_bytes += len(in_data) + self._pending_send = asyncio.run_coroutine_threadsafe( + self._conn.input_audio_buffer.append(audio=in_data), self._loop + ) + return (None, pyaudio.paContinue) + + self._input_stream = self._audio.open( + format=pyaudio.paInt16, + channels=1, + rate=_SAMPLE_RATE, + input=True, + frames_per_buffer=_CHUNK_SAMPLES, + stream_callback=_capture_callback, + ) + + # -- playback ------------------------------------------------------------ + + def start_playback(self) -> None: + """Initialize the speaker playback callback.""" + if self._output_stream is not None: + return + remaining = b"" + # The sequence number the currently-buffered `remaining` bytes were dequeued from, so a + # barge-in that lands *between* callback invocations can still discard them below. + remaining_seq = -1 + + def _playback_callback(_in_data, frame_count, _time_info, _status): + nonlocal remaining, remaining_seq + if remaining and remaining_seq < self._playback_base: + remaining = b"" # a barge-in advanced the base since this chunk was dequeued + + wanted = frame_count * pyaudio.get_sample_size(pyaudio.paInt16) + out = remaining[:wanted] + remaining = remaining[wanted:] + + while len(out) < wanted: + try: + seq, data = self._playback_queue.get_nowait() + except queue.Empty: + out = out + bytes(wanted - len(out)) # pad with silence + continue + if not data: + # end-of-stream marker: pad up to the exact frame size pyaudio asked for + # instead of returning a short buffer, which would corrupt playback on close. + out = out + bytes(wanted - len(out)) + break + if seq < self._playback_base: + remaining = b"" # skipped by a barge-in + continue + take = wanted - len(out) + out = out + data[:take] + remaining = data[take:] + remaining_seq = seq + + return (out, pyaudio.paContinue) + + self._output_stream = self._audio.open( + format=pyaudio.paInt16, + channels=1, + rate=_SAMPLE_RATE, + output=True, + frames_per_buffer=_CHUNK_SAMPLES, + stream_callback=_playback_callback, + ) + + def _next_seq_num(self) -> int: + seq = self._next_seq + self._next_seq += 1 + return seq + + def queue_audio(self, pcm: bytes) -> None: + """Queue one decoded PCM16 chunk of the agent's reply for playback. + + :param pcm: Decoded PCM16 audio bytes. + :type pcm: bytes + """ + self._output_bytes += len(pcm) + self._playback_queue.put((self._next_seq_num(), pcm)) + + def skip_pending_audio(self) -> None: + """Drop audio still queued for playback (used on barge-in).""" + self._playback_base = self._next_seq_num() + + def shutdown(self) -> None: + """Stop capture and playback and release the audio device.""" + if self._input_stream is not None: + self._input_stream.stop_stream() + self._input_stream.close() + self._input_stream = None + if self._dropped_frames: + print(f"(dropped {self._dropped_frames} mic frame(s) while a send was still in flight)") + if self._output_stream is not None: + self.skip_pending_audio() + self._playback_queue.put((self._next_seq_num(), None)) + self._output_stream.stop_stream() + self._output_stream.close() + self._output_stream = None + self._audio.terminate() + + @property + def input_bytes_sent(self) -> int: + """Total raw PCM16 mic-audio bytes actually sent to the service (excludes dropped frames). + + :rtype: int + """ + return self._input_bytes + + @property + def output_bytes_received(self) -> int: + """Total decoded PCM16 reply-audio bytes received from the service. + + :rtype: int + """ + return self._output_bytes + + @property + def input_seconds(self) -> float: + """Total mic audio sent, in seconds (PCM16 = 2 bytes/sample). + + :rtype: float + """ + return self._input_bytes / 2 / _SAMPLE_RATE + + @property + def seconds(self) -> float: + """Total reply audio received, in seconds (PCM16 = 2 bytes/sample). + + :rtype: float + """ + return self._output_bytes / 2 / _SAMPLE_RATE + + +async def _run_audio_conversation(client: AIProjectClient, agent_name: str) -> Optional[str]: + """Hold a live, hands-free conversation with barge-in. + + :param client: The Foundry project client. + :param agent_name: The existing voice agent name. + :type client: ~azure.ai.projects.aio.AIProjectClient + :type agent_name: str + :return: The persisted conversation id, if one is created. + :rtype: str or None + """ + if pyaudio is None: + print("This sample needs pyaudio for audio: pip install pyaudio") + return None + + conversation_id: Optional[str] = None + response_active = False + + # Open the realtime session on the voice agent's dedicated route. + async with client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + # A voice agent owns its model, instructions, voice, turn detection, and + # noise suppression server-side, so this client sends no ``session.update``. + ap = _AudioProcessor(conn) + ap.start_playback() + ap.start_capture() + + print("Speak now -- the agent replies after you pause.") + print("(talk over the agent to interrupt it; press Ctrl-C to end the session)") + + try: + async for event in conn: + if isinstance(event, RealtimeServerEventSessionCreated): + # The persisted conversation id (only present when conversation + # persistence is enabled) is set here, not on response.done. + conversation_id = event.conversation_id or conversation_id + elif isinstance(event, RealtimeServerEventInputAudioBufferSpeechStarted): + # speech_started fires for every user turn, including the very first one, + # when no response is active yet. Always drop whatever reply audio is still + # queued locally -- the speaker can lag well behind the server finishing + # generation, so buffered audio can outlive response_active going false and + # must still be cleared here. Only cancel the *server-side* response (a + # separate RPC) and announce the barge-in when a response is actually in + # flight; canceling with none active is a service error. + ap.skip_pending_audio() + if response_active: + await conn.response.cancel() + print("(listening...)") + elif isinstance(event, RealtimeServerEventConversationItemInputAudioTranscriptionCompleted): + print(f"You: {event.transcript.strip()}") + elif isinstance(event, RealtimeServerEventError): + # Non-fatal errors are reported; a fatal one closes the socket. + print(f"Session error: {event.error.message}") + elif isinstance(event, RealtimeServerEventResponseCreated): + response_active = True + elif isinstance(event, RealtimeServerEventResponseAudioDelta): + # Each delta is a decoded PCM16 chunk; queue it. + ap.queue_audio(event.delta) + elif isinstance(event, RealtimeServerEventResponseAudioTranscriptDone): + _safe_print(f"Agent: {event.transcript}") + elif isinstance(event, RealtimeServerEventResponseDone): + response_active = False + except (KeyboardInterrupt, asyncio.CancelledError): + # Ctrl-C ends the session; read back whatever was persisted so far. + print("\n(ending session...)") + finally: + input_bytes = ap.input_bytes_sent + output_bytes = ap.output_bytes_received + print(f"(received {ap.seconds:.2f}s of reply audio this session)") + print( + f"Input audio (mic -> service): format=PCM16, sample_rate={_SAMPLE_RATE} Hz, channels=1, " + f"duration={ap.input_seconds:.2f}s, size={_format_size(input_bytes)}" + ) + print( + f"Output audio (service -> speakers): format=PCM16, sample_rate={_SAMPLE_RATE} Hz, channels=1, " + f"duration={ap.seconds:.2f}s, size={_format_size(output_bytes)}" + ) + print(f"Total audio transferred: size={_format_size(input_bytes + output_bytes)}") + ap.shutdown() + + return conversation_id + + +async def _read_conversation(client: AIProjectClient, agent_name: str, conversation_id: str) -> None: + """Read the persisted conversation back over the read-only conversation API. + + :param client: The Foundry project client. + :param agent_name: The voice agent name. + :param conversation_id: The persisted conversation id. + :type client: ~azure.ai.projects.aio.AIProjectClient + :type agent_name: str + :type conversation_id: str + """ + conversations = client.beta.voice_agents.conversations + + conversation = await conversations.get(agent_name, conversation_id) + print(f"Conversation {conversation.id}: status={conversation.status}, created_at={conversation.created_at}") + + print("Items (transcript):") + async for item in conversations.list_items(agent_name, conversation_id): + role = item.get("role") or item.get("type") + # Audio turns expose ``transcript``; text turns expose ``text``. + parts = [(part.get("transcript") or part.get("text") or "").strip() for part in (item.get("content") or [])] + transcript = " ".join(p for p in parts if p) + print(f" - {role} id={item.get('id')}") + if transcript: + _safe_print(f" {transcript}") + + +async def audio_conversation() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-live-audio-conversation-agent-async" + + async with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + created_version = None + try: + # 1) Create a voice agent with conversation persistence enabled (`store=True`) so the + # session's conversation can be fetched back by id afterward. + definition = VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Keep replies short and natural.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type=VoiceType.AZURE_STANDARD), + ), + output_modalities=[VoiceOutputModality.AUDIO], + store=True, + ) + created_version = await project_client.agents.create_version( + agent_name=agent_name, + definition=definition, + ) + + # 2) Hold a live microphone conversation with the freshly created agent. + print(f"Starting realtime session with agent: {agent_name}") + conversation_id = await _run_audio_conversation(project_client, agent_name) + + # 3) Fetch the persisted conversation back by id. + if conversation_id: + print(f"Reading persisted conversation {conversation_id!r}...") + try: + await _read_conversation(project_client, agent_name, conversation_id) + except HttpResponseError as e: + print(f"Could not read conversation: {e.status_code} {e.reason}") + # To fetch this session's audio afterward, use + # `project_client.beta.voice_agents.conversations`: + # - get_audio(agent_name, conversation_id) for the merged + # whole-call stereo recording's metadata, then + # download_audio(agent_name, conversation_id) to stream + # the WAV bytes. + # - get_audio_item(agent_name, conversation_id, item_id) for a + # single turn's audio metadata, then + # download_audio_item(agent_name, conversation_id, item_id) + # to stream that turn's bytes. + # See sample_voice_agent_read_conversation_audio.py for a full example. + else: + print("No conversation id was returned; nothing to read.") + except HttpResponseError as e: + print(f"Service responded with an error: {e.status_code} {e.reason}") + finally: + # 4) Clean up the agent created for this sample. + if created_version is not None: + await project_client.agents.delete_version(agent_name=agent_name, agent_version=created_version.version) + print(f"Deleted voice agent version: {created_version.version}") + + +if __name__ == "__main__": + try: + asyncio.run(audio_conversation()) + except KeyboardInterrupt: + print("\nInterrupted.") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_function_tool.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_function_tool.py new file mode 100644 index 000000000000..0921099988c6 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_function_tool.py @@ -0,0 +1,206 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates handling a client-executed `function` tool during + a live voice-agent session: + + 1) Create a voice agent configured with a `get_weather` function tool. + 2) Open a realtime session and send a text turn that should trigger the tool. + 3) Listen for `response.function_call_arguments.done`, execute the function + locally, and send the result back with `conversation.item.create` + + `response.create` so the agent can finish its reply using the tool output. + +USAGE: + python sample_voice_agent_live_function_tool.py + + Before running the sample: + + pip install "azure-ai-projects[voice]>=2.7.0" azure-identity python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the sample voice agent + created and deleted by this script. Defaults to + "sample-voice-agent-function-tool". +""" + +import json +import os +import sys +from typing import Any, Final, List, Tuple, cast + +from dotenv import load_dotenv +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + RealtimeConversationItemFunctionCallOutput, + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventError, + VoiceAgentDefinition, + VoiceAgentFunctionTool, + RealtimeServerEventResponseDone, + RealtimeServerEventResponseFunctionCallArgumentsDone, + RealtimeServerEventResponseTextDone, + VoiceModelType, + VoiceOutputModality, +) + +load_dotenv() + +# Seconds to wait for the agent to finish a response. +_RESPONSE_TIMEOUT: Final = 45 + + +def get_weather(city: str) -> str: + """A trivial local "tool" implementation the agent can call. + + :param city: The city to look up. + :type city: str + :return: A canned weather report for the city. + :rtype: str + """ + return json.dumps({"city": city, "condition": "sunny", "temperature_f": 72}) + + +def _safe_print(text: str) -> None: + """Print text that may contain characters the current console can't display. + + The agent's reply below is model-generated and can contain characters (curly + quotes, em-dashes, etc.) outside some legacy, non-Unicode console encodings + (for example when stdout is piped/redirected on Windows). Rather than crashing + with UnicodeEncodeError, fall back to replacing just the unsupported characters; + a real interactive UTF-8 console prints unaffected. + """ + try: + print(text) + except UnicodeEncodeError: + encoding = sys.stdout.encoding or "ascii" + print(text.encode(encoding, errors="replace").decode(encoding)) + + +def _run_turn_with_tool_support(client: AIProjectClient, agent_name: str, prompt: str) -> None: + """Send one turn and resolve any function-call the agent makes before printing its reply. + + :param client: The Foundry project client. + :param agent_name: The voice agent name. + :param prompt: The user's message for this turn. + :type client: ~azure.ai.projects.AIProjectClient + :type agent_name: str + :type prompt: str + """ + with client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text=prompt)], + ) + ) + conn.response.create() + + # Tool outputs collected from the current turn's function-call(s). These are held back + # and only sent once this turn's own response.done arrives (below) -- calling + # response.create() while the function-call response is still finishing can otherwise + # race with the service and produce a concurrent-response error. + pending_tool_outputs: List[Tuple[str, str]] = [] + while True: + try: + event = conn.recv(timeout=_RESPONSE_TIMEOUT) + except TimeoutError: + print("Timed out waiting for the agent's reply.") + conn.response.cancel() + return + if isinstance(event, RealtimeServerEventResponseFunctionCallArgumentsDone): + # The service forwards the call to us; execute it locally now, but defer sending + # the result until this response's own response.done arrives. + args = json.loads(event.arguments) + print(f"Tool call: {event.name}({args})") + if event.name == "get_weather": + result = get_weather(**args) + else: + result = json.dumps({"error": f"Unknown tool: {event.name}"}) + pending_tool_outputs.append((event.call_id, result)) + elif isinstance(event, RealtimeServerEventResponseTextDone): + # The sample agent uses a text-only output modality, so the + # reply arrives as output text rather than an audio transcript. + _safe_print(f"Agent: {event.text}") + elif isinstance(event, RealtimeServerEventResponseDone): + # A response.done that isn't a function call is the final answer for this turn. + # Output items are typed models in the tested scenarios here, but the underlying + # union is open (forward-compatible with item kinds this SDK doesn't map yet), so + # an unrecognized kind could still surface as a plain mapping; check both. + if pending_tool_outputs: + # The function-call response has now fully completed, so it's safe to submit + # its tool output(s) and ask for a new response. + for call_id, result in pending_tool_outputs: + conn.conversation.item.create( + item=RealtimeConversationItemFunctionCallOutput(call_id=call_id, output=result) + ) + pending_tool_outputs = [] + conn.response.create() + elif not any( + (item.get("type") if isinstance(item, dict) else getattr(item, "type", None)) == "function_call" + for item in (event.response.output or []) + ): + return + elif isinstance(event, RealtimeServerEventError): + print(f"Session error: {event.error.message}") + return + + +def main() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-voice-agent-function-tool" + + get_weather_tool = VoiceAgentFunctionTool( + name="get_weather", + description="Get the current weather for a city.", + parameters=cast( + Any, + { + "type": "object", + "properties": {"city": {"type": "string", "description": "City name, e.g. Seattle."}}, + "required": ["city"], + }, + ), + ) + + with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + created_version = None + try: + created_version = project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions=( + "You are a helpful voice assistant. Use the get_weather tool when the " + "caller asks about the weather, then answer using its result." + ), + output_modalities=[VoiceOutputModality.TEXT], + tools=[get_weather_tool], + ), + ) + print(f"Created voice agent: {agent_name}") + + _run_turn_with_tool_support(project_client, agent_name, "What's the weather like in Seattle right now?") + finally: + if created_version is not None: + project_client.agents.delete_version(agent_name=agent_name, agent_version=created_version.version) + print(f"Deleted voice agent version: {created_version.version}") + + +if __name__ == "__main__": + main() diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation.py new file mode 100644 index 000000000000..db36065a3d40 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation.py @@ -0,0 +1,416 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + End-to-end typed conversation using the ``client.beta.voice_agents.realtime`` namespace added + on top of the generated azure-ai-projects client (see + ``azure.ai.projects.operations.BetaRealtime``). + + 1. Create a voice agent with conversation persistence enabled + (`store=True`) so the conversation can be read back afterward. + 2. Hold a typed, multi-turn conversation: each prompt is sent as a + ``RealtimeConversationItemMessageUser`` and the reply streams back as + typed audio and transcript events. Blank line (or ``exit`` / ``quit``) + ends it. + 3. Fetch the persisted conversation back by id. + 4. Delete the agent created for this sample. + + Reply audio is PCM16, mono, 24 kHz and plays through the speakers when + ``pyaudio`` is installed; runs headless otherwise. For a hands-free mic + conversation with barge-in, see sample_voice_agent_live_audio_conversation_async.py + (that sample needs concurrent send/receive so it stays async-only; see + sample_voice_agent_live_text_conversation_async.py for the async version of + this one). + + pip install "azure-ai-projects[voice]>=2.7.0" azure-identity pyaudio + +USAGE: + python sample_voice_agent_live_text_conversation.py + + Environment variables: + 1) FOUNDRY_PROJECT_ENDPOINT (required) - Foundry project endpoint: + https://.services.ai.azure.com/api/projects/ + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the agent created by this + sample. Defaults to "sample-live-text-conversation-agent". + + Authenticates with DefaultAzureCredential, so sign in first (e.g. `az login`). +""" + +import os +import sys +import time +from typing import Final, Optional, TYPE_CHECKING + +from dotenv import load_dotenv +from azure.core.exceptions import HttpResponseError +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseCreated, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + RealtimeServerEventError, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceAgentTemplateGreetingConfig, + VoiceModelType, + VoiceOutputModality, + VoiceType, +) + +if TYPE_CHECKING: + from azure.ai.projects.operations import BetaRealtimeConnection + + +load_dotenv() + + +def _safe_print(text: str) -> None: + """Print text that may contain characters the current console can't display. + + The agent's replies below are model-generated and can contain characters (curly + quotes, em-dashes, etc.) outside some legacy, non-Unicode console encodings + (for example when stdout is piped/redirected on Windows). Rather than crashing + with UnicodeEncodeError, fall back to replacing just the unsupported characters; + a real interactive UTF-8 console prints unaffected. + """ + try: + print(text) + except UnicodeEncodeError: + encoding = sys.stdout.encoding or "ascii" + print(text.encode(encoding, errors="replace").decode(encoding)) + + +# Seconds to wait for the agent to finish its reply. +_RESPONSE_TIMEOUT: Final = 45 + +# Reply audio format: PCM16, mono, 24 kHz. +_SAMPLE_RATE: Final = 24000 + + +def _format_size(num_bytes: int) -> str: + """Format a byte count as a human-readable string. + + :param num_bytes: The size in bytes. + :type num_bytes: int + :return: A string like "12345 bytes (12.1 KB)" or "2097152 bytes (2.00 MB)". + :rtype: str + """ + if num_bytes < 1024: + return f"{num_bytes} bytes" + if num_bytes < 1024 * 1024: + return f"{num_bytes} bytes ({num_bytes / 1024:.1f} KB)" + return f"{num_bytes} bytes ({num_bytes / (1024 * 1024):.2f} MB)" + + +try: + import pyaudio # type: ignore[import-not-found] +except ImportError: # pragma: no cover - optional playback dependency + pyaudio = None # type: ignore[assignment] + + +class _SpeakerPlayer: + """Play streamed PCM16 audio through the speakers with pyaudio. + + Optional: without pyaudio the player is a no-op and the sample still runs + headless, reporting how much audio it received. + """ + + def __init__(self) -> None: + self._audio = None + self._stream = None + self._bytes = 0 + if pyaudio is not None: + self._audio = pyaudio.PyAudio() + self._stream = self._audio.open( + format=pyaudio.paInt16, + channels=1, + rate=_SAMPLE_RATE, + output=True, + ) + + @property + def enabled(self) -> bool: + return self._stream is not None + + def play(self, pcm: bytes) -> None: + """Write one decoded PCM16 chunk to the speaker. + + :param pcm: Decoded PCM16 audio bytes. + :type pcm: bytes + """ + self._bytes += len(pcm) + if self._stream is not None: + self._stream.write(pcm) + + def close(self) -> None: + """Drain and release the audio device.""" + if self._stream is not None: + self._stream.stop_stream() + self._stream.close() + self._stream = None + if self._audio is not None: + self._audio.terminate() + self._audio = None + + @property + def bytes_received(self) -> int: + """Total decoded PCM16 output-audio bytes received from the service. + + :rtype: int + """ + return self._bytes + + @property + def seconds(self) -> float: + """Total audio received, in seconds (PCM16 = 2 bytes/sample). + + :rtype: float + """ + return self._bytes / 2 / _SAMPLE_RATE + + +class _CancellationNotConfirmed(Exception): + """Raised when a just-cancelled response's terminal event could not be confirmed within + ``_RESPONSE_TIMEOUT``, leaving the stream in an unknown state.""" + + +def _drain_cancelled_response(conn: "BetaRealtimeConnection", response_id: Optional[str]) -> None: + """Wait (bounded) for a just-cancelled response's terminal event, discarding it and any of + its trailing content events, so the next turn's ``pump()`` doesn't mistake this stale + completion for its own. + + :param conn: The open realtime connection. + :param response_id: The id of the response that was just cancelled, if it was captured from + that response's ``response.created`` event. If None, the first terminal event seen is + accepted, since there is nothing more specific to correlate against. + :type conn: ~azure.ai.projects.BetaRealtimeConnection + :type response_id: str or None + :raises _CancellationNotConfirmed: If no matching terminal event arrives in time. + """ + deadline = time.monotonic() + _RESPONSE_TIMEOUT + while True: + remaining = deadline - time.monotonic() + if remaining <= 0: + raise _CancellationNotConfirmed("Timed out waiting to confirm the cancelled response finished.") + try: + event = conn.recv(timeout=remaining) + except TimeoutError as exc: + raise _CancellationNotConfirmed("Timed out waiting to confirm the cancelled response finished.") from exc + if isinstance(event, RealtimeServerEventResponseDone): + if response_id is None or event.response.id == response_id: + return + # A stray completion for some other response id; keep draining. + elif isinstance(event, RealtimeServerEventError): + print(f"Session error while confirming cancellation: {event.error.message}") + + +def _run_text_conversation( # pylint: disable=too-many-statements + client: AIProjectClient, agent_name: str, has_greeting: bool +) -> Optional[str]: + """Hold a typed, multi-turn conversation. + + :param client: The Foundry project client. + :param agent_name: The existing voice agent name. + :param has_greeting: Whether the agent has a configured greeting, which the service plays + automatically as soon as the session opens (before any user turn). When True, that greeting + is drained and displayed before the interactive loop starts. + :type client: ~azure.ai.projects.AIProjectClient + :type agent_name: str + :type has_greeting: bool + :return: The persisted conversation id, if one is created. + :rtype: str or None + """ + conversation_id: Optional[str] = None + audio_delta_count = 0 + player = _SpeakerPlayer() + played = False + + try: + # Open the realtime session on the voice agent's dedicated route. + with client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + + def pump() -> None: + nonlocal conversation_id, audio_delta_count + active_response_id: Optional[str] = None + while True: + try: + event = conn.recv(timeout=_RESPONSE_TIMEOUT) + except TimeoutError: + print("Timed out waiting for the agent's reply.") + conn.response.cancel(response_id=active_response_id) + # Consume the cancellation's own terminal event now, before the next + # turn starts: otherwise a late response.done for *this* cancelled + # response could be mistaken by the next pump() call for its own, + # ending it early and silently dropping the real next reply. + _drain_cancelled_response(conn, active_response_id) + return + if isinstance(event, RealtimeServerEventSessionCreated): + # The persisted conversation id (only present when conversation + # persistence is enabled) is set here, not on response.done. + conversation_id = event.conversation_id or conversation_id + if isinstance(event, RealtimeServerEventResponseCreated): + active_response_id = event.response.id + if isinstance(event, RealtimeServerEventResponseDone): + return + if isinstance(event, RealtimeServerEventError): + print(f"Session error: {event.error.message}") + return + if isinstance(event, RealtimeServerEventResponseAudioDelta): + # Each delta is a decoded PCM16 chunk; play it. + audio_delta_count += 1 + player.play(event.delta) + elif isinstance(event, RealtimeServerEventResponseAudioTranscriptDone): + _safe_print(f"Agent: {event.transcript}") + + if has_greeting: + # The service sends the configured greeting as its own response cycle the + # instant the session opens, entirely independent of any user turn. Drain and + # display it here, before the interactive loop starts: otherwise the first + # pump() call below (triggered by the user's own first message) could instead + # observe this unrelated, already in-flight response.done and return early, + # silently dropping the real reply to what the user actually typed. + print("(agent is greeting...)") + pump() + + print("Type a message and press Enter. Blank line (or 'exit') ends the session.") + + while True: + prompt = input("You: ").strip() + if not prompt or prompt.lower() in ("exit", "quit"): + break + + # Send the turn and ask the agent to respond. + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text=prompt)], + ) + ) + conn.response.create() + pump() + except KeyboardInterrupt: + print("\n(ending session...)") + except _CancellationNotConfirmed: + print("Could not confirm a cancelled response finished; ending the session.") + finally: + played = player.enabled + player.close() + + detail = "played" if played else "received" + output_bytes = player.bytes_received + print(f"(streamed {audio_delta_count} audio chunks, {detail} {player.seconds:.2f}s of audio)") + print( + f"Output audio: format=PCM16, sample_rate={_SAMPLE_RATE} Hz, channels=1, " + f"duration={player.seconds:.2f}s, size={_format_size(output_bytes)}" + ) + if not played: + print("(install pyaudio to hear the reply: pip install pyaudio)") + return conversation_id + + +def _read_conversation(client: AIProjectClient, agent_name: str, conversation_id: str) -> None: + """Read the persisted conversation back over the read-only conversation API. + + :param client: The Foundry project client. + :param agent_name: The voice agent name. + :param conversation_id: The persisted conversation id. + :type client: ~azure.ai.projects.AIProjectClient + :type agent_name: str + :type conversation_id: str + """ + conversations = client.beta.voice_agents.conversations + + conversation = conversations.get(agent_name, conversation_id) + print(f"Conversation {conversation.id}: status={conversation.status}, created_at={conversation.created_at}") + + print("Items (transcript):") + for item in conversations.list_items(agent_name, conversation_id): + role = item.get("role") or item.get("type") + # Audio turns expose ``transcript``; text turns expose ``text``. + parts = [(part.get("transcript") or part.get("text") or "").strip() for part in (item.get("content") or [])] + transcript = " ".join(p for p in parts if p) + print(f" - {role} id={item.get('id')}") + if transcript: + _safe_print(f" {transcript}") + + +def text_conversation() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-live-text-conversation-agent" + + with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + created_version = None + try: + # 1) Create a voice agent with conversation persistence enabled (`store=True`) so the + # session's conversation can be fetched back by id afterward. + definition = VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Keep replies short and natural.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type=VoiceType.AZURE_STANDARD), + ), + output_modalities=[VoiceOutputModality.AUDIO], + greeting=VoiceAgentTemplateGreetingConfig(text="Hi, I'm here to help. What can I do for you?"), + store=True, + ) + created_version = project_client.agents.create_version( + agent_name=agent_name, + definition=definition, + ) + + # 2) Hold the realtime conversation against the freshly created agent. + print(f"Starting realtime session with agent: {agent_name}") + conversation_id = _run_text_conversation(project_client, agent_name, has_greeting=True) + + # 3) Fetch the persisted conversation back by id. + if conversation_id: + print(f"Reading persisted conversation {conversation_id}...") + try: + _read_conversation(project_client, agent_name, conversation_id) + except HttpResponseError as e: + print(f"Could not read conversation: {e.status_code} {e.reason}") + # To fetch this session's audio afterward, use + # `project_client.beta.voice_agents.conversations`: + # - get_audio(agent_name, conversation_id) for the merged + # whole-call stereo recording's metadata, then + # download_audio(agent_name, conversation_id) to stream + # the WAV bytes. + # - get_audio_item(agent_name, conversation_id, item_id) for a + # single turn's audio metadata, then + # download_audio_item(agent_name, conversation_id, item_id) + # to stream that turn's bytes. + # See sample_voice_agent_read_conversation_audio.py for a full example. + else: + print("No conversation id was returned; nothing to read.") + except HttpResponseError as e: + print(f"Service responded with an error: {e.status_code} {e.reason}") + finally: + # 4) Clean up the agent created for this sample. + if created_version is not None: + project_client.agents.delete_version(agent_name=agent_name, agent_version=created_version.version) + print(f"Deleted voice agent version: {created_version.version}") + + +if __name__ == "__main__": + try: + text_conversation() + except KeyboardInterrupt: + print("\nInterrupted.") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation_async.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation_async.py new file mode 100644 index 000000000000..8082e7614b50 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_live_text_conversation_async.py @@ -0,0 +1,423 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + End-to-end typed conversation using the ``client.beta.voice_agents.realtime`` namespace added + on top of the generated azure-ai-projects client (see + ``azure.ai.projects.aio.operations.AsyncBetaRealtime``). + + 1. Create a voice agent with conversation persistence enabled + (`store=True`) so the conversation can be read back afterward. + 2. Hold a typed, multi-turn conversation: each prompt is sent as a + ``RealtimeConversationItemMessageUser`` and the reply streams back as + typed audio and transcript events. Blank line (or ``exit`` / ``quit``) + ends it. + 3. Fetch the persisted conversation back by id. + 4. Delete the agent created for this sample. + + Reply audio is PCM16, mono, 24 kHz and plays through the speakers when + ``pyaudio`` is installed; runs headless otherwise. For a hands-free mic + conversation with barge-in, see sample_voice_agent_live_audio_conversation_async.py. + + pip install "azure-ai-projects[voice]>=2.7.0" azure-identity pyaudio + +USAGE: + python sample_voice_agent_live_text_conversation_async.py + + Environment variables: + 1) FOUNDRY_PROJECT_ENDPOINT (required) - Foundry project endpoint: + https://.services.ai.azure.com/api/projects/ + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. Name for the agent created by this + sample. Defaults to "sample-live-text-conversation-agent-async". + + Authenticates with DefaultAzureCredential, so sign in first (e.g. `az login`). +""" + +import asyncio +import os +import sys +from typing import Final, Optional + +from dotenv import load_dotenv +from azure.core.exceptions import HttpResponseError +from azure.identity.aio import DefaultAzureCredential + +# AsyncBetaRealtimeConnection is re-exported dynamically via aio/operations/_patch.py's `__all__`; +# pylint's static import resolution cannot trace that, but the symbol is valid (verified by +# Pyright/mypy). +from azure.ai.projects.aio.operations import AsyncBetaRealtimeConnection # pylint: disable=no-name-in-module +from azure.ai.projects.aio import AIProjectClient +from azure.ai.projects.models import ( + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseCreated, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + RealtimeServerEventError, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceAgentTemplateGreetingConfig, + VoiceModelType, + VoiceOutputModality, + VoiceType, +) + +load_dotenv() + + +def _safe_print(text: str) -> None: + """Print text that may contain characters the current console can't display. + + The agent's replies below are model-generated and can contain characters (curly + quotes, em-dashes, etc.) outside some legacy, non-Unicode console encodings + (for example when stdout is piped/redirected on Windows). Rather than crashing + with UnicodeEncodeError, fall back to replacing just the unsupported characters; + a real interactive UTF-8 console prints unaffected. + """ + try: + print(text) + except UnicodeEncodeError: + encoding = sys.stdout.encoding or "ascii" + print(text.encode(encoding, errors="replace").decode(encoding)) + + +# Seconds to wait for the agent to finish its reply. +_RESPONSE_TIMEOUT: Final = 45 + +# Reply audio format: PCM16, mono, 24 kHz. +_SAMPLE_RATE: Final = 24000 + + +def _format_size(num_bytes: int) -> str: + """Format a byte count as a human-readable string. + + :param num_bytes: The size in bytes. + :type num_bytes: int + :return: A string like "12345 bytes (12.1 KB)" or "2097152 bytes (2.00 MB)". + :rtype: str + """ + if num_bytes < 1024: + return f"{num_bytes} bytes" + if num_bytes < 1024 * 1024: + return f"{num_bytes} bytes ({num_bytes / 1024:.1f} KB)" + return f"{num_bytes} bytes ({num_bytes / (1024 * 1024):.2f} MB)" + + +try: + import pyaudio # type: ignore[import-not-found] +except ImportError: # pragma: no cover - optional playback dependency + pyaudio = None # type: ignore[assignment] + + +class _SpeakerPlayer: + """Play streamed PCM16 audio through the speakers with pyaudio. + + Optional: without pyaudio the player is a no-op and the sample still runs + headless, reporting how much audio it received. + """ + + def __init__(self) -> None: + self._audio = None + self._stream = None + self._bytes = 0 + if pyaudio is not None: + self._audio = pyaudio.PyAudio() + self._stream = self._audio.open( + format=pyaudio.paInt16, + channels=1, + rate=_SAMPLE_RATE, + output=True, + ) + + @property + def enabled(self) -> bool: + return self._stream is not None + + def play(self, pcm: bytes) -> None: + """Write one decoded PCM16 chunk to the speaker. + + :param pcm: Decoded PCM16 audio bytes. + :type pcm: bytes + """ + self._bytes += len(pcm) + if self._stream is not None: + self._stream.write(pcm) + + def close(self) -> None: + """Drain and release the audio device.""" + if self._stream is not None: + self._stream.stop_stream() + self._stream.close() + self._stream = None + if self._audio is not None: + self._audio.terminate() + self._audio = None + + @property + def bytes_received(self) -> int: + """Total decoded PCM16 output-audio bytes received from the service. + + :rtype: int + """ + return self._bytes + + @property + def seconds(self) -> float: + """Total audio received, in seconds (PCM16 = 2 bytes/sample). + + :rtype: float + """ + return self._bytes / 2 / _SAMPLE_RATE + + +class _CancellationNotConfirmed(Exception): + """Raised when a just-cancelled response's terminal event could not be confirmed within + ``_RESPONSE_TIMEOUT``, leaving the stream in an unknown state.""" + + +async def _drain_cancelled_response(conn: "AsyncBetaRealtimeConnection", response_id: Optional[str]) -> None: + """Wait (bounded) for a just-cancelled response's terminal event, discarding it and any of + its trailing content events, so the next turn's ``pump()`` doesn't mistake this stale + completion for its own. + + :param conn: The open realtime connection. + :param response_id: The id of the response that was just cancelled, if it was captured from + that response's ``response.created`` event. If None, the first terminal event seen is + accepted, since there is nothing more specific to correlate against. + :type conn: ~azure.ai.projects.aio.AsyncBetaRealtimeConnection + :type response_id: str or None + :raises _CancellationNotConfirmed: If no matching terminal event arrives in time. + """ + + async def _drain() -> None: + async for event in conn: + if isinstance(event, RealtimeServerEventResponseDone): + if response_id is None or event.response.id == response_id: + return + # A stray completion for some other response id; keep draining. + elif isinstance(event, RealtimeServerEventError): + print(f"Session error while confirming cancellation: {event.error.message}") + + try: + await asyncio.wait_for(_drain(), timeout=_RESPONSE_TIMEOUT) + except asyncio.TimeoutError as exc: + raise _CancellationNotConfirmed("Timed out waiting to confirm the cancelled response finished.") from exc + + +async def _run_text_conversation( # pylint: disable=too-many-statements + client: AIProjectClient, agent_name: str, has_greeting: bool +) -> Optional[str]: + """Hold a typed, multi-turn conversation. + + :param client: The Foundry project client. + :param agent_name: The existing voice agent name. + :param has_greeting: Whether the agent has a configured greeting, which the service plays + automatically as soon as the session opens (before any user turn). When True, that greeting + is drained and displayed before the interactive loop starts. + :type client: ~azure.ai.projects.aio.AIProjectClient + :type agent_name: str + :type has_greeting: bool + :return: The persisted conversation id, if one is created. + :rtype: str or None + """ + conversation_id: Optional[str] = None + audio_delta_count = 0 + active_response_id: Optional[str] = None + player = _SpeakerPlayer() + + try: + # Open the realtime session on the voice agent's dedicated route. + async with client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + + async def pump() -> None: + nonlocal conversation_id, audio_delta_count, active_response_id + async for event in conn: + if isinstance(event, RealtimeServerEventSessionCreated): + # The persisted conversation id (only present when conversation + # persistence is enabled) is set here, not on response.done. + conversation_id = event.conversation_id or conversation_id + if isinstance(event, RealtimeServerEventResponseCreated): + active_response_id = event.response.id + if isinstance(event, RealtimeServerEventResponseDone): + return + if isinstance(event, RealtimeServerEventError): + print(f"Session error: {event.error.message}") + return + if isinstance(event, RealtimeServerEventResponseAudioDelta): + # Each delta is a decoded PCM16 chunk; play it. + audio_delta_count += 1 + player.play(event.delta) + elif isinstance(event, RealtimeServerEventResponseAudioTranscriptDone): + _safe_print(f"Agent: {event.transcript}") + + if has_greeting: + # The service sends the configured greeting as its own response cycle the + # instant the session opens, entirely independent of any user turn. Drain and + # display it here, before the interactive loop starts: otherwise the first + # pump() call below (triggered by the user's own first message) could instead + # observe this unrelated, already in-flight response.done and return early, + # silently dropping the real reply to what the user actually typed. + print("(agent is greeting...)") + try: + await asyncio.wait_for(pump(), timeout=_RESPONSE_TIMEOUT) + except asyncio.TimeoutError: + print("Timed out waiting for the agent's greeting.") + await conn.response.cancel(response_id=active_response_id) + # Consume the cancellation's own terminal event now, before the next turn + # starts: otherwise a late response.done for *this* cancelled response could + # be mistaken by the next pump() call for its own, ending it early and + # silently dropping the real next reply. + await _drain_cancelled_response(conn, active_response_id) + + print("Type a message and press Enter. Blank line (or 'exit') ends the session.") + + while True: + # input() blocks, so read it off the loop in a worker thread. + prompt = (await asyncio.to_thread(input, "You: ")).strip() + if not prompt or prompt.lower() in ("exit", "quit"): + break + + # Send the turn and ask the agent to respond. + await conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text=prompt)], + ) + ) + await conn.response.create() + + try: + await asyncio.wait_for(pump(), timeout=_RESPONSE_TIMEOUT) + except asyncio.TimeoutError: + print("Timed out waiting for the agent's reply.") + # The server-side response is still active even though we stopped waiting + # locally; cancel it so the next turn's response.create() isn't rejected. + # Then consume its terminal event now, before the next turn starts: + # otherwise a late response.done for *this* cancelled response could be + # mistaken by the next pump() call for its own, ending it early and + # silently dropping the real next reply. + await conn.response.cancel(response_id=active_response_id) + await _drain_cancelled_response(conn, active_response_id) + except (KeyboardInterrupt, asyncio.CancelledError): + print("\n(ending session...)") + except _CancellationNotConfirmed: + print("Could not confirm a cancelled response finished; ending the session.") + finally: + played = player.enabled + player.close() + + detail = "played" if played else "received" + output_bytes = player.bytes_received + print(f"(streamed {audio_delta_count} audio chunks, {detail} {player.seconds:.2f}s of audio)") + print( + f"Output audio: format=PCM16, sample_rate={_SAMPLE_RATE} Hz, channels=1, " + f"duration={player.seconds:.2f}s, size={_format_size(output_bytes)}" + ) + if not played: + print("(install pyaudio to hear the reply: pip install pyaudio)") + return conversation_id + + +async def _read_conversation(client: AIProjectClient, agent_name: str, conversation_id: str) -> None: + """Read the persisted conversation back over the read-only conversation API. + + :param client: The Foundry project client. + :param agent_name: The voice agent name. + :param conversation_id: The persisted conversation id. + :type client: ~azure.ai.projects.aio.AIProjectClient + :type agent_name: str + :type conversation_id: str + """ + conversations = client.beta.voice_agents.conversations + + conversation = await conversations.get(agent_name, conversation_id) + print(f"Conversation {conversation.id}: status={conversation.status}, created_at={conversation.created_at}") + + print("Items (transcript):") + async for item in conversations.list_items(agent_name, conversation_id): + role = item.get("role") or item.get("type") + # Audio turns expose ``transcript``; text turns expose ``text``. + parts = [(part.get("transcript") or part.get("text") or "").strip() for part in (item.get("content") or [])] + transcript = " ".join(p for p in parts if p) + print(f" - {role} id={item.get('id')}") + if transcript: + _safe_print(f" {transcript}") + + +async def text_conversation() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-live-text-conversation-agent-async" + + async with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + created_version = None + try: + # 1) Create a voice agent with conversation persistence enabled (`store=True`) so the + # session's conversation can be fetched back by id afterward. + definition = VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Keep replies short and natural.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type=VoiceType.AZURE_STANDARD), + ), + output_modalities=[VoiceOutputModality.AUDIO], + greeting=VoiceAgentTemplateGreetingConfig(text="Hi, I'm here to help. What can I do for you?"), + store=True, + ) + created_version = await project_client.agents.create_version( + agent_name=agent_name, + definition=definition, + ) + + # 2) Hold the realtime conversation against the freshly created agent. + print(f"Starting realtime session with agent: {agent_name}") + conversation_id = await _run_text_conversation(project_client, agent_name, has_greeting=True) + + # 3) Fetch the persisted conversation back by id. + if conversation_id: + print(f"Reading persisted conversation {conversation_id}...") + try: + await _read_conversation(project_client, agent_name, conversation_id) + except HttpResponseError as e: + print(f"Could not read conversation: {e.status_code} {e.reason}") + # To fetch this session's audio afterward, use + # `project_client.beta.voice_agents.conversations`: + # - get_audio(agent_name, conversation_id) for the merged + # whole-call stereo recording's metadata, then + # download_audio(agent_name, conversation_id) to stream + # the WAV bytes. + # - get_audio_item(agent_name, conversation_id, item_id) for a + # single turn's audio metadata, then + # download_audio_item(agent_name, conversation_id, item_id) + # to stream that turn's bytes. + # See sample_voice_agent_read_conversation_audio.py for a full example. + else: + print("No conversation id was returned; nothing to read.") + except HttpResponseError as e: + print(f"Service responded with an error: {e.status_code} {e.reason}") + finally: + # 4) Clean up the agent created for this sample. + if created_version is not None: + await project_client.agents.delete_version(agent_name=agent_name, agent_version=created_version.version) + print(f"Deleted voice agent version: {created_version.version}") + + +if __name__ == "__main__": + try: + asyncio.run(text_conversation()) + except KeyboardInterrupt: + print("\nInterrupted.") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation.py new file mode 100644 index 000000000000..2f3fd28b2a33 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation.py @@ -0,0 +1,145 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates reading a persisted voice conversation back over + the read-only conversation API exposed by `project_client.beta.voice_agents.conversations`: + the conversation envelope, its responses (model inference turns), and its + ordered items (the transcript). Conversations are created and written by + the voice orchestrator during a live session; this client can only read + them, and only when the agent was configured with `store=True` (see + sample_voice_agent_basic.py). + + Runs with no setup beyond the endpoint: if FOUNDRY_VOICE_CONVERSATION_ID is + not set, this sample creates a temporary voice agent, holds one short + realtime text turn to produce a real conversation, reads it back, then + deletes the agent version it created. Set FOUNDRY_VOICE_AGENT_NAME to hold + that conversation against your own existing agent instead -- it is never + created, modified, or deleted by this sample. Additionally set + FOUNDRY_VOICE_CONVERSATION_ID to skip holding a new conversation entirely + and just read back one your agent already produced. + +USAGE: + python sample_voice_agent_read_conversation.py + + Before running the sample: + + pip install "azure-ai-projects[voice]>=2.7.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of an existing voice agent + (configured with `store=True`) to hold or read a conversation on. + Defaults to a temporary agent, created and deleted by this sample, when + unset. + 3) FOUNDRY_VOICE_CONVERSATION_ID - Optional. The id of a persisted + conversation owned by FOUNDRY_VOICE_AGENT_NAME. If unset, this sample + holds one short realtime text turn to produce one; see + voice_sample_util.py in this folder and + sample_voice_agent_live_text_conversation.py for a full interactive + version. + 4) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name, + used only when creating the temporary agent. Defaults to "gpt-realtime". +""" + +import os +from dotenv import load_dotenv +from azure.core.exceptions import HttpResponseError +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceModelType, + VoiceOutputModality, + VoiceType, +) + +from voice_sample_util import hold_sample_conversation + +load_dotenv() + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") +conversation_id = os.environ.get("FOUNDRY_VOICE_CONVERSATION_ID") +model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" +# Only create (and later clean up) a temporary agent when the caller didn't name their own -- +# creating a version on someone's existing agent could unexpectedly mutate it, and deleting that +# version afterward could delete the agent entirely if it was the agent's only version. +owns_agent = not agent_name +agent_name = agent_name or "sample-read-conversation-agent" + +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, +): + conversations = project_client.beta.voice_agents.conversations + created_version = None + try: + if not conversation_id: + print(f"No FOUNDRY_VOICE_CONVERSATION_ID set; holding a short conversation with '{agent_name}' first...") + if owns_agent: + created_version = project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Keep replies short and natural.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig( + voice="en-US-AvaNeural", voice_type=VoiceType.AZURE_STANDARD + ), + ), + output_modalities=[VoiceOutputModality.AUDIO], + store=True, + ), + ) + conversation_id = hold_sample_conversation(project_client, agent_name) + print(f"Created conversation: {conversation_id}") + + # The conversation envelope: status, timestamps, aggregate usage. + conversation = conversations.get(agent_name, conversation_id) + print(f"Conversation {conversation.id}: status={conversation.status}, created_at={conversation.created_at}") + + # The responses (model inference turns) in the conversation. + print("Responses:") + for response in conversations.list_responses(agent_name, conversation_id): + print(f" - {response.id}: status={response.status}") + + # Read a single response back, with its output and token usage. + detail = conversations.get_response(agent_name, conversation_id, response.id) + print(f" usage={detail.usage}") + + # The items produced by this specific response. Conversation items + # belong to an open union, so on read they surface as mappings + # keyed by their wire fields (``type``, ``id``, ...). + for response_item in conversations.list_response_items(agent_name, conversation_id, response.id): + print(f" item {response_item.get('type')} id={response_item.get('id')}") + + # The ordered conversation items -- the full transcript (user + assistant + tool events). + print("Items (transcript):") + for item in conversations.list_items(agent_name, conversation_id): + item_id = item.get("id") + print(f" - {item.get('type')} id={item_id}") + + # Read a single item back by id. + if item_id: + single = conversations.get_item(agent_name, conversation_id, item_id) + print(f" fetched item id={single.get('id')}") + + # Deleting a conversation removes it and all of its responses, items, and audio. + # This is destructive, so it is shown but not run by default. Uncomment to enable. + # deleted = conversations.delete(agent_name, conversation_id) + # print(f"Deleted conversation {deleted.id}: deleted={deleted.deleted}") + except HttpResponseError as e: + # 404 typically means the conversation was not persisted (agent ran with `store=False`). + print(f"Service responded with an error: {e.status_code} {e.reason}") + finally: + if created_version is not None: + project_client.agents.delete_version(agent_name=agent_name, agent_version=created_version.version) + print(f"Deleted temporary voice agent version: {created_version.version}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation_audio.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation_audio.py new file mode 100644 index 000000000000..3d8c0dbf6190 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_read_conversation_audio.py @@ -0,0 +1,211 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates reading the persisted audio of a voice + conversation via `project_client.beta.voice_agents.conversations`, both the + merged whole-call recording and a single turn's audio segment. For each it + reads the metadata first, then streams the WAV bytes to a local file. The + merged recording is stereo: the caller on the left channel and the agent + on the right. + + Audio is available only after the session has ended and only when the + agent was configured with `store=True`. For bring-your-own-storage (BYOS) + accounts the metadata carries a `blob_uri` instead, and the bytes are read + from your own storage rather than streamed here. + + Runs with no setup beyond the endpoint: if FOUNDRY_VOICE_CONVERSATION_ID is + not set, this sample creates a temporary voice agent, holds one short + realtime text turn to produce a real conversation, then reads its audio + back -- the agent's reply is real synthesized speech either way, so both + the merged recording and the reply's own audio segment are available even + though the turn itself was typed. Set FOUNDRY_VOICE_AGENT_NAME to hold that + conversation against your own existing agent instead -- it is never + created, modified, or deleted by this sample. Additionally set + FOUNDRY_VOICE_CONVERSATION_ID to skip holding a new conversation entirely + and just read back the audio of one your agent already produced. + +USAGE: + python sample_voice_agent_read_conversation_audio.py + + Before running the sample: + + pip install "azure-ai-projects[voice]>=2.7.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of an existing voice + agent (configured with `store=True`) to hold or read a conversation on. + Defaults to a temporary agent, created and deleted by this sample, when + unset. + 3) FOUNDRY_VOICE_CONVERSATION_ID - Optional. The id of a persisted + conversation owned by FOUNDRY_VOICE_AGENT_NAME. If unset, this sample + holds one short realtime text turn to produce one; see + voice_sample_util.py in this folder and + sample_voice_agent_live_text_conversation.py for a full interactive + version. + 4) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name, + used only when creating the temporary agent. Defaults to "gpt-realtime". +""" + +import os +from dotenv import load_dotenv +from azure.core.exceptions import HttpResponseError +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceModelType, + VoiceOutputModality, + VoiceType, +) + +from voice_sample_util import hold_sample_conversation + +load_dotenv() + + +def stream_to_wav(stream, output_path) -> None: + """Write a streamed audio-content response to a local WAV file. + + :param stream: An iterable of audio byte chunks. + :param output_path: The local output path. + :type stream: collections.abc.Iterable[bytes] + :type output_path: str + """ + with open(output_path, "wb") as f: + for chunk in stream: + f.write(chunk) + print(f"Wrote {output_path}") + + +def read_merged_recording(conversations, agent_name, conversation_id) -> None: + """Read the merged whole-call stereo recording (left=user, right=agent). + + :param conversations: The conversation operations client. + :param agent_name: The voice agent name. + :param conversation_id: The persisted conversation id. + :type conversations: azure.ai.projects.operations.BetaVoiceAgentsConversationsOperations + :type agent_name: str + :type conversation_id: str + """ + try: + recording = conversations.get_audio(agent_name, conversation_id) + except HttpResponseError as e: + # A 404 means no merged recording exists for this conversation, for example because the + # agent was configured with `store=False`, or the session has not finished finalizing yet. + if e.status_code == 404: + print("No merged whole-call recording is available for this conversation.") + return + raise + + print( + f"Recording: format={recording.format}, sample_rate={recording.sample_rate}, " + f"channels={recording.channels}, duration_ms={recording.duration_ms}" + ) + + if recording.blob_uri: + # Bring-your-own-storage: download from your own storage using the returned URI. + print(f"Recording is stored in your own storage at: {recording.blob_uri}") + return + + # Foundry-managed storage: stream the bytes and write them to a local WAV file. + stream = conversations.download_audio(agent_name, conversation_id) + stream_to_wav(stream, f"{conversation_id}.wav") + + +def read_first_item_audio(conversations, agent_name, conversation_id) -> None: + """Read the audio segment of the first conversation item that has one. + + :param conversations: The conversation operations client. + :param agent_name: The voice agent name. + :param conversation_id: The persisted conversation id. + :type conversations: azure.ai.projects.operations.BetaVoiceAgentsConversationsOperations + :type agent_name: str + :type conversation_id: str + """ + for item in conversations.list_items(agent_name, conversation_id): + item_id = item.get("id") + if not item_id: + continue + try: + metadata = conversations.get_audio_item(agent_name, conversation_id, item_id) + except HttpResponseError as e: + # A 404 means this item has no persisted audio (for example, a text-only turn). + if e.status_code == 404: + continue + raise + + print(f"Item {item_id}: role={metadata.role}, duration_ms={metadata.duration_ms}") + if metadata.blob_uri: + print(f"Item audio is stored in your own storage at: {metadata.blob_uri}") + return + + stream = conversations.download_audio_item(agent_name, conversation_id, item_id) + stream_to_wav(stream, f"{conversation_id}_{item_id}.wav") + return + + print("No conversation item with audio was found.") + + +def main() -> None: + endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] + agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") + conversation_id = os.environ.get("FOUNDRY_VOICE_CONVERSATION_ID") + model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" + # Only create (and later clean up) a temporary agent when the caller didn't name their own -- + # creating a version on someone's existing agent could unexpectedly mutate it, and deleting + # that version afterward could delete the agent entirely if it was its only version. + owns_agent = not agent_name + agent_name = agent_name or "sample-read-conversation-audio-agent" + + with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, + ): + conversations = project_client.beta.voice_agents.conversations + created_version = None + try: + if not conversation_id: + print( + f"No FOUNDRY_VOICE_CONVERSATION_ID set; holding a short conversation with " + f"'{agent_name}' first..." + ) + if owns_agent: + created_version = project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a friendly voice assistant. Keep replies short and natural.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig( + voice="en-US-AvaNeural", voice_type=VoiceType.AZURE_STANDARD + ), + ), + output_modalities=[VoiceOutputModality.AUDIO], + store=True, + ), + ) + conversation_id = hold_sample_conversation(project_client, agent_name) + print(f"Created conversation: {conversation_id}") + + read_merged_recording(conversations, agent_name, conversation_id) + read_first_item_audio(conversations, agent_name, conversation_id) + except HttpResponseError as e: + # 404: not persisted / not ready. 409: session still in progress. + print(f"Service responded with an error: {e.status_code} {e.reason}") + finally: + if created_version is not None: + project_client.agents.delete_version(agent_name=agent_name, agent_version=created_version.version) + print(f"Deleted temporary voice agent version: {created_version.version}") + + +if __name__ == "__main__": + main() diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_versions.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_versions.py new file mode 100644 index 000000000000..aca6ed007053 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_versions.py @@ -0,0 +1,97 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates working with voice-agent versions. Agents are + immutable: every `create_version` call produces a new version. This sample + creates an agent, adds a new version to it, adds a draft version, lists the + versions, and reads a single version back. + +USAGE: + python sample_voice_agent_versions.py + + Before running the sample: + + pip install "azure-ai-projects>=2.7.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model deployment name. + Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not + set, defaults to "sample-versioned-voice-agent". +""" + +import os +from dotenv import load_dotenv +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import VoiceAgentDefinition, VoiceModelType + +load_dotenv() + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" +agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-versioned-voice-agent" + + +def make_definition(instructions: str) -> VoiceAgentDefinition: + # Each version differs only by its instructions; the rest is identical. + return VoiceAgentDefinition(model_type=VoiceModelType.MANAGED, model=model, instructions=instructions) + + +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, +): + created_versions = [] + try: + # Create the initial agent (this is version 1). + created = project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant."), + ) + created_versions.append(created) + print(f"Created agent '{agent_name}', version: {created.version}") + + # Create a new version with updated instructions. + new_version = project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant. Always greet the caller by name."), + description="Added a personalized greeting.", + ) + created_versions.append(new_version) + print(f"Created new version: {new_version.version}") + + # Create a draft version. Drafts are recorded but excluded from the default + # 'latest' resolution and from version listings unless include_drafts=True. + draft_version = project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant. Experimental draft persona."), + description="Candidate persona under review.", + draft=True, + ) + created_versions.append(draft_version) + print(f"Created draft version: {draft_version.version}") + + # List released versions (drafts excluded by default). + print(f"Released versions of '{agent_name}':") + for version in project_client.agents.list_versions(agent_name=agent_name): + print(f" - version {version.version} (created_at={version.created_at})") + + # List including drafts. + print(f"All versions of '{agent_name}' (including drafts):") + for version in project_client.agents.list_versions(agent_name=agent_name, include_drafts=True): + print(f" - version {version.version} (draft={version.draft})") + + # Read a single version back. + fetched = project_client.agents.get_version(agent_name=agent_name, agent_version=new_version.version) + print(f"Fetched version {fetched.version}: {fetched.definition.instructions}") # type: ignore[attr-defined] + finally: + for version in reversed(created_versions): + project_client.agents.delete_version(agent_name=agent_name, agent_version=version.version) + print(f"Deleted agent version: {version.version}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_with_tools.py b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_with_tools.py new file mode 100644 index 000000000000..a23e775c7868 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/sample_voice_agent_with_tools.py @@ -0,0 +1,148 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates the richer parts of a voice agent definition: + + * Input (microphone) audio configuration: audio format, server-side turn + detection (VAD), input-audio transcription. + * Tools the agent may use during a live session: a client-executed + `function` tool and a service-managed `system` control tool (`mcp` and + `toolbox` tools are shown as constructed objects for illustration). + * Bring-your-own-model (BYOM): set `model_type="self_deployed"` to point + the agent at your own Foundry model deployment instead of a + service-managed model. + +USAGE: + python sample_voice_agent_with_tools.py + + Before running the sample: + + pip install "azure-ai-projects>=2.7.0" python-dotenv + + Set these environment variables with your own values: + 1) FOUNDRY_PROJECT_ENDPOINT - The Azure AI Project endpoint. + 2) FOUNDRY_VOICE_MODEL - Optional. The realtime model (managed) or the + Foundry deployment name (BYOM). Defaults to "gpt-realtime". + 3) FOUNDRY_VOICE_MODEL_TYPE - Optional. "managed" (default) for a + service-hosted model, or "self_deployed" to bring your own deployment. + 4) FOUNDRY_VOICE_AGENT_NAME - Optional. The name of the voice agent. If not + set, defaults to "sample-voice-agent-with-tools". +""" + +import os +from typing import Any, cast + +from dotenv import load_dotenv +from azure.identity import DefaultAzureCredential +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + RealtimeAudioFormatsAudioPcm, + VoiceAgentDefinition, + VoiceAgentFunctionTool, + VoiceAgentMcpTool, + VoiceAgentAudioConfig, + VoiceAgentAudioInputConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentEndConversationSystemTool, + VoiceAgentInputTranscription, + VoiceAgentInputTranscriptionModel, + VoiceModelType, + VoiceOutputModality, + VoiceAgentServerVadTurnDetection, + VoiceAgentToolboxTool, + VoiceType, +) + +load_dotenv() + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +model = os.environ.get("FOUNDRY_VOICE_MODEL") or "gpt-realtime" +# "managed" runs a service-hosted model; "self_deployed" (BYOM) uses your own +# Foundry deployment named by `model`. The service derives whether the model is +# realtime or cascaded; you don't set that here. +model_type = os.environ.get("FOUNDRY_VOICE_MODEL_TYPE") or VoiceModelType.MANAGED +agent_name = os.environ.get("FOUNDRY_VOICE_AGENT_NAME") or "sample-voice-agent-with-tools" + +# A client-executed tool: the service forwards the function call to your app, +# and your app returns the result over the live session. +get_weather = VoiceAgentFunctionTool( + name="get_weather", + description="Get the current weather for a city.", + parameters=cast( + Any, + { + "type": "object", + "properties": {"city": {"type": "string", "description": "City name, e.g. Seattle."}}, + "required": ["city"], + }, + ), +) + +# A service-managed control tool: the platform can end the call on the agent's behalf. +end_call = VoiceAgentEndConversationSystemTool() + +# An MCP tool is executed by the service against a remote MCP server you own. +# It references an external server, so it is constructed here for illustration +# and not attached below. Provide one of server_url, connector_id, or tunnel_id. +_example_mcp_tool = VoiceAgentMcpTool( + server_label="my-mcp-server", + server_url="https://example.com/mcp", + require_approval="never", +) + +# A toolbox tool references a versioned Foundry toolbox you have created. It is +# constructed here for illustration; attach it only if the toolbox exists. +_example_toolbox_tool = VoiceAgentToolboxTool(toolbox_name="my-toolbox", toolbox_version="1") + +definition = VoiceAgentDefinition( + model_type=model_type, + model=model, + instructions="You are a helpful voice assistant. Use tools when they help answer the caller.", + audio=VoiceAgentAudioConfig( + # Input (microphone) side: 24 kHz PCM, server-side VAD so the agent + # auto-responds when the caller stops speaking, plus input-audio + # transcription so user speech is transcribed. + input=VoiceAgentAudioInputConfig( + format=RealtimeAudioFormatsAudioPcm(rate=24000), + turn_detection=VoiceAgentServerVadTurnDetection( + threshold=0.5, + prefix_padding_ms=300, + silence_duration_ms=500, + ), + transcription=VoiceAgentInputTranscription(model=VoiceAgentInputTranscriptionModel.WHISPER1), + ), + # Output (agent speech) side: the voice the agent speaks with. + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type=VoiceType.AZURE_STANDARD), + ), + output_modalities=[VoiceOutputModality.AUDIO], + # Attach the self-contained tools. `_example_mcp_tool` and `_example_toolbox_tool` + # reference external resources you must own, so they are left out here. + tools=[get_weather, end_call], + store=True, +) + +with ( + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential, allow_preview=True) as project_client, +): + created_version = None + try: + created_version = project_client.agents.create_version(agent_name=agent_name, definition=definition) + print(f"Created voice agent '{agent_name}' (model_type={model_type}, model={model})") + + agent_version = project_client.agents.get_version(agent_name=agent_name, agent_version=created_version.version) + tools = agent_version.definition.tools or [] # type: ignore[attr-defined] + print(f"Configured {len(tools)} tool(s):") + for tool in tools: + # `name` isn't declared on every tool kind (e.g. MCP tools have no `name`), + # so fall back to a placeholder for kinds that don't define it. + print(f" - {tool.type}: {getattr(tool, 'name', '(unnamed)')}") + finally: + if created_version is not None: + project_client.agents.delete_version(agent_name=agent_name, agent_version=created_version.version) + print(f"Deleted voice agent version: {created_version.version}") diff --git a/sdk/ai/azure-ai-projects/samples/agents/voice/voice_sample_util.py b/sdk/ai/azure-ai-projects/samples/agents/voice/voice_sample_util.py new file mode 100644 index 000000000000..b1073530343e --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/agents/voice/voice_sample_util.py @@ -0,0 +1,96 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Shared helpers for the voice-agent samples in this folder.""" + +import time +from typing import Final + +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventError, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + VoiceConversationStatus, +) + +# Seconds to wait for the agent's reply before giving up. +_RESPONSE_TIMEOUT: Final = 45 + +# Seconds to wait for the service to finish finalizing the conversation after the session ends, +# and how many times to poll before giving up. +_FINALIZE_POLL_INTERVAL: Final = 1 +_FINALIZE_POLL_ATTEMPTS: Final = 15 + + +def hold_sample_conversation( + project_client: AIProjectClient, agent_name: str, prompt: str = "Say a short, friendly hello." +) -> str: + """Send one short realtime text turn to an existing voice agent and return the resulting + persisted conversation id, once it has finished finalizing. + + Samples that read a conversation back (transcript, responses, audio) do not always have a + live call handy to read. This helper produces a minimal real conversation on demand so those + samples can run without requiring a conversation id up front. The agent named ``agent_name`` + must already exist (see sample_voice_agent_basic.py) and be configured with ``store=True`` so + its conversations are persisted. For a full interactive conversation and a fuller explanation + of the realtime event flow used here, see sample_voice_agent_live_text_conversation.py. + + :param project_client: The Foundry project client. + :param agent_name: The name of an existing voice agent, configured with ``store=True``. + :param prompt: The single text turn to send. + :type project_client: ~azure.ai.projects.AIProjectClient + :type agent_name: str + :type prompt: str + :return: The persisted conversation id. + :rtype: str + :raises RuntimeError: If the session ends without a persisted conversation id, the service + reports a session error, or the conversation does not finish finalizing in time. + """ + conversation_id = None + with project_client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text=prompt)], + ) + ) + conn.response.create() + while True: + event = conn.recv(timeout=_RESPONSE_TIMEOUT) + if isinstance(event, RealtimeServerEventSessionCreated): + # The persisted conversation id (only present when conversation persistence is + # enabled) is set here, not on response.done. + conversation_id = event.conversation_id or conversation_id + if isinstance(event, RealtimeServerEventResponseDone): + break + if isinstance(event, RealtimeServerEventError): + raise RuntimeError(f"Session error while holding a sample conversation: {event.error.message}") + + if not conversation_id: + raise RuntimeError( + "The realtime session ended without a persisted conversation id. Make sure the agent " + "was configured with `store=True`." + ) + + # `response.done` only means the model finished replying, not that the service has finished + # persisting the conversation -- immediately after the session closes, the conversation can + # still briefly report `in_progress` while that finalization completes in the background. + # Poll until it settles so callers can read a complete transcript right away. + conversations = project_client.beta.voice_agents.conversations + for _ in range(_FINALIZE_POLL_ATTEMPTS): + conversation = conversations.get(agent_name, conversation_id) + if conversation.status != VoiceConversationStatus.IN_PROGRESS: + break + time.sleep(_FINALIZE_POLL_INTERVAL) + else: + raise RuntimeError( + f"Conversation {conversation_id} did not finish finalizing within " + f"{_FINALIZE_POLL_ATTEMPTS * _FINALIZE_POLL_INTERVAL} seconds." + ) + + return conversation_id diff --git a/sdk/ai/azure-ai-projects/samples/evaluations/sample_synthetic_multiturn_evaluation.py b/sdk/ai/azure-ai-projects/samples/evaluations/sample_synthetic_multiturn_evaluation.py index 84ba4efebef4..09362a4b9cda 100644 --- a/sdk/ai/azure-ai-projects/samples/evaluations/sample_synthetic_multiturn_evaluation.py +++ b/sdk/ai/azure-ai-projects/samples/evaluations/sample_synthetic_multiturn_evaluation.py @@ -91,9 +91,13 @@ def main() -> None: ) print(f"Agent created (name: {agent.name}, version: {agent.version})") - # max_samples must be in [15, 1000]. The agent source lets the service - # derive seed scenarios from the agent's instructions and metadata. - print(f"\nGenerating {SEED_COUNT} seed scenarios (this takes a few minutes)...") + # The model constructor does not expose max_samples, but the service + # requires it for simulation seed generation. + print("\nGenerating seed scenarios (this takes a few minutes)...") + generation_options = SimulationSeedDataGenerationJobOptions( + model_options=DataGenerationModelOptions(model=model_deployment_name), + ) + generation_options["max_samples"] = SEED_COUNT poller = project_client.beta.datasets.begin_create_generation_job( job=DataGenerationJob( inputs=DataGenerationJobInputs( @@ -106,10 +110,7 @@ def main() -> None: agent_version=agent.version, ), ], - options=SimulationSeedDataGenerationJobOptions( - max_samples=SEED_COUNT, - model_options=DataGenerationModelOptions(model=model_deployment_name), - ), + options=generation_options, output_options=DataGenerationJobOutputOptions(name=f"{agent_name}-simulation-seeds"), ), ), diff --git a/sdk/ai/azure-ai-projects/scripts/FixMatchConditions.ps1 b/sdk/ai/azure-ai-projects/scripts/FixMatchConditions.ps1 new file mode 100644 index 000000000000..2a1517c4b0ff --- /dev/null +++ b/sdk/ai/azure-ai-projects/scripts/FixMatchConditions.ps1 @@ -0,0 +1,129 @@ +[CmdletBinding()] +param( + [string]$PackageRoot = (Split-Path -Parent $PSScriptRoot) +) + +$utilsFile = Join-Path $PackageRoot 'azure\ai\projects\_utils\utils.py' +$utilsContent = Get-Content $utilsFile -Raw +if ($utilsContent -notmatch '(?m)^from azure\.core import MatchConditions\r?$') { + $matchConditionsImport = @('', 'from azure.core import MatchConditions', '') -join [Environment]::NewLine + $utilsContent = $utilsContent -replace '(?m)^(from typing import[^\r\n]+\r?\n)', ('$1' + $matchConditionsImport) +} + +$etagHelperNames = 'quote_etag', 'prep_if_match', 'prep_if_none_match' +$existingEtagHelperCount = 0 +foreach ($helperName in $etagHelperNames) { + if ($utilsContent -match "(?m)^def $helperName\(") { + $existingEtagHelperCount++ + } +} +if ($existingEtagHelperCount -ne 0 -and $existingEtagHelperCount -ne $etagHelperNames.Count) { + throw "Expected all generated ETag helpers or none, but found $existingEtagHelperCount of $($etagHelperNames.Count)." +} +if ($existingEtagHelperCount -eq 0) { + $etagHelpers = @' +def quote_etag(etag: Optional[str]) -> Optional[str]: + if not etag or etag == "*": + return etag + if etag.startswith("W/"): + return etag + if etag.startswith('"') and etag.endswith('"'): + return etag + if etag.startswith("'") and etag.endswith("'"): + return etag + return '"' + etag + '"' + + +def prep_if_match(etag: Optional[str], match_condition: Optional[MatchConditions]) -> Optional[str]: + if match_condition == MatchConditions.IfNotModified: + if_match = quote_etag(etag) if etag else None + return if_match + if match_condition == MatchConditions.IfPresent: + return "*" + return None + + +def prep_if_none_match(etag: Optional[str], match_condition: Optional[MatchConditions]) -> Optional[str]: + if match_condition == MatchConditions.IfModified: + if_none_match = quote_etag(etag) if etag else None + return if_none_match + if match_condition == MatchConditions.IfMissing: + return "*" + return None +'@ + $helperAnchor = '# file-like tuple could be' + if ($utilsContent -notmatch [regex]::Escape($helperAnchor)) { + throw "Could not find the ETag helper insertion point in $utilsFile." + } + $utilsContent = $utilsContent.Replace($helperAnchor, $etagHelpers + "`r`n`r`n" + $helperAnchor) +} +Set-Content $utilsFile $utilsContent -NoNewline + +$operationFiles = @( + @{ + Path = (Join-Path $PackageRoot 'azure\ai\projects\operations\_operations.py') + IsAsync = $false + ExpectedSignatures = 14 + }, + @{ + Path = (Join-Path $PackageRoot 'azure\ai\projects\aio\operations\_operations.py') + IsAsync = $true + ExpectedSignatures = 10 + } +) +foreach ($operationFile in $operationFiles) { + $f = $operationFile.Path + $c = Get-Content $f -Raw + if ($operationFile.IsAsync) { + $c = $c -replace 'from azure\.core import AsyncPipelineClient', 'from azure.core import AsyncPipelineClient, MatchConditions' + } + else { + $c = $c -replace 'from azure\.core import PipelineClient', 'from azure.core import MatchConditions, PipelineClient' + $c = $c -replace 'from \.\._utils\.utils import prepare_multipart_form_data', 'from .._utils.utils import prep_if_match, prep_if_none_match, prepare_multipart_form_data' + } + + $c = [regex]::Replace( + $c, + 'etag: str,(?!\s*match_condition:)', + 'etag: str, match_condition: MatchConditions,' + ) + $c = $c -replace 'match_condition: MatchConditions = MatchConditions\.IfNotModified,', 'match_condition: MatchConditions,' + + $lines = $c -split '\r?\n' + $out = [System.Collections.Generic.List[string]]::new() + for ($i = 0; $i -lt $lines.Length; $i++) { + $line = $lines[$i] + $out.Add($line) + if ($line.Trim() -eq 'etag=etag,') { + $nextLine = if ($i + 1 -lt $lines.Length) { $lines[$i + 1].Trim() } else { '' } + if ($nextLine -ne 'match_condition=match_condition,') { + $indent = ([regex]::Match($line, '^\s*')).Value + $out.Add($indent + 'match_condition=match_condition,') + } + } + if ($line.Trim() -eq ':paramtype etag: str') { + $nextLine = if ($i + 1 -lt $lines.Length) { $lines[$i + 1].Trim() } else { '' } + if ($nextLine -notmatch '^:keyword match_condition:') { + $indent = ([regex]::Match($line, '^\s*')).Value + $out.Add($indent + ':keyword match_condition: The match condition to use upon the etag. Required.') + $out.Add($indent + ':paramtype match_condition: ~azure.core.MatchConditions') + } + } + } + $c = $out -join "`r`n" + + $signatureCount = [regex]::Matches($c, 'match_condition: MatchConditions,').Count + $argumentCount = [regex]::Matches($c, '(?m)^\s*match_condition=match_condition,\r?$').Count + $docCount = [regex]::Matches($c, '(?m)^\s*:paramtype match_condition: ~azure\.core\.MatchConditions\r?$').Count + if ($signatureCount -ne $operationFile.ExpectedSignatures -or $argumentCount -ne 4 -or $docCount -ne 10) { + throw "Unexpected MatchConditions patch counts in ${f}: $signatureCount signatures, $argumentCount arguments, and $docCount docstrings." + } + Set-Content $f $c -NoNewline +} + +$syncOperationsFile = Join-Path $PackageRoot 'azure\ai\projects\operations\_operations.py' +$syncOperations = Get-Content $syncOperationsFile -Raw +$ifMatchCount = [regex]::Matches($syncOperations, 'if_match = prep_if_match\(etag, match_condition\)').Count +if ($ifMatchCount -ne 4) { + throw "Expected 4 generated prep_if_match blocks, but found $ifMatchCount." +} \ No newline at end of file diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client.py b/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client.py new file mode 100644 index 000000000000..07b1d7686537 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client.py @@ -0,0 +1,486 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression,protected-access +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable +"""Transport-mocked unit tests for the hand-written sync realtime (WebSocket) client. + +Unlike ``test_voice_agent_crud.py``, these tests never make an HTTP/WS call: the underlying +``websockets.sync.client.connect`` is replaced with a fake so URL construction, header/auth +handling, event serialization/deserialization, connection cleanup, and dependency/error paths +can all be verified without a live service or a recorded transport. +""" + +import json +import inspect +import logging +from unittest.mock import MagicMock, patch +from urllib.parse import parse_qs, urlparse + +import pytest +from azure.core.credentials import AccessToken +from websockets.typing import Subprotocol + +from azure.ai.projects._realtime import ( + BetaRealtime, + BetaRealtimeConnectionManager, + _assert_trusted_connection_url, + _to_ws_url, + _USER_AGENT, +) +from azure.ai.projects._version import VERSION +from azure.ai.projects.models import ( + RealtimeClientEventResponseCreate, + RealtimeServerEventSessionCreated, +) + +_ENDPOINT = "https://my-account.services.ai.azure.com/api/projects/my-project" + + +class _FakeCredential: + """Sync stub credential that returns a never-expiring token.""" + + def __init__(self, token: str = "fake-token") -> None: + self._token = token + + def get_token(self, *args, **kwargs) -> AccessToken: # pylint: disable=unused-argument + return AccessToken(self._token, 9_999_999_999) + + +def test_realtime_constructor_hides_config_in_kwargs(): + config = MagicMock() + client = MagicMock(_config=config) + + realtime = BetaRealtime(client) + + assert realtime._config is config + assert tuple(inspect.signature(BetaRealtime.__init__).parameters) == ("self", "args", "kwargs") + + +def _make_manager(**overrides) -> BetaRealtimeConnectionManager: + kwargs = { + "endpoint": _ENDPOINT, + "credential": _FakeCredential(), + "credential_scopes": ["https://ai.azure.com/.default"], + "api_version": "v1", + "agent_name": "my-agent", + } + kwargs.update(overrides) + return BetaRealtimeConnectionManager(**kwargs) + + +class TestToWsUrl: + """Unit tests for the pure ``_to_ws_url`` URL-construction helper.""" + + def test_https_endpoint_becomes_wss(self): + url = _to_ws_url(_ENDPOINT, "my-agent") + assert ( + url + == "wss://my-account.services.ai.azure.com/api/projects/my-project/agents/my-agent/endpoint/protocols/voice" + ) + + def test_non_https_endpoint_scheme_is_left_unchanged(self): + # Regression test: _to_ws_url used to translate "http://" to "ws://", but + # BetaRealtimeConnectionManager.enter() unconditionally rejects any non-"wss://" URL to + # protect the live Authorization token in transit, so that translated "ws://" URL could + # never actually be used to connect. Leaving the scheme untouched here means the + # downstream "wss://" check surfaces a clear error instead of an unreachable "ws://" path. + url = _to_ws_url("http://localhost:8080", "my-agent") + assert url == "http://localhost:8080/agents/my-agent/endpoint/protocols/voice" + + def test_trailing_slash_is_stripped(self): + url = _to_ws_url(_ENDPOINT + "/", "my-agent") + assert ( + url + == "wss://my-account.services.ai.azure.com/api/projects/my-project/agents/my-agent/endpoint/protocols/voice" + ) + + +class TestAssertTrustedConnectionUrl: + """Unit tests for the connection_url host allow-list guard (security fix).""" + + def test_matching_host_does_not_raise(self): + _assert_trusted_connection_url(f"wss://{'my-account.services.ai.azure.com'}/custom/path", _ENDPOINT) + + def test_mismatched_host_raises_value_error(self): + with pytest.raises(ValueError): + _assert_trusted_connection_url("wss://evil.example.com/steal-token", _ENDPOINT) + + def test_empty_host_raises_value_error(self): + with pytest.raises(ValueError): + _assert_trusted_connection_url("not-a-url", _ENDPOINT) + + def test_matching_host_explicit_default_port_does_not_raise(self): + # An explicit ":443" is the wss/https default, so this is the same origin as _ENDPOINT + # (which omits the port) and must be accepted. + _assert_trusted_connection_url("wss://my-account.services.ai.azure.com:443/custom/path", _ENDPOINT) + + def test_mismatched_port_raises_value_error(self): + # Regression test (security fix): comparing hostname alone let an override targeting the + # same host on a different, non-default port (a different origin) slip through and + # receive the live bearer token. + with pytest.raises(ValueError): + _assert_trusted_connection_url("wss://my-account.services.ai.azure.com:8443/steal-token", _ENDPOINT) + + +class TestRealtimeConnectionManagerEnter: + """Unit tests for ``BetaRealtimeConnectionManager.enter()``: URL/header construction and errors.""" + + def test_enter_builds_bearer_auth_and_query(self): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager() + conn = manager.enter() + try: + assert conn is not None + finally: + manager.__exit__() + + assert mock_connect.call_count == 1 + _args, kwargs = mock_connect.call_args + called_url = _args[0] + assert called_url.startswith("wss://my-account.services.ai.azure.com") + assert "api-version=v1" in called_url + assert kwargs["additional_headers"]["Authorization"] == "Bearer fake-token" + assert kwargs["additional_headers"]["Foundry-Features"] == "VoiceAgents=V1Preview" + + def test_enter_identifies_sdk_via_user_agent_and_query(self): + # The generated HTTP surface gets SDK identification for free from the core pipeline's + # UserAgentPolicy; this hand-written client builds its own request and must opt in + # explicitly, both as a User-Agent header and (since some proxies/paths don't forward + # WebSocket upgrade headers) as an x-ms-client-sdk query parameter. + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager() + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + assert kwargs["additional_headers"]["User-Agent"] == _USER_AGENT + assert "azsdk-python-ai-projects" in _USER_AGENT + assert VERSION in _USER_AGENT + + query = parse_qs(urlparse(_args[0]).query) + assert query["x-ms-client-sdk"] == [_USER_AGENT] + + def test_enter_caller_user_agent_overrides_default(self): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(extra_headers={"User-Agent": "custom-user-agent"}) + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + assert kwargs["additional_headers"]["User-Agent"] == "custom-user-agent" + + def test_enter_caller_user_agent_overrides_default_case_insensitive(self): + # Regression test: a plain dict merge of extra_headers would leave a differently-cased + # caller override (e.g. "user-agent") as a *separate* key alongside our own "User-Agent" + # default, since Python dict keys are case-sensitive but HTTP header names are not -- + # sending two User-Agent-like headers instead of cleanly honoring the caller's override. + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(extra_headers={"user-agent": "custom-user-agent"}) + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + headers = kwargs["additional_headers"] + assert "User-Agent" not in headers + assert headers["user-agent"] == "custom-user-agent" + + def test_enter_source_retains_client_identification_wiring(self): + # Regression guard for the SDK client-identification fix (ported from azure-ai-voicelive + # PR #48848) surviving a future TypeSpec regeneration. `_realtime.py` is a hand-written + # file that is NOT `_patch.py`-named, so it isn't covered by the code generator's own + # "never touch _patch.py" guarantee -- nothing in the TypeSpec emitter is aware this file + # exists. The tests above already fail on a *behavioral* regression (wrong header/query + # value), but they exercise the code through mocks and could, in principle, still pass + # against a rewritten implementation that happens to produce the same observable values by + # a different (less safe) path. This inspects the actual source of `enter()` so a partial + # revert -- one that drops the case-insensitive guard, say, while keeping the header value + # correct for the common case -- is caught directly, independent of the tests above. + source = inspect.getsource(BetaRealtimeConnectionManager.enter) + assert "_USER_AGENT" in source + assert "_has_header_case_insensitive" in source + assert "x-ms-client-sdk" in source + + def test_enter_disables_library_default_user_agent_header(self): + # Regression test: unlike aiohttp (where an explicit "User-Agent" in `headers` already + # takes precedence over its own default), `websockets.sync.client.connect`'s + # `user_agent_header` is a wholly separate mechanism from `additional_headers` -- passing + # our own "User-Agent" there does not suppress it. Without explicitly disabling it, the + # connection would carry two distinct User-Agent-like values. + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager() + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + assert kwargs["user_agent_header"] is None + + def test_enter_overrides_caller_supplied_subprotocols_kwarg(self): + # Regression test: subprotocols=[Subprotocol("realtime")] is passed explicitly to + # _ws_connect, so a caller-supplied subprotocols override forwarded through **kwargs would + # otherwise collide ("got multiple values for keyword argument 'subprotocols'"). The + # service requires the "realtime" subprotocol, so the override is dropped rather than + # honored -- matching the async implementation's handling of its equivalent `protocols` + # kwarg. + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(subprotocols=["other"]) + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + assert kwargs["subprotocols"] == [Subprotocol("realtime")] + + def test_enter_appends_extra_query_and_headers(self): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(extra_query={"foo": "bar"}, extra_headers={"X-Custom": "1"}) + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + assert "foo=bar" in _args[0] + assert kwargs["additional_headers"]["X-Custom"] == "1" + + def test_enter_sends_structured_inputs_as_query_parameter(self): + # Regression test: structured_inputs used to be serialized into a custom + # "x-ms-voice-structured-inputs" header, but the generated request builder + # (build_beta_voice_agents_realtime_connect_voice_agent_request) defines this as the + # "structured_input" query parameter -- the service never actually read the header. + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(structured_inputs={"greeting_name": "Alex"}) + manager.enter() + manager.__exit__() + + _args, kwargs = mock_connect.call_args + query = parse_qs(urlparse(_args[0]).query) + assert json.loads(query["structured_input"][0]) == {"greeting_name": "Alex"} + assert "x-ms-voice-structured-inputs" not in kwargs["additional_headers"] + + def test_enter_preserves_existing_query_on_connection_url_override(self): + # Regression test: the URL builder used to unconditionally append "?", corrupting an + # override URL that already has a query string (e.g. a SAS-style "?sig=..."). + fake_connection = MagicMock() + override = f"wss://{'my-account.services.ai.azure.com'}/custom?sig=abc" + with patch("websockets.sync.client.connect", return_value=fake_connection) as mock_connect: + manager = _make_manager(connection_url=override) + manager.enter() + manager.__exit__() + + called_url = mock_connect.call_args[0][0] + assert called_url.count("?") == 1 + assert "sig=abc&api-version=v1" in called_url + + def test_enter_rejects_untrusted_connection_url_host(self): + manager = _make_manager(connection_url="wss://evil.example.com/steal-token") + with pytest.raises(ValueError): + manager.enter() + + def test_enter_rejects_non_wss_url(self): + # A plain http(s) endpoint that somehow produced a non-ws(s) URL should never proceed. + manager = _make_manager(endpoint="ftp://not-http-or-https") + with pytest.raises(ValueError): + manager.enter() + + def test_enter_raises_runtime_error_when_websockets_missing(self): + manager = _make_manager() + with patch.dict("sys.modules", {"websockets.sync.client": None, "websockets.typing": None}): + with pytest.raises(RuntimeError, match="websockets"): + manager.enter() + + def test_context_manager_closes_connection_on_exit(self): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + with _make_manager() as conn: + pass + fake_connection.close.assert_called_once() + + +class TestRealtimeConnectionRecv: + """Unit tests for ``BetaRealtimeConnection.recv()``: event dispatch and error/timeout handling.""" + + def test_recv_dispatches_known_event_type(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.return_value = json.dumps({"type": "session.created", "session": {}}) + event = conn.recv() + assert isinstance(event, RealtimeServerEventSessionCreated) + + def test_recv_unknown_event_type_returns_dict(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.return_value = json.dumps({"type": "some.new.event", "foo": "bar"}) + event = conn.recv() + assert isinstance(event, dict) + assert event["foo"] == "bar" + + def test_recv_forwards_timeout_to_underlying_connection(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.return_value = json.dumps({"type": "error", "error": {"message": "boom"}}) + conn.recv(timeout=5.0) + fake_connection.recv.assert_called_once_with(timeout=5.0) + + def test_recv_timeout_error_propagates(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.side_effect = TimeoutError() + with pytest.raises(TimeoutError): + conn.recv(timeout=0.1) + + def test_recv_connection_closed_raises_connection_reset_error(self, request): + from websockets.exceptions import ConnectionClosedOK + + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.side_effect = ConnectionClosedOK(None, None) + with pytest.raises(ConnectionResetError): + conn.recv() + + def test_iteration_stops_cleanly_on_connection_reset(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.side_effect = ConnectionResetError() + assert list(conn) == [] + + def test_iteration_stops_cleanly_on_graceful_close(self, request): + from websockets.exceptions import ConnectionClosedOK + from websockets.frames import Close + + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.side_effect = ConnectionClosedOK(Close(1000, "bye"), None) + assert list(conn) == [] + + def test_iteration_propagates_abnormal_closure(self, request): + # Regression test: recv() converts every websockets.exceptions.ConnectionClosed + # (graceful *and* abnormal) into ConnectionResetError, so a blanket except clause here + # made a real server-side failure (e.g. close code 1011) indistinguishable from a normal + # end of stream -- a `for event in conn:` caller could silently accept a truncated + # response. Only a graceful closure (ConnectionClosedOK) should end iteration quietly. + from websockets.exceptions import ConnectionClosedError + from websockets.frames import Close + + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + fake_connection.recv.side_effect = ConnectionClosedError(Close(1011, "internal error"), None) + with pytest.raises(ConnectionResetError): + list(conn) + + +class TestRealtimeConnectionSend: + """Unit tests for ``BetaRealtimeConnection.send()``: model/str/mapping serialization.""" + + def test_send_serializes_typed_model(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + conn.send(RealtimeClientEventResponseCreate()) + sent_raw = fake_connection.send.call_args[0][0] + payload = json.loads(sent_raw) + assert payload["type"] == "response.create" + + def test_send_passes_through_valid_json_string(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + conn.send('{"type": "response.create"}') + fake_connection.send.assert_called_once_with('{"type": "response.create"}') + + def test_send_rejects_invalid_json_string(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + with pytest.raises(ValueError): + conn.send("not valid json") + + def test_send_serializes_mapping(self, request): + fake_connection = MagicMock() + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager() + conn = manager.enter() + request.addfinalizer(manager.__exit__) + + conn.send({"type": "response.cancel"}) + sent_raw = fake_connection.send.call_args[0][0] + assert json.loads(sent_raw) == {"type": "response.cancel"} + + +def test_realtime_logging_emits_metadata_without_sensitive_content(caplog): + fake_connection = MagicMock() + fake_connection.recv.return_value = json.dumps({"type": "some.new.event", "text": "secret-inbound-content"}) + connection_url = "wss://my-account.services.ai.azure.com/custom?sig=secret-query" + + caplog.set_level(logging.DEBUG, logger="azure.ai.projects._realtime") + with patch("websockets.sync.client.connect", return_value=fake_connection): + manager = _make_manager( + connection_url=connection_url, + structured_inputs={"value": "secret-structured-input"}, + ) + conn = manager.enter() + conn.send({"type": "response.create", "text": "secret-outbound-content"}) + conn.recv() + manager.__exit__() + + messages = "\n".join(record.getMessage() for record in caplog.records) + assert "WebSocket CONNECT target=wss://my-account.services.ai.azure.com/custom" in messages + assert "WebSocket CONNECTED target=wss://my-account.services.ai.azure.com/custom" in messages + assert "WebSocket SEND type=response.create bytes=" in messages + assert "WebSocket RECEIVE type=some.new.event bytes=" in messages + assert "WebSocket CLOSE code=1000" in messages + for sensitive_value in ( + "fake-token", + "secret-query", + "secret-structured-input", + "secret-inbound-content", + "secret-outbound-content", + ): + assert sensitive_value not in messages diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client_async.py new file mode 100644 index 000000000000..1b27b694dac7 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_realtime_client_async.py @@ -0,0 +1,470 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression,protected-access +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable +"""Transport-mocked unit tests for the hand-written async realtime (WebSocket) client. + +Async counterpart of ``test_realtime_client.py``. The underlying ``aiohttp.ClientSession`` is +replaced with a fake so URL construction, header/auth handling, event serialization/ +deserialization, connection cleanup, and dependency/error paths can all be verified without a +live service or a recorded transport. +""" + +import json +import inspect +import logging +from unittest.mock import AsyncMock, MagicMock, patch +from urllib.parse import parse_qs, urlparse + +import pytest +from azure.core.credentials import AccessToken + +from azure.ai.projects.aio._realtime import AsyncBetaRealtime, AsyncBetaRealtimeConnectionManager, _USER_AGENT +from azure.ai.projects._version import VERSION +from azure.ai.projects.models import ( + RealtimeClientEventResponseCreate, + RealtimeServerEventSessionCreated, +) + +_ENDPOINT = "https://my-account.services.ai.azure.com/api/projects/my-project" + +pytestmark = pytest.mark.asyncio + + +class _AsyncFakeCredential: + """Async stub credential that returns a never-expiring token.""" + + def __init__(self, token: str = "fake-token") -> None: + self._token = token + + async def get_token(self, *args, **kwargs) -> AccessToken: # pylint: disable=unused-argument + return AccessToken(self._token, 9_999_999_999) + + +async def test_async_realtime_constructor_hides_config_in_kwargs(): + config = MagicMock() + client = MagicMock(_config=config) + + realtime = AsyncBetaRealtime(client) + + assert realtime._config is config + assert tuple(inspect.signature(AsyncBetaRealtime.__init__).parameters) == ("self", "args", "kwargs") + + +def _make_manager(**overrides) -> AsyncBetaRealtimeConnectionManager: + kwargs = { + "endpoint": _ENDPOINT, + "credential": _AsyncFakeCredential(), + "credential_scopes": ["https://ai.azure.com/.default"], + "api_version": "v1", + "agent_name": "my-agent", + } + kwargs.update(overrides) + return AsyncBetaRealtimeConnectionManager(**kwargs) + + +def _make_fake_msg(msg_type, data=None): + msg = MagicMock() + msg.type = msg_type + msg.data = data + return msg + + +def _make_fake_ws(): + """A fake aiohttp ClientWebSocketResponse with async close() (always awaited by __aexit__).""" + fake_ws = MagicMock() + fake_ws.close = AsyncMock() + return fake_ws + + +def _patch_client_session(fake_ws_connection): + """Patch aiohttp.ClientSession() to return a fake session whose ws_connect/close are async.""" + fake_session = MagicMock() + fake_session.ws_connect = AsyncMock(return_value=fake_ws_connection) + fake_session.close = AsyncMock() + return patch("aiohttp.ClientSession", return_value=fake_session), fake_session + + +class TestAsyncRealtimeConnectionManagerEnter: + """Unit tests for ``AsyncBetaRealtimeConnectionManager.enter()``: URL/header construction and errors.""" + + async def test_enter_builds_bearer_auth_and_query(self): + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + await manager.enter() + await manager.__aexit__() + + assert fake_session.ws_connect.call_count == 1 + _args, kwargs = fake_session.ws_connect.call_args + assert _args[0].startswith("wss://my-account.services.ai.azure.com") + assert kwargs["params"]["api-version"] == "v1" + assert kwargs["headers"]["Authorization"] == "Bearer fake-token" + assert kwargs["headers"]["Foundry-Features"] == "VoiceAgents=V1Preview" + assert "Sec-WebSocket-Protocol" not in kwargs["headers"] + assert kwargs["protocols"] == ("realtime",) + + async def test_enter_identifies_sdk_via_user_agent_and_query(self): + # The generated HTTP surface gets SDK identification for free from the core pipeline's + # UserAgentPolicy; this hand-written client builds its own request and must opt in + # explicitly, both as a User-Agent header and (since some proxies/paths don't forward + # WebSocket upgrade headers) as an x-ms-client-sdk query parameter. + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + await manager.enter() + await manager.__aexit__() + + _args, kwargs = fake_session.ws_connect.call_args + assert kwargs["headers"]["User-Agent"] == _USER_AGENT + assert "azsdk-python-ai-projects" in _USER_AGENT + assert VERSION in _USER_AGENT + assert kwargs["params"]["x-ms-client-sdk"] == _USER_AGENT + + async def test_enter_caller_user_agent_overrides_default(self): + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager(extra_headers={"User-Agent": "custom-user-agent"}) + await manager.enter() + await manager.__aexit__() + + _args, kwargs = fake_session.ws_connect.call_args + assert kwargs["headers"]["User-Agent"] == "custom-user-agent" + + async def test_enter_sends_structured_inputs_as_query_parameter(self): + # Regression test: structured_inputs used to be serialized into a custom + # "x-ms-voice-structured-inputs" header, but the generated request builder + # (build_beta_voice_agents_realtime_connect_voice_agent_request) defines this as the + # "structured_input" query parameter -- the service never actually read the header. + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager(structured_inputs={"greeting_name": "Alex"}) + await manager.enter() + await manager.__aexit__() + + _args, kwargs = fake_session.ws_connect.call_args + assert json.loads(kwargs["params"]["structured_input"]) == {"greeting_name": "Alex"} + assert "x-ms-voice-structured-inputs" not in kwargs["headers"] + + async def test_enter_caller_user_agent_overrides_default_case_insensitive(self): + # Regression test: a plain dict merge of extra_headers would leave a differently-cased + # caller override (e.g. "user-agent") as a *separate* key alongside our own "User-Agent" + # default, since Python dict keys are case-sensitive but HTTP header names are not -- + # sending two User-Agent-like headers instead of cleanly honoring the caller's override. + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager(extra_headers={"user-agent": "custom-user-agent"}) + await manager.enter() + await manager.__aexit__() + + _args, kwargs = fake_session.ws_connect.call_args + headers = kwargs["headers"] + assert "User-Agent" not in headers + assert headers["user-agent"] == "custom-user-agent" + + async def test_enter_source_retains_client_identification_wiring(self): + # Regression guard for the SDK client-identification fix (ported from azure-ai-voicelive + # PR #48848) surviving a future TypeSpec regeneration. `aio/_realtime.py` is a hand-written + # file that is NOT `_patch.py`-named, so it isn't covered by the code generator's own + # "never touch _patch.py" guarantee -- nothing in the TypeSpec emitter is aware this file + # exists. The tests above already fail on a *behavioral* regression (wrong header/query + # value), but they exercise the code through mocks and could, in principle, still pass + # against a rewritten implementation that happens to produce the same observable values by + # a different (less safe) path. This inspects the actual source of `enter()` so a partial + # revert -- one that drops the case-insensitive guard, say, while keeping the header value + # correct for the common case -- is caught directly, independent of the tests above. + source = inspect.getsource(AsyncBetaRealtimeConnectionManager.enter) + assert "_USER_AGENT" in source + assert "_has_header_case_insensitive" in source + assert "x-ms-client-sdk" in source + + async def test_enter_rejects_untrusted_connection_url_host(self): + manager = _make_manager(connection_url="wss://evil.example.com/steal-token") + with pytest.raises(ValueError): + await manager.enter() + + async def test_enter_overrides_caller_supplied_protocols_kwarg(self): + # Regression test: protocols=("realtime",) is now passed explicitly to ws_connect, so a + # caller-supplied protocols override forwarded through **kwargs would otherwise collide + # ("got multiple values for keyword argument 'protocols'"). The service requires the + # "realtime" subprotocol, so the override is dropped rather than honored. + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager(protocols=("other",)) + await manager.enter() + await manager.__aexit__() + + _args, kwargs = fake_session.ws_connect.call_args + assert kwargs["protocols"] == ("realtime",) + + async def test_enter_rejects_non_wss_url(self): + manager = _make_manager(endpoint="ftp://not-http-or-https") + with pytest.raises(ValueError): + await manager.enter() + + async def test_enter_raises_runtime_error_when_aiohttp_missing(self): + manager = _make_manager() + with patch.dict("sys.modules", {"aiohttp": None}): + with pytest.raises(RuntimeError, match="aiohttp"): + await manager.enter() + + async def test_enter_closes_session_on_connect_failure(self): + fake_session = MagicMock() + fake_session.ws_connect = AsyncMock(side_effect=OSError("connection refused")) + fake_session.close = AsyncMock() + with patch("aiohttp.ClientSession", return_value=fake_session): + manager = _make_manager() + with pytest.raises(ConnectionError): + await manager.enter() + fake_session.close.assert_awaited_once() + + async def test_context_manager_closes_connection_on_exit(self): + fake_ws = _make_fake_ws() + patcher, fake_session = _patch_client_session(fake_ws) + with patcher: + async with _make_manager(): + pass + fake_ws.close.assert_awaited_once() + fake_session.close.assert_awaited_once() + + +class TestAsyncRealtimeConnectionRecv: + """Unit tests for ``AsyncBetaRealtimeConnection.recv()``: event dispatch and non-text frames.""" + + async def test_recv_dispatches_known_event_type(self): + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.receive = AsyncMock( + return_value=_make_fake_msg(aiohttp.WSMsgType.TEXT, json.dumps({"type": "session.created", "session": {}})) + ) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + event = await conn.recv() + assert isinstance(event, RealtimeServerEventSessionCreated) + finally: + await manager.__aexit__() + + async def test_recv_skips_ping_pong_frames(self): + # Regression test locking in the existing PING/PONG handling. + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.receive = AsyncMock( + side_effect=[ + _make_fake_msg(aiohttp.WSMsgType.PING, b""), + _make_fake_msg(aiohttp.WSMsgType.PONG, b""), + _make_fake_msg(aiohttp.WSMsgType.TEXT, json.dumps({"type": "session.created", "session": {}})), + ] + ) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + event = await conn.recv() + assert isinstance(event, RealtimeServerEventSessionCreated) + assert fake_ws.receive.await_count == 3 + finally: + await manager.__aexit__() + + async def test_recv_unknown_event_type_returns_dict(self): + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.receive = AsyncMock( + return_value=_make_fake_msg(aiohttp.WSMsgType.TEXT, json.dumps({"type": "some.new.event", "foo": "bar"})) + ) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + event = await conn.recv() + assert isinstance(event, dict) + assert event["foo"] == "bar" + finally: + await manager.__aexit__() + + async def test_recv_close_frame_raises_connection_reset_error(self): + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.receive = AsyncMock(return_value=_make_fake_msg(aiohttp.WSMsgType.CLOSE)) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + with pytest.raises(ConnectionResetError): + await conn.recv() + finally: + await manager.__aexit__() + + async def test_recv_error_frame_raises_connection_reset_error(self): + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.exception = MagicMock(return_value=RuntimeError("boom")) + fake_ws.receive = AsyncMock(return_value=_make_fake_msg(aiohttp.WSMsgType.ERROR)) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + with pytest.raises(ConnectionResetError): + await conn.recv() + finally: + await manager.__aexit__() + + async def test_iteration_stops_cleanly_on_graceful_close(self): + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.close_code = 1000 # Normal Closure + fake_ws.receive = AsyncMock(return_value=_make_fake_msg(aiohttp.WSMsgType.CLOSE)) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + assert [event async for event in conn] == [] + finally: + await manager.__aexit__() + + async def test_iteration_propagates_abnormal_closure(self): + # Regression test: recv() used to raise the same ConnectionResetError for every close + # frame regardless of code, and the async iterator caught all of them, so a real + # server-side failure (e.g. close code 1011) was indistinguishable from a normal end of + # stream -- an `async for event in conn:` caller could silently accept a truncated + # response. Only a graceful closure (code 1000/1001) should end iteration quietly. + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.close_code = 1011 # Internal Error + fake_ws.receive = AsyncMock(return_value=_make_fake_msg(aiohttp.WSMsgType.CLOSE)) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + with pytest.raises(ConnectionResetError): + _ = [event async for event in conn] + finally: + await manager.__aexit__() + + async def test_iteration_propagates_transport_error(self): + # Regression test: same as above, but for the WSMsgType.ERROR path (an actual transport + # exception, not just an abnormal close code) -- this must never be swallowed either. + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.exception = MagicMock(return_value=RuntimeError("boom")) + fake_ws.receive = AsyncMock(return_value=_make_fake_msg(aiohttp.WSMsgType.ERROR)) + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + with pytest.raises(ConnectionResetError): + _ = [event async for event in conn] + finally: + await manager.__aexit__() + + +class TestAsyncRealtimeConnectionSend: + """Unit tests for ``AsyncBetaRealtimeConnection.send()``: model/str/mapping serialization.""" + + async def test_send_serializes_typed_model(self): + fake_ws = _make_fake_ws() + fake_ws.send_str = AsyncMock() + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + await conn.send(RealtimeClientEventResponseCreate()) + sent_raw = fake_ws.send_str.call_args[0][0] + payload = json.loads(sent_raw) + assert payload["type"] == "response.create" + finally: + await manager.__aexit__() + + async def test_send_rejects_invalid_json_string(self): + fake_ws = _make_fake_ws() + fake_ws.send_str = AsyncMock() + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + with pytest.raises(ValueError): + await conn.send("not valid json") + finally: + await manager.__aexit__() + + async def test_send_serializes_mapping(self): + fake_ws = _make_fake_ws() + fake_ws.send_str = AsyncMock() + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager() + conn = await manager.enter() + try: + await conn.send({"type": "response.cancel"}) + sent_raw = fake_ws.send_str.call_args[0][0] + assert json.loads(sent_raw) == {"type": "response.cancel"} + finally: + await manager.__aexit__() + + +async def test_realtime_logging_emits_metadata_without_sensitive_content(caplog): + import aiohttp + + fake_ws = _make_fake_ws() + fake_ws.send_str = AsyncMock() + fake_ws.receive = AsyncMock( + return_value=_make_fake_msg( + aiohttp.WSMsgType.TEXT, + json.dumps({"type": "some.new.event", "text": "secret-inbound-content"}), + ) + ) + connection_url = "wss://my-account.services.ai.azure.com/custom?sig=secret-query" + + caplog.set_level(logging.DEBUG, logger="azure.ai.projects.aio._realtime") + patcher, _ = _patch_client_session(fake_ws) + with patcher: + manager = _make_manager( + connection_url=connection_url, + structured_inputs={"value": "secret-structured-input"}, + ) + conn = await manager.enter() + await conn.send({"type": "response.create", "text": "secret-outbound-content"}) + await conn.recv() + await manager.__aexit__() + + messages = "\n".join(record.getMessage() for record in caplog.records) + assert "WebSocket CONNECT target=wss://my-account.services.ai.azure.com/custom" in messages + assert "WebSocket CONNECTED target=wss://my-account.services.ai.azure.com/custom" in messages + assert "WebSocket SEND type=response.create bytes=" in messages + assert "WebSocket RECEIVE type=some.new.event bytes=" in messages + assert "WebSocket CLOSE code=1000" in messages + for sensitive_value in ( + "fake-token", + "secret-query", + "secret-structured-input", + "secret-inbound-content", + "secret-outbound-content", + ): + assert sensitive_value not in messages diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_telephony_match_conditions.py b/sdk/ai/azure-ai-projects/tests/agents/test_telephony_match_conditions.py new file mode 100644 index 000000000000..20afb5266653 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_telephony_match_conditions.py @@ -0,0 +1,66 @@ +import inspect + +import pytest +from azure.core import MatchConditions + +from azure.ai.projects._utils.utils import prep_if_match, prep_if_none_match +from azure.ai.projects.aio.operations._operations import BetaVoiceAgentsTelephonyOperations as AsyncTelephonyOperations +from azure.ai.projects.operations._operations import ( + BetaVoiceAgentsTelephonyOperations as TelephonyOperations, + build_beta_voice_agents_telephony_cancel_call_job_request, + build_beta_voice_agents_telephony_delete_binding_request, + build_beta_voice_agents_telephony_replace_transfer_targets_request, + build_beta_voice_agents_telephony_update_binding_request, +) + + +@pytest.mark.parametrize( + "etag, match_condition, expected", + [ + ("etag", MatchConditions.IfNotModified, '"etag"'), + ('"etag"', MatchConditions.IfNotModified, '"etag"'), + ('W/"etag"', MatchConditions.IfNotModified, 'W/"etag"'), + ("etag", MatchConditions.IfPresent, "*"), + ("etag", MatchConditions.IfModified, None), + ], +) +def test_prep_if_match(etag, match_condition, expected): + assert prep_if_match(etag, match_condition) == expected + + +@pytest.mark.parametrize( + "etag, match_condition, expected", + [ + ("etag", MatchConditions.IfModified, '"etag"'), + ("etag", MatchConditions.IfMissing, "*"), + ("etag", MatchConditions.IfNotModified, None), + ], +) +def test_prep_if_none_match(etag, match_condition, expected): + assert prep_if_none_match(etag, match_condition) == expected + + +@pytest.mark.parametrize( + "build_request", + [ + lambda **kwargs: build_beta_voice_agents_telephony_update_binding_request("agent", "binding", **kwargs), + lambda **kwargs: build_beta_voice_agents_telephony_delete_binding_request("agent", "binding", **kwargs), + lambda **kwargs: build_beta_voice_agents_telephony_replace_transfer_targets_request("agent", **kwargs), + lambda **kwargs: build_beta_voice_agents_telephony_cancel_call_job_request("agent", "job", **kwargs), + ], +) +def test_telephony_builders_apply_match_condition(build_request): + assert build_request(etag="etag", match_condition=MatchConditions.IfNotModified).headers["If-Match"] == '"etag"' + assert build_request(etag="etag", match_condition=MatchConditions.IfPresent).headers["If-Match"] == "*" + + +@pytest.mark.parametrize("operations_type", [TelephonyOperations, AsyncTelephonyOperations]) +@pytest.mark.parametrize( + "method_name", + ["update_binding", "delete_binding", "replace_transfer_targets", "cancel_call_job"], +) +def test_telephony_operations_expose_match_condition(operations_type, method_name): + parameter = inspect.signature(getattr(operations_type, method_name)).parameters["match_condition"] + + assert parameter.annotation is MatchConditions + assert parameter.default is inspect.Parameter.empty diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations.py new file mode 100644 index 000000000000..3c1ecc499936 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations.py @@ -0,0 +1,244 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression,too-many-statements,broad-exception-caught +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +""" +Recorded tests covering the read-only voice-agent conversation REST API surface exposed through +``project_client.beta.voice_agents.conversations``. + +Conversations, their responses/items, and audio are written by the realtime WebSocket subsystem +during a live session (see ``test_voice_agent_realtime_live.py``) and can only be *read* here -- +there is no REST way to create one. A real ``conversation_id`` can therefore only be obtained by +actually running a live session, which is not itself something the test proxy can capture or +replay (it is a raw WebSocket connection, not an HTTP call through the SDK pipeline). + +To get real recorded/replayable coverage of the REST read-back surface anyway, this test: + * When run live (``AZURE_TEST_RUN_LIVE=true``): creates a `store=True` voice agent, opens a + short-lived realtime session directly (bypassing the recorded pipeline, same as any other + live network call), sends one turn, and waits for the resulting conversation to finalize. + The dynamic conversation id is then sanitized to a fixed placeholder before any of the + REST calls below are made, so what gets written to the recording cassette is stable. + * When replayed from the recording (the normal case in CI): skips the live session entirely + and uses the same fixed placeholder conversation id the cassette already expects. +Either way, the REST calls themselves (list/get conversation, responses, items, audio) go +through ``recorded_by_proxy`` exactly like any other recorded test in this package. +""" + +import re +import time +from typing import Final, Optional + +from test_base import TestBase, servicePreparer +from devtools_testutils import recorded_by_proxy, is_live, add_general_regex_sanitizer +from azure.core.exceptions import HttpResponseError +from azure.ai.projects.models import ( + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceModelType, + VoiceOutputModality, +) + +# Fixed test-owned agent name: unlike conversation_id (server-generated, truly dynamic), this is +# our own choice and does not need is_live()/sanitizer handling -- it is identical in both modes. +_AGENT_NAME: Final = "test-conversations-read-agent" + +# Best-effort fixed wait (live only, seconds) after the realtime session ends, before reading the +# conversation back, so persistence finalization (items/audio) is more likely to have completed. +# This must be a single, fixed wait rather than a poll loop through the recorded client: repeated +# polling would record multiple cassette entries for the same "get conversation" request, but +# playback only ever issues that request once (polling itself is live-only), so a replay would +# incorrectly consume the *first* (possibly still "in_progress") recorded entry instead of the +# settled one. A single wait keeps exactly one logical call -- and therefore one cassette entry +# -- for both the live recording and the replay to agree on. +_FINALIZATION_WAIT_SECONDS: Final = 30 + + +def _create_live_conversation(project_client, model: str) -> str: + """Create a `store=True` voice agent, hold one turn over a live realtime session, and + return the resulting conversation id. Only ever called when ``is_live()``. + + :param project_client: The Foundry project client. + :param model: The realtime model deployment name. + :type project_client: ~azure.ai.projects.AIProjectClient + :type model: str + :return: The persisted conversation id. + :rtype: str + """ + try: + project_client.agents.delete(agent_name=_AGENT_NAME) + except Exception: # pylint: disable=broad-except + pass + + project_client.agents.create_version( + agent_name=_AGENT_NAME, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a helpful voice assistant. Keep replies short.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + store=True, + ), + ) + + conversation_id: Optional[str] = None + with project_client.beta.voice_agents.realtime.connect(agent_name=_AGENT_NAME) as conn: + session_created = conn.recv(timeout=30) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + conversation_id = session_created.conversation_id + + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text="Say hello.")], + ) + ) + conn.response.create() + + deadline = time.monotonic() + 45 + while time.monotonic() < deadline: + event = conn.recv(timeout=30) + if isinstance(event, RealtimeServerEventResponseDone): + break + + assert conversation_id is not None, "Expected session.created to carry a conversation_id (store=True)" + time.sleep(_FINALIZATION_WAIT_SECONDS) + return conversation_id + + +class TestVoiceAgentConversations(TestBase): + """ + Recorded tests covering the read-only voice-agent conversation REST API surface exposed + through ``project_client.beta.voice_agents.conversations`` (conversation envelope, + responses, items, and audio). + + NOTE: The ``beta.voice_agents.conversations.get_generated_audio_item*`` + methods are intentionally NOT covered here: they return the played-back-interrupted + subordinate "generated" audio, which requires deliberately barging in mid-reply during a + live session to produce -- not exercised by the simple single-turn conversation created + here. See this package's engineering notes. + """ + + # To run only this test: + # pytest tests\agents\test_voice_agent_conversations.py::TestVoiceAgentConversations::test_read_conversation -s + @servicePreparer() + @recorded_by_proxy() + def test_read_conversation(self, **kwargs): # pylint: disable=too-many-locals + """ + Test reading back a persisted voice-agent conversation: the envelope, its responses + (with per-response output items), its ordered items (the transcript), the merged + whole-call audio recording, a single item's audio, and finally deleting the conversation. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------------------------+----------------------------------------------------------- + GET /agents/{agent_name}/endpoint/protocols/voice/conversations beta.voice_agents.conversations.list() + GET /agents/{agent_name}/endpoint/protocols/voice/conversations/{id} beta.voice_agents.conversations.get() + GET .../conversations/{id}/responses beta.voice_agents.conversations.list_responses() + GET .../conversations/{id}/responses/{response_id} beta.voice_agents.conversations.get_response() + GET .../conversations/{id}/responses/{response_id}/items beta.voice_agents.conversations.list_response_items() + GET .../conversations/{id}/items beta.voice_agents.conversations.list_items() + GET .../conversations/{id}/items/{item_id} beta.voice_agents.conversations.get_item() + GET .../conversations/{id}/audio beta.voice_agents.conversations.get_audio() + GET .../conversations/{id}/audio/content beta.voice_agents.conversations.download_audio() + GET .../conversations/{id}/items/{item_id}/audio beta.voice_agents.conversations.get_audio_item() + GET .../conversations/{id}/items/{item_id}/audio/content beta.voice_agents.conversations.download_audio_item() + DELETE .../conversations/{id} beta.voice_agents.conversations.delete() + """ + print("\n") + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + conversations = project_client.beta.voice_agents.conversations + + if is_live(): + model = kwargs.get("foundry_voice_model_name") + assert model is not None + conversation_id = _create_live_conversation(project_client, model) + add_general_regex_sanitizer( + regex=re.escape(conversation_id), value="sanitized-conversation-id", function_scoped=True + ) + else: + conversation_id = "sanitized-conversation-id" + + try: + # The conversation should appear in the agent's conversation list. + found = any(c.id == conversation_id for c in conversations.list(_AGENT_NAME)) + assert found, "Expected the new conversation to appear in list" + + # The conversation envelope. + conversation = conversations.get(_AGENT_NAME, conversation_id) + assert conversation.id == conversation_id + assert conversation.status in ("in_progress", "completed", "failed") + assert conversation.created_at is not None + + # The responses (model inference turns) in the conversation. + responses = list(conversations.list_responses(_AGENT_NAME, conversation_id)) + assert len(responses) >= 1 + first_response = responses[0] + response_detail = conversations.get_response(_AGENT_NAME, conversation_id, first_response.id) + assert response_detail.id == first_response.id + + # The items produced by that response (does not raise; count may be 0 or more). + list(conversations.list_response_items(_AGENT_NAME, conversation_id, first_response.id)) + + # The ordered conversation items -- the full transcript (user + assistant + tool events). + items = list(conversations.list_items(_AGENT_NAME, conversation_id)) + assert len(items) >= 1 + first_item_id = items[0].get("id") + assert first_item_id + fetched_item = conversations.get_item(_AGENT_NAME, conversation_id, first_item_id) + assert fetched_item.get("id") == first_item_id + + # The merged whole-call recording and per-item audio. Completion is a hard requirement + # here (not a soft skip): a cassette recorded before the conversation finalized would + # otherwise let this test pass while silently never exercising any of the four audio + # methods below, hiding a regression in all of them (including permanently, if such a + # response were ever re-recorded). + assert ( + conversation.status == "completed" + ), f"Expected a completed conversation to exercise audio assertions, got {conversation.status!r}" + recording = conversations.get_audio(_AGENT_NAME, conversation_id) + assert recording.format is not None + if not recording.blob_uri: + audio_bytes = b"".join(conversations.download_audio(_AGENT_NAME, conversation_id)) + assert len(audio_bytes) > 0 + + # A single item's audio, if any item has one. Setup guarantees at least one audio + # item exists, so at least one retrieval must succeed -- otherwise a fully-broken + # get_audio_item/download_audio_item route would tolerate every 404 and still pass. + found_item_audio = False + for item in items: + item_id = item.get("id") + if not item_id: + continue + try: + item_audio = conversations.get_audio_item(_AGENT_NAME, conversation_id, item_id) + except HttpResponseError as e: + if e.status_code == 404: + continue + raise + found_item_audio = True + assert item_audio.role is not None + if not item_audio.blob_uri: + item_audio_bytes = b"".join( + conversations.download_audio_item(_AGENT_NAME, conversation_id, item_id) + ) + assert len(item_audio_bytes) > 0 + break + assert found_item_audio, "Expected at least one conversation item to have retrievable audio" + finally: + # Deleting a conversation removes it and all of its responses, items, and audio. + conversations.delete(_AGENT_NAME, conversation_id) + if is_live(): + project_client.agents.delete(agent_name=_AGENT_NAME) diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations_async.py new file mode 100644 index 000000000000..d843a1690994 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_conversations_async.py @@ -0,0 +1,234 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression,too-many-statements,broad-exception-caught +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +""" +Recorded tests covering the read-only voice-agent conversation REST API surface exposed through +``project_client.beta.voice_agents.conversations`` (async client). + +Async counterpart of ``test_voice_agent_conversations.py``. See that module's docstring for the +overall rationale (live-only setup to obtain a real conversation id, sanitized to a fixed +placeholder so the recorded REST calls that follow can be replayed). +""" + +import re +import asyncio +import time +from typing import Final, Optional + +from test_base import TestBase, servicePreparer +from devtools_testutils import is_live, add_general_regex_sanitizer +from devtools_testutils.aio import recorded_by_proxy_async +from azure.core.exceptions import HttpResponseError +from azure.ai.projects.models import ( + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventResponseDone, + RealtimeServerEventSessionCreated, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceModelType, + VoiceOutputModality, +) + +# Fixed test-owned agent name: unlike conversation_id (server-generated, truly dynamic), this is +# our own choice and does not need is_live()/sanitizer handling -- it is identical in both modes. +_AGENT_NAME: Final = "test-conversations-read-agent-async" + +# Best-effort fixed wait (live only, seconds) after the realtime session ends, before reading the +# conversation back, so persistence finalization (items/audio) is more likely to have completed. +# This must be a single, fixed wait rather than a poll loop through the recorded client: repeated +# polling would record multiple cassette entries for the same "get conversation" request, but +# playback only ever issues that request once (polling itself is live-only), so a replay would +# incorrectly consume the *first* (possibly still "in_progress") recorded entry instead of the +# settled one. A single wait keeps exactly one logical call -- and therefore one cassette entry +# -- for both the live recording and the replay to agree on. +_FINALIZATION_WAIT_SECONDS: Final = 30 + + +async def _create_live_conversation(project_client, model: str) -> str: + """Create a `store=True` voice agent, hold one turn over a live realtime session, and + return the resulting conversation id. Only ever called when ``is_live()``. + + :param project_client: The Foundry project client. + :param model: The realtime model deployment name. + :type project_client: ~azure.ai.projects.aio.AIProjectClient + :type model: str + :return: The persisted conversation id. + :rtype: str + """ + try: + await project_client.agents.delete(agent_name=_AGENT_NAME) + except Exception: # pylint: disable=broad-except + pass + + await project_client.agents.create_version( + agent_name=_AGENT_NAME, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a helpful voice assistant. Keep replies short.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + store=True, + ), + ) + + conversation_id: Optional[str] = None + async with project_client.beta.voice_agents.realtime.connect(agent_name=_AGENT_NAME) as conn: + session_created = await asyncio.wait_for(conn.recv(), timeout=30) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + conversation_id = session_created.conversation_id + + await conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[RealtimeConversationItemMessageUserContent(type="input_text", text="Say hello.")], + ) + ) + await conn.response.create() + + got_response_done = False + deadline = time.monotonic() + 45 + while time.monotonic() < deadline and not got_response_done: + remaining = max(deadline - time.monotonic(), 0.1) + event = await asyncio.wait_for(conn.recv(), timeout=min(30, remaining)) + if isinstance(event, RealtimeServerEventResponseDone): + got_response_done = True + + assert conversation_id is not None, "Expected session.created to carry a conversation_id (store=True)" + await asyncio.sleep(_FINALIZATION_WAIT_SECONDS) + return conversation_id + + +class TestVoiceAgentConversationsAsync(TestBase): + """ + Recorded tests covering the read-only voice-agent conversation REST API surface exposed + through ``project_client.beta.voice_agents.conversations`` (conversation envelope, + responses, items, and audio), using the async client. + + NOTE: The ``beta.voice_agents.conversations.get_generated_audio_item*`` + methods are intentionally NOT covered here: they return the played-back-interrupted + subordinate "generated" audio, which requires deliberately barging in mid-reply during a + live session to produce -- not exercised by the simple single-turn conversation created + here. See this package's engineering notes. + """ + + # To run only this test: + # pytest tests\agents\test_voice_agent_conversations_async.py::TestVoiceAgentConversationsAsync::test_read_conversation_async -s + @servicePreparer() + @recorded_by_proxy_async() + async def test_read_conversation_async(self, **kwargs): # pylint: disable=too-many-locals + """ + Test reading back a persisted voice-agent conversation: the envelope, its responses + (with per-response output items), its ordered items (the transcript), the merged + whole-call audio recording, a single item's audio, and finally deleting the conversation. + + Routes used in this test: see the sync counterpart's docstring in + ``test_voice_agent_conversations.py`` for the full route table (identical here). + """ + print("\n") + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + conversations = project_client.beta.voice_agents.conversations + + async with project_client: + if is_live(): + model = kwargs.get("foundry_voice_model_name") + assert model is not None + conversation_id = await _create_live_conversation(project_client, model) + add_general_regex_sanitizer( + regex=re.escape(conversation_id), value="sanitized-conversation-id", function_scoped=True + ) + else: + conversation_id = "sanitized-conversation-id" + + try: + # The conversation should appear in the agent's conversation list. + found = False + async for c in conversations.list(_AGENT_NAME): + if c.id == conversation_id: + found = True + break + assert found, "Expected the new conversation to appear in list" + + # The conversation envelope. + conversation = await conversations.get(_AGENT_NAME, conversation_id) + assert conversation.id == conversation_id + assert conversation.status in ("in_progress", "completed", "failed") + assert conversation.created_at is not None + + # The responses (model inference turns) in the conversation. + responses = [r async for r in conversations.list_responses(_AGENT_NAME, conversation_id)] + assert len(responses) >= 1 + first_response = responses[0] + response_detail = await conversations.get_response(_AGENT_NAME, conversation_id, first_response.id) + assert response_detail.id == first_response.id + + # The items produced by that response (does not raise; count may be 0 or more). + _ = [ + item + async for item in conversations.list_response_items(_AGENT_NAME, conversation_id, first_response.id) + ] + + # The ordered conversation items -- the full transcript (user + assistant + tool events). + items = [item async for item in conversations.list_items(_AGENT_NAME, conversation_id)] + assert len(items) >= 1 + first_item_id = items[0].get("id") + assert first_item_id + fetched_item = await conversations.get_item(_AGENT_NAME, conversation_id, first_item_id) + assert fetched_item.get("id") == first_item_id + + # The merged whole-call recording and per-item audio. Completion is a hard + # requirement here (not a soft skip): a cassette recorded before the conversation + # finalized would otherwise let this test pass while silently never exercising any + # of the four audio methods below, hiding a regression in all of them (including + # permanently, if such a response were ever re-recorded). + assert ( + conversation.status == "completed" + ), f"Expected a completed conversation to exercise audio assertions, got {conversation.status!r}" + recording = await conversations.get_audio(_AGENT_NAME, conversation_id) + assert recording.format is not None + if not recording.blob_uri: + audio_chunks = [ + chunk async for chunk in await conversations.download_audio(_AGENT_NAME, conversation_id) + ] + assert len(b"".join(audio_chunks)) > 0 + + # A single item's audio, if any item has one. Setup guarantees at least one audio + # item exists, so at least one retrieval must succeed -- otherwise a fully-broken + # get_audio_item/download_audio_item route would tolerate every 404 and still pass. + found_item_audio = False + for item in items: + item_id = item.get("id") + if not item_id: + continue + try: + item_audio = await conversations.get_audio_item(_AGENT_NAME, conversation_id, item_id) + except HttpResponseError as e: + if e.status_code == 404: + continue + raise + found_item_audio = True + assert item_audio.role is not None + if not item_audio.blob_uri: + item_audio_chunks = [ + chunk + async for chunk in await conversations.download_audio_item( + _AGENT_NAME, conversation_id, item_id + ) + ] + assert len(b"".join(item_audio_chunks)) > 0 + break + assert found_item_audio, "Expected at least one conversation item to have retrievable audio" + finally: + # Deleting a conversation removes it and all of its responses, items, and audio. + await conversations.delete(_AGENT_NAME, conversation_id) + if is_live(): + await project_client.agents.delete(agent_name=_AGENT_NAME) diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud.py new file mode 100644 index 000000000000..78fed1d9abd8 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud.py @@ -0,0 +1,199 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +from test_base import TestBase, servicePreparer +from devtools_testutils import recorded_by_proxy, RecordedTransport +from azure.ai.projects.models import ( + AgentDetails, + AgentKind, + AgentVersionDetails, + GenerateVoiceAgentRequest, + VoiceAgentDefinition, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceOutputModality, +) + + +class TestVoiceAgentCrud(TestBase): + """ + Recorded tests covering the voice-agent (`kind="voice"`) REST API surface exposed through + `project_client.agents.*`. + + NOTE: Some voice-agent REST APIs are intentionally NOT covered here because they are + currently blocked by known service-side bugs (see this package's engineering notes): + - Reading back a conversation (`project_client.beta.voice_agents.conversations.*`) using a + `conversation_id` produced by a live realtime WebSocket session - the service's REST + conversation-ID validator rejects the ID format generated by the realtime WS subsystem. + This is also not practical to cover with HTTP-only recorded tests since it requires an + actual WebSocket session. + Once these are fixed service-side, tests can be added for them. + """ + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud.py::TestVoiceAgentCrud::test_voice_agent_crud -s + @servicePreparer() + @recorded_by_proxy() + def test_voice_agent_crud(self, **kwargs): + """ + Test CRUD operations for voice Agents (`kind="voice"`). + + This test creates a voice agent, creates a new version of it, gets it, gets a specific + version, lists its versions, and deletes it. + + Routes used in this test: + + Action REST API Route Client Method + ------+---------------------------------------------+----------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name} project_client.agents.get() + GET /agents/{agent_name}/versions/{agent_version} project_client.agents.get_version() + GET /agents/{agent_name}/versions project_client.agents.list_versions() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + # Voice-agent operations require the preview opt-in. + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "MyVoiceAgentCrudTest" + + def make_definition(instructions: str) -> VoiceAgentDefinition: + return VoiceAgentDefinition( + model_type="managed", + model=model, + instructions=instructions, + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ) + + # Create the initial voice agent (version 1). + agent_version1: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant."), + ) + self._validate_agent_version(agent_version1, expected_name=agent_name) + assert agent_version1.definition.kind == "voice" # type: ignore[attr-defined] + + # Create a new version with updated instructions. + agent_version2: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant. Always greet the caller by name."), + ) + self._validate_agent_version(agent_version2, expected_name=agent_name) + + # Get the voice agent. + retrieved_agent: AgentDetails = project_client.agents.get(agent_name=agent_name) + self._validate_agent(retrieved_agent, expected_name=agent_name, expected_latest_version=agent_version2.version) + + # Retrieve a specific version. + retrieved_agent_version: AgentVersionDetails = project_client.agents.get_version( + agent_name=agent_name, agent_version=agent_version1.version + ) + self._validate_agent_version( + retrieved_agent_version, expected_name=agent_name, expected_version=agent_version1.version + ) + + # List all versions. + item_count = 0 + for listed_agent_version in project_client.agents.list_versions(agent_name=agent_name): + item_count += 1 + self._validate_agent_version(listed_agent_version, expected_name=agent_name) + assert item_count >= 2 + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud.py::TestVoiceAgentCrud::test_voice_agent_disable_enable -s + @servicePreparer() + @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX2) + def test_voice_agent_disable_enable(self, **kwargs): + """ + Test disable and enable operations for a voice Agent. + + Routes used in this test: + + Action REST API Route Client Method + ------+---------------------------------------------+----------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + POST /agents/{agent_name}:disable project_client.agents.disable() + POST /agents/{agent_name}:enable project_client.agents.enable() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "VoiceAgentDisableEnableTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type="managed", + model=model, + instructions="You are a helpful voice assistant.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # Disable the agent. + project_client.agents.disable(agent_name=agent_name) + disabled_agent: AgentDetails = project_client.agents.get(agent_name=agent_name) + assert str(disabled_agent.state) == "AgentState.DISABLED" or disabled_agent.state == "disabled" + + # Enable the agent. + project_client.agents.enable(agent_name=agent_name) + enabled_agent: AgentDetails = project_client.agents.get(agent_name=agent_name) + assert str(enabled_agent.state) == "AgentState.ENABLED" or enabled_agent.state == "enabled" + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud.py::TestVoiceAgentCrud::test_generate_agent -s + @servicePreparer() + @recorded_by_proxy() + def test_generate_agent(self, **kwargs): + """ + Test guided authoring for a voice Agent via `beta.agents.create_from_prompt()`. + + Routes used in this test: + + Action REST API Route Client Method + ------+----------------------------+----------------------------------- + POST /agents:generate project_client.beta.agents.create_from_prompt() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "VoiceAgentGenerateTest" + + agent: AgentDetails = project_client.beta.agents.create_from_prompt( + GenerateVoiceAgentRequest(kind=AgentKind.VOICE, name=agent_name) + ) + self._validate_agent(agent, expected_name=agent_name) + assert agent.versions.latest.definition.kind == "voice" # type: ignore[attr-defined] + assert agent.versions.latest.definition.instructions # type: ignore[attr-defined] + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud_async.py new file mode 100644 index 000000000000..a16585598a71 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_crud_async.py @@ -0,0 +1,205 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +from test_base import TestBase, servicePreparer +from devtools_testutils.aio import recorded_by_proxy_async +from devtools_testutils import RecordedTransport +from azure.ai.projects.models import ( + AgentDetails, + AgentKind, + AgentVersionDetails, + GenerateVoiceAgentRequest, + VoiceAgentDefinition, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceOutputModality, +) + + +class TestVoiceAgentCrudAsync(TestBase): + """ + Recorded tests covering the voice-agent (`kind="voice"`) REST API surface exposed through + `project_client.agents.*`. + + NOTE: Some voice-agent REST APIs are intentionally NOT covered here because they are + currently blocked by known service-side bugs (see this package's engineering notes): + - Reading back a conversation (`project_client.beta.voice_agents.conversations.*`) using a + `conversation_id` produced by a live realtime WebSocket session - the service's REST + conversation-ID validator rejects the ID format generated by the realtime WS subsystem. + This is also not practical to cover with HTTP-only recorded tests since it requires an + actual WebSocket session. + Once these are fixed service-side, tests can be added for them. + """ + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud_async.py::TestVoiceAgentCrudAsync::test_voice_agent_crud_async -s + @servicePreparer() + @recorded_by_proxy_async() + async def test_voice_agent_crud_async(self, **kwargs): + """ + Test CRUD operations for voice Agents (`kind="voice"`). + + This test creates a voice agent, creates a new version of it, gets it, gets a specific + version, lists its versions, and deletes it. + + Routes used in this test: + + Action REST API Route Client Method + ------+---------------------------------------------+----------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name} project_client.agents.get() + GET /agents/{agent_name}/versions/{agent_version} project_client.agents.get_version() + GET /agents/{agent_name}/versions project_client.agents.list_versions() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + # Voice-agent operations require the preview opt-in. + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "MyVoiceAgentCrudTestAsync" + + def make_definition(instructions: str) -> VoiceAgentDefinition: + return VoiceAgentDefinition( + model_type="managed", + model=model, + instructions=instructions, + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ) + + async with project_client: + # Create the initial voice agent (version 1). + agent_version1: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant."), + ) + self._validate_agent_version(agent_version1, expected_name=agent_name) + assert agent_version1.definition.kind == "voice" # type: ignore[attr-defined] + + # Create a new version with updated instructions. + agent_version2: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=make_definition("You are a helpful voice assistant. Always greet the caller by name."), + ) + self._validate_agent_version(agent_version2, expected_name=agent_name) + + # Get the voice agent. + retrieved_agent: AgentDetails = await project_client.agents.get(agent_name=agent_name) + self._validate_agent( + retrieved_agent, expected_name=agent_name, expected_latest_version=agent_version2.version + ) + + # Retrieve a specific version. + retrieved_agent_version: AgentVersionDetails = await project_client.agents.get_version( + agent_name=agent_name, agent_version=agent_version1.version + ) + self._validate_agent_version( + retrieved_agent_version, expected_name=agent_name, expected_version=agent_version1.version + ) + + # List all versions. + item_count = 0 + async for listed_agent_version in project_client.agents.list_versions(agent_name=agent_name): + item_count += 1 + self._validate_agent_version(listed_agent_version, expected_name=agent_name) + assert item_count >= 2 + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud_async.py::TestVoiceAgentCrudAsync::test_voice_agent_disable_enable_async -s + @servicePreparer() + @recorded_by_proxy_async(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX2) + async def test_voice_agent_disable_enable_async(self, **kwargs): + """ + Test disable and enable operations for a voice Agent. + + Routes used in this test: + + Action REST API Route Client Method + ------+---------------------------------------------+----------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + POST /agents/{agent_name}:disable project_client.agents.disable() + POST /agents/{agent_name}:enable project_client.agents.enable() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "VoiceAgentDisableEnableTestAsync" + + async with project_client: + # Delete any existing agent from previous test runs (ignore failures) + try: + await project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type="managed", + model=model, + instructions="You are a helpful voice assistant.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # Disable the agent. + await project_client.agents.disable(agent_name=agent_name) + disabled_agent: AgentDetails = await project_client.agents.get(agent_name=agent_name) + assert str(disabled_agent.state) == "AgentState.DISABLED" or disabled_agent.state == "disabled" + + # Enable the agent. + await project_client.agents.enable(agent_name=agent_name) + enabled_agent: AgentDetails = await project_client.agents.get(agent_name=agent_name) + assert str(enabled_agent.state) == "AgentState.ENABLED" or enabled_agent.state == "enabled" + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_crud_async.py::TestVoiceAgentCrudAsync::test_generate_agent_async -s + @servicePreparer() + @recorded_by_proxy_async() + async def test_generate_agent_async(self, **kwargs): + """ + Test guided authoring for a voice Agent via `beta.agents.create_from_prompt()`. + + Routes used in this test: + + Action REST API Route Client Method + ------+----------------------------+----------------------------------- + POST /agents:generate project_client.beta.agents.create_from_prompt() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = "VoiceAgentGenerateTestAsync" + + async with project_client: + agent: AgentDetails = await project_client.beta.agents.create_from_prompt( + GenerateVoiceAgentRequest(kind=AgentKind.VOICE, name=agent_name) + ) + self._validate_agent(agent, expected_name=agent_name) + assert agent.versions.latest.definition.kind == "voice" # type: ignore[attr-defined] + assert agent.versions.latest.definition.instructions # type: ignore[attr-defined] + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live.py new file mode 100644 index 000000000000..2baf6a476c93 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live.py @@ -0,0 +1,299 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +""" +Live-only tests for the hand-written sync ``client.beta.voice_agents.realtime`` WebSocket streaming client. + +Unlike ``tests/agents/test_realtime_client.py`` (which mocks the transport to unit-test URL +construction, auth, and error paths without a live service), these tests open a REAL WebSocket +connection to a live voice agent and assert on the actual streamed server events. They are +modeled on the live realtime test pattern used by the ``azure-ai-voicelive`` package +(``sdk/voicelive/azure-ai-voicelive/tests/live/``): skip entirely unless running live, use +generous per-event timeouts, and assert on event *types* and content presence/length rather than +exact audio bytes (the model's actual audio/text output is not deterministic). + +These tests do not use ``store=True`` / read back a persisted conversation -- that surface +(``project_client.beta.voice_agents.conversations.*``) is covered by the separate recorded +tests in ``test_voice_agent_conversations.py``, which need a real conversation id but replay +against a recorded cassette rather than opening a live WebSocket connection on every run. +""" + +import json +import time +from typing import Any, cast, Final, List, Tuple + +import pytest +from test_base import TestBase, servicePreparer +from devtools_testutils import is_live +from azure.ai.projects.models import ( + RealtimeConversationItemFunctionCallOutput, + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventError, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseDone, + RealtimeServerEventResponseFunctionCallArgumentsDone, + RealtimeServerEventResponseTextDone, + RealtimeServerEventSessionCreated, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceAgentFunctionTool, + VoiceModelType, + VoiceOutputModality, +) + +# Seconds to wait for a single server event (session handshake, an audio delta, ...). +_EVENT_TIMEOUT: Final = 30 +# Seconds to wait for a full response turn to finish (may include a tool round-trip). +_RESPONSE_TIMEOUT: Final = 45 + + +def _get_weather(city: str) -> str: + """A trivial local "tool" implementation the agent can call. + + :param city: The city to look up. + :type city: str + :return: A canned weather report for the city. + :rtype: str + """ + return json.dumps({"city": city, "condition": "sunny", "temperature_f": 72}) + + +@pytest.mark.live_test_only +@pytest.mark.skipif( + not is_live(), + reason="Live-only: opens a real WebSocket connection to the realtime service, which cannot " + "be captured/replayed by the test proxy.", +) +class TestVoiceAgentRealtimeLive(TestBase): + """ + Live tests covering ``client.beta.voice_agents.realtime.connect()`` (the hand-written sync WebSocket streaming + client) against a real voice agent and a real service connection. + """ + + def _make_agent_name(self, suffix: str) -> str: + return f"test-realtime-live-{suffix}" + + def _create_basic_agent(self, project_client, agent_name: str, model: str) -> None: + project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a helpful voice assistant. Keep replies short.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ), + ) + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live.py::TestVoiceAgentRealtimeLive::test_realtime_session_lifecycle -s + @servicePreparer() + def test_realtime_session_lifecycle(self, **kwargs): + """ + Test opening and cleanly closing a realtime WebSocket session, and receiving the initial + ``session.created`` handshake event. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("lifecycle") + + try: + self._create_basic_agent(project_client, agent_name, model) + + with project_client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + event = conn.recv(timeout=_EVENT_TIMEOUT) + assert isinstance(event, RealtimeServerEventSessionCreated) + assert event.type == "session.created" + # The `with` block above closes the connection; a second `recv()` after close + # would raise, so we don't attempt one -- clean exit from the block is the assertion. + finally: + project_client.agents.delete(agent_name=agent_name) + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live.py::TestVoiceAgentRealtimeLive::test_realtime_text_turn_produces_audio_and_transcript -s + @servicePreparer() + def test_realtime_text_turn_produces_audio_and_transcript(self, **kwargs): + """ + Test sending one typed user turn and receiving a streamed audio + transcript reply. + + Sends a ``RealtimeConversationItemMessageUser`` text turn and asserts that the service + streams back at least one non-empty audio delta, a transcript-done event with non-empty + text, and a final ``response.done``. Content is not asserted verbatim (the model's actual + wording is not deterministic); only event types, ordering-independent presence, and basic + size/non-emptiness are checked, matching the ``azure-ai-voicelive`` live test convention. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("text-turn") + + try: + self._create_basic_agent(project_client, agent_name, model) + + with project_client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + session_created = conn.recv(timeout=_EVENT_TIMEOUT) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[ + RealtimeConversationItemMessageUserContent( + type="input_text", text="Say the word 'hello' and nothing else." + ) + ], + ) + ) + conn.response.create() + + audio_delta_count = 0 + audio_bytes = 0 + transcript_done_count = 0 + got_response_done = False + deadline = time.monotonic() + _RESPONSE_TIMEOUT + + while time.monotonic() < deadline and not got_response_done: + event = conn.recv(timeout=_EVENT_TIMEOUT) + if isinstance(event, RealtimeServerEventResponseAudioDelta): + audio_delta_count += 1 + audio_bytes += len(event.delta) + elif isinstance(event, RealtimeServerEventResponseAudioTranscriptDone): + transcript_done_count += 1 + assert event.transcript is not None and len(event.transcript.strip()) > 0 + elif isinstance(event, RealtimeServerEventResponseDone): + got_response_done = True + elif isinstance(event, RealtimeServerEventError): + pytest.fail(f"Session error: {event.error.message}") + + assert got_response_done, "Did not receive response.done within the timeout" + assert audio_delta_count > 0, "Expected at least one response.audio.delta event" + assert audio_bytes > 0, "Expected non-empty streamed audio" + assert transcript_done_count == 1, "Expected exactly one audio-transcript-done event" + finally: + project_client.agents.delete(agent_name=agent_name) + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live.py::TestVoiceAgentRealtimeLive::test_realtime_function_tool_call -s + @servicePreparer() + def test_realtime_function_tool_call(self, **kwargs): + """ + Test a client-executed function-tool round trip during a live realtime session. + + Configures the agent with a ``get_weather`` function tool, sends a prompt that should + trigger it, executes the tool call locally when the service asks for it, and sends the + result back so the agent can finish its reply -- mirroring + ``samples/agents/voice/sample_voice_agent_live_function_tool.py``, which this test + adapts into an automated assertion-based form. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("tool-call") + + get_weather_tool = VoiceAgentFunctionTool( + name="get_weather", + description="Get the current weather for a city.", + parameters=cast( + Any, + { + "type": "object", + "properties": {"city": {"type": "string", "description": "City name, e.g. Seattle."}}, + "required": ["city"], + }, + ), + ) + + try: + project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions=( + "You are a helpful voice assistant. Use the get_weather tool when the " + "caller asks about the weather, then answer using its result." + ), + output_modalities=[VoiceOutputModality.TEXT], + tools=[get_weather_tool], + ), + ) + + with project_client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + session_created = conn.recv(timeout=_EVENT_TIMEOUT) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + + conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[ + RealtimeConversationItemMessageUserContent( + type="input_text", text="What's the weather like in Seattle right now?" + ) + ], + ) + ) + conn.response.create() + + tool_call_count = 0 + final_text = "" + deadline = time.monotonic() + _RESPONSE_TIMEOUT + done = False + # Tool outputs collected from the current turn's function-call(s). These are held + # back and only sent once this turn's own response.done arrives (below) -- calling + # response.create() while the function-call response is still finishing can + # otherwise race with the service and produce a concurrent-response error. + pending_tool_outputs: List[Tuple[str, str]] = [] + + while time.monotonic() < deadline and not done: + event = conn.recv(timeout=_EVENT_TIMEOUT) + if isinstance(event, RealtimeServerEventResponseFunctionCallArgumentsDone): + tool_call_count += 1 + assert event.name == "get_weather" + args = json.loads(event.arguments) + assert "city" in args + result = _get_weather(**args) + pending_tool_outputs.append((event.call_id, result)) + elif isinstance(event, RealtimeServerEventResponseTextDone): + final_text = event.text + elif isinstance(event, RealtimeServerEventResponseDone): + # A response.done that isn't itself a function call is the final answer. + # Output items surface as plain mappings (open union) or typed models. + output = event.response.output or [] + is_function_call = any( + (item.get("type") if isinstance(item, dict) else getattr(item, "type", None)) + == "function_call" + for item in output + ) + if pending_tool_outputs: + # The function-call response has now fully completed, so it's safe to + # submit its tool output(s) and ask for a new response. + for call_id, result in pending_tool_outputs: + conn.conversation.item.create( + item=RealtimeConversationItemFunctionCallOutput(call_id=call_id, output=result) + ) + pending_tool_outputs = [] + conn.response.create() + elif not is_function_call: + done = True + elif isinstance(event, RealtimeServerEventError): + pytest.fail(f"Session error: {event.error.message}") + + assert done, "Did not receive a final (non-tool-call) response.done within the timeout" + assert tool_call_count >= 1, "Expected the agent to invoke the get_weather tool at least once" + assert final_text is not None and len(final_text.strip()) > 0 + finally: + project_client.agents.delete(agent_name=agent_name) diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live_async.py new file mode 100644 index 000000000000..4feef324eda4 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_realtime_live_async.py @@ -0,0 +1,297 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +""" +Live-only tests for the hand-written async ``async_client.beta.voice_agents.realtime`` WebSocket streaming client. + +Async counterpart of ``test_voice_agent_realtime_live.py``. See that module's docstring for the +overall rationale (modeled on the ``azure-ai-voicelive`` package's live realtime test pattern: +skip entirely unless running live, generous per-event timeouts, assert on event types and +content presence/length rather than exact audio bytes). +""" + +import asyncio +import json +import time +from typing import Any, cast, Final, List, Tuple + +import pytest +from test_base import TestBase, servicePreparer +from devtools_testutils import is_live +from azure.ai.projects.models import ( + RealtimeConversationItemFunctionCallOutput, + RealtimeConversationItemMessageUser, + RealtimeConversationItemMessageUserContent, + RealtimeConversationItemType, + RealtimeServerEventError, + RealtimeServerEventResponseAudioDelta, + RealtimeServerEventResponseAudioTranscriptDone, + RealtimeServerEventResponseDone, + RealtimeServerEventResponseFunctionCallArgumentsDone, + RealtimeServerEventResponseTextDone, + RealtimeServerEventSessionCreated, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceAgentFunctionTool, + VoiceModelType, + VoiceOutputModality, +) + +# Seconds to wait for a single server event (session handshake, an audio delta, ...). +_EVENT_TIMEOUT: Final = 30 +# Seconds to wait for a full response turn to finish (may include a tool round-trip). +_RESPONSE_TIMEOUT: Final = 45 + + +def _get_weather(city: str) -> str: + """A trivial local "tool" implementation the agent can call. + + :param city: The city to look up. + :type city: str + :return: A canned weather report for the city. + :rtype: str + """ + return json.dumps({"city": city, "condition": "sunny", "temperature_f": 72}) + + +@pytest.mark.live_test_only +@pytest.mark.skipif( + not is_live(), + reason="Live-only: opens a real WebSocket connection to the realtime service, which cannot " + "be captured/replayed by the test proxy.", +) +class TestVoiceAgentRealtimeLiveAsync(TestBase): + """ + Live tests covering ``async_client.beta.voice_agents.realtime.connect()`` (the hand-written async WebSocket + streaming client) against a real voice agent and a real service connection. + """ + + def _make_agent_name(self, suffix: str) -> str: + return f"test-realtime-live-async-{suffix}" + + async def _create_basic_agent(self, project_client, agent_name: str, model: str) -> None: + await project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions="You are a helpful voice assistant. Keep replies short.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ), + ) + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live_async.py::TestVoiceAgentRealtimeLiveAsync::test_realtime_session_lifecycle_async -s + @servicePreparer() + async def test_realtime_session_lifecycle_async(self, **kwargs): + """ + Test opening and cleanly closing a realtime WebSocket session, and receiving the initial + ``session.created`` handshake event. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("lifecycle") + + try: + await self._create_basic_agent(project_client, agent_name, model) + + async with project_client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + event = await asyncio.wait_for(conn.recv(), timeout=_EVENT_TIMEOUT) + assert isinstance(event, RealtimeServerEventSessionCreated) + assert event.type == "session.created" + # The `async with` block above closes the connection; a second `recv()` after close + # would raise, so we don't attempt one -- clean exit from the block is the assertion. + finally: + await project_client.agents.delete(agent_name=agent_name) + await project_client.close() + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live_async.py::TestVoiceAgentRealtimeLiveAsync::test_realtime_text_turn_produces_audio_and_transcript_async -s + @servicePreparer() + async def test_realtime_text_turn_produces_audio_and_transcript_async(self, **kwargs): + """ + Test sending one typed user turn and receiving a streamed audio + transcript reply. + + Sends a ``RealtimeConversationItemMessageUser`` text turn and asserts that the service + streams back at least one non-empty audio delta, a transcript-done event with non-empty + text, and a final ``response.done``. Content is not asserted verbatim (the model's actual + wording is not deterministic); only event types, ordering-independent presence, and basic + size/non-emptiness are checked, matching the ``azure-ai-voicelive`` live test convention. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("text-turn") + + try: + await self._create_basic_agent(project_client, agent_name, model) + + async with project_client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + session_created = await asyncio.wait_for(conn.recv(), timeout=_EVENT_TIMEOUT) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + + await conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[ + RealtimeConversationItemMessageUserContent( + type="input_text", text="Say the word 'hello' and nothing else." + ) + ], + ) + ) + await conn.response.create() + + audio_delta_count = 0 + audio_bytes = 0 + transcript_done_count = 0 + got_response_done = False + deadline = time.monotonic() + _RESPONSE_TIMEOUT + + while time.monotonic() < deadline and not got_response_done: + remaining = max(deadline - time.monotonic(), 0.1) + event = await asyncio.wait_for(conn.recv(), timeout=min(_EVENT_TIMEOUT, remaining)) + if isinstance(event, RealtimeServerEventResponseAudioDelta): + audio_delta_count += 1 + audio_bytes += len(event.delta) + elif isinstance(event, RealtimeServerEventResponseAudioTranscriptDone): + transcript_done_count += 1 + assert event.transcript is not None and len(event.transcript.strip()) > 0 + elif isinstance(event, RealtimeServerEventResponseDone): + got_response_done = True + elif isinstance(event, RealtimeServerEventError): + pytest.fail(f"Session error: {event.error.message}") + + assert got_response_done, "Did not receive response.done within the timeout" + assert audio_delta_count > 0, "Expected at least one response.audio.delta event" + assert audio_bytes > 0, "Expected non-empty streamed audio" + assert transcript_done_count == 1, "Expected exactly one audio-transcript-done event" + finally: + await project_client.agents.delete(agent_name=agent_name) + await project_client.close() + + # To run only this test: + # pytest tests\agents\test_voice_agent_realtime_live_async.py::TestVoiceAgentRealtimeLiveAsync::test_realtime_function_tool_call_async -s + @servicePreparer() + async def test_realtime_function_tool_call_async(self, **kwargs): + """ + Test a client-executed function-tool round trip during a live realtime session. + + Configures the agent with a ``get_weather`` function tool, sends a prompt that should + trigger it, executes the tool call locally when the service asks for it, and sends the + result back so the agent can finish its reply -- the async counterpart of + ``sample_voice_agent_live_function_tool.py``'s pattern, adapted into an automated + assertion-based test. + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(operation_group="agents", allow_preview=True, **kwargs) + agent_name = self._make_agent_name("tool-call") + + get_weather_tool = VoiceAgentFunctionTool( + name="get_weather", + description="Get the current weather for a city.", + parameters=cast( + Any, + { + "type": "object", + "properties": {"city": {"type": "string", "description": "City name, e.g. Seattle."}}, + "required": ["city"], + }, + ), + ) + + try: + await project_client.agents.create_version( + agent_name=agent_name, + definition=VoiceAgentDefinition( + model_type=VoiceModelType.MANAGED, + model=model, + instructions=( + "You are a helpful voice assistant. Use the get_weather tool when the " + "caller asks about the weather, then answer using its result." + ), + output_modalities=[VoiceOutputModality.TEXT], + tools=[get_weather_tool], + ), + ) + + async with project_client.beta.voice_agents.realtime.connect(agent_name=agent_name) as conn: + session_created = await asyncio.wait_for(conn.recv(), timeout=_EVENT_TIMEOUT) + assert isinstance(session_created, RealtimeServerEventSessionCreated) + + await conn.conversation.item.create( + item=RealtimeConversationItemMessageUser( + type=RealtimeConversationItemType.MESSAGE, + content=[ + RealtimeConversationItemMessageUserContent( + type="input_text", text="What's the weather like in Seattle right now?" + ) + ], + ) + ) + await conn.response.create() + + tool_call_count = 0 + final_text = "" + deadline = time.monotonic() + _RESPONSE_TIMEOUT + done = False + # Tool outputs collected from the current turn's function-call(s). These are held + # back and only sent once this turn's own response.done arrives (below) -- calling + # response.create() while the function-call response is still finishing can + # otherwise race with the service and produce a concurrent-response error. + pending_tool_outputs: List[Tuple[str, str]] = [] + + while time.monotonic() < deadline and not done: + remaining = max(deadline - time.monotonic(), 0.1) + event = await asyncio.wait_for(conn.recv(), timeout=min(_EVENT_TIMEOUT, remaining)) + if isinstance(event, RealtimeServerEventResponseFunctionCallArgumentsDone): + tool_call_count += 1 + assert event.name == "get_weather" + args = json.loads(event.arguments) + assert "city" in args + result = _get_weather(**args) + pending_tool_outputs.append((event.call_id, result)) + elif isinstance(event, RealtimeServerEventResponseTextDone): + final_text = event.text + elif isinstance(event, RealtimeServerEventResponseDone): + # A response.done that isn't itself a function call is the final answer. + # Output items surface as plain mappings (open union) or typed models. + output = event.response.output or [] + is_function_call = any( + (item.get("type") if isinstance(item, dict) else getattr(item, "type", None)) + == "function_call" + for item in output + ) + if pending_tool_outputs: + # The function-call response has now fully completed, so it's safe to + # submit its tool output(s) and ask for a new response. + for call_id, result in pending_tool_outputs: + await conn.conversation.item.create( + item=RealtimeConversationItemFunctionCallOutput(call_id=call_id, output=result) + ) + pending_tool_outputs = [] + await conn.response.create() + elif not is_function_call: + done = True + elif isinstance(event, RealtimeServerEventError): + pytest.fail(f"Session error: {event.error.message}") + + assert done, "Did not receive a final (non-tool-call) response.done within the timeout" + assert tool_call_count >= 1, "Expected the agent to invoke the get_weather tool at least once" + assert final_text is not None and len(final_text.strip()) > 0 + finally: + await project_client.agents.delete(agent_name=agent_name) + await project_client.close() diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony.py new file mode 100644 index 000000000000..335bfb4fa1cf --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony.py @@ -0,0 +1,312 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +from test_base import TestBase, servicePreparer +from devtools_testutils import recorded_by_proxy +import pytest +from azure.core import MatchConditions +from azure.core.exceptions import HttpResponseError, ResourceNotFoundError +from azure.ai.projects.models import ( + AgentVersionDetails, + PSTNTelephonyTransferDestination, + TelephonyBindingStatus, + TelephonyTransferTarget, + TelephonyTransferTargets, + UpdateTelephonyBindingRequest, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceOutputModality, +) + + +class TestVoiceAgentTelephony(TestBase): + """ + Recorded tests covering the voice-agent telephony REST API surface exposed through + `project_client.agents.*` (telephony bindings, calls, and transfer targets), and the + top-level `project_client.beta.voice_agents.conversations.*` generated-audio reads. + + NOTE: All tests in this file are currently marked `skip`: + - The telephony routes (`/agents/{agent_name}/telephony_bindings`, `/telephony_calls`, + `/telephony_transfer_targets`) are defined in the TypeSpec/SDK but not yet deployed to + the live test resource: every call returns an empty-body 404 (a routing-layer "no such + route" response from the service mesh, not an application-level not-found error - + confirmed by comparing against a known-working route's fully-populated JSON error body). + Un-skip `test_telephony_bindings_and_transfer_targets`/`test_telephony_calls_not_found` + once the service deploys these routes. + - `beta.voice_agents.conversations.get_generated_audio_item*` with a + made-up conversation/item ID hits the service's conversation-ID format validator and + returns an unhandled `500 server_error` instead of a clean `404` - the exact same + pre-existing behavior as the already-documented `beta.voice_agents.conversations` + limitation below. Testing the success path needs a live realtime session whose playback + was interrupted; testing the not-found path needs a validly-formatted but nonexistent ID + (the format isn't publicly documented). `test_generated_audio_not_found` is left in as a + placeholder and currently skipped. + + Further NOTE: the following are intentionally NOT covered here at all since they require real + infrastructure this test environment does not have: + - `voice_agents.telephony.create_binding` with a real Teams Phone Extension or Twilio provider account + (needs real provider credentials/connections). Its request/response wiring is still + exercised indirectly through the header-injection unit tests in + `tests/foundry_features_header/`. + - `list_calls`/`get_call`/`transfer_call`/`end_call` + against an actual in-progress or historical call (needs a real inbound telephony call). + - Reading back a conversation (`project_client.beta.voice_agents.conversations.*`) using a + `conversation_id` produced by a live realtime WebSocket session - the service's REST + conversation-ID validator rejects the ID format generated by the realtime WS subsystem. + This is also not practical to cover with HTTP-only recorded tests since it requires an + actual WebSocket session. + Once these are fixed/deployed service-side, tests can be added/enabled for them. + """ + + def _make_definition(self, model: str) -> VoiceAgentDefinition: + return VoiceAgentDefinition( + model_type="managed", + model=model, + instructions="You are a helpful voice assistant.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ) + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony.py::TestVoiceAgentTelephony::test_telephony_bindings_and_transfer_targets -s + @pytest.mark.skip( + reason="Telephony routes are defined in the TypeSpec/SDK but not yet deployed on the live " + "test service (empty-body 404s at the routing layer). Un-skip once the service deploys them." + ) + @servicePreparer() + @recorded_by_proxy() + def test_telephony_bindings_and_transfer_targets(self, **kwargs): + """ + Test telephony bindings (list/get/update/delete against a nonexistent binding) and a + round-trip of the telephony transfer targets configured for a voice agent. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------+----------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/telephony_bindings project_client.beta.voice_agents.telephony.list_bindings() + GET /agents/{agent_name}/telephony_transfer_targets project_client.beta.voice_agents.telephony.get_transfer_targets() + PUT /agents/{agent_name}/telephony_transfer_targets project_client.beta.voice_agents.telephony.replace_transfer_targets() + GET /agents/{agent_name}/telephony_bindings/{binding_id} project_client.beta.voice_agents.telephony.get_binding() + PATCH /agents/{agent_name}/telephony_bindings/{binding_id} project_client.beta.voice_agents.telephony.update_binding() + DELETE /agents/{agent_name}/telephony_bindings/{binding_id} project_client.beta.voice_agents.telephony.delete_binding() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + # Voice-agent operations require the preview opt-in. + project_client = self.create_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentTelephonyBindingsTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # A freshly created agent has no telephony bindings. + bindings = list(project_client.beta.voice_agents.telephony.list_bindings(agent_name=agent_name)) + assert len(bindings) == 0 + + # A freshly created agent has no telephony transfer targets configured. + targets: TelephonyTransferTargets = project_client.beta.voice_agents.telephony.get_transfer_targets( + agent_name=agent_name + ) + assert targets is not None + assert len(targets.transfer_targets) == 0 + + # Configure one PSTN transfer target. + new_target = TelephonyTransferTarget( + name="sales_desk", + description="Transfers to the sales desk for pricing questions.", + destination=PSTNTelephonyTransferDestination(value="+14255550123"), + ) + replaced_targets: TelephonyTransferTargets = ( + project_client.beta.voice_agents.telephony.replace_transfer_targets( + agent_name=agent_name, + transfer_targets=[new_target], + etag=None, + match_condition=MatchConditions.IfPresent, + ) + ) + assert len(replaced_targets.transfer_targets) == 1 + assert replaced_targets.transfer_targets[0].name == "sales_desk" + assert replaced_targets.transfer_targets[0].destination.kind == "pstn" + + # Confirm the change persisted. + confirmed_targets: TelephonyTransferTargets = project_client.beta.voice_agents.telephony.get_transfer_targets( + agent_name=agent_name + ) + assert len(confirmed_targets.transfer_targets) == 1 + assert confirmed_targets.transfer_targets[0].name == "sales_desk" + + # Clear the transfer targets (empty array clears all targets). + cleared_targets: TelephonyTransferTargets = project_client.beta.voice_agents.telephony.replace_transfer_targets( + agent_name=agent_name, + transfer_targets=[], + etag=None, + match_condition=MatchConditions.IfPresent, + ) + assert len(cleared_targets.transfer_targets) == 0 + + # A nonexistent telephony binding returns 404 on get/update/delete. + fake_binding_id = "twilio:+10000000000" + with pytest.raises(ResourceNotFoundError): + project_client.beta.voice_agents.telephony.get_binding(agent_name=agent_name, binding_id=fake_binding_id) + with pytest.raises(ResourceNotFoundError): + project_client.beta.voice_agents.telephony.update_binding( + agent_name=agent_name, + binding_id=fake_binding_id, + body=UpdateTelephonyBindingRequest(status=TelephonyBindingStatus.SUSPENDED), + etag=None, + match_condition=MatchConditions.IfPresent, + ) + with pytest.raises(ResourceNotFoundError): + project_client.beta.voice_agents.telephony.delete_binding( + agent_name=agent_name, + binding_id=fake_binding_id, + etag=None, + match_condition=MatchConditions.IfPresent, + ) + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony.py::TestVoiceAgentTelephony::test_telephony_calls_not_found -s + @pytest.mark.skip( + reason="Telephony routes are defined in the TypeSpec/SDK but not yet deployed on the live " + "test service (empty-body 404s at the routing layer). Un-skip once the service deploys them." + ) + @servicePreparer() + @recorded_by_proxy() + def test_telephony_calls_not_found(self, **kwargs): + """ + Test telephony calls: listing (empty on a fresh agent) and get/transfer/end against a + nonexistent call, which return 404. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------+----------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/telephony_calls project_client.beta.voice_agents.telephony.list_calls() + GET /agents/{agent_name}/telephony_calls/{call_id} project_client.beta.voice_agents.telephony.get_call() + POST /agents/{agent_name}/telephony_calls/{call_id}:transfer project_client.beta.voice_agents.telephony.transfer_call() + POST /agents/{agent_name}/telephony_calls/{call_id}:end project_client.beta.voice_agents.telephony.end_call() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentTelephonyCallsTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # A freshly created agent has no telephony call history. + calls = list(project_client.beta.voice_agents.telephony.list_calls(agent_name=agent_name)) + assert len(calls) == 0 + + fake_call_id = "nonexistent-call-id" + with pytest.raises(ResourceNotFoundError): + project_client.beta.voice_agents.telephony.get_call(agent_name=agent_name, call_id=fake_call_id) + with pytest.raises(HttpResponseError) as transfer_exc_info: + project_client.beta.voice_agents.telephony.transfer_call( + agent_name=agent_name, call_id=fake_call_id, target="nonexistent-target" + ) + assert transfer_exc_info.value.status_code == 404 + with pytest.raises(HttpResponseError) as end_exc_info: + project_client.beta.voice_agents.telephony.end_call(agent_name=agent_name, call_id=fake_call_id) + assert end_exc_info.value.status_code == 404 + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony.py::TestVoiceAgentTelephony::test_generated_audio_not_found -s + @pytest.mark.skip( + reason="A made-up conversation/item ID hits the service's conversation-ID format validator " + "and returns an unhandled 500 instead of a clean 404 (same pre-existing behavior as " + "beta.voice_agents.conversations). Needs a validly-formatted but nonexistent ID, or a real " + "realtime session, to test properly." + ) + @servicePreparer() + @recorded_by_proxy() + def test_generated_audio_not_found(self, **kwargs): + """ + Test the `beta.voice_agents.conversations.get_generated_audio_item`/ + `download_generated_audio_item` methods against a nonexistent + conversation item, which return 404. + + Routes used in this test: + + Action REST API Route Client Method + ------+-----------------------------------------------------------------------------------------+----------------------------------------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated project_client.beta.voice_agents.conversations.get_generated_audio_item() + GET /agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated/content project_client.beta.voice_agents.conversations.download_generated_audio_item() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentGeneratedAudioTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + fake_conversation_id = "nonexistent-conversation-id" + fake_item_id = "nonexistent-item-id" + with pytest.raises(ResourceNotFoundError): + project_client.beta.voice_agents.conversations.get_generated_audio_item( + agent_name=agent_name, conversation_id=fake_conversation_id, item_id=fake_item_id + ) + with pytest.raises(HttpResponseError) as content_exc_info: + list( + project_client.beta.voice_agents.conversations.download_generated_audio_item( + agent_name=agent_name, conversation_id=fake_conversation_id, item_id=fake_item_id + ) + ) + assert content_exc_info.value.status_code == 404 + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_async.py new file mode 100644 index 000000000000..80652b970c67 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_async.py @@ -0,0 +1,317 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +from test_base import TestBase, servicePreparer +from devtools_testutils.aio import recorded_by_proxy_async +import pytest +from azure.core import MatchConditions +from azure.core.exceptions import HttpResponseError, ResourceNotFoundError +from azure.ai.projects.models import ( + AgentVersionDetails, + PSTNTelephonyTransferDestination, + TelephonyBindingStatus, + TelephonyTransferTarget, + TelephonyTransferTargets, + UpdateTelephonyBindingRequest, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceOutputModality, +) + + +class TestVoiceAgentTelephonyAsync(TestBase): + """ + Recorded tests covering the voice-agent telephony REST API surface exposed through + `project_client.agents.*` (telephony bindings, calls, and transfer targets), and the + top-level `project_client.beta.voice_agents.conversations.*` generated-audio reads. + + NOTE: All tests in this file are currently marked `skip`: + - The telephony routes (`/agents/{agent_name}/telephony_bindings`, `/telephony_calls`, + `/telephony_transfer_targets`) are defined in the TypeSpec/SDK but not yet deployed to + the live test resource: every call returns an empty-body 404 (a routing-layer "no such + route" response from the service mesh, not an application-level not-found error - + confirmed by comparing against a known-working route's fully-populated JSON error body). + Un-skip `test_telephony_bindings_and_transfer_targets`/`test_telephony_calls_not_found` + once the service deploys these routes. + - `beta.voice_agents.conversations.get_generated_audio_item*` with a + made-up conversation/item ID hits the service's conversation-ID format validator and + returns an unhandled `500 server_error` instead of a clean `404` - the exact same + pre-existing behavior as the already-documented `beta.voice_agents.conversations` + limitation below. Testing the success path needs a live realtime session whose playback + was interrupted; testing the not-found path needs a validly-formatted but nonexistent ID + (the format isn't publicly documented). `test_generated_audio_not_found` is left in as a + placeholder and currently skipped. + + Further NOTE: the following are intentionally NOT covered here at all since they require real + infrastructure this test environment does not have: + - `voice_agents.telephony.create_binding` with a real Teams Phone Extension or Twilio provider account + (needs real provider credentials/connections). Its request/response wiring is still + exercised indirectly through the header-injection unit tests in + `tests/foundry_features_header/`. + - `list_calls`/`get_call`/`transfer_call`/`end_call` + against an actual in-progress or historical call (needs a real inbound telephony call). + - Reading back a conversation (`project_client.beta.voice_agents.conversations.*`) using a + `conversation_id` produced by a live realtime WebSocket session - the service's REST + conversation-ID validator rejects the ID format generated by the realtime WS subsystem. + This is also not practical to cover with HTTP-only recorded tests since it requires an + actual WebSocket session. + Once these are fixed/deployed service-side, tests can be added/enabled for them. + """ + + def _make_definition(self, model: str) -> VoiceAgentDefinition: + return VoiceAgentDefinition( + model_type="managed", + model=model, + instructions="You are a helpful voice assistant.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ) + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony_async.py::TestVoiceAgentTelephonyAsync::test_telephony_bindings_and_transfer_targets -s + @pytest.mark.skip( + reason="Telephony routes are defined in the TypeSpec/SDK but not yet deployed on the live " + "test service (empty-body 404s at the routing layer). Un-skip once the service deploys them." + ) + @servicePreparer() + @recorded_by_proxy_async() + async def test_telephony_bindings_and_transfer_targets(self, **kwargs): + """ + Test telephony bindings (list/get/update/delete against a nonexistent binding) and a + round-trip of the telephony transfer targets configured for a voice agent. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------+----------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/telephony_bindings project_client.beta.voice_agents.telephony.list_bindings() + GET /agents/{agent_name}/telephony_transfer_targets project_client.beta.voice_agents.telephony.get_transfer_targets() + PUT /agents/{agent_name}/telephony_transfer_targets project_client.beta.voice_agents.telephony.replace_transfer_targets() + GET /agents/{agent_name}/telephony_bindings/{binding_id} project_client.beta.voice_agents.telephony.get_binding() + PATCH /agents/{agent_name}/telephony_bindings/{binding_id} project_client.beta.voice_agents.telephony.update_binding() + DELETE /agents/{agent_name}/telephony_bindings/{binding_id} project_client.beta.voice_agents.telephony.delete_binding() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + # Voice-agent operations require the preview opt-in. + project_client = self.create_async_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentTelephonyBindingsTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + await project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # A freshly created agent has no telephony bindings. + bindings = [b async for b in project_client.beta.voice_agents.telephony.list_bindings(agent_name=agent_name)] + assert len(bindings) == 0 + + # A freshly created agent has no telephony transfer targets configured. + targets: TelephonyTransferTargets = await project_client.beta.voice_agents.telephony.get_transfer_targets( + agent_name=agent_name + ) + assert targets is not None + assert len(targets.transfer_targets) == 0 + + # Configure one PSTN transfer target. + new_target = TelephonyTransferTarget( + name="sales_desk", + description="Transfers to the sales desk for pricing questions.", + destination=PSTNTelephonyTransferDestination(value="+14255550123"), + ) + replaced_targets: TelephonyTransferTargets = ( + await project_client.beta.voice_agents.telephony.replace_transfer_targets( + agent_name=agent_name, + transfer_targets=[new_target], + etag=None, + match_condition=MatchConditions.IfPresent, + ) + ) + assert len(replaced_targets.transfer_targets) == 1 + assert replaced_targets.transfer_targets[0].name == "sales_desk" + assert replaced_targets.transfer_targets[0].destination.kind == "pstn" + + # Confirm the change persisted. + confirmed_targets: TelephonyTransferTargets = ( + await project_client.beta.voice_agents.telephony.get_transfer_targets(agent_name=agent_name) + ) + assert len(confirmed_targets.transfer_targets) == 1 + assert confirmed_targets.transfer_targets[0].name == "sales_desk" + + # Clear the transfer targets (empty array clears all targets). + cleared_targets: TelephonyTransferTargets = ( + await project_client.beta.voice_agents.telephony.replace_transfer_targets( + agent_name=agent_name, + transfer_targets=[], + etag=None, + match_condition=MatchConditions.IfPresent, + ) + ) + assert len(cleared_targets.transfer_targets) == 0 + + # A nonexistent telephony binding returns 404 on get/update/delete. + fake_binding_id = "twilio:+10000000000" + with pytest.raises(ResourceNotFoundError): + await project_client.beta.voice_agents.telephony.get_binding( + agent_name=agent_name, binding_id=fake_binding_id + ) + with pytest.raises(ResourceNotFoundError): + await project_client.beta.voice_agents.telephony.update_binding( + agent_name=agent_name, + binding_id=fake_binding_id, + body=UpdateTelephonyBindingRequest(status=TelephonyBindingStatus.SUSPENDED), + etag=None, + match_condition=MatchConditions.IfPresent, + ) + with pytest.raises(ResourceNotFoundError): + await project_client.beta.voice_agents.telephony.delete_binding( + agent_name=agent_name, + binding_id=fake_binding_id, + etag=None, + match_condition=MatchConditions.IfPresent, + ) + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony_async.py::TestVoiceAgentTelephonyAsync::test_telephony_calls_not_found -s + @pytest.mark.skip( + reason="Telephony routes are defined in the TypeSpec/SDK but not yet deployed on the live " + "test service (empty-body 404s at the routing layer). Un-skip once the service deploys them." + ) + @servicePreparer() + @recorded_by_proxy_async() + async def test_telephony_calls_not_found(self, **kwargs): + """ + Test telephony calls: listing (empty on a fresh agent) and get/transfer/end against a + nonexistent call, which return 404. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------+----------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/telephony_calls project_client.beta.voice_agents.telephony.list_calls() + GET /agents/{agent_name}/telephony_calls/{call_id} project_client.beta.voice_agents.telephony.get_call() + POST /agents/{agent_name}/telephony_calls/{call_id}:transfer project_client.beta.voice_agents.telephony.transfer_call() + POST /agents/{agent_name}/telephony_calls/{call_id}:end project_client.beta.voice_agents.telephony.end_call() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentTelephonyCallsTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + await project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + # A freshly created agent has no telephony call history. + calls = [c async for c in project_client.beta.voice_agents.telephony.list_calls(agent_name=agent_name)] + assert len(calls) == 0 + + fake_call_id = "nonexistent-call-id" + with pytest.raises(ResourceNotFoundError): + await project_client.beta.voice_agents.telephony.get_call(agent_name=agent_name, call_id=fake_call_id) + with pytest.raises(HttpResponseError) as transfer_exc_info: + await project_client.beta.voice_agents.telephony.transfer_call( + agent_name=agent_name, call_id=fake_call_id, target="nonexistent-target" + ) + assert transfer_exc_info.value.status_code == 404 + with pytest.raises(HttpResponseError) as end_exc_info: + await project_client.beta.voice_agents.telephony.end_call(agent_name=agent_name, call_id=fake_call_id) + assert end_exc_info.value.status_code == 404 + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony_async.py::TestVoiceAgentTelephonyAsync::test_generated_audio_not_found -s + @pytest.mark.skip( + reason="A made-up conversation/item ID hits the service's conversation-ID format validator " + "and returns an unhandled 500 instead of a clean 404 (same pre-existing behavior as " + "beta.voice_agents.conversations). Needs a validly-formatted but nonexistent ID, or a real " + "realtime session, to test properly." + ) + @servicePreparer() + @recorded_by_proxy_async() + async def test_generated_audio_not_found(self, **kwargs): + """ + Test the `beta.voice_agents.conversations.get_generated_audio_item`/ + `download_generated_audio_item` methods against a nonexistent + conversation item, which return 404. + + Routes used in this test: + + Action REST API Route Client Method + ------+-----------------------------------------------------------------------------------------+----------------------------------------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated project_client.beta.voice_agents.conversations.get_generated_audio_item() + GET /agents/{agent_name}/endpoint/protocols/voice/conversations/{conversation_id}/items/{item_id}/audio/generated/content project_client.beta.voice_agents.conversations.download_generated_audio_item() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + project_client = self.create_async_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentGeneratedAudioTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + await project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + fake_conversation_id = "nonexistent-conversation-id" + fake_item_id = "nonexistent-item-id" + with pytest.raises(ResourceNotFoundError): + await project_client.beta.voice_agents.conversations.get_generated_audio_item( + agent_name=agent_name, conversation_id=fake_conversation_id, item_id=fake_item_id + ) + with pytest.raises(HttpResponseError) as content_exc_info: + [ + chunk + async for chunk in await project_client.beta.voice_agents.conversations.download_generated_audio_item( + agent_name=agent_name, conversation_id=fake_conversation_id, item_id=fake_item_id + ) + ] + assert content_exc_info.value.status_code == 404 + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_call_job.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_call_job.py new file mode 100644 index 000000000000..b9c17454edb8 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_call_job.py @@ -0,0 +1,122 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +from test_base import TestBase, servicePreparer +from devtools_testutils import recorded_by_proxy +import pytest +from azure.core.exceptions import ResourceNotFoundError +from azure.ai.projects.models import ( + AgentVersionDetails, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceOutputModality, +) + + +class TestVoiceAgentTelephonyCallJob(TestBase): + """ + Recorded tests covering the outbound telephony call-job REST API surface exposed through the + top-level `project_client.beta.voice_agents.telephony.*` operation group (added in the + "batch 2" Voice Agents TypeSpec, distinct from the existing `project_client.agents.*` + telephony binding/call methods). + + NOTE: All tests in this file are currently marked `skip`: + - Probing this environment's live Voice Agents test resource with + `voice_agents.telephony.get_call_job` (api-version "v1", the SDK's only known + version) returns `400 UnsupportedApiVersion` with a message identifying the resolved + route (".../agents/{agent_name}/telephony/call_jobs/{call_job_id}") but rejecting + "v1" for it - unlike the routing-layer empty-body 404s seen for the batch-1 + `agents.*` telephony bindings/calls routes (see `test_voice_agent_telephony.py`), this + route *is* registered, but the call-job feature isn't yet enabled for the API + version this SDK targets. Un-skip once the live test service accepts "v1" for these + routes. + + Further NOTE: `create_call_job` is intentionally NOT covered here at all since it requires + real infrastructure this test environment does not have: a real, working `connection_name` + pointing at a provisioned Teams Phone/Twilio Foundry connection -- outbound calls originate + directly from the connection, so no pre-existing telephony binding is required (same + real-provider limitation documented for `create_binding` in `test_voice_agent_telephony.py`). + Once these are fixed/deployed service-side and real provider credentials are available, tests + can be added/enabled for it. + + The `voice_agents.telephony` campaign operation group (`create_campaign`, + `begin_import_campaign_recipients`, `begin_validate_campaign`, `begin_publish_campaign`, + `pause_campaign`/`resume_campaign`/`cancel_campaign`, `get_operation`, and their models) was + removed from the TypeSpec/generated SDK surface; this file no longer covers it. + """ + + def _make_definition(self, model: str) -> VoiceAgentDefinition: + return VoiceAgentDefinition( + model_type="managed", + model=model, + instructions="You are a helpful voice assistant.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ) + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony_call_job.py::TestVoiceAgentTelephonyCallJob::test_telephony_call_job_not_found -s + @pytest.mark.skip( + reason="voice_agents.telephony routes are registered but return 400 UnsupportedApiVersion for " + "api-version 'v1' on the live test service. Un-skip once the service supports 'v1' for " + "this operation group." + ) + @servicePreparer() + @recorded_by_proxy() + def test_telephony_call_job_not_found(self, **kwargs): + """ + Test outbound telephony call jobs: get/cancel against a nonexistent call job, which + return 404. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------+----------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/telephony/call_jobs/{call_job_id} project_client.beta.voice_agents.telephony.get_call_job() + POST /agents/{agent_name}/telephony/call_jobs/{call_job_id}:cancel project_client.beta.voice_agents.telephony.cancel_call_job() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + # Voice-agent operations require the preview opt-in. + project_client = self.create_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentTelephonyCallJobTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + fake_call_job_id = "nonexistent-call-job-id" + with pytest.raises(ResourceNotFoundError): + project_client.beta.voice_agents.telephony.get_call_job(agent_name=agent_name, call_job_id=fake_call_job_id) + with pytest.raises(ResourceNotFoundError): + # cancel_call_job's "etag" is a numeric call-job revision, not an opaque ETag - the + # service rejects an "If-Match: *" unconditional match for this endpoint, so a + # well-formed (if make-believe) revision is passed here instead, using the default + # match_condition (MatchConditions.IfNotModified). + project_client.beta.voice_agents.telephony.cancel_call_job( + agent_name=agent_name, + call_job_id=fake_call_job_id, + etag="0", + ) + + # Delete the voice agent. + result = project_client.agents.delete(agent_name=agent_name) + assert result.deleted diff --git a/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_call_job_async.py b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_call_job_async.py new file mode 100644 index 000000000000..f3c84a8f36a7 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/agents/test_voice_agent_telephony_call_job_async.py @@ -0,0 +1,124 @@ +# pylint: disable=too-many-lines,line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +# cSpell:disable + +from test_base import TestBase, servicePreparer +from devtools_testutils.aio import recorded_by_proxy_async +import pytest +from azure.core.exceptions import ResourceNotFoundError +from azure.ai.projects.models import ( + AgentVersionDetails, + VoiceAgentAudioConfig, + VoiceAgentAudioOutputConfig, + VoiceAgentDefinition, + VoiceOutputModality, +) + + +class TestVoiceAgentTelephonyCallJobAsync(TestBase): + """ + Recorded tests covering the outbound telephony call-job REST API surface exposed through the + top-level `project_client.beta.voice_agents.telephony.*` operation group (added in the + "batch 2" Voice Agents TypeSpec, distinct from the existing `project_client.agents.*` + telephony binding/call methods). + + NOTE: All tests in this file are currently marked `skip`: + - Probing this environment's live Voice Agents test resource with + `voice_agents.telephony.get_call_job` (api-version "v1", the SDK's only known + version) returns `400 UnsupportedApiVersion` with a message identifying the resolved + route (".../agents/{agent_name}/telephony/call_jobs/{call_job_id}") but rejecting + "v1" for it - unlike the routing-layer empty-body 404s seen for the batch-1 + `agents.*` telephony bindings/calls routes (see `test_voice_agent_telephony_async.py`), + this route *is* registered, but the call-job feature isn't yet enabled for the API + version this SDK targets. Un-skip once the live test service accepts "v1" for these + routes. + + Further NOTE: `create_call_job` is intentionally NOT covered here at all since it requires + real infrastructure this test environment does not have: a real, working `connection_name` + pointing at a provisioned Teams Phone/Twilio Foundry connection -- outbound calls originate + directly from the connection, so no pre-existing telephony binding is required (same + real-provider limitation documented for `create_binding` in `test_voice_agent_telephony_async.py`). + Once these are fixed/deployed service-side and real provider credentials are available, tests + can be added/enabled for it. + + The `voice_agents.telephony` campaign operation group (`create_campaign`, + `begin_import_campaign_recipients`, `begin_validate_campaign`, `begin_publish_campaign`, + `pause_campaign`/`resume_campaign`/`cancel_campaign`, `get_operation`, and their models) was + removed from the TypeSpec/generated SDK surface; this file no longer covers it. + """ + + def _make_definition(self, model: str) -> VoiceAgentDefinition: + return VoiceAgentDefinition( + model_type="managed", + model=model, + instructions="You are a helpful voice assistant.", + audio=VoiceAgentAudioConfig( + output=VoiceAgentAudioOutputConfig(voice="en-US-AvaNeural", voice_type="azure-standard") + ), + output_modalities=[VoiceOutputModality.AUDIO], + ) + + # To run only this test: + # pytest tests\agents\test_voice_agent_telephony_call_job_async.py::TestVoiceAgentTelephonyCallJobAsync::test_telephony_call_job_not_found -s + @pytest.mark.skip( + reason="voice_agents.telephony routes are registered but return 400 UnsupportedApiVersion for " + "api-version 'v1' on the live test service. Un-skip once the service supports 'v1' for " + "this operation group." + ) + @servicePreparer() + @recorded_by_proxy_async() + async def test_telephony_call_job_not_found(self, **kwargs): + """ + Test outbound telephony call jobs: get/cancel against a nonexistent call job, which + return 404. + + Routes used in this test: + + Action REST API Route Client Method + ------+-------------------------------------------------------------+----------------------------------------------- + POST /agents/{agent_name}/versions project_client.agents.create_version() + GET /agents/{agent_name}/telephony/call_jobs/{call_job_id} project_client.beta.voice_agents.telephony.get_call_job() + POST /agents/{agent_name}/telephony/call_jobs/{call_job_id}:cancel project_client.beta.voice_agents.telephony.cancel_call_job() + DELETE /agents/{agent_name} project_client.agents.delete() + """ + print("\n") + model = kwargs.get("foundry_voice_model_name") + assert model is not None + # Voice-agent operations require the preview opt-in. + project_client = self.create_async_client(allow_preview=True, **kwargs) + agent_name = "VoiceAgentTelephonyCallJobTest" + + # Delete any existing agent from previous test runs (ignore failures) + try: + await project_client.agents.delete(agent_name=agent_name) + except Exception: # pylint: disable=broad-except + pass + + agent_version: AgentVersionDetails = await project_client.agents.create_version( + agent_name=agent_name, + definition=self._make_definition(model), + ) + self._validate_agent_version(agent_version, expected_name=agent_name) + + fake_call_job_id = "nonexistent-call-job-id" + with pytest.raises(ResourceNotFoundError): + await project_client.beta.voice_agents.telephony.get_call_job( + agent_name=agent_name, call_job_id=fake_call_job_id + ) + with pytest.raises(ResourceNotFoundError): + # cancel_call_job's "etag" is a numeric call-job revision, not an opaque ETag - the + # service rejects an "If-Match: *" unconditional match for this endpoint, so a + # well-formed (if make-believe) revision is passed here instead, using the default + # match_condition (MatchConditions.IfNotModified). + await project_client.beta.voice_agents.telephony.cancel_call_job( + agent_name=agent_name, + call_job_id=fake_call_job_id, + etag="0", + ) + + # Delete the voice agent. + result = await project_client.agents.delete(agent_name=agent_name) + assert result.deleted diff --git a/sdk/ai/azure-ai-projects/tests/conftest.py b/sdk/ai/azure-ai-projects/tests/conftest.py index 20f6677e83b6..d3eaf64184e4 100644 --- a/sdk/ai/azure-ai-projects/tests/conftest.py +++ b/sdk/ai/azure-ai-projects/tests/conftest.py @@ -373,6 +373,30 @@ def sanitize_url_paths(): # would otherwise fail to decode -> UnicodeDecodeError). add_remove_header_sanitizer(headers="Content-Encoding") + # Strip Foundry-Features from record/playback matching. Its value is a comma-joined list of + # preview opt-in flags that legitimately changes over time as new preview features are added + # (e.g. VoiceAgents=V1Preview was added later); exact-matching it against older cassettes + # would otherwise cause spurious playback failures unrelated to what a given test is actually + # validating. Some affected cassettes (test_ai_agents_instrumentor.py/_async.py) have been + # re-recorded and no longer need this, but others still rely on it pending re-recording (see + # test_responses_instrumentor_workflow.py, which currently fails to re-record live due to an + # unrelated pre-existing gap in its expected span-attribute list vs. actual gen_ai.usage.* + # token attributes now returned by the service). Tests that specifically need to assert on + # this header's value use a dedicated unit-test suite (tests/foundry_features_header) with a + # capturing transport instead of the test-proxy, so this does not reduce coverage of the + # header-injection behavior itself. + add_remove_header_sanitizer(headers="Foundry-Features") + + # Strip Accept from record/playback matching. It's a content-negotiation hint set by the + # HTTP client/transport layer, not something the tests are validating, and its value has been + # observed to drift across environments independent of any SDK code change here (e.g. the + # azure-storage-blob generated client hardcodes "application/xml" for blob uploads, but some + # environments send "*/*" instead depending on transport/dependency versions). Exact-matching + # it would otherwise cause spurious playback failures on samples like + # sample_models_create_and_poll.py and sample_datasets*.py that upload blobs via + # container_client.upload_blob(), unrelated to what those samples actually validate. + add_remove_header_sanitizer(headers="Accept") + # Remove the following sanitizers since certain fields are needed in tests and are non-sensitive: # - AZSDK3493: $..name # - AZSDK3430: $..id diff --git a/sdk/ai/azure-ai-projects/tests/foundry_features_header/foundry_features_header_test_base.py b/sdk/ai/azure-ai-projects/tests/foundry_features_header/foundry_features_header_test_base.py index 0cb5faeb0fd4..ffe43ce1167f 100644 --- a/sdk/ai/azure-ai-projects/tests/foundry_features_header/foundry_features_header_test_base.py +++ b/sdk/ai/azure-ai-projects/tests/foundry_features_header/foundry_features_header_test_base.py @@ -45,8 +45,9 @@ "routines": "Routines=V2Preview", "schedules": "Schedules=V1Preview", "skills": "Skills=V1Preview", + "voice_agents": "VoiceAgents=V1Preview", "datasets": "DataGenerationJobs=V1Preview", - "agents": "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + "agents": "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,DraftAgents=V1Preview,VoiceAgents=V1Preview,DigitalWorker=V1Preview,GitHubCopilot=V1Preview,Skills=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", } # Methods on .beta sub-clients that are NOT simple one-HTTP-call wrappers and @@ -72,6 +73,18 @@ ), # multi-step helper: validate -> pending_upload -> azcopy -> pending_create_version -> poll get } +# Public `.beta` attributes that are NOT generated REST operations classes and therefore +# cannot be exercised by the generic header-injection test at all (unlike EXCLUDED_BETA_METHODS, +# which excludes specific methods on an otherwise-testable sub-client). +# +# `realtime` is a hand-written WebSocket entry point (azure/ai/projects/_realtime.py): +# `BetaRealtime.connect(...)` synchronously builds and returns a BetaRealtimeConnectionManager without +# performing any I/O -- the actual WebSocket handshake (which carries its own dedicated +# Foundry-Features header) only happens later, on `__enter__`/`__aenter__`. So it never triggers +# CapturingTransport, and doesn't have an EXPECTED_FOUNDRY_FEATURES entry. Its header behavior is +# verified independently in test_realtime_client.py / test_realtime_client_async.py. +NON_OPERATION_BETA_ATTRIBUTES: frozenset = frozenset({"realtime"}) + # Shared test cases for non-beta methods that optionally send the Foundry-Features header. # Used by both test_foundry_features_header_optional.py (sync) and # test_foundry_features_header_optional_async.py (async). @@ -84,7 +97,7 @@ # The test id is derived automatically from method_name. pytest.param( "agents.create_version", - "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,DraftAgents=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", + "WorkflowAgents=V1Preview,ExternalAgents=V1Preview,DraftAgents=V1Preview,VoiceAgents=V1Preview,DigitalWorker=V1Preview,GitHubCopilot=V1Preview,Skills=V1Preview,AgentsOptimization=V2Preview,ModelRouterControls=V1Preview", ), pytest.param( "evaluation_rules.create_or_update", diff --git a/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_agent_telephony_protocol.py b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_agent_telephony_protocol.py new file mode 100644 index 000000000000..c3f6dada1fcf --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_agent_telephony_protocol.py @@ -0,0 +1,105 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Mocked protocol-level tests for the `voice_agents.telephony` (batch 2) call-job +operation group, covering request construction (HTTP method + URL path) without depending on the +live test service's currently-unavailable API-version support for these routes (see +`tests/agents/test_voice_agent_telephony_call_job.py`, whose recorded tests are all skipped for +that reason). + +Uses the same request-capturing-transport technique as +`tests/foundry_features_header/test_foundry_features_header_on_ga_operations.py`: a transport +that raises as soon as a request is about to be sent, so the generated request builder's URL/method +construction is exercised end-to-end (through the real client, real serialization, and the real +pipeline) without any network I/O or a live/recorded backend. +""" + +from typing import Any, Iterator, List, Tuple + +import pytest +from azure.core.pipeline.transport import HttpTransport +from azure.ai.projects import AIProjectClient + +from foundry_features_header_test_base import ( + FAKE_ENDPOINT, + FakeCredential, + FoundryFeaturesHeaderTestBase, + _RequestCaptured, +) + + +class CapturingTransport(HttpTransport): + """Sync transport that captures the outgoing request and raises _RequestCaptured.""" + + def send(self, request: Any, **kwargs: Any) -> Any: # type: ignore[override] + raise _RequestCaptured(request) + + def open(self) -> None: + pass + + def close(self) -> None: + pass + + def __enter__(self) -> "CapturingTransport": + return self + + def __exit__(self, *args: Any) -> None: + pass + + +@pytest.fixture(scope="module") +def client() -> Iterator[AIProjectClient]: + with AIProjectClient( + endpoint=FAKE_ENDPOINT, + credential=FakeCredential(), # type: ignore[arg-type] + allow_preview=True, + transport=CapturingTransport(), + ) as c: + yield c + + +# (method_name, expected HTTP method, expected static URL path -- fake string/required params are +# always rendered as the literal "fake-value" by FoundryFeaturesHeaderTestBase._fake_for_param). +_TELEPHONY_PROTOCOL_CASES: List[Tuple[str, str, str]] = [ + ("create_call_job", "POST", "/agents/fake-value/telephony/call_jobs"), + ("get_call_job", "GET", "/agents/fake-value/telephony/call_jobs/fake-value"), + ("cancel_call_job", "POST", "/agents/fake-value/telephony/call_jobs/fake-value:cancel"), +] + + +class TestAgentTelephonyProtocol(FoundryFeaturesHeaderTestBase): + """Verify each `voice_agents.telephony` method builds the correct HTTP method and URL path.""" + + @staticmethod + def _capture(call: Any) -> Any: + """Call *call()* and return the captured HttpRequest.""" + try: + result = call() + except _RequestCaptured as exc: + return exc.request + + try: + next(iter(result)) + except _RequestCaptured as exc: + return exc.request + except StopIteration: + raise AssertionError("Iterator exhausted without the transport being called") from None + + raise AssertionError("Transport was never called") + + @pytest.mark.parametrize("method_name,expected_http_method,expected_path", _TELEPHONY_PROTOCOL_CASES) + def test_agent_telephony_request_protocol( + self, + client: AIProjectClient, + method_name: str, + expected_http_method: str, + expected_path: str, + ) -> None: + method = getattr(client.beta.voice_agents.telephony, method_name) + request = self._capture(self._make_fake_call(method)) + assert ( + request.method == expected_http_method + ), f"{method_name}: expected HTTP method {expected_http_method!r}, got {request.method!r}" + assert expected_path in request.url, f"{method_name}: expected path {expected_path!r} in URL {request.url!r}" diff --git a/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_agent_telephony_protocol_async.py b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_agent_telephony_protocol_async.py new file mode 100644 index 000000000000..3dfd987b8b78 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_agent_telephony_protocol_async.py @@ -0,0 +1,101 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Async counterpart of test_agent_telephony_protocol.py -- see that module's docstring.""" + +import inspect +from typing import Any, Iterator, List, Tuple + +import pytest +from azure.core.pipeline.transport import AsyncHttpTransport +from azure.ai.projects.aio import AIProjectClient as AsyncAIProjectClient + +from foundry_features_header_test_base import ( + FAKE_ENDPOINT, + AsyncFakeCredential, + FoundryFeaturesHeaderTestBase, + _RequestCaptured, +) + +pytestmark = pytest.mark.asyncio + + +class CapturingAsyncTransport(AsyncHttpTransport): + """Async transport that captures the outgoing request and raises _RequestCaptured.""" + + async def send(self, request: Any, **kwargs: Any) -> Any: # type: ignore[override] + raise _RequestCaptured(request) + + async def open(self) -> None: + pass + + async def close(self) -> None: + pass + + async def __aenter__(self) -> "CapturingAsyncTransport": + return self + + async def __aexit__(self, *args: Any) -> None: + pass + + +@pytest.fixture(scope="module") +def async_client() -> Iterator[AsyncAIProjectClient]: + yield AsyncAIProjectClient( + endpoint=FAKE_ENDPOINT, + credential=AsyncFakeCredential(), # type: ignore[arg-type] + allow_preview=True, + transport=CapturingAsyncTransport(), + ) + + +# (method_name, expected HTTP method, expected static URL path -- fake string/required params are +# always rendered as the literal "fake-value" by FoundryFeaturesHeaderTestBase._fake_for_param). +_TELEPHONY_PROTOCOL_CASES: List[Tuple[str, str, str]] = [ + ("create_call_job", "POST", "/agents/fake-value/telephony/call_jobs"), + ("get_call_job", "GET", "/agents/fake-value/telephony/call_jobs/fake-value"), + ("cancel_call_job", "POST", "/agents/fake-value/telephony/call_jobs/fake-value:cancel"), +] + + +class TestAgentTelephonyProtocolAsync(FoundryFeaturesHeaderTestBase): + """Verify each async `voice_agents.telephony` method builds the correct HTTP method and URL path.""" + + @staticmethod + async def _capture(call: Any) -> Any: + """Invoke *call()* and return the captured HttpRequest.""" + result = call() + + if inspect.isawaitable(result): + try: + await result + except _RequestCaptured as exc: + return exc.request + raise AssertionError("Transport was never called (awaitable completed without raising)") + + ai = result.__aiter__() + try: + await ai.__anext__() + except _RequestCaptured as exc: + return exc.request + except StopAsyncIteration: + raise AssertionError("Iterator exhausted without the transport being called") from None + + raise AssertionError("Transport was never called") + + @pytest.mark.parametrize("method_name,expected_http_method,expected_path", _TELEPHONY_PROTOCOL_CASES) + async def test_agent_telephony_request_protocol_async( + self, + async_client: AsyncAIProjectClient, + method_name: str, + expected_http_method: str, + expected_path: str, + ) -> None: + method = getattr(async_client.beta.voice_agents.telephony, method_name) + request = await self._capture(self._make_fake_call(method)) + assert ( + request.method == expected_http_method + ), f"{method_name}: expected HTTP method {expected_http_method!r}, got {request.method!r}" + assert expected_path in request.url, f"{method_name}: expected path {expected_path!r} in URL {request.url!r}" diff --git a/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_beta_operations.py b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_beta_operations.py index 43db5c0811f6..60fb13a95280 100644 --- a/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_beta_operations.py +++ b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_beta_operations.py @@ -42,6 +42,7 @@ EXPECTED_FOUNDRY_FEATURES, FAKE_ENDPOINT, FOUNDRY_FEATURES_HEADER, + NON_OPERATION_BETA_ATTRIBUTES, FakeCredential, FoundryFeaturesHeaderTestBase, _RequestCaptured, @@ -95,6 +96,8 @@ def _discover_test_cases() -> list[pytest.param]: for sc_name in sorted(dir(temp.beta)): if sc_name.startswith("_"): continue + if sc_name in NON_OPERATION_BETA_ATTRIBUTES: + continue sc = getattr(temp.beta, sc_name) # Sub-clients are non-callable objects (instances of operations classes). # Skip anything callable (e.g. methods directly on BetaOperations itself). @@ -222,6 +225,21 @@ def test_foundry_features_header_on_beta_operations( extra_kwargs: dict[str, Any] = {} self._assert_header(label, self._make_fake_call(method, extra_kwargs=extra_kwargs), expected_header_value) + @pytest.mark.parametrize("subclient_name", ["conversations", "telephony"]) + def test_foundry_features_header_on_voice_agent_subclients( + self, client: AIProjectClient, subclient_name: str + ) -> None: + """Assert every public nested voice-agent method sends the preview header.""" + subclient = getattr(client.beta.voice_agents, subclient_name) + operation = getattr(subclient, "_operation", subclient) + for method_name in sorted(dir(operation)): + if method_name.startswith("_"): + continue + method = getattr(subclient, method_name) + if callable(method): + label = f".beta.voice_agents.{subclient_name}.{method_name}()" + self._assert_header(label, self._make_fake_call(method), EXPECTED_FOUNDRY_FEATURES["voice_agents"]) + # --------------------------------------------------------------------------- # Pick the first discovered beta method (reuses _TEST_CASES, no extra I/O) diff --git a/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_beta_operations_async.py b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_beta_operations_async.py index afb065d6a155..ec8e8b7a8ae3 100644 --- a/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_beta_operations_async.py +++ b/sdk/ai/azure-ai-projects/tests/foundry_features_header/test_foundry_features_header_on_beta_operations_async.py @@ -44,6 +44,7 @@ EXPECTED_FOUNDRY_FEATURES, FAKE_ENDPOINT, FOUNDRY_FEATURES_HEADER, + NON_OPERATION_BETA_ATTRIBUTES, AsyncFakeCredential, FoundryFeaturesHeaderTestBase, _RequestCaptured, @@ -100,6 +101,8 @@ def _discover_async_test_cases() -> list[pytest.param]: for sc_name in sorted(dir(temp.beta)): if sc_name.startswith("_"): continue + if sc_name in NON_OPERATION_BETA_ATTRIBUTES: + continue sc = getattr(temp.beta, sc_name) # Sub-clients are non-callable objects (instances of operations classes). # Skip anything callable (e.g. methods directly on BetaOperations itself). @@ -244,6 +247,24 @@ async def test_foundry_features_header_on_beta_operations_async( label, self._make_fake_call(method, extra_kwargs=extra_kwargs), expected_header_value ) + @pytest.mark.parametrize("subclient_name", ["conversations", "telephony"]) + @pytest.mark.asyncio + async def test_foundry_features_header_on_voice_agent_subclients_async( + self, async_client: AsyncAIProjectClient, subclient_name: str + ) -> None: + """Assert every public nested voice-agent method sends the preview header.""" + subclient = getattr(async_client.beta.voice_agents, subclient_name) + operation = getattr(subclient, "_operation", subclient) + for method_name in sorted(dir(operation)): + if method_name.startswith("_"): + continue + method = getattr(subclient, method_name) + if callable(method): + label = f".beta.voice_agents.{subclient_name}.{method_name}() [async]" + await self._assert_header_async( + label, self._make_fake_call(method), EXPECTED_FOUNDRY_FEATURES["voice_agents"] + ) + # --------------------------------------------------------------------------- # Pick the first discovered beta method (reuses _ASYNC_TEST_CASES, no extra I/O) diff --git a/sdk/ai/azure-ai-projects/tests/samples/llm_instructions.py b/sdk/ai/azure-ai-projects/tests/samples/llm_instructions.py index 085f5b5f1ec6..21fe8d0b18a5 100644 --- a/sdk/ai/azure-ai-projects/tests/samples/llm_instructions.py +++ b/sdk/ai/azure-ai-projects/tests/samples/llm_instructions.py @@ -18,6 +18,25 @@ from typing import Final +default_instructions: Final[str] = """ +We just ran Python code and captured print/log output in an attached log file (TXT). +Validate whether the sample executed correctly and produced output consistent with its apparent purpose. + +Mark `correct = false` for: +- Exceptions, stack traces, explicit error/failure messages. +- Timeout/auth/connection/service errors that prevent normal completion. +- Malformed or corrupted output indicating broken processing. +- Failures that prevent the sample from completing its intended workflow. + +Intermediate progress, empty list results, and brief payloads can be valid and should not automatically fail. +HTTP 404 or resource-not-found responses are acceptable and should not be marked as failures unless they +prevent the sample from completing. + +Mark `correct = true` when execution succeeds and the output is coherent and consistent with the sample workflow. + +Always include `reason` with a concise explanation tied to the observed print output. +""".strip() + agent_tools_instructions: Final[str] = """ We just ran Python code and captured print/log output in an attached log file (TXT). Validate whether sample execution/output is correct for a tool-driven assistant workflow. @@ -256,7 +275,7 @@ def get_instructions_for_sample_path(sample_path: str) -> str: The sample path may be absolute or relative and may use either '\\' or '/'. Matching is done against the path segment under the `samples/` directory. - Raises ValueError when no explicit folder mapping is found. + Returns generic validation instructions when no explicit folder mapping is found. """ normalized = str(sample_path).replace("\\", "/") @@ -275,8 +294,4 @@ def get_instructions_for_sample_path(sample_path: str) -> str: if folder == key or folder.startswith(f"{key}/"): return INSTRUCTIONS_BY_FOLDER[key] - known = ", ".join(sorted(INSTRUCTIONS_BY_FOLDER.keys())) - raise ValueError( - f"No LLM instruction mapping found for sample folder '{folder}' from path '{sample_path}'. " - f"Add an entry to INSTRUCTIONS_BY_FOLDER. Known folders: {known}" - ) + return default_instructions diff --git a/sdk/ai/azure-ai-projects/tests/samples/test_llm_instructions.py b/sdk/ai/azure-ai-projects/tests/samples/test_llm_instructions.py new file mode 100644 index 000000000000..d71f810b9e11 --- /dev/null +++ b/sdk/ai/azure-ai-projects/tests/samples/test_llm_instructions.py @@ -0,0 +1,39 @@ +from llm_instructions import ( + agent_tools_instructions, + agents_instructions, + default_instructions, + get_instructions_for_sample_path, +) + + +def test_get_instructions_uses_specific_folder_mapping(): + sample_path = "/repo/samples/agents/sample_agent_basic.py" + + assert get_instructions_for_sample_path(sample_path) == agents_instructions + + +def test_get_instructions_uses_longest_folder_mapping(): + sample_path = "/repo/samples/agents/tools/sample_tool.py" + + assert get_instructions_for_sample_path(sample_path) == agent_tools_instructions + + +def test_get_instructions_supports_windows_paths(): + sample_path = r"C:\repo\samples\agents\tools\sample_tool.py" + + assert get_instructions_for_sample_path(sample_path) == agent_tools_instructions + + +def test_get_instructions_falls_back_for_unmapped_folder(): + sample_path = "/repo/samples/responses/sample_responses_basic.py" + + instructions = get_instructions_for_sample_path(sample_path) + + assert instructions == default_instructions + assert "HTTP 404 or resource-not-found responses are acceptable" in instructions + + +def test_get_instructions_falls_back_for_nested_unmapped_folder(): + sample_path = "/repo/samples/new_feature/nested/sample_basic.py" + + assert get_instructions_for_sample_path(sample_path) == default_instructions diff --git a/sdk/ai/azure-ai-projects/tests/samples/test_samples.py b/sdk/ai/azure-ai-projects/tests/samples/test_samples.py index 095787cdd6ce..f2cfb45681d1 100644 --- a/sdk/ai/azure-ai-projects/tests/samples/test_samples.py +++ b/sdk/ai/azure-ai-projects/tests/samples/test_samples.py @@ -114,7 +114,10 @@ def test_agents_samples(self, sample_path: str, **kwargs) -> None: "sample_path", get_sample_paths( "agent_insights", - samples_to_skip=[], + samples_to_skip=[ + "sample_agent_insights_on_demand.py", # Skipped until recordings are available. + "sample_agent_insights_scheduled.py", # Skipped until recordings are available. + ], ), ) @agentInsightsServicePreparer() diff --git a/sdk/ai/azure-ai-projects/tests/test_base.py b/sdk/ai/azure-ai-projects/tests/test_base.py index 5e6e48fef69f..08a28d5d7a40 100644 --- a/sdk/ai/azure-ai-projects/tests/test_base.py +++ b/sdk/ai/azure-ai-projects/tests/test_base.py @@ -43,6 +43,7 @@ foundry_project_api_key="sanitized-api-key", foundry_agent_name="sanitized-agent-name", foundry_model_name="sanitized-model-deployment-name", + foundry_voice_model_name="sanitized-model-deployment-name", llm_validation_project_endpoint="https://sanitized-account-name.services.ai.azure.com/api/projects/sanitized-project-name", image_generation_model_deployment_name="sanitized-gpt-image", bing_project_connection_id="/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sanitized-resource-group/providers/Microsoft.CognitiveServices/accounts/sanitized-account/projects/sanitized-project/connections/sanitized-bing-connection", diff --git a/sdk/ai/azure-ai-projects/tsp-location.yaml.saved b/sdk/ai/azure-ai-projects/tsp-location.yaml.saved index 615a7cd64457..a23f0728544d 100644 --- a/sdk/ai/azure-ai-projects/tsp-location.yaml.saved +++ b/sdk/ai/azure-ai-projects/tsp-location.yaml.saved @@ -1,5 +1,5 @@ directory: specification/ai-foundry/data-plane/Foundry/src/sdk-python-js-azure-ai-projects -commit: 675e111febec298cdc8e640d9f8653cc287c5dd1 +commit: 710828f4424a112000ac9a81896a8648f87b7548 repo: Azure/azure-rest-api-specs additionalDirectories: - specification/ai-foundry/data-plane/Foundry/src/agents diff --git a/sdk/ai/cspell.yaml b/sdk/ai/cspell.yaml index 18e70907235b..6aa78c08b840 100644 --- a/sdk/ai/cspell.yaml +++ b/sdk/ai/cspell.yaml @@ -93,6 +93,7 @@ words: - quantitive - rdel - recsmplmdl + - redef - reraises - roups - runid