feat: release v1.0.1 CADWorld 网站与 LeKiwi 智能抓放
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (pull_request) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (pull_request) Has been cancelled
web-platform-ci / Playwright E2E (pull_request) Has been cancelled
lekiwi-compatibility / cpu-compatibility (pull_request) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (pull_request) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (pull_request) Has been cancelled
web-platform-ci / Playwright E2E (pull_request) Has been cancelled
lekiwi-compatibility / cpu-compatibility (pull_request) Has been cancelled
集成同源 BYOK 会话隔离、精简模型设置、官方订阅入口和 HTTPS 发布运维;保留本地训练/调参与控制能力。同步 npm 版本及 CHANGELOG,记录公网真实 API 验收仍待用户凭据。
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { resolve } from 'node:path';
|
||||
import { writeFile } from 'node:fs/promises';
|
||||
import type {} from '../physics/agent';
|
||||
|
||||
for (const fault of [
|
||||
'empty-grasp',
|
||||
'empty-once',
|
||||
'alignment',
|
||||
'slip',
|
||||
'jam',
|
||||
'navigation',
|
||||
'unreachable',
|
||||
'overspeed',
|
||||
] as const) {
|
||||
test(`真实 WASM 故障:${fault} 不可冒充成功/无限恢复`, async ({ page }, info) => {
|
||||
await page.goto('/physics/agent.html');
|
||||
await page.waitForFunction(() => Boolean(window.lekiwiAgent));
|
||||
await page.evaluate(
|
||||
(url) => window.lekiwiAgent.boot(url),
|
||||
`/@fs${resolve('build/lekiwi/lekiwi-v1.zip')}`,
|
||||
);
|
||||
try {
|
||||
const r = await page.evaluate(
|
||||
(fault) => window.lekiwiAgent.task(0, undefined, { fault }),
|
||||
fault,
|
||||
);
|
||||
await writeFile(info.outputPath('fault-evidence.json'), JSON.stringify(r, null, 2));
|
||||
console.log('WASM fault', {
|
||||
fault,
|
||||
state: r.state,
|
||||
error: r.error,
|
||||
failures: r.failures,
|
||||
recoveries: r.recoveries,
|
||||
simTime: r.simTime,
|
||||
});
|
||||
expect(r.mode).toBe('mock');
|
||||
expect(r.state).toBe(fault === 'empty-once' ? 'succeeded' : 'failed');
|
||||
expect(r.succeeded).toBe(fault === 'empty-once');
|
||||
expect(r.simTime).toBeLessThanOrEqual(70.01);
|
||||
expect(r.llmCalls).toBe(1);
|
||||
if (fault === 'empty-grasp' || fault === 'empty-once' || fault === 'alignment') {
|
||||
const skill = fault === 'alignment' ? 'pregrasp' : 'close';
|
||||
const code = fault === 'alignment' ? 'alignment_timeout' : 'empty_grasp';
|
||||
const recovered = fault === 'empty-once';
|
||||
expect(r.recoveries[skill]).toBe(recovered ? 1 : 2);
|
||||
expect(r.failures.map((f) => f.code)).toEqual(Array(recovered ? 1 : 3).fill(code));
|
||||
if (!recovered) expect(r.trace.every((s) => !s.secure)).toBe(true);
|
||||
else {
|
||||
expect(r.transported).toBeGreaterThanOrEqual(0.5);
|
||||
expect(r.sample.onGoalSupport).toBe(true);
|
||||
}
|
||||
} else {
|
||||
expect(r.recoveries).toEqual({});
|
||||
expect(r.failures).toHaveLength(1);
|
||||
expect(r.failures[0].code).toBe(
|
||||
{
|
||||
slip: 'lost_grasp',
|
||||
jam: 'joint_stall',
|
||||
navigation: 'navigation_timeout',
|
||||
unreachable: 'unreachable',
|
||||
overspeed: 'joint_velocity',
|
||||
}[fault],
|
||||
);
|
||||
}
|
||||
if (fault === 'slip') {
|
||||
expect(Math.max(...r.trace.map((s) => s.transported))).toBeGreaterThan(0.12);
|
||||
expect(r.transported).toBe(0);
|
||||
}
|
||||
} finally {
|
||||
await page.evaluate(() => window.lekiwiAgent.dispose());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (const goal of [
|
||||
[0.237, 0.565, 0.128],
|
||||
[0.277, 0.665, 0.128],
|
||||
]) {
|
||||
test(`真实 WASM 受限目标角点 ${goal.slice(0, 2).join(',')}(非任意目标泛化)`, async ({
|
||||
page,
|
||||
}, info) => {
|
||||
await page.goto('/physics/agent.html');
|
||||
await page.waitForFunction(() => Boolean(window.lekiwiAgent));
|
||||
await page.evaluate(
|
||||
(url) => window.lekiwiAgent.boot(url),
|
||||
`/@fs${resolve('build/lekiwi/lekiwi-v1.zip')}`,
|
||||
);
|
||||
try {
|
||||
const r = await page.evaluate(
|
||||
(goal) => window.lekiwiAgent.task(0, undefined, { goal }),
|
||||
goal,
|
||||
);
|
||||
await writeFile(info.outputPath('goal-evidence.json'), JSON.stringify(r, null, 2));
|
||||
expect(r.state, r.error).toBe('succeeded');
|
||||
expect(r.goal).toEqual(goal);
|
||||
expect(r.succeeded).toBe(true);
|
||||
expect(r.transported).toBeGreaterThanOrEqual(0.5);
|
||||
expect(Math.hypot(...r.sample.object.map((v, i) => v - goal[i]))).toBeLessThan(0.04);
|
||||
} finally {
|
||||
await page.evaluate(() => window.lekiwiAgent.dispose());
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user