fix(hli): add 14 stub routes (501) for SkyEye route coverage 17/17 [AG-ZY-095]
- 14 HLI schema stubs in src/schemas/hli/{persona,user,ticket,dialogue,storage,dashboard}/
- 6 stub handler files in exe-engine/src/router/stubs/
- Registered in AGE-Router with handleStubRoute() + getHLIStubs()
- 157 stub tests passing in exe-engine/tests/stubs/
- Route alignment check: 17/17 PASSED
Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/b28b8dfa-b45c-49b8-812f-cd1924e40762
This commit is contained in:
parent
2194be41b4
commit
7146677f71
|
|
@ -8,6 +8,14 @@
|
|||
|
||||
const { randomUUID } = require('crypto');
|
||||
|
||||
// HLI 501 存根路由(Phase 0 占位,后续 Phase 实现)
|
||||
const { personaStubs } = require('./stubs/persona-stub');
|
||||
const { userStubs } = require('./stubs/user-stub');
|
||||
const { ticketStubs } = require('./stubs/ticket-stub');
|
||||
const { dialogueStubs } = require('./stubs/dialogue-stub');
|
||||
const { storageStubs } = require('./stubs/storage-stub');
|
||||
const { dashboardStubs } = require('./stubs/dashboard-stub');
|
||||
|
||||
/**
|
||||
* AGE-Router 路由网关
|
||||
*
|
||||
|
|
@ -38,6 +46,16 @@ class AGERouter {
|
|||
|
||||
// 限流计数器 { agentId: { count, resetAt } }
|
||||
this._rateLimits = new Map();
|
||||
|
||||
// HLI 存根路由注册表(天眼路由扫描识别用)
|
||||
this._hliStubs = [
|
||||
...personaStubs,
|
||||
...userStubs,
|
||||
...ticketStubs,
|
||||
...dialogueStubs,
|
||||
...storageStubs,
|
||||
...dashboardStubs
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -161,10 +179,35 @@ class AGERouter {
|
|||
adapters: this._loadBalancer.getStatus(),
|
||||
meter: this._resourceMeter.getSummary(),
|
||||
cache: this._contextCache.getStatus(),
|
||||
agents: this._agentController.getRegisteredAgents()
|
||||
agents: this._agentController.getRegisteredAgents(),
|
||||
hliStubs: this._hliStubs.map(s => ({
|
||||
routeId: s.routeId,
|
||||
path: s.path,
|
||||
phase: s.phase,
|
||||
status: 'stub_501'
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 HLI 存根路由请求
|
||||
* @param {string} routePath 路由路径(如 /hli/persona/load)
|
||||
* @returns {object|null} 501 响应,不匹配返回 null
|
||||
*/
|
||||
async handleStubRoute(routePath) {
|
||||
const stub = this._hliStubs.find(s => s.path === routePath);
|
||||
if (!stub) return null;
|
||||
return stub.handler({});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有已注册的 HLI 存根路由
|
||||
* @returns {Array}
|
||||
*/
|
||||
getHLIStubs() {
|
||||
return this._hliStubs;
|
||||
}
|
||||
|
||||
// ── 内部方法 ──
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
// exe-engine/src/router/stubs/dashboard-stub.js
|
||||
// HLI 存根路由 · DASHBOARD 域
|
||||
// 501 占位 — Phase 0 骨架,P3 实现
|
||||
// PRJ-EXE-001 · 版权:国作登字-2026-A-00037559
|
||||
|
||||
'use strict';
|
||||
|
||||
function createStubHandler(routeId, routePath, targetPhase) {
|
||||
return async (req) => {
|
||||
return {
|
||||
statusCode: 501,
|
||||
body: {
|
||||
status: 'not_implemented',
|
||||
routeId,
|
||||
path: routePath,
|
||||
phase: targetPhase,
|
||||
message: `Route ${routePath} is planned for ${targetPhase}. Current: Phase 0.`
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const dashboardStubs = [
|
||||
{
|
||||
routeId: 'HLI-DASHBOARD-001',
|
||||
path: '/hli/dashboard/status',
|
||||
phase: 'P3',
|
||||
handler: createStubHandler('HLI-DASHBOARD-001', '/hli/dashboard/status', 'P3')
|
||||
},
|
||||
{
|
||||
routeId: 'HLI-DASHBOARD-002',
|
||||
path: '/hli/dashboard/realtime',
|
||||
phase: 'P3',
|
||||
handler: createStubHandler('HLI-DASHBOARD-002', '/hli/dashboard/realtime', 'P3')
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = { dashboardStubs, createStubHandler };
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// exe-engine/src/router/stubs/dialogue-stub.js
|
||||
// HLI 存根路由 · DIALOGUE 域
|
||||
// 501 占位 — Phase 0 骨架,P1 实现
|
||||
// PRJ-EXE-001 · 版权:国作登字-2026-A-00037559
|
||||
|
||||
'use strict';
|
||||
|
||||
function createStubHandler(routeId, routePath, targetPhase) {
|
||||
return async (req) => {
|
||||
return {
|
||||
statusCode: 501,
|
||||
body: {
|
||||
status: 'not_implemented',
|
||||
routeId,
|
||||
path: routePath,
|
||||
phase: targetPhase,
|
||||
message: `Route ${routePath} is planned for ${targetPhase}. Current: Phase 0.`
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const dialogueStubs = [
|
||||
{
|
||||
routeId: 'HLI-DIALOGUE-001',
|
||||
path: '/hli/dialogue/send',
|
||||
phase: 'P1',
|
||||
handler: createStubHandler('HLI-DIALOGUE-001', '/hli/dialogue/send', 'P1')
|
||||
},
|
||||
{
|
||||
routeId: 'HLI-DIALOGUE-002',
|
||||
path: '/hli/dialogue/stream',
|
||||
phase: 'P1',
|
||||
handler: createStubHandler('HLI-DIALOGUE-002', '/hli/dialogue/stream', 'P1')
|
||||
},
|
||||
{
|
||||
routeId: 'HLI-DIALOGUE-003',
|
||||
path: '/hli/dialogue/history',
|
||||
phase: 'P1',
|
||||
handler: createStubHandler('HLI-DIALOGUE-003', '/hli/dialogue/history', 'P1')
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = { dialogueStubs, createStubHandler };
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// exe-engine/src/router/stubs/persona-stub.js
|
||||
// HLI 存根路由 · PERSONA 域
|
||||
// 501 占位 — Phase 0 骨架,P1 实现
|
||||
// PRJ-EXE-001 · 版权:国作登字-2026-A-00037559
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* 创建 501 存根处理器
|
||||
* @param {string} routeId HLI 路由 ID
|
||||
* @param {string} routePath 路由路径
|
||||
* @param {string} targetPhase 目标实现阶段
|
||||
* @returns {Function} 处理器函数
|
||||
*/
|
||||
function createStubHandler(routeId, routePath, targetPhase) {
|
||||
return async (req) => {
|
||||
return {
|
||||
statusCode: 501,
|
||||
body: {
|
||||
status: 'not_implemented',
|
||||
routeId,
|
||||
path: routePath,
|
||||
phase: targetPhase,
|
||||
message: `Route ${routePath} is planned for ${targetPhase}. Current: Phase 0.`
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const personaStubs = [
|
||||
{
|
||||
routeId: 'HLI-PERSONA-001',
|
||||
path: '/hli/persona/load',
|
||||
phase: 'P1',
|
||||
handler: createStubHandler('HLI-PERSONA-001', '/hli/persona/load', 'P1')
|
||||
},
|
||||
{
|
||||
routeId: 'HLI-PERSONA-002',
|
||||
path: '/hli/persona/switch',
|
||||
phase: 'P1',
|
||||
handler: createStubHandler('HLI-PERSONA-002', '/hli/persona/switch', 'P1')
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = { personaStubs, createStubHandler };
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// exe-engine/src/router/stubs/storage-stub.js
|
||||
// HLI 存根路由 · STORAGE 域
|
||||
// 501 占位 — Phase 0 骨架,P2 实现
|
||||
// PRJ-EXE-001 · 版权:国作登字-2026-A-00037559
|
||||
|
||||
'use strict';
|
||||
|
||||
function createStubHandler(routeId, routePath, targetPhase) {
|
||||
return async (req) => {
|
||||
return {
|
||||
statusCode: 501,
|
||||
body: {
|
||||
status: 'not_implemented',
|
||||
routeId,
|
||||
path: routePath,
|
||||
phase: targetPhase,
|
||||
message: `Route ${routePath} is planned for ${targetPhase}. Current: Phase 0.`
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const storageStubs = [
|
||||
{
|
||||
routeId: 'HLI-STORAGE-001',
|
||||
path: '/hli/storage/upload',
|
||||
phase: 'P2',
|
||||
handler: createStubHandler('HLI-STORAGE-001', '/hli/storage/upload', 'P2')
|
||||
},
|
||||
{
|
||||
routeId: 'HLI-STORAGE-002',
|
||||
path: '/hli/storage/download',
|
||||
phase: 'P2',
|
||||
handler: createStubHandler('HLI-STORAGE-002', '/hli/storage/download', 'P2')
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = { storageStubs, createStubHandler };
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// exe-engine/src/router/stubs/ticket-stub.js
|
||||
// HLI 存根路由 · TICKET 域
|
||||
// 501 占位 — Phase 0 骨架,P2 实现
|
||||
// PRJ-EXE-001 · 版权:国作登字-2026-A-00037559
|
||||
|
||||
'use strict';
|
||||
|
||||
function createStubHandler(routeId, routePath, targetPhase) {
|
||||
return async (req) => {
|
||||
return {
|
||||
statusCode: 501,
|
||||
body: {
|
||||
status: 'not_implemented',
|
||||
routeId,
|
||||
path: routePath,
|
||||
phase: targetPhase,
|
||||
message: `Route ${routePath} is planned for ${targetPhase}. Current: Phase 0.`
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const ticketStubs = [
|
||||
{
|
||||
routeId: 'HLI-TICKET-001',
|
||||
path: '/hli/ticket/create',
|
||||
phase: 'P2',
|
||||
handler: createStubHandler('HLI-TICKET-001', '/hli/ticket/create', 'P2')
|
||||
},
|
||||
{
|
||||
routeId: 'HLI-TICKET-002',
|
||||
path: '/hli/ticket/query',
|
||||
phase: 'P2',
|
||||
handler: createStubHandler('HLI-TICKET-002', '/hli/ticket/query', 'P2')
|
||||
},
|
||||
{
|
||||
routeId: 'HLI-TICKET-003',
|
||||
path: '/hli/ticket/status',
|
||||
phase: 'P2',
|
||||
handler: createStubHandler('HLI-TICKET-003', '/hli/ticket/status', 'P2')
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = { ticketStubs, createStubHandler };
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// exe-engine/src/router/stubs/user-stub.js
|
||||
// HLI 存根路由 · USER 域
|
||||
// 501 占位 — Phase 0 骨架,P1 实现
|
||||
// PRJ-EXE-001 · 版权:国作登字-2026-A-00037559
|
||||
|
||||
'use strict';
|
||||
|
||||
function createStubHandler(routeId, routePath, targetPhase) {
|
||||
return async (req) => {
|
||||
return {
|
||||
statusCode: 501,
|
||||
body: {
|
||||
status: 'not_implemented',
|
||||
routeId,
|
||||
path: routePath,
|
||||
phase: targetPhase,
|
||||
message: `Route ${routePath} is planned for ${targetPhase}. Current: Phase 0.`
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const userStubs = [
|
||||
{
|
||||
routeId: 'HLI-USER-001',
|
||||
path: '/hli/user/profile',
|
||||
phase: 'P1',
|
||||
handler: createStubHandler('HLI-USER-001', '/hli/user/profile', 'P1')
|
||||
},
|
||||
{
|
||||
routeId: 'HLI-USER-002',
|
||||
path: '/hli/user/profile/update',
|
||||
phase: 'P1',
|
||||
handler: createStubHandler('HLI-USER-002', '/hli/user/profile/update', 'P1')
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = { userStubs, createStubHandler };
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
// exe-engine/tests/stubs/hli-stubs.test.js
|
||||
// HLI 存根路由测试
|
||||
// PRJ-EXE-001 · 501 stub coverage · AG-ZY-095 修复
|
||||
// 版权:国作登字-2026-A-00037559
|
||||
|
||||
'use strict';
|
||||
|
||||
const { personaStubs } = require('../../src/router/stubs/persona-stub');
|
||||
const { userStubs } = require('../../src/router/stubs/user-stub');
|
||||
const { ticketStubs } = require('../../src/router/stubs/ticket-stub');
|
||||
const { dialogueStubs } = require('../../src/router/stubs/dialogue-stub');
|
||||
const { storageStubs } = require('../../src/router/stubs/storage-stub');
|
||||
const { dashboardStubs } = require('../../src/router/stubs/dashboard-stub');
|
||||
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
|
||||
function assert(condition, message) {
|
||||
if (condition) {
|
||||
passed++;
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(` ✅ ${message}`);
|
||||
} else {
|
||||
failed++;
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(` ❌ ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('🔌 HLI 存根路由测试 · 501 Coverage Fix\n');
|
||||
|
||||
// 所有 14 个存根路由定义
|
||||
const ALL_STUBS = [
|
||||
...personaStubs,
|
||||
...userStubs,
|
||||
...ticketStubs,
|
||||
...dialogueStubs,
|
||||
...storageStubs,
|
||||
...dashboardStubs
|
||||
];
|
||||
|
||||
// 期望的路由表
|
||||
const EXPECTED_ROUTES = {
|
||||
'HLI-PERSONA-001': { path: '/hli/persona/load', phase: 'P1' },
|
||||
'HLI-PERSONA-002': { path: '/hli/persona/switch', phase: 'P1' },
|
||||
'HLI-USER-001': { path: '/hli/user/profile', phase: 'P1' },
|
||||
'HLI-USER-002': { path: '/hli/user/profile/update', phase: 'P1' },
|
||||
'HLI-TICKET-001': { path: '/hli/ticket/create', phase: 'P2' },
|
||||
'HLI-TICKET-002': { path: '/hli/ticket/query', phase: 'P2' },
|
||||
'HLI-TICKET-003': { path: '/hli/ticket/status', phase: 'P2' },
|
||||
'HLI-DIALOGUE-001': { path: '/hli/dialogue/send', phase: 'P1' },
|
||||
'HLI-DIALOGUE-002': { path: '/hli/dialogue/stream', phase: 'P1' },
|
||||
'HLI-DIALOGUE-003': { path: '/hli/dialogue/history', phase: 'P1' },
|
||||
'HLI-STORAGE-001': { path: '/hli/storage/upload', phase: 'P2' },
|
||||
'HLI-STORAGE-002': { path: '/hli/storage/download', phase: 'P2' },
|
||||
'HLI-DASHBOARD-001': { path: '/hli/dashboard/status', phase: 'P3' },
|
||||
'HLI-DASHBOARD-002': { path: '/hli/dashboard/realtime', phase: 'P3' }
|
||||
};
|
||||
|
||||
// ── 测试 1: 存根数量 ──
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('── 测试 1: 存根数量完整性 ──');
|
||||
assert(ALL_STUBS.length === 14, `14 个存根路由已注册 (实际: ${ALL_STUBS.length})`);
|
||||
assert(personaStubs.length === 2, 'PERSONA 域 2 个存根');
|
||||
assert(userStubs.length === 2, 'USER 域 2 个存根');
|
||||
assert(ticketStubs.length === 3, 'TICKET 域 3 个存根');
|
||||
assert(dialogueStubs.length === 3, 'DIALOGUE 域 3 个存根');
|
||||
assert(storageStubs.length === 2, 'STORAGE 域 2 个存根');
|
||||
assert(dashboardStubs.length === 2, 'DASHBOARD 域 2 个存根');
|
||||
|
||||
// ── 测试 2: 路由 ID 和路径匹配 ──
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('\n── 测试 2: 路由 ID 和路径匹配 ──');
|
||||
for (const stub of ALL_STUBS) {
|
||||
const expected = EXPECTED_ROUTES[stub.routeId];
|
||||
assert(expected !== undefined, `${stub.routeId} 在期望路由表中`);
|
||||
if (expected) {
|
||||
assert(stub.path === expected.path, `${stub.routeId} 路径正确: ${stub.path}`);
|
||||
assert(stub.phase === expected.phase, `${stub.routeId} 阶段正确: ${stub.phase}`);
|
||||
}
|
||||
}
|
||||
|
||||
// ── 测试 3: 每个存根返回 501 + 正确 JSON ──
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('\n── 测试 3: 每个存根返回 501 + 正确 JSON ──');
|
||||
async function testStubResponses() {
|
||||
for (const stub of ALL_STUBS) {
|
||||
const result = await stub.handler({});
|
||||
assert(result.statusCode === 501, `${stub.routeId} 返回 501`);
|
||||
assert(result.body.status === 'not_implemented', `${stub.routeId} status = not_implemented`);
|
||||
assert(result.body.routeId === stub.routeId, `${stub.routeId} routeId 正确`);
|
||||
assert(result.body.path === stub.path, `${stub.routeId} path 正确`);
|
||||
assert(result.body.phase === stub.phase, `${stub.routeId} phase 正确`);
|
||||
assert(typeof result.body.message === 'string', `${stub.routeId} 有 message`);
|
||||
assert(result.body.message.includes(stub.phase), `${stub.routeId} message 包含目标阶段`);
|
||||
}
|
||||
}
|
||||
|
||||
// ── 测试 4: AGE-Router 集成 ──
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('\n── 测试 4: AGE-Router 集成 ──');
|
||||
async function testRouterIntegration() {
|
||||
const { createEngine } = require('../../src/index');
|
||||
const engine = createEngine();
|
||||
|
||||
// 检查 getHLIStubs 方法存在
|
||||
assert(typeof engine.router.getHLIStubs === 'function', 'router.getHLIStubs() 方法存在');
|
||||
|
||||
const stubs = engine.router.getHLIStubs();
|
||||
assert(stubs.length === 14, `router 注册了 14 个存根 (实际: ${stubs.length})`);
|
||||
|
||||
// 检查 handleStubRoute 方法
|
||||
assert(typeof engine.router.handleStubRoute === 'function', 'router.handleStubRoute() 方法存在');
|
||||
|
||||
const result = await engine.router.handleStubRoute('/hli/persona/load');
|
||||
assert(result !== null, 'handleStubRoute 找到匹配路由');
|
||||
assert(result.statusCode === 501, 'handleStubRoute 返回 501');
|
||||
assert(result.body.routeId === 'HLI-PERSONA-001', 'handleStubRoute routeId 正确');
|
||||
|
||||
const noMatch = await engine.router.handleStubRoute('/hli/nonexistent');
|
||||
assert(noMatch === null, 'handleStubRoute 不匹配返回 null');
|
||||
|
||||
// 检查 getStatus 包含 hliStubs
|
||||
const status = engine.router.getStatus();
|
||||
assert(Array.isArray(status.hliStubs), 'getStatus 包含 hliStubs');
|
||||
assert(status.hliStubs.length === 14, `getStatus.hliStubs 有 14 项 (实际: ${status.hliStubs.length})`);
|
||||
assert(status.hliStubs[0].status === 'stub_501', 'hliStubs 项包含 status: stub_501');
|
||||
}
|
||||
|
||||
async function runAll() {
|
||||
await testStubResponses();
|
||||
await testRouterIntegration();
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('\n══════════════════════════════════════');
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('🔌 HLI 存根路由测试完成');
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(` ✅ 通过: ${passed}`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(` ❌ 失败: ${failed}`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(` 📊 总计: ${passed + failed}`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('══════════════════════════════════════\n');
|
||||
|
||||
if (failed > 0) {
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
runAll();
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"hli_id": "HLI-DASHBOARD-002",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/dashboard/realtime",
|
||||
"method": "GET",
|
||||
"type": "STREAM",
|
||||
"status": "stub",
|
||||
"target_phase": "P3",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P3 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"hli_id": "HLI-DASHBOARD-001",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/dashboard/status",
|
||||
"method": "GET",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P3",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P3 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"hli_id": "HLI-DIALOGUE-003",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/dialogue/history",
|
||||
"method": "GET",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P1",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"session_id": { "type": "string" },
|
||||
"limit": { "type": "number" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P1 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"hli_id": "HLI-DIALOGUE-001",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/dialogue/send",
|
||||
"method": "POST",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P1",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": ["message"],
|
||||
"properties": {
|
||||
"message": { "type": "string" },
|
||||
"persona_id": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P1 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"hli_id": "HLI-DIALOGUE-002",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/dialogue/stream",
|
||||
"method": "POST",
|
||||
"type": "STREAM",
|
||||
"status": "stub",
|
||||
"target_phase": "P1",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": ["message"],
|
||||
"properties": {
|
||||
"message": { "type": "string" },
|
||||
"persona_id": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P1 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"hli_id": "HLI-PERSONA-001",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/persona/load",
|
||||
"method": "POST",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P1",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": ["persona_id"],
|
||||
"properties": {
|
||||
"persona_id": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P1 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"hli_id": "HLI-PERSONA-002",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/persona/switch",
|
||||
"method": "POST",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P1",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": ["persona_id"],
|
||||
"properties": {
|
||||
"persona_id": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P1 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"hli_id": "HLI-STORAGE-002",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/storage/download",
|
||||
"method": "GET",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P2",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": ["file_id"],
|
||||
"properties": {
|
||||
"file_id": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P2 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"hli_id": "HLI-STORAGE-001",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/storage/upload",
|
||||
"method": "POST",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P2",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": ["filename"],
|
||||
"properties": {
|
||||
"filename": { "type": "string" },
|
||||
"content_type": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P2 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"hli_id": "HLI-TICKET-001",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/ticket/create",
|
||||
"method": "POST",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P2",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": ["title"],
|
||||
"properties": {
|
||||
"title": { "type": "string" },
|
||||
"description": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P2 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"hli_id": "HLI-TICKET-002",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/ticket/query",
|
||||
"method": "GET",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P2",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ticket_id": { "type": "string" },
|
||||
"status": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P2 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"hli_id": "HLI-TICKET-003",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/ticket/status",
|
||||
"method": "GET",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P2",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"required": ["ticket_id"],
|
||||
"properties": {
|
||||
"ticket_id": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P2 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"hli_id": "HLI-USER-002",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/user/profile/update",
|
||||
"method": "PUT",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P1",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"display_name": { "type": "string" },
|
||||
"avatar_url": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P1 实现" }
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"hli_id": "HLI-USER-001",
|
||||
"version": "v0.1-stub",
|
||||
"route": "/hli/user/profile",
|
||||
"method": "GET",
|
||||
"type": "REQUEST",
|
||||
"status": "stub",
|
||||
"target_phase": "P1",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_id": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string", "enum": ["not_implemented"] },
|
||||
"phase": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"changelog": [
|
||||
{ "date": "2026-03-26", "note": "501 stub — Phase 0 占位,P1 实现" }
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue