吸收数字员工入口路由策略下发

This commit is contained in:
baiyanyun
2026-06-11 17:44:16 +08:00
parent 43418d0453
commit d292c34579
16 changed files with 1195 additions and 190 deletions

View File

@@ -137,6 +137,77 @@ describe("digital employee sync service", () => {
});
});
it("pulls remote route decision policy and records policy state", async () => {
mockState.fetch.mockResolvedValue(
jsonResponse({
success: true,
data: {
routeDecisionPolicy: {
enabled: true,
autoCreateGovernanceCommands: false,
approvalRequiredIntents: ["Execute"],
blockedIntents: ["Schedule"],
preferredRouteKinds: ["PlanExecution"],
updatedAt: "2026-06-07T08:02:00.000Z",
},
},
}),
);
const { pullDigitalEmployeeRouteDecisionPolicy } = await import("./syncService");
const { readDigitalEmployeeUiState } = await import("./stateService");
const result = await pullDigitalEmployeeRouteDecisionPolicy({ force: true });
expect(result).toMatchObject({
ok: true,
endpoint: "https://manage.example.com/api/digital-employee/policies/route-decision",
policy: {
source: "remote",
enabled: true,
auto_create_governance_commands: false,
approval_required_intents: ["execute"],
blocked_intents: ["schedule"],
preferred_route_kinds: ["PlanExecution"],
remote_updated_at: "2026-06-07T08:02:00.000Z",
last_pulled_at: "2026-06-07T08:00:00.000Z",
last_pull_error: null,
},
});
expect(mockState.fetch).toHaveBeenCalledWith(
"https://manage.example.com/api/digital-employee/policies/route-decision",
expect.objectContaining({ method: "GET" }),
);
expect(readDigitalEmployeeUiState().routeDecisionPolicy).toMatchObject(result.policy);
expect(Array.from(mockState.db?.events.values() ?? [])).toEqual(expect.arrayContaining([
expect.objectContaining({ kind: "digital_workday_pull_route_decision_policy" }),
]));
});
it("keeps the current route decision policy when remote policy pull fails", async () => {
mockState.fetch.mockResolvedValue({
ok: false,
status: 503,
text: vi.fn().mockResolvedValue(JSON.stringify({ message: "route policy unavailable" })),
} as unknown as Response);
const { pullDigitalEmployeeRouteDecisionPolicy } = await import("./syncService");
const result = await pullDigitalEmployeeRouteDecisionPolicy({ force: true });
expect(result).toMatchObject({
ok: false,
error: "route policy unavailable",
policy: {
source: "local",
enabled: true,
auto_create_governance_commands: true,
blocked_intents: [],
approval_required_intents: [],
last_pulled_at: "2026-06-07T08:00:00.000Z",
last_pull_error: "route policy unavailable",
},
});
});
it("pulls remote skill policies and preserves local skill preferences", async () => {
mockState.settings.set("digital_employee_skill_policies_v1", {
version: 1,
@@ -947,6 +1018,10 @@ describe("digital employee sync service", () => {
reason_codes: ["ready_plan_step"],
candidate_skills: ["crm-search"],
created_command_id: "governance-command-1",
policy_source: "remote",
blocked_reason: null,
approval_id: "route-approval-1",
matched_intent: "schedule",
},
});
insertEventEntity("event-approval", "approval_action_recorded", {
@@ -1235,6 +1310,9 @@ describe("digital employee sync service", () => {
reason_codes: ["ready_plan_step"],
candidate_skills: ["crm-search"],
created_command_id: "governance-command-1",
policy_source: "remote",
approval_id: "route-approval-1",
matched_intent: "schedule",
attention_level: "action",
});
expect(businessView("event-approval")).toMatchObject({