galaxy-opc-plugin 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +244 -8
- package/package.json +17 -3
- package/skills/acquisition-management/SKILL.md +83 -0
- package/skills/ai-staff/SKILL.md +89 -0
- package/skills/asset-package/SKILL.md +142 -0
- package/skills/opb-canvas/SKILL.md +88 -0
- package/src/__tests__/e2e/company-lifecycle.test.ts +399 -0
- package/src/__tests__/integration/business-workflows.test.ts +366 -0
- package/src/__tests__/test-utils.ts +316 -0
- package/src/commands/opc-command.ts +422 -0
- package/src/db/index.ts +3 -0
- package/src/db/migrations.test.ts +324 -0
- package/src/db/migrations.ts +131 -0
- package/src/db/schema.ts +211 -0
- package/src/db/sqlite-adapter.ts +5 -0
- package/src/opc/autonomy-rules.ts +132 -0
- package/src/opc/briefing-builder.ts +1331 -0
- package/src/opc/business-workflows.test.ts +535 -0
- package/src/opc/business-workflows.ts +325 -0
- package/src/opc/context-injector.ts +366 -28
- package/src/opc/event-triggers.ts +472 -0
- package/src/opc/intelligence-engine.ts +702 -0
- package/src/opc/milestone-detector.ts +251 -0
- package/src/opc/proactive-service.ts +179 -0
- package/src/opc/reminder-service.ts +4 -43
- package/src/opc/session-task-tracker.ts +60 -0
- package/src/opc/stage-detector.ts +168 -0
- package/src/opc/task-executor.ts +332 -0
- package/src/opc/task-templates.ts +179 -0
- package/src/tools/acquisition-tool.ts +8 -5
- package/src/tools/document-tool.ts +1176 -0
- package/src/tools/finance-tool.test.ts +238 -0
- package/src/tools/finance-tool.ts +922 -14
- package/src/tools/hr-tool.ts +10 -1
- package/src/tools/legal-tool.test.ts +251 -0
- package/src/tools/legal-tool.ts +26 -4
- package/src/tools/lifecycle-tool.test.ts +231 -0
- package/src/tools/media-tool.ts +156 -1
- package/src/tools/monitoring-tool.ts +135 -2
- package/src/tools/opc-tool.test.ts +250 -0
- package/src/tools/opc-tool.ts +251 -28
- package/src/tools/project-tool.test.ts +218 -0
- package/src/tools/schemas.ts +80 -0
- package/src/tools/search-tool.ts +227 -0
- package/src/tools/staff-tool.ts +395 -2
- package/src/web/config-ui.ts +299 -45
package/index.ts
CHANGED
|
@@ -14,7 +14,16 @@ import { registerHttpRoutes } from "./src/api/routes.js";
|
|
|
14
14
|
import type { OpcDatabase } from "./src/db/index.js";
|
|
15
15
|
import { SqliteAdapter } from "./src/db/sqlite-adapter.js";
|
|
16
16
|
import { registerContextInjector } from "./src/opc/context-injector.js";
|
|
17
|
-
import {
|
|
17
|
+
import { startProactiveService } from "./src/opc/proactive-service.js";
|
|
18
|
+
import { runIntelligenceScanForCompany } from "./src/opc/intelligence-engine.js";
|
|
19
|
+
import { detectMilestones } from "./src/opc/milestone-detector.js";
|
|
20
|
+
import { updateCompanyStage } from "./src/opc/stage-detector.js";
|
|
21
|
+
import {
|
|
22
|
+
registerSpawnedSession,
|
|
23
|
+
getSessionTaskMapping,
|
|
24
|
+
removeSessionTaskMapping,
|
|
25
|
+
clearAllSessionMappings,
|
|
26
|
+
} from "./src/opc/session-task-tracker.js";
|
|
18
27
|
import { registerAcquisitionTool } from "./src/tools/acquisition-tool.js";
|
|
19
28
|
import { registerAssetPackageTool } from "./src/tools/asset-package-tool.js";
|
|
20
29
|
import { registerFinanceTool } from "./src/tools/finance-tool.js";
|
|
@@ -28,7 +37,11 @@ import { registerOpcTool } from "./src/tools/opc-tool.js";
|
|
|
28
37
|
import { registerOpbTool } from "./src/tools/opb-tool.js";
|
|
29
38
|
import { registerProcurementTool } from "./src/tools/procurement-tool.js";
|
|
30
39
|
import { registerProjectTool } from "./src/tools/project-tool.js";
|
|
40
|
+
import { registerSearchTool } from "./src/tools/search-tool.js";
|
|
31
41
|
import { registerStaffTool } from "./src/tools/staff-tool.js";
|
|
42
|
+
import { registerDocumentTool } from "./src/tools/document-tool.js";
|
|
43
|
+
import { registerOpcCommand } from "./src/commands/opc-command.js";
|
|
44
|
+
import { triggerEventRules } from "./src/opc/event-triggers.js";
|
|
32
45
|
import { registerConfigUi } from "./src/web/config-ui.js";
|
|
33
46
|
import { registerLandingPage } from "./src/web/landing-page.js";
|
|
34
47
|
|
|
@@ -42,6 +55,12 @@ function resolveDbPath(configured?: string): string {
|
|
|
42
55
|
return dbPath;
|
|
43
56
|
}
|
|
44
57
|
|
|
58
|
+
/** 从 sessionKey 中提取公司 ID(格式: agent:opc-{companyId}:subagent:...) */
|
|
59
|
+
function extractCompanyIdFromSession(sessionKey: string): string | null {
|
|
60
|
+
const match = sessionKey.match(/agent:opc-([^:]+):/);
|
|
61
|
+
return match ? match[1] : null;
|
|
62
|
+
}
|
|
63
|
+
|
|
45
64
|
let db: OpcDatabase | null = null;
|
|
46
65
|
|
|
47
66
|
const plugin = {
|
|
@@ -78,6 +97,7 @@ const plugin = {
|
|
|
78
97
|
registerOpcTool(api, db);
|
|
79
98
|
registerStaffTool(api, db);
|
|
80
99
|
registerOpbTool(api, db);
|
|
100
|
+
registerSearchTool(api);
|
|
81
101
|
|
|
82
102
|
// 注册 Phase 2 专业工具(可通过管理后台禁用)
|
|
83
103
|
if (isEnabled("opc_finance")) registerFinanceTool(api, db);
|
|
@@ -92,6 +112,9 @@ const plugin = {
|
|
|
92
112
|
if (isEnabled("opc_lifecycle")) registerLifecycleTool(api, db);
|
|
93
113
|
if (isEnabled("opc_monitoring")) registerMonitoringTool(api, db);
|
|
94
114
|
|
|
115
|
+
// 文档生成工具(始终启用)
|
|
116
|
+
registerDocumentTool(api, db);
|
|
117
|
+
|
|
95
118
|
// 资金闭环工具(始终启用,核心商业模式)
|
|
96
119
|
registerAcquisitionTool(api, db);
|
|
97
120
|
registerAssetPackageTool(api, db);
|
|
@@ -101,6 +124,9 @@ const plugin = {
|
|
|
101
124
|
// 注册上下文注入钩子
|
|
102
125
|
registerContextInjector(api, db);
|
|
103
126
|
|
|
127
|
+
// 注册 /opc 快捷命令(毫秒级仪表盘,不经 LLM)
|
|
128
|
+
registerOpcCommand(api, db);
|
|
129
|
+
|
|
104
130
|
// 读取 gateway token 用于 API 认证
|
|
105
131
|
const gatewayToken = (() => {
|
|
106
132
|
try {
|
|
@@ -118,8 +144,213 @@ const plugin = {
|
|
|
118
144
|
registerConfigUi(api, db, gatewayToken);
|
|
119
145
|
registerLandingPage(api);
|
|
120
146
|
|
|
121
|
-
//
|
|
122
|
-
|
|
147
|
+
// ── 智能刷新器(共享函数,after_tool_call + subagent_ended 共用) ──
|
|
148
|
+
const refreshTimers = new Map<string, ReturnType<typeof setTimeout>>();
|
|
149
|
+
function triggerIntelligenceRefresh(companyId: string): void {
|
|
150
|
+
const existing = refreshTimers.get(companyId);
|
|
151
|
+
if (existing) clearTimeout(existing);
|
|
152
|
+
refreshTimers.set(companyId, setTimeout(() => {
|
|
153
|
+
refreshTimers.delete(companyId);
|
|
154
|
+
const l = (msg: string) => api.logger.info(msg);
|
|
155
|
+
db!.execute(
|
|
156
|
+
"DELETE FROM opc_insights WHERE company_id = ? AND insight_type = 'data_gap'",
|
|
157
|
+
companyId,
|
|
158
|
+
);
|
|
159
|
+
updateCompanyStage(db!, companyId);
|
|
160
|
+
runIntelligenceScanForCompany(db!, companyId, l);
|
|
161
|
+
detectMilestones(db!, companyId, l);
|
|
162
|
+
}, 5000));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 注册 after_tool_call 钩子 — 工具调用后即时刷新洞察(5秒防抖)+ 拦截 sessions_spawn
|
|
166
|
+
api.on("after_tool_call", (event, ctx) => {
|
|
167
|
+
const aid = ctx.agentId;
|
|
168
|
+
if (!aid?.startsWith("opc-")) return;
|
|
169
|
+
const companyId = aid.slice(4);
|
|
170
|
+
|
|
171
|
+
// ── 拦截 sessions_spawn:提取 taskId + childSessionKey 建立映射 ──
|
|
172
|
+
const toolName = String((event as Record<string, unknown>).toolName ?? "");
|
|
173
|
+
if (toolName === "sessions_spawn") {
|
|
174
|
+
try {
|
|
175
|
+
const taskParam = (event.params as Record<string, unknown>)?.task as string;
|
|
176
|
+
const match = taskParam?.match(/## 任务 ID\n([a-z0-9-]+)/);
|
|
177
|
+
if (match) {
|
|
178
|
+
const taskId = match[1];
|
|
179
|
+
const result = event.result as Record<string, unknown> | undefined;
|
|
180
|
+
const childSessionKey = (result?.childSessionKey || result?.sessionKey) as string | undefined;
|
|
181
|
+
if (childSessionKey) {
|
|
182
|
+
// 从任务记录获取 staffRole 和 title
|
|
183
|
+
const taskRow = db!.queryOne(
|
|
184
|
+
"SELECT staff_role, title FROM opc_staff_tasks WHERE id = ?", taskId,
|
|
185
|
+
) as { staff_role: string; title: string } | null;
|
|
186
|
+
|
|
187
|
+
registerSpawnedSession(childSessionKey, {
|
|
188
|
+
taskId,
|
|
189
|
+
companyId,
|
|
190
|
+
staffRole: taskRow?.staff_role ?? "",
|
|
191
|
+
title: taskRow?.title ?? "",
|
|
192
|
+
runId: result?.runId as string | undefined,
|
|
193
|
+
spawnedAt: new Date().toISOString(),
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// 持久化 session_key 到数据库
|
|
197
|
+
db!.execute(
|
|
198
|
+
"UPDATE opc_staff_tasks SET session_key = ? WHERE id = ?",
|
|
199
|
+
childSessionKey, taskId,
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
api.logger.info(
|
|
203
|
+
`opc: 已追踪子会话 ${childSessionKey} → 任务 ${taskId} (${taskRow?.title ?? "?"})`,
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
} catch (err) {
|
|
208
|
+
api.logger.info(`opc: sessions_spawn 追踪失败: ${err instanceof Error ? err.message : String(err)}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// ── 事件驱动触发引擎:OPC 工具写入数据后自动检查业务规则 ──
|
|
213
|
+
if (toolName.startsWith("opc_")) {
|
|
214
|
+
triggerEventRules(
|
|
215
|
+
db!, companyId, toolName,
|
|
216
|
+
event.params as Record<string, unknown> | undefined,
|
|
217
|
+
event.result as Record<string, unknown> | undefined,
|
|
218
|
+
(msg) => api.logger.info(msg),
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ── 通用:刷新洞察 ──
|
|
223
|
+
triggerIntelligenceRefresh(companyId);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// ── subagent_ended 钩子 — 子会话结束时自动更新任务状态 ──
|
|
227
|
+
api.on("subagent_ended", (event) => {
|
|
228
|
+
try {
|
|
229
|
+
const ev = event as Record<string, unknown>;
|
|
230
|
+
// 优先使用 targetSessionKey(SDK 标准字段),fallback 到 context 中的 childSessionKey
|
|
231
|
+
const sessionKey = ev.targetSessionKey as string
|
|
232
|
+
?? (ev as Record<string, unknown>).childSessionKey as string
|
|
233
|
+
?? ev.sessionKey as string;
|
|
234
|
+
if (!sessionKey) return;
|
|
235
|
+
|
|
236
|
+
const mapping = getSessionTaskMapping(sessionKey);
|
|
237
|
+
if (!mapping) {
|
|
238
|
+
// 非 OPC 任务,也尝试从数据库查找(服务重启后内存映射丢失的情况)
|
|
239
|
+
const dbTask = db!.queryOne(
|
|
240
|
+
"SELECT id, company_id, staff_role, title, status FROM opc_staff_tasks WHERE session_key = ?",
|
|
241
|
+
sessionKey,
|
|
242
|
+
) as { id: string; company_id: string; staff_role: string; title: string; status: string } | null;
|
|
243
|
+
if (!dbTask) return;
|
|
244
|
+
|
|
245
|
+
// 从数据库恢复映射并处理
|
|
246
|
+
handleSubagentEnd(dbTask.id, dbTask.company_id, dbTask.status, event);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const task = db!.queryOne(
|
|
251
|
+
"SELECT status FROM opc_staff_tasks WHERE id = ?", mapping.taskId,
|
|
252
|
+
) as { status: string } | null;
|
|
253
|
+
if (!task) {
|
|
254
|
+
removeSessionTaskMapping(sessionKey);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
handleSubagentEnd(mapping.taskId, mapping.companyId, task.status, event);
|
|
259
|
+
removeSessionTaskMapping(sessionKey);
|
|
260
|
+
} catch (err) {
|
|
261
|
+
api.logger.info(`opc: subagent_ended 处理失败: ${err instanceof Error ? err.message : String(err)}`);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
function handleSubagentEnd(
|
|
266
|
+
taskId: string,
|
|
267
|
+
companyId: string,
|
|
268
|
+
currentStatus: string,
|
|
269
|
+
event: Record<string, unknown>,
|
|
270
|
+
): void {
|
|
271
|
+
const now = new Date().toISOString();
|
|
272
|
+
const outcome = event.outcome as string | undefined;
|
|
273
|
+
|
|
274
|
+
if (outcome === "ok" || outcome === "completed") {
|
|
275
|
+
// 员工正常结束 — 如果任务仍 in_progress,说明员工忘了调 update_task
|
|
276
|
+
if (currentStatus === "in_progress") {
|
|
277
|
+
db!.execute(
|
|
278
|
+
`UPDATE opc_staff_tasks SET status = 'completed', completed_at = ?,
|
|
279
|
+
result_summary = CASE WHEN result_summary = '' THEN ? ELSE result_summary END
|
|
280
|
+
WHERE id = ? AND status = 'in_progress'`,
|
|
281
|
+
now,
|
|
282
|
+
"[系统] 员工会话已正常结束但未提交工作报告",
|
|
283
|
+
taskId,
|
|
284
|
+
);
|
|
285
|
+
api.logger.info(`opc: 子会话正常结束,自动标记任务 ${taskId} 为 completed`);
|
|
286
|
+
}
|
|
287
|
+
} else {
|
|
288
|
+
// error/timeout/killed → 自动取消
|
|
289
|
+
const errorDetail = event.error as string || "";
|
|
290
|
+
db!.execute(
|
|
291
|
+
`UPDATE opc_staff_tasks SET status = 'cancelled', completed_at = ?,
|
|
292
|
+
result_summary = ? WHERE id = ? AND status IN ('in_progress', 'pending')`,
|
|
293
|
+
now,
|
|
294
|
+
`[系统] 员工会话异常终止(${outcome || "unknown"}: ${errorDetail})`,
|
|
295
|
+
taskId,
|
|
296
|
+
);
|
|
297
|
+
api.logger.info(`opc: 子会话异常终止(${outcome}),自动取消任务 ${taskId}`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
triggerIntelligenceRefresh(companyId);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// ── before_tool_call 权限控制 + switch_company 注入 ──
|
|
304
|
+
api.on("before_tool_call", (event, ctx) => {
|
|
305
|
+
// ── switch_company 自动注入 channel/peer 信息 ──
|
|
306
|
+
const btToolName0 = String((event as Record<string, unknown>).toolName ?? "");
|
|
307
|
+
if (btToolName0 === "opc_manage") {
|
|
308
|
+
const action = (event.params as Record<string, unknown>)?.action;
|
|
309
|
+
if (action === "switch_company" && ctx.sessionKey) {
|
|
310
|
+
const sessionKey = ctx.sessionKey;
|
|
311
|
+
api.logger.info(`opc: switch_company sessionKey = "${sessionKey}"`);
|
|
312
|
+
api.logger.info(`opc: switch_company agentId = "${ctx.agentId}", params = ${JSON.stringify(event.params)}`);
|
|
313
|
+
// 提取 channel: ":direct:" 前面的标识(如 feishu)
|
|
314
|
+
const channelMatch = sessionKey.match(/:([a-z_]+):direct:/);
|
|
315
|
+
const peerMatch = sessionKey.match(/:direct:([^:]+)/);
|
|
316
|
+
const channel = channelMatch?.[1] ?? "";
|
|
317
|
+
const peerId = peerMatch?.[1] ?? "";
|
|
318
|
+
api.logger.info(`opc: switch_company parsed channel="${channel}", peerId="${peerId}"`);
|
|
319
|
+
if (channel && peerId) {
|
|
320
|
+
return {
|
|
321
|
+
params: {
|
|
322
|
+
...(event.params as Record<string, unknown> || {}),
|
|
323
|
+
_channel: channel,
|
|
324
|
+
_peer_id: peerId,
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// ── 子会话权限控制 ──
|
|
332
|
+
// 非子会话不拦截
|
|
333
|
+
if (!ctx.sessionKey?.includes("subagent")) return;
|
|
334
|
+
|
|
335
|
+
const btToolName = String((event as Record<string, unknown>).toolName ?? "");
|
|
336
|
+
if (!btToolName.startsWith("opc_")) return; // 非 OPC 工具不拦截
|
|
337
|
+
|
|
338
|
+
// 从 params 中提取 company_id
|
|
339
|
+
const paramCompanyId = (event.params as Record<string, unknown>)?.company_id as string | undefined;
|
|
340
|
+
if (!paramCompanyId) return;
|
|
341
|
+
|
|
342
|
+
// 从父会话 agentId 或 sessionKey 提取公司 ID
|
|
343
|
+
const parentCompanyId = extractCompanyIdFromSession(ctx.sessionKey);
|
|
344
|
+
if (parentCompanyId && paramCompanyId !== parentCompanyId) {
|
|
345
|
+
return {
|
|
346
|
+
block: true,
|
|
347
|
+
blockReason: `权限拒绝:你只能操作公司 ${parentCompanyId} 的数据,不能操作 ${paramCompanyId}`,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// 注册后台服务(数据库生命周期 + 主动智能)
|
|
353
|
+
let stopProactive: (() => void) | null = null;
|
|
123
354
|
api.registerService({
|
|
124
355
|
id: "opc-db-lifecycle",
|
|
125
356
|
start() {
|
|
@@ -129,17 +360,22 @@ const plugin = {
|
|
|
129
360
|
"SELECT value FROM opc_tool_config WHERE key = ?", "webhook_url",
|
|
130
361
|
) as { value: string } | null;
|
|
131
362
|
const webhookUrl = webhookRow?.value?.trim() || undefined;
|
|
132
|
-
//
|
|
133
|
-
|
|
363
|
+
// 启动主动智能服务(每小时全量扫描)
|
|
364
|
+
stopProactive = startProactiveService(
|
|
134
365
|
db!,
|
|
135
366
|
(msg) => api.logger.info(msg),
|
|
136
367
|
webhookUrl,
|
|
137
368
|
);
|
|
138
|
-
api.logger.info(`opc:
|
|
369
|
+
api.logger.info(`opc: 主动智能服务已启动(每小时扫描${webhookUrl ? ",Webhook 已配置" : ""})`);
|
|
139
370
|
},
|
|
140
371
|
stop() {
|
|
141
|
-
|
|
142
|
-
|
|
372
|
+
stopProactive?.();
|
|
373
|
+
stopProactive = null;
|
|
374
|
+
// 清理防抖定时器
|
|
375
|
+
for (const timer of refreshTimers.values()) clearTimeout(timer);
|
|
376
|
+
refreshTimers.clear();
|
|
377
|
+
// 清理会话映射
|
|
378
|
+
clearAllSessionMappings();
|
|
143
379
|
if (db) {
|
|
144
380
|
db.close();
|
|
145
381
|
db = null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "galaxy-opc-plugin",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "星环 Galaxy OPC — 一人公司孵化与赋能平台 OpenClaw 插件",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openclaw",
|
|
@@ -30,10 +30,24 @@
|
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@sinclair/typebox": "0.34.48",
|
|
33
|
-
"
|
|
33
|
+
"@types/pdfkit": "^0.17.5",
|
|
34
|
+
"better-sqlite3": "^11.8.1",
|
|
35
|
+
"docx": "^9.6.0",
|
|
36
|
+
"exceljs": "^4.4.0",
|
|
37
|
+
"pdfkit": "^0.17.2"
|
|
34
38
|
},
|
|
35
39
|
"devDependencies": {
|
|
36
|
-
"@types/better-sqlite3": "^7.6.12"
|
|
40
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
41
|
+
"@types/node": "^20.19.35",
|
|
42
|
+
"@vitest/coverage-v8": "^2.1.9",
|
|
43
|
+
"@vitest/ui": "^2.1.9",
|
|
44
|
+
"vitest": "^2.1.9"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"test": "vitest",
|
|
48
|
+
"test:ui": "vitest --ui",
|
|
49
|
+
"test:run": "vitest run",
|
|
50
|
+
"test:coverage": "vitest run --coverage"
|
|
37
51
|
},
|
|
38
52
|
"openclaw": {
|
|
39
53
|
"extensions": [
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: acquisition-management
|
|
3
|
+
description: |
|
|
4
|
+
收并购管理技能。当用户提到收购、并购、收购亏损公司、税务优化、亏损抵扣、收并购时激活。
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 收并购管理技能
|
|
8
|
+
|
|
9
|
+
使用 `opc_acquisition` 工具管理一人公司收并购流程。当 OPC 经营不善时,星河数科依据参股协议发起收购,亏损可抵扣企业所得税,并为后续资产打包做准备。
|
|
10
|
+
|
|
11
|
+
## 收并购流程
|
|
12
|
+
|
|
13
|
+
### 第一步:发起收购
|
|
14
|
+
|
|
15
|
+
确认目标公司经营状况后,创建收购案例:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"action": "create_acquisition",
|
|
20
|
+
"company_id": "目标公司ID",
|
|
21
|
+
"trigger_reason": "连续亏损,营收不达预期",
|
|
22
|
+
"acquisition_price": 50000,
|
|
23
|
+
"loss_amount": 200000,
|
|
24
|
+
"notes": "依据参股协议第8条发起收购"
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
系统自动完成:
|
|
29
|
+
- 创建收购案例(状态: evaluating)
|
|
30
|
+
- 将公司状态变更为 `acquired`(通过状态机校验)
|
|
31
|
+
- 计算税务抵扣估算:亏损 x 25% 企业所得税率
|
|
32
|
+
|
|
33
|
+
### 第二步:跟踪收购进度
|
|
34
|
+
|
|
35
|
+
查看所有收购案例:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"action": "list_acquisitions",
|
|
40
|
+
"status": "evaluating"
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
案例状态流转: `evaluating`(评估中) → `approved`(已批准) → `closed`(已完成),或 `rejected`(已拒绝)
|
|
45
|
+
|
|
46
|
+
### 第三步:更新收购信息
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"action": "update_acquisition",
|
|
51
|
+
"case_id": "案例ID",
|
|
52
|
+
"status": "approved",
|
|
53
|
+
"acquisition_price": 60000,
|
|
54
|
+
"loss_amount": 180000
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
更新价格或亏损金额时,税务抵扣会自动重新计算。
|
|
59
|
+
|
|
60
|
+
### 第四步:平台汇总
|
|
61
|
+
|
|
62
|
+
查看全平台收并购概况:
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"action": "acquisition_summary"
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
返回: 总收购数、累计亏损、累计税务抵扣优化总额。
|
|
71
|
+
|
|
72
|
+
## 税务优化说明
|
|
73
|
+
|
|
74
|
+
- 亏损抵扣公式: 亏损金额 x 25%(企业所得税率)
|
|
75
|
+
- 小微企业优惠税率下实际可抵扣更多
|
|
76
|
+
- 收购完成后可进入资产打包流程(使用 `opc_asset_package` 工具)
|
|
77
|
+
|
|
78
|
+
## 使用建议
|
|
79
|
+
|
|
80
|
+
1. 收购前先通过 `opc_manage` 查看公司财务状况
|
|
81
|
+
2. 确认亏损金额后发起收购
|
|
82
|
+
3. 收购完成后,将公司加入资产包(`opc_asset_package.add_company_to_package`)
|
|
83
|
+
4. 定期查看 `acquisition_summary` 了解平台整体税务优化效果
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ai-staff
|
|
3
|
+
description: |
|
|
4
|
+
AI 员工配置技能。当用户提到AI员工、AI团队、虚拟员工、配置员工、一人团队、AI助手角色时激活。
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# AI 员工配置技能
|
|
8
|
+
|
|
9
|
+
使用 `opc_staff` 工具为一人公司配置 AI 员工团队,实现"一人 = AI 团队"的核心理念。每个 AI 员工拥有独立的角色定位和专业提示词。
|
|
10
|
+
|
|
11
|
+
## 快速上手
|
|
12
|
+
|
|
13
|
+
### 一键初始化默认团队
|
|
14
|
+
|
|
15
|
+
为公司快速创建 6 个标准 AI 岗位:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"action": "init_default_staff",
|
|
20
|
+
"company_id": "公司ID"
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
默认团队包含:
|
|
25
|
+
- **行政助理** — 日程管理、文件归档、会议安排
|
|
26
|
+
- **HR 专员** — 招聘、入职、薪酬核算、社保公积金
|
|
27
|
+
- **财务顾问** — 账务、发票、税务申报、现金流分析
|
|
28
|
+
- **法务顾问** — 合同审查、知识产权、劳动法务
|
|
29
|
+
- **营销专员** — 内容创作、社交媒体运营、品牌推广
|
|
30
|
+
- **运营经理** — 项目管理、供应链协调、数据分析
|
|
31
|
+
|
|
32
|
+
## 自定义员工
|
|
33
|
+
|
|
34
|
+
### 配置/更新 AI 员工
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"action": "configure_staff",
|
|
39
|
+
"company_id": "公司ID",
|
|
40
|
+
"role_id": "product_manager",
|
|
41
|
+
"name": "产品经理",
|
|
42
|
+
"system_prompt": "你是公司产品经理,负责需求分析、产品规划、用户体验优化和竞品调研。善于用数据驱动产品决策。",
|
|
43
|
+
"skills": "requirement-analysis,user-research,roadmap"
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 查看内置角色模板
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"action": "list_builtin_roles"
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
可用内置角色: admin(行政), hr(HR), finance(财务), legal(法务), marketing(营销), operations(运营)
|
|
56
|
+
|
|
57
|
+
### 查看已配置的员工
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"action": "list_staff",
|
|
62
|
+
"company_id": "公司ID"
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 启用/禁用员工
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"action": "toggle_staff",
|
|
71
|
+
"company_id": "公司ID",
|
|
72
|
+
"role_id": "marketing",
|
|
73
|
+
"enabled": false
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 工作原理
|
|
78
|
+
|
|
79
|
+
配置 AI 员工后,当用户进入公司 Agent 对话时:
|
|
80
|
+
1. 系统自动注入所有已启用员工的角色信息
|
|
81
|
+
2. AI 可根据问题类型自动"调度"对应岗位的专业知识
|
|
82
|
+
3. 每个员工的 system_prompt 定义了其专业能力边界
|
|
83
|
+
|
|
84
|
+
## 使用建议
|
|
85
|
+
|
|
86
|
+
1. 新公司注册后,先运行 `init_default_staff` 一键配置
|
|
87
|
+
2. 根据公司实际业务,添加自定义岗位(如产品经理、技术总监)
|
|
88
|
+
3. 暂时不需要的岗位可以 `toggle_staff` 禁用,无需删除
|
|
89
|
+
4. 定期更新员工的 system_prompt 以匹配公司最新业务方向
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: asset-package
|
|
3
|
+
description: |
|
|
4
|
+
资产打包与城投转让技能。当用户提到资产包、资产打包、城投、城投转让、科技贷、融资服务费、资金闭环时激活。
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 资产打包与城投转让技能
|
|
8
|
+
|
|
9
|
+
使用 `opc_asset_package` 工具完成资金闭环的后半段:将收购的公司打包为科技资产包,转让给城投公司,申请科技贷款,收取融资服务费。
|
|
10
|
+
|
|
11
|
+
## 资金闭环全流程
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
孵化 OPC → 经营不善 → 收购(opc_acquisition) → 资产打包 → 城投转让 → 科技贷 → 服务费
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 资产包管理
|
|
18
|
+
|
|
19
|
+
### 创建资产包
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"action": "create_asset_package",
|
|
24
|
+
"name": "2025年第一批科技资产包",
|
|
25
|
+
"description": "含3家AI领域一人公司"
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
资产包状态: `assembling`(组装中) → `submitted`(已提交) → `approved`(已审批) → `transferred`(已转让)
|
|
30
|
+
|
|
31
|
+
### 添加公司到资产包
|
|
32
|
+
|
|
33
|
+
将已收购的公司加入资产包:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"action": "add_company_to_package",
|
|
38
|
+
"package_id": "资产包ID",
|
|
39
|
+
"company_id": "已收购的公司ID",
|
|
40
|
+
"valuation": 500000
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
系统自动更新资产包总估值和公司数量。
|
|
45
|
+
|
|
46
|
+
### 查看资产包详情
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"action": "get_package_detail",
|
|
51
|
+
"package_id": "资产包ID"
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
返回: 资产包信息 + 包含的公司列表 + 关联的城投转让记录。
|
|
56
|
+
|
|
57
|
+
## 城投转让
|
|
58
|
+
|
|
59
|
+
### 发起城投转让
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"action": "create_ct_transfer",
|
|
64
|
+
"package_id": "资产包ID",
|
|
65
|
+
"ct_company_name": "仁和区城市建设投资有限公司",
|
|
66
|
+
"target_loan_amount": 10000000,
|
|
67
|
+
"interest_rate": 3.5,
|
|
68
|
+
"loan_term_months": 36,
|
|
69
|
+
"notes": "科技贷款申请"
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
转让状态: `negotiating`(洽谈中) → `signed`(已签约) → `loan_approved`(贷款已批) → `completed`(已完成)
|
|
74
|
+
|
|
75
|
+
### 更新转让进度
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"action": "update_ct_transfer",
|
|
80
|
+
"transfer_id": "转让ID",
|
|
81
|
+
"status": "loan_approved",
|
|
82
|
+
"actual_loan_amount": 8000000
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 查看转让列表
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"action": "list_ct_transfers",
|
|
91
|
+
"status": "completed"
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## 融资服务费
|
|
96
|
+
|
|
97
|
+
### 记录服务费
|
|
98
|
+
|
|
99
|
+
贷款完成后,按比例收取融资服务费:
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"action": "record_financing_fee",
|
|
104
|
+
"transfer_id": "转让ID",
|
|
105
|
+
"fee_base": 8000000,
|
|
106
|
+
"fee_rate": 2.5
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
系统自动计算: 8,000,000 x 2.5% = 200,000 元服务费。
|
|
111
|
+
|
|
112
|
+
### 更新服务费状态
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"action": "update_financing_fee",
|
|
117
|
+
"fee_id": "服务费ID",
|
|
118
|
+
"invoice_status": "invoiced",
|
|
119
|
+
"payment_status": "paid"
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 闭环总览
|
|
124
|
+
|
|
125
|
+
查看全平台资金闭环汇总:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"action": "closure_summary"
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
返回: 所有资产包 + 城投转让 + 服务费的完整闭环数据。
|
|
134
|
+
|
|
135
|
+
## 使用建议
|
|
136
|
+
|
|
137
|
+
1. 先通过 `opc_acquisition` 完成收购,确保公司状态为 `acquired`
|
|
138
|
+
2. 创建资产包,将多家已收购公司打包
|
|
139
|
+
3. 资产包提交审批后,申请科技资产认定
|
|
140
|
+
4. 与城投公司洽谈转让,发起科技贷申请
|
|
141
|
+
5. 贷款到账后记录融资服务费
|
|
142
|
+
6. 定期查看 `closure_summary` 掌握整体闭环进度
|