fix: serve a deterministic internal embedding fixture for P2 acceptance

This commit is contained in:
2026-08-11 19:12:37 +02:00
parent 62d05aa614
commit e34b756052
+37 -7
View File
@@ -766,26 +766,32 @@ async function writeInstallationFiles(ctx) {
].join("\n") + "\n";
await atomicWrite(operatorEnvPath, operatorEnv);
await atomicWrite(join(ctx.run.root, "installation", "pi-auth.json"), JSON.stringify({ fixture: true }));
const embeddingStubPath = join(installationDir, "embedding-stub.py");
await atomicWrite(embeddingStubPath, EMBEDDING_STUB_SOURCE);
const override = {
services: {
core: {
image: ctx.coreImageTag,
environment: {
THT_INTERNAL_EMBEDDING_URL: `http://host.docker.internal:${ctx.fixturePorts.embedding}`,
},
extra_hosts: ["host.docker.internal:host-gateway"],
},
"workspace-maintenance": {
image: ctx.coreImageTag,
environment: {
THT_INTERNAL_EMBEDDING_URL: `http://host.docker.internal:${ctx.fixturePorts.embedding}`,
},
extra_hosts: ["host.docker.internal:host-gateway"],
},
qdrant: {
ports: [`127.0.0.1:${qdrantPort}:6333`],
restart: "no",
},
// Deterministic Ollama-compatible embedding fixture on the internal allowlisted host
// name `embedding` (http://embedding:11434). Replaces the real Ollama service entirely.
embedding: {
image: ctx.coreImageTag,
entrypoint: ["python3", "/stub.py"],
volumes: [
{ type: "bind", source: embeddingStubPath, target: "/stub.py", read_only: true },
],
healthcheck: { disable: true },
},
},
};
await atomicWrite(fixtureOverridePath, yamlStringify(override, { lineWidth: 0, sortMapEntries: false }));
@@ -888,7 +894,7 @@ async function dockerCompose(ctx, commandArgs, { allowFailure = false, maxOutput
}
async function startQdrant(ctx) {
await dockerCompose(ctx, ["up", "-d", "qdrant"]);
await dockerCompose(ctx, ["up", "-d", "qdrant", "embedding"]);
for (let attempt = 0; attempt < 60; attempt += 1) {
try {
const response = await fetch(`http://127.0.0.1:${ctx.fixturePorts.qdrant}/collections`);
@@ -972,6 +978,30 @@ function sameSet(left, right) {
return JSON.stringify([...left].sort()) === JSON.stringify([...right].sort());
}
const EMBEDDING_STUB_SOURCE = String.raw`import json
from http.server import BaseHTTPRequestHandler, HTTPServer
class _Handler(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("Content-Length", "0"))
payload = json.loads(self.rfile.read(length))
inputs = payload.get("input", [])
if isinstance(inputs, str):
inputs = [inputs]
embeddings = [[0.01] * 1024 for _ in inputs]
body = json.dumps({"model": payload.get("model", "qwen3-embedding:0.6b"), "embeddings": embeddings}).encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, *args):
pass
HTTPServer(("0.0.0.0", 11434), _Handler).serve_forever()
`;
function realUserHome() {
try {
const output = execFileSync("bash", ["-lc", 'printf "%s" ~'], { encoding: "utf8" }).trim();