mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Address Copilot comments
This commit is contained in:
+1
-1
@@ -116,7 +116,7 @@ curl -X POST "$SEARCH_ENDPOINT/indexes/$INDEX_NAME/docs/index?api-version=2024-0
|
||||
}'
|
||||
```
|
||||
|
||||
You can also point the sample at any existing index that exposes the four fields above; the provider reads `content`, `sourceName`, and `sourceLink` from the search results.
|
||||
You can also point the sample at any existing index that exposes a retrievable text field such as `content`.
|
||||
|
||||
## Running the Agent Host
|
||||
|
||||
|
||||
+4
-6
@@ -7,7 +7,7 @@ from agent_framework import Agent
|
||||
from agent_framework.azure import AzureAISearchContextProvider
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from agent_framework_foundry_hosting import ResponsesHostServer
|
||||
from azure.identity.aio import DefaultAzureCredential
|
||||
from azure.identity import DefaultAzureCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
@@ -37,9 +37,8 @@ async def main():
|
||||
credential=credential,
|
||||
)
|
||||
|
||||
async with (
|
||||
search_provider,
|
||||
Agent(
|
||||
async with search_provider:
|
||||
agent = Agent(
|
||||
client=client,
|
||||
instructions=(
|
||||
"You are a helpful support specialist for Contoso Outdoors. "
|
||||
@@ -51,8 +50,7 @@ async def main():
|
||||
# is no need to store history by the service. Learn more at:
|
||||
# https://developers.openai.com/api/reference/resources/responses/methods/create
|
||||
default_options={"store": False},
|
||||
) as agent,
|
||||
):
|
||||
)
|
||||
server = ResponsesHostServer(agent)
|
||||
await server.run_async()
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
downloaded_skills/
|
||||
+1
-1
@@ -130,7 +130,7 @@ When deploying, make sure `SKILL_NAMES` is set in your `azd` environment so it g
|
||||
azd env set SKILL_NAMES "support-style,escalation-policy"
|
||||
```
|
||||
|
||||
If it is not set, running `azd ai agent init -m <agent-manifest.yaml>` will prompt you to enter it interactively.
|
||||
If it is not set, running `azd ai agent init -m <agent.manifest.yaml>` will prompt you to enter it interactively.
|
||||
|
||||
The deployed agent's Managed Identity needs **Azure AI User** on the Foundry project to download skills at startup. Make sure you have run `provision_skills.py` against the same Foundry project before deploying — otherwise the agent will fail to start with HTTP 404 on the skill download.
|
||||
|
||||
|
||||
+28
-17
@@ -39,6 +39,16 @@ DOWNLOADED_SKILLS_DIR: Final = Path(__file__).parent / "downloaded_skills"
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _safe_extract_zip(zf: zipfile.ZipFile, dest_dir: Path) -> None:
|
||||
"""Extract ``zf`` into ``dest_dir``, rejecting entries that escape it (zip-slip guard)."""
|
||||
dest_root = dest_dir.resolve()
|
||||
for member in zf.infolist():
|
||||
member_path = (dest_root / member.filename).resolve()
|
||||
if dest_root != member_path and dest_root not in member_path.parents:
|
||||
raise RuntimeError(f"Refusing to extract unsafe path '{member.filename}' outside of '{dest_root}'.")
|
||||
zf.extractall(dest_dir)
|
||||
|
||||
|
||||
async def _bootstrap_skills(endpoint: str, skill_names: list[str], target_dir: Path) -> None:
|
||||
"""Download each named skill via ``project.beta.skills`` and unpack it as ``<target_dir>/<name>/SKILL.md``."""
|
||||
if target_dir.exists(): # noqa: ASYNC240
|
||||
@@ -56,7 +66,7 @@ async def _bootstrap_skills(endpoint: str, skill_names: list[str], target_dir: P
|
||||
skill_dir = target_dir / name
|
||||
skill_dir.mkdir()
|
||||
with zipfile.ZipFile(io.BytesIO(zip_bytes)) as zf:
|
||||
zf.extractall(skill_dir)
|
||||
_safe_extract_zip(zf, skill_dir)
|
||||
if not (skill_dir / "SKILL.md").is_file():
|
||||
raise RuntimeError(f"Downloaded archive for '{name}' did not contain a SKILL.md at the root.")
|
||||
|
||||
@@ -77,23 +87,24 @@ async def main() -> None:
|
||||
# instruction-only.
|
||||
skills_provider = SkillsProvider.from_paths(skill_paths=str(DOWNLOADED_SKILLS_DIR))
|
||||
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=project_endpoint,
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
credential=DefaultAzureCredential(),
|
||||
)
|
||||
async with DefaultAzureCredential() as credential:
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=project_endpoint,
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
credential=credential,
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
client=client,
|
||||
instructions="You are a customer-support assistant for Contoso Outdoors.",
|
||||
context_providers=[skills_provider],
|
||||
# History will be managed by the hosting infrastructure, thus there
|
||||
# is no need to store history by the service. Learn more at:
|
||||
# https://developers.openai.com/api/reference/resources/responses/methods/create
|
||||
default_options={"store": False},
|
||||
)
|
||||
server = ResponsesHostServer(agent)
|
||||
await server.run_async()
|
||||
agent = Agent(
|
||||
client=client,
|
||||
instructions="You are a customer-support assistant for Contoso Outdoors.",
|
||||
context_providers=[skills_provider],
|
||||
# History will be managed by the hosting infrastructure, thus there
|
||||
# is no need to store history by the service. Learn more at:
|
||||
# https://developers.openai.com/api/reference/resources/responses/methods/create
|
||||
default_options={"store": False},
|
||||
)
|
||||
server = ResponsesHostServer(agent)
|
||||
await server.run_async()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user