Adds engine and chat tools for registering, discovering, and viewing artifacts with inbox notifications. - Add fn_artifact_register, fn_artifact_list, and fn_artifact_view tools for heartbeat, executor, and chat sessions. - Send best-effort dashboard system inbox notifications when artifacts are registered. - Classify artifact tools for action gating and coordination exemptions, with coverage for executor, heartbeat, permanent agent, and chat flows. - Document the artifact registry behavior and update package metadata, quarantine ledger, and line-count baseline. Files changed: .changeset/fn-6778-artifact-agent-tools.md | 5 + CONCEPTS.md | 3 + docs/agents.md | 1 + packages/core/src/db.ts | 1 + .../src/__tests__/session-error-recovery.test.ts | 1 + .../session-persistence-roundtrip.test.ts | 1 + .../src/__tests__/session-reconnect.test.ts | 1 + .../src/__tests__/session-resume-history.test.ts | 1 + packages/dashboard/src/chat.ts | 6 +- packages/dashboard/src/planning.ts | 4 + packages/dashboard/src/test/mockCoreEngine.ts | 1 + .../engine/src/__tests__/agent-action-gate.test.ts | 3 + .../src/__tests__/agent-artifact-tools.test.ts | 458 +++++++++++++++++++++ .../src/__tests__/executor-step-session.test.ts | 48 +++ .../src/__tests__/gating-classifications.test.ts | 3 + .../src/__tests__/heartbeat-executor.test.ts | 40 +- .../src/__tests__/heartbeat-session-prompt.test.ts | 25 +- .../src/__tests__/permanent-agent-gating.test.ts | 6 + packages/engine/src/agent-heartbeat.ts | 6 +- packages/engine/src/agent-tools.ts | 288 ++++++++++++- packages/engine/src/executor.ts | 25 ++ packages/engine/src/gating-classifications.ts | 7 + packages/engine/src/index.ts | 9 + scripts/lib/test-quarantine.json | 8 +- scripts/line-count-baseline.json | 54 +-- 25 files changed, 945 insertions(+), 60 deletions(-) Fusion-Task-Id: FN-6778 Fusion-Task-Lineage: 7eb4afcb-8140-4f86-9540-eb3b83e64148
76 lines
2.8 KiB
TypeScript
76 lines
2.8 KiB
TypeScript
/**
|
|
* Canonical @fusion/core and @fusion/engine mock helpers for dashboard server tests.
|
|
*
|
|
* If a route test starts failing with "No \"X\" export is defined", update this
|
|
* helper first instead of adding another full inline export map in the test file.
|
|
*/
|
|
import { vi, type Mock } from "vitest";
|
|
|
|
type AnyModule = Record<string, unknown>;
|
|
type AnyMock = Mock;
|
|
|
|
const fallbackFns = new Map<string, AnyMock>();
|
|
|
|
function getFallback(name: string): AnyMock {
|
|
if (!fallbackFns.has(name)) fallbackFns.set(name, vi.fn());
|
|
return fallbackFns.get(name)!;
|
|
}
|
|
|
|
function withFallbackFunctions(actual: AnyModule, moduleValue: AnyModule): AnyModule {
|
|
return new Proxy(moduleValue, {
|
|
get(target, prop, receiver) {
|
|
if (typeof prop !== "string") return Reflect.get(target, prop, receiver);
|
|
if (Reflect.has(target, prop)) return Reflect.get(target, prop, receiver);
|
|
if (["then", "catch", "finally"].includes(prop)) return undefined;
|
|
|
|
const actualValue = actual[prop];
|
|
if (typeof actualValue === "function" || actualValue === undefined) {
|
|
const fn = getFallback(prop);
|
|
target[prop] = fn;
|
|
return fn;
|
|
}
|
|
return actualValue;
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function createCoreMock(
|
|
importActual: () => Promise<AnyModule>,
|
|
overrides: AnyModule = {},
|
|
): Promise<AnyModule> {
|
|
const actual = await importActual();
|
|
return withFallbackFunctions(actual, { ...actual, ...overrides });
|
|
}
|
|
|
|
export function createEngineMock(overrides: AnyModule = {}): AnyModule {
|
|
const actual: AnyModule = {};
|
|
return withFallbackFunctions(actual, {
|
|
createFnAgent: vi.fn(),
|
|
promptWithFallback: vi.fn(),
|
|
/*
|
|
FNXC:TestSkills 2026-06-17-19:33:
|
|
Dashboard route tests mock @fusion/engine wholesale, so skill-aware planning lanes need a shaped session-skill helper result instead of the fallback vi.fn() returning undefined.
|
|
*/
|
|
buildSessionSkillContextSync: vi.fn(() => ({
|
|
skillSelectionContext: undefined,
|
|
resolvedSkillNames: [],
|
|
skillSource: "none" as const,
|
|
})),
|
|
// Returns an iterable tool list; dashboard code spreads its result
|
|
// (`...createWorkflowAuthoringTools(...)`), so it must not be undefined.
|
|
createWorkflowAuthoringTools: vi.fn(() => []),
|
|
/*
|
|
FNXC:DashboardRouteTests 2026-06-18-09:07:
|
|
Planning and chat route files can share worker-level @fusion/engine mocks during broad dashboard API quality runs.
|
|
Keep chat task document tools iterable by default so rescuing chat-routes from quarantine does not poison planning route imports with a fallback vi.fn() result.
|
|
*/
|
|
createChatTaskDocumentTools: vi.fn(() => []),
|
|
createChatArtifactTools: vi.fn(() => []),
|
|
...overrides,
|
|
});
|
|
}
|
|
|
|
export function resetDashboardServerMockState(): void {
|
|
for (const fn of fallbackFns.values()) fn.mockReset();
|
|
}
|