Test the agent locally
Run the phased smoke test and the credential diagnostics, then smoke-test the container over HTTP.
Check the generated code parses
cd azurefoundry_report_generator_skills
python -c "import ast; [ast.parse(open(f).read()) for f in ['__main__.py','claude_skills_agent.py','claude_skills_agent_executor.py','http_agent_server.py']]"A parse error here is real: every placeholder should be filled by now.
The diagnostic scripts
tests/ holds five standalone scripts. Each loads ../.env, so you do not re-export credentials. Run them from the tests/ directory. If everything is healthy you only need test_run.py; use the others to isolate a failure when it stops partway.
| # | Script | What it isolates |
|---|---|---|
| 1 | test_foundry_direct.py | Resource URL, key, model deployment, and auth header style, over plain HTTP with no SDK. Tries api-key, x-api-key, and Authorization: Bearer until one returns 200. |
| 2 | test_anthropic_sdk_foundry.py | The anthropic package's Foundry client, bypassing claude-agent-sdk. If this works and the agent does not, the problem is in the agent SDK layer. |
| 3 | inspect_foundry_client.py | What AnthropicFoundry.__init__ expects for resource, and the base URL each candidate format produces. |
| 4 | debug_sdk.py [model] | claude-agent-sdk end to end with every message dumped. Use it when test_run.py Phase 1 fails with a vague error. |
| 5 | test_run.py | Phases 0 to 3: env, SDK auth, skill discovery, adapter wiring. |
The phased smoke test
cd azurefoundry_report_generator_skills/tests
python test_run.py| Phase | Checks | Exit code on failure |
|---|---|---|
| 0: env sanity | ANTHROPIC_API_KEY is set; in Foundry mode, ANTHROPIC_FOUNDRY_RESOURCE too. | 1 |
| 1: SDK auth | A one-turn query() with no tools returns text (PING). | 2 |
| 2: skill discovery | Copies the skill into a temp .claude/skills/<skill-name>/, asks the SDK to list its skills, and checks the name appears. | 3 |
| 3: adapter wiring | Runs your agent class in an empty temp cwd, so the skill is not invoked, and checks the first event starts with 🤖, and the last is not an error. It also reports whether token usage was captured, without failing on it. | 4 |
Exit code 0 means every phase passed. Phase 3 avoids the skill on purpose, so it works on Windows even when the skill hardcodes Linux paths. What the smoke test does not cover: running the skill end to end when its scripts need Linux paths, the full HTTP /execute NDJSON path, and volume-mounted outputs. Use the container for those.
Smoke-test the container (plain HTTP)
# From the repo root
docker build -f azurefoundry_report_generator_skills/Dockerfile -t report-generator-skills-agent-test .
docker run --rm -it \
-p 9024:9024 \
--env-file azurefoundry_report_generator_skills/.env \
-v "${PWD}/outputs:/outputs" \
report-generator-skills-agent-test
curl http://localhost:9024/health
curl -X POST http://localhost:9024/execute \
-H 'Content-Type: application/json' \
-d '{"context_id":"t1","task_id":"t1","message":"Build a test report"}'Smoke-test the container (AMC variant)
docker run --rm -it -p 8080:8080 --env-file .env report-generator-skills-agent-test
curl -i http://localhost:8080/health # 200 when ready, 503 when not
curl http://localhost:8080/workflows
curl -X POST http://localhost:8080/runs \
-H 'Content-Type: application/json' \
-d '{"inputs": {"topic": "weekly"}}' # returns orchestratorRunId
curl http://localhost:8080/runs/<orchestratorRunId>/status
curl -N http://localhost:8080/runs/<orchestratorRunId>/events
curl http://localhost:8080/runs/<orchestratorRunId>/tokensCheck that the completed step on /status carries inputTokens, outputTokens, and a model, and that /tokens is not zero. Those are what AMC prices.
Related
Last updated 2026-10-21