Files
moltbot/src/trajectory/metadata.test.ts
Vincent Koc cb4fc58547 feat(plugins): move Bonjour discovery into bundled plugin
* fix(deps): detect constant dynamic imports in ownership audit

* feat(plugins): move bonjour discovery into bundled plugin

* test(plugins): remove moved bonjour core tests

* fix(plugins): harden bonjour disable and console restore

* fix(plugins): split gateway discovery ids from services

* fix(plugins): harden bonjour advertiser shutdown

* fix(plugins): clean up bonjour split lint
2026-04-23 23:29:51 -07:00

204 lines
6.1 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from "vitest";
import { REDACTED_SENTINEL } from "../config/redact-snapshot.js";
import { createEmptyPluginRegistry } from "../plugins/registry-empty.js";
import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../plugins/runtime.js";
const loadPluginManifestRegistry = vi.hoisted(() => vi.fn(() => ({ plugins: [] })));
vi.mock("../infra/git-commit.js", () => ({
resolveCommitHash: () => "abcdef0",
}));
vi.mock("../infra/os-summary.js", () => ({
resolveOsSummary: () => ({
platform: "darwin",
arch: "arm64",
release: "test-release",
label: "test-os",
}),
}));
vi.mock("../plugins/manifest-registry.js", () => ({
loadPluginManifestRegistry,
}));
import { buildTrajectoryArtifacts, buildTrajectoryRunMetadata } from "./metadata.js";
afterEach(() => {
resetPluginRuntimeStateForTest();
});
describe("trajectory metadata", () => {
it("redacts harness argv and local paths with the support redaction rules", () => {
const originalArgv = process.argv;
process.argv = [
"node",
"/Users/tester/project/openclaw.js",
"--api-key",
"super-secret",
"--config=/Users/tester/.openclaw/openclaw.json",
];
try {
const metadata = buildTrajectoryRunMetadata({
env: {
HOME: "/Users/tester",
OPENCLAW_STATE_DIR: "/Users/tester/.openclaw",
},
workspaceDir: "/Users/tester/project",
sessionFile: "/Users/tester/project/session.jsonl",
timeoutMs: 30_000,
});
const harness = metadata.harness as {
invocation?: unknown[];
entrypoint?: string;
workspaceDir?: string;
sessionFile?: string;
};
expect(harness.invocation).toEqual([
"node",
"~/project/openclaw.js",
"--api-key",
"<redacted>",
"--config=$OPENCLAW_STATE_DIR/openclaw.json",
]);
expect(harness.entrypoint).toBe("~/project/openclaw.js");
expect(harness.workspaceDir).toBe("~/project");
expect(harness.sessionFile).toBe("~/project/session.jsonl");
} finally {
process.argv = originalArgv;
}
});
it("captures redacted config plus active plugin and skill inventory", () => {
const registry = createEmptyPluginRegistry();
registry.plugins.push({
id: "demo-plugin",
name: "Demo Plugin",
version: "1.2.3",
source: "bundled",
origin: "bundled",
enabled: true,
activated: true,
imported: true,
status: "loaded",
toolNames: ["demo_tool"],
hookNames: [],
channelIds: ["demo-channel"],
cliBackendIds: [],
providerIds: ["demo-provider"],
speechProviderIds: [],
realtimeTranscriptionProviderIds: [],
realtimeVoiceProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
musicGenerationProviderIds: [],
webFetchProviderIds: [],
webSearchProviderIds: [],
memoryEmbeddingProviderIds: [],
agentHarnessIds: ["pi"],
gatewayMethods: [],
cliCommands: [],
services: [],
gatewayDiscoveryServiceIds: [],
commands: [],
httpRoutes: 0,
hookCount: 0,
configSchema: false,
});
setActivePluginRegistry(registry, "trajectory-metadata-test");
const metadata = buildTrajectoryRunMetadata({
config: {
providers: {
openai: {
apiKey: "super-secret",
},
},
} as never,
workspaceDir: "/tmp/workspace",
sessionFile: "/tmp/workspace/session.jsonl",
sessionKey: "agent:main:test",
agentId: "main",
trigger: "user",
provider: "openai",
modelId: "gpt-5.4",
modelApi: "responses",
timeoutMs: 30_000,
reasoningLevel: "high",
skillsSnapshot: {
prompt: "skill prompt",
version: 1,
skills: [{ name: "weather" }],
resolvedSkills: [
{
name: "weather",
description: "Check weather",
filePath: "/tmp/workspace/skills/weather/SKILL.md",
baseDir: "/tmp/workspace/skills/weather",
source: "workspace",
sourceInfo: {
path: "/tmp/workspace/skills/weather/SKILL.md",
source: "workspace",
scope: "project",
origin: "top-level",
baseDir: "/tmp/workspace/skills/weather",
},
disableModelInvocation: false,
},
],
},
userPromptPrefixText: "prefix",
});
const config = metadata.config as {
redacted?: { providers?: { openai?: { apiKey?: string } } };
};
const plugins = metadata.plugins as { source?: string; entries?: Array<{ id: string }> };
const skills = metadata.skills as { entries?: Array<{ id: string; filePath?: string }> };
expect(config.redacted?.providers?.openai?.apiKey).toBe(REDACTED_SENTINEL);
expect(plugins.source).toBe("active-registry");
expect(plugins.entries?.map((entry) => entry.id)).toEqual(["demo-plugin"]);
expect(skills.entries?.[0]).toMatchObject({
id: "weather",
filePath: "/tmp/workspace/skills/weather/SKILL.md",
});
});
it("captures final artifact summaries for export sidecars", () => {
const artifacts = buildTrajectoryArtifacts({
status: "success",
aborted: false,
externalAbort: false,
timedOut: false,
idleTimedOut: false,
timedOutDuringCompaction: false,
compactionCount: 1,
assistantTexts: ["done"],
finalPromptText: "run tests",
itemLifecycle: {
startedCount: 2,
completedCount: 2,
activeCount: 0,
},
toolMetas: [{ toolName: "bash", meta: "npm test" }],
didSendViaMessagingTool: false,
successfulCronAdds: 0,
messagingToolSentTexts: [],
messagingToolSentMediaUrls: [],
messagingToolSentTargets: [],
});
expect(artifacts).toMatchObject({
finalStatus: "success",
assistantTexts: ["done"],
itemLifecycle: {
startedCount: 2,
completedCount: 2,
activeCount: 0,
},
});
});
});