Files
wehub-resource-sync 426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

161 lines
5.6 KiB
TypeScript

/**
* Live e2e for the Ollama plugin's MODEL_USED telemetry path.
*
* Skip gate: requires `OLLAMA_API_ENDPOINT` (or `OLLAMA_API_URL`) pointing at a
* reachable Ollama server. Set e.g. `OLLAMA_API_ENDPOINT=http://localhost:11434`
* and run `ollama create eliza-1-2b -f packages/training/cloud/ollama/Modelfile.eliza-1-2b-q4_k_m` (or set `OLLAMA_SMALL_MODEL` /
* `OLLAMA_EMBEDDING_MODEL` to models you already have) to enable.
*/
import type { IAgentRuntime } from "@elizaos/core";
import { ModelType, runWithTrajectoryContext } from "@elizaos/core";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
const YELLOW = "\x1b[33m";
const RESET = "\x1b[0m";
const OLLAMA_ENDPOINT =
process.env.OLLAMA_API_ENDPOINT?.trim() || process.env.OLLAMA_API_URL?.trim() || "";
const OLLAMA_SMALL_MODEL = process.env.OLLAMA_SMALL_MODEL?.trim() || "eliza-1-2b";
const OLLAMA_EMBEDDING_MODEL = process.env.OLLAMA_EMBEDDING_MODEL?.trim() || "eliza-1-2b";
type MinimalRuntime = {
character: { system: string };
emitEvent: (event: string, payload: unknown) => Promise<void>;
fetch: typeof fetch;
getSetting: (key: string) => string | null;
getService?: (name: string) => unknown;
getServicesByType?: (type: string) => unknown[];
emittedEvents: Array<{ event: string; payload: Record<string, unknown> }>;
};
function createRuntime(extra: Record<string, string> = {}): MinimalRuntime {
const settings: Record<string, string> = {
OLLAMA_API_ENDPOINT: OLLAMA_ENDPOINT,
OLLAMA_SMALL_MODEL,
OLLAMA_LARGE_MODEL: OLLAMA_SMALL_MODEL,
OLLAMA_EMBEDDING_MODEL,
...extra,
};
const emittedEvents: MinimalRuntime["emittedEvents"] = [];
return {
character: { system: "You are a concise test agent. Reply briefly." },
emitEvent: async (event: string, payload: unknown) => {
emittedEvents.push({ event, payload: payload as Record<string, unknown> });
},
fetch: globalThis.fetch.bind(globalThis),
getSetting: (key: string) => settings[key] ?? null,
emittedEvents,
};
}
async function pingOllama(endpoint: string): Promise<boolean> {
const base = endpoint.replace(/\/api\/?$/, "").replace(/\/$/, "");
try {
const res = await fetch(`${base}/api/tags`, {
method: "GET",
signal: AbortSignal.timeout(2000),
});
return res.ok;
} catch {
return false;
}
}
const skipReason = !OLLAMA_ENDPOINT
? "OLLAMA_API_ENDPOINT not set (set OLLAMA_API_ENDPOINT=http://localhost:11434 and `ollama create eliza-1-2b -f packages/training/cloud/ollama/Modelfile.eliza-1-2b-q4_k_m` to enable)"
: null;
if (skipReason) {
process.env.SKIP_REASON ||= skipReason;
console.warn(`${YELLOW}[ollama-live] skipped — ${skipReason}${RESET}`);
}
describe.skipIf(skipReason !== null)("ollama MODEL_USED events (live)", () => {
let serverReachable = false;
beforeAll(async () => {
serverReachable = await pingOllama(OLLAMA_ENDPOINT);
if (!serverReachable) {
console.warn(
`${YELLOW}[ollama-live] OLLAMA_API_ENDPOINT=${OLLAMA_ENDPOINT} unreachable — tests will skip${RESET}`
);
}
}, 5000);
it("emits MODEL_USED with real prompt/completion token counts for TEXT_SMALL", async () => {
if (!serverReachable) return;
const { default: plugin } = await import("../index");
const runtime = createRuntime();
const result = await plugin.models?.[ModelType.TEXT_SMALL]?.(runtime as IAgentRuntime, {
prompt: "Reply with exactly two words: hello there",
});
expect(typeof result === "string" || (typeof result === "object" && result !== null)).toBe(
true
);
const modelUsed = runtime.emittedEvents.find((e) => e.event === "MODEL_USED");
expect(modelUsed).toBeDefined();
expect(modelUsed?.payload).toMatchObject({
source: "ollama",
type: "TEXT_SMALL",
model: OLLAMA_SMALL_MODEL,
});
const tokens = modelUsed?.payload?.tokens as {
prompt: number;
completion: number;
total: number;
};
expect(tokens.prompt).toBeGreaterThan(0);
expect(tokens.completion).toBeGreaterThan(0);
expect(tokens.total).toBeGreaterThanOrEqual(tokens.prompt + tokens.completion);
}, 60_000);
it("records structured-output generation via TEXT_LARGE in active trajectories", async () => {
if (!serverReachable) return;
const { default: plugin } = await import("../index");
const llmCalls: Record<string, unknown>[] = [];
const trajectoryLogger = {
isEnabled: () => true,
logLlmCall: (call: Record<string, unknown>) => {
llmCalls.push(call);
},
};
const baseRuntime = createRuntime();
const runtime = {
...baseRuntime,
getService: (name: string) => (name === "trajectories" ? trajectoryLogger : null),
getServicesByType: (type: string) => (type === "trajectories" ? [trajectoryLogger] : []),
};
await runWithTrajectoryContext({ trajectoryStepId: "step-ollama-live" }, async () => {
await plugin.models?.[ModelType.TEXT_LARGE]?.(
runtime as IAgentRuntime,
{
prompt: 'Return JSON {"ok": true}. Reply with only the JSON, no commentary.',
responseSchema: {
type: "object",
properties: { ok: { type: "boolean" } },
required: ["ok"],
},
} as never
);
});
expect(llmCalls.length).toBeGreaterThanOrEqual(1);
const call = llmCalls[0];
expect(call).toMatchObject({
stepId: "step-ollama-live",
});
expect(typeof call.actionType).toBe("string");
expect((call.promptTokens as number) ?? 0).toBeGreaterThan(0);
}, 60_000);
afterAll(() => {
// The runtime is in-memory and the harness has no resources to release.
});
});