Fullfører spikens siste måling etter at docker-tillatelsen kom på plass. 7.1 — `docker build --platform linux/amd64` grønn på python:3.12-slim-bookworm. `uv sync --frozen` resolverte inne i containeren, inkludert begge git-pinnene, og siste lag ga `import OK`. Det lukker gapet uv-resolusjonen ikke kunne lukke: at avhengighetene LØSER for linux beviser ikke at koden KJØRER der. 7.2 — Andre måling bygde wheelen, SLETTET kilden, og installerte kun wheelen. Den feilet: `llm-ingestion-guard was not found in the package registry`. Wheelens metadata bærer de to avhengighetene som BARE NAVN — [tool.uv.sources] er uv-konfig og reiser ikke med wheelen, og navnene finnes ikke på PyPI. En nedlaster som får et wheel (f.eks. fra release-objektet fase 3 skal lage) treffer denne veggen. Med direct references ved siden av: 65 pakker, exit 0. Dette er den skarpeste friksjonskanten spiken fant, og ingen hadde spurt om den. 7.3 — Samme bygg beviste fase 4a i container: shared_root() peker på site-packages/portfolio_optimiser/_shared, 80 filer, persona-skillen lesbar — uten arbeidstre, siden /build var slettet før installasjonen. Invarianten er dermed målt i situasjonen den ble bygget for, ikke bare i enhetstest. Byggekonteksten er `git archive HEAD` (311 sporede filer) — det en fremmed faktisk laster ned, ikke arbeidstreet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jk8tauXXAojNKC7Tzq7ziF
438 lines
22 KiB
Markdown
438 lines
22 KiB
Markdown
# Fase 4· — research-spike: hostingkontrakten for Foundry Agent Service
|
||
|
||
**Dato:** 2026-08-13 · **Commit ved måling:** `f5ec8c8` · **Metode:** agent-team, fire parallelle
|
||
spor, alle Opus/xhigh · **Leveranse:** svar som kommandoer og siterte kilder, aldri vurderinger.
|
||
|
||
Denne rapporten åpner fase 4 i den kanoniske planen. Den bygger ingen produksjonskode og rører
|
||
ikke `shared/`. Alt som står her er enten kjørt på denne maskinen eller sitert fra Microsoft Learn
|
||
med URL. Det som ikke lot seg verifisere står under **Ikke verifisert** — ikke i brødteksten.
|
||
|
||
---
|
||
|
||
## 0. Sammendrag for den som bare leser ett avsnitt
|
||
|
||
Alle fire spørsmål er besvart med kjørte kommandoer og siterte kilder, og containeren er bygget på
|
||
`linux/amd64` (§7). Underveis kom det ett funn ingen hadde spurt om: **wheelen er ikke installerbar
|
||
alene** — dens metadata bærer to avhengigheter som bare navn, og de finnes ikke på PyPI (§7.2). Det
|
||
er den skarpeste friksjonskanten spiken fant.
|
||
|
||
Spiken felte **tre premisser i planen**:
|
||
|
||
| Premiss i planen | Dom |
|
||
|---|---|
|
||
| «`azd`-utvidelsen heter enten `microsoft.foundry` eller `azure.ai.agents` — én er utdatert» | **Feil.** Begge er gjeldende; den ene er en meta-pakke over den andre |
|
||
| «Foundry injiserer `FOUNDRY_PROJECT_ENDPOINT`, `AZURE_AI_MODEL_DEPLOYMENT_NAME` og `APPLICATIONINSIGHTS_CONNECTION_STRING`» | **To av tre.** `AZURE_AI_MODEL_DEPLOYMENT_NAME` injiseres IKKE — den deklarerer vi selv |
|
||
| «`docker build` og `azd ai agent run` mot `localhost:8088` er testbare UTEN Azure» | **Feil for `azd ai agent run`.** Den krever `azd auth login` og provisjonerte ressurser |
|
||
|
||
Alt materialet er hentet mot det gjeldende hostingbackendet, ikke det gamle preview-et. Se §8 for
|
||
hvorfor det skillet betyr noe når man leser eldre oppskrifter.
|
||
|
||
---
|
||
|
||
## 1. Hostingkontrakten
|
||
|
||
### 1.1 Runtime-kontrakten er kort og eksplisitt
|
||
|
||
Kilde: <https://learn.microsoft.com/azure/foundry/agents/concepts/hosted-agent-contract>
|
||
|
||
| Krav | Detalj (sitert) |
|
||
|---|---|
|
||
| Port | «Listen on port 8088 … HTTP/1.1, plain HTTP. The platform terminates TLS.» |
|
||
| Helse | «Return `200 OK` from `GET /readiness`.» |
|
||
| Protokoll | «Serve at least one of `POST /responses` or `POST /invocations`.» |
|
||
| Miljø | «Read the variables the platform injects at startup.» |
|
||
| Avslutning | «Flush writes and close connections on `SIGTERM`.» |
|
||
|
||
Bind-adresse er `0.0.0.0`, og porten kan overstyres med `PORT`. `/readiness` implementeres ikke av
|
||
oss: «The protocol libraries automatically expose a `/readiness` endpoint for platform health
|
||
checks. You don't need to implement this yourself.»
|
||
|
||
### 1.2 Filsettet
|
||
|
||
Learn oppgir intet normativt «required files»-sett. Det som finnes er hva `azd ai agent init`
|
||
skaper, og hva Microsofts egen MAF-sample faktisk inneholder.
|
||
|
||
Scaffold (<https://learn.microsoft.com/azure/foundry/agents/how-to/init-agent-project>):
|
||
|
||
```
|
||
.
|
||
|-- azure.yaml # Unified azd project and hosted agent configuration
|
||
|-- src/
|
||
| \-- <agent-name>/
|
||
| |-- Dockerfile # Container build definition
|
||
| \-- ... # Agent source code
|
||
|-- .azure/ # Environment configuration
|
||
\-- infra/ # Optional IaC, created only after you eject infrastructure
|
||
```
|
||
|
||
**Agent-manifest er avviklet** — dette er en bruddendring mot enhver eldre oppskrift:
|
||
|
||
> «Agent manifests (`agent.manifest.yaml`) and standalone agent definitions (`agent.yaml`) are
|
||
> deprecated. As of the Foundry `azd` extensions (`azure.ai.agents` 1.0.0-beta.1), all hosted agent
|
||
> configuration lives in a single `azure.yaml`.»
|
||
|
||
Microsofts referansesample for Python/MAF bærer i `src/<agent>/`: `.azdignore`, `.dockerignore`,
|
||
`.env.example`, `Dockerfile`, `main.py`, `requirements.txt`. Merk: **ingen `pyproject.toml`** — den
|
||
bruker `requirements.txt`. Det er relevant for oss, se §3.
|
||
|
||
Samplets Dockerfile, ordrett
|
||
(<https://raw.githubusercontent.com/microsoft-foundry/foundry-samples/main/samples/python/hosted-agents/agent-framework/responses/01-basic/src/agent-framework-agent-basic-responses/Dockerfile>):
|
||
|
||
```dockerfile
|
||
FROM python:3.12-slim
|
||
WORKDIR /app
|
||
COPY . user_agent/
|
||
WORKDIR /app/user_agent
|
||
RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; else echo "No requirements.txt found"; fi
|
||
EXPOSE 8088
|
||
CMD ["python", "main.py"]
|
||
```
|
||
|
||
At Microsofts egen sample lander på `python:3.12-slim` er verdt å merke seg mot §4: det er samme
|
||
base-image vår egen resolusjon peker på, av uavhengige grunner.
|
||
|
||
### 1.3 `azure.yaml` — skjema og det uavklarte
|
||
|
||
`$schema`-linja:
|
||
`# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json`
|
||
|
||
`host:`-verdien for en hosted agent er **`azure.ai.agent`** («Must be `azure.ai.agent`»).
|
||
Sentrale felter (<https://learn.microsoft.com/azure/foundry/agents/concepts/azure-yaml-reference>):
|
||
`kind: hosted`, `project` (sti til kildekatalog), `language`, `uses`, `protocols`, `env`,
|
||
`container`, `startupCommand`, `codeConfiguration`, `image`.
|
||
|
||
**Learn og Microsofts eget sample er uenige på fire punkter.** Dette er ikke en detalj — det er
|
||
forskjellen mellom en `azure.yaml` som virker og en som avvises:
|
||
|
||
| Punkt | Learn-referansen | Samplet (det `azd ai agent init -m` faktisk adopterer) |
|
||
|---|---|---|
|
||
| Byggespråk | `language: docker` | `language: python` + `codeConfiguration` |
|
||
| Miljøvariabler | `env:` som map | `environmentVariables:` som liste av `{name, value}` |
|
||
| Entrypoint | `entryPoint: main.py` | også `entryPoint: ["python", "main.py"]` i en annen artikkel |
|
||
| Protokollversjon | `2.0.0` i azure.yaml-eksempler | `1.0.0` i SDK/REST-eksempler |
|
||
|
||
Anbefaling: **bruk samplet som fasit**, fordi det er fila `azd ai agent init -m` kopierer. Men
|
||
protokollversjonen må avklares før vi skriver vår egen — se **Ikke verifisert** pkt. 4.
|
||
|
||
### 1.4 Container-krav
|
||
|
||
`linux/amd64` er bekreftet påkrevd
|
||
(<https://learn.microsoft.com/azure/foundry/agents/how-to/deploy-hosted-agent>):
|
||
|
||
> «The hosting platform requires x86_64 (linux/amd64) container images. If you build on Apple
|
||
> Silicon or other ARM-based machines, use `docker build --platform linux/amd64 .` to avoid
|
||
> producing an incompatible ARM image.»
|
||
|
||
Planens observasjon står: på operatørens Intel-Mac er dette maskinens egen arkitektur, og vi har
|
||
målt at colima-VM-en rapporterer `linux/x86_64` (§6). Ingen emulering.
|
||
|
||
**CPU/minne motsier seg selv i Learn.** Referansesiden sier fritt intervall («`cpu` from `"0.25"`
|
||
up to `"4.0"`, and `memory` from `0.5Gi` up to `8.0Gi`»), mens konseptsiden gir tre faste tiers
|
||
(0.5 vCPU/1 GiB, 1/2, 2/4). Feilmeldingen avgjør tolkningen: `400 bad_request` med «CPU and Memory
|
||
must be specified as a valid resource tier». **Bruk tier-tabellen.**
|
||
|
||
Dokumenterte tidsgrenser: idle-timeout 15 minutter, sesjonslevetid maks 30 dager, diskbudsjett
|
||
opptil 20 GiB ved ≥1 vCPU hvorav ~20 % er systemreservert.
|
||
|
||
### 1.5 Headere under protokoll 2.0.0
|
||
|
||
Plattformen injiserer `x-agent-user-id` (per bruker) og `x-agent-foundry-call-id` (per request,
|
||
skal videresendes uendret på utgående Foundry-kall). Gatewayen **dropper alt annet enn en
|
||
allowlist** — `Authorization`, `Host`, `Cookie` og `x-forwarded-*` kommer aldri fram; egne headere
|
||
må prefikses `x-client-`. Begge de injiserte er «not guaranteed when you run locally», så koden må
|
||
tåle at de mangler.
|
||
|
||
---
|
||
|
||
## 2. `azd`-utvidelsens navn — planens premiss var feil
|
||
|
||
Planen antok at ett av navnene var utdatert. Målt mot azds offisielle register
|
||
(`https://aka.ms/azd/extensions/registry`, som redirecter til
|
||
`raw.githubusercontent.com/Azure/azure-dev/refs/heads/main/cli/azd/extensions/registry.json`,
|
||
451 555 bytes — byte-identisk med repo-URL-en, altså samme fil): **begge ID-ene finnes samtidig, og
|
||
de gjør forskjellige ting.**
|
||
|
||
| ID | Rolle | Siste versjon | Kommandogruppe |
|
||
|---|---|---|---|
|
||
| `microsoft.foundry` | Meta-pakke uten egne kommandoer og uten binærartefakter | 1.0.0-beta.2 | — |
|
||
| `azure.ai.agents` | Den faktiske utvidelsen; eier `service-target`-provideren «Deploys agents to the Foundry Agent Service» | 1.0.0-beta.9 (utgitt 2026-08-06) | `azd ai agent` |
|
||
|
||
Learn sier det selv rett ut
|
||
(<https://learn.microsoft.com/azure/foundry/agents/how-to/install-cli-foundry-extensions>):
|
||
|
||
> «The `microsoft.foundry` package is a thin meta-package that doesn't contribute its own commands.
|
||
> Installing it pulls in every individual extension, which is the recommended starting point.»
|
||
|
||
**Det som faktisk henger etter i doc-en er ikke ID-navnet, men versjonskravet.** Flere Learn-sider
|
||
sier `azd` 1.25.2 eller senere; registeret krever `>=1.27.1` for begge utvidelsene. Vi installerte
|
||
1.31.0 (§6), så vi ligger over.
|
||
|
||
`darwin/amd64`-artefaktet finnes for `azure.ai.agents` 1.0.0-beta.9 (sha256
|
||
`f0750469a17c7370534db21d5542eb9241f2ffc1093361bf373b5ef71ff43c1f`) — altså støttet på denne
|
||
maskinen.
|
||
|
||
Kommandoene, ordrett fra Learn:
|
||
|
||
```bash
|
||
azd ext install microsoft.foundry # meta-pakke, anbefalt start
|
||
azd ext install azure.ai.agents # bare agent-flaten (drar inn azure.ai.inspector)
|
||
azd ext list
|
||
azd ai agent version
|
||
```
|
||
|
||
`azd extension` og `azd ext` er samme kommando — verifisert i azds kildekode
|
||
(`cli/azd/cmd/extension.go`, linje 50: `Aliases: []string{"ext"},`), ikke bare i doc.
|
||
|
||
---
|
||
|
||
## 3. Avhengighetsformen i container — direct references, ingen publisering
|
||
|
||
Spørsmålet var om `[tool.uv.sources]`-git-pinnene overlever inn i en container, siden de ikke
|
||
finnes i wheel-metadata. **Svaret er ja, i begge pakkeverktøy, uten publisering og uten auth.**
|
||
|
||
| Måling | Kommando | Exit |
|
||
|---|---|---|
|
||
| uv resolverer direct references | `uv pip compile req-direct-min.txt --python-version 3.12 --python-platform linux` | 0 |
|
||
| pip gjør det samme | `pip install --dry-run --report … -r req-direct-min.txt` | 0 |
|
||
| Anonym git-lesing virker | `env -u GIT_ASKPASS GIT_TERMINAL_PROMPT=0 git ls-remote https://git.fromaitochitta.com/open/llm-ingestion-okf.git v0.3.2` | 0 |
|
||
|
||
At **pip** klarer det er poenget: en Dockerfile er ikke bundet til `uv`. uv oppgraderer dessuten
|
||
tag → commit-SHA i outputen, så formen er selv-pinnende.
|
||
|
||
Alle tre pakkenavn er ledige på PyPI (HTTP 404 på `/simple/`), så publisering ville vært mulig —
|
||
men er unødvendig, og ville lagt en release-forpliktelse på to sikkerhetskomponenter som i dag er
|
||
tag-pinnet med vilje.
|
||
|
||
**Én felle er målt.** Default-eksporten fra lockfila produserer en fil pip **avviser**:
|
||
|
||
```
|
||
ERROR: Can't verify hashes for these requirements because we don't have a way
|
||
to hash version control repositories
|
||
```
|
||
|
||
pips hash-modus er alt-eller-ingenting, og en git-URL kan ikke hashes. Den målte veien rundt, som
|
||
beholder hash-verifisering for de 64 PyPI-pakkene:
|
||
|
||
```bash
|
||
uv export --frozen --format requirements.txt --no-dev --no-emit-project -o requirements.txt
|
||
grep -v '^llm-ingestion' requirements.txt > requirements-pypi.txt # hashet
|
||
grep '^llm-ingestion' requirements.txt > requirements-git.txt # commit-pinnet
|
||
```
|
||
|
||
Base-imaget må da ha `git` installert. `-slim`-variantene har det ikke.
|
||
|
||
**Bygg fra eksporten, ikke fra `pyproject.toml`.** Fersk resolusjon velger
|
||
`agent-framework-core==1.13.0` og `mcp==2.0.0`, mens `uv.lock` pinner `1.9.0` / `1.28.0`. Begge er
|
||
lovlige innenfor spennet, men en container bygget fra `pyproject.toml` ville kjørt andre versjoner
|
||
enn utviklermaskinen — og MAF-pinnen `<2` er tosidig nettopp fordi privat-API-premissene må
|
||
re-verifiseres ved bump.
|
||
|
||
---
|
||
|
||
## 4. Base-image — 3.10 til 3.13, aldri 3.14
|
||
|
||
Resolusjonsmatrise mot `x86_64-unknown-linux-gnu`, hele `[project.dependencies]`:
|
||
|
||
| Python | Fersk resolusjon | Med wheel-krav på numpy | numpy | agent-framework-core |
|
||
|---|---|---|---|---|
|
||
| 3.10 | ✅ | ✅ | 2.2.6 | 1.13.0 |
|
||
| 3.11 | ✅ | ✅ | 2.2.6 | 1.13.0 |
|
||
| 3.12 | ✅ | ✅ | 2.2.6 | 1.13.0 |
|
||
| 3.13 | ✅ | ✅ | 2.2.6 | 1.13.0 |
|
||
| 3.14 | ✅ | ❌ | kun via sdist | 1.13.0 |
|
||
|
||
**Den ferske resolusjonen alene er villedende, og det er hele funnet.** Alle fem «resolverer»,
|
||
fordi numpy 2.2.6 har en sdist. Men numpy 2.2.6 har manylinux-x86_64-hjul kun for cp310–cp313 —
|
||
ingen cp314. På 3.14 ville containeren kompilert numpy fra kilde, altså dratt inn en full
|
||
byggekjede og en byggetid ingen har budsjettert. `--only-binary numpy` gjør det til en hard feil i
|
||
stedet for en skjult kostnad:
|
||
|
||
```
|
||
× No solution found when resolving dependencies:
|
||
╰─▶ … numpy>=2.0.0,<=2.2.6 has no usable wheels …
|
||
your requirements are unsatisfiable.
|
||
```
|
||
|
||
Dette er `numpy<2.3`-taket i `pyproject.toml` som binder. Taket står der av to andre grunner
|
||
(3.10-støtte og mypys PEP 695-parsing), og 3.14-utfallet er en bivirkning av dem.
|
||
|
||
**Valg: `python:3.12-slim-bookworm`** — repoet pinner `.python-version` = 3.12, det ligger midt i
|
||
det lovlige båndet, og Microsofts egen MAF-sample bruker `python:3.12-slim` (§1.2).
|
||
|
||
---
|
||
|
||
## 5. `Workflow.as_agent()` — virker, men eksponerer feil ting
|
||
|
||
Målt mot det installerte (`agent-framework-core` 1.9.0), ikke mot dokumentasjonen:
|
||
|
||
- `fresh_workflow(...)` returnerer en ekte `agent_framework._workflows._workflow.Workflow`
|
||
- `.as_agent()` konstruerer en `WorkflowAgent(BaseAgent)` som tilfredsstiller `SupportsAgentRun`
|
||
- `await ag.run(...)` **kjører**, og returnerer proposer- og checker-meldingene
|
||
|
||
Learn bekrefter at dette er den offisielle mekanismen
|
||
(<https://learn.microsoft.com/agent-framework/hosting/foundry-hosted-agent>):
|
||
|
||
> «you can expose an `Agent`, including a workflow wrapped with `Workflow.as_agent()`, through the
|
||
> Foundry Responses or Invocations protocol with minimal code.»
|
||
|
||
**Og likevel er svaret «wrapper», ikke «direkte».** `fresh_workflow` er steg 3 av åtte i
|
||
`run_project` (`src/portfolio_optimiser/run.py:554`). Validatoren, kostbaseline-forankringen,
|
||
provenance-stempelet, checker-gaten, ledgeren og læringssløyfa ligger alle **utenfor**
|
||
`Workflow`-grafen. En hosted agent bygget på `as_agent()` alene ville servert ugatede agent-forslag
|
||
— altså brutt repoets egen invariant om at den deterministiske validatoren er obligatorisk og
|
||
blokkerende.
|
||
|
||
Signaturgapet er konkret: hosting-flaten tar `str`/`Message` inn og gir `AgentResponse` ut;
|
||
`run_project` tar `project_id` pluss to påkrevde keyword-argumenter uten default (`docs_dir`,
|
||
`verdict_input`) og gir en frozen `RunResult`-dataclass. **Fase 4c er derfor et signaturproblem,
|
||
ikke et grafproblem.**
|
||
|
||
To detaljer med konsekvens:
|
||
|
||
1. `AgentResponse.text` **konkatenerer** proposer + checker + orkestratorens sluttnotis til én
|
||
streng. Dagens kode skiller dem på `author_name` (`run.py:330`). En hosted flate som returnerer
|
||
`.text` ville slått de to falsifisererne sammen til én tekst.
|
||
2. `fresh_workflow` er en factory nettopp fordi et gjenbrukt workflow akkumulerer tråd på tvers av
|
||
kall. En hostet agent er per definisjon ett langlevd objekt som betjener mange forespørsler.
|
||
**Dette er den største uavklarte risikoen spiken fant**, og må måles før 4c-designet låses.
|
||
|
||
Dette bekrefter planens 4c-valg: **Invocations, ikke Responses.** `run_project` er ett kall med
|
||
strukturert inn og strukturert ut, ikke en samtale. Learn plasserer Invocations på «custom
|
||
payloads, non-conversational processing».
|
||
|
||
---
|
||
|
||
## 6. Miljøet — hva som ble reparert på maskinen
|
||
|
||
Verktøykjeden manglet ved oppstart. Målt før:
|
||
|
||
| Verktøy | Før | Etter |
|
||
|---|---|---|
|
||
| `az` | 2.84.0 (var installert) | uendret |
|
||
| `azd` | not found | 1.31.0 (formelen heter `azure-dev`) |
|
||
| `docker` | not found | klient 29.7.2 / server 29.5.2 |
|
||
| daemon | ingen | colima 0.10.3 → `linux/x86_64`, 6 CPU, 10 GB |
|
||
|
||
Docker Desktop-casken var registrert som installert (4.50.0) mens `/Applications/Docker.app` ikke
|
||
fantes og Caskroom-katalogen var 0 B — en foreldet brew-oppføring. **colima ble valgt framfor
|
||
Docker Desktop** fordi Desktop krever GUI-oppstart og admin-passord, mens colima kjører fra
|
||
terminalen. På en Intel-Mac er colima-VM-en `linux/amd64` nativt.
|
||
|
||
Én etterlatenskap måtte ryddes: `~/.docker/config.json` pekte på `credsStore: "desktop"`, en
|
||
credential-helper som ikke lenger fantes, og som feilet ethvert image-oppslag. `auths` var tom, så
|
||
linja ble fjernet (backup: `~/.docker/config.json.bak-20260813-213134`).
|
||
|
||
---
|
||
|
||
## 7. Containeren er bygget — to målinger
|
||
|
||
Byggekonteksten er `git archive HEAD` (311 sporede filer, 3,7 MB), altså **det en fremmed faktisk
|
||
laster ned** — ikke arbeidstreet med `.venv` og lokale artefakter.
|
||
|
||
### 7.1 Bygger og importerer på `linux/amd64`
|
||
|
||
```bash
|
||
docker build --platform linux/amd64 --build-arg PYVER=3.12 -f Dockerfile.measure -t po-measure:py312 .
|
||
```
|
||
|
||
Exit 0. `uv sync --frozen --no-dev` resolverte inne i containeren — inkludert de to git-pinnede
|
||
avhengighetene — og siste lag ga `import OK`. Det lukker gapet §3/§4 ikke kunne lukke: uv-resolusjon
|
||
viser at avhengighetene *løser* for linux; dette viser at koden *importerer og kjører* der.
|
||
|
||
### 7.2 Wheelen er IKKE installerbar alene — målt
|
||
|
||
Andre måling bygde wheelen, **slettet kilden**, og installerte kun wheelen i et rent miljø. Den
|
||
feilet:
|
||
|
||
```
|
||
× No solution found when resolving dependencies:
|
||
╰─▶ Because llm-ingestion-guard was not found in the package registry
|
||
and portfolio-optimiser==1.0.0 depends on llm-ingestion-guard …
|
||
your requirements are unsatisfiable.
|
||
```
|
||
|
||
**Dette er den viktigste friksjonsobservasjonen i hele spiken.** Wheelens metadata bærer de to
|
||
avhengighetene som *bare navn*, fordi `[tool.uv.sources]` er uv-konfigurasjon og ikke reiser med
|
||
wheelen. Navnene finnes ikke på PyPI (§3). En nedlaster som får et wheel — f.eks. fra et
|
||
release-objekt, som er fase 3-raden — treffer denne veggen med mindre de to git-kravene oppgis ved
|
||
siden av. Det må stå i installasjonsdokumentasjonen, eller løses ved publisering.
|
||
|
||
Med direct references ved siden av virker det:
|
||
|
||
```bash
|
||
uv pip install /dist/*.whl \
|
||
"llm-ingestion-okf @ git+https://git.fromaitochitta.com/open/llm-ingestion-okf.git@v0.3.2" \
|
||
"llm-ingestion-guard @ git+https://git.fromaitochitta.com/open/llm-ingestion-pipeline-security.git@v0.3.4"
|
||
```
|
||
|
||
→ `Installed 65 packages`, exit 0.
|
||
|
||
### 7.3 Fase 4a holder i container
|
||
|
||
Samme bygg verifiserte pakkede data uten arbeidstre — `/build` var slettet før installasjonen:
|
||
|
||
```
|
||
pakke: /app/venv/lib/python3.12/site-packages/portfolio_optimiser
|
||
shared_root: /app/venv/lib/python3.12/site-packages/portfolio_optimiser/_shared
|
||
filer under shared_root: 80
|
||
PAKKEDE DATA OK
|
||
```
|
||
|
||
`shared/skills/expert-reviewer/SKILL.md` er lesbar derfra. Fase 4a-invarianten — wheelen bærer
|
||
`shared/` som pakkede data, arbeidstreet er kun en overstyring — er dermed målt i den situasjonen
|
||
den ble bygget for, ikke bare i enhetstest.
|
||
|
||
---
|
||
|
||
## Ikke verifisert
|
||
|
||
1. **Lokal kjøring uten Azure.** Planen og STATE påsto at `azd ai agent run` mot `localhost:8088`
|
||
er testbart uten Azure. Learn sier det motsatte: kommandoen krever `azd auth login`, henter
|
||
miljøvariabler fra et azd-miljø, og «The local agent still calls cloud-hosted models».
|
||
`--local` sparer *deploy*, ikke *Azure*. **Dette er kostnadsrelevant og bør inn i planen.**
|
||
2. **`AZURE_AI_MODEL_DEPLOYMENT_NAME` injiseres ikke.** Bekreftet injisert:
|
||
`FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_PROJECT_ARM_ID`, `FOUNDRY_AGENT_NAME`,
|
||
`FOUNDRY_AGENT_VERSION`, `FOUNDRY_AGENT_SESSION_ID`, `FOUNDRY_AGENT_ID`,
|
||
`APPLICATIONINSIGHTS_CONNECTION_STRING`, `FOUNDRY_HOSTING_ENVIRONMENT`, `HOME`, `PORT`.
|
||
Modelldeployment-navnet deklarerer vi selv. `FOUNDRY_PROJECT_ENDPOINT` skal **ikke** redeklareres
|
||
i `azure.yaml` — det risikerer å skygge plattformens verdi. Kilden til vår antakelse var
|
||
MAF-hostingsiden, som motsier plattformdoksettet og Microsofts eget sample.
|
||
3. **Rollen for deploy er `Foundry Project Manager` på prosjekt-scope**, ikke `Foundry User` som
|
||
1b-forberedelsen bruker. De to er ulike oppgaver (kjøre modellkall vs. deploye en agent) og bør
|
||
ikke blandes.
|
||
4. **Protokollversjon i `azure.yaml`: `1.0.0` eller `2.0.0`.** Learn viser begge i samme doksett.
|
||
Container-protokoll 2.0.0 er separat fra protokoll-versjonsfeltet, og 1.0.0 er deprekert med
|
||
blokkering etter fristen. Må avklares mot JSON-skjemaet før vi skriver fila.
|
||
5. **`env:`-map vs `environmentVariables:`-liste**, og **`language: docker` vs `language: python`**
|
||
— Learn og samplet er uenige, og skjemafila er ikke lest.
|
||
6. **Påkrevd vs valgfritt felt-for-felt** for `azure.ai.agent`-tjenesten. Learns tabell har ingen
|
||
Required-kolonne; autoriteten er `schemas/v1.0/azure.yaml.json`, som ikke er lest.
|
||
7. **Ikke-root-krav** finnes ikke dokumentert, og Microsofts sample kjører som root uten `USER`.
|
||
Fravær av dokumentasjon er ikke en garanti.
|
||
8. **`agent-framework-foundry-hosting` er ikke installert**, og import-stien er omstridt:
|
||
Learn bruker `agent_framework_foundry_hosting`, et MAF-sample bruker `agent_framework.foundry`.
|
||
Vår installerte 1.8.2 eksporterer ingen av host-server-klassene. Siste PyPI-versjon er
|
||
`1.0.0b260730` — **ingen stabil release finnes.**
|
||
9. **Kompatibilitet** mellom hosting-pakka og `agent-framework-core` 1.9.0 er ikke testet.
|
||
10. **Foundry Agent Service i Norway East** — regionslista inkluderer den, men modell- og
|
||
kvotedekning per region er ikke sjekket.
|
||
|
||
---
|
||
|
||
## 8. Hvorfor eldre oppskrifter ikke kan brukes
|
||
|
||
Foundry har byttet hostingbackend. Det gamle public-preview-backendet er under avvikling
|
||
(<https://learn.microsoft.com/azure/foundry/agents/how-to/migrate-hosted-agent-preview>):
|
||
|
||
> «The initial public preview hosting backend is retiring. … Existing agent deployments on the old
|
||
> backend aren't migrated automatically and are supported only until August 20, 2026.»
|
||
|
||
**Dette er ingen frist for oss** — vi har aldri deployet, og har derfor ingenting å migrere. Det er
|
||
en *dateringsregel*: en blogg, oppskrift eller Learn-side skrevet mot det gamle backendet beskriver
|
||
en flate som ikke lenger er den vi bygger mot, uansett hvor godt den er skrevet. Konkret er tre
|
||
ting fra den epoken allerede ugyldige: `agent.manifest.yaml`/`agent.yaml` (§1.2),
|
||
`Foundry-Features: HostedAgents=V1Preview`-headeren, og protokollversjonsformatet `"v1"`.
|
||
|
||
Alt materialet i denne rapporten er hentet mot det gjeldende backendet. Det er også grunnen til at
|
||
rapporten siterer URL og dato på hver påstand i stedet for å oppsummere: neste økt skal kunne se
|
||
hva som var sant da, ikke bare hva jeg konkluderte.
|