From 8427585072bfc2a3b80f7521cc390385d515d194 Mon Sep 17 00:00:00 2001 From: Howie Leung Date: Fri, 17 Jul 2026 15:30:09 -0700 Subject: [PATCH] Add sample routines for hosted agents with various triggers --- .../sample_routines_crud.py | 46 ++++- .../sample_routines_with_dispatch.py | 53 ++++- ...mple_routines_with_github_issue_trigger.py | 185 ++++++++++++++++++ .../sample_routines_with_schedule_trigger.py | 53 ++++- .../sample_routines_with_timer_trigger.py | 67 ++++--- 5 files changed, 351 insertions(+), 53 deletions(-) rename sdk/ai/azure-ai-projects/samples/{routines => hosted_agents}/sample_routines_crud.py (64%) rename sdk/ai/azure-ai-projects/samples/{routines => hosted_agents}/sample_routines_with_dispatch.py (65%) create mode 100644 sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_github_issue_trigger.py rename sdk/ai/azure-ai-projects/samples/{routines => hosted_agents}/sample_routines_with_schedule_trigger.py (72%) rename sdk/ai/azure-ai-projects/samples/{routines => hosted_agents}/sample_routines_with_timer_trigger.py (66%) diff --git a/sdk/ai/azure-ai-projects/samples/routines/sample_routines_crud.py b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_crud.py similarity index 64% rename from sdk/ai/azure-ai-projects/samples/routines/sample_routines_crud.py rename to sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_crud.py index 45aadc1f8b26..273f02dda296 100644 --- a/sdk/ai/azure-ai-projects/samples/routines/sample_routines_crud.py +++ b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_crud.py @@ -9,10 +9,11 @@ This sample demonstrates how to perform CRUD operations on Routines using the synchronous AIProjectClient. - It creates a routine bound to an existing hosted agent, retrieves it, - toggles its `enabled` state via `disable` / `enable`, lists routines, - and finally deletes it. A `CustomRoutineTrigger` is used to keep the - sample self-contained (no GitHub or schedule resources required). + It uploads the basic hosted-agent code from `assets/basic-agent/` as a + temporary hosted-agent version, creates a routine bound to that hosted + agent, retrieves it, toggles its `enabled` state via `disable` / `enable`, + lists routines, and finally deletes it. A `CustomRoutineTrigger` is used + to keep the sample self-contained (no GitHub or schedule resources required). Routines are currently a preview feature. In the Python SDK, you access these operations via `project_client.beta.routines`. @@ -27,12 +28,13 @@ 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_HOSTED_AGENT_NAME - The name of an existing Hosted Agent to invoke - when the routine fires. + 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model used by the + temporary hosted agent. + 3) FOUNDRY_HOSTED_AGENT_NAME - Optional. The Hosted Agent name. Defaults to + `MyHostedAgent`. """ import os - from dotenv import load_dotenv from azure.core.exceptions import ResourceNotFoundError @@ -40,16 +42,23 @@ from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( + CodeConfiguration, CustomRoutineTrigger, + HostedAgentDefinition, InvokeAgentResponsesApiRoutineAction, + ProtocolVersionRecord, Routine, RoutineTrigger, ) +from hosted_agents_util import create_version_from_code, select_basic_agent_code_zip + load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] -agent_name = os.environ["FOUNDRY_HOSTED_AGENT_NAME"] +agent_name = os.environ.get("FOUNDRY_HOSTED_AGENT_NAME", "MyHostedAgent") +model_name = os.environ["FOUNDRY_MODEL_NAME"] +dependency_resolution, code_zip_stream = select_basic_agent_code_zip(True) def print_routine_state(routine: Routine) -> None: @@ -57,8 +66,29 @@ def print_routine_state(routine: Routine) -> None: with ( + code_zip_stream as code_stream, DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_from_code( + project_client=project_client, + agent_name=agent_name, + description="Routines CRUD hosted agent uploaded from assets/basic-agent.", + definition=HostedAgentDefinition( + cpu="0.5", + memory="1Gi", + code_configuration=CodeConfiguration( + runtime="python_3_14", + entry_point=["python", "main.py"], + dependency_resolution=dependency_resolution, + ), + environment_variables={ + "FOUNDRY_PROJECT_ENDPOINT": endpoint, + "FOUNDRY_MODEL_NAME": model_name, + }, + protocol_versions=[ProtocolVersionRecord(protocol="responses", version="2.0.0")], + ), + code=code_stream, + ), ): routine_name = "sample-routine" diff --git a/sdk/ai/azure-ai-projects/samples/routines/sample_routines_with_dispatch.py b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_dispatch.py similarity index 65% rename from sdk/ai/azure-ai-projects/samples/routines/sample_routines_with_dispatch.py rename to sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_dispatch.py index 1c5164cf00c8..408ffe971161 100644 --- a/sdk/ai/azure-ai-projects/samples/routines/sample_routines_with_dispatch.py +++ b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_dispatch.py @@ -11,13 +11,15 @@ resulting run by polling `list_runs(...)` using the synchronous AIProjectClient. - The routine is bound to an existing hosted agent. Because the trigger is - a `CustomRoutineTrigger`, the routine never fires on its own; the sample - explicitly invokes it with `project_client.beta.routines.dispatch(...)` - passing an `InvokeAgentResponsesApiDispatchPayload` carrying the input - sent to the agent. The sample then polls the run history until a - terminal phase is reached (or a deadline elapses), printing each - observed transition. The routine is deleted at the end of the sample. + The sample uploads the basic hosted-agent code from `assets/basic-agent/` + as a temporary hosted-agent version and routes the configured hosted agent + name to that version. Because the trigger is a `CustomRoutineTrigger`, the + routine never fires on its own; the sample explicitly invokes it with + `project_client.beta.routines.dispatch(...)` passing an + `InvokeAgentResponsesApiDispatchPayload` carrying the input sent to the + agent. The sample then polls the run history until a terminal phase is + reached (or a deadline elapses), printing each observed transition. The + routine and hosted-agent version are deleted at the end of the sample. Routines are currently a preview feature. In the Python SDK, you access these operations via `project_client.beta.routines`. @@ -32,8 +34,10 @@ 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_HOSTED_AGENT_NAME - The name of an existing Hosted Agent to invoke - when the routine is dispatched. + 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model used by the + temporary hosted agent. + 3) FOUNDRY_HOSTED_AGENT_NAME - Optional. The Hosted Agent name. Defaults to + `MyHostedAgent`. """ import json @@ -47,22 +51,51 @@ from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( + CodeConfiguration, + CodeDependencyResolution, CustomRoutineTrigger, + HostedAgentDefinition, InvokeAgentResponsesApiDispatchPayload, InvokeAgentResponsesApiRoutineAction, + ProtocolVersionRecord, RoutineRun, RoutineRunPhase, ) +from hosted_agents_util import create_version_from_code, select_basic_agent_code_zip + load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] -agent_name = os.environ["FOUNDRY_HOSTED_AGENT_NAME"] +agent_name = os.environ.get("FOUNDRY_HOSTED_AGENT_NAME", "MyHostedAgent") +model_name = os.environ["FOUNDRY_MODEL_NAME"] +dependency_resolution, code_zip_stream = select_basic_agent_code_zip(True) with ( + code_zip_stream as code_stream, DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_from_code( + project_client=project_client, + agent_name=agent_name, + description="Routines dispatch hosted agent uploaded from assets/basic-agent.", + definition=HostedAgentDefinition( + cpu="0.5", + memory="1Gi", + code_configuration=CodeConfiguration( + runtime="python_3_14", + entry_point=["python", "main.py"], + dependency_resolution=CodeDependencyResolution.REMOTE_BUILD, + ), + environment_variables={ + "FOUNDRY_PROJECT_ENDPOINT": endpoint, + "FOUNDRY_MODEL_NAME": model_name, + }, + protocol_versions=[ProtocolVersionRecord(protocol="responses", version="2.0.0")], + ), + code=code_stream, + ), ): routine_name = "sample-routine-dispatch" diff --git a/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_github_issue_trigger.py b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_github_issue_trigger.py new file mode 100644 index 000000000000..22de0fc8e272 --- /dev/null +++ b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_github_issue_trigger.py @@ -0,0 +1,185 @@ +# pylint: disable=line-too-long,useless-suppression +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +""" +DESCRIPTION: + This sample demonstrates how to create a Routine that fires when a GitHub + issue is opened in a GitHub repository. + + The sample first uploads the basic hosted-agent code from + `samples/hosted_agents/assets/basic-agent/` as a temporary hosted-agent + version, routes the configured hosted agent name to that version, and then + creates a routine configured with a `GitHubIssueRoutineTrigger`. The trigger + uses a GitHub-compatible Foundry RemoteTool connection supplied through + `GITHUB_CONNECTION_NAME`. After creating the routine, open an issue in the + configured repository to fire it. The sample polls the routine run history + for a short period and then deletes the routine and hosted-agent version. + + Routines are currently a preview feature. In the Python SDK, you access + these operations via `project_client.beta.routines`. + +USAGE: + python sample_routines_with_github_issue_trigger.py + + Before running the sample: + + pip install "azure-ai-projects>=2.2.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_MODEL_NAME - The deployment name of the AI model used by the + temporary hosted agent. + 3) FOUNDRY_HOSTED_AGENT_NAME - Optional. The hosted agent name to route to + the temporary uploaded version. Defaults to `MyHostedAgent`. + 4) GITHUB_CONNECTION_NAME - The Foundry GitHub RemoteTool connection name. + The connection must be GitHub-compatible and use PAT or OAuth2 credentials. + 5) GITHUB_USERNAME - The GitHub owner or organization name. + 6) GITHUB_REPOSITORY - The GitHub repository name in the format of https://github.com/xxx/xxx.git. + 7) POLL_INTERVAL_SECONDS - Optional. Seconds to sleep between run-history polls. + Defaults to 10. +""" + +import json +import os +import time + +from dotenv import load_dotenv + +from azure.core.exceptions import ResourceNotFoundError +from azure.identity import DefaultAzureCredential + +from azure.ai.projects import AIProjectClient +from azure.ai.projects.models import ( + CodeConfiguration, + GitHubIssueEvent, + GitHubIssueRoutineTrigger, + HostedAgentDefinition, + InvokeAgentResponsesApiRoutineAction, + ProtocolVersionRecord, + RoutineRun, +) + +from hosted_agents_util import create_version_from_code, select_basic_agent_code_zip + +load_dotenv() + +endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] +agent_name = os.environ.get("FOUNDRY_HOSTED_AGENT_NAME", "MyHostedAgent") +model_name = os.environ["FOUNDRY_MODEL_NAME"] +github_connection_name = os.environ["GITHUB_CONNECTION_NAME"] +poll_interval_seconds = int(os.environ.get("POLL_INTERVAL_SECONDS", "10")) + +github_owner = os.environ["GITHUB_USERNAME"] +github_repository = os.environ["GITHUB_REPOSITORY"] + + +def main() -> None: + dependency_resolution, code_zip_stream = select_basic_agent_code_zip(True) + + with ( + code_zip_stream as code_stream, + DefaultAzureCredential() as credential, + AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_from_code( + project_client=project_client, + agent_name=agent_name, + description="GitHub issue routine sample hosted agent uploaded from assets/basic-agent.", + definition=HostedAgentDefinition( + cpu="0.5", + memory="1Gi", + code_configuration=CodeConfiguration( + runtime="python_3_14", + entry_point=["python", "main.py"], + dependency_resolution=dependency_resolution, + ), + environment_variables={ + "FOUNDRY_PROJECT_ENDPOINT": endpoint, + "FOUNDRY_MODEL_NAME": model_name, + }, + protocol_versions=[ProtocolVersionRecord(protocol="responses", version="2.0.0")], + ), + code=code_stream, + ), + ): + routine_name = "sample-routine-github-issue" + + print(f"Preparing routine `{routine_name}` for {github_repository}.") + try: + print(f"Deleting any existing routine `{routine_name}`.") + project_client.beta.routines.delete(routine_name) + print(f"Routine `{routine_name}` deleted") + except ResourceNotFoundError: + pass + + print(f"Creating routine `{routine_name}`.") + created = project_client.beta.routines.create_or_update( + routine_name, + description="Routine used by the GitHub issue trigger sample.", + enabled=True, + triggers={ + "on-issue": GitHubIssueRoutineTrigger( + connection_id=github_connection_name, # currently it accept connection name + owner=github_owner, + repository=github_repository, + issue_event=GitHubIssueEvent.OPENED, + ), + }, + action=InvokeAgentResponsesApiRoutineAction(agent_name=agent_name), + ) + print( + f"Created routine: {created.name} enabled={created.enabled} " + f"repo={github_owner}/{github_repository} event={GitHubIssueEvent.OPENED}" + ) + print(f"Open a GitHub issue in {github_repository} to fire the routine.") + print("Waiting for a routine run for up to 10 minutes...") + + try: + seen_phases: dict[str, str] = {} + final_run: RoutineRun | None = None + run_was_triggered = False + terminal_statuses = {"finished", "failed", "killed"} + + deadline = time.monotonic() + 600 + while time.monotonic() < deadline: + runs = list(project_client.beta.routines.list_runs(routine_name, limit=20, order="desc")) + for run in runs: + run_was_triggered = True + current_phase = str(run.phase) + if seen_phases.get(run.id) == current_phase: + continue + seen_phases[run.id] = current_phase + print( + f" - run_id={run.id} phase={run.phase} status={run.status} " + f"trigger_type={run.trigger_type} triggered_at={run.triggered_at} ended_at={run.ended_at}" + ) + if str(run.status).lower() in terminal_statuses: + final_run = run + + if final_run is not None: + break + time.sleep(poll_interval_seconds) + + if final_run: + print("Final run:") + print(json.dumps(final_run.as_dict(), indent=2, default=str)) + print(f"The response Id is {final_run.response_id}") + elif run_was_triggered: + print("A routine run was observed, but no terminal run state was reached within the deadline.") + else: + print("No GitHub issue-triggered run was observed within the deadline.") + except KeyboardInterrupt: + print("Interrupted by user; cleaning up routine before exiting.") + finally: + try: + project_client.beta.routines.delete(routine_name) + print("Routine deleted") + except ResourceNotFoundError: + pass + + +if __name__ == "__main__": + main() diff --git a/sdk/ai/azure-ai-projects/samples/routines/sample_routines_with_schedule_trigger.py b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_schedule_trigger.py similarity index 72% rename from sdk/ai/azure-ai-projects/samples/routines/sample_routines_with_schedule_trigger.py rename to sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_schedule_trigger.py index 7f3b6404d644..533581ebe8eb 100644 --- a/sdk/ai/azure-ai-projects/samples/routines/sample_routines_with_schedule_trigger.py +++ b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_schedule_trigger.py @@ -10,11 +10,14 @@ recurring cron schedule, then record the resulting runs by polling `list_runs(...)` using the synchronous AIProjectClient. - The routine is bound to an existing hosted agent and scheduled with a + The sample uploads the basic hosted-agent code from `assets/basic-agent/` + as a temporary hosted-agent version, routes the configured hosted agent + name to that version, and schedules the routine with a `ScheduleRoutineTrigger` using a 5-field cron expression. The service enforces a minimum interval of five minutes, so the sample polls the run history for up to ~6 minutes to catch the first fire, prints each - observed phase transition, then deletes the routine. + observed phase transition, then deletes the routine and hosted-agent + version. Routines are currently a preview feature. In the Python SDK, you access these operations via `project_client.beta.routines`. @@ -29,15 +32,19 @@ 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_HOSTED_AGENT_NAME - The name of an existing Hosted Agent to invoke - when the routine schedule fires. - 3) POLL_INTERVAL_SECONDS - Optional. Seconds to sleep between run-history polls. - Defaults to 15. + 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model used by the + temporary hosted agent. + 3) FOUNDRY_HOSTED_AGENT_NAME - Optional. The Hosted Agent name. Defaults to + `MyHostedAgent`. + 4) POLL_INTERVAL_SECONDS - Optional. Seconds to sleep between run-history polls. + Defaults to 15. """ import json import os +import sys import time +from pathlib import Path from dotenv import load_dotenv @@ -46,23 +53,55 @@ from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( + CodeConfiguration, + HostedAgentDefinition, InvokeAgentResponsesApiRoutineAction, + ProtocolVersionRecord, RoutineRun, RoutineRunPhase, ScheduleRoutineTrigger, ) +_HOSTED_AGENTS_DIR = Path(__file__).resolve().parent +if str(_HOSTED_AGENTS_DIR) not in sys.path: + sys.path.insert(0, str(_HOSTED_AGENTS_DIR)) + +from hosted_agents_util import create_version_from_code, select_basic_agent_code_zip + load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] -agent_name = os.environ["FOUNDRY_HOSTED_AGENT_NAME"] +agent_name = os.environ.get("FOUNDRY_HOSTED_AGENT_NAME", "MyHostedAgent") +model_name = os.environ["FOUNDRY_MODEL_NAME"] poll_interval_seconds = int(os.environ.get("POLL_INTERVAL_SECONDS", "15")) +dependency_resolution, code_zip_stream = select_basic_agent_code_zip(True) def main() -> None: with ( + code_zip_stream as code_stream, DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_from_code( + project_client=project_client, + agent_name=agent_name, + description="Routines schedule hosted agent uploaded from assets/basic-agent.", + definition=HostedAgentDefinition( + cpu="0.5", + memory="1Gi", + code_configuration=CodeConfiguration( + runtime="python_3_14", + entry_point=["python", "main.py"], + dependency_resolution=dependency_resolution, + ), + environment_variables={ + "FOUNDRY_PROJECT_ENDPOINT": endpoint, + "FOUNDRY_MODEL_NAME": model_name, + }, + protocol_versions=[ProtocolVersionRecord(protocol="responses", version="2.0.0")], + ), + code=code_stream, + ), ): routine_name = "sample-routine-schedule" diff --git a/sdk/ai/azure-ai-projects/samples/routines/sample_routines_with_timer_trigger.py b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_timer_trigger.py similarity index 66% rename from sdk/ai/azure-ai-projects/samples/routines/sample_routines_with_timer_trigger.py rename to sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_timer_trigger.py index 1ef31fb4a108..b9b8256b4d4d 100644 --- a/sdk/ai/azure-ai-projects/samples/routines/sample_routines_with_timer_trigger.py +++ b/sdk/ai/azure-ai-projects/samples/hosted_agents/sample_routines_with_timer_trigger.py @@ -10,10 +10,12 @@ from a one-shot timer trigger, then record the resulting runs by polling `list_runs(...)` using the synchronous AIProjectClient. - The routine is bound to an existing hosted agent and scheduled to fire a - short time in the future. The sample then polls the run history until a - terminal phase is reached (or a deadline elapses), printing each observed - transition. The routine is deleted at the end of the sample. + The sample uploads the basic hosted-agent code from `assets/basic-agent/` + as a temporary hosted-agent version, routes the configured hosted agent + name to that version, and schedules the routine to fire a short time in + the future. The sample then polls the run history until a terminal phase is + reached (or a deadline elapses), printing each observed transition. The + routine and hosted-agent version are deleted at the end of the sample. Routines are currently a preview feature. In the Python SDK, you access these operations via `project_client.beta.routines`. @@ -28,8 +30,10 @@ 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_HOSTED_AGENT_NAME - The name of an existing Hosted Agent to invoke - when the routine timer fires. + 2) FOUNDRY_MODEL_NAME - The deployment name of the AI model used by the + temporary hosted agent. + 3) FOUNDRY_HOSTED_AGENT_NAME - Optional. The Hosted Agent name. Defaults to + `MyHostedAgent`. """ import datetime @@ -40,47 +44,54 @@ from dotenv import load_dotenv from azure.core.exceptions import ResourceNotFoundError -from azure.core.settings import settings - -settings.tracing_implementation = "opentelemetry" -from opentelemetry import trace -from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter -from azure.monitor.opentelemetry import configure_azure_monitor -from azure.ai.projects.telemetry import AIProjectInstrumentor from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.ai.projects.models import ( + CodeConfiguration, + HostedAgentDefinition, InvokeAgentResponsesApiRoutineAction, + ProtocolVersionRecord, RoutineRun, RoutineRunPhase, TimerRoutineTrigger, ) -load_dotenv() +from hosted_agents_util import create_version_from_code, select_basic_agent_code_zip -# Console exporter: spans printed to stdout as they finish. -tracer_provider = TracerProvider() -tracer_provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter())) -trace.set_tracer_provider(tracer_provider) -tracer = trace.get_tracer(__name__) -AIProjectInstrumentor().instrument() +load_dotenv() endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"] -agent_name = os.environ["FOUNDRY_HOSTED_AGENT_NAME"] - +agent_name = os.environ.get("FOUNDRY_HOSTED_AGENT_NAME", "MyHostedAgent") +model_name = os.environ["FOUNDRY_MODEL_NAME"] +dependency_resolution, code_zip_stream = select_basic_agent_code_zip(True) with ( + code_zip_stream as code_stream, DefaultAzureCredential() as credential, AIProjectClient(endpoint=endpoint, credential=credential) as project_client, + create_version_from_code( + project_client=project_client, + agent_name=agent_name, + description="Routines timer hosted agent uploaded from assets/basic-agent.", + definition=HostedAgentDefinition( + cpu="0.5", + memory="1Gi", + code_configuration=CodeConfiguration( + runtime="python_3_14", + entry_point=["python", "main.py"], + dependency_resolution=dependency_resolution, + ), + environment_variables={ + "FOUNDRY_PROJECT_ENDPOINT": endpoint, + "FOUNDRY_MODEL_NAME": model_name, + }, + protocol_versions=[ProtocolVersionRecord(protocol="responses", version="2.0.0")], + ), + code=code_stream, + ), ): - # Azure Monitor exporter: same spans also sent to the Application Insights - # resource attached to the Foundry project, viewable in the "Tracing" tab - # on ai.azure.com. - configure_azure_monitor(connection_string=project_client.telemetry.get_application_insights_connection_string()) - routine_name = "sample-routine-timer" try: