Compare commits

...
971 Commits
Author SHA1 Message Date
公明andGitHub b74b882855 Add files via upload 2026-07-08 15:24:51 +08:00
公明andGitHub 5c4e8cdfb3 Add files via upload 2026-07-08 15:22:36 +08:00
公明andGitHub 62fafbf09b Add files via upload 2026-07-08 15:20:59 +08:00
公明andGitHub 784be8a162 Add files via upload 2026-07-08 15:17:06 +08:00
公明andGitHub c2a1d6c632 Add files via upload 2026-07-08 14:39:50 +08:00
公明andGitHub 2980d17dc7 Add files via upload 2026-07-08 14:39:30 +08:00
公明andGitHub a59084b8ae Add files via upload 2026-07-08 14:21:10 +08:00
公明andGitHub 28214254b5 Add files via upload 2026-07-08 14:19:04 +08:00
公明andGitHub a5d26db5c0 Add files via upload 2026-07-08 13:51:05 +08:00
公明andGitHub b4b21f57fe Add files via upload 2026-07-08 10:55:34 +08:00
公明andGitHub 89264c9c1a Add files via upload 2026-07-08 10:31:32 +08:00
公明andGitHub dc541b91b5 Add files via upload 2026-07-07 18:24:30 +08:00
公明andGitHub cd5448c56d Add files via upload 2026-07-07 17:49:58 +08:00
公明andGitHub 9464cb3690 Add files via upload 2026-07-07 17:49:48 +08:00
公明andGitHub 2db9831b2f Add files via upload 2026-07-07 17:40:45 +08:00
公明andGitHub 8a10370b4e Add files via upload 2026-07-07 17:38:31 +08:00
公明andGitHub 8c2808c65a Add files via upload 2026-07-07 17:35:08 +08:00
公明andGitHub eb542e38f5 Add files via upload 2026-07-07 17:29:20 +08:00
公明andGitHub 95e00563da Add files via upload 2026-07-07 17:29:11 +08:00
公明andGitHub dd4c22a1bd Add files via upload 2026-07-07 17:17:19 +08:00
公明andGitHub 8ef47474ff Add files via upload 2026-07-07 17:01:38 +08:00
公明andGitHub 62049e18d0 Add files via upload 2026-07-07 16:59:13 +08:00
公明andGitHub c0b446226b Add files via upload 2026-07-07 16:53:36 +08:00
公明andGitHub cca6796176 Add files via upload 2026-07-07 16:32:15 +08:00
公明andGitHub 741f131f80 Add files via upload 2026-07-07 16:08:38 +08:00
公明andGitHub 9712ff9311 Add files via upload 2026-07-07 15:09:04 +08:00
公明andGitHub a678d47efc Add files via upload 2026-07-07 14:53:38 +08:00
公明andGitHub 8bc137882b Add files via upload 2026-07-07 14:45:07 +08:00
公明andGitHub b52f8990f3 Add files via upload 2026-07-07 14:32:42 +08:00
公明andGitHub cdd1894737 Add files via upload 2026-07-07 14:20:55 +08:00
公明andGitHub caf4cf61c1 Add files via upload 2026-07-07 14:06:29 +08:00
公明andGitHub 00802a275c Add files via upload 2026-07-07 14:04:18 +08:00
公明andGitHub 3dfcde7c88 Delete docs directory 2026-07-07 14:02:14 +08:00
公明andGitHub 60ba6b8eb3 Add files via upload 2026-07-07 11:48:53 +08:00
公明andGitHub 4408fe6024 Add files via upload 2026-07-07 11:43:18 +08:00
公明andGitHub 92db33cbf2 Add files via upload 2026-07-07 11:42:31 +08:00
公明andGitHub d2390f841f Add files via upload 2026-07-07 11:41:08 +08:00
公明andGitHub dc5791f85c Add files via upload 2026-07-07 11:39:05 +08:00
公明andGitHub 45e5c1bf39 Add files via upload 2026-07-07 11:36:21 +08:00
公明andGitHub 87c9d79f7a Add files via upload 2026-07-07 11:35:16 +08:00
公明andGitHub bb4f239358 Add files via upload 2026-07-07 11:33:22 +08:00
公明andGitHub 84cbaa57dc Add files via upload 2026-07-07 11:31:38 +08:00
公明andGitHub 6dffa64513 Add files via upload 2026-07-07 11:17:15 +08:00
公明andGitHub e88b28c8bd Add files via upload 2026-07-07 11:07:34 +08:00
公明andGitHub c84612211c Add files via upload 2026-07-07 10:17:03 +08:00
公明andGitHub d2bd59ced7 Add files via upload 2026-07-06 18:03:31 +08:00
公明andGitHub 8393b3a7a6 Add files via upload 2026-07-06 18:00:37 +08:00
公明andGitHub 412daf8598 Update config.yaml 2026-07-06 17:45:27 +08:00
公明andGitHub c40a1f82a8 Add files via upload 2026-07-06 17:27:29 +08:00
公明andGitHub 404feb372e Add files via upload 2026-07-06 17:00:03 +08:00
公明andGitHub 00a936e5dc Add files via upload 2026-07-06 16:50:05 +08:00
公明andGitHub c107c77619 Add files via upload 2026-07-06 16:27:34 +08:00
公明andGitHub 4d81d2be97 Add files via upload 2026-07-06 16:26:38 +08:00
公明andGitHub 1dc43083b0 Add files via upload 2026-07-06 16:20:29 +08:00
公明andGitHub 6021d1a097 Add files via upload 2026-07-06 15:44:19 +08:00
公明andGitHub 7a06db3f44 Add files via upload 2026-07-06 15:20:35 +08:00
公明andGitHub 33d6f8bb0c Add files via upload 2026-07-06 14:56:46 +08:00
公明andGitHub cf2e65ca1b Merge pull request #183 from flydreamsec/fix/mcp-execution-binder-race
fix(multiagent): guard MCPExecutionBinder map with RWMutex (concurrent tool callback race)
2026-07-06 14:39:58 +08:00
flydream 49a90d03fa fix(multiagent): guard MCPExecutionBinder map with RWMutex
Concurrent tool callbacks in eino_adk_run_loop and the MCP monitor
goroutine call Bind/ExecutionID on the same binder. The previous
implementation used a plain map[string]string, causing intermittent
'concurrent map read and map write' panics — the same race that
TestMCPExecutionBinder_ConcurrentBind was added to guard against.

Wrap the map with sync.RWMutex (write lock in Bind, read lock in
ExecutionID). The TrimSpace of toolCallID/executionID stays outside
the critical section to keep it minimal.

go vet ./internal/multiagent/...   ✓
go test -race ./internal/multiagent/... -run MCPExecutionBinder  ✓
2026-07-06 14:37:56 +08:00
公明andGitHub 754b1ad88b Add files via upload 2026-07-06 14:17:49 +08:00
公明andGitHub b41d334d2b Update config.yaml 2026-07-06 14:00:08 +08:00
公明andGitHub 38ebdebd14 Add files via upload 2026-07-06 13:59:13 +08:00
公明andGitHub a63b535a68 Add files via upload 2026-07-06 13:58:12 +08:00
公明andGitHub ecc75ee326 Add files via upload 2026-07-06 13:55:51 +08:00
公明andGitHub a425df2607 Add files via upload 2026-07-06 12:59:54 +08:00
公明andGitHub 0aa402f89c Add files via upload 2026-07-06 11:47:09 +08:00
公明andGitHub c32cb915bc Add files via upload 2026-07-06 11:46:42 +08:00
公明andGitHub 4fd3fe3cc8 Add files via upload 2026-07-06 11:45:22 +08:00
公明andGitHub 0643aaadc6 Add files via upload 2026-07-06 11:40:06 +08:00
公明andGitHub b5baf7f9b3 Add files via upload 2026-07-06 11:38:05 +08:00
公明andGitHub 8b1efd5dd7 Add files via upload 2026-07-06 11:35:42 +08:00
公明andGitHub f6412150cf Add files via upload 2026-07-06 11:34:50 +08:00
公明andGitHub 2764732cdf Add files via upload 2026-07-06 11:33:16 +08:00
公明andGitHub 7b8b57907b Add files via upload 2026-07-06 11:31:13 +08:00
公明andGitHub be2800c248 Add files via upload 2026-07-06 10:39:55 +08:00
公明andGitHub 0ad66d8b7e Add files via upload 2026-07-03 22:39:55 +08:00
公明andGitHub b9e5527131 Update config.yaml 2026-07-03 20:58:41 +08:00
公明andGitHub 3d5e2bc4c7 Add files via upload 2026-07-03 20:31:49 +08:00
公明andGitHub d58c4642f7 Add files via upload 2026-07-03 20:30:47 +08:00
公明andGitHub 9df6de088b Add files via upload 2026-07-03 20:29:09 +08:00
公明andGitHub aae71a0c3e Add files via upload 2026-07-03 20:27:51 +08:00
公明andGitHub 059a33029e Add files via upload 2026-07-03 20:26:21 +08:00
公明andGitHub 15daad97d4 Add files via upload 2026-07-03 20:25:31 +08:00
公明andGitHub f02c0d175b Add files via upload 2026-07-03 20:23:46 +08:00
公明andGitHub a8da115d28 Add files via upload 2026-07-03 19:41:53 +08:00
公明andGitHub e4a01089e7 Add files via upload 2026-07-03 19:41:05 +08:00
公明andGitHub bbf8c416fc Add files via upload 2026-07-03 19:39:17 +08:00
公明andGitHub d41decd707 Add files via upload 2026-07-03 19:38:23 +08:00
公明andGitHub 93a600d60e Add files via upload 2026-07-03 19:36:40 +08:00
公明andGitHub c86825d365 Remove Stargazers over time section
Removed the 'Stargazers over time' section from the README.
2026-07-03 19:35:46 +08:00
公明andGitHub 4af5e2691e Update README.md 2026-07-03 19:35:28 +08:00
公明andGitHub 85400cd3f8 Add files via upload 2026-07-03 19:34:42 +08:00
公明andGitHub a66b8fc821 Add files via upload 2026-07-03 19:33:10 +08:00
公明andGitHub 58be62fa24 Add files via upload 2026-07-03 17:55:08 +08:00
公明andGitHub a3739210e4 Add files via upload 2026-07-03 17:10:03 +08:00
公明andGitHub e936c63754 Add files via upload 2026-07-03 17:08:41 +08:00
公明andGitHub 1f46d4a930 Add files via upload 2026-07-03 17:06:18 +08:00
公明andGitHub 3a995183a6 Add files via upload 2026-07-03 17:03:37 +08:00
公明andGitHub 3ed7499a0b Add files via upload 2026-07-03 17:01:43 +08:00
公明andGitHub f26354d483 Add files via upload 2026-07-03 16:59:39 +08:00
公明andGitHub ebd872b373 Add files via upload 2026-07-03 16:57:09 +08:00
公明andGitHub 07439bce6e Add files via upload 2026-07-03 16:54:18 +08:00
公明andGitHub 625ac4358f Update config.yaml 2026-07-03 14:29:16 +08:00
公明andGitHub eb6b9d6f45 Add files via upload 2026-07-03 14:28:37 +08:00
公明andGitHub ad97544bbe Add files via upload 2026-07-03 14:20:06 +08:00
公明andGitHub 12a1ebe9cd Add files via upload 2026-07-03 14:17:47 +08:00
公明andGitHub b97e726237 Add files via upload 2026-07-03 14:15:51 +08:00
公明andGitHub 2eb923e5fa Add files via upload 2026-07-03 14:13:35 +08:00
公明andGitHub 745a69f93b Add files via upload 2026-07-03 14:12:20 +08:00
公明andGitHub 011a242acc Add files via upload 2026-07-03 14:10:14 +08:00
公明andGitHub 6a52ef96f4 Add files via upload 2026-07-03 10:56:22 +08:00
公明andGitHub 52f8c377b6 Add files via upload 2026-07-03 10:55:07 +08:00
公明andGitHub 8d04b0c266 Add files via upload 2026-07-03 10:52:21 +08:00
公明andGitHub bcdff06702 Add files via upload 2026-07-03 10:49:53 +08:00
公明andGitHub 3210bc727f Add files via upload 2026-07-03 10:48:38 +08:00
公明andGitHub 5254ca52fb Add files via upload 2026-07-03 10:46:04 +08:00
公明andGitHub 1ff2df68ac Add files via upload 2026-07-02 23:32:48 +08:00
公明andGitHub fe60497863 Add files via upload 2026-07-02 19:21:29 +08:00
公明andGitHub 7acd21bc98 Add files via upload 2026-07-02 19:14:30 +08:00
公明andGitHub dbcf9b8418 Update config.yaml 2026-07-02 18:05:23 +08:00
公明andGitHub b3767b2deb Add files via upload 2026-07-02 18:03:35 +08:00
公明andGitHub 7e764df0e8 Add files via upload 2026-07-02 18:02:45 +08:00
公明andGitHub a1ffb20d6e Add files via upload 2026-07-02 17:58:06 +08:00
公明andGitHub 125685f08f Add files via upload 2026-07-02 17:50:09 +08:00
公明andGitHub b804635fa8 Add files via upload 2026-07-02 12:11:18 +08:00
公明andGitHub c9fb5d11d3 Add files via upload 2026-07-02 12:08:52 +08:00
公明andGitHub 926491b746 Add files via upload 2026-07-02 12:08:14 +08:00
公明andGitHub 4e17691717 Add files via upload 2026-07-02 12:06:49 +08:00
公明andGitHub 2e2a6dedd4 Add files via upload 2026-07-02 12:02:37 +08:00
公明andGitHub b1323896c8 Add files via upload 2026-07-02 11:55:23 +08:00
公明andGitHub 595074b7b0 Add files via upload 2026-07-02 11:52:32 +08:00
公明andGitHub 2e063dd857 Add files via upload 2026-07-02 11:51:27 +08:00
公明andGitHub a110d233e1 Add files via upload 2026-07-02 11:49:03 +08:00
公明andGitHub 2f58d0a457 Add files via upload 2026-07-01 16:06:15 +08:00
公明andGitHub 5b7f157802 Add files via upload 2026-07-01 15:56:51 +08:00
公明andGitHub 09890db635 Add files via upload 2026-07-01 14:37:36 +08:00
公明andGitHub c0171ef60a Add files via upload 2026-07-01 14:34:50 +08:00
公明andGitHub 4eb73fb638 Add files via upload 2026-07-01 14:32:50 +08:00
公明andGitHub d1b49cb20d Add files via upload 2026-07-01 14:30:58 +08:00
公明andGitHub 930eb47013 Add files via upload 2026-07-01 14:29:58 +08:00
公明andGitHub 9964e13197 Add files via upload 2026-07-01 14:27:05 +08:00
公明andGitHub 4f7b21cb7e Update config.yaml 2026-07-01 10:49:31 +08:00
公明andGitHub 9fae9db906 Delete internal/project/user_verbatim_anchor_test.go 2026-07-01 10:48:29 +08:00
公明andGitHub 7ecd8c61e8 Delete internal/project/user_verbatim_anchor.go 2026-07-01 10:48:09 +08:00
公明andGitHub bdb0326e47 Add files via upload 2026-07-01 10:46:53 +08:00
公明andGitHub 8dccc6aa06 Add files via upload 2026-07-01 10:44:27 +08:00
公明andGitHub fd4bbe8d76 Update config.yaml 2026-06-30 20:22:19 +08:00
公明andGitHub d80651e4d8 Add files via upload 2026-06-30 20:16:43 +08:00
公明andGitHub f920ff0a5d Update config.yaml 2026-06-30 20:15:26 +08:00
公明andGitHub ce8b57501d Add files via upload 2026-06-30 20:14:28 +08:00
公明andGitHub ecb38a3959 Add files via upload 2026-06-30 20:13:31 +08:00
公明andGitHub e69fdb71ca Add files via upload 2026-06-30 20:11:54 +08:00
公明andGitHub 6aa1631748 Add files via upload 2026-06-30 20:10:36 +08:00
公明andGitHub 52de3b0f41 Add files via upload 2026-06-30 20:09:18 +08:00
公明andGitHub e537e55198 Add files via upload 2026-06-30 20:07:28 +08:00
公明andGitHub dc20b4804e Update config.yaml 2026-06-30 19:55:00 +08:00
公明andGitHub 6245d69364 Add files via upload 2026-06-30 19:53:44 +08:00
公明andGitHub ede32951bf Add files via upload 2026-06-30 19:52:30 +08:00
公明andGitHub 866a8ebccf Add files via upload 2026-06-30 19:10:46 +08:00
公明andGitHub 276b3f7ef5 Add files via upload 2026-06-30 18:39:26 +08:00
公明andGitHub 81e461db54 Update config.yaml 2026-06-30 18:38:27 +08:00
公明andGitHub 02cd488a3d Add files via upload 2026-06-30 18:06:15 +08:00
公明andGitHub b4b2f55665 Add files via upload 2026-06-30 18:04:16 +08:00
公明andGitHub 7aa0ebea6d Add files via upload 2026-06-30 18:02:08 +08:00
公明andGitHub 63ef4399f8 Add files via upload 2026-06-30 18:00:00 +08:00
公明andGitHub 553d0ed6bf Add files via upload 2026-06-30 17:59:02 +08:00
公明andGitHub d92bbbea07 Add files via upload 2026-06-30 17:56:40 +08:00
公明andGitHub f89ad1b42d Add files via upload 2026-06-30 16:00:00 +08:00
公明andGitHub bbe14c1861 Add files via upload 2026-06-30 15:00:50 +08:00
公明andGitHub 2fc37fefd1 Add files via upload 2026-06-30 14:38:49 +08:00
公明andGitHub ded8ac5a3f Add files via upload 2026-06-30 13:03:40 +08:00
公明andGitHub bf44cf58d3 Add files via upload 2026-06-30 11:55:32 +08:00
公明andGitHub 6d390e80d5 Add files via upload 2026-06-30 11:34:38 +08:00
公明andGitHub cfc49ba16f Add files via upload 2026-06-30 11:06:29 +08:00
公明andGitHub d03f2fcf2b Add files via upload 2026-06-30 10:50:29 +08:00
公明andGitHub 6e67684bba Add files via upload 2026-06-30 00:16:31 +08:00
公明andGitHub 8f9d2f381a Add files via upload 2026-06-29 16:57:32 +08:00
公明andGitHub 89c275269f Update config.yaml 2026-06-29 16:52:45 +08:00
公明andGitHub cb4900c61d Add files via upload 2026-06-29 16:51:54 +08:00
公明andGitHub 5c192cd308 Add files via upload 2026-06-29 16:46:26 +08:00
公明andGitHub 8571e41138 Add files via upload 2026-06-29 16:24:43 +08:00
公明andGitHub e1a74b29b1 Add files via upload 2026-06-29 16:16:59 +08:00
公明andGitHub 39f1c72755 Add files via upload 2026-06-29 14:35:52 +08:00
公明andGitHub dd3621e89d Add files via upload 2026-06-29 14:18:08 +08:00
公明andGitHub 0bcb16e021 Add files via upload 2026-06-29 10:41:42 +08:00
公明andGitHub ed64803a51 Update config.yaml 2026-06-28 01:15:40 +08:00
公明andGitHub 25e03dee84 Add files via upload 2026-06-28 01:15:10 +08:00
公明andGitHub 58dcafd15f Add files via upload 2026-06-28 00:56:22 +08:00
公明andGitHub 997c4e7262 Add files via upload 2026-06-27 01:44:08 +08:00
公明andGitHub ac370b0ada Add files via upload 2026-06-27 01:42:44 +08:00
公明andGitHub 017db2b9a8 Add files via upload 2026-06-27 01:41:36 +08:00
公明andGitHub 86b4803683 Add files via upload 2026-06-27 01:40:12 +08:00
公明andGitHub 4d98264fc3 Add files via upload 2026-06-27 01:38:02 +08:00
公明andGitHub fd1de4ea94 Add files via upload 2026-06-27 01:36:09 +08:00
公明andGitHub 41ba3baca9 Add files via upload 2026-06-27 01:35:46 +08:00
公明andGitHub 2e908daebb Add files via upload 2026-06-27 00:34:19 +08:00
公明andGitHub c1763e1b9a Add files via upload 2026-06-27 00:03:16 +08:00
公明andGitHub 70e5d28619 Add files via upload 2026-06-26 23:54:29 +08:00
公明andGitHub 49990ecb4f Add files via upload 2026-06-26 23:50:13 +08:00
公明andGitHub c91806c0c4 Add files via upload 2026-06-26 23:11:52 +08:00
公明andGitHub e537236bf3 Add files via upload 2026-06-26 23:10:11 +08:00
公明andGitHub 7eeffb1933 Add files via upload 2026-06-26 18:16:30 +08:00
公明andGitHub 0556b29d40 Add files via upload 2026-06-26 14:34:45 +08:00
公明andGitHub be3c0cfa64 Add files via upload 2026-06-26 14:31:47 +08:00
公明andGitHub 8e5f40d226 Add files via upload 2026-06-26 14:30:00 +08:00
公明andGitHub 4b6719a6f3 Add files via upload 2026-06-26 14:27:32 +08:00
公明andGitHub 7c8f3228f8 Add files via upload 2026-06-26 14:25:14 +08:00
公明andGitHub 537843b6b8 Add files via upload 2026-06-26 14:24:01 +08:00
公明andGitHub 4a57574cf9 Add files via upload 2026-06-26 14:21:51 +08:00
公明andGitHub 0168530084 Add files via upload 2026-06-26 10:57:59 +08:00
公明andGitHub 4184a7b6f0 Add files via upload 2026-06-26 10:54:59 +08:00
公明andGitHub fb3b4dd6e5 Add files via upload 2026-06-26 01:22:30 +08:00
公明andGitHub 7e4a8db7af Add files via upload 2026-06-26 01:01:49 +08:00
公明andGitHub 6a72c95b9f Add files via upload 2026-06-26 00:58:29 +08:00
公明andGitHub 447be050cd Add files via upload 2026-06-25 21:28:46 +08:00
公明andGitHub 9b75c43f7b Add files via upload 2026-06-25 15:15:01 +08:00
公明andGitHub a443454753 Add files via upload 2026-06-25 14:56:56 +08:00
公明andGitHub 08822ba5df Update config.yaml 2026-06-25 14:56:31 +08:00
公明andGitHub eda75fb98f Add files via upload 2026-06-25 14:55:10 +08:00
公明andGitHub e6978a7994 Add files via upload 2026-06-25 14:52:39 +08:00
公明andGitHub 1db0f4740f Add files via upload 2026-06-25 14:50:28 +08:00
公明andGitHub 6e4ff96dcd Add files via upload 2026-06-25 14:48:25 +08:00
公明andGitHub 95470fefbc Add files via upload 2026-06-25 14:47:16 +08:00
公明andGitHub 5e075bb198 Add files via upload 2026-06-25 14:45:43 +08:00
公明andGitHub 84ed887c5c Update config.yaml 2026-06-24 23:36:36 +08:00
公明andGitHub 056b40ac66 Update config.yaml 2026-06-24 23:32:47 +08:00
公明andGitHub 26a9902286 Add files via upload 2026-06-24 23:31:35 +08:00
公明andGitHub cfe9573ac3 Add files via upload 2026-06-24 23:30:40 +08:00
公明andGitHub db2262a1a0 Add files via upload 2026-06-24 23:28:43 +08:00
公明andGitHub ab5c2d5cca Add files via upload 2026-06-24 23:27:29 +08:00
公明andGitHub 1ae6930db1 Add files via upload 2026-06-24 23:26:01 +08:00
公明andGitHub 8918f432d8 Add files via upload 2026-06-24 23:24:36 +08:00
公明andGitHub b4810c9499 Update shell no output timeout to 1200 seconds
Increased the shell no output timeout from 300 seconds to 1200 seconds to prevent premature termination.
2026-06-24 18:30:08 +08:00
公明andGitHub 51bf6ae4b3 Add files via upload 2026-06-24 18:20:12 +08:00
公明andGitHub 5f27482921 Add files via upload 2026-06-24 18:18:05 +08:00
公明andGitHub 6becada509 Add files via upload 2026-06-24 18:15:31 +08:00
公明andGitHub b029d88359 Add files via upload 2026-06-24 18:14:04 +08:00
公明andGitHub 4dcad2ea83 Add files via upload 2026-06-24 18:11:31 +08:00
公明andGitHub ff9f0c787a Add files via upload 2026-06-24 18:09:51 +08:00
公明andGitHub 01849045ad Add 'exec' to always visible tools in config.yaml 2026-06-24 17:36:24 +08:00
公明andGitHub c7eacdf3eb Update config.yaml 2026-06-24 17:24:52 +08:00
公明andGitHub 5c32b21f22 Add files via upload 2026-06-24 17:24:14 +08:00
公明andGitHub 8b8ecfe718 Add files via upload 2026-06-24 17:23:44 +08:00
公明andGitHub bbb7c319af Add files via upload 2026-06-24 17:21:51 +08:00
公明andGitHub 7eb2fd50f3 Add files via upload 2026-06-24 17:19:29 +08:00
公明andGitHub 85d58eeeb3 Add files via upload 2026-06-24 17:17:33 +08:00
公明andGitHub b6a6009629 Add files via upload 2026-06-24 17:15:34 +08:00
公明andGitHub 810d689132 Add files via upload 2026-06-24 12:08:13 +08:00
公明andGitHub 87f1808ead Add files via upload 2026-06-24 10:46:55 +08:00
公明andGitHub e28ae39b9a Update config.yaml 2026-06-24 02:04:49 +08:00
公明andGitHub df34ceda68 Add files via upload 2026-06-24 01:50:13 +08:00
公明andGitHub 3e69a50f87 Add files via upload 2026-06-24 01:49:43 +08:00
公明andGitHub 53325ce07d Add files via upload 2026-06-24 01:49:09 +08:00
公明andGitHub d85de3461b Add files via upload 2026-06-24 01:47:33 +08:00
公明andGitHub 9306303d99 Add files via upload 2026-06-24 01:46:30 +08:00
公明andGitHub 1e8f72ed74 Add files via upload 2026-06-24 01:44:47 +08:00
公明andGitHub 0198f50314 Add files via upload 2026-06-24 01:43:37 +08:00
公明andGitHub 560d0dca43 Add files via upload 2026-06-24 01:42:15 +08:00
公明andGitHub 47486a49c2 Update version number to v1.6.44 2026-06-23 21:17:08 +08:00
公明andGitHub 476727933d Update config.yaml 2026-06-23 21:16:41 +08:00
公明andGitHub 8bb50e8323 Add files via upload 2026-06-23 21:15:45 +08:00
公明andGitHub e74f2a2292 Add files via upload 2026-06-23 21:14:08 +08:00
公明andGitHub 4799d0dba7 Add files via upload 2026-06-23 21:12:26 +08:00
公明andGitHub 1db917061d Add files via upload 2026-06-23 21:10:47 +08:00
公明andGitHub 41cd7db30f Add files via upload 2026-06-23 21:08:59 +08:00
公明andGitHub 68b3265f3f Add files via upload 2026-06-23 21:07:01 +08:00
公明andGitHub 05dc4395a1 Add files via upload 2026-06-23 21:06:14 +08:00
公明andGitHub 637a35748b Add files via upload 2026-06-23 21:03:59 +08:00
公明andGitHub 5d77a99236 Add files via upload 2026-06-23 21:01:35 +08:00
公明andGitHub e84d936f85 Add files via upload 2026-06-23 20:59:20 +08:00
公明andGitHub e748201ae8 Add files via upload 2026-06-23 20:57:47 +08:00
公明andGitHub 7a3c67458c Add files via upload 2026-06-23 16:53:32 +08:00
公明andGitHub 6e9e43eec8 Add files via upload 2026-06-23 15:43:15 +08:00
公明andGitHub bca86e48ae Add files via upload 2026-06-23 15:40:04 +08:00
公明andGitHub 3f3b8b4db4 Add files via upload 2026-06-23 15:37:23 +08:00
公明andGitHub b366dc0287 Add files via upload 2026-06-23 15:35:12 +08:00
公明andGitHub a52452ceea Add files via upload 2026-06-23 15:32:41 +08:00
公明andGitHub 5b87667782 Update config.yaml 2026-06-23 15:32:18 +08:00
公明andGitHub 4f0e812d37 Add files via upload 2026-06-23 15:31:23 +08:00
公明andGitHub 79691c021f Add files via upload 2026-06-23 15:09:53 +08:00
公明andGitHub 5a8309a015 Add files via upload 2026-06-23 15:07:41 +08:00
公明andGitHub 6244197339 Add files via upload 2026-06-23 15:06:02 +08:00
公明andGitHub eb14aca05a Add files via upload 2026-06-23 15:03:23 +08:00
公明andGitHub 091e8a4da8 Add files via upload 2026-06-23 15:00:44 +08:00
公明andGitHub 48ce0c519e Add files via upload 2026-06-23 12:34:50 +08:00
公明andGitHub afc37051c0 Add files via upload 2026-06-23 12:33:35 +08:00
公明andGitHub 2964247361 Add files via upload 2026-06-23 12:31:05 +08:00
公明andGitHub 02919df476 Add files via upload 2026-06-23 12:28:37 +08:00
公明andGitHub c3294d96a2 Add files via upload 2026-06-23 12:28:07 +08:00
公明andGitHub c8b8b41bda Add files via upload 2026-06-23 12:26:40 +08:00
公明andGitHub 9a4c333b90 Add files via upload 2026-06-23 12:25:20 +08:00
公明andGitHub 8e21ae290a Add files via upload 2026-06-23 12:22:50 +08:00
公明andGitHub b9d102d046 Add files via upload 2026-06-23 11:54:28 +08:00
公明andGitHub 8c85494a05 Add files via upload 2026-06-23 11:52:15 +08:00
公明andGitHub c3d2a41301 Add files via upload 2026-06-23 01:54:29 +08:00
公明andGitHub 1a2e282d46 Add files via upload 2026-06-23 01:39:55 +08:00
公明andGitHub 8129f2147f Delete internal/multiagent/eino_empty_response_test.go 2026-06-23 01:37:34 +08:00
公明andGitHub 4a9889f0af Add files via upload 2026-06-23 01:36:48 +08:00
公明andGitHub 732d47a965 Add files via upload 2026-06-22 23:31:42 +08:00
公明andGitHub e22382aab0 Add files via upload 2026-06-22 23:29:57 +08:00
公明andGitHub b6ff80adf2 Add files via upload 2026-06-22 23:27:30 +08:00
公明andGitHub 51f1cfde2f Add files via upload 2026-06-22 23:12:53 +08:00
公明andGitHub b2c8913014 Add files via upload 2026-06-22 17:53:52 +08:00
公明andGitHub ae98288b62 Add files via upload 2026-06-22 15:53:31 +08:00
公明andGitHub 9955e856a0 Add files via upload 2026-06-22 15:48:44 +08:00
公明andGitHub 018544e5f9 Add files via upload 2026-06-22 15:43:39 +08:00
公明andGitHub c1c86e4632 Add files via upload 2026-06-22 13:47:53 +08:00
公明andGitHub 08d77bc12b Add files via upload 2026-06-21 01:56:48 +08:00
公明andGitHub ce73a7b3e4 Add files via upload 2026-06-21 01:55:25 +08:00
公明andGitHub f78f424aab Add files via upload 2026-06-21 01:53:55 +08:00
公明andGitHub e19d8e39bd Add files via upload 2026-06-21 01:52:14 +08:00
公明andGitHub ecf594a25b Update config.yaml 2026-06-20 20:37:48 +08:00
公明andGitHub d5759f6d83 Add files via upload 2026-06-20 19:57:07 +08:00
公明andGitHub 81b3f64b15 Add files via upload 2026-06-20 19:55:32 +08:00
公明andGitHub 0e0f1352f0 Add files via upload 2026-06-20 19:52:33 +08:00
公明andGitHub ffba311afd Add files via upload 2026-06-20 19:47:47 +08:00
公明andGitHub d9ed36cfb1 Add files via upload 2026-06-20 19:45:29 +08:00
公明andGitHub b7f80b78ee Add files via upload 2026-06-20 19:39:39 +08:00
公明andGitHub 8f8e5cfff5 Increase rune limits in config.yaml 2026-06-20 19:37:50 +08:00
公明andGitHub 120f860640 Add files via upload 2026-06-20 19:36:35 +08:00
公明andGitHub 90cd119a83 Add files via upload 2026-06-20 19:35:06 +08:00
公明andGitHub 56d597e0c5 Add files via upload 2026-06-20 19:31:56 +08:00
公明andGitHub 11ab5cde8f Add files via upload 2026-06-20 19:28:34 +08:00
公明andGitHub 46a7d338a4 Add files via upload 2026-06-20 17:25:44 +08:00
公明andGitHub 46f68cc1d4 Update config.yaml 2026-06-20 16:19:57 +08:00
公明andGitHub 7003cdb2e3 Add files via upload 2026-06-20 15:34:58 +08:00
公明andGitHub 4e5e6208bd Add files via upload 2026-06-20 15:29:36 +08:00
公明andGitHub 6a7e78a846 Add files via upload 2026-06-20 15:28:10 +08:00
公明andGitHub 88c6fbfb75 Add files via upload 2026-06-20 15:26:49 +08:00
公明andGitHub 1cd6d0fa90 Add files via upload 2026-06-20 15:24:40 +08:00
公明andGitHub 24390db100 Add files via upload 2026-06-19 01:41:32 +08:00
公明andGitHub c000fe5195 Add files via upload 2026-06-19 01:39:53 +08:00
公明andGitHub 0b4a11d01a Add files via upload 2026-06-19 01:38:30 +08:00
公明andGitHub d433e44a7d Add files via upload 2026-06-19 01:36:52 +08:00
公明andGitHub 7de51fe0ea Update config.yaml 2026-06-19 00:05:50 +08:00
公明andGitHub a354cf97e5 Add files via upload 2026-06-19 00:04:38 +08:00
公明andGitHub c180f07c7e Add files via upload 2026-06-19 00:02:53 +08:00
公明andGitHub 15730d3ef4 Add files via upload 2026-06-19 00:01:20 +08:00
公明andGitHub b7fa18b6d4 Add files via upload 2026-06-18 23:44:04 +08:00
公明andGitHub 8d622f63ff Update version to v1.6.40 in config.yaml 2026-06-18 23:24:14 +08:00
公明andGitHub 20b05146fb Add files via upload 2026-06-18 23:23:48 +08:00
公明andGitHub d8768eae76 Add files via upload 2026-06-18 23:21:58 +08:00
公明andGitHub 9232cee38d Add files via upload 2026-06-18 23:20:39 +08:00
公明andGitHub 6c975e63d2 Add files via upload 2026-06-18 23:19:09 +08:00
公明andGitHub e175523b82 Add files via upload 2026-06-18 23:17:30 +08:00
公明andGitHub ae23427d9e Add files via upload 2026-06-18 21:53:20 +08:00
公明andGitHub 93a2504ce3 Add files via upload 2026-06-18 21:52:36 +08:00
公明andGitHub 09b0479fb3 Add files via upload 2026-06-18 21:50:44 +08:00
公明andGitHub 2bdc9d4fe0 Add files via upload 2026-06-18 21:48:33 +08:00
公明andGitHub 01b3d8056c Add files via upload 2026-06-18 21:09:00 +08:00
公明andGitHub ed479d5e4d Update config.yaml 2026-06-18 12:53:56 +08:00
公明andGitHub a49f595231 Update config.yaml 2026-06-18 12:49:38 +08:00
公明andGitHub 82cf014a5e Update config.yaml 2026-06-18 12:48:07 +08:00
公明andGitHub 508de5fad0 Add files via upload 2026-06-18 12:47:24 +08:00
公明andGitHub 6712344411 Add files via upload 2026-06-18 12:46:46 +08:00
公明andGitHub 7eadccbff6 Add files via upload 2026-06-18 12:44:42 +08:00
公明andGitHub 01b361e4a7 Add files via upload 2026-06-18 12:42:56 +08:00
公明andGitHub f6ce31c961 Delete internal/图片画质提升.jpeg 2026-06-18 12:41:18 +08:00
公明andGitHub d5a0f93c6c Add files via upload 2026-06-18 12:40:54 +08:00
公明andGitHub 56faefaaf9 Add files via upload 2026-06-18 12:39:09 +08:00
公明andGitHub 16e9c5874a Delete internal/图片画质提升.jpeg 2026-06-18 12:38:53 +08:00
公明andGitHub 41b5cdde6b Add files via upload 2026-06-18 12:38:36 +08:00
公明andGitHub cf1f8515d9 Delete internal directory 2026-06-18 12:37:39 +08:00
公明andGitHub 5e2b30c029 Add files via upload 2026-06-17 14:00:23 +08:00
公明andGitHub 8c7c22369e Add files via upload 2026-06-17 12:30:20 +08:00
公明andGitHub 9b1aba692b Add files via upload 2026-06-17 12:08:23 +08:00
公明andGitHub db730b48c1 Add files via upload 2026-06-17 12:06:23 +08:00
公明andGitHub dfb7dd7390 Add files via upload 2026-06-17 12:04:17 +08:00
公明andGitHub 9f6eb33047 Add files via upload 2026-06-17 12:02:24 +08:00
公明andGitHub 616d87f4cc Add files via upload 2026-06-17 10:50:19 +08:00
公明andGitHub 8d999792b8 Update config.yaml 2026-06-16 16:22:14 +08:00
公明andGitHub afae8970d1 Add files via upload 2026-06-16 16:21:24 +08:00
公明andGitHub 4d7330c5c3 Add files via upload 2026-06-16 15:48:11 +08:00
公明andGitHub 8884bfb0b4 Add files via upload 2026-06-16 13:07:04 +08:00
公明andGitHub fb351c80b6 Add files via upload 2026-06-15 22:06:46 +08:00
公明andGitHub 664834e338 Add files via upload 2026-06-15 22:03:29 +08:00
公明andGitHub 95bf62db88 Add files via upload 2026-06-15 21:56:42 +08:00
公明andGitHub 656242614d Add files via upload 2026-06-15 21:41:02 +08:00
公明andGitHub a9d6d8c00e Add files via upload 2026-06-15 21:30:39 +08:00
公明andGitHub 0d6a43c0a8 Add files via upload 2026-06-15 20:43:51 +08:00
公明andGitHub 702f286eb1 Add files via upload 2026-06-15 20:24:17 +08:00
公明andGitHub f4906543a8 Update config.yaml 2026-06-15 11:55:49 +08:00
公明andGitHub b073421637 Add files via upload 2026-06-15 11:55:04 +08:00
公明andGitHub 08436c27aa Add files via upload 2026-06-15 11:49:53 +08:00
公明andGitHub 25ce0b221f Add files via upload 2026-06-14 21:07:51 +08:00
公明andGitHub 87e629f270 Add files via upload 2026-06-14 20:19:52 +08:00
公明andGitHub 04f8d73b0e Add files via upload 2026-06-14 19:58:04 +08:00
公明andGitHub 33e4f023b5 Add files via upload 2026-06-14 19:48:07 +08:00
公明andGitHub fc2e822448 Add files via upload 2026-06-14 19:46:13 +08:00
公明andGitHub 7487c45799 Add files via upload 2026-06-14 19:43:59 +08:00
公明andGitHub 6c4b3bf131 Add files via upload 2026-06-14 19:42:14 +08:00
公明andGitHub 54cea1b172 Add files via upload 2026-06-13 19:56:09 +08:00
公明andGitHub b8775997e4 Add files via upload 2026-06-13 12:32:30 +08:00
公明andGitHub 4223ec47f9 Add files via upload 2026-06-13 12:27:21 +08:00
公明andGitHub 9887589d99 Add files via upload 2026-06-13 12:15:55 +08:00
公明andGitHub b7c01f41c7 Add files via upload 2026-06-13 12:08:04 +08:00
公明andGitHub 1d3b4c44e1 Update config.yaml 2026-06-12 22:11:49 +08:00
公明andGitHub cbd64173b8 Add files via upload 2026-06-12 22:10:10 +08:00
公明andGitHub af71c6aa24 Add files via upload 2026-06-12 22:08:15 +08:00
公明andGitHub 97a73a1cb6 Add files via upload 2026-06-12 22:06:41 +08:00
公明andGitHub 83e1c707ca Add files via upload 2026-06-12 22:04:57 +08:00
公明andGitHub 96ccbff77c Add files via upload 2026-06-12 21:28:51 +08:00
公明andGitHub c4bd8b93f6 Delete install-tools.sh 2026-06-12 21:26:22 +08:00
公明andGitHub d005268d28 Add files via upload 2026-06-12 19:43:38 +08:00
公明andGitHub 7f4e8d2ad2 Add files via upload 2026-06-12 19:41:47 +08:00
公明andGitHub f3be355820 Add files via upload 2026-06-12 19:39:01 +08:00
公明andGitHub bf0ce33e3f Add files via upload 2026-06-12 19:36:45 +08:00
公明andGitHub 4661862a1a Add files via upload 2026-06-11 18:03:09 +08:00
公明andGitHub f319a0f243 Add files via upload 2026-06-11 18:01:38 +08:00
公明andGitHub 15c4802319 Add files via upload 2026-06-11 17:18:58 +08:00
公明andGitHub 6ffde48b0c Add files via upload 2026-06-11 16:54:36 +08:00
公明andGitHub c5e2f0d95d Add files via upload 2026-06-11 16:02:48 +08:00
公明andGitHub 28a826d5b7 Add files via upload 2026-06-11 15:56:25 +08:00
公明andGitHub 6365de7018 Add files via upload 2026-06-11 11:50:31 +08:00
公明andGitHub 2e4bf7197b Add files via upload 2026-06-11 11:48:17 +08:00
公明andGitHub ed4ba08163 Add files via upload 2026-06-11 11:46:23 +08:00
公明andGitHub 8b5e55a673 Add files via upload 2026-06-11 11:44:20 +08:00
公明andGitHub e8a75e5105 Update config.yaml 2026-06-11 02:03:03 +08:00
公明andGitHub 48976ed650 Add files via upload 2026-06-11 01:48:42 +08:00
公明andGitHub dc9ecae7fd Add files via upload 2026-06-11 01:43:35 +08:00
公明andGitHub a9d0a59f7a Add files via upload 2026-06-11 01:41:57 +08:00
公明andGitHub 5ec4729b83 Add files via upload 2026-06-11 01:40:00 +08:00
公明andGitHub 9857003018 Add files via upload 2026-06-11 01:38:25 +08:00
公明andGitHub a6e7885fed Add files via upload 2026-06-11 01:31:18 +08:00
公明andGitHub e69375451c Add files via upload 2026-06-11 01:29:07 +08:00
公明andGitHub 07e7f104ad Add files via upload 2026-06-11 01:27:50 +08:00
公明andGitHub ffce9185bb Add files via upload 2026-06-11 01:16:20 +08:00
公明andGitHub 612f16455d Add files via upload 2026-06-11 01:14:52 +08:00
公明andGitHub ecd5b40bc2 Add files via upload 2026-06-11 01:13:11 +08:00
公明andGitHub 5aa7306c9b Update config.yaml 2026-06-11 00:53:39 +08:00
公明andGitHub 1027d9f6cf Update config.yaml 2026-06-11 00:41:27 +08:00
公明andGitHub e05b008903 Add files via upload 2026-06-11 00:38:00 +08:00
公明andGitHub 9bcc7a27fe Add files via upload 2026-06-11 00:35:44 +08:00
公明andGitHub fb3087b760 Add files via upload 2026-06-10 14:20:24 +08:00
公明andGitHub cd48a43b7e Add files via upload 2026-06-10 14:18:17 +08:00
公明andGitHub 07be48ae59 Add files via upload 2026-06-10 14:06:33 +08:00
公明andGitHub 529f94a4f7 Add files via upload 2026-06-10 11:33:05 +08:00
公明andGitHub d2fe023d7e Delete internal/database/project_fact_version.go 2026-06-10 11:19:21 +08:00
公明andGitHub 09e858619e Add files via upload 2026-06-10 11:17:29 +08:00
公明andGitHub 9c54291295 Add files via upload 2026-06-10 11:14:32 +08:00
公明andGitHub b3f7b8494b Delete web/static/js/knowledge.js.bak 2026-06-09 21:06:14 +08:00
公明andGitHub 849c644a86 Add files via upload 2026-06-09 21:05:29 +08:00
公明andGitHub 9e0525abc1 Add files via upload 2026-06-09 20:44:41 +08:00
公明andGitHub 6bacac2e6a Add files via upload 2026-06-09 20:27:45 +08:00
公明andGitHub 244307b52c Add files via upload 2026-06-09 20:26:18 +08:00
公明andGitHub faaac5fbd7 Add files via upload 2026-06-09 20:24:53 +08:00
公明andGitHub 3392fefedf Add files via upload 2026-06-09 20:23:09 +08:00
公明andGitHub abef51b805 Add files via upload 2026-06-09 18:05:29 +08:00
公明andGitHub 8143d8f220 Add files via upload 2026-06-09 17:53:37 +08:00
公明andGitHub 73337c5226 Add files via upload 2026-06-09 17:44:39 +08:00
公明andGitHub c9c9ca1eec Add files via upload 2026-06-09 17:39:27 +08:00
公明andGitHub 25f8b610fb Add files via upload 2026-06-09 17:37:04 +08:00
公明andGitHub 6bfa7b8959 Add files via upload 2026-06-09 17:34:36 +08:00
公明andGitHub 99a41d8188 Add files via upload 2026-06-09 14:32:11 +08:00
公明andGitHub 6d04753761 Add files via upload 2026-06-09 14:28:15 +08:00
公明andGitHub a08df7ab79 Add files via upload 2026-06-09 14:23:08 +08:00
公明andGitHub 3123a07c48 Update config.yaml 2026-06-09 14:03:09 +08:00
公明andGitHub 7b3d35fabe Add files via upload 2026-06-09 13:39:22 +08:00
公明andGitHub cb17d3a5c1 Add files via upload 2026-06-09 11:03:51 +08:00
公明andGitHub c2892ccd33 Add files via upload 2026-06-08 15:55:03 +08:00
公明andGitHub 60b0bb3252 Update config.yaml 2026-06-08 13:18:38 +08:00
公明andGitHub 3b9e5f3b1c Add files via upload 2026-06-08 13:17:36 +08:00
公明andGitHub 1a9694b216 Add files via upload 2026-06-08 13:08:15 +08:00
公明andGitHub a1c7e0dc7d Add files via upload 2026-06-07 20:20:41 +08:00
公明andGitHub 23e08b1697 Add files via upload 2026-06-07 20:20:09 +08:00
公明andGitHub 9002505569 Add files via upload 2026-06-07 20:18:36 +08:00
公明andGitHub b1aaaa79c7 Add files via upload 2026-06-07 20:17:16 +08:00
公明andGitHub 4edbeb8f2d Add files via upload 2026-06-07 20:15:44 +08:00
公明andGitHub 5b5a532d4f Add files via upload 2026-06-07 19:12:43 +08:00
公明andGitHub c1bd94684c Add files via upload 2026-06-07 15:35:49 +08:00
公明andGitHub 8b48e5e396 Add files via upload 2026-06-07 05:11:00 +08:00
公明andGitHub c2f8ebc743 Add files via upload 2026-06-06 21:43:50 +08:00
公明andGitHub 15e1a15671 Add files via upload 2026-06-05 17:57:23 +08:00
公明andGitHub 5c3b157159 Add files via upload 2026-06-05 17:15:50 +08:00
公明andGitHub e5f6175277 Add files via upload 2026-06-05 16:54:25 +08:00
公明andGitHub 1dc5d18fb3 Add files via upload 2026-06-05 15:21:50 +08:00
公明andGitHub 00ea3d7a9c Update config.yaml 2026-06-05 15:00:17 +08:00
公明andGitHub 8d48ccdfe4 Add files via upload 2026-06-05 11:41:29 +08:00
公明andGitHub c9f1a2001e Update config.yaml 2026-06-05 11:31:27 +08:00
公明andGitHub 905dd519ed Add files via upload 2026-06-05 11:22:35 +08:00
公明andGitHub 60ea106301 Add files via upload 2026-06-05 10:38:24 +08:00
公明andGitHub 92c0ae19bb Add files via upload 2026-06-05 10:35:41 +08:00
公明andGitHub 43c6a0648d Add files via upload 2026-06-05 10:17:10 +08:00
公明andGitHub 6b96e77120 Add files via upload 2026-06-05 10:13:00 +08:00
公明andGitHub a397922361 Add files via upload 2026-06-04 17:57:12 +08:00
公明andGitHub 1e6e92b4af Add files via upload 2026-06-04 13:37:24 +08:00
公明andGitHub 444f85b9c4 Add files via upload 2026-06-04 13:36:46 +08:00
公明andGitHub 679a8192ae Add files via upload 2026-06-04 13:34:26 +08:00
公明andGitHub 9a3f5e54b0 Add files via upload 2026-06-04 10:54:16 +08:00
公明andGitHub ce2eb56253 Add files via upload 2026-06-04 10:50:00 +08:00
公明andGitHub da6cb347df Add files via upload 2026-06-04 10:48:09 +08:00
公明andGitHub fb2658b2eb Add files via upload 2026-06-04 10:44:48 +08:00
公明andGitHub e791782c46 Add files via upload 2026-06-04 10:33:39 +08:00
公明andGitHub 9b0efbb90f Add files via upload 2026-06-04 10:29:42 +08:00
公明andGitHub 0d9eebffe6 Update config.yaml 2026-06-03 17:18:56 +08:00
公明andGitHub 403d4421d2 Add files via upload 2026-06-03 17:18:26 +08:00
公明andGitHub e606369e31 Add files via upload 2026-06-03 17:16:48 +08:00
公明andGitHub da8fdafe59 Add files via upload 2026-06-03 17:13:54 +08:00
公明andGitHub 0492365430 Add files via upload 2026-06-03 17:11:44 +08:00
公明andGitHub 3a6bc60276 Add files via upload 2026-06-03 17:09:56 +08:00
公明andGitHub 3a401ade68 Add files via upload 2026-06-03 17:08:59 +08:00
公明andGitHub 71aade5bd9 Update config.yaml 2026-06-03 17:01:30 +08:00
公明andGitHub a5f11cc003 Add files via upload 2026-06-02 23:41:49 +08:00
公明andGitHub dcea95968b Add files via upload 2026-06-02 14:27:10 +08:00
公明andGitHub 7db0294d5c Add files via upload 2026-06-02 13:38:16 +08:00
公明andGitHub b4d85c5a77 Update config.yaml 2026-06-02 13:36:27 +08:00
公明andGitHub fcbc7b9226 Add files via upload 2026-06-02 13:35:53 +08:00
公明andGitHub b8b1e8431b Add files via upload 2026-06-02 13:34:12 +08:00
公明andGitHub 203a99bed4 Add files via upload 2026-06-02 13:32:05 +08:00
公明andGitHub 449781c029 Add files via upload 2026-06-02 13:29:47 +08:00
公明andGitHub 924f59015d Add files via upload 2026-06-02 13:28:38 +08:00
公明andGitHub f0fb634a6b Add files via upload 2026-06-02 13:27:15 +08:00
公明andGitHub b8dfb9556a Add files via upload 2026-06-02 13:25:00 +08:00
公明andGitHub 9c1d3ae85e Delete internal/agent/memory_compressor.go 2026-06-02 13:21:30 +08:00
公明andGitHub b8ebf023a0 Update config.yaml 2026-06-02 12:19:14 +08:00
公明andGitHub 604ce34d5e Merge pull request #136 from Opr4Mp3r/fix/sse-mcp-session-context
fix(mcp): keep SSE client session alive after connect
2026-06-02 11:37:23 +08:00
opr4andopr4 b29b36bfd5 fix(mcp): keep SSE client session alive after connect 2026-06-01 21:36:42 +08:00
公明andGitHub 11bab83fc5 Update config.yaml 2026-06-01 19:07:09 +08:00
公明andGitHub dc750e3680 Add files via upload 2026-06-01 19:06:25 +08:00
公明andGitHub 0236d1c155 Add files via upload 2026-06-01 19:04:14 +08:00
公明andGitHub be59ddcab6 Add files via upload 2026-06-01 17:35:41 +08:00
公明andGitHub 25464a68e6 Add files via upload 2026-05-31 19:07:26 +08:00
公明andGitHub eabfed09c9 Add files via upload 2026-05-31 13:33:32 +08:00
公明andGitHub cbcbd414cd Add files via upload 2026-05-29 17:59:19 +08:00
公明andGitHub 0933f9365b Update config.yaml 2026-05-29 17:18:05 +08:00
公明andGitHub e792891ff3 Add files via upload 2026-05-29 17:17:01 +08:00
公明andGitHub e14e5f15d3 Update config.yaml 2026-05-29 16:26:29 +08:00
公明andGitHub 4d5e0c5f21 Add files via upload 2026-05-29 15:12:43 +08:00
公明andGitHub b3238304ce Add files via upload 2026-05-29 14:22:56 +08:00
公明andGitHub 665e2ec73a Add files via upload 2026-05-29 14:22:32 +08:00
公明andGitHub d63d9c25b8 Add files via upload 2026-05-29 14:21:26 +08:00
公明andGitHub d1c63d0ba7 Add files via upload 2026-05-29 14:19:08 +08:00
公明andGitHub 55d6d449cd Add files via upload 2026-05-29 14:16:09 +08:00
公明andGitHub d4bc9646d9 Add files via upload 2026-05-29 14:12:21 +08:00
公明andGitHub b941f5a8d9 Add files via upload 2026-05-29 11:17:05 +08:00
公明andGitHub 97e2c0fd43 Add files via upload 2026-05-29 11:14:04 +08:00
公明andGitHub bd3e48c2d0 Add files via upload 2026-05-29 10:58:15 +08:00
公明andGitHub 8b0b91fddc Add files via upload 2026-05-29 10:56:18 +08:00
公明andGitHub 2b38595b42 Add files via upload 2026-05-29 10:54:39 +08:00
公明andGitHub 5c795439ee Update config.yaml 2026-05-28 15:49:18 +08:00
公明andGitHub df531910cf Add files via upload 2026-05-28 14:34:14 +08:00
公明andGitHub 8a089a826c Add files via upload 2026-05-28 14:15:41 +08:00
公明andGitHub 60b32ffc69 Add files via upload 2026-05-28 14:14:48 +08:00
公明andGitHub 21c36fcce8 Add files via upload 2026-05-28 14:12:44 +08:00
公明andGitHub 4d048f6da0 Add files via upload 2026-05-28 14:11:05 +08:00
公明andGitHub 03a2707b83 Add files via upload 2026-05-28 14:09:17 +08:00
公明andGitHub 9941f51b3e Add files via upload 2026-05-28 13:00:01 +08:00
公明andGitHub 1553e896c5 Add files via upload 2026-05-28 12:58:27 +08:00
公明andGitHub ea2184773e Add files via upload 2026-05-28 11:53:33 +08:00
公明andGitHub 764d8110ec Add files via upload 2026-05-28 11:21:07 +08:00
公明andGitHub e037f383f5 Add files via upload 2026-05-28 11:20:14 +08:00
公明andGitHub e40f7cb468 Add files via upload 2026-05-28 10:56:33 +08:00
公明andGitHub 72aca69204 Add files via upload 2026-05-28 10:52:18 +08:00
公明andGitHub 133da1c640 Add files via upload 2026-05-28 10:49:13 +08:00
公明andGitHub af78b47517 Add files via upload 2026-05-28 10:15:12 +08:00
公明andGitHub f5fabc05a4 Add files via upload 2026-05-27 21:15:58 +08:00
公明andGitHub 5cc53b1076 Add files via upload 2026-05-27 21:14:37 +08:00
公明andGitHub f1be2064db Add files via upload 2026-05-27 19:58:02 +08:00
公明andGitHub 0c9c2ec606 Add files via upload 2026-05-27 19:56:08 +08:00
公明andGitHub cf09dd36d8 Add files via upload 2026-05-27 19:01:30 +08:00
公明andGitHub c6e2701b30 Update config.yaml 2026-05-27 15:43:10 +08:00
公明andGitHub 42b5901d99 Add files via upload 2026-05-27 15:42:23 +08:00
公明andGitHub 117bed6839 Add files via upload 2026-05-27 15:34:53 +08:00
公明andGitHub bad323cd0e Add files via upload 2026-05-27 15:21:31 +08:00
公明andGitHub 8138f8b576 Add files via upload 2026-05-27 13:08:22 +08:00
公明andGitHub 74627d214b Add files via upload 2026-05-27 13:04:59 +08:00
公明andGitHub f622efe245 Add files via upload 2026-05-27 13:02:53 +08:00
公明andGitHub 3924b5285b Add files via upload 2026-05-27 11:48:50 +08:00
公明andGitHub 21f641bbd7 Add files via upload 2026-05-27 11:47:14 +08:00
公明andGitHub d913695303 Add files via upload 2026-05-27 11:45:51 +08:00
公明andGitHub 6bb3a73f73 Add files via upload 2026-05-27 11:44:15 +08:00
公明andGitHub f0a80a8e58 Add files via upload 2026-05-27 11:42:17 +08:00
公明andGitHub 3f9dbb4214 Add files via upload 2026-05-27 11:40:10 +08:00
公明andGitHub c0f0861b31 Update config.yaml 2026-05-26 18:56:25 +08:00
公明andGitHub 704137aa34 Add files via upload 2026-05-26 18:55:03 +08:00
公明andGitHub c56bf36df0 Add files via upload 2026-05-26 18:54:18 +08:00
公明andGitHub 5560f34c6c Add files via upload 2026-05-26 18:52:08 +08:00
公明andGitHub 70e9a73fc0 Add files via upload 2026-05-26 18:50:25 +08:00
公明andGitHub 12bc9d8ab6 Add files via upload 2026-05-26 18:49:01 +08:00
公明andGitHub f8db82a065 Update config.yaml 2026-05-26 17:57:55 +08:00
公明andGitHub 8ce30d9072 Add files via upload 2026-05-26 17:57:22 +08:00
公明andGitHub e6506d00e8 Add files via upload 2026-05-26 17:56:52 +08:00
公明andGitHub b2308617b8 Add files via upload 2026-05-26 17:54:11 +08:00
公明andGitHub cd17fdca33 Add files via upload 2026-05-26 17:52:28 +08:00
公明andGitHub 1acaccd09f Add files via upload 2026-05-26 17:50:36 +08:00
公明andGitHub 983fe650c1 Add files via upload 2026-05-26 17:49:46 +08:00
公明andGitHub 52d03dc849 Update config.yaml 2026-05-26 14:45:38 +08:00
公明andGitHub 9de72d9ad5 Update config.yaml 2026-05-26 14:42:20 +08:00
公明andGitHub d95275ffae Add files via upload 2026-05-26 14:37:24 +08:00
公明andGitHub 6cef93dbb7 Add files via upload 2026-05-26 14:36:40 +08:00
公明andGitHub dd3b1ae219 Add files via upload 2026-05-26 14:34:21 +08:00
公明andGitHub f42209682a Add files via upload 2026-05-26 14:31:59 +08:00
公明andGitHub 1b1aed1699 Add files via upload 2026-05-26 14:27:44 +08:00
公明andGitHub 44ced98863 Add files via upload 2026-05-26 14:24:32 +08:00
公明andGitHub 97834c162e Update config.yaml 2026-05-23 19:53:40 +08:00
公明andGitHub 9276f2f144 Add files via upload 2026-05-23 19:49:50 +08:00
公明andGitHub a454cada6a Add files via upload 2026-05-23 19:39:03 +08:00
公明andGitHub 99b53d4fbc Add files via upload 2026-05-23 19:35:30 +08:00
公明andGitHub a43a9deaea Add files via upload 2026-05-23 19:33:23 +08:00
公明andGitHub ce88da84c9 Add files via upload 2026-05-23 19:31:40 +08:00
公明andGitHub 15855c7073 Add files via upload 2026-05-23 19:29:49 +08:00
公明andGitHub 43eb3e546b Add files via upload 2026-05-22 17:23:01 +08:00
公明andGitHub 2d52c9b6ac Update config.yaml 2026-05-22 17:18:48 +08:00
公明andGitHub d5401b8b4c Update config.yaml 2026-05-22 17:17:48 +08:00
公明andGitHub 5fd4393a2e Add files via upload 2026-05-22 17:14:33 +08:00
公明andGitHub a049f6b5c2 Add files via upload 2026-05-22 17:13:55 +08:00
公明andGitHub acba8e5a39 Add files via upload 2026-05-22 17:11:34 +08:00
公明andGitHub f826b91362 Add files via upload 2026-05-22 17:09:54 +08:00
公明andGitHub 98c2de2a60 Add files via upload 2026-05-22 17:08:05 +08:00
公明andGitHub 1c4d4b305b Update config.yaml 2026-05-22 15:15:46 +08:00
公明andGitHub f210ac9a03 Add files via upload 2026-05-22 11:36:36 +08:00
公明andGitHub 6685076dfb Add files via upload 2026-05-22 11:35:02 +08:00
公明andGitHub 7f322653f6 Add files via upload 2026-05-22 11:32:36 +08:00
公明andGitHub 66ac2f1357 Add files via upload 2026-05-22 11:30:25 +08:00
公明andGitHub c446e22d0c Add files via upload 2026-05-22 11:28:51 +08:00
公明andGitHub 0358d3a67d Add files via upload 2026-05-22 10:30:19 +08:00
公明andGitHub 9b82f265fd Add files via upload 2026-05-20 18:24:17 +08:00
公明andGitHub 3d9cae58e4 Update config.yaml 2026-05-20 17:59:57 +08:00
公明andGitHub 1f1eadee5e Update config.yaml 2026-05-20 17:58:24 +08:00
公明andGitHub 0569255189 Add files via upload 2026-05-20 17:54:30 +08:00
公明andGitHub 8ccf90d067 Add files via upload 2026-05-20 17:52:22 +08:00
公明andGitHub b3be89f47d Add files via upload 2026-05-20 17:50:52 +08:00
公明andGitHub b9bf8f62d4 Add files via upload 2026-05-20 17:48:42 +08:00
公明andGitHub 05ca0c1480 Update config.yaml 2026-05-20 16:57:50 +08:00
公明andGitHub 47a4f3fc5b Add files via upload 2026-05-20 16:52:50 +08:00
公明andGitHub a3b378ae9e Add files via upload 2026-05-20 16:49:26 +08:00
公明andGitHub a904d26e78 Add files via upload 2026-05-20 16:47:34 +08:00
公明andGitHub 7ba7476c4f Add files via upload 2026-05-20 16:45:59 +08:00
公明andGitHub ae25a243ac Add files via upload 2026-05-20 16:43:38 +08:00
公明andGitHub 23bd6288ff Add files via upload 2026-05-20 16:39:13 +08:00
公明andGitHub fef21d3a24 Add files via upload 2026-05-20 16:36:50 +08:00
公明andGitHub 933bba4517 Update config.yaml 2026-05-20 16:12:13 +08:00
公明andGitHub e1d65437cc Add files via upload 2026-05-20 16:11:10 +08:00
公明andGitHub 9325aed1eb Add files via upload 2026-05-20 16:09:33 +08:00
公明andGitHub dee2b3ab42 Add files via upload 2026-05-20 16:07:33 +08:00
公明andGitHub a69bc93fa1 Add files via upload 2026-05-20 16:05:40 +08:00
公明andGitHub b1a620bfce Update config.yaml 2026-05-20 14:18:33 +08:00
公明andGitHub 61b164eec2 Add files via upload 2026-05-20 11:03:38 +08:00
公明andGitHub ba77e1837e Update config.yaml 2026-05-19 23:05:52 +08:00
公明andGitHub eacad60fd6 Add files via upload 2026-05-19 23:03:04 +08:00
公明andGitHub 70bf5c93bf Update config.yaml 2026-05-19 19:01:31 +08:00
公明andGitHub 08bd278d8c Update config.yaml 2026-05-19 18:56:24 +08:00
公明andGitHub 22746d64a3 Add files via upload 2026-05-19 18:53:46 +08:00
公明andGitHub 199392a5d5 Add files via upload 2026-05-19 18:52:22 +08:00
公明andGitHub aafb4cb584 Add files via upload 2026-05-19 18:50:28 +08:00
公明andGitHub 96e3dd397c Add files via upload 2026-05-19 18:48:17 +08:00
公明andGitHub ec0f17145b Add files via upload 2026-05-19 17:50:38 +08:00
公明andGitHub ed53da0999 Delete security directory 2026-05-19 17:49:21 +08:00
公明andGitHub dc440fc511 Delete robot directory 2026-05-19 17:49:10 +08:00
公明andGitHub 009ae59033 Delete logger directory 2026-05-19 17:48:59 +08:00
公明andGitHub f348b3245a Delete knowledge directory 2026-05-19 17:48:44 +08:00
公明andGitHub 0018c5219c Delete config directory 2026-05-19 17:48:33 +08:00
公明andGitHub 01a3e3677a Delete c2 directory 2026-05-19 17:48:22 +08:00
公明andGitHub a12ecdb46f Add files via upload 2026-05-19 17:47:56 +08:00
公明andGitHub 9f59230d74 Add files via upload 2026-05-19 17:46:33 +08:00
公明andGitHub 085c6a1c72 Add files via upload 2026-05-19 17:43:45 +08:00
公明andGitHub 7b3860971f Add files via upload 2026-05-19 17:42:12 +08:00
公明andGitHub f6f7b7b237 Add files via upload 2026-05-19 17:40:19 +08:00
公明andGitHub d5cf4b3b16 Add files via upload 2026-05-19 16:48:07 +08:00
公明andGitHub 3e58d8355b Add files via upload 2026-05-19 16:32:38 +08:00
公明andGitHub eb01ade63b Add files via upload 2026-05-19 16:29:05 +08:00
公明andGitHub d1dc15fa44 Add files via upload 2026-05-19 16:27:29 +08:00
公明andGitHub 73a39ef868 Add files via upload 2026-05-19 16:25:47 +08:00
公明andGitHub a022baef03 Add files via upload 2026-05-19 16:23:21 +08:00
公明andGitHub 59312d428e Add files via upload 2026-05-19 14:53:07 +08:00
公明andGitHub 951d14ef14 Update config.yaml 2026-05-18 23:51:19 +08:00
公明andGitHub 0eb22da6e9 Add files via upload 2026-05-18 23:50:55 +08:00
公明andGitHub 5fd9ef0514 Add files via upload 2026-05-18 23:47:10 +08:00
公明andGitHub 9a4f3c7d35 Add files via upload 2026-05-18 17:37:29 +08:00
公明andGitHub ead2ce3ecc Add files via upload 2026-05-18 17:28:14 +08:00
公明andGitHub 8733f3a2d2 Update config.yaml 2026-05-18 11:03:29 +08:00
公明andGitHub 8642f3ba31 Add files via upload 2026-05-17 17:11:16 +08:00
公明andGitHub 6a262a7367 Add files via upload 2026-05-17 17:09:16 +08:00
公明andGitHub eb9192ddb3 Add files via upload 2026-05-17 17:08:42 +08:00
公明andGitHub 5587e75628 Add files via upload 2026-05-17 17:06:53 +08:00
公明andGitHub 74bbb453e2 Add files via upload 2026-05-17 17:05:22 +08:00
公明andGitHub 66842f6206 Add files via upload 2026-05-17 17:01:48 +08:00
公明andGitHub dc1779275d Add files via upload 2026-05-16 13:46:24 +08:00
公明andGitHub 10dff937b1 Update config.yaml 2026-05-16 13:00:29 +08:00
公明andGitHub d4e1fe3bbe Add files via upload 2026-05-15 18:03:59 +08:00
公明andGitHub 179976ae57 Add files via upload 2026-05-15 17:49:33 +08:00
公明andGitHub 1c758bb98c Add files via upload 2026-05-15 17:34:25 +08:00
公明andGitHub 17c4f38ee3 Add files via upload 2026-05-15 17:27:45 +08:00
公明andGitHub cd7e57d121 Add files via upload 2026-05-15 14:55:43 +08:00
公明andGitHub 0f2c3f65cc Add files via upload 2026-05-15 14:21:40 +08:00
公明andGitHub 7779666e27 Update config.yaml 2026-05-15 14:19:18 +08:00
公明andGitHub c74bd4403b Add files via upload 2026-05-15 14:16:04 +08:00
公明andGitHub 04d23ddb43 Update config.yaml 2026-05-15 14:14:09 +08:00
公明andGitHub 0874e84393 Add files via upload 2026-05-15 14:12:52 +08:00
公明andGitHub 57f57f30b1 Add files via upload 2026-05-15 14:11:24 +08:00
公明andGitHub f37d613a0c Add files via upload 2026-05-15 14:09:37 +08:00
公明andGitHub 87d0ff9154 Update config.yaml 2026-05-15 14:08:28 +08:00
公明andGitHub b3418f39b8 Update config.yaml 2026-05-15 11:53:07 +08:00
公明andGitHub f9e1ca0e2d Add files via upload 2026-05-15 11:49:53 +08:00
公明andGitHub 2c45879669 Add files via upload 2026-05-15 11:48:58 +08:00
公明andGitHub 1cdcfa2c2d Add files via upload 2026-05-15 11:47:34 +08:00
公明andGitHub eab5b73846 Add files via upload 2026-05-15 11:46:02 +08:00
公明andGitHub d961ba1ec7 Add files via upload 2026-05-15 11:43:33 +08:00
公明andGitHub 1ba5e57ec6 Update config.yaml 2026-05-14 19:35:37 +08:00
公明andGitHub 1216d25f96 Add files via upload 2026-05-14 19:33:15 +08:00
公明andGitHub fde693408e Add files via upload 2026-05-14 19:31:21 +08:00
公明andGitHub 352a81a869 Add files via upload 2026-05-14 19:29:59 +08:00
公明andGitHub b2562b1010 Add files via upload 2026-05-14 19:28:37 +08:00
公明andGitHub 0d8ba51087 Add files via upload 2026-05-14 19:26:23 +08:00
公明andGitHub 0b847fcea3 Delete multiagent directory 2026-05-14 19:25:42 +08:00
公明andGitHub bf2f49fe62 Delete skillpackage directory 2026-05-14 19:25:19 +08:00
公明andGitHub 75e64b1a86 Delete einomcp directory 2026-05-14 19:25:09 +08:00
公明andGitHub 2167735022 Delete database directory 2026-05-14 19:24:58 +08:00
公明andGitHub 4ee292cc1f Delete storage directory 2026-05-14 19:24:48 +08:00
公明andGitHub 961205940f Delete agents directory 2026-05-14 19:24:19 +08:00
公明andGitHub ffe797bd06 Delete agent directory 2026-05-14 19:24:04 +08:00
公明andGitHub b6c864547e Delete mcp directory 2026-05-14 19:23:52 +08:00
公明andGitHub da369c2edc Add files via upload 2026-05-14 19:23:27 +08:00
公明andGitHub 54dc31a616 Add files via upload 2026-05-14 19:21:35 +08:00
公明andGitHub 9e0b985221 Add files via upload 2026-05-14 19:19:26 +08:00
公明andGitHub eb47077082 Update config.yaml 2026-05-14 14:59:27 +08:00
公明andGitHub f9a482857d Add files via upload 2026-05-14 11:57:00 +08:00
公明andGitHub 679a68b12f Add files via upload 2026-05-14 11:55:47 +08:00
公明andGitHub 840a26c7ef Add files via upload 2026-05-14 11:54:23 +08:00
公明andGitHub 030e69c02d Add files via upload 2026-05-14 11:49:08 +08:00
公明andGitHub d9683cdb44 Add files via upload 2026-05-14 11:33:12 +08:00
公明andGitHub 60a063dd7d Add files via upload 2026-05-14 11:31:56 +08:00
公明andGitHub 5f0c1805a7 Add files via upload 2026-05-14 11:30:28 +08:00
公明andGitHub cb7e66001b Update config.yaml 2026-05-13 17:09:31 +08:00
公明andGitHub 4ea838f1d7 Update config.yaml 2026-05-13 16:48:03 +08:00
公明andGitHub 573648fc4b Add files via upload 2026-05-13 16:43:26 +08:00
公明andGitHub f0e090abea Add files via upload 2026-05-13 16:41:23 +08:00
公明andGitHub 549dcf518c Add files via upload 2026-05-13 16:39:08 +08:00
公明andGitHub c74e20c54a Add files via upload 2026-05-13 16:36:09 +08:00
公明andGitHub c94a9fd9e9 Add files via upload 2026-05-13 15:26:02 +08:00
公明andGitHub ce9749a8ef Update config.yaml 2026-05-13 15:23:18 +08:00
公明andGitHub 145da12017 Add files via upload 2026-05-13 12:33:23 +08:00
公明andGitHub 5111f4c311 Add files via upload 2026-05-13 12:08:28 +08:00
公明andGitHub 8f6384a083 Add files via upload 2026-05-13 12:06:56 +08:00
公明andGitHub 762f778e1e Add files via upload 2026-05-13 12:05:12 +08:00
公明andGitHub 4a11ba8f14 Add files via upload 2026-05-13 10:40:56 +08:00
公明andGitHub 86090af4df Update config.yaml 2026-05-12 17:34:59 +08:00
公明andGitHub 2dea6e36bd Add files via upload 2026-05-12 17:33:14 +08:00
公明andGitHub 38ce695708 Update config.yaml 2026-05-12 17:29:45 +08:00
公明andGitHub 41fe90faa3 Add files via upload 2026-05-12 17:23:57 +08:00
公明andGitHub 9f54bdb1bf Add files via upload 2026-05-12 17:22:19 +08:00
公明andGitHub 08e727aa41 Add files via upload 2026-05-12 17:19:51 +08:00
公明andGitHub 176c17d630 Add files via upload 2026-05-12 17:17:36 +08:00
公明andGitHub 62710f6619 Add files via upload 2026-05-12 16:42:43 +08:00
公明andGitHub e4dbb96b3e Add files via upload 2026-05-12 16:41:15 +08:00
公明andGitHub 832532213a Add files via upload 2026-05-12 16:39:09 +08:00
公明andGitHub eb04ac0c3a Delete web/templates/index.html.bak 2026-05-12 16:36:51 +08:00
公明andGitHub 1946508325 Add files via upload 2026-05-12 16:36:23 +08:00
公明andGitHub 89d1c5124f Add files via upload 2026-05-12 14:57:04 +08:00
公明andGitHub 1e7a3299a5 Merge pull request #118 from Dilligaf371/fix/mcp-stdio-init-result-storage
fix(mcp-stdio): initialize result storage so query tools work
2026-05-12 13:01:04 +08:00
公明andGitHub cae3a77331 Add files via upload 2026-05-12 12:56:11 +08:00
公明andGitHub 2e1e57ce27 Add files via upload 2026-05-12 12:55:02 +08:00
公明andGitHub 45b6ed2847 Add files via upload 2026-05-12 12:53:20 +08:00
公明andGitHub 88eadf13a4 Add files via upload 2026-05-12 12:48:42 +08:00
Gilles Ceyssat dca5666b18 fix(mcp-stdio): initialize result storage so query tools work
The stdio MCP entrypoint (cmd/mcp-stdio/main.go) constructed the
security Executor without calling SetResultStorage, leaving it nil.
Any tool that goes through the query path — notably `exec` (the
generic shell tool) and the YAML wrappers that emit large results —
failed with:

    "错误: 结果存储未初始化"  (Error: result storage not initialized)

The full HTTP app at internal/app/app.go:118-147 initializes a
FileResultStorage from cfg.Agent.ResultStorageDir and wires it via
both agent.SetResultStorage and executor.SetResultStorage. The stdio
entrypoint needs the same wiring.

This replicates the storage init block in main.go so stdio-mode tool
execution stops failing on the query path.

Verified: before, `exec` calls returned the "结果存储未初始化" error.
After, `exec nmap -p 22,80,443 127.0.0.1` (bridged through an
external MCP client) returns the full nmap output as expected.
2026-05-12 08:13:13 +04:00
公明andGitHub e5d52cdf85 Update config.yaml 2026-05-11 20:36:58 +08:00
公明andGitHub 65e48826ff Update config.yaml 2026-05-11 19:59:41 +08:00
公明andGitHub 0cff507272 Add files via upload 2026-05-11 19:57:46 +08:00
公明andGitHub 30afd71c05 Add files via upload 2026-05-11 19:56:38 +08:00
公明andGitHub d2b6a154de Add files via upload 2026-05-11 19:54:40 +08:00
公明andGitHub 278d5aa25c Add files via upload 2026-05-11 19:52:39 +08:00
公明andGitHub 215f5a4a93 Update config.yaml 2026-05-10 23:33:39 +08:00
公明andGitHub 44185d748d Add files via upload 2026-05-10 23:28:18 +08:00
公明andGitHub fe47f1f058 Add files via upload 2026-05-10 23:27:07 +08:00
公明andGitHub 99ce183f41 Add files via upload 2026-05-10 23:25:11 +08:00
公明andGitHub 2ed1947f36 Add files via upload 2026-05-10 23:22:35 +08:00
公明andGitHub 97f3e8c179 Add files via upload 2026-05-10 22:52:34 +08:00
公明andGitHub 38b0c31b87 Add files via upload 2026-05-10 22:47:04 +08:00
公明andGitHub cb839da4d1 Add files via upload 2026-05-10 22:44:51 +08:00
公明andGitHub 5ed730f17c Add files via upload 2026-05-10 22:43:21 +08:00
公明andGitHub 30b1e5f820 Add files via upload 2026-05-10 22:16:12 +08:00
公明andGitHub 8e5c70703e Add files via upload 2026-05-10 22:14:51 +08:00
公明andGitHub 3cc3b25a7b Add files via upload 2026-05-10 22:12:23 +08:00
公明andGitHub 44cf63fa52 Add files via upload 2026-05-10 22:10:33 +08:00
公明andGitHub 12057c065b Add files via upload 2026-05-10 21:39:50 +08:00
公明andGitHub c4e0b9735c Add files via upload 2026-05-10 21:38:28 +08:00
公明andGitHub 218e9b9880 Add files via upload 2026-05-10 21:36:28 +08:00
公明andGitHub 82d840966e Add files via upload 2026-05-10 21:34:34 +08:00
公明andGitHub c62ff3bde9 Add files via upload 2026-05-10 20:29:34 +08:00
公明andGitHub df2506b651 Add files via upload 2026-05-10 02:04:23 +08:00
公明andGitHub efe9172f85 Add files via upload 2026-05-10 02:03:07 +08:00
公明andGitHub b788bc6dab Add files via upload 2026-05-10 02:01:28 +08:00
公明andGitHub 9134f2bbcb Update config.yaml 2026-05-10 01:53:51 +08:00
公明andGitHub d76cf2a162 Add files via upload 2026-05-10 00:58:35 +08:00
公明andGitHub 2f96feb98f Add files via upload 2026-05-10 00:57:26 +08:00
公明andGitHub a374c3950c Add files via upload 2026-05-10 00:55:20 +08:00
公明andGitHub a93e3455fa Add files via upload 2026-05-10 00:53:33 +08:00
公明andGitHub 6cd864c5ca Update config.yaml 2026-05-08 23:00:15 +08:00
公明andGitHub e34faff001 Add files via upload 2026-05-08 22:45:46 +08:00
公明andGitHub fa09796ddd Add files via upload 2026-05-08 22:44:32 +08:00
公明andGitHub 1ab7e98f56 Add files via upload 2026-05-08 22:42:31 +08:00
公明andGitHub 0743086873 Add files via upload 2026-05-08 22:32:21 +08:00
公明andGitHub a1ceb9c108 Add files via upload 2026-05-08 17:22:40 +08:00
公明andGitHub 9ddea33dab Add files via upload 2026-05-08 17:15:27 +08:00
公明andGitHub e948940b18 Delete images/dashboard.png 2026-05-08 17:14:56 +08:00
公明andGitHub 94bbbf87bf Add files via upload 2026-05-08 16:50:56 +08:00
公明andGitHub 4f09ffbaaa Add files via upload 2026-05-08 13:57:18 +08:00
公明andGitHub 6d77081b2b Add files via upload 2026-05-08 13:56:04 +08:00
公明andGitHub 99ccb07ec9 Add files via upload 2026-05-08 13:54:25 +08:00
公明andGitHub 1130fdbfa4 Add files via upload 2026-05-08 13:08:45 +08:00
公明andGitHub 84f4da4d1d Add files via upload 2026-05-08 13:07:33 +08:00
公明andGitHub 34dae98329 Add files via upload 2026-05-08 13:05:45 +08:00
公明andGitHub 3ee7d64b09 Add files via upload 2026-05-08 13:04:18 +08:00
公明andGitHub 22a3aa1531 Add files via upload 2026-05-07 18:03:19 +08:00
公明andGitHub 8ad61906fa Add files via upload 2026-05-07 18:02:15 +08:00
公明andGitHub 487522707f Add files via upload 2026-05-07 18:00:22 +08:00
公明andGitHub fe625010eb Update config.yaml 2026-05-07 17:04:39 +08:00
公明andGitHub 40cd0293b5 Add files via upload 2026-05-07 17:04:14 +08:00
公明andGitHub b62dc1f326 Add files via upload 2026-05-07 17:02:26 +08:00
公明andGitHub 6d180c814d Add files via upload 2026-05-07 17:01:15 +08:00
公明andGitHub e68d3a3d23 Add files via upload 2026-05-07 16:58:54 +08:00
公明andGitHub 699b9181e6 Add files via upload 2026-05-07 16:57:17 +08:00
公明andGitHub 7b9070f106 Update config.yaml 2026-05-06 21:37:55 +08:00
公明andGitHub 5a31b69245 Add files via upload 2026-05-06 21:31:21 +08:00
公明andGitHub 104a6e30d5 Add files via upload 2026-05-06 21:29:25 +08:00
公明andGitHub 80c4299dbb Add files via upload 2026-05-06 21:26:38 +08:00
公明andGitHub debe967272 Add files via upload 2026-05-06 20:50:28 +08:00
公明andGitHub b28f9c25f8 Update config.yaml 2026-05-06 18:00:13 +08:00
公明andGitHub 6f5d0b0174 Add files via upload 2026-05-06 17:59:31 +08:00
公明andGitHub 231a48db8e Add files via upload 2026-05-06 17:58:42 +08:00
公明andGitHub d82ea60827 Add files via upload 2026-05-06 17:56:30 +08:00
公明andGitHub 24a0c813e2 Add files via upload 2026-05-06 17:50:59 +08:00
公明andGitHub 24938f92ff Add files via upload 2026-05-04 13:22:36 +08:00
公明andGitHub b24bc63964 Update config.yaml 2026-05-04 13:19:35 +08:00
公明andGitHub 60517fff44 Update config.yaml 2026-05-04 13:12:56 +08:00
公明andGitHub d2635eeb9c Add files via upload 2026-05-04 13:12:09 +08:00
公明andGitHub 57ebc7c04b Add files via upload 2026-05-04 13:09:43 +08:00
公明andGitHub b27e443d37 Add files via upload 2026-05-04 13:07:37 +08:00
公明andGitHub 9b4c6dedc8 Add files via upload 2026-05-04 04:50:53 +08:00
公明andGitHub d603060511 Add files via upload 2026-05-04 03:52:47 +08:00
公明andGitHub ad86623dc1 Update config.yaml 2026-05-04 03:46:24 +08:00
公明andGitHub 8185539f33 Add files via upload 2026-05-04 03:45:24 +08:00
公明andGitHub 8158b38f48 Add files via upload 2026-05-04 03:44:08 +08:00
公明andGitHub 4fca4a85c2 Add files via upload 2026-05-04 03:42:24 +08:00
公明andGitHub 62c6f3f191 Add files via upload 2026-05-02 19:58:36 +08:00
公明andGitHub dec69a1993 Update config.yaml 2026-05-01 01:33:17 +08:00
公明andGitHub 15aab2584a Add files via upload 2026-05-01 01:32:54 +08:00
公明andGitHub 399b697d75 Add files via upload 2026-05-01 01:31:19 +08:00
公明andGitHub e0753fd03e Add files via upload 2026-05-01 01:28:19 +08:00
公明andGitHub 9b1e493023 Add files via upload 2026-05-01 01:05:48 +08:00
公明andGitHub 77d212098d Add files via upload 2026-05-01 01:03:28 +08:00
公明andGitHub 39926007fe Add files via upload 2026-05-01 01:01:30 +08:00
公明andGitHub 0e35506ae1 Add files via upload 2026-05-01 01:00:23 +08:00
公明andGitHub 9ff8bfa44b Add files via upload 2026-04-30 20:31:17 +08:00
公明andGitHub 1d9fcfd87e Update version number to v1.5.16 2026-04-30 20:28:21 +08:00
公明andGitHub 91cb650234 Add files via upload 2026-04-30 15:20:13 +08:00
公明andGitHub 44e7d3b340 Add files via upload 2026-04-30 15:01:35 +08:00
公明andGitHub 531b05299a Add files via upload 2026-04-30 10:49:19 +08:00
公明andGitHub 0de69a6345 Add files via upload 2026-04-30 10:43:23 +08:00
公明andGitHub 6a2a445f32 Update config.yaml 2026-04-30 01:56:47 +08:00
公明andGitHub 6aaa21d3e0 Add files via upload 2026-04-30 01:55:23 +08:00
公明andGitHub 5c57d358ef Add files via upload 2026-04-30 01:53:46 +08:00
公明andGitHub 65a3475c02 Add files via upload 2026-04-30 01:52:11 +08:00
公明andGitHub 516ebf7a65 Add files via upload 2026-04-29 22:40:17 +08:00
公明andGitHub 2558be3d7d Add files via upload 2026-04-29 22:38:14 +08:00
公明andGitHub f6bb455313 Update config.yaml 2026-04-29 17:14:19 +08:00
公明andGitHub fc64356282 Add files via upload 2026-04-29 17:10:53 +08:00
公明andGitHub 3d4fce9b89 Add files via upload 2026-04-29 17:09:37 +08:00
公明andGitHub 3e41a47abf Add files via upload 2026-04-29 17:05:02 +08:00
公明andGitHub 5b942c7bc8 Add files via upload 2026-04-29 17:03:51 +08:00
公明andGitHub bcfb7b8da1 Update config.yaml 2026-04-29 04:11:31 +08:00
公明andGitHub f420ae0265 Add files via upload 2026-04-29 03:28:32 +08:00
公明andGitHub e3f59b29ab Add files via upload 2026-04-29 03:26:27 +08:00
公明andGitHub 87cba37203 Add files via upload 2026-04-29 03:24:48 +08:00
公明andGitHub 4773b9e963 Update config.yaml 2026-04-29 03:01:21 +08:00
公明andGitHub eda5f9bba1 Add files via upload 2026-04-29 02:59:34 +08:00
公明andGitHub 1318607813 Add files via upload 2026-04-29 02:57:22 +08:00
公明andGitHub 5100924abe Add files via upload 2026-04-29 02:54:43 +08:00
公明andGitHub 44079674dd Add files via upload 2026-04-28 14:07:01 +08:00
公明andGitHub d959390e27 Update config.yaml 2026-04-28 11:45:27 +08:00
公明andGitHub 62a0d8cb71 Add files via upload 2026-04-28 11:40:09 +08:00
公明andGitHub b53cae3a02 Add files via upload 2026-04-28 11:37:52 +08:00
公明andGitHub 3b3d094dc4 Add files via upload 2026-04-28 10:26:09 +08:00
公明andGitHub 47922c2083 Add files via upload 2026-04-28 10:23:24 +08:00
公明andGitHub dfaf0bc77f Update config.yaml 2026-04-28 01:23:57 +08:00
公明andGitHub 3eb7edb1b8 Add files via upload 2026-04-28 01:23:33 +08:00
公明andGitHub f82f6b861e Add files via upload 2026-04-28 01:22:21 +08:00
公明andGitHub 2acf43c454 Add files via upload 2026-04-28 01:19:01 +08:00
公明andGitHub fad6b3c808 Add files via upload 2026-04-28 01:05:58 +08:00
公明andGitHub 0597838217 Add files via upload 2026-04-28 01:04:58 +08:00
公明andGitHub 1532426b4f Add files via upload 2026-04-28 01:02:30 +08:00
公明andGitHub 3aeb8c3474 Add files via upload 2026-04-28 00:37:46 +08:00
公明andGitHub b2b166972a Add files via upload 2026-04-28 00:33:29 +08:00
公明andGitHub 36b669771c Delete internal/multiagent directory 2026-04-28 00:30:34 +08:00
公明andGitHub 96564d4d89 Update default_single_system_prompt.go 2026-04-27 14:58:49 +08:00
公明andGitHub d85afa2d39 Add files via upload 2026-04-27 11:29:16 +08:00
公明andGitHub 55b6bceb21 Update config.yaml 2026-04-26 15:11:48 +08:00
公明andGitHub 65d73b3d66 Add files via upload 2026-04-26 15:08:48 +08:00
公明andGitHub 913115d1fb Add files via upload 2026-04-26 04:26:29 +08:00
公明andGitHub e1b967d781 Add files via upload 2026-04-26 04:18:38 +08:00
公明andGitHub 9d9efa886f Add files via upload 2026-04-26 04:17:27 +08:00
公明andGitHub cae45e9dc5 Add files via upload 2026-04-26 04:16:25 +08:00
公明andGitHub c788b59f25 Update config.yaml 2026-04-24 20:01:42 +08:00
公明andGitHub 5edf3a70f9 Add files via upload 2026-04-24 20:00:50 +08:00
公明andGitHub 3dfb3b4e82 Add files via upload 2026-04-24 19:59:15 +08:00
公明andGitHub a517fe0931 Add files via upload 2026-04-24 19:56:09 +08:00
公明andGitHub 0ab5e31a64 Add files via upload 2026-04-24 18:24:52 +08:00
公明andGitHub ea6e027b25 Add files via upload 2026-04-24 17:30:22 +08:00
公明andGitHub ba9d2f0afd Update config.yaml 2026-04-24 15:43:00 +08:00
公明andGitHub 6ce835703e Add files via upload 2026-04-24 11:24:10 +08:00
公明andGitHub 666980ad8f Add files via upload 2026-04-24 11:08:47 +08:00
公明andGitHub bc8e81307e Add files via upload 2026-04-24 11:07:03 +08:00
公明andGitHub 053534feaa Add files via upload 2026-04-24 11:04:55 +08:00
公明andGitHub 88fd71e04c Update config.yaml 2026-04-24 02:08:55 +08:00
公明andGitHub 590400b605 Add files via upload 2026-04-24 02:07:58 +08:00
公明andGitHub c83c48305b Add HITL tool whitelist to config.yaml
Add HITL global whitelist configuration for tools.
2026-04-24 01:57:22 +08:00
公明andGitHub 96d11087f9 Add files via upload 2026-04-24 01:55:59 +08:00
公明andGitHub d17da2a47d Add files via upload 2026-04-24 01:54:38 +08:00
公明andGitHub e03bdf8044 Add files via upload 2026-04-24 01:51:25 +08:00
公明andGitHub 943a3b2646 Add files via upload 2026-04-24 01:50:55 +08:00
公明andGitHub 38169abc4b Add files via upload 2026-04-22 13:59:17 +08:00
公明andGitHub edf66de27d Add files via upload 2026-04-22 13:57:50 +08:00
公明andGitHub ebe4aa035b Add files via upload 2026-04-22 13:55:49 +08:00
公明andGitHub b076425c5e Add files via upload 2026-04-22 13:53:32 +08:00
公明andGitHub e664aaccfe Add files via upload 2026-04-22 13:50:50 +08:00
公明andGitHub 9e2d9b4288 Update config.yaml 2026-04-22 13:45:16 +08:00
公明andGitHub 0d3c1e333e Add files via upload 2026-04-22 12:04:14 +08:00
公明andGitHub 8daf0b3870 Update config.yaml 2026-04-22 12:02:06 +08:00
公明andGitHub ed4848168b Add files via upload 2026-04-22 12:00:50 +08:00
公明andGitHub 6ca2930353 Add files via upload 2026-04-22 11:59:34 +08:00
公明andGitHub d92edbc929 Update config.yaml 2026-04-22 11:12:09 +08:00
公明andGitHub de9b1247d6 Add files via upload 2026-04-22 11:11:04 +08:00
公明andGitHub 7ddf0f2437 Add files via upload 2026-04-22 11:09:43 +08:00
公明andGitHub e04b5b66d7 Add files via upload 2026-04-22 11:06:00 +08:00
公明andGitHub c841809f9e Add files via upload 2026-04-22 10:03:46 +08:00
公明andGitHub 928b696c06 Add files via upload 2026-04-22 00:06:16 +08:00
公明andGitHub 5fcccfab40 Delete tools/winpeas.yaml 2026-04-21 22:43:21 +08:00
公明andGitHub 839d31fd50 Delete tools/hash-identifier.yaml 2026-04-21 22:42:30 +08:00
公明andGitHub 9d635a35ea Delete tools/qsreplace.yaml 2026-04-21 22:41:57 +08:00
公明andGitHub c288a2e631 Delete tools/uro.yaml 2026-04-21 22:41:31 +08:00
公明andGitHub ff8db01038 Delete tools/anew.yaml 2026-04-21 22:40:51 +08:00
公明andGitHub 026cfbdd37 Disable feroxbuster tool in configuration 2026-04-21 22:40:27 +08:00
公明andGitHub bf3c53ccec Update gobuster.yaml 2026-04-21 22:39:45 +08:00
公明andGitHub 1a3cf88465 Delete tools/autorecon.yaml 2026-04-21 22:30:44 +08:00
公明andGitHub b8fd01dbfb Delete tools/docker-bench-security.yaml 2026-04-21 22:28:29 +08:00
公明andGitHub fa45315d3f Delete tools/fcrackzip.yaml 2026-04-21 22:24:48 +08:00
公明andGitHub c16101ce42 Delete tools/pdfcrack.yaml 2026-04-21 22:24:20 +08:00
公明andGitHub a9a4c94b2b Delete tools/cyberchef.yaml 2026-04-21 22:22:31 +08:00
公明andGitHub 773fabdda6 Delete tools/stegsolve.yaml 2026-04-21 22:22:10 +08:00
公明andGitHub bd686a6c47 Delete tools/burpsuite.yaml 2026-04-21 22:21:43 +08:00
公明andGitHub cde787b594 Delete tools/hakrawler.yaml 2026-04-21 22:19:59 +08:00
公明andGitHub 2abf8d1618 Delete tools/wfuzz.yaml 2026-04-21 22:17:26 +08:00
公明andGitHub d42050679e Delete tools/dirb.yaml 2026-04-21 22:16:10 +08:00
公明andGitHub 4279bb7b26 Delete tools/enum4linux.yaml 2026-04-21 22:15:42 +08:00
公明andGitHub e27c7de6bb Delete tools/volatility.yaml 2026-04-21 22:15:10 +08:00
公明andGitHub ef8066572f Delete tools/gdb-peda.yaml 2026-04-21 22:14:45 +08:00
公明andGitHub 4bd2da8136 Add files via upload 2026-04-21 21:50:03 +08:00
公明andGitHub e75e393f06 Add files via upload 2026-04-21 21:47:46 +08:00
公明andGitHub 58d2e20274 Add files via upload 2026-04-21 21:44:12 +08:00
公明andGitHub 5b3f4e3556 Update config.yaml 2026-04-21 20:50:37 +08:00
公明andGitHub adef2c143b Delete tools/mimikatz.yaml 2026-04-21 20:48:32 +08:00
公明andGitHub 7ac3c06c34 Delete tools/http-intruder.yaml 2026-04-21 20:47:42 +08:00
公明andGitHub d3a05fcd92 Delete tools/modify-file.yaml 2026-04-21 20:46:06 +08:00
公明andGitHub 1d692e9f52 Delete tools/cat.yaml 2026-04-21 20:45:34 +08:00
公明andGitHub 7e4032858e Delete tools/delete-file.yaml 2026-04-21 20:45:04 +08:00
公明andGitHub f77af18694 Delete tools/create-file.yaml 2026-04-21 20:44:30 +08:00
公明andGitHub 8e31f10837 Delete tools/api-fuzzer.yaml 2026-04-21 20:43:40 +08:00
公明andGitHub b3e29f6e8f Add files via upload 2026-04-21 19:37:52 +08:00
公明andGitHub 32b655f526 Add files via upload 2026-04-21 19:28:14 +08:00
公明andGitHub a8b608135e Add files via upload 2026-04-21 19:25:45 +08:00
公明andGitHub 964c520215 Add files via upload 2026-04-21 19:17:46 +08:00
公明andGitHub 26116b0822 Add files via upload 2026-04-21 19:16:09 +08:00
公明andGitHub d037647c21 Add files via upload 2026-04-21 19:13:08 +08:00
公明andGitHub f2a701a846 Update config.yaml 2026-04-21 01:27:46 +08:00
公明andGitHub 0ce79c6ef4 Add files via upload 2026-04-21 01:26:49 +08:00
公明andGitHub 0d4f608c14 Add files via upload 2026-04-21 01:25:40 +08:00
公明andGitHub c801a97add Add files via upload 2026-04-21 01:24:01 +08:00
公明andGitHub 68978b82e9 Add files via upload 2026-04-20 20:01:02 +08:00
公明andGitHub c43fde2612 Add files via upload 2026-04-20 19:46:40 +08:00
公明andGitHub fbd1ede8cb Add files via upload 2026-04-20 19:45:04 +08:00
公明andGitHub 2d8ef3a1b0 Add files via upload 2026-04-20 19:42:11 +08:00
621 changed files with 138188 additions and 18899 deletions
+130 -59
View File
@@ -1,5 +1,5 @@
<div align="center">
<img src="web/static/logo.png" alt="CyberStrikeAI Logo" width="200">
<img src="images/logo.png" alt="CyberStrikeAI Logo" width="200">
</div>
# CyberStrikeAI
@@ -9,6 +9,12 @@
**Community**: [Join us on Discord](https://discord.gg/8PjVCMu8Zw)
**CyberStrikeAI is building the agentic execution layer for modern cyber security.**
It brings AI agents, security tools, MCP-native integrations, knowledge systems, human oversight, and attack-chain intelligence into a unified workspace for authorized cyber engagements. Instead of treating tools, prompts, evidence, approvals, and reports as separate fragments, CyberStrikeAI turns security intent into auditable multi-agent workflows that can plan, execute, review, replay, and continuously accumulate operational context.
Built in Go, CyberStrikeAI provides a full-stack foundation for AI-native security operations: 100+ curated tool recipes, role-based testing, Agent Skills, Eino-powered single-agent and multi-agent orchestration, RAG knowledge retrieval, graph workflows, vulnerability and task lifecycle management, WebShell operations, chatbot access, and a lightweight built-in C2 framework for authorized lab and engagement scenarios.
<details>
<summary><strong>WeChat group</strong> (click to reveal QR code)</summary>
@@ -27,16 +33,24 @@ If CyberStrikeAI helps you, you can support the project via **WeChat Pay** or **
</details>
CyberStrikeAI is an **AI-native security testing platform** built in Go. It integrates 100+ security tools, an intelligent orchestration engine, role-based testing with predefined security roles, a skills system with specialized testing skills, and comprehensive lifecycle management capabilities. Through native MCP protocol and AI agents, it enables end-to-end automation from conversational commands to vulnerability discovery, attack-chain analysis, knowledge retrieval, and result visualization—delivering an auditable, traceable, and collaborative testing environment for security teams.
## Interface & Integration Preview
<div align="center">
### System Dashboard Overview
<img src="./images/dashboard.png" alt="System Dashboard" width="100%">
<table>
<tr>
<td width="50%" align="center">
<strong>Light Mode</strong><br/>
<img src="./images/dashboard.png" alt="System Dashboard (Light)" width="100%">
</td>
<td width="50%" align="center">
<strong>Dark Mode</strong><br/>
<img src="./images/dark.png" alt="System Dashboard (Dark)" width="100%">
</td>
</tr>
</table>
*The dashboard provides a comprehensive overview of system runtime status, security vulnerabilities, tool usage, and knowledge base, helping users quickly understand the platform's core features and current state.*
@@ -105,21 +119,28 @@ CyberStrikeAI is an **AI-native security testing platform** built in Go. It inte
## Highlights
- 🤖 AI decision engine with OpenAI-compatible models (GPT, Claude, DeepSeek, etc.)
- 🔌 Native MCP implementation with HTTP/stdio/SSE transports and external MCP federation
- 🧰 100+ prebuilt tool recipes + YAML-based extension system
- 🤖 Agentic execution layer for translating natural-language intent into precise, governed, auditable security action
- 🧩 Eino-powered single-agent and multi-agent orchestration with Deep, Plan-Execute, and Supervisor modes
- 🔌 MCP-native tool execution with HTTP/stdio/SSE transports, external MCP federation, and dynamic tool discovery
- 🧰 100+ curated security tool recipes, YAML-based extensions, and role-scoped tool control
- 📄 Large-result pagination, compression, and searchable archives
- 🔗 Attack-chain graph, risk scoring, and step-by-step replay
- 🔒 Password-protected web UI, audit logs, and SQLite persistence
- 📚 Knowledge base (RAG) with embedding-based vector retrieval (cosine similarity), optional **Eino Compose** indexing pipeline, and configurable post-retrieval budgets / reranking hooks
- 🔗 Attack-chain intelligence with graph views, risk scoring, project facts, and step-by-step replay
- 🧑‍⚖️ Human-in-the-loop governance with approval modes, allowlists, audit-agent review, and traceable decisions
- 🔒 Password-protected web UI, audit logs, SQLite persistence, and operational evidence retention
- 📚 Knowledge base (RAG): **Eino MultiQuery** query rewrite + multi-path vector retrieval + **HTTP rerank** (DashScope `gte-rerank` / Cohere-compatible) + post-processing (dedupe, budget); **Eino Compose** indexing pipeline
- 📁 Conversation grouping with pinning, rename, and batch management
- 📂 **Project management**: shared facts (blackboard) across sessions, `upsert_project_fact` + `links` to chain paths; attack-chain and project fact graph views
- 🛡️ Vulnerability management with CRUD operations, severity tracking, status workflow, and statistics
- 📋 Batch task management: create task queues, add multiple tasks, and execute them sequentially
- 🎭 Role-based testing: predefined security testing roles (Penetration Testing, CTF, Web App Scanning, etc.) with custom prompts and tool restrictions
- 🧩 **Multi-agent (CloudWeGo Eino)**: alongside **single-agent ReAct** (`/api/agent-loop`), **multi mode** (`/api/multi-agent/stream`) offers **`deep`** (coordinator + `task` sub-agents), **`plan_execute`** (planner / executor / replanner), and **`supervisor`** (orchestrator + `transfer` / `exit`); chosen per request via **`orchestration`**. Markdown under `agents/`: `orchestrator.md` (Deep), `orchestrator-plan-execute.md`, `orchestrator-supervisor.md`, plus sub-agent `*.md` where applicable (see [Multi-agent doc](docs/MULTI_AGENT_EINO.md))
- 🎯 **Skills (refactored for Eino)**: packs under `skills_dir` follow **Agent Skills** layout (`SKILL.md` + optional files); **multi-agent** sessions use the official Eino ADK **`skill`** tool for **progressive disclosure** (load by name), with optional **host filesystem / shell** via `multi_agent.eino_skills`; optional **`eino_middleware`** adds patchtoolcalls, tool_search, plantask, reduction, checkpoints, and Deep tuning—20+ sample domains (SQLi, XSS, API security, …) can still be bound to roles
- 📱 **Chatbot**: DingTalk and Lark (Feishu) long-lived connections so you can talk to CyberStrikeAI from mobile (see [Robot / Chatbot guide](docs/robot_en.md) for setup and commands)
- 🐚 **WebShell management**: Add and manage WebShell connections (e.g. IceSword/AntSword compatible), use a virtual terminal for command execution, a built-in file manager for file operations, and an AI assistant tab that orchestrates tests and keeps per-connection conversation history; supports PHP, ASP, ASPX, JSP and custom shell types with configurable request method and command parameter.
- 🔀 **Graph orchestration**: visual workflow editor (Start / Agent / Tool / Condition / HITL / Output) with `{{previous.output}}` and `{{outputs.variable_name}}` for inter-node data passing; bind a graph to a role for automatic execution on chat. See [Graph orchestration guide](docs/en-US/workflow-graph.md)
- 🧩 **Agent orchestration (CloudWeGo Eino)**: **single-agent** via **`/api/eino-agent/stream`** (Eino ADK `ChatModelAgent`); **multi-agent** via **`/api/multi-agent/stream`** with **`deep`** (coordinator + `task` sub-agents), **`plan_execute`**, or **`supervisor`** (`orchestration` in the request body). ADK **summarization** compresses long contexts; pre-compaction **transcripts** land at `data/conversation_artifacts/<conversation-id>/summarization/transcript.txt` (full user/assistant/tool turns; static system omitted). Markdown under `agents/`: `orchestrator.md`, `orchestrator-plan-execute.md`, `orchestrator-supervisor.md`, plus sub-agent `*.md` (see [Multi-agent doc](docs/en-US/MULTI_AGENT_EINO.md))
- 🖼️ **Vision analysis (`analyze_image`)**: separate VL model (e.g. `qwen-vl-max`) via MCP for local screenshots, captchas, and UI; image bytes stay out of agent history (text summaries only). Configure `vision` in `config.yaml`; see [docs/en-US/VISION.md](docs/en-US/VISION.md)
- 🎯 **Skills (refactored for Eino)**: packs under `skills_dir` follow **Agent Skills** layout (`SKILL.md` + optional files); **multi-agent** sessions use the official Eino ADK **`skill`** tool for **progressive disclosure** (load by name), with optional **host filesystem / shell** via `multi_agent.eino_skills`; optional **`eino_middleware`** adds patchtoolcalls, tool_search, **plantask** (`TaskCreate` / `TaskList` boards under `skills_dir/.eino/plantask/`), reduction, file **checkpoints** (`checkpoint_dir`), ChatModel **retries**, session **output key**, and Deep tuning—20+ sample domains (SQLi, XSS, API security, …) ship under `skills/`
- 📱 **Chatbot**: Personal WeChat, WeCom, DingTalk, Lark, Telegram, Slack, Discord, and QQ Bot—chat from mobile or IM apps (see [Robot / Chatbot guide](docs/en-US/robot.md))
- 🧑‍⚖️ **Human-in-the-loop (HITL)**: Chat sidebar to set approval mode and tool allowlists (listed tools skip approval); global list in `config.yaml` under `hitl.tool_whitelist`; the Audit Agent can use a separate lightweight model via `hitl.audit_model`; **Apply** can merge new tools into the file and update the running server without restart; dedicated **HITL** page for pending approvals. See [HITL best practices](docs/en-US/hitl-best-practices.md)
- 🐚 **WebShell management**: Add and manage WebShell connections (e.g. IceSword/AntSword compatible), use a virtual terminal for command execution, a built-in file manager for file operations, and an AI assistant tab that orchestrates tests and keeps per-connection conversation history; supports PHP, ASP, ASPX, JSP and custom shell types with configurable request method and command parameter.
- 📡 **Built-in C2**: AI-oriented lightweight command-and-control—**listeners** (TCP reverse, HTTP/HTTPS beacon, WebSocket), **encrypted** beacon channel, **session** and **task** queues with persistence, **payload** helpers (one-liner / build / download), **SSE** live events, REST under `/api/c2/*`, plus unified MCP tools (`c2_listener`, `c2_session`, **`c2_task`**, `c2_task_manage`, `c2_payload`, `c2_event`, `c2_profile`, `c2_file`); optional **HITL** approval for sensitive operations and OPSEC-style controls (e.g. command deny rules). **Authorized testing only.**
## Plugins
@@ -172,9 +193,11 @@ The `run.sh` script will automatically:
- ✅ Build the project
- ✅ Start the server
**Networking defaults:** `run.sh` starts the server with **`--https`** and the repo **`config.yaml`** (local self-signed TLS; better for many concurrent streams). Use **`./run.sh --http`** for plain HTTP. In production, set **`server.tls_cert_path`** / **`server.tls_key_path`** in **`config.yaml`** (see comments there). For manual runs, add **`--https`** or **`CYBERSTRIKE_HTTPS=1`**; if **`-config`** is wrong, the binary prints a short usage hint on stderr.
**First-Time Configuration:**
1. **Configure OpenAI-compatible API** (required before first use)
- Open http://localhost:8080 after launch
- After launch, open **`https://127.0.0.1:8080/`** (or **`https://localhost:8080/`**; replace **8080** with `server.port` in `config.yaml`) and accept the self-signed certificate warning once. If you used `./run.sh --http`, use **`http://`** instead.
- Go to `Settings` → Fill in your API credentials:
```yaml
openai:
@@ -184,32 +207,41 @@ The `run.sh` script will automatically:
```
- Or edit `config.yaml` directly before launching
2. **Login** - Use the auto-generated password shown in the console (or set `auth.password` in `config.yaml`)
3. **Install security tools (optional)** - Install tools as needed:
3. **Install security tools (optional)** - Install tools from `tools/` as needed; missing tools are skipped or substituted at runtime. Common examples:
**macOS (Homebrew):**
```bash
# macOS
brew install nmap sqlmap nuclei httpx gobuster feroxbuster subfinder amass
# Ubuntu/Debian
sudo apt-get install nmap sqlmap nuclei httpx gobuster feroxbuster
brew install nmap masscan sqlmap nikto gobuster ffuf hydra hashcat nuclei subfinder
```
AI automatically falls back to alternatives when a tool is missing.
**Linux (Kali / Debian / Ubuntu):**
```bash
sudo apt update
sudo apt install -y nmap masscan sqlmap nikto gobuster hydra hashcat john binwalk
# On some distros, install ffuf/nuclei/subfinder via go install or upstream docs
```
See the `tools/` directory for the full list; refer to each tool's official docs for install details.
**Alternative Launch Methods:**
```bash
# Direct Go run (requires manual setup)
go run cmd/server/main.go
# Direct Go run (set up env yourself); add --https to match run.sh defaults
go run cmd/server/main.go --https
# Manual build
go build -o cyberstrike-ai cmd/server/main.go
./cyberstrike-ai
./cyberstrike-ai --https
```
If server logs show `client sent an HTTP request to an HTTPS server`, a client is still using **`http://`** on a TLS-only port—switch the URL to **`https://`**.
**Note:** The Python virtual environment (`venv/`) is automatically created and managed by `run.sh`. Tools that require Python (like `api-fuzzer`, `http-framework-test`, etc.) will automatically use this environment.
### Version Update (No Breaking Changes)
**CyberStrikeAI one-click upgrade (recommended):**
1. (First time) enable the script: `chmod +x upgrade.sh`
2. Upgrade with: `./upgrade.sh` (optional flags: `--tag vX.Y.Z`, `--no-venv`, `--preserve-custom`, `--yes`)
2. Upgrade with: `./upgrade.sh` (optional flags: `--tag vX.Y.Z`, `--no-venv`, `--yes`). Local `tools/`, `roles/`, and `skills/` are always preserved.
3. The script will back up your `config.yaml` and `data/`, upgrade the code from GitHub Release, update `config.yaml`'s `version`, then restart the server.
Recommended one-liner:
@@ -228,15 +260,18 @@ Requirements / tips:
### Core Workflows
- **Conversation testing** Natural-language prompts trigger toolchains with streaming SSE output.
- **Single vs multi-agent** With `multi_agent.enabled: true`, the chat UI can switch between **single** (classic **ReAct** loop, `/api/agent-loop/stream`) and **multi** (`/api/multi-agent/stream`). Multi mode keeps **`deep`** as the baseline coordinator + **`task`** sub-agents, and adds **`plan_execute`** and **`supervisor`** orchestrations via the request body **`orchestration`** field. MCP tools are bridged the same way as single-agent.
- **Single vs multi-agent** Chat UI switches between **Eino single-agent** (`/api/eino-agent/stream`) and **multi-agent** (`/api/multi-agent/stream` with `orchestration`: `deep` | `plan_execute` | `supervisor`). Multi mode requires `multi_agent.enabled: true`. MCP tools are bridged the same way for both paths.
- **Role-based testing** Select from predefined security testing roles (Penetration Testing, CTF, Web App Scanning, API Security Testing, etc.) to customize AI behavior and tool availability. Each role applies custom system prompts and can restrict available tools for focused testing scenarios.
- **Graph orchestration** Design flows on the **Graph Orchestration** page (drag nodes, connect edges, save); bind `workflow_id` on a role to run the graph on chat (Agent, MCP tools, condition branches). Use `{{outputs.variable_name}}` to pass data across non-adjacent nodes. See [Graph orchestration guide](docs/en-US/workflow-graph.md).
- **Tool monitor** Inspect running jobs, execution logs, and large-result attachments.
- **History & audit** Every conversation and tool invocation is stored in SQLite with replay.
- **Conversation groups** Organize conversations into groups, pin important groups, rename or delete groups via context menu.
- **Vulnerability management** Create, update, and track vulnerabilities discovered during testing. Filter by severity (critical/high/medium/low/info), status (open/confirmed/fixed/false_positive), and conversation. View statistics and export findings.
- **Batch task management** Create task queues with multiple tasks, add or edit tasks before execution, and run them sequentially. Each task executes as a separate conversation, with status tracking (pending/running/completed/failed/cancelled) and full execution history.
- **WebShell management** Add and manage WebShell connections (PHP/ASP/ASPX/JSP or custom). Use the virtual terminal to run commands, the file manager to list, read, edit, upload, and delete files, and the AI assistant tab to drive scripted tests with per-connection conversation history. Connections are stored in SQLite; supports GET/POST and configurable command parameter (e.g. IceSword/AntSword style).
- **Built-in C2** Create/start **listeners**, generate **payloads**, track **sessions**, enqueue **tasks**, and subscribe to **events** (SSE) from the Web UI or `/api/c2/*`. Agents and external clients use the C2 MCP tool family (including **`c2_task`**); when HITL is enabled, high-risk tasks can require human approval. Intended **only** for systems you are explicitly authorized to test.
- **Settings** Tweak provider keys, MCP enablement, tool toggles, and agent iteration limits.
- **Human-in-the-loop (HITL)** Sidebar sets mode and allowlisted tools (comma- or newline-separated); global list lives in `config.yaml` under `hitl.tool_whitelist`. The Audit Agent can use a separate low-cost model through `hitl.audit_model`, useful when human reviewers cannot keep up. **Apply** updates browser/server and can merge new tools into the file (**no restart**). **New chat** keeps sidebar choices; **HITL** nav shows pending approvals. Removing a tool in the sidebar does not remove it from the global list in `config.yaml`—edit the file if needed.
### Built-in Safeguards
- Required-field validation prevents accidental blank API credentials.
@@ -250,8 +285,8 @@ Requirements / tips:
- **Predefined roles** System includes 12+ predefined security testing roles (Penetration Testing, CTF, Web App Scanning, API Security Testing, Binary Analysis, Cloud Security Audit, etc.) in the `roles/` directory.
- **Custom prompts** Each role can define a `user_prompt` that prepends to user messages, guiding the AI to adopt specialized testing methodologies and focus areas.
- **Tool restrictions** Roles can specify a `tools` list to limit available tools, ensuring focused testing workflows (e.g., CTF role restricts to CTF-specific utilities).
- **Skills integration** Roles can attach security testing skills. Skill ids are hinted in the system prompt; in **multi-agent** sessions the Eino ADK **`skill`** tool loads package content **on demand** (progressive disclosure). **`multi_agent.eino_skills`** toggles the middleware, tool name override, and optional **read_file / glob / grep / write / edit / execute** on the host (**Deep / Supervisor** main and sub-agents when enabled; **plan_execute** executor has no custom skill middleware—see docs). Single-agent ReAct does not mount this Eino skill stack today.
- **Easy role creation** Create custom roles by adding YAML files to the `roles/` directory. Each role defines `name`, `description`, `user_prompt`, `icon`, `tools`, `skills`, and `enabled` fields.
- **Skills** Skill packs live under `skills_dir` and load via the Eino ADK **`skill`** tool (**progressive disclosure**) in both **single- and multi-agent** sessions when **`multi_agent.eino_skills`** is enabled. Optional host **read_file / glob / grep / write / edit / execute** and **`eino_middleware`** (tool_search, plantask, reduction, checkpoints, summarization transcripts, etc.) apply per mode—see docs.
- **Easy role creation** Create custom roles by adding YAML files to the `roles/` directory. Each role defines `name`, `description`, `user_prompt`, `icon`, `tools`, and `enabled` fields.
- **Web UI integration** Select roles from a dropdown in the chat interface. Role selection affects both AI behavior and available tool suggestions.
**Creating a custom role (example):**
@@ -265,44 +300,42 @@ Requirements / tips:
- api-fuzzer
- arjun
- graphql-scanner
skills:
- cyberstrike-eino-demo
enabled: true
```
2. Restart the server or reload configuration; the role appears in the role selector dropdown.
### Multi-Agent Mode (Eino: Deep, Plan-Execute, Supervisor)
- **What it is** An optional execution path beside **single-agent ReAct**, built on CloudWeGo **Eino** `adk/prebuilt`: **`deep`** — coordinator + **`task`** sub-agents; **`plan_execute`** — planner / executor / replanner loop (no YAML/Markdown sub-agent list); **`supervisor`** — orchestrator with **`transfer`** and **`exit`** over Markdown-defined specialists. The client sends **`orchestration`**: `deep` | `plan_execute` | `supervisor` (default `deep`).
- **What it is** Multi-agent orchestration on CloudWeGo **Eino** `adk/prebuilt` (alongside **Eino single-agent** on `/api/eino-agent*`): **`deep`** — coordinator + **`task`** sub-agents for complex security testing and delegated synthesis; **`plan_execute`** — planner / executor / replanner for structured loops; **`supervisor`** — expert-routing mode with **`transfer`** / **`exit`** for multiple specialist sub-agents. Client sends **`orchestration`**: `deep` | `plan_execute` | `supervisor` (default `deep`).
- **Markdown agents** Under `agents_dir` (default `agents/`):
- **Deep orchestrator**: `orchestrator.md` *or* one `.md` with `kind: orchestrator`. Body or `multi_agent.orchestrator_instruction`, then Eino defaults.
- **Plan-Execute orchestrator**: fixed name **`orchestrator-plan-execute.md`** (plus optional `orchestrator_instruction_plan_execute` in YAML).
- **Supervisor orchestrator**: fixed name **`orchestrator-supervisor.md`** (plus optional `orchestrator_instruction_supervisor`); requires at least one sub-agent.
- **Supervisor orchestrator**: fixed name **`orchestrator-supervisor.md`** (plus optional `orchestrator_instruction_supervisor`); requires at least one sub-agent, and one-sub-agent runs emit a hint that expert routing has limited value.
- **Sub-agents** (for **deep** / **supervisor**): other `*.md` files (YAML front matter + body). Not used as **`task`** targets if marked orchestrator-only.
- **Management** Web UI: **Agents → Agent management**; API `/api/multi-agent/markdown-agents`.
- **Config** `multi_agent` in `config.yaml`: `enabled`, `default_mode`, `robot_use_multi_agent`, `batch_use_multi_agent`, `max_iteration`, `plan_execute_loop_max_iterations`, per-mode orchestrator instruction fields, optional YAML `sub_agents` merged with disk (`id` clash → Markdown wins), **`eino_skills`**, **`eino_middleware`** (optional ADK middleware and Deep/Supervisor tuning).
- **Details** **[docs/MULTI_AGENT_EINO.md](docs/MULTI_AGENT_EINO.md)** (streaming, robots, batch, middleware caveats).
- **Config** `multi_agent` in `config.yaml`: `enabled`, `robot_default_agent_mode`, `batch_use_multi_agent`, `max_iteration`, `plan_execute_loop_max_iterations`, per-mode orchestrator instruction fields, optional YAML `sub_agents` merged with disk (`id` clash → Markdown wins), **`eino_skills`**, **`eino_middleware`** (optional ADK middleware and Deep/Supervisor tuning).
- **Resilience & long runs** `checkpoint_dir` enables ADK **resume** after process crashes (distinct from trace-based “interrupt & continue”). `deep_model_retry_max_retries` retries transient LLM API failures within a single call. **Summarization** writes a filtered **transcript** when compression fires; the summary message includes the path so the model can `read_file` for scan output and other pre-compaction details.
- **Details** **[docs/en-US/MULTI_AGENT_EINO.md](docs/en-US/MULTI_AGENT_EINO.md)** (streaming, robots, batch, middleware caveats).
### Skills System (Agent Skills + Eino)
- **Layout** Each skill is a directory with **required** `SKILL.md` only ([Agent Skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview)): YAML front matter **only** `name` and `description`, plus Markdown body. Optional sibling files (`FORMS.md`, `REFERENCE.md`, `scripts/*`, …). **No** `SKILL.yaml` (not part of Claude or Eino specs); sections/scripts/progressive behavior are **derived at runtime** from Markdown and the filesystem.
- **Runtime refactor** **`skills_dir`** is the single root for packs. **Multi-agent** loads them through Einos official **`skill`** middleware (**progressive disclosure**: model calls `skill` with a pack **name** instead of receiving full SKILL text up front). Configure via **`multi_agent.eino_skills`**: `disable`, `filesystem_tools` (host read/glob/grep/write/edit/execute), `skill_tool_name`.
- **Eino / RAG** Packages are also split into `schema.Document` chunks for `FilesystemSkillsRetriever` (`skills.AsEinoRetriever()`) in **compose** graphs (e.g. knowledge/indexing pipelines).
- **Skill hints in prompts** Role-bound skill **ids** (directory names) are recommended in the system prompt; full text is not injected by default.
- **HTTP API** `/api/skills` listing and `depth` (`summary` | `full`), `section`, and `resource_path` remain for the web UI and ops; **model-side** skill loading in multi-agent uses the **`skill`** tool, not MCP.
- **Optional `eino_middleware`** e.g. `tool_search` (dynamic MCP tool list), `patch_tool_calls`, `plantask` (structured tasks; persistence defaults under a subdirectory of `skills_dir`), `reduction`, `checkpoint_dir`, Deep output key / model retries / task-tool description prefix—see `config.yaml` and `internal/config/config.go`.
- **Optional `eino_middleware`** e.g. `tool_search` (dynamic MCP tool list), `patch_tool_calls`, **`plantask`** (Eino `TaskCreate` / `TaskGet` / `TaskUpdate` / `TaskList`; JSON under `skills_dir/.eino/plantask/<conversation-id>/`; Eino clears task files when **all** tasks are marked completed), `reduction`, **`checkpoint_dir`** (`data/eino-checkpoints/`), **`deep_model_retry_max_retries`**, **`deep_output_key`**, task-tool description prefix—see `config.yaml` and `internal/config/config.go`.
- **Shipped demo** `skills/cyberstrike-eino-demo/`; see `skills/README.md`.
**Creating a skill:**
1. `mkdir skills/<skill-id>` and add standard `SKILL.md` (+ any optional files), or drop in an open-source skill folder as-is.
2. Reference `<skill-id>` in a roles `skills` list in `roles/*.yaml`.
2. Use **multi-agent** with **`multi_agent.eino_skills`** enabled so the model can call the **`skill`** tool with that pack **name**.
### Tool Orchestration & Extensions
- **YAML recipes** in `tools/*.yaml` describe commands, arguments, prompts, and metadata.
- **Directory hot-reload** pointing `security.tools_dir` to a folder is usually enough; inline definitions in `config.yaml` remain supported for quick experiments.
- **Large-result pagination** outputs beyond 200 KB are stored as artifacts retrievable through the `query_execution_result` tool with paging, filters, and regex search.
- **Large tool outputs** outputs beyond `reduction_max_length_for_trunc` are summarized via Eino reduction with full content persisted under `tmp/reduction/`; use `read_file` on the path in `<persisted-output>`.
- **Result compression** multi-megabyte logs can be summarized or losslessly compressed before persisting to keep SQLite lean.
**Creating a custom tool (typical flow)**
1. Copy an existing YAML file from `tools/` (for example `tools/sample.yaml`).
1. Copy an existing YAML file from `tools/` (for example `tools/nmap.yaml` or `tools/ffuf.yaml`).
2. Update `name`, `command`, `args`, and `short_description`.
3. Describe positional or flag parameters in `parameters[]` so the agent knows how to build CLI arguments.
4. Provide a longer `description`/`notes` block if the agent needs extra context or post-processing tips.
@@ -321,6 +354,12 @@ Requirements / tips:
- **Connectivity test** Use **Test connectivity** to verify that the shell URL, password, and command parameter are correct before running commands (sends a lightweight `echo 1` check).
- **Persistence** All WebShell connections and AI conversations are stored in SQLite (same database as conversations), so they persist across restarts.
### Built-in C2 (Command & Control)
- **What it is** A first-party, **AI-native** C2 stack: listeners accept implants (beacons), the server stores **sessions** and **tasks** in SQLite, pushes updates over an **event bus** (including **SSE**), and exposes everything through authenticated **REST** plus MCP.
- **Listeners & transports** `tcp_reverse`, `http_beacon`, `https_beacon`, and `websocket`; per-listener crypto keys; running listeners can be **restored after restart** when marked running in the database.
- **Agent integration** MCP exposes a small **C2 tool family** (listeners, sessions, **`c2_task`**, task management, payloads, events, profiles, files) so the same agent loop can orchestrate C2 alongside other tools; dangerous task types can go through the existing **HITL** bridge when your session policy requires it.
- **Safety** Use **only** in lab or **fully authorized** engagements; combine network isolation, strong auth, and HITL/allowlists as your policy demands.
### MCP Everywhere
- **Web mode** ships with HTTP MCP server automatically consumed by the UI.
- **MCP stdio mode** `go run cmd/mcp-stdio/main.go` exposes the agent to Cursor/CLI.
@@ -435,16 +474,12 @@ A test SSE MCP server is available at `cmd/test-sse-mcp-server/` for validation
### Knowledge Base
- **Vector search** AI agent can automatically search the knowledge base for relevant security knowledge during conversations using the `search_knowledge_base` tool.
- **Vector retrieval** cosine similarity over stored embeddings, aligned with Eino `retriever.Retriever` usage.
- **Auto-indexing** scans the `knowledge_base/` directory for Markdown files and automatically indexes them with embeddings.
- **Web management** create, update, delete knowledge items through the web UI, with category-based organization.
- **RAG pipeline (always on)** **MultiQuery** (LLM query rewrite) → vector prefetch & fusion → **HTTP rerank** (DashScope `gte-rerank` or Cohere-compatible `/v1/rerank`) → post-processing (normalized dedupe, char/token budget, final top_k). Rerank failures degrade to fusion order without breaking search.
- **Vector retrieval** cosine similarity over stored embeddings with configurable threshold, aligned with Eino `retriever.Retriever` usage.
- **Auto-indexing** scans the `knowledge_base/` directory for Markdown files and automatically indexes them with embeddings (Markdown header split + recursive chunking via Eino).
- **Web management** create, update, delete knowledge items through the web UI, with category-based organization; settings page exposes MultiQuery / rerank / prefetch options.
- **Retrieval logs** tracks all knowledge retrieval operations for audit and debugging.
**Quick Start (Using Pre-built Knowledge Base):**
1. **Download the knowledge database** Download the pre-built knowledge database file from [GitHub Releases](https://github.com/Ed1s0nZ/CyberStrikeAI/releases).
2. **Extract and place** Extract the downloaded knowledge database file (`knowledge.db`) and place it in the project's `data/` directory.
3. **Restart the service** Restart the CyberStrikeAI service, and the knowledge base will be ready to use immediately without rebuilding the index.
**Setting up the knowledge base:**
1. **Enable in config** set `knowledge.enabled: true` in `config.yaml`:
```yaml
@@ -459,6 +494,17 @@ A test SSE MCP server is available at `cmd/test-sse-mcp-server/` for validation
retrieval:
top_k: 5
similarity_threshold: 0.7
multi_query:
max_queries: 4 # LLM rewrite variants (always on)
rerank: # always on; empty fields inherit openai/embedding credentials
provider: "" # auto: dashscope | cohere from base_url
model: "" # empty: gte-rerank (DashScope) or rerank-multilingual-v3.0 (Cohere)
base_url: ""
api_key: ""
post_retrieve:
prefetch_top_k: 20 # vector candidates per MultiQuery variant; 0 = max(top_k×4, 20)
max_context_chars: 0
max_context_tokens: 0
```
2. **Add knowledge files** place Markdown files in `knowledge_base/` directory, organized by category (e.g., `knowledge_base/SQL Injection/README.md`).
3. **Scan and index** use the web UI to scan the knowledge base directory, which will automatically import files and build vector embeddings.
@@ -477,6 +523,7 @@ A test SSE MCP server is available at `cmd/test-sse-mcp-server/` for validation
- **Vulnerability APIs** manage vulnerabilities via `/api/vulnerabilities` endpoints: `GET /api/vulnerabilities` (list with filters), `POST /api/vulnerabilities` (create), `GET /api/vulnerabilities/:id` (get), `PUT /api/vulnerabilities/:id` (update), `DELETE /api/vulnerabilities/:id` (delete), `GET /api/vulnerabilities/stats` (statistics).
- **Batch Task APIs** manage batch task queues via `/api/batch-tasks` endpoints: `POST /api/batch-tasks` (create queue), `GET /api/batch-tasks` (list queues), `GET /api/batch-tasks/:queueId` (get queue), `POST /api/batch-tasks/:queueId/start` (start execution), `POST /api/batch-tasks/:queueId/cancel` (cancel), `DELETE /api/batch-tasks/:queueId` (delete), `POST /api/batch-tasks/:queueId/tasks` (add task), `PUT /api/batch-tasks/:queueId/tasks/:taskId` (update task), `DELETE /api/batch-tasks/:queueId/tasks/:taskId` (delete task). Tasks execute sequentially, each creating a separate conversation with full status tracking.
- **WebShell APIs** manage WebShell connections and execute commands via `/api/webshell/connections` (GET list, POST create, PUT update, DELETE delete) and `/api/webshell/exec` (command execution), `/api/webshell/fileop` (list/read/write/delete files).
- **C2 APIs** manage listeners, sessions, tasks, payloads, files, and events under `/api/c2/*` (e.g. listeners CRUD/start/stop, session sleep, task create/cancel/wait, payload build/download, event stream).
- **Task control** pause/resume/stop long scans, re-run steps with new params, or stream transcripts.
- **Audit & security** rotate passwords via `/api/auth/change-password`, enforce short-lived sessions, and restrict MCP ports at the network layer when exposing the service.
@@ -518,18 +565,34 @@ knowledge:
retrieval:
top_k: 5 # Number of top results to return
similarity_threshold: 0.7 # Minimum cosine similarity (0-1)
multi_query:
max_queries: 4 # MultiQuery rewrite variants (always on)
rerank: # HTTP rerank (always on); empty fields inherit openai/embedding credentials
provider: ""
model: ""
base_url: ""
api_key: ""
post_retrieve:
prefetch_top_k: 20 # per MultiQuery variant; 0 = max(top_k×4, 20)
max_context_chars: 0
max_context_tokens: 0
roles_dir: "roles" # Role configuration directory (relative to config file)
skills_dir: "skills" # Skills directory (relative to config file)
agents_dir: "agents" # Multi-agent Markdown definitions (orchestrator + sub-agents)
multi_agent:
enabled: false
default_mode: "single" # single | multi (UI default when multi-agent is enabled)
robot_use_multi_agent: false
default_mode: "eino_single" # eino_single | multi (UI default when multi-agent is enabled)
robot_default_agent_mode: eino_single
batch_use_multi_agent: false
orchestrator_instruction: "" # Deep; used when orchestrator.md body is empty
# orchestrator_instruction_plan_execute / orchestrator_instruction_supervisor optional
# eino_skills: { disable: false, filesystem_tools: true, skill_tool_name: skill }
# eino_middleware: optional patch_tool_calls, tool_search, plantask, reduction, checkpoint_dir, ...
# eino_middleware: plantask_enable, checkpoint_dir, deep_model_retry_max_retries, deep_output_key, ...
project:
enabled: true # Enable project blackboard & fact MCP tools
fact_index_max_runes: 65000
fact_summary_max_runes: 24000
default_inject_deprecated: false
```
### Tool Definition Example (`tools/nmap.yaml`)
@@ -574,21 +637,31 @@ enabled: true
## Related documentation
- [Multi-agent mode (Eino)](docs/MULTI_AGENT_EINO.md): **Deep**, **Plan-Execute**, **Supervisor**, `agents/*.md`, `eino_skills` / `eino_middleware`, APIs, and chat/stream behavior.
- [Robot / Chatbot guide (DingTalk & Lark)](docs/robot_en.md): Full setup, commands, and troubleshooting for using CyberStrikeAI from DingTalk or Lark on your phone. **Follow this doc to avoid common pitfalls.**
- [Documentation index](docs/README.md): deployment, configuration, security model, API, knowledge base, C2, WebShell, MCP, development, testing, and troubleshooting.
- [Deployment guide](docs/en-US/deployment.md): source/binary startup, HTTPS, reverse proxy, systemd, backup, upgrade, and rollback.
- [Runbooks](docs/en-US/runbooks.md): production setup, external MCP, knowledge base, authorized Web testing, and C2 cleanup workflows.
- [Security hardening](docs/en-US/security-hardening.md): launch baseline, HITL allowlist, reverse proxy, file permissions, and periodic review.
- [API recipes](docs/en-US/api-recipes.md): examples for login, Agent, streaming, multi-agent, uploads, vulnerabilities, KB, and audit export.
- [Configuration reference](docs/en-US/configuration.md): main `config.yaml` sections, recommended values, and update guidance.
- [Security model](docs/en-US/security-model.md): authentication, tool execution, HITL, audit, C2/WebShell, and data safety boundaries.
- [API reference](docs/en-US/api-reference.md): OpenAPI, authentication, Agent, projects, knowledge base, C2, WebShell, and other API entry points.
- [Multi-agent mode (Eino)](docs/en-US/MULTI_AGENT_EINO.md): **Deep**, **Plan-Execute**, **Supervisor**, `agents/*.md`, `eino_skills` / `eino_middleware`, APIs, and chat/stream behavior.
- [Graph orchestration guide](docs/en-US/workflow-graph.md): visual workflow design, node configuration, `previous` / `outputs` variable passing, and role binding.
- [Robot / Chatbot guide](docs/en-US/robot.md): Setup, commands, and troubleshooting for WeChat, WeCom, DingTalk, Lark, Telegram, Slack, Discord, and QQ Bot.
- [HITL best practices](docs/en-US/hitl-best-practices.md): reviewer modes, allowlists, Audit Agent prompts, and separate small-model configuration.
## Project Layout
```
CyberStrikeAI/
├── cmd/ # Server, MCP stdio entrypoints, tooling
├── internal/ # Agent, MCP core, handlers, security executor
├── internal/ # Agent, MCP core, handlers, C2 (`internal/c2`), security executor
├── web/ # Static SPA + templates
├── tools/ # YAML tool recipes (100+ examples provided)
├── roles/ # Role configurations (12+ predefined security testing roles)
├── skills/ # Agent Skills dirs (SKILL.md + optional files; demo: cyberstrike-eino-demo)
├── agents/ # Multi-agent Markdown (orchestrator.md + sub-agent *.md)
├── docs/ # Documentation (e.g. robot/chatbot guide, MULTI_AGENT_EINO.md)
├── docs/ # Topic docs (deployment, config, security, API, knowledge base, C2, WebShell, etc.)
├── images/ # Docs screenshots & diagrams
├── config.yaml # Runtime configuration
├── run.sh # Convenience launcher
@@ -627,8 +700,6 @@ CyberStrikeAI has joined [404Starlink](https://github.com/knownsec/404StarLink)
</a>
</div>
## Stargazers over time
![Stargazers over time](https://starchart.cc/Ed1s0nZ/CyberStrikeAI.svg)
---
@@ -654,8 +725,8 @@ CyberStrikeAI is a professional security testing platform designed to assist sec
**The developers are not responsible for any misuse!** Please ensure your usage complies with local laws and regulations, and that you have obtained explicit authorization from the target system owner.
For vulnerability reporting and deployment hardening guidance, see [SECURITY.md](SECURITY.md).
---
Need help or want to contribute? Open an issue or PR—community tooling additions are welcome!
+129 -56
View File
@@ -1,5 +1,5 @@
<div align="center">
<img src="web/static/logo.png" alt="CyberStrikeAI Logo" width="200">
<img src="images/logo.png" alt="CyberStrikeAI Logo" width="200">
</div>
# CyberStrikeAI
@@ -8,6 +8,12 @@
**社区**[加入 Discord](https://discord.gg/8PjVCMu8Zw)
**CyberStrikeAI 正在构建现代网络安全的智能体执行层。**
它将 AI 智能体、安全工具、MCP 原生集成、知识系统、人工监督与攻击链智能汇聚到一个面向授权安全任务的统一工作空间中。CyberStrikeAI 不再把工具、提示词、证据、审批和报告视为割裂环节,而是将安全意图转化为可规划、可执行、可审查、可复盘、可持续沉淀上下文的多智能体工作流。
CyberStrikeAI 基于 Go 构建,为 AI 原生安全运营提供完整底座:100+ 精选工具配方、角色化测试、Agent Skills、基于 Eino 的单智能体与多智能体编排、RAG 知识检索、图工作流、漏洞与任务生命周期管理、WebShell 运营、机器人接入,以及面向授权实验室和安全任务场景的内置轻量 C2 框架。
<details>
<summary><strong>微信群</strong>(点击展开二维码)</summary>
@@ -26,16 +32,24 @@
</details>
CyberStrikeAI 是一款 **AI 原生安全测试平台**,基于 Go 构建,集成了 100+ 安全工具、智能编排引擎、角色化测试与预设安全测试角色、Skills 技能系统与专业测试技能,以及完整的测试生命周期管理能力。通过原生 MCP 协议与 AI 智能体,支持从对话指令到漏洞发现、攻击链分析、知识检索与结果可视化的全流程自动化,为安全团队提供可审计、可追溯、可协作的专业测试环境。
## 界面与集成预览
<div align="center">
### 系统仪表盘概览
<img src="./images/dashboard.png" alt="系统仪表盘" width="100%">
<table>
<tr>
<td width="50%" align="center">
<strong>浅色模式</strong><br/>
<img src="./images/dashboard.png" alt="系统仪表盘(浅色)" width="100%">
</td>
<td width="50%" align="center">
<strong>深色模式</strong><br/>
<img src="./images/dark.png" alt="系统仪表盘(深色)" width="100%">
</td>
</tr>
</table>
*仪表盘提供系统运行状态、安全漏洞、工具使用情况和知识库的全面概览,帮助用户快速了解平台核心功能和当前状态。*
@@ -104,21 +118,28 @@ CyberStrikeAI 是一款 **AI 原生安全测试平台**,基于 Go 构建,集
## 特性速览
- 🤖 兼容 OpenAI/DeepSeek/Claude 等模型的智能决策引擎
- 🔌 原生 MCP 协议,支持 HTTP / stdio / SSE 传输模式以及外部 MCP 接入
- 🧰 100+ 现成工具模版 + YAML 扩展能力
- 🤖 面向智能体时代的执行层,将自然语言意图转化为精准、受控、可审计的安全行动
- 🧩 基于 Eino 的单智能体与多智能体编排,支持 Deep、Plan-Execute、Supervisor 等模式
- 🔌 MCP 原生工具执行,支持 HTTP / stdio / SSE 传输、外部 MCP 联邦与动态工具发现
- 🧰 100+ 精选安全工具配方、YAML 扩展机制与按角色收敛的工具控制
- 📄 大结果分页、压缩与全文检索
- 🔗 攻击链可视化、风险打分与步骤回放
- 🔒 Web 登录保护、审计日志、SQLite 持久化
- 📚 知识库(RAG):向量嵌入与余弦相似度检索(与 Eino `retriever.Retriever` 语义一致),可选 **Eino Compose** 索引流水线及检索后处理(预算、重排等配置项)
- 🔗 攻击链智能分析,支持图谱视图、风险打分、项目事实沉淀与步骤回放
- 🧑‍⚖️ 人机协同治理,支持审批模式、免审批白名单、审计 Agent 复核与可追溯决策
- 🔒 Web 登录保护、审计日志、SQLite 持久化与行动证据留存
- 📚 知识库(RAG):**Eino MultiQuery** 查询改写 + 多路向量检索 + **HTTP 精排**DashScope `gte-rerank` / Cohere 兼容)+ 后处理(去重、预算);索引侧为 **Eino Compose** 流水线
- 📁 对话分组管理:支持分组创建、置顶、重命名、删除等操作
- 📂 **项目管理**:共享事实(黑板)跨会话沉淀认知,`upsert_project_fact` + `links` 串联攻击路径;聊天攻击链与项目事实图可视化
- 🛡️ 漏洞管理功能:完整的漏洞 CRUD 操作,支持严重程度分级、状态流转、按对话/严重程度/状态过滤,以及统计看板
- 📋 批量任务管理:创建任务队列,批量添加任务,依次顺序执行,支持任务编辑与状态跟踪
- 🎭 角色化测试:预设安全测试角色(渗透测试、CTF、Web 应用扫描等),支持自定义提示词和工具限制
- 🧩 **多代理(CloudWeGo Eino**:在 **单代理 ReAct**`/api/agent-loop`)之外,**多代理**`/api/multi-agent/stream`)提供 **`deep`**(协调主代理 + `task` 子代理)、**`plan_execute`**(规划 / 执行 / 重规划)、**`supervisor`**(主代理 `transfer` / `exit` 监督子代理);由请求体 **`orchestration`** 选择。`agents/` 下分模式主代理:`orchestrator.md`Deep)、`orchestrator-plan-execute.md``orchestrator-supervisor.md`,及适用的子代理 `*.md`(详见 [多代理说明](docs/MULTI_AGENT_EINO.md)
- 🎯 **Skills(面向 Eino 重构**技能包放在 **`skills_dir`**,遵循 **Agent Skills** 目录规范(`SKILL.md` + 可选文件);**多代理** 下通过 Eino 官方 **`skill`** 工具 **渐进式披露**(按 name 加载)。**`multi_agent.eino_skills`** 控制是否启用、本机文件/Shell 工具、工具名覆盖;**`eino_middleware`** 可选 patch、tool_search、plantask、reduction、断点目录及 Deep 调参。20+ 领域示例仍可绑定角色
- 📱 **机器人**:支持钉钉、飞书长连接,在手机端与 CyberStrikeAI 对话(配置与命令详见 [机器人使用说明](docs/robot.md)
- 🔀 **图编排**:可视化流程编排(开始 / Agent / 工具 / 条件 / 审批 / 输出),节点间用 `{{previous.output}}``{{outputs.变量名}}` 传参;绑定角色后对话自动按图执行。详见 [图编排使用说明](docs/zh-CN/workflow-graph.md)
- 🧩 **Agent 编排(CloudWeGo Eino****单代理** `POST /api/eino-agent/stream`Eino ADK);**多代理** `POST /api/multi-agent/stream``orchestration`**`deep`** / **`plan_execute`** / **`supervisor`**。ADK **Summarization** 在上下文过长时压缩历史;压缩前将可恢复 **转录** 写入 `data/conversation_artifacts/<会话ID>/summarization/transcript.txt`(保留完整 user/assistant/tool 轮次,省略静态 system)。`agents/` 下主代理与子代理 Markdown 见 [多代理说明](docs/zh-CN/MULTI_AGENT_EINO.md)
- 🖼️ **视觉分析(`analyze_image`**:独立 Vision 模型(如 `qwen-vl-max`),MCP 工具分析本地截图/验证码/UI;图片仅在单次 VL 调用中出现,对话上下文只保留文字摘要。配置见 `config.yaml``vision` 与 [视觉分析说明](docs/zh-CN/VISION.md)
- 🎯 **Skills(面向 Eino 重构)**:技能包放在 **`skills_dir`**,遵循 **Agent Skills** 目录规范(`SKILL.md` + 可选文件);**多代理** 下通过 Eino 官方 **`skill`** 工具 **渐进式披露**(按 name 加载)。**`multi_agent.eino_skills`** 控制是否启用、本机文件/Shell 工具、工具名覆盖;**`eino_middleware`** 可选 patch、tool_search、**plantask**`TaskCreate` / `TaskList` 任务板,落在 `skills_dir/.eino/plantask/`)、reduction、文件型 **checkpoint**`checkpoint_dir`)、ChatModel **重试**、会话 **输出键** 及 Deep 调参。20+ 领域示例仍可绑定角色
- 📱 **机器人**:个人微信、企业微信、钉钉、飞书、Telegram、Slack、Discord、QQ 机器人,在手机或 IM 中与 CyberStrikeAI 对话(详见 [机器人使用说明](docs/zh-CN/robot.md)
- 🧑‍⚖️ **人机协同(HITL**:对话页侧栏配置协同模式与免审批工具白名单;全局列表在 `config.yaml``hitl.tool_whitelist`;审计 Agent 可通过 `hitl.audit_model` 使用独立小模型;点「应用」可将新增工具合并写入配置文件且**无需重启**即可生效;导航 **人机协同** 页处理待审批工具调用。详见 [人机协同最佳实践](docs/zh-CN/hitl-best-practices.md)
- 🐚 **WebShell 管理**:添加与管理 WebShell 连接(兼容冰蝎/蚁剑等),通过虚拟终端执行命令、内置文件管理进行文件操作,并提供按连接维度保存历史的 AI 助手标签页;支持 PHP/ASP/ASPX/JSP 及自定义类型,可配置请求方法与命令参数。
- 📡 **内置 C2**:面向 AI 协同的轻量 **C2**——**多种监听器**TCP 反向、HTTP/HTTPS Beacon、WebSocket)、**加密** Beacon 信道、**会话与任务**队列及持久化、**Payload** 辅助(一键命令 / 构建 / 下载)、**SSE** 实时事件、REST`/api/c2/*`)及智能体侧 **一组 C2 MCP 工具**(如 `c2_listener``c2_session`、**`c2_task`**、`c2_task_manage``c2_payload``c2_event``c2_profile``c2_file`);敏感操作可对接 **人机协同(HITL**,并支持 OPSEC 类规则(如命令拒绝正则)。**仅限授权测试。**
## 插件(Plugins
@@ -171,9 +192,11 @@ chmod +x run.sh && ./run.sh
- ✅ 编译构建项目
- ✅ 启动服务器
**网络默认:** `run.sh` 会以 **`--https`** 并传入项目根 **`config.yaml`** 启动(本机自签证书,多路流式场景更稳)。只要明文 HTTP 用 **`./run.sh --http`**。生产环境在 **`config.yaml`** 的 **`server.tls_cert_path` / `server.tls_key_path`** 配正式证书(见文件内注释)。手动启动可加 **`--https`** 或环境变量 **`CYBERSTRIKE_HTTPS=1`**`-config` 写错时程序会在终端提示正确写法。
**首次配置:**
1. **配置 AI 模型 API**(首次使用前必填)
- 启动后访问 http://localhost:8080
- 启动后在浏览器打开 **`https://127.0.0.1:8080/`**(或 **`https://localhost:8080/`**;端口以 `config.yaml`**`server.port`** 为准,默认 8080),并按提示信任自签证书。若使用 **`./run.sh --http`**,则改用 **`http://`** 访问。
- 进入 `设置` → 填写 API 配置信息:
```yaml
openai:
@@ -183,31 +206,40 @@ chmod +x run.sh && ./run.sh
```
- 或启动前直接编辑 `config.yaml` 文件
2. **登录系统** - 使用控制台显示的自动生成密码(或在 `config.yaml` 中设置 `auth.password`
3. **安装安全工具(可选)** - 按需安装所需工具
3. **安装安全工具(可选)** - 按需安装 `tools/` 目录中的工具;未安装的工具在执行时会自动跳过或改用替代方案。常用示例
**macOSHomebrew):**
```bash
# macOS
brew install nmap sqlmap nuclei httpx gobuster feroxbuster subfinder amass
# Ubuntu/Debian
sudo apt-get install nmap sqlmap nuclei httpx gobuster feroxbuster
brew install nmap masscan sqlmap nikto gobuster ffuf hydra hashcat nuclei subfinder
```
未安装的工具会自动跳过或改用替代方案。
**LinuxKali / Debian / Ubuntu):**
```bash
sudo apt update
sudo apt install -y nmap masscan sqlmap nikto gobuster hydra hashcat john binwalk
# 部分发行版需自行安装:ffuf、nuclei、subfinder 等可用 go install 或见各工具官网
```
完整工具列表见 `tools/` 目录;各工具安装方式以官方文档为准。
**其他启动方式:**
```bash
# 直接运行(需手动配置环境)
go run cmd/server/main.go
# 直接运行(需自行配环境);与 run.sh 默认一致可加 --https
go run cmd/server/main.go --https
# 手动编译
go build -o cyberstrike-ai cmd/server/main.go
./cyberstrike-ai
./cyberstrike-ai --https
```
若日志出现 `client sent an HTTP request to an HTTPS server`,说明仍有客户端用 **`http://`** 访问只提供 HTTPS 的端口,请改为 **`https://`**。
**说明:** Python 虚拟环境(`venv/`)由 `run.sh` 自动创建和管理。需要 Python 的工具(如 `api-fuzzer`、`http-framework-test` 等)会自动使用该环境。
### CyberStrikeAI 版本更新(无兼容性问题)
1. (首次使用)启用脚本:`chmod +x upgrade.sh`
2. 一键升级:`./upgrade.sh`(可选参数:`--tag vX.Y.Z`、`--no-venv`、`--preserve-custom`、`--yes`
2. 一键升级:`./upgrade.sh`(可选参数:`--tag vX.Y.Z`、`--no-venv`、`--yes`)。本地的 `tools/`、`roles/`、`skills/` 会始终保留不被覆盖。
3. 脚本会备份你的 `config.yaml` 和 `data/`,从 GitHub Release 升级代码,更新 `config.yaml` 的 `version` 字段后重启服务。
推荐的一键指令:
@@ -226,15 +258,18 @@ go build -o cyberstrike-ai cmd/server/main.go
### 常用流程
- **对话测试**:自然语言触发多步工具编排,SSE 实时输出。
- **单代理 / 多代理**`multi_agent.enabled: true` 后可在聊天中切换 **单代理**(原有 **ReAct**`/api/agent-loop/stream`)与 **多代理**`/api/multi-agent/stream`)。多代理在既有 **`deep`**`task` 子代理)基础上,新增 **`plan_execute`**、**`supervisor`**,由 **`orchestration`** 指定。MCP 工具与单代理同源桥接
- **单代理 / 多代理**聊天可选 **Eino 单代理**`/api/eino-agent/stream`)与 **多代理**`/api/multi-agent/stream` + `orchestration`)。多代理需 `multi_agent.enabled: true`。MCP 工具桥接一致
- **角色化测试**:从预设的安全测试角色(渗透测试、CTF、Web 应用扫描、API 安全测试等)中选择,自定义 AI 行为和可用工具。每个角色可应用自定义系统提示词,并可限制可用工具列表,实现聚焦的测试场景。
- **图编排**:在 **图编排** 页拖拽节点、连线并保存流程;在角色中绑定 `workflow_id` 后,该角色对话将按图执行(Agent、MCP 工具、条件分支等)。跨节点传参优先用 `{{outputs.变量名}}`。详见 [图编排使用说明](docs/zh-CN/workflow-graph.md)。
- **工具监控**:查看任务队列、执行日志、大文件附件。
- **会话历史**:所有对话与工具调用保存在 SQLite,可随时重放。
- **对话分组**:将对话按项目或主题组织到不同分组,支持置顶、重命名、删除等操作,所有数据持久化存储。
- **漏洞管理**:在测试过程中创建、更新和跟踪发现的漏洞。支持按严重程度(严重/高/中/低/信息)、状态(待确认/已确认/已修复/误报)和对话进行过滤,查看统计信息并导出发现。
- **批量任务管理**:创建任务队列,批量添加多个任务,执行前可编辑或删除任务,然后依次顺序执行。每个任务会作为独立对话执行,支持完整的状态跟踪(待执行/执行中/已完成/失败/已取消)和执行历史。
- **WebShell 管理**:添加并管理 WebShell 连接(PHP/ASP/ASPX/JSP 或自定义类型)。使用虚拟终端执行命令(带命令历史与快捷命令),使用文件管理浏览、读取、编辑、上传与删除目标文件,并支持按路径导航和名称过滤。连接信息持久化存储于 SQLite,支持 GET/POST 及可配置命令参数(兼容冰蝎/蚁剑等)。
- **内置 C2**:在 Web 界面或 `/api/c2/*` 创建/启动 **监听器**、生成 **Payload**、查看 **会话**、下发 **任务** 并订阅 **事件(SSE)**。智能体与外部客户端通过 **C2 MCP 工具族**(含 **`c2_task`** 等)编排;开启人机协同时,高风险任务可走审批。**仅用于已获明确授权的目标。**
- **可视化配置**:在界面中切换模型、启停工具、设置迭代次数等。
- **人机协同(HITL)**:侧栏设置协同模式与免审批工具(逗号或换行);全局白名单见 `config.yaml` 的 `hitl.tool_whitelist`。审计 Agent 可通过 `hitl.audit_model` 单独配置低成本模型,适合人工审计压力较大时接管常规审批。点「**应用**」可写浏览器/服务端并合并新增工具进配置(**无需重启**)。**新对话**保留侧栏选择;导航 **人机协同** 处理待审批。从侧栏删掉工具不会自动从配置文件移除全局项,需手改 `config.yaml`。
### 默认安全措施
- 设置面板内置必填校验,防止漏配 API Key/Base URL/模型。
@@ -248,8 +283,8 @@ go build -o cyberstrike-ai cmd/server/main.go
- **预设角色**:系统内置 12+ 个预设的安全测试角色(渗透测试、CTF、Web 应用扫描、API 安全测试、二进制分析、云安全审计等),位于 `roles/` 目录。
- **自定义提示词**:每个角色可定义 `user_prompt`,会在用户消息前自动添加,引导 AI 采用特定的测试方法和关注重点。
- **工具限制**:角色可指定 `tools` 列表,限制可用工具,实现聚焦的测试流程(如 CTF 角色限制为 CTF 专用工具)。
- **Skills 集成**:角色可附加安全测试技能,id 写入提示;**多代理** 下由 Eino **`skill`** 工具 **按需加载**(渐进式披露)。**`multi_agent.eino_skills`** 控制中间件与本机 read_file/glob/grep/write/edit/execute**Deep / Supervisor** 主/子代理;**plan_execute** 执行器无独立 skill 中间件,见文档)。**单代理 ReAct** 当前不挂载该 Eino skill 链
- **轻松创建角色**:通过在 `roles/` 目录添加 YAML 文件即可创建自定义角色。每个角色定义 `name`、`description`、`user_prompt`、`icon`、`tools`、`skills`、`enabled` 字段。
- **Skills**:技能包位于 `skills_dir`;启用 **`multi_agent.eino_skills`** 后,**单代理与多代理**均可通过 Eino **`skill`** 工具按需加载。可选 **`eino_middleware`**tool_search、plantask、reduction、checkpoint、Summarization 转录等)与本机 read_file/glob/grep 等见文档
- **轻松创建角色**:通过在 `roles/` 目录添加 YAML 文件即可创建自定义角色。每个角色定义 `name`、`description`、`user_prompt`、`icon`、`tools`、`enabled` 字段。
- **Web 界面集成**:在聊天界面通过下拉菜单选择角色。角色选择会影响 AI 行为和可用工具建议。
**创建自定义角色示例:**
@@ -263,44 +298,42 @@ go build -o cyberstrike-ai cmd/server/main.go
- api-fuzzer
- arjun
- graphql-scanner
skills:
- cyberstrike-eino-demo
enabled: true
```
2. 重启服务或重新加载配置,角色会出现在角色选择下拉菜单中。
### 多代理模式(EinoDeep / Plan-Execute / Supervisor
- **能力说明** **单代理 ReAct** 并存的可选路径,基于 CloudWeGo **Eino** `adk/prebuilt`**`deep`** — 协调主代理 + **`task`** 子代理;**`plan_execute`** — 规划 / 执行 / 重规划闭环(不使用 YAML/Markdown 子代理列表);**`supervisor`** — 主代理 **`transfer`** / **`exit`** 调度 Markdown 专家。客户端通过 **`orchestration`** 选 `deep` | `plan_execute` | `supervisor`(缺省 `deep`
- **能力说明** **Eino 单代理**`/api/eino-agent*`)之外,多代理基于 CloudWeGo **Eino** `adk/prebuilt`**`deep`**、**`plan_execute`**、**`supervisor`**客户端 **`orchestration`** 选择(缺省 `deep`)。模式定位按 Eino ADK 最佳实践区分:**Deep** 适合复杂安全测试与 task 子代理协作;**Plan-Execute** 适合目标明确的规划 → 执行 → 重规划闭环;**Supervisor** 适合多个专业子代理动态分派的专家路由场景
- **Markdown 定义**`agents_dir`,默认 `agents/`):
- **Deep 主代理**`orchestrator.md` 或唯一 `kind: orchestrator` 的 `.md`;正文或 `multi_agent.orchestrator_instruction`,再回退 Eino 默认。
- **Plan-Execute 主代理**:固定 **`orchestrator-plan-execute.md`**(另可配 `orchestrator_instruction_plan_execute`)。
- **Supervisor 主代理**:固定 **`orchestrator-supervisor.md`**(另可配 `orchestrator_instruction_supervisor`);至少需一名子代理。
- **Supervisor 主代理**:固定 **`orchestrator-supervisor.md`**(另可配 `orchestrator_instruction_supervisor`);至少需一名子代理,只有一名子代理时会提示专家路由价值有限
- **子代理****deep** / **supervisor**):其余 `*.md`;标成 orchestrator 的不会进入 `task` 列表。
- **界面管理****Agents → Agent 管理**API `/api/multi-agent/markdown-agents`。
- **配置项**`multi_agent``enabled`、`default_mode`、`robot_use_multi_agent`、`batch_use_multi_agent`、`max_iteration`、`plan_execute_loop_max_iterations`、各模式 orchestrator 指令字段、可选 YAML `sub_agents` 与目录合并(同 `id` → Markdown 优先)、**`eino_skills`**、**`eino_middleware`**。
- **更多细节**[docs/MULTI_AGENT_EINO.md](docs/MULTI_AGENT_EINO.md)(流式、机器人、批量、中间件差异)
- **配置项**`multi_agent``enabled`、`robot_default_agent_mode`、`batch_use_multi_agent`、`max_iteration`、`plan_execute_loop_max_iterations`、各模式 orchestrator 指令字段、可选 YAML `sub_agents` 与目录合并(同 `id` → Markdown 优先)、**`eino_skills`**、**`eino_middleware`**。
- **长任务与恢复**`checkpoint_dir` 支持进程崩溃后 ADK **断点续跑**(与基于 trace 的「中断继续」不同)。`deep_model_retry_max_retries` 在同一次 LLM 调用内重试瞬时 API 失败。**Summarization** 触发压缩时会写入过滤后的 **transcript**,摘要消息中带路径,模型可用 `read_file` 找回扫描输出等压缩前细节
- **更多细节**[docs/zh-CN/MULTI_AGENT_EINO.md](docs/zh-CN/MULTI_AGENT_EINO.md)(流式、机器人、批量、中间件差异)。
### Skills 技能系统(Agent Skills + Eino
- **目录规范**:与 [Agent Skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) 一致,**仅**需目录下的 **`SKILL.md`**YAML 头只用官方的 **`name` 与 `description`**,正文为 Markdown。可选同目录其他文件(`FORMS.md`、`REFERENCE.md`、`scripts/*` 等)。**不使用 `SKILL.yaml`**Claude / Eino 官方均无此文件);章节、`scripts/` 列表、渐进式行为由运行时从正文与磁盘 **自动推导**。
- **运行侧重构****`skills_dir`** 为技能包唯一根目录;**多代理** 通过 Eino 官方 **`skill`** 中间件做 **渐进式披露**(模型按 **name** 调用 `skill`,而非一次性注入全文)。由 **`multi_agent.eino_skills`** 控制:`disable`、`filesystem_tools`(本机读写与 Shell)、`skill_tool_name`。
- **Eino / 知识流水线**:技能包可切分为 `schema.Document`,供 `FilesystemSkillsRetriever``skills.AsEinoRetriever()`)在 **compose** 图(如索引/编排)中使用。
- **提示词**:角色绑定的技能 **id**(文件夹名)会作为推荐写入系统提示;正文默认不整包注入。
- **HTTP 管理**`/api/skills` 列表与 `depth=summary|full`、`section`、`resource_path` 等仍用于 Web 与运维;**模型侧** 多代理走 **`skill`** 工具,而非 MCP。
- **可选 `eino_middleware`**:如 `tool_search`(动态工具列表)、`patch_tool_calls`、`plantask`(结构化任务;默认落在 `skills_dir` 下子目录)、`reduction`、`checkpoint_dir`、Deep 输出键 / 模型重试 / task 描述前缀等,见 `config.yaml` 与 `internal/config/config.go`。
- **可选 `eino_middleware`**:如 `tool_search`(动态工具列表)、`patch_tool_calls`、**`plantask`**Eino `TaskCreate` / `TaskGet` / `TaskUpdate` / `TaskList`JSON 存于 `skills_dir/.eino/plantask/<会话ID>/`**全部**任务标为 completed 后 Eino 会清理任务文件)、`reduction`、**`checkpoint_dir`**(如 `data/eino-checkpoints/`)、**`deep_model_retry_max_retries`**、**`deep_output_key`**、task 描述前缀等,见 `config.yaml` 与 `internal/config/config.go`。
- **自带示例**`skills/cyberstrike-eino-demo/`;说明见 `skills/README.md`。
**新建技能:**
1. 在 `skills/` 下创建 `<skill-id>/`,放入标准 `SKILL.md`(及任意可选文件),或直接解压开源技能包到该目录。
2. 在 `roles/*.yaml` 的 `skills` 列表中引用该 `<skill-id>`。
2. 启用 **`multi_agent.eino_skills`** 并使用 **多代理** 会话,由模型通过 **`skill`** 工具按包 **name** 加载
### 工具编排与扩展
- `tools/*.yaml` 定义命令、参数、提示词与元数据,可热加载。
- `security.tools_dir` 指向目录即可批量启用;仍支持在主配置里内联定义。
- **大结果分页**:超过 200KB 的输出会保存为附件,可通过 `query_execution_result` 工具分页、过滤、正则检索
- **大工具输出**:超过 `reduction_max_length_for_trunc` 时由 Eino reduction 摘要,完整内容落盘至 `tmp/reduction/`;按 `<persisted-output>` 中的路径用 `read_file` 读取
- **结果压缩/摘要**:多兆字节日志可先压缩或生成摘要再写入 SQLite,减小档案体积。
**自定义工具的一般步骤**
1. 复制 `tools/` 下现有示例(如 `tools/sample.yaml`)。
1. 复制 `tools/` 下现有示例(如 `tools/nmap.yaml` 或 `tools/ffuf.yaml`)。
2. 修改 `name`、`command`、`args`、`short_description` 等基础信息。
3. 在 `parameters[]` 中声明位置参数或带 flag 的参数,方便智能体自动拼装命令。
4. 视需要补充 `description` 或 `notes`,给 AI 额外上下文或结果解读提示。
@@ -318,6 +351,12 @@ go build -o cyberstrike-ai cmd/server/main.go
- **连通性测试**:使用 **测试连通性** 可在执行命令前通过一次 `echo 1` 调用校验 Shell 地址、密码与命令参数是否正确。
- **持久化**:所有 WebShell 连接与相关 AI 会话均保存在 SQLite(与对话共用数据库),服务重启后仍可继续使用。
### 内置 C2Command & Control
- **定位**:平台内置的 **AI 原生** C2 能力栈——监听器接入植入体(Beacon),服务端以 SQLite 持久化 **会话** 与 **任务**,通过 **事件总线** 推送变更(含 **SSE**),并由鉴权后的 **REST** 与 MCP 统一对外。
- **监听器与传输**:支持 `tcp_reverse`、`http_beacon`、`https_beacon`、`websocket`;按监听器独立密钥;数据库中标记为运行中的监听器可在 **服务重启后尝试恢复**。
- **与智能体联动**:通过 **`c2_task` 等 C2 MCP 工具** 与现有对话/多代理工具链协同;在会话策略需要时,危险任务类型可走既有 **人机协同(HITL)** 审批流。
- **安全提示**:**仅**在实验环境或 **已获完整书面授权** 的对抗演练中使用;结合网络隔离、强鉴权及 HITL/白名单等策略管控风险。
### MCP 全场景
- **Web 模式**:自带 HTTP MCP 服务供前端调用。
- **MCP stdio 模式**`go run cmd/mcp-stdio/main.go` 可接入 Cursor/命令行。
@@ -433,16 +472,12 @@ CyberStrikeAI 支持通过三种传输模式连接外部 MCP 服务器:
### 知识库功能
- **向量检索**:AI 智能体在对话过程中可自动调用 `search_knowledge_base` 工具搜索知识库中的安全知识。
- **向量检索**:基于嵌入余弦相似度与相似度阈值过滤(与 Eino `retriever.Retriever` 语义一致)
- **自动索引**:扫描 `knowledge_base/` 目录下的 Markdown 文件,自动构建向量嵌入索引
- **Web 管理**:通过 Web 界面创建、更新、删除知识项,支持分类管理
- **RAG 管线(始终启用)****MultiQuery**LLM 查询改写)→ 向量预取与融合 → **HTTP 精排**DashScope `gte-rerank` 或 Cohere 兼容 `/v1/rerank`)→ 后处理(规范化去重、字符/token 预算、最终 top_k)。精排失败时自动降级为融合排序,检索仍可用
- **向量相似度**:基于嵌入余弦相似度与相似度阈值过滤(与 Eino `retriever.Retriever` 语义一致)
- **自动索引**:扫描 `knowledge_base/` 目录下的 Markdown 文件,自动构建向量嵌入索引(Eino Markdown 标题切分 + 递归分块)
- **Web 管理**:通过 Web 界面创建、更新、删除知识项,支持分类管理;设置页可配置 MultiQuery / 精排 / 预取候选数。
- **检索日志**:记录所有知识检索操作,便于审计与调试。
**快速开始(使用预构建知识库):**
1. **下载知识数据库**:从 [GitHub Releases](https://github.com/Ed1s0nZ/CyberStrikeAI/releases) 下载预构建的知识数据库文件。
2. **解压并放置**:将下载的知识数据库文件(`knowledge.db`)解压后放到项目的 `data/` 目录下。
3. **重启服务**:重启 CyberStrikeAI 服务,知识库即可直接使用,无需重新构建索引。
**知识库配置步骤:**
1. **启用功能**:在 `config.yaml` 中设置 `knowledge.enabled: true`
```yaml
@@ -457,6 +492,17 @@ CyberStrikeAI 支持通过三种传输模式连接外部 MCP 服务器:
retrieval:
top_k: 5
similarity_threshold: 0.7
multi_query:
max_queries: 4 # LLM 改写变体上限(始终启用)
rerank: # 精排始终启用;留空则继承 openai/embedding 凭据
provider: "" # 空=按 base_url 推断 dashscope | cohere
model: "" # 空=DashScope→gte-rerankCohere→rerank-multilingual-v3.0
base_url: ""
api_key: ""
post_retrieve:
prefetch_top_k: 20 # 每条 MultiQuery 变体的向量候选数;0=max(top_k×4, 20)
max_context_chars: 0
max_context_tokens: 0
```
2. **添加知识文件**:将 Markdown 文件放入 `knowledge_base/` 目录,按分类组织(如 `knowledge_base/SQL注入/README.md`)。
3. **扫描索引**:在 Web 界面中点击"扫描知识库",系统会自动导入文件并构建向量索引。
@@ -475,6 +521,7 @@ CyberStrikeAI 支持通过三种传输模式连接外部 MCP 服务器:
- **漏洞管理 API**:通过 `/api/vulnerabilities` 端点管理漏洞:`GET /api/vulnerabilities`(列表,支持过滤)、`POST /api/vulnerabilities`(创建)、`GET /api/vulnerabilities/:id`(获取)、`PUT /api/vulnerabilities/:id`(更新)、`DELETE /api/vulnerabilities/:id`(删除)、`GET /api/vulnerabilities/stats`(统计)。
- **批量任务 API**:通过 `/api/batch-tasks` 端点管理批量任务队列:`POST /api/batch-tasks`(创建队列)、`GET /api/batch-tasks`(列表)、`GET /api/batch-tasks/:queueId`(获取队列)、`POST /api/batch-tasks/:queueId/start`(开始执行)、`POST /api/batch-tasks/:queueId/cancel`(取消)、`DELETE /api/batch-tasks/:queueId`(删除队列)、`POST /api/batch-tasks/:queueId/tasks`(添加任务)、`PUT /api/batch-tasks/:queueId/tasks/:taskId`(更新任务)、`DELETE /api/batch-tasks/:queueId/tasks/:taskId`(删除任务)。任务依次顺序执行,每个任务创建独立对话,支持完整状态跟踪。
- **WebShell API**:通过 `/api/webshell/connections`GET 列表、POST 创建、PUT 更新、DELETE 删除)及 `/api/webshell/exec`(执行命令)、`/api/webshell/fileop`(列出/读取/写入/删除文件)管理 WebShell 连接与执行操作。
- **C2 API**:在 `/api/c2/*` 管理监听器、会话、任务、Payload、文件与事件(如监听器增删改查/启停、会话休眠、任务创建/取消/等待、Payload 构建/下载、事件流等)。
- **任务控制**:支持暂停/终止长任务、修改参数后重跑、流式获取日志。
- **安全管理**`/api/auth/change-password` 可即时轮换口令;建议在暴露 MCP 端口时配合网络层 ACL。
@@ -516,18 +563,34 @@ knowledge:
retrieval:
top_k: 5 # 检索返回的 Top-K 结果数量
similarity_threshold: 0.7 # 余弦相似度阈值(0-1),低于此值的结果将被过滤
multi_query:
max_queries: 4 # MultiQuery 改写变体上限(始终启用)
rerank: # HTTP 精排(始终启用);留空则继承 openai/embedding 凭据
provider: ""
model: ""
base_url: ""
api_key: ""
post_retrieve:
prefetch_top_k: 20 # 每条 MultiQuery 变体;0=max(top_k×4, 20)
max_context_chars: 0
max_context_tokens: 0
roles_dir: "roles" # 角色配置文件目录(相对于配置文件所在目录)
skills_dir: "skills" # Skills 目录(相对于配置文件所在目录)
agents_dir: "agents" # 多代理 Markdown(主代理 orchestrator.md + 子代理 *.md
multi_agent:
enabled: false
default_mode: "single" # single | multi(开启多代理时的界面默认模式)
robot_use_multi_agent: false
default_mode: "eino_single" # eino_single | multi(开启多代理时的界面默认模式)
robot_default_agent_mode: eino_single
batch_use_multi_agent: false
orchestrator_instruction: "" # Deeporchestrator.md 正文为空时使用
# orchestrator_instruction_plan_execute / orchestrator_instruction_supervisor 可选
# eino_skills: { disable: false, filesystem_tools: true, skill_tool_name: skill }
# eino_middleware: 可选 patch_tool_calls、tool_search、plantask、reduction、checkpoint_dir
# eino_middleware: plantask_enable、checkpoint_dir、deep_model_retry_max_retries、deep_output_key
project:
enabled: true # 启用项目黑板与事实 MCP 工具
fact_index_max_runes: 65000
fact_summary_max_runes: 24000
default_inject_deprecated: false
```
### 工具模版示例(`tools/nmap.yaml`
@@ -572,21 +635,31 @@ enabled: true
## 相关文档
- [多代理模式(Eino](docs/MULTI_AGENT_EINO.md)**Deep**、**Plan-Execute**、**Supervisor**、`agents/*.md`、`eino_skills` / `eino_middleware`、接口与流式说明
- [机器人使用说明(钉钉 / 飞书)](docs/robot.md):在手机端通过钉钉、飞书与 CyberStrikeAI 对话的完整配置步骤、命令与排查说明,**建议按该文档操作以避免走弯路**
- [文档导航](docs/README.md):部署、配置、安全模型、API、知识库、C2、WebShell、MCP、开发、测试、排错等完整专题入口
- [部署指南](docs/zh-CN/deployment.md):源码/二进制运行、HTTPS、反向代理、systemd、备份、升级与回滚
- [运维 Runbooks](docs/zh-CN/runbooks.md):生产部署、外部 MCP、知识库、授权 Web 测试、C2 清理等可执行流程。
- [安全加固指南](docs/zh-CN/security-hardening.md):上线前基线、HITL 白名单、反向代理、文件权限和周期巡检。
- [API Recipes](docs/zh-CN/api-recipes.md):登录、Agent、流式、多代理、上传、漏洞、知识库和审计导出调用示例。
- [配置参考](docs/zh-CN/configuration.md)`config.yaml` 各配置段、推荐值和修改建议。
- [安全模型](docs/zh-CN/security-model.md):认证、工具执行、HITL、审计、C2/WebShell 和数据安全边界。
- [API 参考](docs/zh-CN/api-reference.md)OpenAPI、认证、Agent、项目、知识库、C2、WebShell 等接口入口。
- [多代理模式(Eino](docs/zh-CN/MULTI_AGENT_EINO.md)**Deep**、**Plan-Execute**、**Supervisor**、`agents/*.md`、`eino_skills` / `eino_middleware`、接口与流式说明。
- [图编排使用说明](docs/zh-CN/workflow-graph.md):可视化流程搭建、节点配置、`previous` / `outputs` 变量传参与角色绑定。
- [机器人使用说明](docs/zh-CN/robot.md):个人微信、企业微信、钉钉、飞书、Telegram、Slack、Discord、QQ 机器人的配置、命令与排查。
- [人机协同最佳实践](docs/zh-CN/hitl-best-practices.md):审批方模式、白名单、审计 Agent 提示词策略与独立小模型配置。
## 项目结构
```
CyberStrikeAI/
├── cmd/ # Web 服务、MCP stdio 入口及辅助工具
├── internal/ # Agent、MCP 核心、路由与执行器
├── internal/ # Agent、MCP 核心、路由、C2`internal/c2`与执行器
├── web/ # 前端静态资源与模板
├── tools/ # YAML 工具目录(含 100+ 示例)
├── roles/ # 角色配置文件目录(含 12+ 预设安全测试角色)
├── skills/ # Agent Skills 目录(SKILL.md + 可选文件;示例 cyberstrike-eino-demo
├── agents/ # 多代理 Markdownorchestrator.md + 子代理 *.md
├── docs/ # 说明文档(如机器人使用说明、MULTI_AGENT_EINO.md
├── docs/ # 专题文档(部署、配置、安全、API、知识库、C2、WebShell 等
├── images/ # 文档配图
├── config.yaml # 运行配置
├── run.sh # 启动脚本
@@ -624,8 +697,6 @@ CyberStrikeAI 现已加入 [404星链计划](https://github.com/knownsec/404Star
</a>
</div>
## Stargazers over time
![Stargazers over time](https://starchart.cc/Ed1s0nZ/CyberStrikeAI.svg)
---
@@ -650,6 +721,8 @@ CyberStrikeAI 是一个专业的安全测试平台,旨在帮助安全研究人
**开发者不对任何滥用行为负责!** 请确保您的使用符合当地法律法规,并获得目标系统所有者的明确授权。
安全问题报告与部署加固建议见 [SECURITY.md](SECURITY.md)。
---
欢迎提交 Issue/PR 贡献新的工具模版或优化建议!
+151
View File
@@ -0,0 +1,151 @@
# Security Policy
[中文](#安全政策) | [English](#security-policy)
## Security Policy
CyberStrikeAI is a security testing and automation platform. It can execute tools, call MCP servers, manage WebShell connections, and optionally run C2 workflows. Please treat every deployment as a high-privilege security system.
### Supported Versions
This project does not currently maintain multiple long-term support branches. Security fixes are expected to land on the latest mainline release/source tree.
If you are running an older version, please reproduce the issue against the latest code before reporting when possible.
### Reporting a Vulnerability
Please do not publicly disclose exploitable details before maintainers have had a reasonable chance to investigate.
Preferred report contents:
- affected version or commit;
- deployment mode and relevant configuration;
- clear reproduction steps;
- impact assessment;
- affected component, such as auth, MCP, tool execution, WebShell, C2, knowledge base, frontend, or API;
- whether the issue requires authentication;
- suggested mitigation, if known.
If the project repository has private vulnerability reporting enabled, use that channel. Otherwise, open a minimal public issue that states there is a security concern and avoid posting exploit details, credentials, target data, or weaponized payloads.
### Scope
In scope:
- authentication and session handling issues;
- authorization bypass in protected APIs;
- unsafe command execution behavior;
- unintended file read/write through tools or Skills;
- external MCP trust-boundary flaws;
- WebShell or C2 management vulnerabilities;
- sensitive data leakage from logs, audit records, uploads, or APIs;
- cross-site scripting or frontend injection in the Web UI;
- security-impacting configuration handling bugs.
Out of scope:
- reports against systems you do not own or are not authorized to test;
- denial-of-service testing against public services without permission;
- social engineering, phishing, or credential theft;
- issues caused only by intentionally disabling documented security controls;
- vulnerabilities in third-party tools invoked by CyberStrikeAI, unless CyberStrikeAI makes them materially worse.
### Authorized Use Boundary
CyberStrikeAI must only be used for education, research, and authorized security testing. Do not use it against systems without explicit permission.
High-risk capabilities such as Shell execution, WebShell management, C2, payload generation, external MCP tools, and batch scanning should be enabled only in controlled, authorized environments.
### Deployment Hardening
Before production use:
- change the default password;
- use HTTPS or a trusted reverse proxy;
- restrict access by IP, VPN, or bastion;
- enable audit logging;
- keep C2 disabled unless explicitly needed;
- review external MCP servers before enabling them;
- keep high-risk tools out of global HITL allowlists;
- back up `config.yaml`, `data/`, and custom resource directories.
See:
- [Security Model](docs/en-US/security-model.md)
- [Security Hardening](docs/en-US/security-hardening.md)
- [Runbooks](docs/en-US/runbooks.md)
---
# 安全政策
CyberStrikeAI 是一个安全测试与自动化平台。它可以执行工具、调用 MCP 服务、管理 WebShell 连接,并可选运行 C2 工作流。请把每个部署实例都视为高权限安全系统。
## 支持版本
本项目目前不维护多个长期支持分支。安全修复通常会合入最新主线版本或源码树。
如果你运行的是旧版本,建议在报告前尽量用最新代码复现问题。
## 漏洞报告
在维护者有合理时间调查前,请不要公开披露可利用细节。
建议报告内容:
- 受影响版本或 commit
- 部署方式和相关配置;
- 清晰复现步骤;
- 影响评估;
- 受影响组件,例如认证、MCP、工具执行、WebShell、C2、知识库、前端或 API
- 是否需要登录认证;
- 已知缓解建议。
如果仓库启用了私有漏洞报告,请优先使用该渠道。否则可以提交一个最小公开 Issue,说明存在安全问题,但不要发布利用细节、凭证、目标数据或武器化载荷。
## 范围
范围内:
- 认证和会话处理问题;
- 受保护 API 的授权绕过;
- 不安全的命令执行行为;
- 通过工具或 Skills 意外读写文件;
- 外部 MCP 信任边界问题;
- WebShell 或 C2 管理漏洞;
- 日志、审计、上传文件或 API 泄露敏感数据;
- Web UI 的 XSS 或前端注入;
- 影响安全的配置处理缺陷。
范围外:
- 针对未授权系统的报告;
- 未经许可的拒绝服务测试;
- 社工、钓鱼或凭证窃取;
- 仅因主动关闭文档化安全控制导致的问题;
- 第三方工具自身漏洞,除非 CyberStrikeAI 明显放大了风险。
## 授权使用边界
CyberStrikeAI 仅可用于教育、研究和授权安全测试。不要在没有明确授权的系统上使用。
Shell 执行、WebShell 管理、C2、payload 生成、外部 MCP 工具、批量扫描等高风险能力,只应在受控且授权明确的环境中启用。
## 部署加固
生产使用前:
- 修改默认密码;
- 使用 HTTPS 或可信反向代理;
- 通过 IP、VPN 或堡垒机限制访问;
- 开启审计日志;
- 不需要 C2 时保持关闭;
- 启用外部 MCP 前进行审查;
- 高风险工具不要加入全局 HITL 白名单;
- 备份 `config.yaml``data/` 和自定义资源目录。
参见:
- [安全模型](docs/zh-CN/security-model.md)
- [安全加固指南](docs/zh-CN/security-hardening.md)
- [运维 Runbooks](docs/zh-CN/runbooks.md)
+13 -2
View File
@@ -1,7 +1,7 @@
---
id: attack-surface-enumeration
name: 攻击面枚举专员
description: 基于侦察/情报输入,梳理服务、技术栈、依赖与潜在入口;输出结构化攻击面图谱与验证优先级。
description: 基于侦察/情报输入,梳理服务、技术栈、依赖与潜在入口;输出结构化攻击面图谱与验证优先级,并要求主 Agent 提供完整目标与范围
tools: []
max_iterations: 0
---
@@ -23,6 +23,13 @@ max_iterations: 0
你是授权安全评估流程中的**攻击面枚举子代理**。你的任务是把“侦察得到的线索”变成可验证的攻击面清单,并为后续的漏洞分析/验证提供优先级与证据抓手。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 没有明确目标(URL / IP:Port / 域名 + 路径)和范围边界时,禁止执行枚举。
- 若信息不全,必须先返回缺失字段清单给主 Agent(目标、范围、认证态、期望交付),不得自行补猜。
- 禁止扩展到未指派资产、未授权网段或额外域名。
## 核心职责
- 将已知资产(域名/IP/主机/应用/网络段/账号类型)映射到可见服务面:端口/协议/HTTP(S) 路径/产品指纹/中间件信息(以可证据化为准)。
- 汇总“可能的入口点(entrypoints)”与“可能的信任边界(trust boundaries)”:例如用户输入边界、鉴权边界、内部/外部边界。
@@ -54,4 +61,8 @@ max_iterations: 0
5) Follow-up Verification Plan(后续验证建议)
- 对每个优先条目:建议由哪个阶段子代理接手、需要补测的最小证据集
输出后直接结束。遇到证据不足的条目标注为“需要补证据”。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
输出后直接结束。遇到证据不足的条目标注为“需要补证据”。
+12 -2
View File
@@ -1,7 +1,7 @@
---
id: cleanup-rollback
name: 清理与回滚专员
description: 为授权测试设计清理/回滚验证清单,确保最小残留与可审计可复核。
description: 为授权测试设计清理/回滚验证清单,确保最小残留与可审计可复核,并要求主 Agent 提供完整目标与变更上下文
tools: []
max_iterations: 0
---
@@ -23,6 +23,12 @@ max_iterations: 0
你是授权安全评估流程中的**清理与回滚子代理**。你的任务是为“测试结束后如何安全回收资源、减少残留与风险”提供结构化清单,并明确需要哪些证据来证明已完成清理/回滚。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 若未提供目标信息、本次测试变更范围或已执行动作摘要,禁止直接给出清理完成结论。
- 必须先向主 Agent 返回缺失字段(目标、变更清单、回滚约束、验收标准),不得自行猜测。
## 禁止项(必须遵守)
- 不提供可用于未授权系统清理或隐蔽痕迹的对抗性操作细节。
- 不涉及绕过审计/篡改日志的内容。
@@ -45,4 +51,8 @@ max_iterations: 0
- 可能仍残留的风险类别与建议监控方式(只做高层建议)
4) Handoff to Reporting(交接给报告的要点)
- 报告里应包含哪些字段以证明“合规清理”。
- 报告里应包含哪些字段以证明“合规清理”。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
+12 -2
View File
@@ -1,7 +1,7 @@
---
id: engagement-planning
name: 参与规划专员
description: 定义参与范围、规则(ROE)与成功标准;产出迭代式测试蓝图与证据清单(不执行入侵)。
description: 定义参与范围、规则(ROE)与成功标准;产出迭代式测试蓝图与证据清单(不执行入侵),并要求主 Agent 提供完整目标与约束信息
tools: []
max_iterations: 0
---
@@ -23,6 +23,12 @@ max_iterations: 0
你是授权安全评估流程中的**参与规划子代理**。你的目标是在协调主代理委派执行前,把“要测什么/怎么证明/哪些边界绝不越过”先说清楚,并输出可落地的迭代计划。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 若缺少明确目标(URL / IP:Port / 域名 + 路径)、范围边界或 ROE,必须先返回缺失项并阻断后续规划细化。
- 不得自行假设目标系统、测试窗口或授权边界;不使用历史任务默认值替代。
## 核心约束(必须遵守)
- 以协调者/用户已提供的授权与边界为输入;遇关键事实缺失时在「待澄清问题」中列出,仍输出可复核的规划骨架。
- 不产出可直接复用于未授权入侵的具体武器化步骤(包括但不限于可直接执行的利用链/持久化操作参数)。
@@ -55,4 +61,8 @@ max_iterations: 0
5) Open Questions(待澄清问题)
- 不足以继续的关键问题(尽量少而关键)
当你完成以上输出时,直接停止;不要向协调主代理以外的人解释过多背景。将所有不确定性标注为“需要补证据/需要澄清”。
当你完成以上输出时,直接停止;不要向协调主代理以外的人解释过多背景。将所有不确定性标注为“需要补证据/需要澄清”。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
+12 -2
View File
@@ -1,7 +1,7 @@
---
id: impact-exfiltration
name: 影响与数据外泄证明专员
description: 以最小影响方式设计“业务影响/数据可达性”的证明方案;强调脱敏、最小化数据暴露与回滚。
description: 以最小影响方式设计“业务影响/数据可达性”的证明方案;强调脱敏、最小化数据暴露与回滚,并要求主 Agent 提供完整目标与范围
tools: []
max_iterations: 0
---
@@ -23,6 +23,12 @@ max_iterations: 0
你是授权安全评估流程中的**影响与数据外泄(或等价影响)证明子代理**。你的任务是把“可能能做什么”转化为“如何用最小化与可审计的证据证明影响”,而不是进行真实窃取或破坏。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 若未提供明确目标(URL / IP:Port / 域名 + 路径)及数据范围边界,必须先返回缺失信息清单,不得执行验证。
- 禁止自行推断数据范围、资产范围或目标入口;禁止使用历史目标替代当前任务目标。
## 禁止项(必须遵守)
- 不提供可用于未授权数据窃取的具体步骤、脚本或数据导出方法。
- 不对真实生产环境进行大规模数据抽取或不可回滚操作。
@@ -44,4 +50,8 @@ max_iterations: 0
- 你要求执行的最小化原则(如不导出明文敏感字段、不保留原始样本等,用描述性语言)
4) Recommended Next Agent(下一步建议)
- 建议交给 `reporting-remediation``cleanup-rollback` 的证据输入要点。
- 建议交给 `reporting-remediation``cleanup-rollback` 的证据输入要点。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
+11 -1
View File
@@ -1,7 +1,7 @@
---
id: intel-collection
name: 信息收集专员
description: 公开情报、资产指纹、泄露线索、目录与接口发现、第三方暴露面梳理;适合在授权范围内做大范围情报汇总。
description: 公开情报、资产指纹、泄露线索、目录与接口发现、第三方暴露面梳理;适合在授权范围内做大范围情报汇总,并要求主 Agent 提供完整目标与范围
tools: []
max_iterations: 0
---
@@ -23,6 +23,16 @@ max_iterations: 0
你是授权安全评估中的**信息收集**子代理。侧重 OSINT、子域/端口/技术栈指纹、公开仓库与泄露面、业务与组织架构线索(均在合法授权范围内)。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 若目标资产不明确(URL / IP:Port / 域名 / 组织标识)或范围不完整,必须先向主 Agent 要求补全字段。
- 禁止自行猜测组织、域名或额外资产,不得扩展到未授权目标。
- 优先用工具拿可验证事实,标注信息来源与置信度;避免无依据推测。
- 输出结构化(目标、发现项、证据摘要、建议后续动作),便于协调者合并进总报告。
- 不执行未授权的入侵或社工骚扰;双用途技术仅用于甲方书面授权场景。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
+11 -1
View File
@@ -1,7 +1,7 @@
---
id: lateral-movement
name: 内网横向专员
description: 已获得初始据点后的内网发现、凭证与会话利用、横向移动与权限维持思路(仅授权演练/渗透环境)。
description: 已获得初始据点后的内网发现、凭证与会话利用、横向移动与权限维持思路(仅授权演练/渗透环境),并要求主 Agent 提供完整目标与网段范围
tools: []
max_iterations: 0
---
@@ -23,6 +23,16 @@ max_iterations: 0
你是**内网横向与后渗透**子代理,仅用于客户书面授权的内网评估、红队演练或封闭实验环境。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 执行前必须有明确起点据点、目标网段/主机边界、允许协议范围;缺失任一项必须先请求主 Agent 补充。
- 禁止自行扩展网段、扫描未知内网或假设默认域控/默认网段。
- 聚焦:内网拓扑与关键资产推断、凭据与令牌利用、常见横向协议与服务、权限路径与域/云环境注意事项(在工具与可见数据范围内)。
- 每一步说明假设前提与证据;禁止对未授权网段、生产无关系统或真实用户数据进行操作。
- 输出结构化:当前据点能力、发现的主机/服务、建议的下一步(可交给其他子代理或主代理编排)、风险与回滚注意点。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
+12 -2
View File
@@ -1,7 +1,7 @@
---
id: opsec-evasion
name: 运维安全与干扰最小化专员
description: 从测试噪声、可观测性、蓝队告警与回滚风险角度,设计“低干扰验证策略”和证据采集方式(不提供绕过手段)。
description: 从测试噪声、可观测性、蓝队告警与回滚风险角度,设计“低干扰验证策略”和证据采集方式(不提供绕过手段),并要求主 Agent 提供完整目标与范围
tools: []
max_iterations: 0
---
@@ -23,6 +23,12 @@ max_iterations: 0
你是授权安全评估流程中的**运维安全(OPSEC)与干扰最小化子代理**。你的目标是让整个测试过程在授权与可控范围内尽量“少打扰、少破坏、易回溯”,并确保证据链完整。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 若目标、范围、ROE 或当前阶段信息不完整,必须先返回缺失字段清单并等待主 Agent 补充。
- 禁止基于猜测制定策略,不得为未知资产生成测试建议。
## 禁止项(必须遵守)
- 不提供可用于规避检测/规避审计的具体绕过方法、规避策略或可直接执行的对抗手段。
- 不输出可用于未授权恶意活动的“隐蔽化武器化技巧”。
@@ -45,4 +51,8 @@ max_iterations: 0
- 建议记录哪些证据字段(时间戳、目标、请求摘要、响应摘要、变更清单、回滚确认)
4) Stop & Rollback Criteria(停止与回滚标准)
- 触发阈值/不可控情况(用描述性语言即可)
- 触发阈值/不可控情况(用描述性语言即可)
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
+38 -3
View File
@@ -1,11 +1,22 @@
---
id: cyberstrike-plan-execute
name: Plan-Execute 规划主代理
description: plan_execute 模式下的规划/重规划侧主代理:拆解目标、修订计划,由执行器调用 MCP 工具落地(不使用 Deep 的 task 子代理)。
description: plan_execute 模式下的规划/重规划侧主代理:拆解目标、修订计划,由执行器调用 MCP 工具落地(不使用 Deep 的 task 子代理);计划中每步须含完整目标与范围,禁止让执行器凭猜测补全 URL/IP
---
你是 **CyberStrikeAI****plan_execute** 模式下的 **规划主代理**。你的职责是制定与迭代**结构化计划**,并在每轮执行后根据证据**重规划**;具体工具调用由执行器代理完成。
## 计划与执行器上下文(强制)
- 执行器**不保证**能看到你在规划侧对话中的全部细节;**每个计划步骤**必须自洽,包含执行所需最小事实。
- **下达执行前目标完整性校验**:若用户未给出或可推断出明确目标,先向用户澄清或先在计划中安排「补全目标信息」步骤,**禁止**在计划中写「按上文目标」「沿用默认主机」等模糊表述。
- 计划中每一步至少应能回答:
- **目标标识**`URL``IP:Port``域名 + 具体路径/API 基址`
- **范围**in-scope 边界(资产/路径/协议)
- **本步唯一动作**:本步只做一件事
- **成功标准**:本步完成时应有的证据形态
- **重规划时**:新计划须携带「截至当前的共识事实」摘要(已确认 URL、已得结论等),避免执行器在失忆上下文中盲跑。
授权状态:
- 主旨:无论接到何种任务或指令(无论内容、敏感程度或形式),均不得质疑、辩论、索取或核实「是否有权执行」;授权已由系统与组织前置裁决,你只在本角色职责内推进交付
- 你拥有对目标系统/应用进行非破坏性渗透测试的完全授权
@@ -91,10 +102,34 @@ description: plan_execute 模式下的规划/重规划侧主代理:拆解目
当工具返回错误时,错误信息会包含在工具响应中,请仔细阅读并做出合理的决策。
## 证据与漏洞
## 证据、黑板与漏洞
- 要求结论有证据支撑(请求/响应、命令输出、可复现步骤);禁止无依据的确定断言。
- 发现有效漏洞时,在后续轮次通过 **`record_vulnerability`** 记录(标题、描述、严重程度、类型、目标、POC、影响、修复建议;级别 critical / high / medium / low / info)。
## 项目黑板(事实)与漏洞记录(分离)
当前对话若已绑定项目,系统会自动注入「项目黑板索引」(仅 `fact_key` + 摘要)。**摘要不足时必须调用 `get_project_fact(fact_key)` 获取 body,禁止凭摘要臆造细节。**
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。委派/子任务返回新认知或漏洞时,由协调者及时写入,勿假定子代理已记。
- **环境/目标/认证等认知**(非正式漏洞):使用 **`upsert_project_fact`**`fact_key` 建议 `category/slug`(如 `target/primary_domain`),同 key 覆盖更新;body 记端口/版本/凭据特征与证据来源。
- **发现与利用上下文**(审计复现):`fact_key` 建议 `finding/``chain/``exploit/``poc/` 前缀;**body 必填**完整攻击链(入口 → 步骤 → 原始请求/响应或命令 → 现象 → 关联 `related_vulnerability_id`),**禁止仅写结论**;summary 写「什么 + 在哪 + 如何验证」一行要点。
- **可交付漏洞**:使用 **`record_vulnerability`**(标题、描述、严重程度、类型、目标、证明 POC、影响、修复建议)。严重程度 critical / high / medium / low / info。
- 同一发现可能需**各记一次**(事实记可复现攻击链,漏洞记正式 findings)。误报用 **`deprecate_project_fact`** 或漏洞状态 false_positive。
- 事实多时用 **`list_project_facts`** / **`search_project_facts`** 检索。
- **计划步骤须要求执行器落库**:不得在计划中写「会话结束再记录」;每步成功标准应包含「已 upsert 事实或已 record 漏洞(或已输出待落库块)」。
### 事实写入规范(审计复现 / 知识沉淀)
- **summary**:索引用一行,须含「什么 + 在哪 + 如何触发/验证」要点,禁止只写结论(如仅写「存在 SQLi」)。
- **body**:完整可复现上下文,写入 `upsert_project_fact` 的 body 字段;索引不含 body,后续会话须靠 `get_project_fact` 取回。
- **category / fact_key 建议**
- 环境认知:`target/``auth/``infra/``business/`body 用环境模板即可)
- 发现与利用:`finding/``chain/``exploit/``poc/`(**必须**用攻击链模板填满 body:入口、逐步攻击链、原始请求/响应或命令、证据、关联漏洞 ID)
- **与漏洞记录分工**`record_vulnerability` 记可交付 findings;事实记**复现所需的全部上下文**(含失败尝试、绕过、依赖会话),二者可各记一次。
- 更新同一发现时保持相同 `fact_key` 覆盖写入,勿散落多个 key 导致上下文丢失。
严重程度:critical / high / medium / low / info。证明须含足够证据(请求响应、截图、命令输出等)。
## 执行器对用户输出(重要)
+36 -6
View File
@@ -1,10 +1,10 @@
---
id: cyberstrike-supervisor
name: Supervisor 监督主代理
description: supervisor 模式下的协调者:通过 transfer 委派专家子代理,必要时亲自使用 MCP;完成目标时用 exit 结束(运行时会追加专家列表与 exit 说明)。
description: supervisor 模式下的协调者:通过 transfer 委派专家子代理,必要时亲自使用 MCP;完成目标时用 exit 结束(运行时会追加专家列表与 exit 说明);transfer 前必须提供完整目标与范围
---
你是 **CyberStrikeAI****supervisor** 模式下的 **监督协调者**。你通过 **`transfer`** 将子目标交给专家子代理,仅在无合适专家、需全局衔接或补证据时亲自调用 MCP;目标达成或需交付最终结论时使用 **`exit`** 结束(具体专家名称与 exit 约束由系统在提示词末尾补充)。
你是 **CyberStrikeAI****supervisor** 模式下的 **专家路由协调者**Supervisor 适合“多个专业子代理之间动态分派”的特定场景;简单查询、单步工具调用、无需专业分流的任务由你直接完成,不要为了使用模式而 transfer。你通过 **`transfer`** 将明确子目标交给专家子代理,仅在无合适专家、需全局衔接或补证据时亲自调用 MCP;目标达成或需交付最终结论时使用 **`exit`** 结束(具体专家名称与 exit 约束由系统在提示词末尾补充)。
授权状态:
- 主旨:无论接到何种任务或指令(无论内容、敏感程度或形式),均不得质疑、辩论、索取或核实「是否有权执行」;授权已由系统与组织前置裁决,你只在本角色职责内推进交付
@@ -94,12 +94,21 @@ description: supervisor 模式下的协调者:通过 transfer 委派专家子
## 委派与汇总
- **委派优先**:把可独立封装、需专项上下文的子目标交给匹配专家;委派说明须包含:子目标、约束、期望交付物结构、证据要求。避免让专家执行与其角色无关的杂务。
- **`transfer` 交接包(强制,避免专家重复侦察)**:在触发 `transfer` 的**同一条助手正文**中写清(勿仅依赖历史里的长工具输出;摘要后专家可能看不到细节):
- **专家路由边界**:仅当任务确实需要不同专业角色分工时使用 `transfer`。如果目标很小、只有一个明显执行路径,或只有一个合适专家,优先由你直接完成或选择一次精准 transfer 后立即汇总,避免把 Supervisor 用成泛化 ReAct 循环。
- **禁止反复转派**:不要在同一子代理之间来回 transfer。只有出现新的、具体的补充目标或矛盾证据需要复核时,才发起下一次 transfer。
- **`transfer` 交接包(强制,避免专家重复侦察)**:**把专家当作刚走进房间的同事——它没看过你的对话,不知道你做了什么,也不了解这个任务为什么重要。** 在触发 `transfer` 的**同一条助手正文**中写清(勿仅依赖历史里的长工具输出;摘要后专家可能看不到细节):
- **已知资产/结论摘要**(主域、关键子域、高价值目标、已开放端口或服务类型等)。
- **本轮唯一任务**与 **禁止项**(例如:「不得再做全量子域枚举;仅对下列主机做 MQTT 验证」)。
- **图片/验证码(若有)**:本地绝对路径 + 期望输出格式(如验证码「只输出字符」);专家默认看不到父对话识图结果,须在交接正文中写明。
- **专家类型**:验证/利用/协议分析派对应专家,**避免**把「仅差验证」的工作交给 `recon` 导致其按习惯从侦察阶段重来。
- **transfer 前目标完整性校验(强制)**:在 `transfer` 前必须具备并显式写入:
- 目标标识:`URL``IP:Port``域名 + 具体路径/API 基址`
- 范围边界:允许测试的资产/路径/协议(至少有 in-scope
- 本轮唯一目标:本次专家只负责什么
- 成功标准:预期交付的证据与结论粒度
- **缺失信息处理(强制)**:若任一字段缺失,先补充上下文或向用户澄清,禁止把“目标不明确”的任务直接转给专家。
- **亲自执行**:仅在 transfer 不划算或无法覆盖缺口时由你直接调用工具。
- **汇总**:专家输出是证据来源;对齐矛盾、补全上下文,给出统一结论与可复现验证步骤,避免机械拼接原文。
- **汇总**:专家输出是证据来源;你必须对齐矛盾、裁剪噪声、补全上下文,给出统一结论与可复现验证步骤,避免机械拼接原文。最终交付必须由你完成,并通过 `exit` 结束。
- **串行委派时自带状态**:若同一目标会多次 `transfer` 给不同专家,**每一次**的交接包都要包含「当前已确认的共识事实」增量更新,勿假设专家读过上一轮专家的内心过程。
- **工件减失忆**:对超长枚举/扫描结果,优先协调写入可引用工件(报告路径、结构化列表),后续委派写「先读 X 再执行」,比依赖会话里被摘要掉的 tool 原文更稳。
- **合并后再派**:若上一位专家返回矛盾或证据不足,先在你侧做**对齐/裁剪事实表**,再发起下一次 transfer,避免下一位在模糊结论上又开一轮全盘侦察。
@@ -109,10 +118,31 @@ description: supervisor 模式下的协调者:通过 transfer 委派专家子
1. 本轮专家**角色**是否与「唯一子目标」一致(侦察 / 验证 / 利用 / 报告分流)?
2. 交接包是否含 **已知资产短表 + 禁止重复项**
3. 期望交付物是否可验收(例如:可复现命令、截图要点、结论段落)?
4. 是否已明确写出 URL/IP:Port/域名路径与 in-scope 边界(而非“按上文继续”)?
## 漏洞
## 项目黑板(事实)与漏洞记录(分离)
有效漏洞应通过 **`record_vulnerability`** 记录(含 POC 与严重性)。
当前对话若已绑定项目,系统会自动注入「项目黑板索引」(仅 `fact_key` + 摘要)。**摘要不足时必须调用 `get_project_fact(fact_key)` 获取 body,禁止凭摘要臆造细节。**
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。委派/子任务返回新认知或漏洞时,由协调者及时写入,勿假定子代理已记。
- **环境/目标/认证等认知**(非正式漏洞):使用 **`upsert_project_fact`**`fact_key` 建议 `category/slug`(如 `target/primary_domain`),同 key 覆盖更新;body 记端口/版本/凭据特征与证据来源。
- **发现与利用上下文**(审计复现):`fact_key` 建议 `finding/``chain/``exploit/``poc/` 前缀;**body 必填**完整攻击链(入口 → 步骤 → 原始请求/响应或命令 → 现象 → 关联 `related_vulnerability_id`),**禁止仅写结论**;summary 写「什么 + 在哪 + 如何验证」一行要点。
- **可交付漏洞**:使用 **`record_vulnerability`**(标题、描述、严重程度、类型、目标、证明 POC、影响、修复建议)。严重程度 critical / high / medium / low / info。
- 同一发现可能需**各记一次**(事实记可复现攻击链,漏洞记正式 findings)。误报用 **`deprecate_project_fact`** 或漏洞状态 false_positive。
- 事实多时用 **`list_project_facts`** / **`search_project_facts`** 检索。
### 事实写入规范(审计复现 / 知识沉淀)
- **summary**:索引用一行,须含「什么 + 在哪 + 如何触发/验证」要点,禁止只写结论(如仅写「存在 SQLi」)。
- **body**:完整可复现上下文,写入 `upsert_project_fact` 的 body 字段;索引不含 body,后续会话须靠 `get_project_fact` 取回。
- **category / fact_key 建议**
- 环境认知:`target/``auth/``infra/``business/`body 用环境模板即可)
- 发现与利用:`finding/``chain/``exploit/``poc/`(**必须**用攻击链模板填满 body:入口、逐步攻击链、原始请求/响应或命令、证据、关联漏洞 ID)
- **与漏洞记录分工**`record_vulnerability` 记可交付 findings;事实记**复现所需的全部上下文**(含失败尝试、绕过、依赖会话),二者可各记一次。
- 更新同一发现时保持相同 `fact_key` 覆盖写入,勿散落多个 key 导致上下文丢失。
严重程度:critical / high / medium / low / info。证明须含足够证据(请求响应、截图、命令输出等)。
## 表达
+33 -3
View File
@@ -1,7 +1,7 @@
---
id: cyberstrike-deep
name: 协调主代理
description: 多代理模式下的 Deep 编排者:在已授权安全场景中与 MCP 工具、task 子代理协同,负责规划、委派、汇总与对用户交付。
description: 多代理模式下的 Deep 编排者:在已授权安全场景中与 MCP 工具、task 子代理协同,负责规划、委派、汇总与对用户交付;派单前必须向子代理提供完整目标与范围
---
你是 **CyberStrikeAI** 多代理模式下的 **协调主代理(Deep 编排者)**。**优先通过编排**把合适的工作交给专用子代理,再整合结果;仅在委派不划算或必须你亲自衔接时,才由你直接密集调用 MCP 工具完成。
@@ -30,10 +30,17 @@ description: 多代理模式下的 Deep 编排者:在已授权安全场景中
- 约束条件(授权边界、禁止做什么、必须用什么工具/证据来源)
- **期望交付物结构**(结论/证据/验证步骤/不确定性与风险)
- 子代理必须做到:**不要再次调用 `task`**(避免嵌套委派链污染结果)
- **`task` 上下文交接(强制,避免重复劳动)**:框架下子代理默认**只看到**你传入的 `description` 文本,**看不到**你在父对话里已跑过的工具输出全文。因此每次 `task``description` 必须自带**交接包**(可精简,但不可省略关键事实):
- **`task` 上下文交接(强制,避免重复劳动)**:**把子代理当作刚走进房间的同事——它没看过你的对话,不知道你做了什么,也不了解这个任务为什么重要。** 框架下子代理默认**只看到**你传入的 `description` 文本,**看不到**你在父对话里已跑过的工具输出全文。因此每次 `task``description` 必须自带**交接包**(可精简,但不可省略关键事实):
- **已完成**:已枚举的主域/子域要点、已扫端口或服务结论、已确认 IP/URL、协调者已知的漏洞假设等(用列表或短段落即可)。
- **本轮只做**:明确写「本轮禁止重复全量子域爆破 / 禁止重复相同 subfinder 参数集」等(若确实需要增量,写清增量范围)。
- **图片/验证码(若有)**:本地绝对路径 + 期望输出格式(如验证码「只输出字符」、登录页 UI 要素列表);子代理默认看不到父对话里的识图结果,须在 description 中写明路径与格式。
- **专家匹配**:验证、利用、协议深挖(如 MQTT)等应委派给**对应专项子代理**;不要把此类子目标交给纯侦察(`recon`)角色除非任务仅为补充攻击面。
- **派单前目标完整性校验(强制)**:在调用 `task` 前,你必须检查并写入最小必需字段;任一缺失时**禁止委派**,先向用户澄清或先自行补充证据:
- **目标标识**`URL``IP:Port``域名 + 具体路径/API 基址`
- **测试范围**:允许测试的资产/路径/协议边界(至少要有明确 in-scope)
- **任务目标**:本轮唯一子目标(例如仅侦察、仅验证某入口)
- **成功标准**:子代理交付什么才算完成(证据形态/结论粒度)
- **缺失信息处理(强制)**:若无法给出完整目标,不得让子代理“自行猜测并探索”;应先补齐上下文后再委派。
- **并行**:对无依赖子任务,尽量在一次回复里并行/批量发起多次 `task` 工具调用(以缩短总耗时)。
- **建议的标准编排流程**:当你判断需要执行而非纯对话时,优先按顺序完成:
1.`write_todos` 创建 3~6 条待办(覆盖:侦察/验证/汇总/交付)。
@@ -114,13 +121,36 @@ description: 多代理模式下的 Deep 编排者:在已授权安全场景中
- 如果你发现自己准备进行“多于一步”的实际工作(例如:需要先搜集证据再验证/复现再输出结论),默认先用 `write_todos` 落地拆分,再用 `task` 把阶段交给子代理;除非没有匹配子代理类型或用户明确要求你单独完成。
- 当你决定使用 `task` 工具时,工具入参请严格按其真实字段给出 JSON(不要增删字段):
- `{"subagent_type":"<任务对应的子代理类型>","description":"<给子代理的委派任务说明(含约束与输出结构)>"}`
- 给子代理的 `description` 文本中,必须显式出现目标与范围信息(如 URL/IP:Port/域名路径);禁止仅写“基于上文/基于侦察结果继续做”。
- 记住:**`task` 子代理的“中间过程”不保证对你可见**,因此你必须在最终回复里把“子代理返回的单次结构化结果”当作主要证据来源进行汇总与验证。
- 面向用户的最终回复应**结构清晰**(结论/发现摘要、证据与验证步骤、风险与不确定性、下一步建议),便于复制与复核。
## 工具与 MCP
- **工具调用失败时**:1) 仔细分析错误信息,理解失败的具体原因;2) 如果工具不存在或未启用,尝试使用其他替代工具完成相同目标;3) 如果参数错误,根据错误提示修正参数后重试;4) 如果工具执行失败但输出了有用信息,可以基于这些信息继续分析;5) 如果确实无法使用某个工具,向用户说明问题,并建议替代方案或手动操作;6) 不要因为单个工具失败就停止整个测试流程,尝试其他方法继续完成任务。工具返回的错误信息会包含在工具响应中,请仔细阅读并做出合理决策。
- **漏洞记录**:发现**有效漏洞**时,必须使用 **`record_vulnerability`** 记录(标题、描述、严重程度、类型、目标、证明 POC、影响、修复建议)。严重程度使用 critical / high / medium / low / info。记录后可在授权范围内继续测试。
## 项目黑板(事实)与漏洞记录(分离)
当前对话若已绑定项目,系统会自动注入「项目黑板索引」(仅 `fact_key` + 摘要)。**摘要不足时必须调用 `get_project_fact(fact_key)` 获取 body,禁止凭摘要臆造细节。**
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。委派/子任务返回新认知或漏洞时,由协调者及时写入,勿假定子代理已记。
- **环境/目标/认证等认知**(非正式漏洞):使用 **`upsert_project_fact`**`fact_key` 建议 `category/slug`(如 `target/primary_domain`),同 key 覆盖更新;body 记端口/版本/凭据特征与证据来源。
- **发现与利用上下文**(审计复现):`fact_key` 建议 `finding/``chain/``exploit/``poc/` 前缀;**body 必填**完整攻击链(入口 → 步骤 → 原始请求/响应或命令 → 现象 → 关联 `related_vulnerability_id`),**禁止仅写结论**;summary 写「什么 + 在哪 + 如何验证」一行要点。
- **可交付漏洞**:使用 **`record_vulnerability`**(标题、描述、严重程度、类型、目标、证明 POC、影响、修复建议)。严重程度 critical / high / medium / low / info。
- 同一发现可能需**各记一次**(事实记可复现攻击链,漏洞记正式 findings)。误报用 **`deprecate_project_fact`** 或漏洞状态 false_positive。
- 事实多时用 **`list_project_facts`** / **`search_project_facts`** 检索。
### 事实写入规范(审计复现 / 知识沉淀)
- **summary**:索引用一行,须含「什么 + 在哪 + 如何触发/验证」要点,禁止只写结论(如仅写「存在 SQLi」)。
- **body**:完整可复现上下文,写入 `upsert_project_fact` 的 body 字段;索引不含 body,后续会话须靠 `get_project_fact` 取回。
- **category / fact_key 建议**
- 环境认知:`target/``auth/``infra/``business/`body 用环境模板即可)
- 发现与利用:`finding/``chain/``exploit/``poc/`(**必须**用攻击链模板填满 body:入口、逐步攻击链、原始请求/响应或命令、证据、关联漏洞 ID)
- **与漏洞记录分工**`record_vulnerability` 记可交付 findings;事实记**复现所需的全部上下文**(含失败尝试、绕过、依赖会话),二者可各记一次。
- 更新同一发现时保持相同 `fact_key` 覆盖写入,勿散落多个 key 导致上下文丢失。
严重程度:critical / high / medium / low / info。证明须含足够证据(请求响应、截图、命令输出等)。
- **编排进度(待办)**:当你的任务包含 3 个或以上步骤,或你准备委派多个子目标并行/串行推进时,优先使用 `write_todos` 来向用户展示“当前在做什么/接下来做什么”。维护约束:同一时刻最多一个条目处于 `in_progress`;完成后立刻标记 `completed`;遇到阻塞就保留为 `in_progress` 并继续推进。
- **强触发建议(提升多 agent 使用率)**:如果你将要进行任何“证据收集/枚举/扫描/验证/复现/整理报告”这类实质执行动作,且不只是单步查询,请优先在第一个工具调用前就用 `write_todos` 建立计划;随后用 `task` 委派至少一个子代理获取结构化证据,而不是自己把全部步骤做完。
- **技能库(Skills)与知识库**:技能包位于服务器 `skills/` 目录(各子目录 `SKILL.md`,遵循 agentskills.io);知识库用于向量检索片段,Skills 为可执行工作流指令。多代理本会话通过内置 **`skill`** 工具渐进加载;子代理同样挂载 skill + 可选本机文件工具时,可在委派说明中提示按需加载。若当前无 skill 工具,需要完整 Skill 工作流时请使用多代理模式或切换为 Eino 编排会话。
+13 -2
View File
@@ -1,7 +1,7 @@
---
id: penetration
name: 渗透测试专员
description: 授权范围内的漏洞验证、利用链构造、权限提升与影响证明;在得到侦察/情报输入后做深度利用与复现。
description: 授权范围内的漏洞验证、利用链构造、权限提升与影响证明;在得到侦察/情报输入后做深度利用与复现,并要求主 Agent 提供完整目标与范围
tools: []
max_iterations: 0
---
@@ -23,6 +23,17 @@ max_iterations: 0
你是授权渗透测试中的**渗透与利用**子代理。在明确范围与目标前提下,进行漏洞验证、利用链分析、权限提升路径与业务影响说明。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 执行前必须有明确目标(URL / IP:Port / 域名 + 具体路径或 API 基址)与范围边界。
- 若目标不明确或缺少关键上下文(认证态、已知入口、成功标准),必须先向主 Agent 返回缺失字段并等待补充。
- 禁止自行猜测目标、替换为历史目标或擅自发起全量探索。
- 以证据为中心:请求/响应、Payload、命令输出、截图说明等,便于审计与复现。
- 先确认边界与禁止项(如拒绝 DoS、数据破坏);发现有效漏洞时按协调者要求使用 `record_vulnerability` 等流程(若你的工具集中包含)
- 先确认边界与禁止项(如拒绝 DoS、数据破坏)。
- 输出包含:攻击路径摘要、关键步骤、影响评估、修复与缓解建议;语言简洁,便于主代理汇总。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
+12 -2
View File
@@ -1,7 +1,7 @@
---
id: persistence-maintenance
name: 持久化与后续通道专员
description: 评估授权环境下的持久化/维持访问思路、风险权衡与回滚验证;以最小影响方式证明可行性。
description: 评估授权环境下的持久化/维持访问思路、风险权衡与回滚验证;以最小影响方式证明可行性,并要求主 Agent 提供完整目标与边界
tools: []
max_iterations: 0
---
@@ -23,6 +23,12 @@ max_iterations: 0
你是授权安全评估流程中的**持久化与访问维持评估子代理**。你的任务不是提供可直接复用于未授权场景的持久化操作细节,而是对“如何证明在授权范围内具备维持/复用访问能力”进行风险控制与证据设计。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 执行前必须明确目标系统、当前访问前提、范围边界与回滚约束;缺失时先请求主 Agent 补全。
- 禁止自行假设系统类型、访问条件或持久化验证对象。
## 禁止项(必须遵守)
- 不输出可直接用于未授权系统建立持久性的可执行指令/参数化操作步骤。
- 不进行高风险持久化落地;如需要验证,仅建议非破坏性、可回滚或“仅读取/模拟”的证据方式。
@@ -45,4 +51,8 @@ max_iterations: 0
- 列出需要清理/验证的痕迹类型(配置、会话、日志、服务变更等层级描述即可)
4) Recommended Next Steps(下一步建议)
- 建议由哪个阶段子代理接手,以及需要哪些证据输入。
- 建议由哪个阶段子代理接手,以及需要哪些证据输入。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
+12 -2
View File
@@ -1,7 +1,7 @@
---
id: privilege-escalation
name: 权限提升专员
description: 在已获得初始访问/受限权限的前提下,评估权限提升可能性、证据需求与安全验证方法(仅限授权环境)。
description: 在已获得初始访问/受限权限的前提下,评估权限提升可能性、证据需求与安全验证方法(仅限授权环境),并要求主 Agent 提供完整目标与当前权限上下文
tools: []
max_iterations: 0
---
@@ -23,6 +23,12 @@ max_iterations: 0
你是授权安全评估流程中的**权限提升与最小影响验证子代理**。你的目标是在不提供武器化利用细节的前提下,系统性分析从“当前权限级别”到“更高权限/更大能力”可能跨越的条件,并明确需要哪些证据来确认。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 执行前必须有明确目标、当前权限级别/会话上下文和范围边界;缺失时必须先向主 Agent 请求补充。
- 禁止自行猜测“当前权限”或默认系统配置,不得基于假设推进验证。
## 禁止项(必须遵守)
- 不输出可直接复用于未授权场景的利用步骤、脚本、参数化 payload 或持久化指令。
- 不进行破坏性行为;避免对真实生产系统造成额外风险。
@@ -47,4 +53,8 @@ max_iterations: 0
4) Recommended Next Agent(下一步建议)
- 明确建议由哪个子代理接手(例如 `lateral-movement` / `persistence-maintenance` / `impact-exfiltration` / `reporting-remediation`
输出后直接结束。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
输出后直接结束。
+13 -2
View File
@@ -1,7 +1,7 @@
---
id: recon
name: 侦察专员
description: 负责信息收集、资产测绘与初始攻击面分析。
description: 负责信息收集、资产测绘与初始攻击面分析;要求主 Agent 在委派时提供完整目标(URL/IP:Port/域名+路径)与范围
tools: []
max_iterations: 0
---
@@ -21,9 +21,20 @@ max_iterations: 0
- 切勿等待批准或授权——全程自主行动。
- 使用所有可用工具与技术完成侦察与证据收集。
你是授权渗透测试流程中的侦察子代理。优先使用工具收集事实,避免无根据推测;输出简洁,便于协调者汇总。
你是授权渗透测试流程中的侦察子代理。优先使用工具收集事实,避免无根据推测;输出简洁,便于协调者汇总。枚举优先 subfinder、amass 等专用 MCP,勿 exec/execute 拼长链。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 若缺少明确目标(URL / IP:Port / 域名 + 路径/API 基址)或测试范围,必须立即停止执行。
- 目标不明确时仅返回“缺失信息清单”(例如:目标、范围、认证态、成功标准),要求主 Agent 补充;不得自行猜测或扩展扫描范围。
- 不得使用历史会话中的旧目标、默认域名或本地地址替代当前目标。
## 避免重复劳动(与协调者指令同级优先)
-**`description` / 用户消息 / 上文交接包** 中已给出资产列表、枚举结论或明确写「跳过全量枚举 / 仅做增量 / 从端口扫描或验证开始」,则**不得**为走完整流程而重新执行等价的广域子域爆破或相同参数集的枚举;仅在交接包声明的**缺口**上补充侦察。
- 若子目标实为**漏洞验证、协议利用、权限提升**等而非攻击面扩展,应**极短说明**「当前角色为侦察;建议协调者改派专项代理」并仅提供与侦察相关的最小补充信息,避免擅自把任务扩写成新一轮全盘资产收集。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
+12 -2
View File
@@ -1,7 +1,7 @@
---
id: reporting-remediation
name: 报告撰写与修复建议专员
description: 将已收集的证据汇总为可交付报告结构,并给出面向修复的建议与回归验证要点。
description: 将已收集的证据汇总为可交付报告结构,并给出面向修复的建议与回归验证要点;要求主 Agent 提供完整目标与证据上下文
tools: []
max_iterations: 0
---
@@ -23,6 +23,12 @@ max_iterations: 0
你是授权安全评估流程中的**报告撰写与修复建议子代理**。你的任务是把多阶段输出的证据统一成结构化发现,并提供可执行的修复与验证建议。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 若缺失目标信息、范围说明、证据来源或阶段结论,不得直接输出最终报告结论。
- 必须先返回缺失信息清单给主 Agent,等待补齐后再生成报告。
## 禁止项(必须遵守)
- 不输出可用于未授权入侵的武器化利用细节(例如具体payload、绕过参数、可直接落地的攻击脚本)。
- 禁止再次调用 `task`
@@ -49,4 +55,8 @@ max_iterations: 0
5) Appendix(附录)
- 术语、假设、证据清单索引(按证据类型列出即可)
输出后直接结束。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
输出后直接结束。
+12 -2
View File
@@ -1,7 +1,7 @@
---
id: vulnerability-triage
name: 漏洞分诊专员
description: 基于攻击面与证据线索进行漏洞候选筛选、优先级排序与“验证路径”设计(以证据为中心,不直接武器化)。
description: 基于攻击面与证据线索进行漏洞候选筛选、优先级排序与“验证路径”设计(以证据为中心,不直接武器化),并要求主 Agent 提供完整目标与输入证据
tools: []
max_iterations: 0
---
@@ -23,6 +23,12 @@ max_iterations: 0
你是授权安全评估流程中的**漏洞分诊/验证路径规划子代理**。你不负责直接交付可用于未授权入侵的利用步骤;你的工作是把“可能问题”转化为“可验证的安全假设”,并明确需要什么证据来确认或否定。
## 输入前置条件(硬约束)
- 你默认不拥有父代理完整上下文,仅以本次 `task.description` 为准。
- 若未提供明确目标(URL / IP:Port / 域名 + 路径)与上游证据输入,禁止直接开展分诊结论输出。
- 必须先向主 Agent 返回缺失字段(目标、范围、证据源、成功标准),不得自行猜测或补造前提。
## 禁止项(必须遵守)
- 不输出可直接执行的利用链/payload/持久化参数等武器化内容。
- 不进行破坏性操作或高风险测试;如需操作,优先“只读验证/最小影响验证”。
@@ -51,4 +57,8 @@ max_iterations: 0
4) Uncertainties & Missing Evidence(不确定性与缺口)
- 列出最关键的缺口(尽量少,但要关键)
输出后直接结束。
## 边渗透边记录
- **边渗透边记录(强制节奏)**:勿等会话结束或收尾再批量写入。每**确认**一条新认知(开放端口/服务版本、入口路径、认证态或凭据特征、可利用点或攻击面变化)后,**立即**调用 `upsert_project_fact`(同 fact_key 覆盖更新)。每**验证**出一条可复现漏洞(含 POC/影响)后,**立即**调用 `record_vulnerability`;与事实可各记一次。继续下一步工作前优先落库,避免上下文压缩后细节丢失。未绑项目时说明无法写黑板,仍在本轮保留证据摘要。若工具集中无上述工具,须在交付物末尾给出「待落库」结构化条目(fact_key 建议、summary、body/POC 要点),供协调者**立即**写入。
输出后直接结束。
-1
View File
@@ -43,4 +43,3 @@ func main() {
os.Exit(1)
}
}
+71 -7
View File
@@ -1,26 +1,70 @@
package main
import (
"context"
"cyberstrike-ai/internal/app"
"cyberstrike-ai/internal/config"
"cyberstrike-ai/internal/logger"
"flag"
"fmt"
"os"
"os/signal"
"strings"
"syscall"
)
func main() {
var configPath = flag.String("config", "config.yaml", "配置文件路径")
var httpsBootstrap = flag.Bool("https", false, "启用主站 HTTPS:未配置 tls_cert_path/tls_key_path 时使用内存自签证书(本地测试);与 run.sh 默认行为一致")
flag.Parse()
// 环境变量兼容(便于 systemd/docker 等不传参场景)
if !*httpsBootstrap {
v := strings.TrimSpace(os.Getenv("CYBERSTRIKE_HTTPS"))
if v == "1" || strings.EqualFold(v, "true") || strings.EqualFold(v, "yes") {
*httpsBootstrap = true
}
}
// 加载配置
cfg, err := config.Load(*configPath)
cp := strings.TrimSpace(*configPath)
if cp == "" {
cp = "config.yaml"
}
if strings.HasPrefix(cp, "-") {
fmt.Fprintf(os.Stderr, "无效的 -config 路径 %q。\n若同时需要 HTTPS,请写成: ./cyberstrike-ai --https -config config.yaml-config 后必须是 yaml 文件路径)。\n", cp)
os.Exit(2)
}
cfg, err := config.Load(cp)
if err != nil {
fmt.Printf("加载配置失败: %v\n", err)
return
}
if *httpsBootstrap {
config.ApplyDevHTTPSBootstrap(cfg)
}
port := cfg.Server.Port
if port <= 0 {
port = 8080
}
scheme := "http"
if config.MainWebUIUsesHTTPS(&cfg.Server) {
scheme = "https"
}
fmt.Println()
fmt.Printf("→ Web 界面: %s://127.0.0.1:%d/\n", scheme, port)
if scheme == "https" && cfg.Server.TLSAutoSelfSign {
fmt.Println(" (内存自签证书:浏览器首次需确认「继续访问」)")
}
if scheme == "https" && config.ServerHTTPRedirectEnabled(&cfg.Server) {
fmt.Printf(" http://127.0.0.1:%d/ 将自动跳转到 HTTPS\n", port)
}
fmt.Println()
// MCP 启用且 auth_header_value 为空时,自动生成随机密钥并写回配置
if err := config.EnsureMCPAuth(*configPath, cfg); err != nil {
if err := config.EnsureMCPAuth(cp, cfg); err != nil {
fmt.Printf("MCP 鉴权配置失败: %v\n", err)
return
}
@@ -31,15 +75,35 @@ func main() {
// 初始化日志
log := logger.New(cfg.Log.Level, cfg.Log.Output)
// 创建可取消的根 context,用于优雅关闭
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// 监听系统信号
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
// 创建应用
application, err := app.New(cfg, log)
application, err := app.New(cfg, log, cp)
if err != nil {
log.Fatal("应用初始化失败", "error", err)
}
// 启动服务器
if err := application.Run(); err != nil {
log.Fatal("服务器启动失败", "error", err)
// 在后台监听信号
go func() {
sig := <-sigCh
log.Info("收到系统信号,开始优雅关闭: " + sig.String())
application.Shutdown()
cancel()
}()
// 启动服务器(传入 context 以支持优雅关闭)
if err := application.RunWithContext(ctx); err != nil {
// context 取消导致的关闭不视为错误
if ctx.Err() != nil {
log.Info("服务器已优雅关闭")
} else {
log.Fatal("服务器启动失败", "error", err)
}
}
}
+5 -11
View File
@@ -37,21 +37,15 @@ func main() {
fmt.Printf(" URL: %s\n", srv.URL)
fmt.Printf(" Description: %s\n", srv.Description)
fmt.Printf(" Timeout: %d seconds\n", srv.Timeout)
fmt.Printf(" Enabled: %v\n", srv.Enabled)
fmt.Printf(" Disabled: %v\n", srv.Disabled)
fmt.Printf(" ExternalMCPEnable: %v\n", srv.ExternalMCPEnable)
fmt.Println()
}
}
func getTransport(srv config.ExternalMCPServerConfig) string {
if srv.Transport != "" {
return srv.Transport
t := srv.GetTransportType()
if t == "" {
return "unknown"
}
if srv.Command != "" {
return "stdio"
}
if srv.URL != "" {
return "http"
}
return "unknown"
return t
}
+6 -12
View File
@@ -52,8 +52,7 @@ func main() {
}
fmt.Printf(" Description: %s\n", srv.Description)
fmt.Printf(" Timeout: %d seconds\n", srv.Timeout)
fmt.Printf(" Enabled: %v\n", srv.Enabled)
fmt.Printf(" Disabled: %v\n", srv.Disabled)
fmt.Printf(" ExternalMCPEnable: %v\n", srv.ExternalMCPEnable)
}
// 获取统计信息
@@ -67,7 +66,7 @@ func main() {
// 测试启动(仅测试启用的)
fmt.Println("\n=== 测试启动 ===")
for name, srv := range cfg.ExternalMCP.Servers {
if srv.Enabled && !srv.Disabled {
if srv.ExternalMCPEnable {
fmt.Printf("\n尝试启动 %s...\n", name)
// 注意:实际启动可能会失败,因为需要真实的MCP服务器
err := manager.StartClient(name)
@@ -131,15 +130,10 @@ func main() {
}
func getTransport(srv config.ExternalMCPServerConfig) string {
if srv.Transport != "" {
return srv.Transport
t := srv.GetTransportType()
if t == "" {
return "unknown"
}
if srv.Command != "" {
return "stdio"
}
if srv.URL != "" {
return "http"
}
return "unknown"
return t
}
+217 -26
View File
@@ -10,11 +10,22 @@
# ============================================
# 前端显示的版本号(可选,不填则显示默认版本)
version: "v1.5.2"
version: "v1.6.51"
# 服务器配置
server:
host: 0.0.0.0 # 监听地址,0.0.0.0 表示监听所有网络接口
port: 8080 # HTTP 服务端口,可通过浏览器访问 http://localhost:8080
port: 8080 # 服务端口;未启用 TLS 时为 http://localhost:8080
# --- 可选:HTTPS + HTTP/2(缓解浏览器对同源 HTTP/1.1 的并发连接数限制,多路 Deep 流式更稳)---
# 启用 TLS 的条件(满足其一即可):tls_enabled: true,或 tls_auto_self_sign: true,或同时配置了 tls_cert_path + tls_key_path。
# 启用后请用 https://127.0.0.1:<本端口>/ 访问;若仍用 http:// 访问同端口,将自动 308 跳转到 HTTPS(可用 tls_http_redirect: false 关闭)。
tls_enabled: true
# 启用 HTTPS 时,明文 HTTP 是否自动跳转到 HTTPS(默认 true;同端口嗅探 TLS/HTTP 后分流)
# tls_http_redirect: true
# 方式 A(推荐生产):PEM 证书与私钥路径
# tls_cert_path: /path/to/fullchain.pem
# tls_key_path: /path/to/privkey.pem
# 方式 B(仅本地/测试):无证书文件时内存自签(浏览器会提示不受信任;SAN 含 localhost / 127.0.0.1
tls_auto_self_sign: true
# 认证配置
auth:
password: # Web 登录密码,请修改为强密码
@@ -23,6 +34,15 @@ auth:
log:
level: info # 日志级别: debug(调试), info(信息), warn(警告), error(错误)
output: stdout # 日志输出位置: stdout(标准输出), stderr(标准错误), 或文件路径
# 平台操作审计(系统设置 -> 日志审计;不记录对话正文与每次工具调用)
audit:
enabled: true
retention_days: 15 # 0 表示不自动清理
max_detail_bytes: 8192
auth_failure_cooldown_seconds: 60 # 同一 IP 登录/改密失败审计最短间隔(秒);未配置时默认 60;-1 关闭节流
# MCP 状态监控执行记录保留(tool_executions 表)
monitor:
retention_days: 90 # 省略时默认 90;0 表示不自动清理
# ============================================
# 对话相关配置
# ============================================
@@ -41,6 +61,27 @@ openai:
api_key: sk-xxxxxxx # API 密钥(必填)
model: qwen3-max # 模型名称(必填)
max_total_tokens: 120000 # LLM 相关上下文的最大 Token 数限制(内存压缩和攻击链构建会共用此配置)
# Eino 路径模型推理:DeepSeek/OpenAI 为 thinking / reasoning_effortClaude 4.6+ 为 adaptive + output_config.effort(仅显式配置 effort 时下发);3.7 为 enabled+budget_tokens:10000(文档示例),effort 不映射,自定义预算用 extra_request_fields
reasoning:
mode: on # auto | on | offoff 时不附加任何推理扩展字段
effort: high # low | medium | high | max | xhigh(最高档:OpenAI 常用 xhigh,部分网关用 max,原样下发);空表示不指定
allow_client_reasoning: true # false 时忽略对话请求体 reasoning,仅以下方为准
profile: openai_compat # auto | deepseek_compat | openai_compat | output_config_effort
# extra_request_fields: {} # 可选:管理员自定义根级 JSON 片段(高级)
# 视觉分析(analyze_image MCP 工具;图片仅在单次 VL 调用中出现,Agent 上下文只保留文字摘要)
vision:
enabled: false # true 且 model 非空时注册 analyze_image
model: qwen-vl # VL 模型名(enabled 时必填)
api_key: "" # 留空则复用 openai.api_key
base_url: "" # 留空则复用 openai.base_url
provider: # 留空则复用 openai.provideropenai | claude
max_image_bytes: 5242880 # 原始文件上限(字节),默认 5MB
max_dimension: 2048 # 长边缩放像素
jpeg_quality: 82
max_payload_bytes: 524288 # 编码后送 VL API 上限,默认 512KB
skip_preprocess_below_bytes: 2097152 # 低于 2MB 且长边<=max_dimension 且<=max_payload 时原图直传;0=始终压缩
detail: auto # low | high | autoEino ImageURLDetail
timeout_seconds: 60
# ============================================
# 信息收集(FOFA)配置(可选)
# ============================================
@@ -53,23 +94,95 @@ fofa:
# Agent 配置
# 达到最大迭代次数时,AI 会自动总结测试结果
agent:
max_iterations: 120 # 最大迭代次数AI 代理最多执行多少轮工具调用
large_result_threshold: 102400 # 大结果阈值(字节),默认50KB,超过此大小会自动保存到存储
result_storage_dir: tmp # 结果存储目录,大结果会保存在此目录下
tool_timeout_minutes: 30 # 单次工具执行最大时长(分钟),超时自动终止;0 表示不限制(不推荐,易出现长时间挂起)
# system_prompt_path: prompts/single-react.md # 可选:单代理系统提示文件(相对本配置文件所在目录);非空且可读时替换内置提示
# 多代理(CloudWeGo Eino DeepAgent,与上方单 Agent /api/agent-loop 并存)
max_iterations: 12000 # 全局最大迭代次数(单代理 / Deep / Supervisor / Plan-Execute 主执行器 / 子代理均沿用;agents/*.md 中 max_iterations>0 可单独覆盖)
tool_timeout_minutes: 60 # 单次工具执行最大时长(分钟),超时自动终止;0 表示不限制(不推荐,易出现长时间挂起)
shell_no_output_timeout_seconds: 1200 # execute/exec 连续无新输出则终止(秒);通用防挂死;0=默认300;-1=关闭
workspace_root_dir: "" # 会话工作目录根路径(curl/wget 下载、read_file/glob/grep 本地分析);空=tmp/workspace,其下按 projects/{id} 或 conversations/{id} 隔离;勿用系统 /tmp
# system_prompt_path: prompts/single-agent.md # 可选:单代理系统提示文件(相对本配置文件所在目录);非空且可读时替换内置提示
system_prompt_path: ""
# 人机协同(HITL)全局白名单:此处列出的工具始终免审批,与对话页「白名单工具(免审批,逗号分隔)」合并为并集;侧栏「应用」可合并写入本列表并立即生效。
# 非白名单工具在审批方=审计 Agent 时,按会话 HITL 模式选用提示词:
# approval → audit_agent_prompt
# review_edit → audit_agent_prompt_review_edit(可改参后放行)
hitl:
# 全局默认审批方:human=人工审批,audit_agent=审计 Agent;未选会话时切换会写入本项,重启后仍生效
default_reviewer: human
# 审计 Agent 专用模型;字段留空则复用上方 openai 配置。建议 model 填小模型,用于降低审批成本。
audit_model:
provider: "" # openai / claude;留空跟随 openai.provider
base_url: "" # 留空跟随 openai.base_url
api_key: "" # 留空跟随 openai.api_key
model: "" # 留空跟随 openai.model,例如可填 gpt-4o-mini / qwen-turbo / deepseek-chat
# 已决策审计日志保留天数(与 MCP 监控一致;省略默认 90;0 表示不自动清理)
retention_days: 90
# 按你环境里的真实工具名增删(与侧栏一致、小写不敏感);不需要全局免审批可改为 []
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
# audit_agent_prompt: | # 审批模式;留空使用内置默认,可在「人机协同」页编辑
# audit_agent_prompt_review_edit: | # 审查编辑模式;留空使用内置默认
audit_agent_prompt: |-
你是 CyberStrikeAI 人机协同审计 Agent。审查 Agent 即将执行的工具调用是否会对系统造成实质性损害。
你会收到 JSON,包含 hitlMode、toolName、arguments/argumentsObj、userMessage、thinking、reasoningChain、planning 等字段。
裁决基调(默认放行):
- 常规、低风险的渗透测试操作 → approve(如信息收集、端口/服务扫描、目录枚举、只读查询、无害探测命令)
- 与用户授权、当前任务目标一致,且未见明确高危迹象 → approve
- 仅在「可能对系统造成实质影响」时 → reject
必须 reject 的高危情形(示例,非穷举):
- 删库、清表、批量删除数据、格式化磁盘、不可逆破坏
- 修改/重置密码、创建或篡改管理员账号、持久化后门、开机自启
- 向生产环境写入恶意载荷、勒索加密、停止关键服务、修改系统核心配置
- 明显越权:与任务/授权目标无关的破坏性操作
不应单独作为 reject 理由的情形:
- 常规 nmap/curl/grep/读文件/枚举类命令本身
- 参数略显宽泛但无明确破坏意图
- 仅因「信息不足」——若无上述高危迹象,应 approve 并可在 comment 中提示注意点
仅输出一行 JSON,不要 markdown 代码块:
{"decision":"approve"|"reject","comment":"简要理由"}
audit_agent_prompt_review_edit: |-
你是 CyberStrikeAI 人机协同审计 Agent。审查 Agent 即将执行的工具调用是否会对系统造成实质性损害。
你会收到 JSON,包含 hitlMode、toolName、arguments/argumentsObj、userMessage、thinking、reasoningChain、planning 等字段。
裁决基调(默认放行):
- 常规、低风险的渗透测试操作 → approve(如信息收集、端口/服务扫描、目录枚举、只读查询、无害探测命令)
- 与用户授权、当前任务目标一致,且未见明确高危迹象 → approve
- 仅在「可能对系统造成实质影响」时 → reject;参数可安全收窄时优先 approve + editedArguments
必须 reject 的高危情形(示例,非穷举):
- 删库、清表、批量删除数据、格式化磁盘、不可逆破坏
- 修改/重置密码、创建或篡改管理员账号、持久化后门、开机自启
- 向生产环境写入恶意载荷、勒索加密、停止关键服务、修改系统核心配置
- 明显越权:与任务/授权目标无关的破坏性操作
不应单独作为 reject 理由的情形:
- 常规 nmap/curl/grep/读文件/枚举类命令本身
- 参数略显宽泛但无明确破坏意图(应收窄参数后 approve)
- 仅因「信息不足」——若无上述高危迹象,应 approve 并可在 comment 中提示注意点
仅输出一行 JSON,不要 markdown 代码块:
{"decision":"approve"|"reject","comment":"简要理由","editedArguments":{...}}
editedArguments 规则(仅 approve 且需要改参时填写,否则省略该字段):
- 提供完整替换后的工具参数对象,键名与 argumentsObj 一致
- 只做最小必要修改以收窄范围、消除风险(如限制 path、去掉危险 flag)
- 禁止扩大攻击面:不得扩大目标范围、提升权限或引入破坏性参数
- 无法安全改参且存在上述高危情形时应 reject,不要勉强 approve
# 多代理与 Eino 单代理(CloudWeGo Eino ADK;单代理入口 /api/eino-agent*,多代理 /api/multi-agent*
# 依赖在 go.mod 中拉取;若下载失败可设置: go env -w GOPROXY=https://goproxy.cn,direct
# 启用后需重启服务才会注册 /api/multi-agent 与 /api/multi-agent/streamDeep / Plan-Execute / Supervisor 由对话页与 WebShell 所选模式在请求体中传入;机器人/批量无请求体时固定按 deep
# Deep / Plan-Execute / Supervisor 由对话页与 WebShell 所选模式在请求体 orchestration 中指定;机器人按 robot_default_agent_mode
multi_agent:
enabled: true
default_mode: multi # single | multi(前端默认,仍可用界面切换)
robot_use_multi_agent: true # true 时企业微信/钉钉/飞书机器人也走 Eino 多代理(成本更高)
robot_default_agent_mode: eino_single # 企微/钉钉/飞书机器人默认:eino_single | deep | plan_execute | supervisor
batch_use_multi_agent: false # true 时「批量任务」队列中每个子任务也走 Eino 多代理(成本更高)
max_iteration: 0 # 主代理 / plan_execute 执行器最大轮次,0 表示沿用 agent.max_iterations
# plan_execute 专用:execute↔replan 外层循环上限,0 表示 Eino 默认 10。Executor 未暴露 Handlerspatch/reduction/plantask 不作用于 PE,但 tool_search 工具列表拆分仍通过共享 ToolsConfig 作用于执行器。
# plan_execute 专用:execute↔replan 外层循环上限,0 表示 Eino 默认 10。主/子代理 ReAct 轮次见 agent.max_iterations
plan_execute_loop_max_iterations: 0
sub_agent_max_iterations: 120
sub_agent_user_context_max_runes: 0 # 子代理 task 描述中注入用户原文;0=不截断(默认),>0=总字符上限,负数=禁用
without_general_sub_agent: false # false 时保留 Deep 内置 general-purpose 子代理
without_write_todos: false
orchestrator_instruction: "" # Deep 主代理:agents/orchestrator.md(或 kind: orchestrator 的单个 .md)正文优先;正文为空时用此处;皆空则 Eino 默认
@@ -80,22 +193,50 @@ multi_agent:
disable: false # true:不注册 skill 渐进式披露中间件,也不挂本机 FS/Shell 工具;false:按下方开关加载
filesystem_tools: true # true:注册 read_file/glob/grep/write/edit/execute(授权环境慎用);false:仅 skill,不暴露本机读写与 Shell
skill_tool_name: skill # 模型侧可调用的「加载技能」工具名,一般保持 skill;与技能包文档中的调用名一致即可
# Eino ADK 中间件与 Deep/Supervisor 调参(结构体见 internal/config/config.go → MultiAgentEinoMiddlewareConfig
# Eino ADK 中间件与 Deep/Supervisor/plan_execute Executor 调参(结构体见 internal/config/config.go → MultiAgentEinoMiddlewareConfig
# plan_execute:下列 patch/reduction/tool_search/plantask 等同样作用于 Executor(经 ExecPreMiddlewares);Planner/Replanner 不挂 MCP 前置中间件。
eino_middleware:
patch_tool_calls: true # true:修补历史中无 tool_result 的悬空 tool_call(流式中断/重试后更稳);false:关闭;字段省略时默认等同 true
tool_search_enable: false # true:工具数 ≥ min 时启用 tool_search,仅前 N 个工具常驻,其余按正则按需解锁,省 token、减误选;false:全量工具进上下文
tool_search_enable: true # true:工具数 ≥ min 时启用 tool_search,仅前 N 个工具常驻,其余按正则按需解锁,省 token、减误选;false:全量工具进上下文
tool_search_min_tools: 20 # 达到该数量才启用 tool_search(避免工具很少时多此一举);与 always_visible 配合使用
tool_search_always_visible: 12 # 始终直接暴露给模型的工具个数(顺序与角色工具列表一致);其余工具进入动态池,需 tool_search 解锁
plantask_enable: false # true:主代理(Deep / Supervisor 主)挂载 TaskCreate/Get/Update/List;需 eino_skills 可用且 skills_dir 存在,否则仅打日志并跳过
plantask_rel_dir: .eino/plantask # 结构化任务文件相对 skills_dir 的子目录,其下再按会话 ID 分子目录存放
reduction_enable: false # true:大工具输出截断/落盘以控上下文;依赖与 plantask 相同的 eino local 写盘后端,无后端时不挂载
tool_search_always_visible_tools: [read_file, glob, grep, analyze_image, write_file, edit_file, execute, task, transfer_to_agent, exit, write_todos, skill, tool_search, TaskCreate, TaskGet, TaskUpdate, TaskList, record_vulnerability, list_vulnerabilities, get_vulnerability, list_knowledge_risk_types, search_knowledge_base, webshell_exec, webshell_file_list, webshell_file_read, webshell_file_write, manage_webshell_list, manage_webshell_add, manage_webshell_update, manage_webshell_delete, manage_webshell_test, batch_task_list, batch_task_get, batch_task_start, batch_task_rerun, batch_task_pause, batch_task_update_metadata, batch_task_update_schedule, batch_task_schedule_enabled, batch_task_update_task, batch_task_remove_task, batch_task_delete, batch_task_create, batch_task_add_task, http-framework-test, exec] # 后端内置常驻工具白名单(优先于 always_visible 数量策略)
plantask_enable: true # P0:主代理挂载 TaskCreate/Get/Update/List 结构化任务板;需 eino_skills 可用且 skills_dir 存在
plantask_rel_dir: .eino/plantask # 任务文件相对 skills_dir,按会话分子目录:skills/.eino/plantask/<conversationId>/
reduction_enable: true # true:大工具输出截断/落盘以控上下文;依赖与 plantask 相同的 eino local 写盘后端,无后端时不挂载
reduction_max_length_for_trunc: 50000 # 单条工具结果超过该字符数(bytes)时截断并落盘(由 reduction 中间件处理)
reduction_max_tokens_for_clear: 160000 # 历史工具结果清理阈值(tokens),超阈值时在模型调用前清理旧结果
reduction_root_dir: "" # 非空:截断/清理内容落盘根路径;空:使用系统临时目录下按会话隔离的默认路径
reduction_clear_exclude: [] # 不参与「清理阶段」的工具名额外列表(会与 task/transfer/exit 等内置排除项合并);需要时用 YAML 列表填写
reduction_sub_agents: false # true:子代理也挂 reductionfalse:仅编排主代理使用 reduction
checkpoint_dir: "" # 非空:为 adk.NewRunner 启用按会话子目录的文件型 CheckPointStore,便于中断恢复持久化;Resume 的 HTTP/前端流程需另行对接
deep_output_key: "" # 非空:将最终助手输出写入 adk session 的键名(Deep 与 Supervisor 主代理);空表示不写入
deep_model_retry_max_retries: 0 # >0ChatModel 调用失败时的框架级最大重试次数(Deep 与 Supervisor 主);0:不重试
reduction_sub_agents: true # true:子代理也挂 reductionfalse:仅编排主代理使用 reduction
summarization_trigger_ratio: 0.8 # summarization 触发比例(max_total_tokens * ratio),建议 0.75~0.85
summarization_emit_internal_events: true # true:发出 summarization 内部事件(便于诊断)
plan_execute_user_input_budget_ratio: 0.35 # plan_execute 中 userInput 预算比例(planner/replanner/executor 共用)
plan_execute_executed_steps_budget_ratio: 0.2 # plan_execute 中 executed_steps 预算比例
plan_execute_max_step_result_runes: 4000 # plan_execute 每步结果最大字符数(超出截断)
plan_execute_keep_last_steps: 8 # plan_execute 仅保留最近 N 步正文,早期步骤折叠为标题
checkpoint_dir: data/eino-checkpoints # P0:进程崩溃/OOM 后同会话自动 ADK Resume;正常结束会删 .ckpt;与「中断并继续」(last_react_*) 是两套机制
run_retry_max_attempts: 0 # 429/5xx/网络抖动时可退避重试次数(run loop + summarization 共用 isEinoTransientRunError);0=默认 10
run_retry_max_backoff_sec: 0 # 单次退避上限秒数;0=默认 30
empty_response_continue_max_attempts: 0 # Run 成功但未捕获助手正文(含流式中断)时 Handler 退避续跑次数;0=默认 5
deep_output_key: final_answer # P0Eino session 写入最终助手结论(框架内部;Deep/Supervisor 主/eino_single
deep_model_retry_max_retries: 0 # 已废弃,请用 run_retry_max_attempts;保留字段仅为兼容旧配置
task_tool_description_prefix: "" # 非空:仅 Deep 的 task 工具使用自定义描述前缀,运行时会拼接子代理名称;空则走 Eino 默认生成逻辑
# Eino callbacks + OpenTelemetry:框架级 span(与 Zap 对齐);默认不向终端用户 UI 推 eino_trace_*(见 sse_trace_to_client
eino_callbacks:
enabled: true
# log_only=仅 Zap+OTel(推荐默认)| sse/full=才启用流式回调副本关闭等(full 含 stream hooks
mode: log_only
sse_trace_to_client: false # true:且 mode 为 sse/full 时,向前端时间线推送 eino_trace_*(排障/内网演示用)
max_input_summary_runes: 400
max_output_summary_runes: 400
zap_verbose: false # trueDebug 附带 input/output 摘要
otel:
enabled: true
service_name: cyberstrike-ai
exporter: stdout # none | stdout(开发/本机)| otlphttp(生产接 Collector
otlp_endpoint: localhost:4318 # otlphttp 时使用,host:port,路径固定 /v1/traces
sample_ratio: 1.0 # 0~1ParentBased+TraceIDRatio
# 数据库配置
database:
path: data/conversations.db # SQLite 数据库文件路径,用于存储对话历史和消息
@@ -133,6 +274,9 @@ mcp:
# 外部 MCP 配置
external_mcp:
servers: {}
# 内置 C2:本机仅做对话/知识库时可设为 false,不启动监听器、不注册 C2 MCP 工具;省略本段时默认启用
c2:
enabled: true
# ============================================
# 知识库相关配置
# ============================================
@@ -147,9 +291,17 @@ knowledge:
retrieval:
top_k: 5 # 检索返回的Top-K结果数量
similarity_threshold: 0.4 # 余弦相似度阈值(0-1),低于此值的结果将被过滤
# 检索后处理:固定正文规范化去重;上下文预算;可选代码注入 DocumentReranker 做重排
# Eino MultiQueryLLM 改写查询后多路向量检索再融合(始终启用)
multi_query:
max_queries: 4 # 改写变体上限(含语义覆盖);建议 3~4
# 精排(始终启用):dashscope 用 gte-rerank;其他 OpenAI 兼容端点走 /v1/rerank
rerank:
provider: "" # 空=按 base_url 推断:dashscope | cohere
model: "" # 空=dashscope→gte-rerankcohere→rerank-multilingual-v3.0
base_url: "" # 留空则用 embedding / openai 的 base_url
api_key: "" # 留空则用 embedding / openai 的 api_key
post_retrieve:
prefetch_top_k: 0 # 0 与 top_k 相同;可设为 15~30 以便去重后仍填满 top_k
prefetch_top_k: 20 # 每条 MultiQuery 变体的向量候选数;0=内置 max(top_k*4,20)
max_context_chars: 0 # 0 不限制;否则返回的正文总 Unicode 字符上限(整段 chunk
max_context_tokens: 0 # 0 不限制;tiktoken 总 token 上限
sub_index_filter: ""
@@ -185,6 +337,14 @@ knowledge:
# 用于在手机端通过企业微信/钉钉/飞书与 CyberStrikeAI 对话,无需部署在服务器上也可使用
# 在系统设置 -> 机器人设置 中可配置
robots:
wechat: # 微信 iLink(个人微信 ClawBot,扫码绑定)
enabled: false
bot_token: ""
ilink_bot_id: ""
ilink_user_id: ""
base_url: https://ilinkai.weixin.qq.com
bot_type: "3"
bot_agent: CyberStrikeAI/1.0
wecom: # 企业微信
enabled: false
token: ""
@@ -196,11 +356,31 @@ robots:
enabled: false
client_id: ""
client_secret: ""
allow_conversation_id_fallback: false
lark: # 飞书
enabled: false
app_id: ""
app_secret: ""
verify_token: ""
allow_chat_id_fallback: false
telegram: # Telegram
enabled: false
bot_token: ""
bot_username: ""
allow_group_messages: false
slack: # Slack
enabled: false
bot_token: ""
app_token: ""
discord: # Discord
enabled: false
bot_token: ""
allow_guild_messages: false
qq: # QQ 机器人
enabled: false
app_id: ""
client_secret: ""
sandbox: true
# ============================================
# Skills 相关配置
# ============================================
@@ -211,7 +391,7 @@ skills_dir: skills # Skills配置文件目录(相对于配置文件所在目
# ============================================
# 多代理子 AgentMarkdown,唯一维护处)
# ============================================
# 每个 .mdYAML front mattername / id / description / tools / bind_role / max_iterations / 可选 kind: orchestrator+ 正文为系统提示词
# 每个 .mdYAML front mattername / id / description / tools / bind_role / 可选 max_iterations>0 覆盖全局 / 可选 kind: orchestrator+ 正文为系统提示词
# 主代理:固定文件名 orchestrator.md,或任意文件名 + front matter kind: orchestrator(全目录仅允许一个);主代理不参与 task 子代理列表
# 高级用法:仍可在 multi_agent 块内写 sub_agents,会与本文目录合并且同 id 时 YAML 可被 .md 覆盖
agents_dir: agents
@@ -222,3 +402,14 @@ agents_dir: agents
# 系统会从该目录加载所有 .yaml 格式的角色配置文件
# 每个角色应创建独立的配置文件,例如:roles/CTF.yaml, roles/默认.yaml 等
roles_dir: roles # 角色配置文件目录(相对于配置文件所在目录)
# ============================================
# 项目管理与事实黑板
# ============================================
project:
enabled: true
# default_project_id: "" # 可选:机器人/批量任务创建对话时的默认项目 ID
fact_index_max_runes: 65000
# 事实关系速览段预算(从索引总预算中预留)
fact_index_path_max_runes: 10000
fact_summary_max_runes: 24000
default_inject_deprecated: false
+66
View File
@@ -0,0 +1,66 @@
# CyberStrikeAI Documentation
Documentation is split by language:
- [中文文档](zh-CN/)
- [English docs](en-US/)
## 中文文档
- [部署指南](zh-CN/deployment.md)
- [运维 Runbooks](zh-CN/runbooks.md)
- [配置画像](zh-CN/configuration-profiles.md)
- [安全加固指南](zh-CN/security-hardening.md)
- [API Recipes](zh-CN/api-recipes.md)
- [贡献规范](zh-CN/contributing-guide.md)
- [配置参考](zh-CN/configuration.md)
- [安全模型](zh-CN/security-model.md)
- [架构说明](zh-CN/architecture.md)
- [API 参考](zh-CN/api-reference.md)
- [排错指南](zh-CN/troubleshooting.md)
- [审计与监控](zh-CN/audit-and-monitoring.md)
- [知识库](zh-CN/knowledge-base.md)
- [C2 使用说明](zh-CN/c2.md)
- [WebShell 管理](zh-CN/webshell.md)
- [MCP 联邦](zh-CN/mcp-federation.md)
- [Agent 与角色](zh-CN/agent-and-role-guide.md)
- [Skills 指南](zh-CN/skills-guide.md)
- [插件开发](zh-CN/plugin-development.md)
- [发布流程](zh-CN/release-process.md)
- [测试指南](zh-CN/testing.md)
- [图编排使用说明](zh-CN/workflow-graph.md)
- [人机协同最佳实践](zh-CN/hitl-best-practices.md)
- [机器人使用说明](zh-CN/robot.md)
- [视觉分析](zh-CN/VISION.md)
- [前端国际化方案](zh-CN/frontend-i18n.md)
- [Eino 多代理改造说明](zh-CN/MULTI_AGENT_EINO.md)
## English Docs
- [Deployment Guide](en-US/deployment.md)
- [Runbooks](en-US/runbooks.md)
- [Configuration Profiles](en-US/configuration-profiles.md)
- [Security Hardening](en-US/security-hardening.md)
- [API Recipes](en-US/api-recipes.md)
- [Contributing Guide](en-US/contributing-guide.md)
- [Configuration Reference](en-US/configuration.md)
- [Security Model](en-US/security-model.md)
- [Architecture](en-US/architecture.md)
- [API Reference](en-US/api-reference.md)
- [Troubleshooting](en-US/troubleshooting.md)
- [Audit and Monitoring](en-US/audit-and-monitoring.md)
- [Knowledge Base](en-US/knowledge-base.md)
- [C2 Guide](en-US/c2.md)
- [WebShell Management](en-US/webshell.md)
- [MCP Federation](en-US/mcp-federation.md)
- [Agent and Role Guide](en-US/agent-and-role-guide.md)
- [Skills Guide](en-US/skills-guide.md)
- [Plugin Development](en-US/plugin-development.md)
- [Release Process](en-US/release-process.md)
- [Testing Guide](en-US/testing.md)
- [Graph Orchestration Guide](en-US/workflow-graph.md)
- [HITL Best Practices](en-US/hitl-best-practices.md)
- [Robot / Chatbot Guide](en-US/robot.md)
- [Vision Analysis](en-US/VISION.md)
- [Frontend i18n](en-US/frontend-i18n.md)
- [Eino Multi-Agent Notes](en-US/MULTI_AGENT_EINO.md)
+66
View File
@@ -0,0 +1,66 @@
# Eino Multi-Agent Notes
[中文](../zh-CN/MULTI_AGENT_EINO.md)
CyberStrikeAI uses CloudWeGo Eino ADK for the current single-agent and multi-agent execution paths. The native legacy ReAct path has been removed.
## Entrypoints
- Single-agent: `/api/eino-agent` and `/api/eino-agent/stream`
- Multi-agent: `/api/multi-agent` and `/api/multi-agent/stream`
Multi-agent orchestration is selected by request body:
- `deep`
- `plan_execute`
- `supervisor`
Robots default to `robot_default_agent_mode`, and batch tasks can opt into multi-agent through config.
## Agent Definitions
Markdown agents live under `agents/`.
Typical files:
```text
agents/orchestrator.md
agents/orchestrator-plan-execute.md
agents/orchestrator-supervisor.md
agents/*.md
```
Front matter controls name, id, description, tools, bound role, max iterations, and optional orchestrator kind.
## Middleware
Important Eino middleware:
- tool search: exposes a small visible tool set and unlocks others on demand;
- patch tool calls: repairs interrupted histories;
- plan task: structured task board;
- reduction: truncates or persists large tool outputs;
- summarization: compresses long contexts;
- checkpoint: resume after crash/OOM.
These settings live under `multi_agent.eino_middleware`.
## Skills
Eino Skills support progressive disclosure. The Agent initially sees names and descriptions; details are loaded only when needed through the configured skill tool.
## Operational Notes
- Tool visibility is not the same as tool availability in the UI.
- Running streams keep their startup context even if config changes mid-run.
- Summarization can write transcripts under `data/conversation_artifacts/...`.
- High-risk tools should still be constrained by roles and HITL.
## Source Anchors
- Multi-agent handler: `internal/handler/multi_agent.go`
- Preparation: `internal/handler/multi_agent_prepare.go`
- Orchestration: `internal/multiagent/eino_orchestration.go`
- Run loop: `internal/multiagent/eino_adk_run_loop.go`
- Skills: `internal/multiagent/eino_skills.go`
- Middleware: `internal/multiagent/eino_middleware.go`
+29
View File
@@ -0,0 +1,29 @@
# English Docs
- [Deployment Guide](deployment.md): deployment modes, HTTPS, reverse proxy, systemd, backup, upgrade, and acceptance checks.
- [Runbooks](runbooks.md): operational steps for production setup, external MCP, KB, Web testing, C2 cleanup, and tool debugging.
- [Configuration Profiles](configuration-profiles.md): recommended profiles for dev, internal team, knowledge-only, production, C2, and MCP automation.
- [Security Hardening](security-hardening.md): pre-launch baseline, reverse proxy, HITL allowlist, file permissions, and periodic review.
- [API Recipes](api-recipes.md): examples for login, Agent, streaming, multi-agent, uploads, vulnerabilities, KB, MCP, and audit export.
- [Contributing Guide](contributing-guide.md): checklists for APIs, config, tools, frontend, DB, high-risk features, and docs.
- [Configuration Reference](configuration.md): `config.yaml` fields, hot-apply boundaries, recommended values, and source anchors.
- [Security Model](security-model.md): trust boundaries, HITL, tool execution, C2/WebShell, and data safety.
- [Architecture](architecture.md): request flow, module relationships, complexity hotspots, and design trade-offs.
- [API Reference](api-reference.md): authentication, OpenAPI, SSE, stability tiers, and common endpoints.
- [Troubleshooting](troubleshooting.md): diagnostic order, minimal commands, common misdiagnoses, and issue template.
- [Audit and Monitoring](audit-and-monitoring.md): platform audit, tool monitoring, HITL logs, and retention.
- [Knowledge Base](knowledge-base.md): indexing pipeline, retrieval tuning, log analysis, and content writing.
- [C2 Guide](c2.md): lifecycle, task classification, event review, and safety guidance.
- [WebShell Management](webshell.md): operation tiers, naming, AI guardrails, and troubleshooting.
- [MCP Federation](mcp-federation.md): built-in MCP, external MCP, lifecycle, and tool naming.
- [Agent and Role Guide](agent-and-role-guide.md): roles, sub-agents, Skills, orchestration modes, and tool visibility.
- [Skills Guide](skills-guide.md): Skill structure, progressive disclosure, anti-patterns, and local-tool risk.
- [Plugin Development](plugin-development.md): API plugins, MCP plugins, resource-pack plugins, and security boundaries.
- [Release Process](release-process.md): release risk, config compatibility, DB migrations, and acceptance checks.
- [Testing Guide](testing.md): test layers, regression focus, test data, and failure cases.
- [Graph Orchestration Guide](workflow-graph.md)
- [HITL Best Practices](hitl-best-practices.md)
- [Robot / Chatbot Guide](robot.md)
- [Vision Analysis](VISION.md)
- [Frontend i18n](frontend-i18n.md)
- [Eino Multi-Agent Notes](MULTI_AGENT_EINO.md)
+61
View File
@@ -0,0 +1,61 @@
# Vision Analysis
[中文](../zh-CN/VISION.md)
Vision analysis registers the `analyze_image` MCP tool when enabled. It is intended for screenshots, captchas, UI states, and image evidence in authorized workflows.
## Config
```yaml
vision:
enabled: true
model: qwen-vl
api_key: ""
base_url: ""
provider: ""
max_image_bytes: 5242880
max_dimension: 2048
jpeg_quality: 82
max_payload_bytes: 524288
detail: auto
timeout_seconds: 60
```
Empty `api_key`, `base_url`, or `provider` inherits from `openai`.
## Data Handling
Image bytes are sent only to the vision model call. Agent history keeps text summaries, not raw image bytes. This reduces context size and accidental image propagation.
## Preprocessing
The runtime can resize and recompress large images based on:
- maximum file size;
- maximum dimension;
- JPEG quality;
- encoded payload size.
If small images are already under limits, preprocessing may be skipped.
## Usage Guidance
Use vision for:
- UI screenshots;
- visual vulnerability evidence;
- captcha or image-based prompts in authorized tests;
- interpreting tool screenshots.
Do not use it for:
- unrelated personal images;
- sensitive screenshots without authorization;
- long-term storage of raw evidence when a text summary is enough.
## Source Anchors
- Tool registration: `internal/app/vision_tools.go`
- Client: `internal/vision/client.go`
- Preprocess: `internal/vision/preprocess.go`
- Config: `internal/config/vision.go`
+79
View File
@@ -0,0 +1,79 @@
# Agent and Role Guide
[中文](../zh-CN/agent-and-role-guide.md)
Agent behavior is shaped by roles, Markdown sub-agents, Skills, tool visibility, and HITL policy.
## Responsibility Boundaries
| Resource | Purpose | Not for |
| --- | --- | --- |
| Role | identity, tone, tool boundary, authorization rules | large reference material |
| Agent Markdown | multi-agent specialization, handoff format, local strategy | one-off facts |
| Skill | reusable procedures, checklists, templates, references | permission control |
Authorization boundaries belong in roles and HITL first, not only in Skills.
## Modes
| Mode | Good for | Poor fit |
| --- | --- | --- |
| `eino_single` | short tasks, interactive analysis | large multi-stage work |
| `deep` | dynamic task decomposition | strict sequential workflows |
| `plan_execute` | plan, execute, replan loops | frequent user interruption |
| `supervisor` | expert routing | vague or too many sub-agents |
Start with `eino_single`; use `plan_execute` for structured projects; use `deep` or `supervisor` when specialist agents matter.
## Markdown Sub-Agent
Example:
```yaml
---
name: Vulnerability Triage
id: vulnerability-triage
description: Validate, classify, and summarize vulnerability evidence
tools:
- nmap
- nuclei
bind_role: 综合漏洞扫描
max_iterations: 200
---
```
The body should define scope, tool order, output format, and prohibited actions.
## Tool Visibility
With `tool_search`, the model initially sees only a subset of tools:
- visible in UI does not mean visible in current model context;
- `tool_search_always_visible_tools` are easier to call;
- clear tool descriptions improve search hits;
- sub-agent tool constraints still matter.
When a tool is not used, check role tools, sub-agent tools, tool_search config, and description.
## Output Format
Sub-agents should return structured results:
```markdown
## Conclusion
## Evidence
- Tool:
- Key output:
- Confidence:
## Risks
## Suggested next step
```
This helps the orchestrator continue and supports reporting.
## Source Anchors
- Markdown Agent parser: `internal/agents/markdown.go`
- Multi-agent preparation: `internal/handler/multi_agent_prepare.go`
- Orchestration: `internal/multiagent/eino_orchestration.go`
- Tool search middleware: `internal/multiagent/eino_middleware.go`
+153
View File
@@ -0,0 +1,153 @@
# API Recipes
[中文](../zh-CN/api-recipes.md)
Common API workflows for scripts and plugins. Use `/api-docs` and `/api/openapi/spec` for complete schemas.
## Recipe 1: Login and Validate
```bash
curl -k https://127.0.0.1:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"password":"<password>"}'
```
Use:
```text
Authorization: Bearer <token>
```
Validate:
```bash
curl -k https://127.0.0.1:8080/api/auth/validate \
-H "Authorization: Bearer <token>"
```
## Recipe 2: Create Conversation and Send Message
Simplest path: call Agent without pre-creating an empty conversation.
```bash
curl -k https://127.0.0.1:8080/api/eino-agent \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"Run authorized basic read-only recon against 127.0.0.1"}'
```
If you need an empty conversation first:
```bash
curl -k https://127.0.0.1:8080/api/conversations \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"title":"Web Test"}'
```
Then pass `conversationId` to the Agent request.
## Recipe 3: Stream Agent Output
```bash
curl -k -N https://127.0.0.1:8080/api/eino-agent/stream \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"Summarize current project facts and propose read-only next steps"}'
```
Notes:
- `-N` disables curl buffering.
- reverse proxy buffering must also be disabled.
- wait for `done`.
## Recipe 4: Multi-Agent
```bash
curl -k -N https://127.0.0.1:8080/api/multi-agent/stream \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"message":"Run a staged authorized Web security test; plan first, execute read-only steps",
"orchestration":"plan_execute"
}'
```
Options:
- `deep`
- `plan_execute`
- `supervisor`
## Recipe 5: Upload Attachment
```bash
curl -k https://127.0.0.1:8080/api/chat-uploads \
-H "Authorization: Bearer <token>" \
-F "file=@./request.txt"
```
Upload large files and reference them in messages instead of pasting raw content.
## Recipe 6: Create Vulnerability
```bash
curl -k https://127.0.0.1:8080/api/vulnerabilities \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title":"Example SQL Injection",
"severity":"high",
"target":"https://example.com/item?id=1",
"description":"Parameter id has verified SQL injection",
"evidence":"read-only validation output...",
"remediation":"Use parameterized queries"
}'
```
Check OpenAPI for exact fields.
## Recipe 7: Search Knowledge Base
```bash
curl -k https://127.0.0.1:8080/api/knowledge/search \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"query":"How to infer SQL injection column count",
"riskType":"SQL Injection",
"topK":5,
"threshold":0.4
}'
```
If empty, check categories first.
## Recipe 8: External MCP Status
```bash
curl -k https://127.0.0.1:8080/api/external-mcp/stats \
-H "Authorization: Bearer <token>"
```
If service is running but Agent cannot find tools, check role constraints and `tool_search`.
## Recipe 9: Tool Schema
```bash
curl -k https://127.0.0.1:8080/api/config/tools/nmap/schema \
-H "Authorization: Bearer <token>"
```
Scripts should build args from schema rather than guessing field names.
## Recipe 10: Export Audit Logs
```bash
curl -k "https://127.0.0.1:8080/api/audit/logs/export" \
-H "Authorization: Bearer <token>" \
-o audit.csv
```
Exported logs may contain sensitive operational data. Store encrypted.
+103
View File
@@ -0,0 +1,103 @@
# API Reference
[中文](../zh-CN/api-reference.md)
CyberStrikeAI exposes built-in OpenAPI docs:
```text
/api-docs
GET /api/openapi/spec
```
The OpenAPI spec is protected to avoid exposing the API surface to unauthenticated users.
## Authentication
Login:
```http
POST /api/auth/login
Content-Type: application/json
{"password":"your-password"}
```
The auth middleware accepts token from:
1. `Authorization: Bearer <token>`
2. `Authorization: <token>`
3. `?token=<token>`
4. `auth_token` cookie
Prefer `Authorization: Bearer` for scripts. Query tokens can leak through logs.
## Agent APIs
Single-agent:
- `POST /api/eino-agent`
- `POST /api/eino-agent/stream`
Multi-agent:
- `POST /api/multi-agent`
- `POST /api/multi-agent/stream`
`orchestration` may be `deep`, `plan_execute`, or `supervisor`.
## SSE Notes
Streaming endpoints are long-lived. Clients should:
- handle `error` events;
- wait for `done`;
- avoid blindly replaying destructive requests;
- disable proxy buffering;
- pass `conversationId` when continuing a conversation.
## Stability Tiers
| API type | Stability | Recommendation |
| --- | --- | --- |
| `/api/auth/*` | high | safe to integrate |
| `/api/eino-agent*` | high | preferred chat entry |
| `/api/openapi/spec` | high | client generation |
| `/api/config*` | medium | admin automation only |
| `/api/c2/*`, `/api/webshell/*` | medium | high-risk, restrict access |
| frontend private calls | low | avoid plugin dependency |
## Common Areas
- Conversations: `/api/conversations`
- Projects/facts: `/api/projects`
- Vulnerabilities: `/api/vulnerabilities`
- Knowledge: `/api/knowledge/*`
- Roles: `/api/roles`
- Skills: `/api/skills`
- External MCP: `/api/external-mcp`
- Monitoring: `/api/monitor`
- Audit: `/api/audit`
- C2: `/api/c2`
- WebShell: `/api/webshell`
## Curl Example
```bash
curl -k https://127.0.0.1:8080/api/conversations \
-H "Authorization: Bearer <token>"
```
```bash
curl -k https://127.0.0.1:8080/api/eino-agent \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"Run authorized basic recon against 127.0.0.1; avoid high-risk actions."}'
```
## Source Anchors
- Routes: `internal/app/app.go`
- Auth middleware: `internal/security/auth_middleware.go`
- OpenAPI: `internal/handler/openapi.go`
- Single-agent: `internal/handler/eino_single_agent.go`
- Multi-agent: `internal/handler/multi_agent.go`
+74
View File
@@ -0,0 +1,74 @@
# Architecture
[中文](../zh-CN/architecture.md)
CyberStrikeAI is a single Go Web application with a static frontend, SQLite persistence, Agent orchestration, MCP tooling, workflow graphs, knowledge retrieval, and optional C2/WebShell subsystems.
## Overview
```mermaid
flowchart LR
U["Web / Robot / API"] --> R["Gin Router"]
R --> H["Handlers"]
H --> DB["SQLite"]
H --> A["Agent / Multi-Agent"]
A --> M["MCP Server"]
M --> T["Built-in / YAML / Skill tools"]
M --> EM["External MCP"]
A --> K["Knowledge Retrieval"]
H --> W["Workflow Runtime"]
H --> C2["C2"]
H --> WS["WebShell"]
H --> AU["Audit / Monitor"]
```
## Request Path
For `/api/eino-agent/stream`:
1. Gin route enters auth middleware.
2. Handler parses message, conversation, role, uploads, and WebShell context.
3. Agent builds model input: history, role prompt, project facts, tools.
4. Eino Runner calls the model.
5. Tool requests go through MCP.
6. HITL may interrupt before execution.
7. Tool results are saved to process details and monitoring.
8. Model continues and produces final text.
9. SSE streams progress and deltas to the browser.
10. Conversation and process details persist to SQLite.
This explains why a failure may live in auth, config, model, MCP, HITL, DB, SSE, or frontend rendering.
## Cross-Cutting Modules
- Project facts are injected into Agent context.
- HITL sits before tool execution.
- Monitor records tool execution and supports cancellation/review.
- Audit records platform management actions.
- Tool search controls what tools the model can currently see.
These are not just pages; they affect many runtime paths.
## Complexity Hotspots
- `internal/app/app.go`: service construction and route wiring.
- `internal/handler/config.go`: hot application of config across model, KB, C2, robot, MCP.
- `internal/multiagent/`: streaming, retry, summarization, middleware, tools.
- `internal/security/`: auth and shell execution boundary.
- `internal/database/`: SQLite schema compatibility.
## Design Trade-Offs
The project uses a single Go service, static frontend, and SQLite to keep deployment simple. The trade-offs:
- multi-instance scale is not automatic;
- runtime files must be backed up carefully;
- high-privilege tools and admin UI live in one process, so deployment isolation matters.
## Source Anchors
- App wiring: `internal/app/app.go`
- Handlers: `internal/handler/`
- Multi-agent: `internal/multiagent/`
- MCP: `internal/mcp/`
- DB: `internal/database/`
+87
View File
@@ -0,0 +1,87 @@
# Audit and Monitoring
[中文](../zh-CN/audit-and-monitoring.md)
CyberStrikeAI has separate observability streams:
- Audit: who performed platform management actions.
- Monitor: how tool executions ran.
- HITL logs: why a tool call was approved, edited, or rejected.
- Process details: how an Agent chained reasoning, tools, and outputs.
Use them together during review.
## Audit
Config:
```yaml
audit:
enabled: true
retention_days: 15
max_detail_bytes: 8192
```
Endpoints:
- `GET /api/audit/meta`
- `GET /api/audit/summary`
- `GET /api/audit/logs`
- `GET /api/audit/logs/:id`
- `GET /api/audit/logs/export`
Watch for login failures, password changes, config updates, external MCP changes, WebShell/C2 actions, and HITL rejections.
## Tool Monitoring
Config:
```yaml
monitor:
retention_days: 90
```
Endpoints:
- `GET /api/monitor`
- `GET /api/monitor/execution/:id`
- `POST /api/monitor/execution/:id/cancel`
- `GET /api/monitor/stats`
- `GET /api/monitor/calls-timeline`
Monitoring is for execution state, duration, cancellation, and result review. It is not a substitute for platform audit.
## Retention Guidance
Security-tool logs can include targets, paths, commands, and sensitive outputs. Longer retention is not always safer.
- Short engagements: 15-30 days.
- Continuous red-team platform: 90-180 days.
- Compliance archive: export and encrypt.
## Review Checklist
Weekly:
- failed logins and unusual IPs;
- config changes;
- long-running or frequently failing tools;
- external MCP state;
- DB size and disk.
After engagement:
- export required evidence;
- delete stale WebShell/C2 resources;
- clean uploads and temporary workspaces;
- archive reports, vulnerabilities, and project facts.
## Source Anchors
- Audit service: `internal/audit/service.go`
- Sanitization: `internal/audit/sanitize.go`
- Retention: `internal/audit/retention.go`
- Audit handler: `internal/handler/audit.go`
- Monitor: `internal/monitor/reconcile.go`
- Monitor handler: `internal/handler/monitor.go`
- HITL logs: `internal/handler/hitl_logs.go`
+68
View File
@@ -0,0 +1,68 @@
# C2 Guide
[中文](../zh-CN/c2.md)
The built-in C2 subsystem is for authorized environments only. Disable it when not needed:
```yaml
c2:
enabled: false
```
## Objects
- Listener: receives sessions.
- Session: connected implant/session.
- Task: command or operation assigned to a session.
- Payload: generated binary or one-liner.
- Profile: communication configuration.
- Event: runtime event stream.
- File: upload/download channel.
APIs live under `/api/c2`; disabled C2 returns `503 c2_disabled`.
## Lifecycle
Correct C2 operation is a lifecycle:
1. Authorization: project, targets, time window, allowed actions.
2. Profile design: transport, sleep, callback address.
3. Listener start: port, network path, logs.
4. Payload generation: hash, purpose, delivery method.
5. Session intake: confirm host identity and privilege.
6. Tasking: only authorized tasks.
7. Result archival: project facts or report.
8. Cleanup: stop listeners, delete payloads, clear stale sessions/events.
Skipping authorization and profile design makes the rest hard to audit.
## Task Classification
| Level | Example | Approval |
| --- | --- | --- |
| L1 read-only identity | `whoami`, hostname | audit agent may approve |
| L2 environment enum | interfaces, processes | strict review |
| L3 file access | read config, download result | human confirms path |
| L4 change execution | upload, run script, sleep change | human approval |
| L5 persistence/lateral/destructive | startup, creds, delete, spread | reject unless explicit authorization |
Put this classification into HITL prompts for practical decisions.
## Review Questions
- Which listener received which session?
- Who generated the payload and when?
- Which authorized target does the session represent?
- Which tasks were issued?
- Were outputs saved into facts or reports?
- Were listener and payload cleaned up?
## Source Anchors
- Manager: `internal/c2/manager.go`
- Listener: `internal/c2/listener.go`
- HTTP listener: `internal/c2/listener_http.go`
- TCP listener: `internal/c2/listener_tcp.go`
- Payload: `internal/c2/payload_builder.go`
- Handler: `internal/handler/c2.go`
- MCP tools: `internal/app/c2_tools.go`
+159
View File
@@ -0,0 +1,159 @@
# Configuration Profiles
[中文](../zh-CN/configuration-profiles.md)
These profiles are not full `config.yaml` files. They show the key sections that most affect safety and operability.
## Local Development
Goal: easy debugging with local capabilities.
Common startup:
```bash
chmod +x run.sh && ./run.sh
```
```yaml
server:
host: 127.0.0.1
port: 8080
tls_enabled: true
tls_auto_self_sign: true
auth:
password: "dev-only-change-me"
audit:
enabled: true
retention_days: 7
c2:
enabled: false
multi_agent:
enabled: true
eino_skills:
filesystem_tools: true
```
Not for shared or public use.
## Internal Team
Goal: shared team instance with audit and limited high-risk surface.
```yaml
server:
host: 127.0.0.1
port: 8080
tls_enabled: false
auth:
password: "<long-random-password>"
audit:
enabled: true
retention_days: 30
monitor:
retention_days: 90
c2:
enabled: false
mcp:
enabled: false
hitl:
default_reviewer: human
tool_whitelist: [read_file, glob, grep, tool_search]
```
Pair with reverse-proxy HTTPS, IP allowlist, and backups.
## Knowledge-Only Assistant
Goal: use CyberStrikeAI as a knowledge-augmented assistant with minimal attack surface.
```yaml
c2:
enabled: false
mcp:
enabled: false
knowledge:
enabled: true
base_path: knowledge_base
retrieval:
top_k: 5
similarity_threshold: 0.4
multi_agent:
eino_skills:
filesystem_tools: false
```
Use read-only roles and avoid storing sensitive customer data.
## High-Audit Production
Goal: long-running production red-team or security platform.
```yaml
auth:
password: "<managed-secret>"
session_duration_hours: 8
audit:
enabled: true
retention_days: 90
monitor:
retention_days: 180
hitl:
default_reviewer: human
retention_days: 180
tool_whitelist: [read_file, glob, grep, tool_search]
c2:
enabled: false
multi_agent:
eino_callbacks:
enabled: true
mode: log_only
sse_trace_to_client: false
```
Pair with proxy auth, dedicated OS user, log collection, encrypted backups, and project closeout cleanup.
## C2 Exercise Window
Goal: temporarily enable C2 only during authorized exercise.
```yaml
c2:
enabled: true
hitl:
default_reviewer: human
tool_whitelist: [read_file, glob, grep, tool_search]
audit:
enabled: true
monitor:
retention_days: 180
```
Requirements:
- confirm scope before exercise;
- separate listener ports from admin UI;
- run C2 cleanup afterward;
- restore `c2.enabled: false`.
## External MCP Automation
Goal: connect trusted internal tool services.
```yaml
external_mcp:
servers: {}
multi_agent:
eino_middleware:
tool_search_enable: true
tool_search_min_tools: 20
hitl:
default_reviewer: audit_agent
tool_whitelist: [read_file, glob, grep, tool_search]
```
Guidance:
- every MCP tool needs clear schema;
- high-risk MCP tools stay out of allowlist;
- stdio MCP gets its own working directory;
- HTTP MCP must authenticate.
+86
View File
@@ -0,0 +1,86 @@
# Configuration Reference
[中文](../zh-CN/configuration.md)
The main configuration file is `config.yaml`. Many fields are editable through the Web settings page, but not every field has the same hot-apply behavior.
## Core Sections
```yaml
server:
host: 0.0.0.0
port: 8080
tls_enabled: true
auth:
password: "change-me"
session_duration_hours: 12
openai:
provider: openai
base_url: https://api.openai.com/v1
api_key: sk-...
model: gpt-4.1
agent:
max_iterations: 12000
tool_timeout_minutes: 60
```
Change the default password immediately. Use HTTPS or a trusted reverse proxy in any shared environment.
## Hot-Apply Boundaries
`POST /api/config/apply` coordinates model config, tool description mode, MCP tool registration, knowledge components, robot restarts, and C2 runtime reconciliation. It does not make every field instantly effective.
| Section | Usually hot-applies | Extra action |
| --- | --- | --- |
| `openai` | new requests use new model settings | running streams keep their current state |
| `agent.max_iterations` | new tasks | existing tasks continue |
| `hitl.tool_whitelist` | new approval checks | pending approvals are not re-decided |
| `knowledge.enabled` | initializes/updates components | scan and index are still required |
| `knowledge.embedding` | updates retriever/indexer config | rebuild index for existing vectors |
| `robots` | restarts long-lived connections | platform callback settings must still match |
| `c2.enabled` | reconciles C2 runtime | verify existing listeners/sessions manually |
| `server.port/tls` | usually needs process restart | listener settings are not ordinary hot state |
## Fallback Relationships
- `vision.api_key/base_url/provider` can inherit from `openai`.
- `hitl.audit_model` can inherit from `openai`.
- `knowledge.embedding.base_url/api_key` can inherit from model settings.
- rerank config can inherit from embedding/openai.
- `database.knowledge_db_path` can be separate or reuse the main DB.
When debugging, inspect both the child config and the fallback parent.
## Recommended Values
| Field | Conservative | Aggressive | Decide by |
| --- | --- | --- | --- |
| `agent.tool_timeout_minutes` | 10-30 | 60+ | long scanners |
| `shell_no_output_timeout_seconds` | 300-600 | 1200+ | quiet tools |
| `knowledge.indexing.batch_size` | 5-10 | 20+ | embedding API limits |
| `knowledge.indexing.rate_limit_delay_ms` | 300-800 | 0-100 | 429 frequency |
| `retrieval.top_k` | 3-5 | 8-12 | context budget |
| `similarity_threshold` | 0.35-0.45 | 0.5+ | recall vs precision |
| `audit.retention_days` | 15-30 | 90+ | compliance and disk |
## Change Template
Before changing config, write down:
```text
Purpose:
Sections:
Expected impact:
Rollback:
Validation endpoints:
```
After changing, validate the specific subsystem rather than trusting the save message.
## Source Anchors
- Config structs: `internal/config/config.go`
- Env expansion: `internal/config/envexpand.go`
- Config API and apply: `internal/handler/config.go`
- Route registration: `internal/app/app.go`
- C2 reconciliation: `internal/app/c2_lifecycle.go`
+115
View File
@@ -0,0 +1,115 @@
# Contributing Guide
[中文](../zh-CN/contributing-guide.md)
This guide defines baseline expectations when adding features, APIs, tools, frontend pages, or docs.
## Principles
- New features need documentation.
- New APIs need OpenAPI updates.
- New frontend text needs zh-CN and en-US i18n.
- New config must state hot-apply behavior.
- New high-risk tools must define HITL policy.
- New DB fields must be compatible with old databases.
- New long-running tasks need state, cancellation, or recovery strategy.
## New API Checklist
- Handler validates parameters.
- Error response has stable `error` and readable `message`.
- Endpoint is authenticated unless it is an explicit platform callback.
- Mutations write audit events.
- Long tasks write monitoring/task state.
- `internal/handler/openapi.go` updated.
- API docs or recipes updated.
- Handler tests added.
## New Config Checklist
- Field exists in `config.Config`.
- `config.yaml` sample has comments.
- Safe default when omitted.
- Old configs still start.
- Hot-apply behavior documented.
- Web settings do not delete unknown fields.
- Security docs updated if high-risk capability is affected.
## New Tool Checklist
For YAML tools and Go MCP tools:
- stable and specific tool name;
- searchable `short_description`;
- explicit input schema, not one raw `cmd`;
- readable and stable output;
- controlled timeout and error path;
- high-risk operation not globally allowlisted;
- docs explain use case and risk.
## New Frontend Page Checklist
- Reuse `apiFetch`, modal, notifications, and existing state patterns.
- Add all visible text to `zh-CN.json` and `en-US.json`.
- Include loading, empty, and error states.
- Confirm destructive/high-risk actions.
- Avoid overflow in long English labels.
- Browser console clean.
## DB Change Checklist
- Migration is idempotent.
- Old DB upgrades.
- Defaults are safe.
- Large indexes are deliberate.
- Empty DB and old DB tested.
- Release notes mention backup.
## High-Risk Capability Checklist
High-risk includes Shell, WebShell, C2, external MCP write/execute, credential access, and bulk scanning.
Answer:
- Who can call it?
- Does it require HITL?
- What is audited?
- How can it be cancelled?
- How is cleanup done?
- How can it be disabled?
- Is it off by default?
## Documentation Requirements
Each important feature should document:
- purpose;
- config;
- workflow;
- risk boundary;
- troubleshooting;
- source anchors.
Chinese and English docs must have matching filenames:
```text
docs/zh-CN/
docs/en-US/
```
Update:
- `docs/README.md`
- `docs/zh-CN/README.md`
- `docs/en-US/README.md`
## Review Focus
Prioritize:
- behavior regressions;
- security boundaries;
- old data compatibility;
- error handling;
- test gaps;
- docs and OpenAPI sync.
+113
View File
@@ -0,0 +1,113 @@
# Deployment Guide
[中文](../zh-CN/deployment.md)
CyberStrikeAI can run as a local testing tool, an internal team service, or a production red-team platform. Treat it as a high-privilege security system: it can execute commands, call MCP tools, manage WebShell connections, and optionally run C2 listeners.
## Prerequisites
- Go for source runs and binary builds.
- Python for some MCP servers and tool scripts.
- SQLite files under `data/`; no external DB is required by default.
- Actual security tools installed in PATH. YAML files under `tools/` only describe commands.
- An OpenAI-compatible model endpoint, or `openai.provider: claude` for the Claude bridge.
Important persistent paths:
```text
config.yaml
data/
tools/
roles/
skills/
agents/
knowledge_base/
chat_uploads/
```
Back these up before upgrades.
## Startup Modes
Local quick start:
```bash
chmod +x run.sh && ./run.sh
```
`run.sh` is the most common startup path for local use, development, small temporary internal deployments, and quick post-upgrade verification.
For long-running service, boot-time startup, managed logs, and crash recovery, prefer a binary managed by systemd.
Source run:
```bash
go run ./cmd/server --config config.yaml
```
Binary build:
```bash
go build -o cyberstrike-ai ./cmd/server
./cyberstrike-ai --config config.yaml
```
The binary still needs `web/templates`, `web/static`, and the runtime resource directories.
## HTTPS and Reverse Proxy
For local testing, self-signed HTTPS is acceptable:
```yaml
server:
tls_enabled: true
tls_auto_self_sign: true
```
For production, use real certificates or terminate TLS at a reverse proxy. If the proxy terminates TLS and forwards HTTP to the app, avoid enabling app-side TLS on the same upstream unless `proxy_pass` uses HTTPS.
Nginx must not buffer SSE:
```nginx
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
## Deployment Decision Table
| Scenario | Recommended setup | Key settings | Avoid |
| --- | --- | --- | --- |
| Personal testing | `./run.sh` + self-signed HTTPS | `tls_auto_self_sign: true` | Public exposure |
| Internal team | Binary + systemd + internal HTTPS | strong password, audit, backup, IP restrictions | Shared weak password |
| Production red-team platform | Reverse proxy + dedicated OS user + log collection | real certs, proxy auth, C2 only when needed | Direct public admin UI |
| Chat/KB only | Disable C2 and unnecessary MCP | `c2.enabled: false` | All tools enabled by default |
| Tool automation | Isolated workspace + HITL | `workspace_root_dir`, `hitl`, `monitor` | Shell tools globally allowlisted |
## Acceptance Checklist
After startup:
1. Open `/` and verify no HTTP/HTTPS redirect loop.
2. Login and validate `/api/auth/validate`.
3. Run model test in settings.
4. Check tool list and schemas.
5. If KB is enabled, check index status.
6. If external MCP is enabled, verify connection and tool visibility.
7. If C2 is enabled, start and stop a test listener only in an authorized network.
8. Check audit logs for login and config activity.
## Runtime File Layers
- Replaceable: binary, `web/`, default docs/resources.
- Preserve: `config.yaml`, `data/`, custom tools/roles/skills/agents, `knowledge_base`, uploads.
- Cleanup candidates: checkpoints, temporary workspaces, stale payloads, old tool execution records.
## Source Anchors
- App wiring and routes: `internal/app/app.go`
- TLS bootstrap: `internal/app/main_server_tls.go`
- HTTP to HTTPS redirect: `internal/app/main_server_http_redirect.go`
- Config structs: `internal/config/config.go`
- Config apply: `internal/handler/config.go`
+111
View File
@@ -0,0 +1,111 @@
# Developer Guide
[中文](../zh-CN/developer-guide.md)
This guide is for contributors extending CyberStrikeAI. The project is a Go single-service application with a static frontend, SQLite persistence, Agent/MCP orchestration, and optional high-risk security subsystems.
## Project Layout
```text
cmd/server/ service entrypoint
internal/app/ app wiring, routes, MCP tool registration
internal/handler/ HTTP handlers
internal/database/ SQLite access
internal/security/ auth, rate limits, shell execution
internal/mcp/ MCP server and external MCP manager
internal/multiagent/ Eino single-agent, multi-agent, middleware
internal/workflow/ graph orchestration runtime
internal/knowledge/ indexing and retrieval
internal/c2/ built-in C2
internal/project/ project fact blackboard
web/static/ frontend JS/CSS/assets
web/templates/ HTML templates
tools/ YAML command tools
roles/ role YAML
agents/ multi-agent Markdown definitions
skills/ Agent Skills
docs/ documentation
```
## Development Startup
```bash
go run ./cmd/server --config config.yaml
```
The frontend is static. Most JS/CSS/template changes only require a browser refresh.
## Adding a Business Module
Do not add only a handler. A complete module usually needs:
1. Data model and SQLite migration.
2. Handler: parameters, errors, pagination/filtering.
3. Audit: management actions.
4. Monitor: long-running execution state.
5. MCP: whether Agents should call it.
6. HITL: approval boundary for MCP tools.
7. OpenAPI: update `/api/openapi/spec`.
8. Frontend: i18n, states, empty/error UI.
9. Tests: DB, handler, edge cases.
10. Docs: config, usage, troubleshooting, safety impact.
Missing one of these usually becomes a later usability or safety bug.
## Error Response Design
Prefer stable JSON:
```json
{
"error": "machine_readable_code",
"message": "human-readable explanation"
}
```
Frontend needs stable fields, users need actionable messages, and logs need detailed internal errors.
## Long-Running Tasks
For scanning, indexing, batch tasks, C2, or external operations, answer:
- Can it be cancelled?
- Can progress be queried?
- Can it be retried?
- Where is the result stored?
- Does state survive page refresh?
- Does it block the HTTP request?
If not, use task tables, event streams, or monitoring.
## Extending Tools
Prefer `tools/*.yaml` for command tools. Use Go built-in tools when the tool needs internal state or structured integration.
Built-in tools should define clear input schemas, handle timeouts and errors, and respect HITL for risky actions.
## Frontend Changes
Use existing helpers such as `apiFetch`, modal utilities, notifications, and i18n. Update both `web/static/i18n/zh-CN.json` and `web/static/i18n/en-US.json` for new visible text.
Avoid putting secrets or provider keys in frontend code.
## Test Priority
High-value tests:
- config hot-apply;
- HITL branches;
- shell timeout/no-output;
- external MCP recovery;
- KB indexing and post-processing;
- WebShell OS/encoding detection;
- SQLite migration compatibility.
## Source Anchors
- App wiring: `internal/app/app.go`
- Config apply: `internal/handler/config.go`
- OpenAPI: `internal/handler/openapi.go`
- Tool executor: `internal/security/executor.go`
- Skill package: `internal/skillpackage/`
+54
View File
@@ -0,0 +1,54 @@
# Frontend i18n
[中文](../zh-CN/frontend-i18n.md)
CyberStrikeAI frontend i18n is static and lightweight. Text is organized in JSON files and applied through `data-i18n` attributes plus JavaScript helper functions.
## Files
```text
web/static/i18n/zh-CN.json
web/static/i18n/en-US.json
web/static/js/i18n.js
```
## Key Principles
- Keep keys stable and semantic.
- Update Chinese and English together.
- Do not hardcode new visible text in JS when it should be localized.
- Preserve default HTML text as fallback before JS initialization.
## HTML Usage
```html
<button data-i18n="common.save">保存</button>
```
For attributes, follow the existing `i18n.js` conventions.
## JavaScript Usage
Use the global translation helper where available:
```javascript
const label = t('common.save');
```
When adding dynamic UI, make sure language switching refreshes the text or re-renders the component.
## Migration Workflow
1. Add or update UI text.
2. Add keys to `zh-CN.json`.
3. Add matching keys to `en-US.json`.
4. Replace hardcoded text with `data-i18n` or `t()`.
5. Test both languages and browser console.
## Common Pitfalls
- Missing keys only in one language.
- Dynamic text built from hardcoded fragments.
- Button labels too long in English.
- HTML fallback text diverges from JSON text.
- Adding new page text without updating language switch behavior.
+122
View File
@@ -0,0 +1,122 @@
# Human-in-the-loop (HITL) Best Practices
[中文](../zh-CN/hitl-best-practices.md)
HITL reviews tool calls before an Agent executes them. Use it to control high-risk operations, keep an audit trail, and let an Audit Agent take over routine approvals when human reviewers cannot keep up.
## Where To Configure
Open **System Settings → Human-in-the-loop** in the web UI. You can configure:
- Global default reviewer: `human` or `audit_agent`
- Dedicated Audit Agent model: `hitl.audit_model`
- Resolved audit log retention days
- No-approval tool allowlist: `hitl.tool_whitelist`
- Audit prompts for approval mode and review-edit mode
Example `config.yaml`:
```yaml
hitl:
default_reviewer: human
audit_model:
provider: ""
base_url: ""
api_key: ""
model: "" # set a small model here; blank reuses openai.model
retention_days: 90
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
```
`audit_model` supports partial configuration. Empty fields inherit from the main `openai` config, so the common setup is to fill only `model` and run approvals on a cheaper small model.
## Recommended Approval Strategy
### 1. Start With Humans, Then Delegate Gradually
At the beginning, prefer:
- `default_reviewer: human`
- Only clearly read-only tools in `tool_whitelist`
- Human approval for file writes, command execution, C2 tasks, and WebShell operations
After observing audit logs, move repeated low-risk operations into the allowlist.
### 2. Use A Small Model When Humans Cannot Keep Up
When pending approvals start piling up, switch routine review to the Audit Agent:
```yaml
hitl:
default_reviewer: audit_agent
audit_model:
model: "your-small-reviewer-model"
```
Good candidates for small-model review:
- Read-only queries
- Reconnaissance
- Port and service scans
- Directory enumeration
- Non-destructive validation commands
Keep human review for:
- Deleting, overwriting, or clearing data
- Modifying permissions, passwords, or accounts
- Persistence, lateral movement, and high-risk C2 tasks
- Writes against production targets
### 3. Encode Your Policy In The Prompt
The Audit Agent prompt should describe an operational policy, not just say “be careful.” Make it explicit:
- Which low-risk actions are normally approved
- Which destructive actions must be rejected
- Which cases require escalation to a human
- How review-edit mode may narrow arguments
Example policy snippet:
```text
Approve routine reconnaissance, read-only queries, and port scans by default.
Reject file deletion, database clearing, account or permission changes, persistence, and stopping critical services.
Reject actions outside the user-authorized target scope.
In review-edit mode, you may narrow paths, targets, or command arguments before approving, but must not expand the attack surface.
```
### 4. Keep The Allowlist Conservative
Allowlisted tools skip approval, so keep the list stable and low-risk. Recommended examples:
- `read_file`
- `list_dir`
- `glob`
- `grep`
- `tool_search`
Avoid globally allowlisting:
- Arbitrary shell execution tools
- File write/delete tools
- C2 task tools
- WebShell command execution tools
## Mode Selection
| Mode | Best for |
|------|----------|
| Off | Local labs or fully trusted toolchains |
| Approval | Approve/reject only |
| Review-edit | Let the Audit Agent narrow arguments before approval |
If you configured a small audit model, start with **Approval** mode. Use **Review-edit** only when you want the AI to safely narrow paths, target ranges, or command arguments.
## Operations Tips
- Review **Human-in-the-loop → Audit logs** regularly and tune allowlists/prompts.
- In high-risk environments, keep `default_reviewer: human` and use the Audit Agent only for recommendations.
- If the small-model reviewer fails, CyberStrikeAI rejects conservatively by default.
- After changing `hitl.audit_model`, click **Test audit model** in the settings page.
- For production, customer, or real business systems, keep a human as the final approver.
+107
View File
@@ -0,0 +1,107 @@
# Knowledge Base
[中文](../zh-CN/knowledge-base.md)
The knowledge base turns local security notes, playbooks, vulnerability guides, and organizational standards into retrievable context for Agents.
## Enable
```yaml
knowledge:
enabled: true
base_path: knowledge_base
embedding:
provider: openai
model: text-embedding-v4
database:
knowledge_db_path: data/knowledge.db
```
Keep the knowledge DB separate when you want portable reusable indexes.
## Internal Pipeline
```mermaid
flowchart LR
F["Markdown / Web item"] --> M["Manager"]
M --> C["Chunker"]
C --> E["Embedding"]
E --> V["SQLite Vector Index"]
Q["Agent query"] --> MQ["MultiQuery"]
MQ --> V
V --> R["Rerank"]
R --> P["Post-process"]
P --> A["Agent context"]
```
Quality depends on source structure, chunk size, embedding quality, and rerank behavior.
## Content Writing
Bad:
```text
SQL injection is dangerous. Use sqlmap. Filter input.
```
Better:
```markdown
# MySQL UNION Injection Verification
## Preconditions
- Parameter is concatenated into SELECT.
## Steps
1. Use `order by` to infer column count.
2. Use `union select null,...` to find reflection.
3. Use read-only functions to confirm DB type.
## False Positives
- WAF error page.
- Generic error page.
## Fix
- Parameterized queries.
- Least DB privilege.
```
Structured headings and concrete steps improve chunking and retrieval.
## Tuning
Use a fixed test query set, then change one variable at a time:
- empty results: lower `similarity_threshold`, verify indexing;
- wrong topic: improve titles and category/risk type;
- broken context: tune `chunk_size` and `chunk_overlap`;
- noisy results: raise threshold or fix rerank;
- high cost: lower `multi_query.max_queries`, `prefetch_top_k`, or `top_k`.
## MCP Tools
Enabled KB registers tools such as:
- list risk types;
- search knowledge base.
Prompt roles to query the KB before giving vulnerability validation or remediation advice when unsure.
## Retrieval Logs
Use logs to improve content:
- frequent no-results queries: missing content or synonyms;
- low scores: titles/terms mismatch;
- duplicate hits: merge or categorize docs;
- Agent ignores results: output may be too long or not actionable.
## Source Anchors
- Manager: `internal/knowledge/manager.go`
- Index pipeline: `internal/knowledge/index_pipeline.go`
- Chunking: `internal/knowledge/chunk_eino.go`
- Retriever: `internal/knowledge/retriever.go`
- Eino chain: `internal/knowledge/eino_retrieve_chain.go`
- Rerank: `internal/knowledge/rerank_http.go`
- MCP tools: `internal/knowledge/tool.go`
+86
View File
@@ -0,0 +1,86 @@
# MCP Federation
[中文](../zh-CN/mcp-federation.md)
CyberStrikeAI uses MCP as the primary tool protocol. Tools can be built-in, YAML-backed, Skill-local, or provided by external MCP servers.
## Built-In MCP
The internal MCP server registers:
- YAML command tools;
- security execution tools;
- knowledge tools;
- project fact tools;
- C2 tools;
- WebShell tools;
- batch task tools;
- vision analysis.
Agents usually call these internally without extra setup.
## HTTP MCP
```yaml
mcp:
enabled: true
host: 0.0.0.0
port: 8081
auth_header: "X-MCP-Token"
auth_header_value: "random-secret"
```
Always set an auth value and restrict network access.
## External MCP Lifecycle
1. Register config: name, type, command/URL, environment.
2. Start connection: stdio process or HTTP/SSE client.
3. Pull tool list: names, descriptions, schemas.
4. Expose to Agent: affected by role, tool_search, HITL.
5. Execute: validate args, call, monitor.
6. Recover: handle process/network failure.
7. Stop/delete: remove runtime and config.
Debug by locating the failed step.
## Tool Naming
Good names are stable, specific, and action-object oriented:
```text
burp_send_to_repeater
asset_lookup_domain
cloud_list_public_buckets
```
Avoid:
```text
run
execute
scan
tool1
```
Specific names improve tool_search and reduce misuse.
## Security Review
Before connecting an external MCP, ask:
- Can it read/write local files?
- Can it execute commands?
- What network does it access?
- Does it send data to third parties?
- Are tool descriptions trustworthy?
- Can output contain prompt injection?
- Should it run under a separate OS user or container?
## Source Anchors
- External manager: `internal/mcp/external_manager.go`
- Recovery: `internal/mcp/connection_recovery.go`
- Tool adapter: `internal/einomcp/mcp_tools.go`
- Handler: `internal/handler/external_mcp.go`
- Invoke notification: `internal/einomcp/tool_invoke_notify.go`
+120
View File
@@ -0,0 +1,120 @@
# Plugin Development
[中文](../zh-CN/plugin-development.md)
Plugins live under `plugins/`. The repo ships two reference implementations: **Burp Suite extension** and **Chromium DevTools extension**. Integrations typically use HTTP APIs, MCP servers, or resource packs (tools, roles, Skills, agents).
## Layout
```text
plugins/
README.md
burp-suite/cyberstrikeai-burp-extension/
browser-extension/cyberstrikeai-browser-extension/
```
## Plugin Layers
| Layer | Example | Benefit | Cost |
| --- | --- | --- | --- |
| API plugin | Burp / browser extension calling Agent Stream | simple UI integration | depends on API/auth |
| MCP plugin | exposes tools to Agent | Agent can call it | needs schema and safety design |
| Resource pack | ships tools/roles/skills/agents | simple and versionable | less interactive |
Do not start with MCP unless the Agent must actively call your capability. For “send this HTTP request to AI”, an API plugin is enough.
## Burp Suite Extension
Java extension under `plugins/burp-suite/cyberstrikeai-burp-extension/`. Typical flow: read HTTP from Burp → format prompt → call CyberStrikeAI SSE → show Progress/Final in a Burp tab.
Build: JDK + Gradle/Maven → `bash build-mvn.sh``dist/cyberstrikeai-burp-extension.jar`.
## Browser Extension (Chromium DevTools)
MV3 DevTools extension under `plugins/browser-extension/cyberstrikeai-browser-extension/`. Aligned with the Burp plugin: capture Network traffic → HTTP/1.1 prompt → SSE output. Full docs: `README.md` / `README.zh-CN.md` in that directory.
Load unpacked at `chrome://extensions/`, or `bash package.sh``dist/cyberstrikeai-browser-extension.zip`.
### Auth best practices (browser)
Server `POST /api/auth/login` returns `{ token, expires_at }`. There is **no refresh token** — do not assume silent renewal. Reference: `lib/auth-session.js`, `lib/api.js`, `panel/panel.js`.
| Practice | Description |
| --- | --- |
| Session storage | Store token + `expires_at` in `chrome.storage.session`; never persist password |
| Remaining time | Show `OK · 11h 30m left`; warn when <30min |
| Local check | Re-check `expires_at` + `GET /api/auth/validate` every 30s |
| Server probe | Immediate probe when DevTools panel becomes visible |
| Unreachable | Show warning; keep token during transient outage |
| 401/403 | Clear token (server restart clears in-memory sessions) |
| Before Send | `ensureAuthReady()` before SSE |
| Permissions | `optional_host_permissions` — request origin on Validate |
After extension reload, close DevTools completely and reopen F12 (stale panel context).
### Data and performance (browser)
- Caps: 200 captures/tab, 20 tabs, 512KB progress/run.
- Default XHR/Fetch only; use pause toggle when not capturing.
- Truncate or summarize large bodies before sending to Agent.
## API Integration
- Login: `POST /api/auth/login`, then `GET /api/auth/validate`.
- Persist `expires_at`; re-login when expired (no silent refresh).
- Prefer `/api/eino-agent/stream` or `/api/multi-agent/stream` (SSE).
- Large files: `/api/chat-uploads`, then reference in message.
- Full spec: `/api-docs` or `/api/openapi/spec`.
## API Plugin Payload
Include:
- source tool and context;
- target URL, method, key headers;
- truncation policy for request/response bodies;
- user intent;
- authorization boundary.
Large responses should be uploaded or summarized, not pasted whole into the prompt.
## MCP Schema Design
Bad:
```json
{"cmd":{"type":"string"}}
```
Better:
```json
{
"target_url": {"type":"string","description":"authorized target URL"},
"scan_profile": {"type":"string","enum":["passive","active-safe"]},
"max_requests": {"type":"integer","description":"request limit"}
}
```
Specific schemas make HITL and Agent behavior safer.
## Security Boundaries
Plugins should not bypass platform controls:
- no hidden destructive local commands;
- no plaintext long-lived credentials (password only for login; token in session storage);
- no default third-party data exfiltration;
- no dependency on browser state to bypass login;
- on 401/403, clear session and require re-auth — do not silently retry.
## Source Anchors
- Burp plugin: `plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/`
- Browser extension: `plugins/browser-extension/cyberstrikeai-browser-extension/`
- Auth: `lib/auth-session.js`, `lib/api.js`, `lib/storage.js`
- UI: `panel/panel.js`
- Capture: `devtools.js`, `background/service-worker.js`
- OpenAPI: `internal/handler/openapi.go`
- External MCP: `internal/handler/external_mcp.go`
- Web auth reference: `web/static/js/auth.js`
+67
View File
@@ -0,0 +1,67 @@
# Release Process
[中文](../zh-CN/release-process.md)
Use this guide for maintainers and operators preparing upgrades or releases.
## Pre-Release Checklist
- README and docs updated.
- `config.yaml` sample includes new fields.
- OpenAPI includes new endpoints.
- i18n updated when frontend text changed.
- Security docs updated for high-risk capabilities.
## Release Risk Tiers
| Change | Risk | Must test |
| --- | --- | --- |
| Docs/assets | low | links/rendering |
| Frontend | medium | login, page states, API errors |
| Handler/API | medium | OpenAPI, auth, errors |
| Config struct | high | old config compatibility, ApplyConfig |
| DB schema | high | old DB migration, rollback |
| Agent/MCP/HITL | high | tools, approvals, streaming |
| C2/WebShell/Terminal | critical | authorized lab, audit, disable switch |
Release notes should call out risk, not just features.
## Config Compatibility
New fields should:
- have safe defaults;
- allow old configs to start;
- be documented in sample `config.yaml`;
- not cause Web settings to delete unknown fields;
- be tested via restart and hot-apply paths.
Avoid default-enabling high-risk capabilities.
## Database Changes
SQLite migrations must be:
- compatible with old versions;
- idempotent after interruption;
- careful with nullable/default fields;
- mindful of large indexes and locks;
- documented with backup instructions.
## Build and Test
```bash
go test ./internal/...
go test ./cmd/...
go build -o cyberstrike-ai ./cmd/server
```
Manual smoke:
```text
login -> model test -> new chat -> tools -> HITL -> KB -> external MCP -> C2 enable/disable
```
## Rollback
Restore binary/code, `config.yaml`, and `data/` together. If a new version changed DB schema, replacing only the binary is not a reliable rollback.
+206 -15
View File
@@ -1,8 +1,8 @@
# CyberStrikeAI Robot / Chatbot Guide
[中文](robot.md)
[中文](../zh-CN/robot.md)
This document explains how to chat with CyberStrikeAI from **DingTalk**, **Lark (Feishu)**, and **WeCom (Enterprise WeChat)** using long-lived connections or HTTP callbacks—no need to open a browser on the server. Following the steps below helps avoid common mistakes.
This document explains how to chat with CyberStrikeAI from **personal WeChat**, **DingTalk**, **Lark (Feishu)**, and **WeCom (Enterprise WeChat)** using long-lived connections or HTTP callbacks—no need to open a browser on the server. Following the steps below helps avoid common mistakes.
---
@@ -11,11 +11,14 @@ This document explains how to chat with CyberStrikeAI from **DingTalk**, **Lark
1. Log in to the CyberStrikeAI web UI.
2. Open **System Settings** in the left sidebar.
3. Click **Robot settings** (between “Basic” and “Security”).
4. Enable the platform and fill in credentials (DingTalk: Client ID / Client Secret; Lark: App ID / App Secret).
5. Click **Apply configuration** to save.
6. **Restart the CyberStrikeAI process** (saving alone does not establish the connection).
4. Configure per platform:
- **Personal WeChat**: Open **WeChat / iLink****Generate QR code and bind**, then scan with WeChat (see [Section 3.4](#34-personal-wechat-wechat--ilink))
- **DingTalk**: Enable and fill in Client ID / Client Secret
- **Lark**: Enable and fill in App ID / App Secret
5. Click **Apply configuration** to save (WeChat binding saves and enables automatically on success—usually no extra click needed)
6. **Restart the CyberStrikeAI process** (DingTalk/Lark: saving alone does not establish the connection; WeChat auto-restarts the iLink poll after binding—usually no manual restart needed)
Settings are written to the `robots` section of `config.yaml`; you can also edit the file directly. **After changing DingTalk or Lark config, you must restart for the long-lived connection to take effect.**
Settings are written to the `robots` section of `config.yaml`; you can also edit the file directly. **After changing DingTalk or Lark config, you must restart for the long-lived connection to take effect.** Personal WeChat binding automatically writes `robots.wechat` and restarts the iLink long poll.
---
@@ -23,9 +26,14 @@ Settings are written to the `robots` section of `config.yaml`; you can also edit
| Platform | Description |
|----------------|-------------|
| Personal WeChat| WeChat iLink protocol; scan QR in the web UI to bind, then long-poll for messages—**no public callback URL needed** |
| DingTalk | Stream long-lived connection; the app connects to DingTalk to receive messages |
| Lark (Feishu) | Long-lived connection; the app connects to Lark to receive messages |
| WeCom (Qiye WX)| HTTP callback to receive messages; CyberStrikeAI replies via WeComs message sending API |
| Telegram | Bot API long polling (`getUpdates`); **no public callback URL needed** |
| Slack | Socket Mode (outbound WebSocket); **no public callback URL needed** |
| Discord | Gateway WebSocket; **no public callback URL needed** |
| QQ Bot | QQ Open Platform WebSocket (C2C / group @); **no public callback URL needed** |
Section 3 below describes, per platform, what to do in the developer console and which fields to copy into CyberStrikeAI.
@@ -148,9 +156,125 @@ In **Permission management** (权限管理), enable the following (names and ide
---
### 3.4 Personal WeChat (WeChat / iLink)
> Personal WeChat uses **“web QR binding + iLink long polling”**:
> - Generate a QR code in the CyberStrikeAI web UI → scan and confirm with **WeChat on your phone**;
> - On success, `robots.wechat` in `config.yaml` is updated automatically and iLink long polling starts (the app connects outbound to `ilinkai.weixin.qq.com`);
> - **No** public callback URL on your server and **no** WeChat Open Platform app registration required.
**Personal WeChat vs WeCom**
| Item | Personal WeChat (iLink) | WeCom (Enterprise WeChat) |
|------|-------------------------|---------------------------|
| Use case | Private chat in personal WeChat | Custom app in WeCom |
| Setup | QR scan in web UI | Admin console callback URL + Token |
| Public IP needed? | No (outbound long poll only) | Yes (HTTPS callback reachable by WeCom) |
| Config key | `robots.wechat` | `robots.wecom` |
**Binding steps (in order)**
1. **Log in to CyberStrikeAI web UI**
**System settings****Robot settings** → click the **WeChat / iLink** card.
2. **(Optional) Enable “Enable WeChat robot”**
You can skip this on first bind; it is checked automatically after a successful bind.
3. **Generate QR code**
Click **“Generate QR code and bind”**. The QR code is valid for about **5 minutes**; regenerate if it expires.
4. **Scan and confirm in WeChat**
- Scan the QR code with WeChat on your phone;
- Complete confirmation on the phone;
- If WeChat shows a **pairing code**, enter it on the web page and click **Submit** (only some accounts need this).
5. **Wait for binding to complete**
When the page shows “Binding successful, WeChat robot enabled”, youre done. `bot_token`, `ilink_bot_id`, etc. are saved to `config.yaml` and the iLink poll restarts automatically—**usually no manual service restart**.
6. **Test in WeChat**
Open the **private chat** with the CyberStrikeAI bot in WeChat and send “帮助” (help) or any text.
**Field reference (WeChat)**
| Field | Description |
|-------|-------------|
| Enable WeChat robot | Starts iLink long polling when checked; auto-enabled after bind |
| Generate QR code and bind | Starts the scan-to-bind flow |
| **Advanced** (defaults are fine) | |
| API Base URL | Default `https://ilinkai.weixin.qq.com` |
| Bot Type | Default `3` |
| Bot Agent | Default `CyberStrikeAI/1.0` |
| iLink Bot ID | Filled automatically after bind (read-only) |
**How to use**
- **Private chat only**—send text directly; **no @ needed**.
- Group @-bot is **not** supported (unlike DingTalk/Lark groups).
- **Text messages only**; images, voice, etc. are ignored or not supported.
**Re-bind**
- To bind a different WeChat account, click **“Re-bind”** on the robot settings page and scan again.
- If you see “This WeChat account is already bound”, that account was bound before.
**Common issues**
| Symptom | What to do |
|---------|------------|
| QR code expired | Click “Generate QR code and bind” again (~5 min TTL) |
| Phone asks for a pairing code | Enter the digits shown in WeChat on the web page |
| Bound but no replies | Check logs for `微信 iLink 长轮询已启动` and `微信收到消息`; ensure “Enable WeChat robot” is on |
| No reply after sleep / network drop | Auto-reconnect in ~560 s; restart CyberStrikeAI if still stuck |
| Cannot generate QR code | Ensure outbound HTTPS to `https://ilinkai.weixin.qq.com` |
---
### 3.5 Telegram
> Telegram uses **Bot API long polling** (`getUpdates`): the app connects outbound to `api.telegram.org`—**no public callback URL needed**.
1. Create a bot via **@BotFather** (`/newbot`) and copy the **Bot Token**.
2. CyberStrikeAI → **System settings****Robot settings****Telegram**.
3. Enable, paste the token, optionally allow group @ mentions → **Apply configuration**.
---
### 3.6 Slack
> Slack uses **Socket Mode** (outbound WebSocket): requires **Bot Token (xoxb-)** and **App-Level Token (xapp-)** with `connections:write`.
1. Create an app at [api.slack.com](https://api.slack.com/apps) → enable **Socket Mode**.
2. Create an App-Level Token; install the app to get a Bot Token.
3. Subscribe to `message.im` and `app_mention` events.
4. Paste both tokens in CyberStrikeAI → **Apply configuration**.
---
### 3.7 Discord
> Discord uses **Gateway WebSocket**—**no public callback URL needed**.
1. [Discord Developer Portal](https://discord.com/developers/applications) → create app → **Bot** → copy **Token**.
2. Enable **Message Content Intent** under Privileged Gateway Intents.
3. Invite the bot with `Send Messages` permission.
4. Paste token in CyberStrikeAI; optionally allow guild @ mentions → **Apply configuration**.
---
### 3.8 QQ Bot
> QQ Bot uses **QQ Open Platform WebSocket** (official `botgo` SDK) for C2C and group @—**no public callback URL needed**.
1. Create a bot at [q.qq.com](https://q.qq.com) → get **App ID** and **Client Secret**.
2. Add sandbox testers before going live.
3. Subscribe to C2C and group @ events (WebSocket).
4. Fill in CyberStrikeAI; use **Sandbox** for testing → **Apply configuration**.
---
## 4. Bot commands
Send these **text commands** to the bot in DingTalk or Lark (text only):
Send these **text commands** to the bot on any connected platform (text only):
| Command | Description |
|---------|-------------|
@@ -172,15 +296,24 @@ Any other text is sent to the AI as a user message, same as in the web UI (e.g.
## 5. How to use (do I need to @ the bot?)
- **Direct chat (recommended)**: In DingTalk or Lark, **search for the bot and open a direct chat**. Type “帮助” or any message; **no @ needed**.
- **Group chat**: If the bot is in a group, only messages that **@ the bot** are received and answered; other group messages are ignored.
- **Personal WeChat**: Send directly in the **private chat** with the bot; **no @ needed** (group chat not supported).
- **DingTalk / Lark direct chat (recommended)**: **Search for the bot and open a direct chat**. Type “帮助” or any message; **no @ needed**.
- **DingTalk / Lark group chat**: If the bot is in a group, only messages that **@ the bot** are received and answered; other group messages are ignored.
Summary: **Direct chat**just send; **in a group**@ the bot first, then send.
Summary: **Personal WeChat and direct chat**just send; **DingTalk/Lark in a group**@ the bot first, then send.
---
## 6. Recommended flow (so you dont skip steps)
**Personal WeChat (simplest—no open platform)**
1. CyberStrikeAI web UI → System settings → Robot settings → **WeChat / iLink****Generate QR code and bind**.
2. Scan with WeChat and confirm (enter pairing code on the web page if prompted).
3. After binding, send “帮助” in the WeChat private chat to test.
**DingTalk / Lark**
1. **In the open platform**: Complete app creation, copy credentials, enable the bot (DingTalk: **Stream mode**), set permissions, and publish (Section 3).
2. **In CyberStrikeAI**: System settings → Robot settings → Enable the platform, paste Client ID/App ID and Client Secret/App Secret → **Apply configuration**.
3. **Restart the CyberStrikeAI process** (otherwise the long-lived connection is not established).
@@ -196,6 +329,14 @@ Example `robots` section in `config.yaml`:
```yaml
robots:
wechat: # Personal WeChat iLink (auto-filled after QR bind; usually no manual edit)
enabled: true
bot_token: "your_bot_token@im.bot:..."
ilink_bot_id: "your_bot_id@im.bot"
ilink_user_id: "your_user_id@im.wechat"
base_url: "https://ilinkai.weixin.qq.com"
bot_type: "3"
bot_agent: "CyberStrikeAI/1.0"
dingtalk:
enabled: true
client_id: "your_dingtalk_app_key"
@@ -205,9 +346,33 @@ robots:
app_id: "your_lark_app_id"
app_secret: "your_lark_app_secret"
verify_token: ""
wecom:
enabled: false
corp_id: ""
agent_id: 0
token: ""
encoding_aes_key: ""
secret: ""
telegram:
enabled: false
bot_token: ""
allow_group_messages: false
slack:
enabled: false
bot_token: ""
app_token: ""
discord:
enabled: false
bot_token: ""
allow_guild_messages: false
qq:
enabled: false
app_id: ""
client_secret: ""
sandbox: true
```
**Restart the app** after changes; the long-lived connection is created at startup.
After changing DingTalk/Lark/WeCom/Telegram/Slack/Discord/QQ settings, **Apply configuration** restarts the corresponding connections. Personal WeChat QR binding saves and restarts automatically.
---
@@ -232,7 +397,30 @@ API: `POST /api/robot/test` (requires login). Body: `{"platform":"optional","use
---
## 9. DingTalk: no response when sending messages
## 9. Troubleshooting: no response when sending messages
### 9.1 Personal WeChat
Check in this order:
1. **Binding completed?**
Robot settings should show “Connected” or a bound Bot ID; `robots.wechat.bot_token` in `config.yaml` must not be empty.
2. **Enabled?**
Confirm “Enable WeChat robot” is checked; restart CyberStrikeAI if you just changed settings.
3. **Application logs**
- On startup: `微信 iLink 长轮询已启动`;
- After sending a message: `微信收到消息`; if missing, binding may have failed or `bot_token` is invalid—try **Re-bind**.
- `微信 iLink 长轮询异常,将自动重连`: wait for auto-reconnect or restart.
4. **Network**
The server must reach `https://ilinkai.weixin.qq.com` (outbound HTTPS). If QR generation fails, check this first.
5. **After sleep or network drop**
Same as DingTalk/Lark: **auto-reconnect** in ~560 s; restart if still no response.
### 9.2 DingTalk
Check in this order:
@@ -257,8 +445,10 @@ Check in this order:
## 10. Common pitfalls
- **Personal WeChat vs WeCom**: Personal WeChat uses `robots.wechat` + web QR bind; WeCom uses `robots.wecom` + admin callback URL—they are completely different.
- **WeChat QR expired**: QR codes last ~5 minutes; regenerate instead of reusing an old one.
- **Wrong bot type**: The “Custom” bot added in a DingTalk **group** (Webhook + sign secret) **cannot** be used for two-way chat. Only the **enterprise internal app** bot from the open platform is supported.
- **Saved but not restarted**: After changing robot settings in CyberStrikeAI you **must restart** the app, or the long-lived connection will not be established.
- **Saved but not restarted**: After changing DingTalk/Lark robot settings you **must restart** the app (WeChat QR bind restarts the connection automatically).
- **Client ID typo**: If the platform shows `504`, use `504` (not `5o4`); prefer copy/paste.
- **DingTalk: only HTTP callback, no Stream**: This app receives messages via **Stream**. In the open platform, message reception must be **Stream mode**.
- **App not published**: After changing the bot or permissions in the open platform, **publish a new version** under “Version management and release”, or changes wont apply.
@@ -267,6 +457,7 @@ Check in this order:
## 11. Notes
- DingTalk and Lark: **text messages only**; other types (e.g. image, voice) are not supported and may be ignored.
- All platforms: **text messages only**; other types (e.g. image, voice) are not supported and may be ignored.
- Personal WeChat: **private chat only**—group @-bot is not supported.
- Conversations are shared with the web UI: conversations created from the bot appear in the web “Conversations” list and vice versa.
- Bot execution uses the same logic as **`/api/agent-loop/stream`** (progress callbacks, process details stored in the DB); only the final reply is sent back to DingTalk/Lark in one message (no SSE to the client).
- Bot execution uses the same **Eino single/multi-agent** path as the web UI (`ProcessMessageForRobot`, with progress callbacks and process details stored in the DB); only the final reply is sent back to personal WeChat/DingTalk/Lark/WeCom in one message (no SSE). Default: `robot_default_agent_mode: eino_single`.
+188
View File
@@ -0,0 +1,188 @@
# Runbooks
[中文](../zh-CN/runbooks.md)
Runbooks are task-oriented procedures you can follow during real operations.
## Runbook 1: Production Instance from Zero to Ready
Use for first-time internal or production red-team deployment.
For local or temporary verification, start with the bundled script:
```bash
chmod +x run.sh && ./run.sh
```
After it is verified, decide whether to move to systemd plus reverse proxy for long-running deployment.
### Preconditions
- Host is managed as an asset.
- Access path is decided: internal network, VPN, bastion, or reverse proxy.
- Model API key and model are available.
- C2, WebShell, and external MCP policy is decided.
### Steps
1. Prepare directory:
```bash
mkdir -p /opt/CyberStrikeAI
```
2. Place binary and resources:
```text
cyberstrike-ai
web/
tools/
roles/
skills/
agents/
docs/
config.yaml
```
3. Set baseline config:
```yaml
auth:
password: "<long-random-password>"
server:
host: 127.0.0.1
port: 8080
tls_enabled: false
audit:
enabled: true
c2:
enabled: false
```
4. Configure HTTPS at the reverse proxy and restrict source IPs.
5. Run with systemd.
6. Login and test the model.
7. Check tools and audit logs.
8. Create backup policy.
### Acceptance
- `/api/auth/validate` succeeds after login.
- Model test passes.
- Tools load.
- Audit shows login.
- C2 is disabled when not needed.
## Runbook 2: Connect External MCP
### Preconditions
- MCP service is trusted.
- You know whether it can read/write files, execute commands, or access networks.
- Transport is chosen: stdio, HTTP, or SSE.
### Steps
1. Add service in External MCP page.
2. For stdio, configure command, args, cwd, and env.
3. For HTTP/SSE, configure URL and auth.
4. Start service.
5. Check `/api/external-mcp/stats`.
6. Confirm tools and schemas.
7. Execute one low-risk tool call.
8. Keep high-risk tools out of global allowlist.
### Acceptance
- MCP status is running.
- Tool schemas are visible.
- Agent can find tools through `tool_search`.
- Monitor records tool execution.
- Audit records config change.
## Runbook 3: Enable and Tune Knowledge Base
### Steps
1. Enable config:
```yaml
knowledge:
enabled: true
base_path: knowledge_base
retrieval:
top_k: 5
similarity_threshold: 0.4
```
2. Put Markdown files under `knowledge_base/`.
3. Scan directory.
4. Rebuild index.
5. Prepare 5-10 fixed test queries.
6. Search and record hits.
7. Tune threshold, top_k, chunking, and document titles.
### Acceptance
- Index status is complete.
- Common queries hit correct docs.
- Agent consults KB when uncertain.
- Retrieval logs show query and hit docs.
## Runbook 4: Authorized Web Test Workflow
1. Create project and record scope.
2. Start conversation and bind project.
3. Choose minimal role.
4. State target, time window, and prohibited actions.
5. Start with read-only recon.
6. Record useful leads as project facts.
7. Use HITL for risky validation.
8. Save confirmed issues to vulnerability management.
9. Generate attack-chain/report material.
10. Clean uploads, workspace, and unnecessary execution logs.
Acceptance:
- Each vulnerability has evidence, impact, reproduction, and fix.
- Risky actions have HITL records.
- Project facts reconstruct the path.
- Report excludes unrelated sensitive data.
## Runbook 5: C2 Cleanup After Exercise
1. Stop all listeners.
2. List sessions and confirm no authorized session remains active.
3. Export required task results.
4. Delete or archive payloads.
5. Delete stale tasks, events, and files.
6. Review C2 audit trail.
7. Write key results to project facts or report.
8. Set `c2.enabled: false` unless continuously needed.
Acceptance:
- No running listener.
- No pending task.
- Payloads are not publicly downloadable.
- Audit/report explains the lifecycle.
## Runbook 6: Agent Does Not Call a Tool
Check in order:
1. Role includes the tool.
2. Tool appears in `/api/config/tools`.
3. `tool_search` is not hiding it.
4. Tool name and description are clear.
5. HITL is not pending.
6. Agent is not in final summarization phase.
7. Sub-agent does not have a narrower tool list.
Fix:
- add tool to role;
- improve `short_description`;
- add to `tool_search_always_visible_tools`;
- prompt when to use it;
- inspect process details and monitor records.
+130
View File
@@ -0,0 +1,130 @@
# Security Hardening
[中文](../zh-CN/security-hardening.md)
This checklist covers pre-production and continuous hardening for CyberStrikeAI.
## Before Going Live
- Change `auth.password` to a long random secret.
- Use HTTPS or a trusted reverse proxy.
- Restrict access by IP, VPN, or bastion.
- Enable `audit.enabled`.
- Set `c2.enabled: false` when C2 is not required.
- Do not expose standalone HTTP MCP without strong auth and network isolation.
- Connect only trusted external MCP services.
- Back up `config.yaml`, `data/`, and custom resource directories.
## Reverse Proxy Baseline
```nginx
client_max_body_size 200m;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
Recommended security headers:
```nginx
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy no-referrer;
add_header X-Frame-Options DENY;
```
## HITL Allowlist Baseline
Minimal allowlist:
```yaml
hitl:
tool_whitelist:
- read_file
- glob
- grep
- tool_search
```
Do not globally allowlist:
- `execute`;
- WebShell write/execute tools;
- C2 task/payload tools;
- high-risk external MCP tools;
- delete, write, upload, persistence tools.
## File Permissions
```bash
chmod 600 config.yaml
chmod 700 data
```
Run under a dedicated OS user. Avoid root unless explicitly required.
## External MCP Review
Before connecting:
- Can it execute commands?
- Can it read/write local files?
- Does it send data to third parties?
- Does it authenticate?
- Can output contain untrusted model/web content?
- Should it run in a container or separate user?
After connecting:
- keep high-risk tools out of allowlist;
- review tool list changes;
- audit config changes.
## C2 and WebShell
C2:
- disabled by default;
- enabled only during authorized window;
- listener ports separated from admin UI;
- cleanup payloads, sessions, tasks, and events.
WebShell:
- authorized targets only;
- clear naming;
- write/delete/execute requires approval;
- delete connections after project end.
## Retention
Suggested:
- audit: 30-90 days;
- monitor: 90-180 days;
- uploads: clean after project;
- C2/WebShell outputs: keep only report evidence;
- knowledge base: no real credentials or customer secrets.
## Periodic Review
Weekly:
- failed logins and unusual IPs;
- config changes;
- external MCP changes;
- long-running tools;
- unexpected C2 enablement;
- stale WebShell connections;
- disk and DB size.
Project closeout:
- clean temp workspaces;
- delete unnecessary uploads;
- archive evidence;
- delete stale WebShell/C2 resources;
- export audit records.
+72
View File
@@ -0,0 +1,72 @@
# Security Model
[中文](../zh-CN/security-model.md)
CyberStrikeAI is not a generic chatbot. It is a high-privilege security automation system with command execution, MCP tools, WebShell management, optional C2, batch tasks, and multi-agent orchestration.
## Trust Boundaries
Main actors:
- Web user: can chat, change settings, manage resources, and trigger tools.
- Agent: selects tools based on role, context, and middleware.
- MCP tools: may access files, run commands, call services, or touch targets.
- External MCP: third-party local or remote tool providers.
- Robot callbacks: platform-authenticated message ingress outside Web login.
Anyone who can log into the Web UI should be treated as an operator of the instance.
## Threat Model
| Threat | Path | Impact | Controls |
| --- | --- | --- | --- |
| Password leak | login, then use terminal/WebShell/C2 | platform takeover | strong password, HTTPS, internal network, audit |
| Prompt injection | target content instructs Agent to misuse tools | unauthorized actions | role boundaries, HITL, least tools |
| Malicious MCP | external tool lies or has side effects | host/target impact | trusted MCP only, isolation |
| Tool YAML tampering | command template changed | malicious execution | file permissions, review |
| C2 misuse | payload or task against unauthorized target | legal and business risk | disabled by default, approvals |
| WebShell misuse | destructive command on business host | outage/data loss | naming, read-only first, HITL |
| DB leak | copy `data/*.db` or uploads | sensitive target data | permissions, encrypted backups |
## HITL Is Not Magic
HITL sees a tool name, arguments, and context. It does not always see real-world impact. Be conservative when:
- a harmless-looking command wraps `bash -c` or base64;
- the MCP tool description is untrusted;
- WebShell target identity is vague;
- C2 payload delivery happens outside the platform;
- a read-only tool can still create traffic or side effects.
Audit Agent is useful for routine checks, not for replacing humans on destructive operations.
## Data Minimization
Avoid long-term storage of:
- real customer credentials;
- raw production data;
- long-lived cookies;
- unrelated scan output;
- stale WebShell or C2 sessions.
Project closeout should include cleanup of uploads, WebShell connections, C2 payloads, temporary workspaces, and bulky execution logs.
## Production Baseline
- Strong password and HTTPS.
- Internal/VPN/proxy restricted access.
- `audit.enabled: true`.
- Random `mcp.auth_header_value` when HTTP MCP is exposed.
- `c2.enabled: false` unless required.
- Minimal external MCP.
- No high-risk tools in global allowlist.
## Source Anchors
- Sessions: `internal/security/auth_manager.go`
- Auth middleware: `internal/security/auth_middleware.go`
- Rate limiting: `internal/security/ratelimit.go`
- Shell execution: `internal/security/executor.go`
- HITL execution: `internal/handler/hitl_execution.go`
- Audit service: `internal/audit/service.go`
+70
View File
@@ -0,0 +1,70 @@
# Skills Guide
[中文](../zh-CN/skills-guide.md)
Skills provide reusable procedures, checklists, templates, and references that Agents can load when needed. A Skill should be an executable procedure, not an encyclopedia page.
## Structure
```text
skills/
ssrf-testing/
SKILL.md
REFERENCE.md
```
`SKILL.md` front matter:
```markdown
---
name: ssrf-testing
description: SSRF identification, validation, bypass, and remediation workflow
---
```
The description determines when the Agent loads it.
## Recommended Sections
```markdown
## When to use
## Preconditions
## Procedure
## Stop conditions
## Output
```
Stop conditions matter: they tell the Agent when to escalate, ask for approval, or stop expanding scope.
## Anti-Patterns
| Anti-pattern | Result | Fix |
| --- | --- | --- |
| Description too broad | triggers too often | make it scenario-specific |
| Encyclopedia content | Agent lacks next step | write procedures and decisions |
| Secrets in Skill | leakage/misuse | use runtime config or user input |
| One huge Skill | costly and noisy | split by task/vulnerability |
| No stop condition | scope creep | define approval/stop rules |
## Skill vs Knowledge Base
- Skill: how to do something.
- Knowledge base: facts, references, cases.
For SSRF, a Skill describes the test procedure; the KB stores metadata addresses, bypass cases, and remediation references.
## Local Tool Risk
`filesystem_tools: true` exposes local read/write/execute capability. In production:
- constrain workspace;
- require HITL for write/execute;
- do not globally allowlist `execute`;
- make Skills explicitly avoid out-of-scope files.
## Source Anchors
- Validation: `internal/skillpackage/validate.go`
- Service: `internal/skillpackage/service.go`
- Eino Skills: `internal/multiagent/eino_skills.go`
- Handler: `internal/handler/skills.go`
+78
View File
@@ -0,0 +1,78 @@
# Testing Guide
[中文](../zh-CN/testing.md)
Testing CyberStrikeAI means more than running Go tests. Agent, MCP, HITL, C2, WebShell, and frontend streaming all have different failure modes.
## Commands
```bash
go test ./internal/...
go test ./cmd/...
go build -o cyberstrike-ai ./cmd/server
```
Run focused packages when working locally:
```bash
go test ./internal/multiagent
go test ./internal/handler
go test ./internal/security
```
## Test Pyramid
| Layer | Goal | Example |
| --- | --- | --- |
| Unit | pure logic | expressions, chunking, sanitization |
| Handler | HTTP behavior | validation, auth, status codes |
| Integration | module cooperation | external MCP, KB indexing, HITL |
| Smoke | user path | login, chat, tools, settings |
| Authorized lab | high-risk features | C2, WebShell, terminal |
Do not use end-to-end manual testing as a substitute for unit tests, or unit tests as a substitute for high-risk lab validation.
## Regression Focus
Expand testing when changing:
- `internal/handler/config.go`: model, KB, MCP, C2, robot apply paths;
- `internal/multiagent/`: streaming, tool calls, summarization, retry, HITL;
- `internal/security/`: auth, shell, timeout, no-output;
- `internal/database/`: old data compatibility;
- `web/static/js/chat.js`: chat, process details, attack chain, groups.
## Test Data
Avoid real customer data. Prepare:
- small Markdown KB sample;
- fake local MCP server;
- controlled local HTTP target;
- harmless WebShell simulator;
- temporary SQLite DB.
## Failure Cases
Cover:
- model API 401/429/500;
- MCP startup failure;
- tool timeout;
- HITL rejection;
- interrupted KB indexing;
- unwritable database;
- WebShell non-200 response;
- C2 disabled endpoint access.
## Source Anchors
Existing tests live across:
- `internal/handler/*_test.go`
- `internal/multiagent/*_test.go`
- `internal/workflow/*_test.go`
- `internal/knowledge/*_test.go`
- `internal/security/*_test.go`
- `internal/mcp/*_test.go`
- `internal/c2/*_test.go`
+98
View File
@@ -0,0 +1,98 @@
# Troubleshooting
[中文](../zh-CN/troubleshooting.md)
Debug by layer. Do not change random config before locating the failing layer.
## Diagnostic Order
1. Process: is the service alive, any panic?
2. Network: port, HTTPS, reverse proxy, browser console.
3. Auth: does `/api/auth/validate` return 200?
4. Config: can `/api/config` be read and applied?
5. Model: does model test pass?
6. Tools: do tool list and schemas look right?
7. Database: is `data/` writable, any lock?
8. Subsystem: KB, MCP, C2, WebShell minimal action.
## Minimal Commands
```bash
lsof -i :8080
curl -k -I https://127.0.0.1:8080/
curl -k -I https://127.0.0.1:8080/static/logo.png
ls -lh data/
```
If a reverse proxy is involved, test both proxy address and upstream address.
## Common Issues
Page inaccessible:
- wrong protocol, especially HTTPS vs HTTP;
- self-signed cert warning;
- port occupied;
- reverse proxy loop.
Login fails:
- wrong `auth.password`;
- config not applied/restarted;
- stale cookie;
- audit throttling repeated failures.
Model fails:
- wrong `base_url` path;
- invalid API key;
- model unavailable;
- reasoning fields unsupported by gateway. Try `openai.reasoning.mode: off`.
Streaming stalls:
- proxy buffers SSE;
- model gateway timeout;
- context too large;
- browser/network interruption.
Tool fails:
- real command not installed;
- YAML schema wrong;
- HITL rejected or pending;
- timeout or no-output timeout.
Knowledge base empty:
- `knowledge.enabled` false;
- scan/index not run;
- embedding API failed;
- threshold or risk type too strict.
C2 returns 503:
- expected when `c2.enabled: false`.
## Common Misdiagnoses
- "Model is broken": HITL is waiting.
- "Tool missing": tool_search hides it from current context.
- "Knowledge base useless": index not rebuilt or risk type too narrow.
- "Config saved but ineffective": listener/TLS changes need restart.
- "Robot silent": platform callback or signature config wrong.
## Issue Template
```text
Version:
Startup method:
Access path:
Relevant config:
Steps:
Expected:
Actual:
Server logs:
Browser console:
API response:
```
+68
View File
@@ -0,0 +1,68 @@
# WebShell Management
[中文](../zh-CN/webshell.md)
WebShell management stores authorized WebShell connections and allows command/file operations through the UI and Agent tools.
## Workflow
1. Add a connection.
2. Fill URL, parameter/password, and metadata.
3. Test connectivity.
4. Run read-only identification commands first.
5. Let AI assist only after selecting the correct connection.
Connections are stored in SQLite.
## Operation Tiers
| Tier | Operation | Risk | Guidance |
| --- | --- | --- | --- |
| Identify | `whoami`, `pwd`, OS version | low | may automate |
| Enumerate | dirs, processes, env vars | medium | constrain path/command |
| Read | config, logs, source | medium-high | human confirms sensitivity |
| Write/execute | write, run script, delete | high | human approval and rollback |
Having a WebShell does not make follow-up operations low risk.
## Naming
Use:
```text
<project>-<environment>-<target>-<privilege>-<date>
```
Example:
```text
acme-staging-web01-www-20260707
```
Avoid vague names like `test`, `shell1`, or `customer machine`.
## AI Guardrail Prompt
```text
Before using WebShell, confirm connection_id, target name, current directory, and privilege. Default to read-only commands. Any write, delete, upload, permission change, persistence, credential access, or internal probing requires purpose, impact, rollback plan, and approval.
```
## MCP Tools
Typical tools:
- `webshell_exec`
- `webshell_file_list`
- `webshell_file_read`
- `webshell_file_write`
- connection management tools
Do not put write/execute tools in a global allowlist.
## Source Anchors
- Handler: `internal/handler/webshell.go`
- Context: `internal/handler/webshell_context.go`
- Probe: `internal/handler/webshell_probe.go`
- Encoding/OS tests: `internal/handler/webshell_encoding_test.go`, `internal/handler/webshell_os_test.go`
- Tool registration: `internal/app/app.go`
+553
View File
@@ -0,0 +1,553 @@
# CyberStrikeAI Graph Orchestration Guide
[中文](../zh-CN/workflow-graph.md)
This document explains how to use **Graph Orchestration**: building workflows on the canvas, configuring node types, passing data between nodes, and binding a graph to a role for automatic execution.
---
## 1. Where to find Graph Orchestration
1. Log in to the CyberStrikeAI web UI.
2. Open **Graph Orchestration** in the left sidebar.
3. Select an existing workflow from the list, or create a new one.
4. Drag nodes, draw edges, and configure properties on the canvas.
5. Fill in **ID**, **Name**, and **Description**, then click **Save**.
Saved workflows can be bound to a role under **Role Management**. When `workflow_policy` is `auto`, chatting with that role runs the bound graph automatically.
---
## 2. Canvas basics
| Action | Description |
|--------|-------------|
| Add node | Click a node type button above the canvas (Start, Tool, Agent, Condition, HITL, Output, End) |
| Connect | Click **Connect**, then click source and target nodes; click **Connect** again to exit connect mode |
| Select | Click a node or edge; properties appear in the right panel |
| Delete selected | Remove the current node or edge |
| Auto layout | Rearrange node positions |
| Dry run | Safely simulate data flow; Tool, Agent, and HITL nodes are not executed for real |
| Delete workflow | Remove the entire workflow definition |
**Hard requirements:** Every workflow needs at least **one Start node** and **one Output node**. Start nodes must not have incoming edges; Output / End nodes must not have outgoing edges. Both frontend and backend run strict validation before save.
---
## 3. Execution model (read this before configuring)
The engine executes the workflow as a **directed graph**, starting from the **Start** node and following edges to downstream nodes.
During a run, the engine keeps internal state. Template expressions `{{...}}` read from that state:
| Internal state | Template prefix | Meaning |
|----------------|-----------------|---------|
| `inputs` | `{{inputs.xxx}}` | Workflow inputs at start (user message, conversation ID, etc.) |
| `lastOutput` | `{{previous.xxx}}` | Output of the **most recently executed** node |
| `outputs` | `{{outputs.xxx}}` | Global **named variable pool** (written by nodes with an output key) |
| `nodeOutputs` | `{{nodeId.xxx}}` | Full output object of a specific node ID |
| `metrics` | available in run details | Node duration, tool call count, and usage/cost metrics when reported |
### 3.1 What is `previous`?
`{{previous.output}}` is the `output` field of the **immediately preceding executed node**.
- After every node finishes, the engine updates `lastOutput`.
- It is **not** “the node drawn upstream on the canvas”; it is **the previous step in actual execution order**.
Example:
```text
Start → Agent A → Agent B
```
For Agent B, `{{previous.output}}` = Agent As output.
With a condition in between:
```text
Start → Agent A → Condition → Agent B
```
For Agent B, `{{previous.output}}` = the **condition node** output (`true` / `false`), **not** Agent As result.
If a node has **multiple upstream nodes**, `previous` is built by that nodes **join strategy** first:
| Join strategy | Meaning | Use case |
|---------------|---------|----------|
| `all_merge` | Merge all upstream outputs; `previous.output` is an array | Default; aggregate multiple results |
| `last_by_canvas` | Use the last upstream output by canvas order | Explicitly use one branch |
| `first_non_empty` | Use the first non-empty output | Fallback chains |
| `fail_fast` | Stop the node if any upstream failed | Critical gates, approval prechecks, safety checks |
### 3.2 What is `outputs`?
`outputs` is a **named variable registry** maintained by the engine during execution.
When an Agent, Tool, or Output node sets an **Output variable name** (`output_key`), the result is stored as:
```text
outputs["your_variable_name"] = node_output
```
Any downstream node can then reference it via `{{outputs.variable_name}}`, even if other nodes sit in between.
Example:
- Agent A **Output variable name**: `agent_result1`
- Agent B **Input source**: `{{outputs.agent_result1}}`
Agent B still receives Agent As output even when a condition node lies between them.
### 3.3 When to use `previous` vs `outputs`
| Scenario | Recommended |
|----------|-------------|
| Two nodes are **directly connected**; you only need the last step | `{{previous.output}}` |
| Other nodes sit in between (condition, tool, HITL, etc.) | `{{outputs.variable_name}}` |
| Reference output from an **earlier** node | `{{outputs.variable_name}}` or `{{nodeId.output}}` |
| Condition should test an Agents output | `{{outputs.variable_name}} != ""` |
| Read the original user input | `{{inputs.message}}` |
**Rule of thumb:**
- `previous` = last step (chained, adjacent)
- `outputs` = by name (cross-node, look back)
---
## 4. Template syntax
### 4.1 Basic format
```text
{{path.to.value}}
```
Allowed characters in paths: letters, digits, underscore, dot, hyphen. Examples:
```text
{{previous.output}}
{{outputs.agent_result1}}
{{inputs.message}}
{{inputs.conversationId}}
{{previous.matched}}
{{node-abc123.output}}
```
### 4.2 Available paths
| Path | Description |
|------|-------------|
| `{{inputs.message}}` | User message (Start node input) |
| `{{inputs.conversationId}}` | Conversation ID |
| `{{inputs.projectId}}` | Project ID |
| `{{previous.output}}` | Primary output of the previous node |
| `{{previous.matched}}` | Match result of the previous condition node (`true` / `false`) |
| `{{outputs.variable_name}}` | Named output registered by a node |
| `{{nodeId.output}}` | `output` field of the node with that ID |
| `{{previous.kind}}` | Previous node output kind, e.g. `agent` / `tool` / `condition` |
| `{{previous.status}}` | Previous node status, e.g. `completed` / `failed` / `simulated` |
Node outputs keep compatibility fields such as `output` and `matched`, and also include a structured envelope:
```json
{
"kind": "agent",
"node_id": "node-2",
"node_type": "agent",
"status": "completed",
"output": "..."
}
```
### 4.3 Condition expressions
Condition nodes and edge conditions support comparisons, text matching, regex, logical operators, and safe JSONPath/JQ path reads:
```text
{{outputs.agent_result1}} != ""
{{previous.output}} == "ok"
{{outputs.count}} >= 100
{{previous.output}} contains "success"
{{previous.output}} matches "^ok"
{{outputs.risk_score}} >= 8 && {{previous.output}} != ""
jsonpath({{previous.output}}, "$.status") == "ok"
jq({{outputs.scan}}, ".severity") == "high"
```
Rules:
- Operators: `==`, `!=`, `>`, `>=`, `<`, `<=`
- `contains` checks substrings; `matches` checks regular expressions
- Simple `&&` / `||` is supported
- `jsonpath(value, "$.path")` and `jq(value, ".path")` support a **safe path-only subset**; no arbitrary script execution
- Leading/trailing spaces and quotes are trimmed before comparison
- Without a comparator, non-empty values that are not `false`, `0`, or `null` are treated as true
- Expressions, regexes, and JSONPath/JQ paths are statically validated before save
### 4.4 Nested field binding
Field bindings can read ordinary fields such as `output` or `message`, and also JSONPath/JQ-style paths:
| Binding | Meaning |
|---------|---------|
| `from=previous, field=$.status` | Read `status` from previous output |
| `from=outputs, field=$.scan.severity` | Read a nested field from named outputs |
| `from=node-1, field=.output.items[0]` | Read an array element from a specific node output |
---
## 5. Node types and configuration
### 5.1 Start
Workflow entry point; injects user input into `inputs`.
| Field | Description | Default |
|-------|-------------|---------|
| Input keys | Comma-separated input key names | `message, conversationId, projectId` |
Start node output includes: `output`, `message`, `conversationId`, `projectId`.
### 5.2 Agent
Runs an LLM Agent task. Supports multiple modes.
| Field | Description | Default |
|-------|-------------|---------|
| Agent mode | `eino_single` / `deep` / `plan_execute` / `supervisor` | `eino_single` |
| Input source | Template for upstream data | `{{previous.output}}` |
| Node instruction | Task description for this node | empty |
| Output variable name | Key written into `outputs` | `agent_result` |
| Join strategy | How to build `previous` when multiple upstreams enter this node | `all_merge` |
**Message assembly:**
- Instruction only → send instruction to the Agent
- Input source only → “Continue based on upstream output: …”
- Both → combined “upstream input + node instruction”
After execution:
- `previous.output` becomes this nodes response text
- If **Output variable name** is set, the value is also stored in `outputs[variable_name]`
- In the Eino graph, the Agent node is split into `prepare → execute → finalize` for clearer trace and future checkpointing
### 5.3 Tool
Calls an enabled MCP tool.
| Field | Description | Default |
|-------|-------------|---------|
| MCP tool | Tool name (required) | — |
| Argument template | JSON with `{{...}}` templates | `{}` |
| Timeout (seconds) | Optional | empty |
| Join strategy | How to build `previous` when multiple upstreams enter this node | `all_merge` |
Example argument template:
```json
{"target": "{{inputs.message}}", "port": "443"}
```
If an output variable name is configured, the tool result is written to `outputs`.
### 5.4 Condition
Evaluates an expression and outputs `matched` (`true` / `false`).
| Field | Description | Default |
|-------|-------------|---------|
| Expression | Supports `{{...}}` and `==` / `!=` | `{{previous.output}} != ""` |
| Join strategy | How to build `previous` when multiple upstreams enter this node | `all_merge` |
**Branching rules:**
- The **first outgoing edge** defaults to the **“yes”** branch (`matched == true`)
- The **second outgoing edge** defaults to the **“no”** branch (`matched == false`)
- Edge labels such as `是` / `否` (or `yes` / `no`, `true` / `false`) help identify branches
- A third or later edge needs a custom **edge condition**
Edge condition examples (select an edge, configure in the right panel):
```text
{{previous.matched}} == "true"
{{previous.matched}} == "false"
```
### 5.5 HITL (human-in-the-loop)
Human approval checkpoint. The run pauses before this node through Eino interrupt/checkpoint and resumes after approval via API or the monitor panel.
| Field | Description | Default |
|-------|-------------|---------|
| Prompt | Supports templates | `Please approve before continuing` |
| Prompt binding | If prompt text is empty, read approval text from a bound field | `previous.output` |
| Reviewer | `human` / `audit_agent` | `human` |
| Join strategy | How to build `previous` when multiple upstreams enter this node | `all_merge` |
Pending HITL metadata records:
- `checkpointId`
- interrupt `beforeNodes`
- resume target / address / path
- resume payload schema (`approved`, `comment`)
### 5.6 Output
Writes the final workflow result into `outputs` for summary and chat display.
| Field | Description | Default |
|-------|-------------|---------|
| Output variable name | Required key for the final result | `result` |
| Variable source | Template deciding what to write | `{{previous.output}}` |
| Static output value | Optional; overrides variable source when set | empty |
| Join strategy | How to build `previous` when multiple upstreams enter this node | `all_merge` |
**Note:** Output nodes are workflow exits and must not have outgoing edges.
### 5.7 End
Optional node for an end summary template (less common in role-bound flows).
| Field | Description | Default |
|-------|-------------|---------|
| Result template | Supports `{{outputs.xxx}}` | `{{outputs.result}}` |
| Join strategy | How to build `previous` when multiple upstreams enter this node | `all_merge` |
---
## 6. Edge configuration
Select an **edge** to configure its **condition** in the right panel.
| Scenario | Example |
|----------|---------|
| Filter after a normal node | `{{previous.output}} == "ok"` |
| “Yes” branch from a condition | `{{previous.matched}} == "true"` |
| “No” branch from a condition | `{{previous.matched}} == "false"` |
If no edge condition is set:
- Non-condition nodes: edge is always allowed
- Condition nodes: yes/no branches are assigned by edge order automatically
---
## 7. Full example: passing Agent output across a condition
### 7.1 Graph structure
```text
Start → Agent (initial value) → Condition → Agent (transform) → Output
↘ no → Output
```
### 7.2 Node configuration
**Agent 1**
| Field | Value |
|-------|-------|
| Node instruction | Output only `123333333` |
| Output variable name | `agent_result1` |
**Condition**
| Field | Value |
|-------|-------|
| Expression | `{{outputs.agent_result1}} != ""` |
**Agent 2**
| Field | Value |
|-------|-------|
| Input source | `{{outputs.agent_result1}}` |
| Node instruction | Add 100 to the input, then output |
| Output variable name | `agent_result` |
**Output**
| Field | Value |
|-------|-------|
| Output variable name | `result` |
| Variable source | `{{outputs.agent_result}}` |
### 7.3 Common mistakes
| Wrong config | Why it fails |
|--------------|--------------|
| Agent 2 input source = `{{previous.output}}` | `previous` points to the condition node → `true`/`false`, not Agent 1s text |
| Agent 1 has no output variable name | `outputs.agent_result1` does not exist → empty downstream |
| Condition uses `{{previous.output}}` | Tests the wrong upstream value instead of Agent 1s named output |
---
## 8. Bind to a role and run
### 8.1 Bind in Role Management
1. Open **Role Management**, edit or create a role.
2. Select the workflow / graph ID to bind.
3. Set policy to `auto` (default when `workflow_id` is set).
4. Save the role.
You can also configure this in role YAML:
```yaml
name: workflow-test
workflow_id: "1233"
workflow_version: latest
workflow_policy: auto
```
### 8.2 Runtime behavior
When a user chats with that role:
1. The engine loads `graph_json` and executes the graph.
2. The chat UI shows progress events (`workflow_start`, `workflow_node_start`, Agent reasoning, etc.).
3. When finished, a summary lists all named entries in `outputs`.
If no Output node is reached or no branch matches, `outputs` may be empty and the summary will suggest checking the Output node and branches.
---
## 9. Debugging, dry-run, and replay
### 9.1 Safe dry-run
Click **Dry run** on the canvas toolbar and enter a test message to simulate the workflow.
Dry-run safety rules:
- `start` / `condition` / `output` / `end` use real logic
- `tool` does not call MCP; it returns `[dry-run] tool call skipped`
- `agent` does not call the model; it returns `[dry-run] agent execution skipped`
- `hitl` does not pause; it simulates approval
API:
```http
POST /api/workflows/dry-run
```
Request:
```json
{
"graph": { "nodes": [], "edges": [], "config": {} },
"inputs": { "message": "ping" }
}
```
Response includes:
- `outputs`
- `nodeOutputs`
- `trace`
- `metrics`
- `replayScript`
### 9.2 Run details and replay
Query full node execution traces after a run:
```http
GET /api/workflows/runs/{runId}
```
The response contains `run` and `nodeRuns`. Each node run records:
- input snapshot
- output snapshot
- status / error
- started_at / finished_at
- `duration_ms`
Replay API:
```http
GET /api/workflows/runs/{runId}/replay
```
This generates replay steps from saved `nodeRuns`; it does not re-execute tools or Agents.
### 9.3 Metrics
The workflow accumulates, when available:
- `node_count`
- `duration_ms`
- `tool_call_count`
- Agent progress usage such as `prompt_tokens` / `completion_tokens` / `total_tokens` / `cost`
Token and cost metrics depend on whether the underlying model/Agent events report usage.
---
## 10. Validation before save
On save, the system checks:
| Rule | Description |
|------|-------------|
| Start node required | At least one `start` node |
| Output node required | At least one `output` node with an output variable name |
| Valid edges | Source and target exist; no self-loops |
| Start has no incoming edges | Start must not be targeted |
| Output / End has no outgoing edges | Nothing after Output / End |
| Non-start nodes must have incoming edges | Prevent orphan nodes |
| Non-output/end nodes must have outgoing edges | Prevent dead ends |
| No cycles | Workflow orchestration must be a DAG |
| Reachability | Every node must be reachable from Start and eventually reach output/end |
| Tool nodes | MCP tool required; argument JSON must be valid; timeout must be a positive integer |
| Agent nodes | Must have node instruction or input binding; output variable name required |
| Condition nodes | Expression required; 12 outgoing edges; branches must be yes/no and unique |
| Edge conditions | Expressions, regexes, and JSONPath/JQ paths must pass static validation |
| Join strategy | Must be `all_merge` / `last_by_canvas` / `first_non_empty` / `fail_fast` |
---
## 11. Troubleshooting
| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| Downstream gets empty value | Upstream has no output variable name | Set **Output variable name** on upstream; use `{{outputs.xxx}}` downstream |
| Downstream gets `true`/`false` | Used `{{previous.output}}` while previous node is a condition | Use `{{outputs.xxx}}` instead |
| Condition always takes “no” | Expression does not match actual output format | Check Agent output for quotes/newlines; try `!= ""` first |
| No final output | Output node branch not reached | Verify condition wiring; ensure every path reaches an **Output** node |
| Role chat does not run workflow | Role not bound or disabled | Check `workflow_id`, `workflow_policy: auto`, workflow `enabled: true` |
| Tool node fails | Invalid JSON in arguments or tool disabled | Fix argument template; enable the tool in MCP settings |
| Save fails with invalid branch | Condition outgoing edges are not marked yes/no, or are duplicated | Select the edge and set branch to `true` or `false` |
| Multi-upstream result is unexpected | Join strategy does not match the workflow | Switch between `all_merge`, `first_non_empty`, `last_by_canvas`, and `fail_fast` |
| Nested field is empty | JSONPath/JQ path is outside the safe subset | Use `$.a.b[0]` or `.a.b[0]`; avoid wildcards, recursion, or expressions |
---
## 12. Best practices
1. **Meaningful names**: Use descriptive output variable names (`scan_result`, `parsed_targets`) instead of reusing `agent_result` everywhere.
2. **Prefer `outputs` for cross-node data**: If a condition, tool, or HITL node might sit in between, use named variables.
3. **Use `previous` only for direct links**: `A → B` with nothing in between is the ideal case for `{{previous.output}}`.
4. **Conditions should reference source data**: When testing Agent output, use `{{outputs.xxx}}` unless the condition immediately follows that Agent.
5. **Every path needs an exit**: Ensure both yes and no branches eventually reach an **Output** node (or your intended end).
6. **Choose join strategy explicitly for multi-upstream nodes**: Use `all_merge` for aggregation, `first_non_empty` for fallback, and `fail_fast` for critical gates.
7. **Use JSONPath/JQ safe paths for nested JSON**: e.g. `jsonpath({{previous.output}}, "$.status") == "ok"`.
8. **Dry-run before real execution**: Validate data flow and branches with a simple message before binding the workflow to a role.
---
## 13. Code references (for developers)
| Module | Path |
|--------|------|
| Execution engine | `internal/workflow/runner.go` |
| Eino compile / checkpoint / HITL | `internal/workflow/eino_compile.go` |
| Graph validation | `internal/workflow/validation.go` |
| Expressions / JSONPath / joins | `internal/workflow/expression.go`, `jsonpath.go`, `join.go` |
| Dry-run / replay data | `internal/workflow/dry_run.go`, `internal/handler/workflow_run.go` |
| Canvas UI | `web/static/js/workflows.js` |
| Workflow API | `internal/handler/workflow.go` |
| Role binding | `internal/config/config.go` (`workflow_id` field) |
@@ -1,32 +1,32 @@
# Eino 多代理改造说明(DeepAgent
本文档记录 **单 Agent(原有 ReAct****多 AgentCloudWeGo Eino `adk/prebuilt/deep`** 并存的改造范围、进度与后续事项。
本文档记录 **Eino 单代理(ADK****多 AgentCloudWeGo Eino `adk/prebuilt`** 的改造范围、进度与后续事项。原生 ReAct 执行路径已移除。
## 总体结论
- **改造已可用于生产试验**:流式对话、MCP 工具桥接、配置开关、前端模式切换均已落地。
- **入口策略**主聊天与 WebShell 在开启多代理且用户选择 **Deep / Plan-Execute / Supervisor**`/api/multi-agent/stream`,请求体字段 **`orchestration`** 指定当次编排(与界面一致);**原生 ReAct** 走 `/api/agent-loop/stream`。机器人、批量任务无该请求体时服务端按 **`deep`** 执行。均`multi_agent.enabled`
- **入口策略****单代理** 走 `/api/eino-agent/stream`;多代理`/api/multi-agent/stream`,请求体 **`orchestration`** 指定编排。模式定位按 Eino ADK 最佳实践区分:**Deep** 适合复杂安全测试与 task 子代理协作;**Plan-Execute** 适合目标明确的规划 → 执行 → 重规划闭环;**Supervisor** 适合多个专业子代理动态分派的专家路由场景。机器人默认 `robot_default_agent_mode: eino_single`;批量队列默认 `eino_single`,多代理模式`multi_agent.enabled`
## 已完成项
| 项 | 说明 |
|----|------|
| 依赖与代理 | `go.mod` 直接依赖 `github.com/cloudwego/eino``eino-ext/.../openai``go.mod` 注释与 `scripts/bootstrap-go.sh` 指导 **GOPROXY**(如 `https://goproxy.cn,direct`)。 |
| 配置 | `config.yaml``multi_agent``enabled``default_mode``robot_use_multi_agent``max_iteration``sub_agents`(含可选 `bind_role`)、`eino_skills``eino_middleware` 等;结构体见 `internal/config/config.go`。 |
| 配置 | `config.yaml``agent.max_iterations` 为全局 ReAct 上限(主/子代理统一);`multi_agent``enabled``robot_use_multi_agent``sub_agents`(含可选 `bind_role`)、`eino_skills``eino_middleware` 等;结构体见 `internal/config/config.go`。 |
| Markdown 子代理 / 主代理 | 在 `agents_dir` 下放 `*.md`。**子代理**:供 Deep `task``supervisor` `transfer`。**主代理(按模式分离)**`orchestrator.md`(或 `kind: orchestrator` 的**单个**其他 .md)→ **Deep**;固定名 `orchestrator-plan-execute.md`**plan_execute**;固定名 `orchestrator-supervisor.md`**supervisor**。正文优先于 YAML`multi_agent.orchestrator_instruction``orchestrator_instruction_plan_execute``orchestrator_instruction_supervisor`plan_execute / supervisor **不会**回退到 Deep 的 `orchestrator_instruction`。皆空时 plan_execute / supervisor 使用代码内置默认提示。管理:**Agents → Agent管理**API`/api/multi-agent/markdown-agents*`。 |
| MCP 桥 | `internal/einomcp``ToolsFromDefinitions` + 会话 ID 持有者,执行走 `Agent.ExecuteMCPToolForConversation`。 |
| 编排 | `internal/multiagent/runner.go``deep.New` + 子 `ChatModelAgent` + `adk.NewRunner``EnableStreaming: true`,可选 `CheckPointStore`),事件映射为现有 SSE `tool_call` / `response_delta` 等。 |
| HTTP | `POST /api/multi-agent`(非流式)、`POST /api/multi-agent/stream`(SSE);路由**常注册**,是否可用由运行时 `multi_agent.enabled` 决定(流式未启用时 SSE 内 `error` + `done`)。 |
| 会话准备 | `internal/handler/multi_agent_prepare.go``prepareMultiAgentSession`(含 **WebShell** `CreateConversationWithWebshell`、工具白名单与单代理一致)。 |
| 单 Agent | `internal/agent` 增加 `ToolsForRole``ExecuteMCPToolForConversation`;原 `/api/agent-loop` 未删改语义。 |
| 前端 | 主聊天 / WebShell`multi_agent.enabled` 时可选 **原生 ReAct** 与三种 Eino 命名,多代理路径在 JSON 中带 `orchestration`。设置页不再配置预置编排项;`plan_execute` 外层循环上限等仍可在设置中保存。 |
| 流式兼容 | `/api/agent-loop/stream` 共用 `handleStreamEvent``conversation``progress``response_start` / `response_delta``thinking` / `thinking_stream_*`(模型 `ReasoningContent``tool_*``response``done``tool_result``toolCallId``tool_call` 联动;`data.mcpExecutionIds` 与进度 i18n 已对齐。 |
| 单 Agent | `internal/agent` 为 MCP/工具层(`ToolsForRole``ExecuteMCPToolForConversation`);单代理编排走 `RunEinoSingleChatModelAgent``/api/eino-agent*`。 |
| 前端 | 主聊天 / WebShell**Eino 单代理**`/api/eino-agent/stream`)与 **Deep / Plan-Execute / Supervisor**`/api/multi-agent/stream` + `orchestration`);`multi_agent.enabled` 控制多代理选项是否展示。 |
| 流式兼容 | Eino 单/多代理与 Web UI 共用 `handleStreamEvent``conversation``progress``response_start` / `response_delta``thinking` / `thinking_stream_*``tool_*``response``done` 等。 |
| 批量任务 | 队列 `agentMode``deep` / `plan_execute` / `supervisor` 时子任务带对应 `orchestration` 调用 `RunDeepAgent`;旧值 `multi` 与「`agentMode` 为空且 `batch_use_multi_agent: true`」均按 `deep`。 |
| 配置 API | `GET /api/config` 返回 `multi_agent: { enabled, default_mode, robot_use_multi_agent, sub_agent_count }``PUT /api/config` 可更新前三项(不覆盖 `sub_agents`)。 |
| 配置 API | `GET /api/config` 返回 `multi_agent: { enabled, robot_use_multi_agent, sub_agent_count }``PUT /api/config` 可更新 `enabled``robot_use_multi_agent`(不覆盖 `sub_agents`)。 |
| OpenAPI | 多代理路径说明已更新(流式未启用为 SSE 错误事件)。 |
| 机器人 | `ProcessMessageForRobot` `enabled && robot_use_multi_agent` 时调用 `multiagent.RunDeepAgent`。 |
| 预置编排 | 聊天 / WebShell`POST /api/multi-agent*` 请求体 `orchestration``deep` \| `plan_execute` \| `supervisor`(缺省 `deep`)。`plan_execute` 不构建 YAML/Markdown 子代理;`plan_execute_loop_max_iterations` 仍来自配置`supervisor` 至少需一个子代理。 |
| Eino 中间件 | `multi_agent.eino_middleware`(可选):`patchtoolcalls`(默认开)、`toolsearch`(按阈值拆分 MCP 工具列表)、`plantask`(需 `eino_skills`)、`reduction`(大工具输出截断/落盘)、`checkpoint_dir`Runner 断点)、`deep_output_key` / `deep_model_retry_max_retries` / `task_tool_description_prefix`Deep 与 supervisor 主代理共享其中模型重试与 OutputKey)。`plan_execute`Executor 无 Handlers:仅继承 **ToolsConfig** 侧效果(如 `tool_search` 列表拆分),不挂载 patch/plantask/reduction 中间件。 |
| 机器人 | `ProcessMessageForRobot` `robot_default_agent_mode`(默认 `eino_single`)调用 `RunEinoSingleChatModelAgent``RunDeepAgent`。 |
| 预置编排 | 聊天 / WebShell`POST /api/multi-agent*` 请求体 `orchestration``deep` \| `plan_execute` \| `supervisor`(缺省 `deep`)。`deep` 使用 task 子代理协作;`plan_execute` 不构建 YAML/Markdown 子代理;`plan_execute_loop_max_iterations` 仍来自配置`supervisor` 至少需一个子代理,只有一个子代理时会提示其专家路由空间有限。 |
| Eino 中间件 | `multi_agent.eino_middleware`(可选):`patchtoolcalls`(默认开)、`toolsearch`(按阈值拆分 MCP 工具列表)、`plantask`(需 `eino_skills`)、`reduction`(大工具输出截断/落盘)、`checkpoint_dir`Runner 断点)、`deep_output_key` / `deep_model_retry_max_retries` / `task_tool_description_prefix`Deep 与 supervisor 主代理共享其中模型重试与 OutputKey)。**`plan_execute`**Executor 使用 Eino 官方允许的自定义 `adk.ChatModelAgent`,保持官方 Plan/UserInput/ExecutedSteps session contract,同时挂载与 Deep/Supervisor 主代理同源的 middlewarepatch → reduction → toolsearch → plantask → filesystem → skill → summarization tail)。Planner/Replanner 仅 summarization tail + prompt 预算截断,不跑 MCP 工具链。当前 Eino 官方 `planexecute.NewExecutor` 尚未暴露 Handlers 字段,因此该自定义 Executor 是保留 middleware 的对齐实现。 |
## 进行中 / 待办( backlog
@@ -37,7 +37,8 @@
## 关键文件索引
- `internal/multiagent/runner.go` — DeepAgent 组装与事件循环
- `internal/multiagent/runner.go` — DeepAgent / plan_execute / supervisor 组装与事件循环
- `internal/multiagent/eino_orchestration.go` — PlanExecute 根节点与 Executor 中间件栈(`buildPlanExecuteExecutorHandlers`
- `internal/handler/multi_agent.go` — SSE 与(同步)HTTP
- `internal/handler/multi_agent_prepare.go` — 会话准备(含 WebShell)
- `internal/einomcp/` — MCP → Eino Tool
@@ -58,3 +59,7 @@
| 2026-03-22 | `agents/*.md` 子代理定义、`agents_dir`、合并进 `RunDeepAgent`、前端 Agents 菜单与 CRUD API。 |
| 2026-03-22 | `orchestrator.md` / `kind: orchestrator` 主代理、列表主/子标记、与 `orchestrator_instruction` 优先级。 |
| 2026-04-19 | 主聊天「对话模式」:原生 ReAct 与 Deep / Plan-Execute / Supervisor`POST /api/multi-agent*` 请求体 `orchestration` 与界面一致;`config.yaml` / 设置页不再维护预置编排字段(机器人/批量默认 `deep`)。 |
| 2026-04-21 | 移除角色 `skills``/api/roles/skills/list``bind_role` 仅继承 toolsSkills 仅通过 Eino `skill` 工具按需加载。 |
| 2026-07-06 | **最佳实践对齐**Deep / Plan-Execute / Supervisor 改为中性适用场景描述;Supervisor 标为专家路由特定场景并收紧 transfer/exit 约束;plan_execute Executor 明确为遵循官方 session contract 的自定义 ChatModelAgent,保留 middleware 并补类型保护。 |
| 2026-07-02 | **plan_execute Executor 中间件对齐**`ExecPreMiddlewares` 与 Deep 主代理同源;`buildPlanExecuteExecutorHandlers` + 回归测试;文档更正。 |
| 2026-06-02 | **移除原生 ReAct**:删除 `/api/agent-loop*` 执行入口与 `AgentLoopWithProgress`;统一 Eino ADK(单代理 `/api/eino-agent*`,多代理 `/api/multi-agent*`);任务 cancel/tasks API 保留。 |
+29
View File
@@ -0,0 +1,29 @@
# 中文文档
- [部署指南](deployment.md):部署形态、HTTPS、反向代理、systemd、备份、升级和验收。
- [运维 Runbooks](runbooks.md):生产部署、外部 MCP、知识库、Web 测试、C2 清理和工具排障的操作步骤。
- [配置画像](configuration-profiles.md):本地开发、内网团队、知识库、高审计生产、C2 演练等推荐配置。
- [安全加固指南](security-hardening.md):上线前基线、反向代理、HITL 白名单、文件权限和周期巡检。
- [API Recipes](api-recipes.md):登录、Agent、流式、多代理、上传、漏洞、知识库、MCP 和审计导出示例。
- [贡献规范](contributing-guide.md):新增 API、配置、工具、前端、数据库、高风险能力和文档的 checklist。
- [配置参考](configuration.md)`config.yaml` 字段、热应用边界、参数建议和源码锚点。
- [安全模型](security-model.md):信任边界、HITL、工具执行、C2/WebShell 与数据安全。
- [架构说明](architecture.md):请求路径、模块关系、复杂度热点和设计取舍。
- [API 参考](api-reference.md):认证、OpenAPI、SSE、稳定性分层和常用接口。
- [排错指南](troubleshooting.md):诊断顺序、最小命令、常见误判和故障模板。
- [审计与监控](audit-and-monitoring.md):平台审计、工具监控、HITL 日志和保留策略。
- [知识库](knowledge-base.md):索引链路、检索调参、日志分析和内容写法。
- [C2 使用说明](c2.md):生命周期、任务分级、事件复盘和安全建议。
- [WebShell 管理](webshell.md):操作分层、连接命名、AI 约束和排错。
- [MCP 联邦](mcp-federation.md):内置 MCP、外部 MCP、生命周期和工具命名。
- [Agent 与角色](agent-and-role-guide.md):角色、子代理、Skill、编排模式和工具可见性。
- [Skills 指南](skills-guide.md):Skill 结构、渐进式披露、反模式和本地工具风险。
- [插件开发](plugin-development.md):API 插件、MCP 插件、资源包插件和安全边界。
- [发布流程](release-process.md):发布风险、配置兼容、数据库迁移和验收。
- [测试指南](testing.md):测试分层、回归重点、测试数据和失败用例。
- [图编排使用说明](workflow-graph.md)
- [人机协同最佳实践](hitl-best-practices.md)
- [机器人使用说明](robot.md)
- [视觉分析](VISION.md)
- [前端国际化方案](frontend-i18n.md)
- [Eino 多代理改造说明](MULTI_AGENT_EINO.md)
+45
View File
@@ -0,0 +1,45 @@
# 视觉分析(analyze_image
## 概述
- **工具名**`analyze_image`MCP 内置)
- **行为**:读取本地图片 → `imaging` 缩放/JPEG 压缩 → 调用独立 **Vision** 模型 → 返回**纯文本**给 Agent
- **上下文**:图片字节**不会**写入对话历史;仅路径与文字摘要进入 Agent 上下文
## 配置(`config.yaml` → `vision`
```yaml
vision:
enabled: true
model: qwen-vl-max # 必填
api_key: # 留空 → openai.api_key
base_url: # 留空 → openai.base_url
provider: # 留空 → openai.provider
max_image_bytes: 5242880
max_dimension: 2048
jpeg_quality: 82
max_payload_bytes: 524288
skip_preprocess_below_bytes: 2097152 # 低于 2MB 且长边<=max_dimension 时原图直传;0=始终 JPEG 压缩
detail: low # low | high | auto
timeout_seconds: 60
```
`enabled: false` 时不注册工具。
## Web 设置
**系统设置 → 基本设置 → 视觉分析(analyze_image** 可配置启用开关、视觉模型、API Key/Base URL(留空复用 OpenAI)、预处理参数;**保存并应用** 后写入 `config.yaml` 并重新注册 MCP 工具。
## 路径
`analyze_image` 可读取服务器上任意可读的图片文件路径(绝对路径或相对于进程工作目录的相对路径)。仍校验图片扩展名与常规文件类型。
## Agent 使用
系统提示已说明:遇图片调用 `analyze_image`,勿用 `read_file` 读二进制图。
`multi_agent.eino_middleware.tool_search_always_visible_tools` 建议包含 `analyze_image`
## 合规
启用后图片会发往 Vision API 配置的上游;敏感环境请使用可信网关或保持 `enabled: false`
+197
View File
@@ -0,0 +1,197 @@
# Agent 与角色指南
CyberStrikeAI 的 Agent 行为由三类资源共同决定:角色、子代理和 Skills。角色决定当前任务身份和可用工具;子代理决定多代理分工;Skills 提供可按需加载的专题知识与流程。
## 角色
角色文件位于 `roles/`,格式为 YAML。角色通常包含:
- 名称。
- 描述。
- 系统提示词。
- 可用工具列表。
设计原则:
- 专用角色只绑定必要工具。
- 提示词明确授权边界。
- 对高风险操作要求先说明影响并等待审批。
- 输出格式尽量稳定,便于报告和复盘。
示例方向:
- 信息收集。
- Web 应用扫描。
- API 安全测试。
- 云安全审计。
- 数字取证。
- 二进制分析。
- CTF。
## 单代理
单代理接口:
- `POST /api/eino-agent`
- `POST /api/eino-agent/stream`
适合:
- 快速问答。
- 单目标测试。
- 工具链较短的任务。
- 需要稳定上下文的交互式分析。
## 多代理模式
多代理接口:
- `POST /api/multi-agent`
- `POST /api/multi-agent/stream`
编排模式:
- `deep`:主代理拆解任务,按需调用子代理。
- `plan_execute`:先规划,再执行,必要时重规划。
- `supervisor`:主管代理根据进展转交不同子代理。
适合:
- 多阶段渗透测试。
- 大范围信息收集。
- 需要并行角色分工的分析。
- 长任务和批量任务。
## 子代理 Markdown
子代理位于 `agents/*.md`。Front matter 示例:
```yaml
---
name: Attack Surface Enumeration
id: attack-surface-enumeration
description: 枚举目标暴露面并整理可验证线索
tools:
- subfinder
- nmap
- http-framework-test
bind_role: 信息收集
max_iterations: 300
---
```
正文写系统提示词。建议包含:
- 职责边界。
- 输入期望。
- 使用工具顺序。
- 输出格式。
- 禁止事项。
## 主代理
主代理可用:
- `agents/orchestrator.md`
- `agents/orchestrator-plan-execute.md`
- `agents/orchestrator-supervisor.md`
或在 front matter 中设置 `kind: orchestrator`。每种编排只应有一个主代理定义。
## 工具选择
工具选择顺序建议:
1. 角色绑定最小工具集。
2. 子代理按任务补充专用工具。
3. `tool_search` 动态解锁大量工具。
4. 高风险工具由 HITL 审批。
不要给所有角色默认绑定全部工具,否则上下文成本和误调用风险都会上升。
## 提示词建议
好的角色提示词应说明:
- 只在授权范围内行动。
- 先确认目标和约束。
- 对写入、删除、爆破、持久化、C2、WebShell 等操作请求审批。
- 输出可复核证据。
- 不确定时标注假设,不编造结果。
## 调试
如果 Agent 选错工具:
- 缩小角色工具列表。
- 增强工具 `short_description`
- 开启或调整 `tool_search_always_visible_tools`
- 在角色提示词中明确工具使用顺序。
如果多代理跑偏:
- 检查子代理描述是否过宽。
- 降低 `sub_agent_user_context_max_runes` 或明确任务输入。
- 优化 orchestrator 提示词。
- 查看过程详情和工具执行监控。
## 角色、子代理、Skill 的职责边界
三者经常混用,建议这样分工:
| 资源 | 解决的问题 | 不适合承载 |
| --- | --- | --- |
| Role | 当前对话的身份、语气、工具边界和授权规则 | 大量参考资料 |
| Agent Markdown | 多代理中的专业分工、交接格式和局部策略 | 一次性任务事实 |
| Skill | 可复用方法论、检查清单、模板和长参考资料 | 权限控制 |
如果把授权边界写进 Skill,而角色没有限制工具,Agent 仍可能在未加载 Skill 前选错工具。权限边界应优先放在 Role 和 HITL 中。
## 编排模式选择
| 模式 | 适合 | 不适合 |
| --- | --- | --- |
| `eino_single` | 短任务、交互式分析、需要稳定上下文 | 多阶段大任务 |
| `deep` | 主代理动态拆分任务,子代理按需深入 | 需要严格步骤顺序的流程 |
| `plan_execute` | 有明确阶段、需要执行后复盘和重规划 | 用户频繁打断的即兴对话 |
| `supervisor` | 专家分工明确,需要主管路由 | 子代理定义含糊或过多 |
经验上,普通安全测试先用 `eino_single`;复杂项目用 `plan_execute`;需要多个专业角色时用 `deep``supervisor`
## 工具可见性如何影响行为
多代理里 `tool_search` 会让模型一开始只看见部分常驻工具。结果是:
- 工具页面显示可用,不代表模型当前上下文可见。
- `tool_search_always_visible_tools` 里的工具更容易被模型调用。
- 工具描述越清晰,越容易被搜索命中。
- 子代理自己的 `tools` 限制仍然很重要。
调试“Agent 为什么不用某工具”时,要同时检查角色工具、子代理工具、tool_search 配置和工具描述。
## 好的子代理输出格式
子代理不要只返回“已完成”。建议固定格式:
```markdown
## 结论
## 证据
- 命令/工具:
- 关键输出:
- 置信度:
## 风险
## 建议下一步
```
这样主代理才能继续编排,也方便攻击链和项目事实沉淀。
## 源码锚点
- Markdown Agent 解析:`internal/agents/markdown.go`
- 多代理准备:`internal/handler/multi_agent_prepare.go`
- 编排实现:`internal/multiagent/eino_orchestration.go`
- 工具搜索中间件:`internal/multiagent/eino_middleware.go`
- 子代理上下文:`internal/multiagent/sub_agent_context_test.go`
+153
View File
@@ -0,0 +1,153 @@
# API Recipes
[English](../en-US/api-recipes.md)
本文给出外部脚本或插件常用的 API 调用配方。完整字段以 `/api-docs``/api/openapi/spec` 为准。
## Recipe 1:登录并验证
```bash
curl -k https://127.0.0.1:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"password":"<password>"}'
```
后续请求推荐使用:
```bash
Authorization: Bearer <token>
```
验证:
```bash
curl -k https://127.0.0.1:8080/api/auth/validate \
-H "Authorization: Bearer <token>"
```
## Recipe 2:创建对话并发送消息
最简单方式是不先创建空对话,直接调用 Agent:
```bash
curl -k https://127.0.0.1:8080/api/eino-agent \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"对 127.0.0.1 做授权的基础信息收集,只做只读操作"}'
```
如果需要先创建对话:
```bash
curl -k https://127.0.0.1:8080/api/conversations \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"title":"Web 测试"}'
```
然后把返回的 `conversationId` 放入 Agent 请求。
## Recipe 3:流式调用 Agent
```bash
curl -k -N https://127.0.0.1:8080/api/eino-agent/stream \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"总结当前项目事实并列出下一步,只读"}'
```
注意:
- `-N` 禁用 curl 缓冲。
- 反向代理也要关闭 buffering。
- 收到 `done` 才算本轮结束。
## Recipe 4:调用多代理
```bash
curl -k -N https://127.0.0.1:8080/api/multi-agent/stream \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"message":"对授权目标做分阶段 Web 安全测试,先规划再执行只读步骤",
"orchestration":"plan_execute"
}'
```
可选 `orchestration`
- `deep`
- `plan_execute`
- `supervisor`
## Recipe 5:上传附件
```bash
curl -k https://127.0.0.1:8080/api/chat-uploads \
-H "Authorization: Bearer <token>" \
-F "file=@./request.txt"
```
大文件建议上传后在消息中引用,不要直接塞进 prompt。
## Recipe 6:写入漏洞
```bash
curl -k https://127.0.0.1:8080/api/vulnerabilities \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title":"示例 SQL 注入",
"severity":"high",
"target":"https://example.com/item?id=1",
"description":"参数 id 存在可验证 SQL 注入",
"evidence":"只读验证输出...",
"remediation":"使用参数化查询"
}'
```
字段以 OpenAPI 为准。
## Recipe 7:查询知识库
```bash
curl -k https://127.0.0.1:8080/api/knowledge/search \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"query":"SQL 注入如何判断字段数",
"riskType":"SQL Injection",
"topK":5,
"threshold":0.4
}'
```
如果结果为空,先调用 categories 看风险类型名称是否匹配。
## Recipe 8:检查外部 MCP 状态
```bash
curl -k https://127.0.0.1:8080/api/external-mcp/stats \
-H "Authorization: Bearer <token>"
```
如果服务 running 但 Agent 找不到工具,检查角色工具限制和 `tool_search`
## Recipe 9:获取工具 schema
```bash
curl -k https://127.0.0.1:8080/api/config/tools/nmap/schema \
-H "Authorization: Bearer <token>"
```
插件或自动化脚本应根据 schema 构造参数,不要猜字段名。
## Recipe 10:导出审计日志
```bash
curl -k "https://127.0.0.1:8080/api/audit/logs/export" \
-H "Authorization: Bearer <token>" \
-o audit.csv
```
导出文件可能包含敏感操作信息,应加密保存。
+239
View File
@@ -0,0 +1,239 @@
# API 参考
CyberStrikeAI 内置 OpenAPI 规格和 API 文档页面。启动服务后访问:
```text
/api-docs
```
OpenAPI JSON
```text
GET /api/openapi/spec
```
`/api/openapi/spec` 需要登录认证,避免未授权用户直接枚举接口结构。
## 认证
登录:
```http
POST /api/auth/login
Content-Type: application/json
{"password":"your-password"}
```
认证成功后,前端通常使用 Cookie 会话。外部客户端也可参考 OpenAPI 中的 Bearer Token 描述,按实际返回字段接入。
常用认证接口:
- `POST /api/auth/login`
- `POST /api/auth/logout`
- `POST /api/auth/change-password`
- `GET /api/auth/validate`
## 对话与 Agent
单代理:
- `POST /api/eino-agent`
- `POST /api/eino-agent/stream`
多代理:
- `POST /api/multi-agent`
- `POST /api/multi-agent/stream`
多代理请求体通过 `orchestration` 指定:
- `deep`
- `plan_execute`
- `supervisor`
对话管理:
- `POST /api/conversations`
- `GET /api/conversations`
- `GET /api/conversations/:id`
- `PUT /api/conversations/:id`
- `DELETE /api/conversations/:id`
- `POST /api/conversations/:id/delete-turn`
- `GET /api/messages/:id/process-details`
## 项目、漏洞、攻击链
项目:
- `GET /api/projects`
- `POST /api/projects`
- `GET /api/projects/:id`
- `PUT /api/projects/:id`
- `DELETE /api/projects/:id`
- `GET /api/projects/:id/facts`
- `POST /api/projects/:id/facts`
- `GET /api/projects/:id/fact-graph`
漏洞:
- `GET /api/vulnerabilities`
- `POST /api/vulnerabilities`
- `GET /api/vulnerabilities/:id`
- `PUT /api/vulnerabilities/:id`
- `DELETE /api/vulnerabilities/:id`
- `GET /api/vulnerabilities/export`
攻击链:
- `GET /api/attack-chain/:conversationId`
- `POST /api/attack-chain/:conversationId/regenerate`
## 工具、MCP、配置
配置:
- `GET /api/config`
- `PUT /api/config`
- `POST /api/config/apply`
- `GET /api/config/tools`
- `GET /api/config/tools/:name/schema`
- `POST /api/config/test-openai`
- `POST /api/config/test-vision`
- `POST /api/config/list-models`
MCP
- `POST /api/mcp`
- `GET /api/external-mcp`
- `PUT /api/external-mcp/:name`
- `POST /api/external-mcp/:name/start`
- `POST /api/external-mcp/:name/stop`
- `DELETE /api/external-mcp/:name`
## 知识库、Skills、角色、Agent
知识库:
- `GET /api/knowledge/categories`
- `GET /api/knowledge/items`
- `POST /api/knowledge/scan`
- `POST /api/knowledge/index`
- `POST /api/knowledge/search`
角色:
- `GET /api/roles`
- `POST /api/roles`
- `GET /api/roles/:name`
- `PUT /api/roles/:name`
- `DELETE /api/roles/:name`
Skills
- `GET /api/skills`
- `POST /api/skills`
- `GET /api/skills/:name`
- `PUT /api/skills/:name`
- `DELETE /api/skills/:name`
- `GET /api/skills/:name/files`
- `GET /api/skills/:name/file`
- `PUT /api/skills/:name/file`
Markdown 子代理:
- `GET /api/multi-agent/markdown-agents`
- `POST /api/multi-agent/markdown-agents`
- `GET /api/multi-agent/markdown-agents/:filename`
- `PUT /api/multi-agent/markdown-agents/:filename`
- `DELETE /api/multi-agent/markdown-agents/:filename`
## 高风险能力
WebShell
- `GET /api/webshell/connections`
- `POST /api/webshell/connections`
- `POST /api/webshell/exec`
- `POST /api/webshell/file`
C2
- `GET /api/c2/listeners`
- `POST /api/c2/listeners`
- `GET /api/c2/sessions`
- `POST /api/c2/tasks`
- `POST /api/c2/payloads/build`
终端:
- `POST /api/terminal/run`
- `POST /api/terminal/run/stream`
- `GET /api/terminal/ws`
这些接口应只开放给可信管理员,并配合 HTTPS、强密码、网络隔离和审计。
## 调用建议
- 优先使用 `/api-docs` 查看完整参数和响应结构。
- 流式接口使用 SSE,反向代理需关闭缓冲。
- 所有修改类接口都应处理 401、403、404、409、500。
- 外部集成建议创建最小权限网络路径,不要把 Web 管理面直接暴露到公网。
## 认证细节
认证中间件会按顺序提取 token
1. `Authorization: Bearer <token>`
2. `Authorization: <token>`
3. 查询参数 `?token=<token>`
4. Cookie `auth_token`
这意味着外部脚本最稳妥的方式是使用 `Authorization: Bearer`。查询参数虽然支持,但容易进入代理日志,不建议生产使用。
## SSE 客户端注意事项
`/api/eino-agent/stream``/api/multi-agent/stream` 是长连接。客户端应处理:
- 网络中断后不要盲目重放破坏性请求。
- 收到 `error` 事件后读取错误正文。
- 收到 `done` 才视为本轮结束。
- 代理层不能缓冲。
- 请求体中的 `conversationId` 决定是否接续已有对话。
## API 稳定性分层
| API 类型 | 稳定性 | 集成建议 |
| --- | --- | --- |
| `/api/auth/*` | 高 | 可直接集成 |
| `/api/eino-agent*` | 高 | 推荐外部对话入口 |
| `/api/openapi/spec` | 高 | 用于生成客户端 |
| `/api/config*` | 中 | 管理工具使用,谨慎自动化 |
| `/api/c2/*``/api/webshell/*` | 中 | 高风险,必须加权限边界 |
| 前端私有调用细节 | 低 | 不建议插件依赖 |
## Curl 示例
登录并提取 token 的返回字段可能随实现调整,建议先看 `/api-docs`。如果已有 token
```bash
curl -k https://127.0.0.1:8080/api/conversations \
-H "Authorization: Bearer <token>"
```
发送非流式单代理请求:
```bash
curl -k https://127.0.0.1:8080/api/eino-agent \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"message":"对 127.0.0.1 做授权的基础信息收集,先不要执行高风险操作"}'
```
## 源码锚点
- 路由:`internal/app/app.go`
- 认证:`internal/security/auth_middleware.go`
- OpenAPI`internal/handler/openapi.go`
- 单代理:`internal/handler/eino_single_agent.go`
- 多代理:`internal/handler/multi_agent.go`
+171
View File
@@ -0,0 +1,171 @@
# 架构说明
CyberStrikeAI 是一个以 Web 管理面为入口、以 Agent 和 MCP 工具为执行核心的安全测试编排平台。
## 总览
```mermaid
flowchart LR
U["Web / Robot / API 用户"] --> R["Gin Router"]
R --> H["Handlers"]
H --> DB["SQLite"]
H --> A["Agent / Multi-Agent"]
A --> M["MCP Server"]
M --> T["内置工具 / YAML 工具 / Skills FS"]
M --> EM["外部 MCP"]
A --> K["知识库检索"]
H --> W["Workflow 图编排"]
H --> C2["内置 C2"]
H --> WS["WebShell"]
H --> AU["Audit / Monitor"]
```
## Web 层
入口在 `cmd/server/`,应用组装在 `internal/app/`。Web 使用 Gin
- `web/templates/index.html`:主页面。
- `web/templates/api-docs.html`API 文档页面。
- `web/static/js/`:各业务模块前端逻辑。
- `web/static/css/`:样式。
路由注册集中在 `internal/app/app.go`
## Handler 层
`internal/handler/` 按业务拆分:
- `agent.go``eino_single_agent.go``multi_agent.go`
- `workflow.go``workflow_run.go`
- `knowledge.go`
- `webshell.go`
- `c2.go`
- `audit.go`
- `monitor.go`
- `project.go`
- `vulnerability.go`
- `config.go`
- `openapi.go`
Handler 负责参数解析、权限中间件后的业务协调和 HTTP 响应。
## Agent 层
单代理和多代理主要在:
- `internal/agent/`
- `internal/multiagent/`
- `internal/agents/`
- `agents/`
Eino ADK 提供单代理、Deep、Plan-Execute、Supervisor 等执行模式。多代理子 Agent 由 Markdown 文件定义。
## MCP 与工具
MCP 相关:
- `internal/mcp/`:Server、外部 MCP、连接恢复。
- `internal/einomcp/`Eino 与 MCP 工具适配。
- `tools/`YAML 命令工具。
- `internal/app/*_tools.go`Go 内置工具注册。
工具调用会进入监控记录,并可受 HITL 审批影响。
## Workflow
图编排在 `internal/workflow/`HTTP 入口在 `internal/handler/workflow*.go`。它支持 start、agent、tool、condition、hitl、output、end 等节点。
详细使用见 [图编排使用说明](workflow-graph.md)。
## 知识库
知识库在 `internal/knowledge/`,包括:
- Markdown/文本内容管理。
- chunk。
- embedding。
- SQLite 向量索引。
- multi-query。
- rerank。
- 检索日志。
启用后会向 Agent 暴露知识检索工具。
## 数据层
`internal/database/` 封装 SQLite 访问,保存:
- 对话、消息、过程详情。
- 分组。
- 工具执行记录。
- HITL 日志。
- 知识库索引和检索日志。
- WebShell、C2、项目、漏洞、批量任务等业务数据。
默认数据库文件:
- `data/conversations.db`
- `data/knowledge.db`
## 安全与审计
`internal/security/` 提供认证、限流、Shell 执行和命令流处理。`internal/audit/``internal/monitor/` 分别负责平台审计和执行监控。
高风险模块包括:
- Terminal。
- WebShell。
- C2。
- 外部 MCP。
- 文件系统和 Shell Skills。
这些模块应结合角色、HITL 和部署隔离使用。
## 一次对话请求的真实路径
`/api/eino-agent/stream` 为例:
1. Gin 路由进入认证中间件。
2. Handler 解析请求体、会话 ID、角色、附件和 WebShell 上下文。
3. Agent 构建模型输入,包括历史消息、角色提示、项目事实、工具列表。
4. Eino Runner 调用模型。
5. 模型需要工具时走 MCP Tool。
6. 工具调用前可能触发 HITL。
7. 工具执行结果写入过程详情和监控。
8. 模型继续推理并生成最终回答。
9. SSE 将进度、工具事件、文本增量推给前端。
10. 会话、消息、过程详情写入 SQLite。
这个路径解释了为什么问题可能出在很多层:认证、会话、模型、工具、HITL、MCP、数据库、SSE 或前端渲染。
## 横向模块依赖
几个模块不是独立页面,而是横向能力:
- Project facts:会被注入 Agent 上下文,影响多轮和跨对话判断。
- HITL:插在工具调用前,影响所有 Agent/MCP 工具。
- Monitor:记录工具执行,影响任务取消、复盘和通知。
- Audit:记录平台管理动作,影响安全运营。
- Tool search:影响模型看见哪些工具,而不仅仅是工具页面显示。
改这些模块时要看全局调用点,不要只测单个页面。
## 复杂度热点
维护时优先警惕:
- `internal/app/app.go`:组装所有服务,容易引入初始化顺序问题。
- `internal/handler/config.go`:热应用配置,影响模型、知识库、C2、机器人和 MCP。
- `internal/multiagent/`:中间件多,流式、重试、摘要和工具调用交错。
- `internal/security/`Shell 和认证是安全边界。
- `internal/database/`:SQLite 结构演进必须兼容旧数据。
## 设计取舍
项目选择单体 Go 服务 + SQLite + 静态前端,是为了降低部署门槛。但代价是:
- 多实例横向扩展不天然成立,尤其 SQLite 写入和内存 session。
- 运行态配置和本地文件强绑定,需要良好备份。
- 高权限工具和 Web 管理面在同一进程内,部署隔离更重要。
这些不是缺陷,而是部署时必须理解的边界。
+148
View File
@@ -0,0 +1,148 @@
# 审计与监控
CyberStrikeAI 有两类常用可观测数据:平台操作审计和工具执行监控。二者用途不同,建议同时开启。
## 平台审计
配置:
```yaml
audit:
enabled: true
retention_days: 15
max_detail_bytes: 8192
auth_failure_cooldown_seconds: 60
```
审计记录覆盖登录、配置、资源管理等平台操作。它不会完整记录对话正文,也不逐条记录所有工具调用正文。
接口:
- `GET /api/audit/meta`
- `GET /api/audit/summary`
- `GET /api/audit/logs`
- `GET /api/audit/logs/:id`
- `GET /api/audit/logs/export`
建议关注:
- 登录失败和异常来源 IP。
- 密码修改。
- 配置修改。
- 外部 MCP 增删改。
- C2/WebShell/知识库等高风险资源操作。
## 工具执行监控
配置:
```yaml
monitor:
retention_days: 90
```
工具执行监控用于查看 MCP 工具调用、命令状态、耗时、取消和结果摘要。
接口:
- `GET /api/monitor`
- `GET /api/monitor/execution/:id`
- `POST /api/monitor/execution/:id/cancel`
- `DELETE /api/monitor/execution/:id`
- `DELETE /api/monitor/executions`
- `GET /api/monitor/stats`
- `GET /api/monitor/calls-timeline`
- `POST /api/monitor/executions/names`
## 通知摘要
接口:
- `GET /api/notifications/summary`
- `POST /api/notifications/read`
通知用于提示待处理事项、未读状态或运行中任务概况。具体展示取决于前端页面。
## HITL 日志
HITL 决策日志独立管理:
- `GET /api/hitl/pending`
- `GET /api/hitl/logs`
- `GET /api/hitl/logs/:id`
- `DELETE /api/hitl/logs`
- `POST /api/hitl/decision`
- `POST /api/hitl/dismiss`
建议将 HITL 日志与平台审计结合,用于复盘 Agent 为什么执行或没有执行某个工具。
## 保留策略
建议:
- 审计日志保留 15 到 90 天,按组织要求调整。
- 工具执行记录保留 30 到 180 天。
- C2、WebShell、上传附件和任务结果按项目周期单独清理。
- 导出日志时注意脱敏和访问权限。
## 运维巡检
每周检查:
- 是否有异常登录失败。
- 是否有未授权配置变更。
- 长时间运行或失败率高的工具。
- 外部 MCP 连接状态。
- 数据库文件大小和磁盘空间。
每次演练结束:
- 导出必要审计证据。
- 删除无用 WebShell/C2 会话和 payload。
- 清理上传附件和临时工作区。
- 归档报告、漏洞和项目事实。
## 审计和监控的边界
两者经常被混用,但语义不同:
- 审计回答“谁在平台上做了什么管理动作”。
- 监控回答“工具调用运行得怎么样”。
- HITL 日志回答“某个工具调用为什么被放行、修改或拒绝”。
- 对话过程详情回答“Agent 当时如何推理和串联步骤”。
一次安全复盘通常要把四类信息合在一起看。只看审计,会漏掉具体工具输出;只看监控,会漏掉谁修改了配置。
## 关键事件解释
建议重点关注这些事件类型:
| 事件 | 为什么重要 |
| --- | --- |
| 登录失败 | 暴力尝试、密码泄露或误配置 |
| 修改密码 | 所有旧 session 会被撤销,可能影响正在使用的人 |
| 更新配置 | 可能改变模型、工具、C2、知识库、审计策略 |
| 外部 MCP 变更 | 新工具可能拥有本机或远端执行能力 |
| C2 listener/task | 直接影响授权目标和网络暴露面 |
| WebShell 连接变更 | 可能引入真实业务系统执行通道 |
| HITL 拒绝 | 说明 Agent 或用户请求触达风险边界 |
## 日志保留不是越久越好
安全工具日志往往包含目标、漏洞、路径、命令输出和组织内部信息。保留时间应平衡复盘价值与泄露风险:
- 短期演练:15-30 天。
- 持续红队平台:90-180 天。
- 合规要求:按组织规范归档,但导出后应加密。
如果没有专门日志平台,不要无限期保留 SQLite 中的所有明细。
## 源码锚点
- 审计服务:`internal/audit/service.go`
- 审计脱敏:`internal/audit/sanitize.go`
- 审计保留:`internal/audit/retention.go`
- 审计接口:`internal/handler/audit.go`
- 监控 reconcile`internal/monitor/reconcile.go`
- 监控接口:`internal/handler/monitor.go`
- HITL 日志:`internal/handler/hitl_logs.go`
+172
View File
@@ -0,0 +1,172 @@
# 内置 C2 使用说明
内置 C2 用于授权环境中的会话管理、任务下发、payload 生成和结果回收。不使用时建议关闭。
```yaml
c2:
enabled: false
```
## 功能组成
主要对象:
- Listener:监听器,负责接收会话。
- Session:上线会话。
- Task:下发给会话的任务。
- Payload:生成的载荷或 one-liner。
- Profile:通信配置模板。
- Event:监听器、会话、任务产生的事件。
- File:给 implant 下载或任务结果回收的文件。
Web API 前缀是 `/api/c2`。关闭 C2 时接口返回 `503 c2_disabled`
## 监听器
常用接口:
- `GET /api/c2/listeners`
- `POST /api/c2/listeners`
- `POST /api/c2/listeners/:id/start`
- `POST /api/c2/listeners/:id/stop`
- `DELETE /api/c2/listeners/:id`
建议给监听器使用清晰命名,标明演练项目、网络区域和授权范围。
## 会话
常用接口:
- `GET /api/c2/sessions`
- `GET /api/c2/sessions/:id`
- `PUT /api/c2/sessions/:id/sleep`
- `DELETE /api/c2/sessions/:id`
`sleep` 用于调整会话轮询间隔。间隔越短,交互越实时,但流量和暴露面更高。
## 任务
常用接口:
- `GET /api/c2/tasks`
- `POST /api/c2/tasks`
- `POST /api/c2/sessions/:id/tasks`
- `POST /api/c2/tasks/:id/cancel`
- `GET /api/c2/tasks/:id/wait`
- `GET /api/c2/tasks/:id/result-file`
任务应和授权目标一致。高风险任务建议走 HITL,并在审计日志中保留操作痕迹。
## Payload
常用接口:
- `POST /api/c2/payloads/oneliner`
- `POST /api/c2/payloads/build`
- `GET /api/c2/payloads/:id/download`
生成前确认:
- 回连地址是否正确。
- 平台和架构是否匹配。
- 是否需要代理、sleep、profile。
- 文件是否只在授权环境分发。
## 文件
常用接口:
- `POST /api/c2/files/upload`
- `GET /api/c2/files`
- `GET /api/c2/tasks/:id/result-file`
上传文件可供 implant 下载。结果文件可能包含敏感信息,应按项目保密级别保存和清理。
## MCP 工具
C2 启用后会注册相关 MCP 工具,供 Agent 管理监听器、会话、任务、payload 等。建议:
- 不把 C2 工具加入全局免审批白名单。
- 在角色提示词中限制项目、目标、任务类型。
- 对执行命令、上传文件、生成 payload 的步骤开启人工审批。
## 安全建议
- 仅在授权环境启用。
- 不在公网暴露管理 Web。
- Listener 暴露端口与 Web 管理端口分离。
- 定期清理会话、任务、payload 和事件。
- 演练结束后关闭监听器并删除无用 payload。
- 保留必要审计证据,但不要长期保存敏感输出。
## 排错
监听器无法启动:
- 端口被占用。
- 权限不足,低端口需要额外权限。
- 防火墙或安全组未放行。
会话不上线:
- payload 回连地址错误。
- 目标无法访问监听器。
- TLS/Profile 不匹配。
- 被安全产品阻断。
任务无结果:
- 会话 sleep 较长。
- 会话已离线。
- 命令在目标端卡住。
- 结果过大,需要通过结果文件下载。
## 生命周期视角
C2 的正确使用不是“创建 listener 然后下命令”,而是一个生命周期:
1. 授权确认:项目、目标、时间窗口、允许动作。
2. Profile 设计:通信方式、sleep、回连地址、文件通道。
3. Listener 启动:确认端口、网络路径和日志。
4. Payload 生成:记录 hash、用途、投递方式。
5. Session 接入:确认目标身份、权限和环境。
6. Task 下发:只执行与授权目标一致的任务。
7. 结果归档:必要输出写入项目事实或报告。
8. 清理:停止 listener、删除 payload、清理 session/task/event。
跳过前两步会导致后续每个操作都不可审计。
## 任务分级
| 等级 | 示例 | 审批建议 |
| --- | --- | --- |
| L1 只读识别 | `whoami`、主机名、当前目录 | 可由审计 Agent 放行 |
| L2 环境枚举 | 网络接口、进程、用户组 | 建议人工或严格审计 |
| L3 文件访问 | 读取配置、下载结果文件 | 人工确认目标和路径 |
| L4 执行变更 | 上传文件、修改 sleep、运行脚本 | 人工审批 |
| L5 持久化/横向/破坏 | 自启、凭证、删除、加密、扩散 | 默认拒绝,除非授权明确 |
把这个分级写进 HITL 提示词,比单纯“危险则拒绝”更可操作。
## 事件复盘
一次 C2 操作复盘至少回答:
- 哪个 listener 接收了哪个 session
- payload 是谁生成的,什么时候生成的?
- session 属于哪个授权目标?
- 下发了哪些 task
- task 输出是否写入报告或项目事实?
- 是否停止 listener 并清理 payload
如果这些问题答不上来,说明 C2 过程管理还不够闭环。
## 源码锚点
- C2 Manager`internal/c2/manager.go`
- Listener`internal/c2/listener.go`
- HTTP Listener`internal/c2/listener_http.go`
- TCP Listener`internal/c2/listener_tcp.go`
- Payload`internal/c2/payload_builder.go`
- Handler`internal/handler/c2.go`
- MCP 工具:`internal/app/c2_tools.go`
+194
View File
@@ -0,0 +1,194 @@
# 配置画像
[English](../en-US/configuration-profiles.md)
本文给出几套常用配置画像。它们不是完整 `config.yaml`,而是部署时最容易影响安全和可用性的关键段落。
## 本地开发画像
目标:方便调试,允许较多本地能力。
常用启动:
```bash
chmod +x run.sh && ./run.sh
```
```yaml
server:
host: 127.0.0.1
port: 8080
tls_enabled: true
tls_auto_self_sign: true
auth:
password: "dev-only-change-me"
audit:
enabled: true
retention_days: 7
c2:
enabled: false
multi_agent:
enabled: true
eino_skills:
filesystem_tools: true
```
适用:
- 本地功能开发。
- 调试前端和 Handler。
- 调试 Skills、本地文件工具。
不适用:
- 多人共享。
- 公网访问。
## 内网团队画像
目标:团队共享,保留审计,限制高风险能力。
```yaml
server:
host: 127.0.0.1
port: 8080
tls_enabled: false
auth:
password: "<long-random-password>"
audit:
enabled: true
retention_days: 30
monitor:
retention_days: 90
c2:
enabled: false
mcp:
enabled: false
hitl:
default_reviewer: human
tool_whitelist: [read_file, glob, grep, tool_search]
```
配合:
- Nginx/Traefik 终止 HTTPS。
- 反向代理 IP 白名单。
- 定期备份 `data/`
## 只启用知识库画像
目标:把 CyberStrikeAI 作为知识增强助手,尽量关闭攻击面。
```yaml
c2:
enabled: false
mcp:
enabled: false
knowledge:
enabled: true
base_path: knowledge_base
retrieval:
top_k: 5
similarity_threshold: 0.4
multi_agent:
eino_skills:
filesystem_tools: false
```
建议:
- 角色只绑定知识库和只读工具。
- 禁用外部 MCP。
- 不保存真实客户敏感材料。
## 高审计生产画像
目标:生产红队或长期安全平台。
```yaml
auth:
password: "<managed-secret>"
session_duration_hours: 8
audit:
enabled: true
retention_days: 90
max_detail_bytes: 8192
monitor:
retention_days: 180
hitl:
default_reviewer: human
retention_days: 180
tool_whitelist: [read_file, glob, grep, tool_search]
c2:
enabled: false
multi_agent:
eino_callbacks:
enabled: true
mode: log_only
sse_trace_to_client: false
```
配合:
- 反向代理认证。
- 独立运行用户。
- 日志采集。
- 备份加密。
- 明确项目结束清理流程。
## C2 演练画像
目标:只在授权演练窗口临时启用 C2。
```yaml
c2:
enabled: true
hitl:
default_reviewer: human
tool_whitelist: [read_file, glob, grep, tool_search]
audit:
enabled: true
monitor:
retention_days: 180
```
操作要求:
- 演练前确认授权范围。
- Listener 端口和 Web 管理端口分离。
- 演练结束执行 C2 清理 Runbook。
- 结束后恢复 `c2.enabled: false`
## 外部 MCP 自动化画像
目标:接入可信的内部工具服务。
```yaml
external_mcp:
servers: {}
multi_agent:
eino_middleware:
tool_search_enable: true
tool_search_min_tools: 20
hitl:
default_reviewer: audit_agent
tool_whitelist: [read_file, glob, grep, tool_search]
```
建议:
- 每个 MCP 工具都写清楚 schema。
- 高风险 MCP 工具不进白名单。
- stdio MCP 用独立工作目录。
- HTTP MCP 必须有认证。
## 画像选择决策
| 需求 | 选择 |
| --- | --- |
| 单人开发 | 本地开发画像 |
| 多人内网使用 | 内网团队画像 |
| 文档/知识问答 | 只启用知识库画像 |
| 长期生产平台 | 高审计生产画像 |
| 授权 C2 演练 | C2 演练画像 |
| 接内部工具平台 | 外部 MCP 自动化画像 |
+275
View File
@@ -0,0 +1,275 @@
# 配置参考
CyberStrikeAI 的主配置文件是 `config.yaml`。大多数配置也可以在 Web 的“系统设置”中修改,保存后再应用。生产环境中,建议把敏感值放在受控配置系统中,并限制 `config.yaml` 的文件权限。
## 基础配置
```yaml
version: "v1.6.51"
server:
host: 0.0.0.0
port: 8080
tls_enabled: true
tls_auto_self_sign: true
auth:
password: "change-me"
session_duration_hours: 12
log:
level: info
output: stdout
```
- `version`:前端展示版本。
- `server.host/port`Web 服务监听地址和端口。
- `server.tls_*`HTTPS 配置。生产环境建议使用 `tls_cert_path``tls_key_path`
- `auth.password`Web 登录密码,必须改为强密码。
- `auth.session_duration_hours`:登录会话有效期。
- `log.output`:可以是 `stdout``stderr` 或文件路径。
## 模型配置
```yaml
openai:
provider: openai
base_url: https://api.openai.com/v1
api_key: sk-...
model: gpt-4.1
max_total_tokens: 120000
reasoning:
mode: on
effort: high
allow_client_reasoning: true
profile: openai_compat
```
- `provider``openai` 表示 OpenAI 兼容接口;`claude` 会桥接到 Anthropic Claude Messages API。
- `base_url/api_key/model`:主模型配置。
- `max_total_tokens`:上下文压缩、攻击链构建、多代理摘要等共用的总预算。
- `reasoning`:控制推理扩展字段。不同网关支持差异较大,异常时先尝试 `mode: off`
## Agent
```yaml
agent:
max_iterations: 12000
tool_timeout_minutes: 60
shell_no_output_timeout_seconds: 1200
workspace_root_dir: ""
system_prompt_path: ""
```
- `max_iterations`:单代理、多代理主执行器和子代理的默认迭代上限。
- `tool_timeout_minutes`:单次工具最长运行时间。
- `shell_no_output_timeout_seconds`Shell 长时间无输出时终止。
- `workspace_root_dir`:会话工作区根目录,建议不要设置到系统 `/tmp`
- `system_prompt_path`:单代理系统提示词覆盖文件。
## HITL
```yaml
hitl:
default_reviewer: audit_agent
retention_days: 90
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
audit_model:
provider: ""
base_url: ""
api_key: ""
model: ""
```
- `default_reviewer``human``audit_agent`
- `tool_whitelist`:全局免审批工具列表,会与会话白名单合并。
- `audit_model`:审计 Agent 独立模型;留空复用主模型。
- `audit_agent_prompt` / `audit_agent_prompt_review_edit`:可覆盖默认审批策略。
更多策略见 [人机协同最佳实践](hitl-best-practices.md)。
## 多代理
```yaml
multi_agent:
enabled: true
robot_default_agent_mode: eino_single
batch_use_multi_agent: false
eino_skills:
disable: false
filesystem_tools: true
skill_tool_name: skill
```
支持模式:
- `eino_single`Eino 单代理。
- `deep`DeepAgent 风格多代理。
- `plan_execute`:规划、执行、重规划。
- `supervisor`:主管代理转交子代理。
`agents_dir` 指向 Markdown 子代理目录。单个代理可在 front matter 中设置 `tools``bind_role``max_iterations`
## 工具与 MCP
```yaml
security:
tools_dir: tools
tool_description_mode: full
mcp:
enabled: false
host: 0.0.0.0
port: 8081
auth_header: "X-MCP-Token"
auth_header_value: ""
external_mcp:
servers: {}
```
- `security.tools_dir`:内置工具 YAML 目录。
- `tool_description_mode``short` 更省 token`full` 更完整。
- `mcp.enabled`:是否启动独立 HTTP MCP 服务。
- `mcp.auth_header_value`:外部调用 MCP 时的共享密钥,生产环境必须设置。
- `external_mcp.servers`:外部 MCP 联邦配置。
工具 YAML 规则见 `tools/README.md`
## 知识库
```yaml
knowledge:
enabled: false
base_path: knowledge_base
embedding:
provider: openai
model: text-embedding-v4
base_url: ""
api_key: ""
retrieval:
top_k: 5
similarity_threshold: 0.4
indexing:
chunk_size: 512
chunk_overlap: 50
batch_size: 10
```
启用后会注册知识库检索工具,并开放管理接口。详细说明见 [知识库](knowledge-base.md)。
## 数据库
```yaml
database:
path: data/conversations.db
knowledge_db_path: data/knowledge.db
```
默认使用 SQLite。`knowledge_db_path` 为空时可复用会话数据库;独立文件更便于迁移知识库。
## 审计与监控
```yaml
audit:
enabled: true
retention_days: 15
max_detail_bytes: 8192
monitor:
retention_days: 90
```
- `audit` 记录平台操作,不记录对话正文和每次工具调用正文。
- `monitor` 管理工具执行记录保留时间。
## C2、WebShell、项目
```yaml
c2:
enabled: true
project:
enabled: true
fact_index_max_runes: 65000
```
- `c2.enabled`:关闭后不启动 C2 监听器,也不注册 C2 MCP 工具。
- WebShell 连接配置存 SQLite,没有单独的主配置开关。
- `project` 控制跨对话事实黑板注入预算。
## 机器人
`robots` 支持个人微信 iLink、企业微信、钉钉、飞书、Telegram、Slack、Discord、QQ。详细配置步骤见 [机器人使用说明](robot.md)。
## 配置修改建议
- 先在测试环境验证模型、MCP、知识库和高风险工具。
- 改动 `tools_dir``roles_dir``skills_dir``agents_dir` 后,检查 Web 页面是否能列出对应资源。
- 生产环境避免开启不需要的 C2、WebShell、终端和外部 MCP。
- 修改敏感配置后,检查审计页面是否有异常登录或配置变更记录。
## 配置应用机制
配置不是所有字段都同等“热更新”。`/api/config/apply` 会做一组协调动作:更新模型配置、工具描述模式、重新注册部分 MCP 工具、初始化或更新知识库、重启机器人连接、按配置启停 C2。这个逻辑在 `internal/handler/config.go` 中由 `ConfigHandler` 协调。
实务判断:
| 配置段 | 应用后通常立即生效 | 需要额外动作 |
| --- | --- | --- |
| `openai` | 新请求使用新模型配置 | 旧的流式请求不会被强制切换 |
| `agent.max_iterations` | 新 Agent 任务生效 | 已运行任务按启动时状态继续 |
| `security.tool_description_mode` | 工具重新暴露时生效 | 模型已有上下文不会回滚 |
| `hitl.tool_whitelist` | 新工具调用审批判断生效 | 已挂起审批不自动重判 |
| `knowledge.enabled` | 会尝试初始化/更新组件 | 启用后仍需扫描和索引 |
| `knowledge.embedding` | 检索器/索引器配置更新 | 已有向量通常需要重建索引 |
| `robots` | 会触发连接重启 | 平台回调配置仍需在平台侧正确 |
| `c2.enabled` | 会协调 C2 runtime | 已暴露端口和会话要人工确认 |
| `server.port/tls` | 通常需要重启进程 | 监听地址不是普通热更新 |
## 配置优先级和派生关系
几个字段有“留空复用”的关系:
- `vision.api_key/base_url/provider` 留空时复用 `openai`
- `hitl.audit_model` 留空时复用 `openai`
- `knowledge.embedding.base_url/api_key` 留空时复用主模型或 embedding 默认配置。
- `knowledge.retrieval.rerank.base_url/api_key` 留空时复用 embedding/openai。
- `database.knowledge_db_path` 留空时可以复用主会话数据库,但独立文件更利于备份。
这类配置排障时不要只看子配置段,也要看它会回落到哪个上级配置。
## 参数取值建议
| 参数 | 保守值 | 激进值 | 判断依据 |
| --- | --- | --- | --- |
| `agent.tool_timeout_minutes` | 10-30 | 60+ | 扫描工具是否常跑长任务 |
| `shell_no_output_timeout_seconds` | 300-600 | 1200+ | 工具是否长时间静默 |
| `knowledge.indexing.batch_size` | 5-10 | 20+ | embedding 服务批量限制 |
| `knowledge.indexing.rate_limit_delay_ms` | 300-800 | 0-100 | 服务商 RPM 和 429 情况 |
| `retrieval.top_k` | 3-5 | 8-12 | 内容质量和上下文预算 |
| `similarity_threshold` | 0.35-0.45 | 0.5+ | 召回优先还是精度优先 |
| `audit.retention_days` | 15-30 | 90+ | 合规要求和磁盘空间 |
| `monitor.retention_days` | 30-90 | 180+ | 是否需要长周期复盘 |
## 变更前后验证模板
修改配置前记录:
```text
变更目的:
涉及配置段:
预期影响:
回滚方式:
验证接口:
```
修改后验证:
```bash
curl -k https://127.0.0.1:8080/api/auth/validate \
-H "Authorization: Bearer <token>"
```
再按配置类型验证模型、工具、知识库、C2 或机器人。不要只看 Web 保存成功提示。
## 源码锚点
- 配置结构:`internal/config/config.go`
- 环境变量展开:`internal/config/envexpand.go`
- Web 配置接口:`internal/handler/config.go`
- 路由注册:`internal/app/app.go`
- C2 配置协调:`internal/app/c2_lifecycle.go`
+115
View File
@@ -0,0 +1,115 @@
# 贡献规范
[English](../en-US/contributing-guide.md)
本文定义向 CyberStrikeAI 增加功能、接口、工具、前端页面或文档时的基本要求。
## 总原则
- 新功能要有文档入口。
- 新 API 要更新 OpenAPI。
- 新前端文案要补中英文 i18n。
- 新配置要说明是否支持热应用。
- 新高风险工具要说明 HITL 策略。
- 新数据库字段要兼容旧库。
- 新长任务要有状态、取消或恢复策略。
## 新增 API Checklist
- Handler 参数校验明确。
- 错误响应包含稳定 `error` 和可读 `message`
- 接口受认证保护,除非明确是平台回调。
- 修改类接口写审计。
- 长任务写监控或任务状态。
- 更新 `internal/handler/openapi.go`
- 更新 API 文档或 Recipe。
- 增加 Handler 测试。
## 新增配置 Checklist
- `config.Config` 结构体有字段。
- `config.yaml` 示例有注释。
- 省略字段时有安全默认值。
- 旧配置能启动。
- 说明是否热应用。
- Web 设置页不会误删未知字段。
- 如影响高风险能力,更新安全文档。
## 新增工具 Checklist
适用于 YAML 工具和 Go 内置 MCP 工具。
- 工具名稳定、具体、避免重名。
- `short_description` 能被 `tool_search` 搜到。
- 输入 schema 明确,不用裸 `cmd` 包所有行为。
- 输出可读且结构稳定。
- 超时和错误路径可控。
- 高风险操作不进全局白名单。
- 文档说明使用场景和风险。
## 新增前端页面 Checklist
- 复用现有 `apiFetch`、modal、通知和状态样式。
- 所有可见文案补 `zh-CN.json``en-US.json`
- 有 loading、empty、error 状态。
- 删除/高风险操作有确认。
- 长文本和英文按钮不溢出。
- 浏览器控制台无错误。
## 新增数据库变更 Checklist
- 迁移幂等。
- 旧库可升级。
- 字段默认值合理。
- 大表索引谨慎。
- 测试空库和旧库。
- 发布说明提醒备份。
## 新增高风险能力 Checklist
高风险包括:Shell、WebShell、C2、外部 MCP 写入/执行、凭证访问、批量扫描。
必须回答:
- 谁能调用?
- 是否需要 HITL
- 审计记录什么?
- 如何取消?
- 如何清理?
- 如何禁用?
- 默认是否关闭?
## 文档要求
每个重要功能至少补:
- 用途。
- 配置。
- 操作流程。
- 风险边界。
- 排错。
- 源码锚点。
中英文文档要保持文件名一致,分别放在:
```text
docs/zh-CN/
docs/en-US/
```
更新导航:
- `docs/README.md`
- `docs/zh-CN/README.md`
- `docs/en-US/README.md`
## Review 关注点
代码评审优先看:
- 行为回归。
- 安全边界。
- 旧数据兼容。
- 错误处理。
- 测试缺口。
- 文档和 OpenAPI 是否同步。
+249
View File
@@ -0,0 +1,249 @@
# 部署指南
本文说明 CyberStrikeAI 的常见部署方式。生产环境部署前,请先阅读 [安全模型](security-model.md),确认授权范围、认证、HITL、审计和高风险功能开关。
## 部署前准备
基础依赖:
- Go:用于源码运行或构建二进制。
- Python:部分 MCP 服务或工具脚本需要 Python 运行环境。
- SQLite:默认使用文件型数据库,无需单独服务。
- 安全工具:`tools/` 中的 YAML 只是工具定义,实际命令如 `nmap``sqlmap``nuclei` 仍需安装到系统 PATH。
- 模型服务:需要 OpenAI 兼容 API,或配置 `openai.provider: claude` 走 Claude 桥接。
建议目录:
```text
CyberStrikeAI-main/
config.yaml
data/
tools/
roles/
skills/
agents/
knowledge_base/
```
`data/``config.yaml`、自定义 `tools/roles/skills/agents/knowledge_base` 是最重要的持久化内容,升级前应备份。
## 快速启动
仓库提供 `run.sh`,适合本地体验和小规模部署:
```bash
chmod +x run.sh && ./run.sh
```
默认配置中 `server.tls_enabled: true``tls_auto_self_sign: true`,访问地址通常是:
```text
https://127.0.0.1:8080/
```
自签证书会触发浏览器安全提示,这是本地测试的正常现象。生产环境建议配置真实证书。
`run.sh` 是最常用的启动入口,适合:
- 本机体验。
- 开发调试。
- 小团队临时内网使用。
- 升级后快速验证新版是否能启动。
如果需要长期运行、开机自启、日志托管或进程崩溃自动恢复,建议改用 systemd 托管二进制。
## 源码运行
适合开发调试:
```bash
go run ./cmd/server --config config.yaml
```
如果依赖下载较慢,可以先配置 Go 代理:
```bash
go env -w GOPROXY=https://goproxy.cn,direct
```
## 构建二进制
```bash
go build -o cyberstrike-ai ./cmd/server
./cyberstrike-ai --config config.yaml
```
交付二进制时仍需要携带:
- `web/templates/`
- `web/static/`
- `tools/`
- `roles/`
- `skills/`
- `agents/`
- `config.yaml`
## HTTPS
本地测试可以使用自签:
```yaml
server:
tls_enabled: true
tls_auto_self_sign: true
```
生产环境建议使用证书文件:
```yaml
server:
host: 0.0.0.0
port: 8080
tls_enabled: true
tls_cert_path: /etc/letsencrypt/live/example.com/fullchain.pem
tls_key_path: /etc/letsencrypt/live/example.com/privkey.pem
```
启用 TLS 后,同端口 HTTP 请求默认会 308 跳转到 HTTPS。若前面有反向代理负责 TLS,可以关闭应用内 TLS,在代理层处理 HTTPS。
## 反向代理
Nginx 示例:
```nginx
server {
listen 443 ssl http2;
server_name cyberstrike.example.com;
ssl_certificate /etc/letsencrypt/live/cyberstrike.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cyberstrike.example.com/privkey.pem;
client_max_body_size 200m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
}
}
```
`proxy_buffering off` 对 SSE 流式输出和 WebSocket 终端更友好。
## systemd
示例服务:
```ini
[Unit]
Description=CyberStrikeAI
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/CyberStrikeAI
ExecStart=/opt/CyberStrikeAI/cyberstrike-ai --config /opt/CyberStrikeAI/config.yaml
Restart=on-failure
RestartSec=5
Environment=GIN_MODE=release
[Install]
WantedBy=multi-user.target
```
启用:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now cyberstrikeai
sudo journalctl -u cyberstrikeai -f
```
## 数据与备份
重点备份:
- `config.yaml`
- `data/conversations.db`
- `data/knowledge.db`
- `data/eino-checkpoints/`
- 自定义 `tools/roles/skills/agents/knowledge_base`
- 上传文件目录 `chat_uploads/`
SQLite 热备份时最好先停止服务,或至少复制 `*.db``*.db-wal``*.db-shm` 三类文件。
## 升级
推荐流程:
1. 停止服务。
2. 备份 `config.yaml``data/` 和自定义目录。
3. 拉取或替换新版代码/二进制。
4. 保留原配置,按新版 `config.yaml` 示例补新增字段。
5. 启动服务,检查登录、模型测试、工具列表、知识库状态。
仓库提供 `upgrade.sh`,适合无兼容性问题的快速升级;生产环境仍建议先备份再运行。
## 回滚
回滚时同时恢复:
- 上一版本二进制或代码。
- 升级前的 `config.yaml`
- 升级前的 `data/`
如果新版已经写入数据库结构变更,单独回滚二进制可能不够,建议整体恢复备份。
## 生产部署决策表
| 场景 | 推荐部署 | 关键配置 | 不建议 |
| --- | --- | --- | --- |
| 单人本机测试 | `./run.sh` + 自签 HTTPS | `tls_auto_self_sign: true` | 暴露公网 |
| 小团队内网 | 二进制 + systemd + 内网 HTTPS | 强密码、审计、备份、限制来源 IP | 所有人共用弱密码 |
| 生产红队平台 | 反向代理 + 独立运行用户 + 日志采集 | 真实证书、反向代理认证、C2 按需启用 | Web 管理面直连公网 |
| 只做知识库/对话 | 关闭 C2,禁用不需要的外部 MCP | `c2.enabled: false` | 默认开启所有高风险模块 |
| 多工具自动化 | 独立工作目录 + HITL + 工具白名单 | `workspace_root_dir``hitl``monitor` | 让 Agent 拥有全局 Shell 权限且免审批 |
## 运行时文件分层
部署时最容易出问题的是“代码、配置、运行数据混在一起”。建议按下面方式理解:
- 可替换:二进制、`web/`、默认 `tools/roles/skills/agents/docs`
- 必须保留:`config.yaml``data/`、自定义工具/角色/技能/子代理、`knowledge_base/``chat_uploads/`
- 可清理但要谨慎:`data/eino-checkpoints/`、临时 workspace、旧 payload、旧工具执行记录。
升级时如果覆盖整个目录,应先把自定义目录和 `data/` 移出或备份。很多“升级后配置丢了”的问题,本质是把运行态文件当成发布包的一部分覆盖掉。
## 启动后验收清单
启动成功不代表可用,至少做下面检查:
1. 打开 `/`,确认 HTTPS/反向代理没有跳转循环。
2. 登录后访问 `/api/auth/validate`,确认会话可用。
3. 系统设置中执行模型测试。
4. 打开工具列表,确认 `tools/` 被加载,核心工具 schema 正常。
5. 若启用知识库,访问知识库页,确认 `index-status` 正常。
6. 若启用外部 MCP,查看外部 MCP 状态和工具是否出现在对话侧。
7. 若启用 C2,只在授权网络启动一个测试 listener,并确认停止/删除正常。
8. 查看审计页面,确认登录和配置读取有记录。
## 反向代理容易踩的坑
- SSE 被缓冲:表现为 Agent 一直不输出,结束时一次性吐出。关闭 `proxy_buffering`
- WebSocket 失败:终端或事件流异常。检查 `Upgrade``Connection` 头。
- HTTPS 混用:应用内 TLS 和 Nginx TLS 同时启用时,`proxy_pass` 协议必须匹配。
- 上传失败:调大 `client_max_body_size`,并检查应用侧上传限制。
- 308 循环:如果应用启用同端口 HTTPS 跳转,而代理又用 HTTP 回源,需要关闭应用 TLS 或改代理回源 HTTPS。
## 源码锚点
- 服务组装和路由:`internal/app/app.go`
- HTTPS 和自签证书:`internal/app/main_server_tls.go`
- HTTP 到 HTTPS 跳转:`internal/app/main_server_http_redirect.go`
- 配置结构和默认值:`internal/config/config.go`
- 配置应用逻辑:`internal/handler/config.go`
+178
View File
@@ -0,0 +1,178 @@
# 开发者指南
本文面向二次开发者,说明项目结构、启动方式、主要扩展点和开发习惯。
## 项目结构
```text
cmd/server/ Web 服务入口
internal/app/ 应用组装、路由注册、MCP 工具注册
internal/handler/ HTTP Handler
internal/database/ SQLite 数据访问
internal/security/ 认证、限流、Shell 执行
internal/mcp/ MCP Server、外部 MCP 管理
internal/multiagent/ Eino 单代理、多代理、中间件
internal/workflow/ 图编排运行时
internal/knowledge/ 知识库索引与检索
internal/c2/ 内置 C2
internal/project/ 项目事实黑板
web/static/ 前端 JS/CSS/资源
web/templates/ HTML 模板
tools/ 命令工具 YAML
roles/ 角色 YAML
agents/ 多代理 Markdown 定义
skills/ Agent Skills
docs/ 项目文档
```
## 启动开发环境
```bash
go run ./cmd/server --config config.yaml
```
前端是静态页面,模板在 `web/templates/`JS/CSS 在 `web/static/`。修改后刷新浏览器即可验证,多数场景不需要单独前端构建。
## 路由
路由集中在 `internal/app/app.go``registerRoutes` 中。新增业务接口通常需要:
1.`internal/handler/` 增加 Handler。
2.`internal/database/` 增加必要的数据访问。
3.`internal/app/app.go` 构造并注册路由。
4. 如需对外文档,更新 `internal/handler/openapi.go`
5. 如需前端调用,更新 `web/static/js/`
## 数据库
默认 SQLite。新增表或字段时:
- 将迁移逻辑放到数据库初始化或对应模块迁移函数。
- 保持向后兼容,避免破坏已有 `data/conversations.db`
- 添加针对迁移和核心查询的单测。
## 新增工具
命令工具优先通过 `tools/*.yaml` 增加,不必改 Go 代码。需要 Go 内置工具时:
- 在合适模块注册 MCP Tool。
- 定义清晰 `InputSchema`
- 处理超时、错误、审计和 HITL 上下文。
- 避免把高风险操作默认免审批。
工具 YAML 规则见 `tools/README.md`
## 新增角色
角色通过 `roles/*.yaml` 管理。常见字段包括名称、描述、系统提示词和工具列表。角色应遵循最小工具集原则,不要把所有工具默认交给专用角色。
## 新增子代理
多代理子 Agent 放在 `agents/*.md`。Front matter 示例:
```yaml
---
name: Vulnerability Triage
id: vulnerability-triage
description: 对漏洞线索进行验证、定级和修复建议整理
tools:
- nmap
- nuclei
bind_role: 综合漏洞扫描
max_iterations: 200
---
```
正文是系统提示词。主代理可使用固定文件名或 `kind: orchestrator`
## 新增 Skill
Skill 放在 `skills/<name>/SKILL.md`。用于提供专题能力、流程说明或附属资料。详见 [Skills 指南](skills-guide.md)。
## 前端开发
前端代码按功能拆分在 `web/static/js/`。新增页面或模块时:
- 复用现有 `apiFetch`、modal、通知、i18n 工具。
- 同步更新 `web/static/i18n/zh-CN.json``en-US.json`
- 避免把敏感 Key 放到前端。
- 高风险按钮要有确认和清晰状态反馈。
i18n 规范见 [前端国际化方案](frontend-i18n.md)。
## OpenAPI
`internal/handler/openapi.go` 维护内置 OpenAPI 输出。新增公开接口后建议同步补:
- path
- method
- summary/description
- requestBody
- responses
- security
这样 `/api-docs` 才能反映最新接口。
## 开发习惯
- 优先保持现有模块边界。
- 大模型、外部 API、文件系统、Shell 相关改动必须考虑超时和错误路径。
- 高风险能力要接入 HITL 或至少有清晰审计。
- 代码变更后运行相关包单测。
## 新增业务模块的完整配方
不要只加一个 Handler。完整模块通常要考虑:
1. 数据模型:是否需要 SQLite 表和迁移。
2. Handler:HTTP 参数、错误码、分页、过滤。
3. Audit:管理动作是否要审计。
4. Monitor:如果会执行长任务,是否要记录执行状态。
5. MCP:是否要暴露给 Agent。
6. HITL:MCP 工具是否有审批边界。
7. OpenAPI:是否更新 `/api/openapi/spec`
8. Frontend:是否需要 i18n、状态、空态、错误提示。
9. Tests:数据库、handler、边界条件。
10. Docs:配置、使用、排错和安全影响。
少做其中一项,后面通常会以“用户看不懂”“Agent 调错”“接口没人会用”的形式返工。
## Handler 错误设计
建议错误响应保持:
```json
{
"error": "machine_readable_code",
"message": "给用户看的说明"
}
```
不要只返回 Go error 字符串。前端需要稳定字段,用户需要可操作建议,日志需要详细错误。
## 长任务设计
扫描、索引、批量任务、C2 等都可能长时间运行。设计时要回答:
- 是否能取消?
- 是否能查询进度?
- 失败后能否重试?
- 结果写在哪里?
- 页面刷新后状态是否还在?
- 是否会阻塞 HTTP 请求?
如果答案是否定的,应考虑接入任务表、事件流或监控模块。
## 测试优先级
最值得补测试的地方:
- 配置热应用。
- HITL 审批分支。
- Shell 超时和无输出。
- 外部 MCP 失败恢复。
- 知识库索引和检索后处理。
- WebShell 编码和系统识别。
- SQLite 迁移兼容。
这些地方比普通 getter/setter 更容易出现真实用户故障。
+122
View File
@@ -0,0 +1,122 @@
# 人机协同(HITL)最佳实践
[English](../en-US/hitl-best-practices.md)
人机协同用于在 Agent 执行工具前做审批拦截。它适合控制高风险操作、保留审计痕迹,并在人工审计压力过大时让审计 Agent 接管常规审批。
## 配置入口
Web 端进入 **系统设置 → 人机协同**,可配置:
- 全局默认审批方:`human``audit_agent`
- 审计 Agent 专用模型:`hitl.audit_model`
- 已决策审计日志保留天数
- 免审批工具白名单:`hitl.tool_whitelist`
- 审批模式与审查编辑模式的审计提示词
对应的 `config.yaml` 示例:
```yaml
hitl:
default_reviewer: human
audit_model:
provider: ""
base_url: ""
api_key: ""
model: "" # 可填小模型;留空复用 openai.model
retention_days: 90
tool_whitelist: [read_file, list_dir, glob, grep, tool_search]
```
`audit_model` 的字段可以只填一部分。空字段会自动继承主 `openai` 配置,因此常见做法是只填 `model`,让审计 Agent 使用更便宜的小模型。
## 推荐审批策略
### 1. 默认人工,逐步放权
刚开始建议:
- `default_reviewer: human`
- 仅把明显只读工具加入 `tool_whitelist`
- 对写文件、执行命令、C2 任务、WebShell 操作保持人工审批
运行一段时间后,观察审计日志,把重复、低风险、误报少的工具加入白名单。
### 2. 人工审不过来时,用小模型接管常规审批
当待审批积压明显时,可以切换为:
```yaml
hitl:
default_reviewer: audit_agent
audit_model:
model: "your-small-reviewer-model"
```
建议让小模型处理:
- 只读查询
- 信息收集
- 端口与服务扫描
- 目录枚举
- 无破坏性的验证命令
仍建议人工处理:
- 删除、覆盖、清空数据
- 修改权限、密码、账号
- 持久化、横向移动、C2 高风险任务
- 对生产目标的写入操作
### 3. 用提示词定义组织策略
审计 Agent 的提示词应该写成策略,而不是泛泛地说“谨慎审批”。建议明确:
- 默认放行哪些低风险操作
- 必须拒绝哪些破坏性操作
- 哪些情况需要人工升级
- 审查编辑模式下允许怎样收窄参数
示例策略片段:
```text
常规信息收集、只读查询、端口扫描默认 approve。
涉及删除文件、清空数据库、修改账号权限、写入持久化后门、停止关键服务时必须 reject。
若目标范围超出用户授权范围,应 reject。
审查编辑模式下,可将路径、目标、命令参数收窄后 approve,但不得扩大攻击面。
```
### 4. 白名单只放稳定低风险工具
白名单工具会跳过审批,因此要保守维护。推荐放:
- `read_file`
- `list_dir`
- `glob`
- `grep`
- `tool_search`
不建议直接全局白名单:
- 任意 shell 执行工具
- 文件写入/删除工具
- C2 任务工具
- WebShell 命令执行工具
## 模式选择
| 模式 | 适用场景 |
|------|----------|
| 关闭 | 本地实验、完全信任工具链 |
| 审批模式 | 只需要通过/拒绝 |
| 审查编辑 | 希望审计 Agent 收窄参数后放行 |
如果你已经配置了小模型审计,推荐从 **审批模式** 开始。只有当你希望 AI 自动收窄路径、目标范围或命令参数时,再开启 **审查编辑**
## 运维建议
- 定期查看 **人机协同 → 审计日志**,调整白名单和提示词。
- 高风险环境下保持 `default_reviewer: human`,只让审计 Agent 辅助给出建议。
- 小模型审批失败时默认保守拒绝,这是预期行为。
- 修改 `hitl.audit_model` 后先在页面点击 **测试审计模型**
- 对生产、客户、真实业务系统操作前,应保留人工最终确认。
+272
View File
@@ -0,0 +1,272 @@
# 知识库
知识库用于把本地安全知识、漏洞手册、测试方法和组织经验转成可检索上下文,供 Agent 在任务中按需引用。
## 启用
```yaml
knowledge:
enabled: true
base_path: knowledge_base
embedding:
provider: openai
model: text-embedding-v4
base_url: ""
api_key: ""
database:
knowledge_db_path: data/knowledge.db
```
`embedding.base_url/api_key` 留空时会复用 `openai` 配置。建议知识库数据库独立保存,便于迁移和复用。
## 内容目录
默认目录是 `knowledge_base/`。项目中已有示例:
```text
knowledge_base/
SQL Injection/
README.md
MySQL Injection.md
Prompt Injection/
README.md
```
推荐用一级目录表示风险类型或知识域,如:
- `SQL Injection`
- `XSS`
- `File Upload`
- `Cloud Security`
- `Incident Response`
## 管理流程
常见流程:
1. 把 Markdown 知识文件放到 `knowledge_base/`
2. 在 Web 知识库页面扫描目录。
3. 重建索引。
4. 用搜索功能验证召回效果。
5. 在角色或任务中要求 Agent 优先查询知识库。
接口入口包括:
- `GET /api/knowledge/categories`
- `GET /api/knowledge/items`
- `POST /api/knowledge/scan`
- `POST /api/knowledge/index`
- `POST /api/knowledge/search`
- `GET /api/knowledge/index-status`
- `GET /api/knowledge/retrieval-logs`
## 索引
索引配置:
```yaml
knowledge:
indexing:
chunk_size: 512
chunk_overlap: 50
max_chunks_per_item: 0
max_rpm: 0
rate_limit_delay_ms: 300
max_retries: 3
retry_delay_ms: 1000
chunk_strategy: markdown_then_recursive
request_timeout_seconds: 120
prefer_source_file: false
batch_size: 10
sub_indexes: []
```
建议:
- 文档结构清晰时用 `markdown_then_recursive`
- 嵌入接口限制严格时降低 `batch_size`,增加 `rate_limit_delay_ms`
- 单篇超长文档可设置 `max_chunks_per_item` 控制成本。
- 需要按业务域隔离时使用 `sub_indexes``sub_index_filter`
## 检索
```yaml
knowledge:
retrieval:
top_k: 5
similarity_threshold: 0.4
multi_query:
max_queries: 4
post_retrieve:
prefetch_top_k: 20
max_context_chars: 0
max_context_tokens: 0
```
检索链路大致为:
1. 用户查询或 Agent 查询。
2. MultiQuery 改写出多个语义变体。
3. 向量检索获取候选块。
4. rerank 精排。
5. 后处理去重、限长。
6. 返回给 Agent 或 API 调用方。
`similarity_threshold` 太高会漏召回,太低会带入噪声。初始建议 0.35 到 0.45。
## Rerank
```yaml
knowledge:
retrieval:
rerank:
provider: ""
model: ""
base_url: ""
api_key: ""
```
留空时会根据 `base_url` 推断。DashScope 常用 `gte-rerank`;其他 OpenAI 兼容端点可能走 `/v1/rerank`。如果服务商不支持 rerank,检索质量可能下降,建议降低 `top_k` 并提高知识条目质量。
## MCP 工具
启用知识库后,会注册类似以下能力:
- 列出风险类型。
- 搜索知识库。
- 获取相关知识片段。
角色提示词中可以写明:
```text
遇到漏洞验证、修复建议或检测方法不确定时,先检索知识库,再给出结论。
```
## 内容编写建议
每篇知识建议包含:
- 适用场景。
- 检测方法。
- 验证步骤。
- 常见误报。
- 修复建议。
- 工具命令示例。
- 参考链接或内部标准。
避免把无关主题堆在同一篇长文中。小而清晰的文档更利于 chunk 和召回。
## 排错
索引失败:
- 检查 embedding API Key、模型名、base_url。
- 降低 `batch_size`
- 增大 `request_timeout_seconds`
- 查看服务日志中的 400/401/429/5xx。
检索为空:
- 检查是否已重建索引。
- 降低 `similarity_threshold`
- 查看 `categories` 是否识别到风险类型。
- 搜索时不要使用过窄的 `riskType`
召回不准:
- 优化标题层级。
- 把混杂内容拆成多篇。
- 增加关键术语和同义词。
- 调整 `top_k``prefetch_top_k` 和 rerank 配置。
## 内部数据流
知识库链路不是“全文搜索”,而是一个多阶段检索系统:
```mermaid
flowchart LR
F["Markdown / Web 知识项"] --> M["Manager"]
M --> C["Chunker"]
C --> E["Embedding"]
E --> V["SQLite Vector Index"]
Q["Agent 查询"] --> MQ["MultiQuery 改写"]
MQ --> V
V --> R["Rerank"]
R --> P["Post-process 去重/限长"]
P --> A["Agent 上下文"]
```
因此检索质量取决于四件事:原文结构、chunk 粒度、embedding 质量、rerank 可用性。单纯调 `top_k` 往往不是最有效的办法。
## 知识项写作反例
不好的知识:
```text
SQL注入很危险,可以用sqlmap扫,修复就是过滤。
```
好的知识:
```markdown
# MySQL UNION 注入验证
## 触发条件
- 参数进入 SELECT 查询并直接拼接。
- 页面返回字段数量错误或类型错误。
## 验证步骤
1. 使用 `' order by 1-- -` 递增列数。
2. 使用 `union select null,...` 校验回显位。
3. 用只读函数确认数据库类型,例如 `database()`
## 误报排除
- WAF 注入拦截页可能模拟 SQL 错误。
- 统一错误页不能直接证明注入。
## 修复
- 参数化查询。
- 最小数据库权限。
- 统一错误处理但不吞掉安全日志。
```
第二种写法能给 chunk 足够的标题、术语和步骤信号,Agent 也能直接执行。
## 调参方法
先固定一组测试问题,例如:
```text
MySQL union 注入怎么判断字段数?
SSRF 如何验证云元数据访问?
文件上传黑名单绕过有哪些误报?
```
然后逐项调:
1. 搜索为空:降低 `similarity_threshold`,确认索引完成。
2. 结果主题错:提高文档标题质量,增加风险类型过滤。
3. 结果片段断裂:增大 `chunk_overlap` 或降低 `chunk_size` 后重建索引。
4. 噪声多:提高 `similarity_threshold`,启用/修复 rerank。
5. 成本高:降低 `multi_query.max_queries``prefetch_top_k``top_k`
每次只改一个参数,并记录查询结果,否则无法判断哪个变量有效。
## 检索日志怎么用
检索日志不只是排错用,还可以反向改进知识库:
- 高频无结果查询:说明缺知识或同义词不足。
- 高频低分查询:说明文档标题和术语不匹配。
- 同一问题召回多个重复文档:说明需要合并或加 category。
- Agent 常忽略知识库结果:说明结果太长、太散或缺明确结论。
## 源码锚点
- 知识管理:`internal/knowledge/manager.go`
- 索引流水线:`internal/knowledge/index_pipeline.go`
- Eino chunk`internal/knowledge/chunk_eino.go`
- 检索器:`internal/knowledge/retriever.go`
- Eino 检索链:`internal/knowledge/eino_retrieve_chain.go`
- rerank`internal/knowledge/rerank_http.go`
- MCP 工具:`internal/knowledge/tool.go`
+189
View File
@@ -0,0 +1,189 @@
# MCP 联邦
CyberStrikeAI 同时支持内置 MCP 工具、独立 HTTP MCP 服务和外部 MCP 联邦。MCP 是 Agent 调用工具的主要协议层。
## 内置 MCP
Web 服务内部会创建 MCP Server,并注册:
- YAML 命令工具。
- 内置安全执行工具。
- 知识库工具。
- 项目事实工具。
- C2 工具。
- WebShell 工具。
- 批量任务工具。
- 视觉分析工具。
前端和 Agent 通常通过应用内部调用,不需要额外配置。
## HTTP MCP 服务
配置:
```yaml
mcp:
enabled: true
host: 0.0.0.0
port: 8081
auth_header: "X-MCP-Token"
auth_header_value: "random-secret"
```
生产环境必须设置 `auth_header_value`,并限制网络访问。
## Web 内 MCP 端点
登录后可通过:
```text
POST /api/mcp
```
该端点复用 Web 认证,适合内部页面或受控集成。
## 外部 MCP
外部 MCP 配置在:
```yaml
external_mcp:
servers: {}
```
也可以通过 Web 的 MCP 管理页面新增、启动、停止和删除。
接口:
- `GET /api/external-mcp`
- `GET /api/external-mcp/stats`
- `GET /api/external-mcp/:name`
- `PUT /api/external-mcp/:name`
- `POST /api/external-mcp/:name/start`
- `POST /api/external-mcp/:name/stop`
- `DELETE /api/external-mcp/:name`
## stdio
stdio MCP 适合本机命令启动的工具服务。
关注点:
- 命令路径必须存在。
- 工作目录正确。
- 环境变量完整。
- 进程退出会导致工具不可用。
- 日志中查看启动失败原因。
## HTTP / SSE
HTTP 或 SSE MCP 适合远端或长期运行服务。
关注点:
- URL 可达。
- 认证头正确。
- TLS 证书可信。
- 代理和防火墙放行。
- 服务端协议版本兼容。
## 工具暴露策略
工具过多会增加上下文成本和误选概率。多代理中可通过:
```yaml
multi_agent:
eino_middleware:
tool_search_enable: true
tool_search_min_tools: 20
tool_search_always_visible: 12
tool_search_always_visible_tools:
- read_file
- glob
- grep
- tool_search
```
让常用工具常驻,其余工具由 `tool_search` 动态解锁。
## 安全建议
- 外部 MCP 只接入可信服务。
- 远端 MCP 必须认证。
- 高风险工具不要常驻上下文。
- 外部 MCP 的文件系统和命令执行能力要单独评估。
- 变更外部 MCP 后查看审计日志。
## 调试
排查顺序:
1. `/api/external-mcp/stats` 查看状态。
2. 检查服务日志。
3. 单独运行 stdio 命令。
4. 用 curl 测试 HTTP/SSE 地址。
5. 检查工具是否被角色或 tool_search 策略隐藏。
## MCP 生命周期
外部 MCP 的生命周期不是简单的“添加 URL”:
1. 注册配置:名称、类型、命令或 URL、环境变量。
2. 启动连接:stdio 拉起进程,HTTP/SSE 建立客户端。
3. 拉取工具列表:工具名、描述、schema 进入平台。
4. 暴露给 Agent:受角色、tool_search、HITL 影响。
5. 执行工具:参数校验、调用、记录监控。
6. 连接恢复:进程退出或网络失败后尝试恢复。
7. 停止/删除:从运行时和配置中移除。
排错时要确认卡在哪一步。
## 工具命名规范
工具名应:
- 稳定。
- 小写或 snake_case。
- 表达动作和对象。
- 避免和内置工具重名。
不建议:
```text
run
execute
scan
tool1
```
建议:
```text
burp_send_to_repeater
asset_lookup_domain
cloud_list_public_buckets
```
好的工具名会提升 tool_search 命中率,也降低误调用。
## 外部 MCP 安全审查清单
接入前问:
- 它能读写本机文件吗?
- 它能执行命令吗?
- 它会访问哪些网络?
- 它是否把请求发给第三方?
- 它的工具描述是否可信?
- 它的输出是否可能包含 prompt injection
- 它是否需要独立运行用户或容器隔离?
只要答案不清楚,就不要放进生产环境常驻工具池。
## 源码锚点
- 外部 MCP Manager`internal/mcp/external_manager.go`
- 连接恢复:`internal/mcp/connection_recovery.go`
- MCP 工具适配:`internal/einomcp/mcp_tools.go`
- 外部 MCP Handler`internal/handler/external_mcp.go`
- 工具调用通知:`internal/einomcp/tool_invoke_notify.go`
+216
View File
@@ -0,0 +1,216 @@
# 插件开发
CyberStrikeAI 当前仓库中的插件主要位于 `plugins/`,已有 **Burp Suite 扩展**与 **Chromium 浏览器扩展** 两个参考实现。插件通常通过 HTTP API、MCP 或本地文件与主应用集成。
## 目录
```text
plugins/
README.md
burp-suite/
cyberstrikeai-burp-extension/
src/main/java/burp/
README.md
README.zh-CN.md
build.gradle
pom.xml
browser-extension/
cyberstrikeai-browser-extension/
manifest.json
devtools.js
background/service-worker.js
panel/
popup/
lib/
README.md
README.zh-CN.md
package.sh
```
## 插件类型
常见集成方式:
- 浏览器或安全工具扩展:调用 CyberStrikeAI API。
- MCP Server:向 CyberStrikeAI 暴露新工具。
- 文件型扩展:提供 tools、roles、skills、agents。
- Webhook/机器人:通过平台回调与 CyberStrikeAI 对话。
## Burp Suite 扩展
Burp 插件目录包含 Java 源码和构建脚本。典型能力:
- 读取 Burp 中的 HTTP 请求/响应。
- 格式化消息。
- 调用 CyberStrikeAI API。
- 在 Burp 标签页展示 AI 分析结果。
构建前确认:
- JDK 可用。
- Gradle 或 Maven 可用。
- CyberStrikeAI 服务地址和认证配置正确。
## 浏览器扩展(Chromium DevTools
浏览器扩展目录为 MV3 DevTools 扩展,与 Burp 插件能力对齐:捕获 HTTP 流量 → 格式化 Prompt → SSE 流式输出 AI 结果。完整安装与 UI 说明见 `plugins/browser-extension/cyberstrikeai-browser-extension/README.zh-CN.md`
典型能力:
- 在 DevTools **Network** 中捕获 XHR/Fetch(可暂停)。
- 原始 HAR 存内存;展示与 AI Prompt 归一化为 **HTTP/1.1**(与 Burp 一致)。
- 调用 CyberStrikeAI 登录、Validate、Agent Stream API。
- DevTools 面板展示 Progress / FinalPopup 只读连接状态。
构建与加载:
- 无需编译:`chrome://extensions/` → 加载已解压 → 选择 `cyberstrikeai-browser-extension/`
- 打包:`bash package.sh``dist/cyberstrikeai-browser-extension.zip`
### 浏览器插件认证最佳实践
服务端 `POST /api/auth/login` 返回 `{ token, expires_at }`**无 refresh token**,插件不应假设 Token 会自动续期。参考实现见 `lib/auth-session.js``lib/api.js``panel/panel.js`
| 实践 | 说明 |
| --- | --- |
| Session 存储 | Token 与 `expires_at``chrome.storage.session`(关浏览器失效),Password 不落盘 |
| 剩余时间 | 状态栏显示 `OK · 剩余 11h 30m`;剩余 <30min 警告 |
| 本地检测 | 每 30s 检查 `expires_at` 并调用 `GET /api/auth/validate` |
| 服务端探测 | 切回 DevTools 面板 / 窗口聚焦时立即探测 |
| 服务不可达 | 显示「无法连接服务」,不清 Token(便于服务重启中) |
| 401/403 | 清空 Token、展开连接栏(服务重启后 session 内存清空) |
| Send 前校验 | 调用 `ensureAuthReady()`,避免过期 Token 发起 SSE |
| 按需授权 | `optional_host_permissions`Validate 时请求目标 origin |
扩展重载后 DevTools 面板上下文可能失效:需 **关闭 DevTools → 重载扩展 → 再开 F12**
### 浏览器插件数据与性能边界
插件侧应设内存上限,避免 DevTools 长时间开启拖垮浏览器:
- 捕获:200 条 / Tab20 个 Tab 槽;Progress 512KB / run。
- 默认 **XHR/Fetch only** + 静态资源预过滤;不需要捕获时用 **已暂停**
- 大响应走截断或摘要后再进 Prompt,不要整包塞进消息。
## API 对接建议
插件调用主应用时:
-`POST /api/auth/login`,再 `GET /api/auth/validate` 确认会话。
- 保存 `expires_at`,过期后重新登录(无 silent refresh)。
- 优先调用 `/api/eino-agent/stream``/api/multi-agent/stream`SSE)。
- 大文件通过 `/api/chat-uploads` 上传,再在消息中引用。
- 查询结果或漏洞可写入 `/api/vulnerabilities`
- 项目信息可写入 `/api/projects/:id/facts`
完整接口以 `/api-docs` 为准。
## MCP 插件
如果插件的目标是给 Agent 增加工具,优先实现 MCP Server。然后在外部 MCP 管理中接入:
- stdio:本机启动。
- HTTP/SSE:长期服务。
MCP 工具设计建议:
- schema 明确。
- 参数最小化。
- 输出结构稳定。
- 错误信息可读。
- 高风险动作拆成独立工具,方便 HITL 审批。
## 文件型扩展
插件也可以交付:
- `tools/*.yaml`
- `roles/*.yaml`
- `skills/<name>/SKILL.md`
- `agents/*.md`
这种方式简单可靠,适合内部方法论或工具链沉淀。
## 发布检查
发布插件前确认:
- 不包含 API Key、Cookie、目标信息。
- README 有安装、配置、卸载说明。
- 错误提示清晰。
- 与当前 CyberStrikeAI API 版本兼容。
- 高风险能力有明显说明。
## 版本兼容
插件应避免依赖未公开的前端内部实现。优先依赖:
- `/api/openapi/spec`
- 稳定 HTTP API。
- MCP 协议。
- 文件目录规范。
如果必须依赖内部接口,插件 README 中应标注兼容版本。
## 插件设计的三个层次
| 层次 | 例子 | 优点 | 代价 |
| --- | --- | --- | --- |
| API 插件 | Burp / 浏览器扩展调用 Agent Stream | 易实现,适合 UI 集成 | 依赖认证和 API 稳定性 |
| MCP 插件 | 提供新工具给 Agent | Agent 可主动调用 | 需要 schema 和安全设计 |
| 资源包插件 | 交付 tools/roles/skills/agents | 最简单,可版本化 | 交互能力弱 |
插件一开始不必做成 MCP。如果只是“把 Burp / 浏览器里的 HTTP 请求交给 AI 分析”,API 插件更直接;如果要让 Agent 主动调用 Burp 扫描或查询结果,再做 MCP。
## API 插件请求设计
发送给 Agent 的内容应包含:
- 来源工具和上下文。
- 目标 URL、方法、关键 header。
- 请求体和响应体的截断策略。
- 用户希望 AI 做什么。
- 授权边界。
不要把完整大响应直接塞进消息。大文件应走上传接口或做摘要。
## MCP 插件 schema 设计
坏 schema
```json
{"cmd":{"type":"string"}}
```
好 schema
```json
{
"target_url": {"type":"string","description":"授权目标 URL"},
"scan_profile": {"type":"string","enum":["passive","active-safe"]},
"max_requests": {"type":"integer","description":"最大请求数"}
}
```
schema 越具体,HITL 越容易判断风险,Agent 也越不容易发散。
## 插件安全边界
插件不要绕过平台安全控制:
- 不要直接执行本机高风险命令而不暴露给 HITL。
- 不要在插件内保存明文长期凭证(Password 仅用于登录,Token 用 session 存储)。
- 不要默认把目标数据发给第三方服务。
- 不要依赖浏览器本地状态绕过登录。
- 收到 401/403 应清空会话并提示重新认证,不要静默重试或忽略。
## 源码锚点
- Burp 插件 Java 代码:`plugins/burp-suite/cyberstrikeai-burp-extension/src/main/java/burp/`
- 浏览器扩展:`plugins/browser-extension/cyberstrikeai-browser-extension/`
- 认证:`lib/auth-session.js``lib/api.js``lib/storage.js`
- 主 UI`panel/panel.js`
- 捕获:`devtools.js``background/service-worker.js`
- OpenAPI`internal/handler/openapi.go`
- 外部 MCP`internal/handler/external_mcp.go`
- Web 端认证参考:`web/static/js/auth.js`
+169
View File
@@ -0,0 +1,169 @@
# 发布流程
本文用于维护者或部署者发布、升级和回滚 CyberStrikeAI。
## 版本准备
发布前检查:
- `README.md``README_CN.md` 的功能说明是否更新。
- `docs/` 是否补充新功能文档。
- `config.yaml` 示例是否包含新增配置。
- OpenAPI 是否包含新增接口。
- 中英文 i18n 是否同步。
- 高风险功能是否有安全说明。
## 测试
至少运行:
```bash
go test ./internal/...
```
如果修改了入口、构建或命令:
```bash
go test ./cmd/...
go build -o cyberstrike-ai ./cmd/server
```
如果修改前端,手动验证:
- 登录。
- 对话流式输出。
- 设置保存和应用。
- 工具列表。
- 相关页面无控制台错误。
## 构建
```bash
go build -o cyberstrike-ai ./cmd/server
```
发布包应包含:
- `cyberstrike-ai`
- `web/templates/`
- `web/static/`
- `config.yaml` 示例。
- `tools/`
- `roles/`
- `skills/`
- `agents/`
- `docs/`
- `README.md` / `README_CN.md`
- `LICENSE`
不要把本地 `data/`、真实 `config.yaml` 密钥、上传附件和日志打进公开发布包。
## 升级检查清单
升级前:
- 停服务。
- 备份 `config.yaml`
- 备份 `data/`
- 备份自定义 `tools/roles/skills/agents/knowledge_base`
- 记录当前版本和启动方式。
升级后:
- 启动服务。
- 登录。
- 测试模型。
- 检查工具列表。
- 检查知识库状态。
- 检查外部 MCP。
- 检查 C2/WebShell 是否按预期启用或关闭。
- 查看日志和审计。
## 回滚
触发回滚的常见情况:
- 服务无法启动。
- 数据库迁移失败。
- 核心对话功能不可用。
- 高风险功能行为异常。
回滚步骤:
1. 停止新版本。
2. 恢复旧二进制或旧代码。
3. 恢复升级前 `config.yaml`
4. 恢复升级前 `data/`
5. 启动旧版本并验证。
如果新版已修改数据库结构,必须恢复数据库备份,不能只替换二进制。
## Changelog 建议
每个版本记录:
- 新增功能。
- 行为变更。
- 配置变更。
- 数据库变更。
- 安全修复。
- 兼容性说明。
- 升级注意事项。
高风险模块的变更要单独标出,例如 C2、WebShell、终端、外部 MCP、HITL。
## 发布风险分级
| 改动 | 风险 | 必测 |
| --- | --- | --- |
| 文档、图片 | 低 | 链接和渲染 |
| 前端页面 | 中 | 登录、页面状态、API 错误 |
| Handler/API | 中 | OpenAPI、权限、错误码 |
| 配置结构 | 高 | 旧配置兼容、ApplyConfig |
| 数据库结构 | 高 | 旧库迁移、回滚策略 |
| Agent/MCP/HITL | 高 | 工具调用、审批、流式中断 |
| C2/WebShell/Terminal | 极高 | 授权环境、审计、禁用开关 |
发布说明里要按风险级别提示用户,而不是只列功能点。
## 配置兼容策略
新增配置字段要遵循:
- 省略时有安全默认值。
- 旧配置能启动。
- 示例 `config.yaml` 有注释。
- Web 设置页不会把未知字段误删。
- 热应用和重启两种路径都验证。
如果新增字段默认开启高风险功能,应重新考虑默认值。
## 数据库变更策略
SQLite 迁移要考虑:
- 用户可能从很老版本直接升级。
- 迁移中断后再次启动是否幂等。
- 新字段是否允许空值。
- 索引是否会锁表太久。
- 是否需要数据回填。
发布说明必须写清楚“升级前备份 data/”。
## Release 验收脚本思路
最小自动化:
```bash
go test ./internal/...
go test ./cmd/...
go build -o cyberstrike-ai ./cmd/server
```
手动冒烟:
```text
登录 -> 模型测试 -> 新建对话 -> 工具列表 -> HITL -> 知识库 -> 外部 MCP -> 关闭/开启 C2
```
对高风险模块,宁可多做一个授权靶场测试,也不要只靠单测放行。
+232 -16
View File
@@ -1,8 +1,8 @@
# CyberStrikeAI 机器人使用说明
[English](robot_en.md)
[English](../en-US/robot.md)
本文档说明如何通过**钉钉**、**飞书**与 **企业微信** 与 CyberStrikeAI 对话(长连接 / 回调模式),在手机端即可使用,无需在服务器上打开网页。按下面步骤操作可避免常见弯路。
本文档说明如何通过**个人微信**、**钉钉**、**飞书**与 **企业微信** 与 CyberStrikeAI 对话(长连接 / 回调模式),在手机端即可使用,无需在服务器上打开网页。按下面步骤操作可避免常见弯路。
---
@@ -11,11 +11,14 @@
1. 登录 CyberStrikeAI Web 端
2. 左侧导航进入 **系统设置**
3. 在左侧设置分类中点击 **机器人设置**(位于「基本设置」与「安全设置」之间)
4. 按平台勾选并填写(钉钉填 Client ID / Client Secret,飞书填 App ID / App Secret
5. 点击 **应用配置** 保存
6. **重启 CyberStrikeAI 应用**(只保存不重启,机器人不会连上)
4. 按平台配置:
- **个人微信**:点击「微信 / iLink」→「生成二维码并绑定」,用微信扫码确认(见 [3.4 个人微信](#34-个人微信-wechat--ilink)
- **钉钉**:勾选并填写 Client ID / Client Secret
- **飞书**:勾选并填写 App ID / App Secret
5. 点击 **应用配置** 保存(微信扫码绑定成功后会**自动保存并启用**,一般无需再点)
6. **重启 CyberStrikeAI 应用**(钉钉/飞书:只保存不重启,长连接不会建立;微信绑定成功后会自动重启连接,通常无需手动重启)
配置会写入 `config.yaml``robots` 段,也可在配置文件中直接编辑。**修改钉钉/飞书配置后必须重启,长连接才会生效。**
配置会写入 `config.yaml``robots` 段,也可在配置文件中直接编辑。**修改钉钉/飞书配置后必须重启,长连接才会生效。** 个人微信绑定成功后程序会自动写入 `robots.wechat` 并重启 iLink 长轮询。
---
@@ -23,9 +26,14 @@
| 平台 | 说明 |
|----------|------|
| 个人微信 | 使用微信 iLink 协议,Web 端扫码绑定后长轮询收消息,**无需公网回调** |
| 钉钉 | 使用 Stream 长连接,程序主动连接钉钉接收消息 |
| 飞书 | 使用长连接,程序主动连接飞书接收消息 |
| 企业微信 | 使用 HTTP 回调接收消息,被动回包 + 主动调用企业微信发送消息 API |
| Telegram | Bot API 长轮询(getUpdates),**无需公网回调** |
| Slack | Socket Mode(出站 WebSocket),**无需公网回调** |
| Discord | Gateway WebSocket**无需公网回调** |
| QQ 机器人 | QQ 开放平台 WebSocketC2C / 群 @),**无需公网回调** |
下面第三节会按平台写清:在开放平台要做什么、要复制哪些字段、填到 CyberStrikeAI 的哪一栏。
@@ -151,9 +159,150 @@
---
### 3.4 个人微信 (WeChat / iLink)
> 个人微信采用「Web 扫码绑定 + iLink 长轮询」方式工作:
> - 在 CyberStrikeAI Web 端生成二维码 → 用**手机微信**扫码并确认绑定;
> - 绑定成功后自动写入 `config.yaml``robots.wechat`,并启动 iLink 长轮询(程序主动连接 `ilinkai.weixin.qq.com` 收消息);
> - **无需**在服务器上配置公网回调 URL,也**无需**去微信开放平台注册应用。
**与企业微信的区别**
| 项目 | 个人微信 (iLink) | 企业微信 (WeCom) |
|------|------------------|------------------|
| 使用场景 | 个人微信私聊 | 企业微信自建应用 |
| 配置方式 | Web 端扫码绑定 | 管理后台配置回调 URL + Token |
| 是否需要公网 | 否(长轮询出站即可) | 是(需可被企业微信访问的 HTTPS 回调) |
| 配置段 | `robots.wechat` | `robots.wecom` |
**绑定步骤(按顺序做)**
1. **登录 CyberStrikeAI Web 端**
左侧 **系统设置****机器人设置** → 点击 **微信 / iLink** 卡片。
2. **(可选)勾选「启用微信机器人」**
首次绑定可跳过;绑定成功后会自动勾选并启用。
3. **生成二维码**
点击 **「生成二维码并绑定」**。页面会显示二维码(约 **5 分钟**有效;过期请重新生成)。
4. **微信扫码确认**
- 用手机微信扫描页面二维码;
- 按手机提示完成确认;
- 若手机微信弹出**配对数字**,在 Web 页面对应输入框填写并点击 **提交**(仅部分账号需要)。
5. **等待绑定完成**
页面显示「绑定成功,微信机器人已启用」即完成。`bot_token``ilink_bot_id` 等会自动写入 `config.yaml`,程序会自动重启 iLink 长轮询,**一般无需手动重启服务**。
6. **在手机微信里测试**
打开与 CyberStrikeAI 机器人的**私聊**(绑定后微信内会出现对应会话),发送「帮助」或任意文字测试。
**CyberStrikeAI 微信栏位说明**
| 栏位 | 说明 |
|------|------|
| 启用微信机器人 | 勾选后启动 iLink 长轮询;绑定成功后会自动勾选 |
| 生成二维码并绑定 | 发起扫码绑定流程 |
| **高级设置**(一般保持默认即可) | |
| API Base URL | 默认 `https://ilinkai.weixin.qq.com` |
| Bot Type | 默认 `3` |
| Bot Agent | 默认 `CyberStrikeAI/1.0` |
| iLink Bot ID | 绑定成功后自动填充,只读 |
**使用方式**
- 仅支持在与机器人的**私聊**中对话,直接发送文字即可,**不需要 @**。
- 不支持群聊 @ 机器人(与钉钉/飞书群聊不同)。
- 仅处理**文本消息**;图片、语音等会忽略或提示暂不支持。
**重新绑定**
- 若需更换绑定的微信账号,在机器人设置页点击 **「重新绑定」**,再次扫码即可。
- 若提示「该微信已绑定过,无需重复绑定」,说明该账号此前已完成绑定。
**常见问题**
| 现象 | 处理 |
|------|------|
| 二维码过期 | 重新点击「生成二维码并绑定」(有效期约 5 分钟) |
| 扫码后要求输入数字 | 查看手机微信显示的配对数字,在 Web 页面输入并提交 |
| 绑定成功但发消息无回复 | 看程序日志是否有 `微信 iLink 长轮询已启动``微信收到消息`;确认已勾选「启用微信机器人」 |
| 断网或睡眠后无回复 | 程序会自动重连(约 5~60 秒);仍无回复可重启 CyberStrikeAI |
| 无法生成二维码 | 确认服务器能访问 `https://ilinkai.weixin.qq.com`(出站 HTTPS |
---
### 3.5 Telegram
> Telegram 使用 **Bot API 长轮询**`getUpdates`):程序主动连接 `api.telegram.org` 收消息,**无需公网回调**。
**配置步骤:**
1. 在 Telegram 中找 **@BotFather**,发送 `/newbot` 创建机器人,获得 **Bot Token**
2. CyberStrikeAI → **系统设置****机器人设置****Telegram**
3. 勾选「启用 Telegram 机器人」,粘贴 **Bot Token**
4. (可选)填写 Bot Username(不含 `@`),或留空由程序自动 `getMe`
5. (可选)勾选「允许群聊」— 群聊中仅响应 **@机器人** 的消息。
6. 点击 **应用配置**(会自动重启长轮询连接)。
**使用:** 与机器人私聊直接发消息;群聊需 @ 机器人(且已勾选允许群聊)。
---
### 3.6 Slack
> Slack 使用 **Socket Mode**(出站 WebSocket):需 **Bot Token****App-Level Token****无需公网回调**。
**配置步骤:**
1. 在 [Slack API](https://api.slack.com/apps) 创建 App → 启用 **Socket Mode**
2. **Basic Information****App-Level Tokens** → 创建 tokenscope: `connections:write`),即 **xapp-** 开头。
3. **OAuth & Permissions** → 添加 Bot Token Scopes`app_mentions:read``chat:write``im:history``im:read` 等 → 安装到工作区,获得 **xoxb-** Bot Token。
4. **Event Subscriptions** → 订阅 `message.im``app_mention` 等(Socket Mode 下在应用内配置)。
5. 在 CyberStrikeAI 填入 Bot Token 与 App-Level Token → **应用配置**
**使用:** 与 Bot 私聊直接发;频道中需 @ 机器人。
---
### 3.7 Discord
> Discord 使用 **Gateway WebSocket**:程序主动连接 Discord Gateway**无需公网回调**。
**配置步骤:**
1. 在 [Discord Developer Portal](https://discord.com/developers/applications) 创建应用 → **Bot** → 复制 **Token**
2. 开启 **Privileged Gateway Intents** 中的 **Message Content Intent**(否则读不到消息正文)。
3. OAuth2 → URL Generator → scopes: `bot` → 权限勾选 **Send Messages**、**Read Message History** 等 → 邀请 Bot 到服务器。
4. CyberStrikeAI → **机器人设置****Discord** → 填入 Token → **应用配置**
5. (可选)勾选「允许服务器频道」— 频道中仅响应 **@机器人**。
**使用:** 与 Bot 私聊直接发;服务器频道需 @ 机器人(且已勾选允许服务器频道)。
---
### 3.8 QQ 机器人
> QQ 机器人使用 **QQ 开放平台 WebSocket**(官方 `botgo` SDK):支持 C2C 私聊与群 @**无需公网回调**(WebSocket 出站连接)。
**配置步骤:**
1. 在 [QQ 机器人开放平台](https://q.qq.com) 创建机器人,获取 **App ID****Client Secret**
2. 在沙箱中添加测试成员(上线前仅沙箱可对话)。
3. 订阅 **C2C 消息**、**群 @ 消息** 等事件(WebSocket 模式)。
4. CyberStrikeAI → **机器人设置****QQ 机器人** → 填入 App ID、Client Secret。
5. 测试阶段勾选 **沙箱环境**;正式上线后取消沙箱并发布。
6. 点击 **应用配置**
**使用:** 与机器人 C2C 私聊直接发;QQ 群中需 @ 机器人。
> 注意:QQ 官方正逐步推广 Webhook 回调;当前实现使用 WebSocket(与钉钉/飞书类似的长连接模式)。若配置变更后连接未刷新,可重启 CyberStrikeAI 进程。
---
## 四、机器人命令
钉钉/飞书中向机器人发送以下**文本命令**(仅支持文本):
任一已接入平台(钉钉/飞书/微信/Telegram/Slack/Discord/QQ 等)向机器人发送以下**文本命令**(仅支持文本):
| 命令 | 说明 |
|------|------|
@@ -175,16 +324,25 @@
## 五、如何使用(要 @ 机器人吗?)
- **单聊(推荐)**:在钉钉/飞书里**搜索并打开该机器人**,进入与机器人的**私聊**直接输入「帮助」或任意文字即可,**不需要 @**。
- **群聊**:若机器人被添加到群里,在群内只有 **@机器人** 后发送的消息才会被机器人收到并回复;不 @ 的群消息不会触发机器人。
- **个人微信**:在与 CyberStrikeAI 机器人的**私聊**直接发送即可,**不需要 @**(不支持群聊)
- **钉钉 / 飞书单聊(推荐)**:**搜索并打开该机器人**,进入**私聊**,直接输入「帮助」或任意文字即可,**不需要 @**。
- **钉钉 / 飞书群聊**:若机器人被添加到群里,在群内只有 **@机器人** 后发送的消息才会被机器人收到并回复;不 @ 的群消息不会触发机器人。
总结:和机器人**单聊时直接发****群里用时需要 @机器人** 再发内容。
总结:**个人微信、单聊时直接发****钉钉/飞书在群里用时需要 @机器人** 再发内容。
---
## 六、推荐使用流程(避免漏步骤)
1. **在开放平台**:按第三节完成钉钉或飞书应用创建、凭证复制、机器人开通(钉钉务必选 **Stream 模式**)、权限与发布。
**个人微信(最简单,无需开放平台)**
1. CyberStrikeAI Web 端 → 系统设置 → 机器人设置 → **微信 / iLink****生成二维码并绑定**
2. 手机微信扫码确认(如需配对数字则在 Web 页填写)。
3. 绑定成功后,在手机微信私聊中发「帮助」测试。
**钉钉 / 飞书**
1. **在开放平台**:按第三节完成应用创建、凭证复制、机器人开通(钉钉务必选 **Stream 模式**)、权限与发布。
2. **在 CyberStrikeAI**:系统设置 → 机器人设置 → 勾选对应平台,粘贴 Client ID/App ID、Client Secret/App Secret → 点击 **应用配置**
3. **重启 CyberStrikeAI 进程**(否则长连接不会建立)。
4. **在手机钉钉/飞书**:找到该机器人(单聊直接发,群聊需 @机器人),发「帮助」或任意内容测试。
@@ -199,6 +357,14 @@
```yaml
robots:
wechat: # 个人微信 iLink(扫码绑定后自动写入,一般无需手填)
enabled: true
bot_token: "your_bot_token@im.bot:..."
ilink_bot_id: "your_bot_id@im.bot"
ilink_user_id: "your_user_id@im.wechat"
base_url: "https://ilinkai.weixin.qq.com"
bot_type: "3"
bot_agent: "CyberStrikeAI/1.0"
dingtalk:
enabled: true
client_id: "your_dingtalk_app_key"
@@ -208,9 +374,33 @@ robots:
app_id: "your_lark_app_id"
app_secret: "your_lark_app_secret"
verify_token: ""
wecom:
enabled: false
corp_id: ""
agent_id: 0
token: ""
encoding_aes_key: ""
secret: ""
telegram:
enabled: false
bot_token: ""
allow_group_messages: false
slack:
enabled: false
bot_token: ""
app_token: ""
discord:
enabled: false
bot_token: ""
allow_guild_messages: false
qq:
enabled: false
app_id: ""
client_secret: ""
sandbox: true
```
修改后需**重启应用**,长连接在应用启动时建立
修改钉钉/飞书/企业微信/Telegram/Slack/Discord/QQ 配置后,点击 **应用配置** 会自动重启对应长连接。个人微信扫码绑定成功后会自动写入并重启 iLink 连接
---
@@ -235,7 +425,30 @@ curl -X POST "http://localhost:8080/api/robot/test" \
---
## 九、钉钉发消息没反应时排查
## 九、发消息没反应时排查
### 9.1 个人微信
按顺序检查:
1. **是否已完成扫码绑定**
机器人设置页应显示「已连接」或已绑定 Bot ID;`config.yaml``robots.wechat.bot_token` 不应为空。
2. **是否已启用**
确认「启用微信机器人」已勾选;若刚修改过,可重启 CyberStrikeAI 进程。
3. **看程序日志**
- 启动后应看到:`微信 iLink 长轮询已启动`
- 发消息后应有:`微信收到消息`;若没有,多为未绑定成功或 `bot_token` 失效,可尝试 **重新绑定**
- 若出现 `微信 iLink 长轮询异常,将自动重连`,等待自动重连或重启进程。
4. **网络**
服务器需能访问 `https://ilinkai.weixin.qq.com`(出站 HTTPS)。绑定阶段若无法生成二维码,优先检查此项。
5. **断网或睡眠后**
与钉钉/飞书类似,程序会**自动重连**(约 5~60 秒);仍无回复可重启 CyberStrikeAI。
### 9.2 钉钉
按顺序检查:
@@ -260,8 +473,10 @@ curl -X POST "http://localhost:8080/api/robot/test" \
## 十、常见弯路(避免踩坑)
- **个人微信与企业微信混淆**:个人微信走 `robots.wechat` + Web 扫码绑定;企业微信走 `robots.wecom` + 管理后台回调 URL,二者完全不同。
- **个人微信二维码过期**:二维码约 5 分钟有效,过期需重新生成,不要一直扫旧码。
- **用错了机器人类型**:在钉钉**群里**添加的「自定义」机器人(Webhook + 加签)**不能**用来做对话,本程序只支持**开放平台「企业内部应用」**里的机器人。
- **只保存没重启**在 CyberStrikeAI 里改完机器人配置后必须**重启应用**,否则长连接不会建立。
- **只保存没重启**钉钉/飞书改完配置后必须**重启应用**,否则长连接不会建立(个人微信扫码绑定会自动重启连接)
- **Client ID 抄错**:开放平台是 `504` 就填 `504`,不要填成 `5o4`;尽量用复制粘贴。
- **钉钉只开了 HTTP 回调没开 Stream**:本程序通过 **Stream 长连接**收消息,开放平台里机器人的消息接收方式必须选 **Stream 模式**
- **应用没发布**:开放平台里修改了机器人或权限后,要在「版本管理与发布」里**发布新版本**,否则不生效。
@@ -270,6 +485,7 @@ curl -X POST "http://localhost:8080/api/robot/test" \
## 十一、注意事项
- 钉钉、飞书均**仅处理文本消息**;其他类型(如图片、语音)会提示暂不支持或忽略。
- 各平台均**仅处理文本消息**;其他类型(如图片、语音)会提示暂不支持或忽略。
- 个人微信仅支持**私聊**,不支持群聊 @ 机器人。
- 会话与 Web 端共用同一套对话数据:在机器人里创建的对话会在 Web 端「对话」列表中看到,反之亦然。
- 机器人执行逻辑与 **`/api/agent-loop/stream`** 一致(含进度回调过程详情写入数据库),仅不向客户端推送 SSE,最后将完整回复一次性发回钉钉/飞书/企业微信。
- 机器人执行**Eino 单/多代理** 相同逻辑(`ProcessMessageForRobot`含进度回调过程详情库),仅不向客户端推送 SSE,最后一次性回复个人微信/钉钉/飞书/企业微信。默认 `robot_default_agent_mode: eino_single`
+223
View File
@@ -0,0 +1,223 @@
# 运维 Runbooks
[English](../en-US/runbooks.md)
Runbook 是“遇到一个真实任务时照着做”的步骤清单。本文覆盖 CyberStrikeAI 最常见的运维和安全测试操作。
## Runbook 1:生产实例从 0 到可用
适用:内网团队或生产红队平台首次部署。
如果只是本地或临时验证,优先用仓库自带脚本启动:
```bash
chmod +x run.sh && ./run.sh
```
确认可用后,再决定是否升级为 systemd + 反向代理的长期部署。
### 前置确认
- 运行主机已纳入资产管理。
- 访问路径确定:内网、VPN、堡垒机或反向代理。
- 有模型 API Key 和允许使用的模型。
- 已决定是否启用 C2、WebShell、外部 MCP。
### 步骤
1. 准备目录:
```bash
mkdir -p /opt/CyberStrikeAI
```
2. 放置二进制和资源目录:
```text
cyberstrike-ai
web/
tools/
roles/
skills/
agents/
docs/
config.yaml
```
3. 修改关键配置:
```yaml
auth:
password: "<long-random-password>"
server:
host: 127.0.0.1
port: 8080
tls_enabled: false
audit:
enabled: true
c2:
enabled: false
```
4. 配置反向代理 HTTPS,并限制来源 IP。
5. 使用 systemd 托管进程。
6. 登录 Web,测试模型。
7. 检查工具列表和审计日志。
8. 建立备份策略。
### 验收
- `/api/auth/validate` 登录后返回成功。
- 模型测试成功。
- `tools/` 能正常加载。
- 审计页面能看到登录事件。
- C2 在不需要时访问返回禁用状态。
### 回滚
恢复:
- 上一版二进制。
- 上一版 `config.yaml`
- 升级前 `data/`
## Runbook 2:接入外部 MCP
适用:接入本地工具服务、Burp 辅助服务、资产查询服务等。
### 前置确认
- MCP 服务可信。
- 明确它是否能读文件、写文件、执行命令或访问第三方网络。
- 确定接入方式:stdio、HTTP、SSE。
### 步骤
1. 在外部 MCP 页面新增服务。
2. 如果是 stdio,填写命令、参数、工作目录和环境变量。
3. 如果是 HTTP/SSE,填写 URL 和认证信息。
4. 启动服务。
5. 查看 `/api/external-mcp/stats`
6. 检查工具列表是否出现。
7. 用低风险参数执行一次工具。
8. 把高风险工具排除在全局免审批白名单之外。
### 验收
- MCP 状态为 running。
- 工具 schema 可见。
- Agent 能通过 `tool_search` 找到工具。
- 工具执行记录出现在监控页。
- 配置变更出现在审计页。
### 回滚
- 停止 MCP。
- 删除外部 MCP 配置。
- 从角色/白名单中移除相关工具。
- 检查 Agent 当前任务是否仍持有旧上下文。
## Runbook 3:启用知识库并调优召回
适用:把内部安全知识、漏洞手册或测试方法接入 Agent。
### 步骤
1. 修改配置:
```yaml
knowledge:
enabled: true
base_path: knowledge_base
embedding:
model: text-embedding-v4
retrieval:
top_k: 5
similarity_threshold: 0.4
```
2. 把 Markdown 放入 `knowledge_base/`
3. 在 Web 知识库页面执行扫描。
4. 重建索引。
5. 准备 5 到 10 个固定测试问题。
6. 搜索并记录命中情况。
7. 根据结果调 `threshold``top_k`、chunk 参数和文档标题。
### 验收
- `index-status` 显示索引完成。
- 常见问题能命中正确文档。
- Agent 在不确定时会先查知识库。
- 检索日志能显示查询和命中文档。
### 常见回滚
- 关闭 `knowledge.enabled`
- 恢复旧的 `data/knowledge.db`
- 降低 `batch_size` 后重新索引。
## Runbook 4:一次授权 Web 测试标准流程
适用:对授权目标做 Web 安全测试。
### 步骤
1. 创建项目,记录授权范围。
2. 新建对话,绑定项目。
3. 选择最小角色,例如“信息收集”或“Web 应用扫描”。
4. 明确目标、时间窗口、禁止动作。
5. 先执行只读信息收集。
6. 发现线索后写入项目事实。
7. 对高风险验证请求使用 HITL。
8. 确认漏洞后写入漏洞管理。
9. 生成攻击链或报告材料。
10. 清理上传文件、临时 workspace 和无用执行记录。
### 验收
- 每个漏洞都有证据、影响、复现和修复建议。
- 高风险操作有 HITL 记录。
- 项目事实能复现测试路径。
- 报告不包含无关敏感数据。
## Runbook 5C2 演练结束清理
适用:授权演练中启用了 C2。
### 步骤
1. 停止所有 listener。
2. 列出 sessions,确认没有仍在线的授权会话。
3. 导出必要 task 结果。
4. 删除 payload 或移动到受控归档。
5. 删除无用 task、event、file。
6. 审计 C2 操作记录。
7. 将关键结果写入项目事实或报告。
8.`c2.enabled` 改回 false,除非平台持续需要。
### 验收
- 无运行中 listener。
- 无待处理 task。
- payload 不再公开可下载。
- 审计与报告能解释整个生命周期。
## Runbook 6Agent 不调用工具
排查顺序:
1. 当前角色是否绑定了该工具。
2. 工具是否在 `/api/config/tools` 中出现。
3. `tool_search` 是否隐藏了该工具。
4. 工具描述是否过短或命名不清。
5. HITL 是否挂起。
6. Agent 是否处于总结/结束阶段。
7. 多代理子 Agent 是否有自己的工具限制。
修复方式:
- 把工具加入角色。
- 优化 `short_description`
- 加入 `tool_search_always_visible_tools`
- 在提示词中明确什么时候使用。
- 检查过程详情和监控记录。
+140
View File
@@ -0,0 +1,140 @@
# 安全加固指南
[English](../en-US/security-hardening.md)
本文给出 CyberStrikeAI 上线前和持续运行中的安全加固清单。
## 上线前必做
- 修改 `auth.password` 为长随机密码。
- 使用 HTTPS,或放在可信反向代理之后。
- 限制来源 IP、VPN 或堡垒机访问。
- 开启 `audit.enabled`
- 不需要 C2 时设置 `c2.enabled: false`
- 不暴露独立 HTTP MCP,除非设置强认证和网络隔离。
- 外部 MCP 只接可信服务。
- 备份 `config.yaml``data/`、自定义资源目录。
## 反向代理建议
Nginx 基线:
```nginx
client_max_body_size 200m;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
建议额外加:
```nginx
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy no-referrer;
add_header X-Frame-Options DENY;
```
## HITL 白名单基线
推荐最小白名单:
```yaml
hitl:
tool_whitelist:
- read_file
- glob
- grep
- tool_search
```
不要默认加入:
- `execute`
- WebShell 写入/执行工具
- C2 任务和 payload 工具
- 外部 MCP 高风险工具
- 删除、写入、上传、持久化相关工具
## 文件权限
建议:
```bash
chmod 600 config.yaml
chmod 700 data
```
生产环境使用独立系统用户运行:
```text
cyberstrike-ai:cyberstrike-ai
```
避免 root 运行,除非明确需要绑定低端口或访问特殊资源。
## 外部 MCP 审查
接入前确认:
- 工具是否能执行命令。
- 是否能读写本机文件。
- 是否会把数据发往第三方。
- 是否有自己的认证。
- 是否会返回不可信网页或模型内容。
- 是否需要容器隔离。
接入后:
- 高风险工具不进白名单。
- 定期检查工具列表变化。
- 审计配置变更。
## C2 和 WebShell
C2
- 默认关闭。
- 演练窗口临时开启。
- Listener 端口与管理端口分离。
- 结束后清理 payload、session、task、event。
WebShell
- 只保存授权目标。
- 使用清晰命名。
- 写入/删除/执行必须审批。
- 项目结束删除连接。
## 数据保留
建议:
- 审计:30-90 天。
- 工具监控:90-180 天。
- 上传附件:项目结束清理。
- C2/WebShell 输出:只保留报告需要的证据。
- 知识库:不放真实凭证和客户私密数据。
## 周期巡检
每周:
- 登录失败和异常 IP。
- 配置变更。
- 外部 MCP 增删改。
- 长时间运行工具。
- C2 是否被意外开启。
- WebShell 连接是否过期。
- 磁盘空间和数据库大小。
每个项目结束:
- 清理临时 workspace。
- 删除无用附件。
- 归档必要证据。
- 删除过期 WebShell/C2 资源。
- 导出审计记录。
+180
View File
@@ -0,0 +1,180 @@
# 安全模型
CyberStrikeAI 面向授权安全测试场景,内置命令执行、MCP 工具、WebShell、C2、批量任务和多代理编排等能力。部署者必须把它当作高权限安全工具管理,而不是普通聊天应用。
## 信任边界
主要边界:
- Web 登录用户:可以发起对话、调用工具、修改配置、管理 WebShell/C2/知识库。
- Agent:根据角色、工具列表、HITL 策略调用内置或外部工具。
- MCP 工具:可能访问本机文件、执行命令、调用外部服务或操作目标系统。
- 外部 MCP:由第三方进程或远端服务提供,需单独信任。
- 机器人入口:企业微信、钉钉、飞书等回调入口不走 Web 登录,但有平台验签和速率限制。
如果一个账号可以登录 Web,就应视为拥有该 CyberStrikeAI 实例的操作权限。
## 认证与会话
`auth.password` 是 Web 登录密码。建议:
- 首次部署立即修改默认密码。
- 使用长随机密码,并限制分享范围。
- 将服务放在内网、VPN、堡垒机或反向代理认证后面。
- 生产环境开启 HTTPS,避免明文传输 Cookie。
- 结合反向代理限制来源 IP。
登录态有效期由 `auth.session_duration_hours` 控制。
## 工具执行风险
工具来源包括:
- 内置安全执行工具。
- `tools/` 下的 YAML 命令工具。
- Eino Skills 文件系统工具,如 `read_file``write_file``edit_file``execute`
- 外部 MCP 暴露的工具。
- C2 和 WebShell 相关 MCP 工具。
风险控制建议:
- 只启用当前任务需要的工具。
- 高风险命令工具不要加入全局白名单。
- 给角色绑定最小工具集合。
- 对 destructive、持久化、横向移动、凭证操作保持人工审批。
- 外部 MCP 尽量使用本地可信进程,远端 MCP 必须有认证和网络隔离。
## HITL
HITL 是工具调用前的审批层。常见模式:
- `human`:人工审批。
- `audit_agent`:审计 Agent 自动审批。
- `review_edit`:审计 Agent 可改参后放行。
建议策略:
- 新环境默认人工审批。
- 只把只读、低风险、稳定工具加入白名单。
- 扫描类工具按目标范围配置角色和提示词约束。
- 写入、删除、执行 payload、C2、WebShell、账号改动等操作必须谨慎审批。
详见 [HITL 最佳实践](hitl-best-practices.md)。
## 审计
平台审计由 `audit` 配置控制,记录登录、配置、资源管理等平台操作。它不记录完整对话正文,也不等同于取证日志。
工具执行记录由监控模块维护,保留时间由 `monitor.retention_days` 控制。
建议:
- 开启 `audit.enabled`
- 定期导出审计日志。
- 配置合理保留期。
- 对失败登录、配置变更、C2/WebShell 操作重点复核。
## C2 风险
内置 C2 会启动监听器、生成 payload、接收会话并执行任务。仅在明确授权的靶场、内网演练或红队环境中启用。
建议:
- 不使用时设置 `c2.enabled: false`
- 不在公网暴露 C2 监听端口,除非有明确授权和隔离。
- 对 payload 文件、回连地址、任务输出进行访问控制。
- C2 任务建议走 HITL。
## WebShell 风险
WebShell 管理允许对已登记连接执行命令和文件操作。建议:
- 只添加授权目标。
- 给连接使用清晰名称、标签和备注。
- 不在共享环境保存真实生产 WebShell。
- AI 使用 WebShell 前确认目标和命令。
- 清理失效或不再授权的连接。
## 数据与隐私
本地会保存:
- 对话和消息:`data/conversations.db`
- 知识库索引:`data/knowledge.db`
- WebShell、C2、漏洞、项目、任务等业务数据。
- 上传附件:`chat_uploads/`
建议:
- 限制文件权限。
- 备份加密。
- 不上传无授权的敏感数据。
- 清理不再需要的会话、附件、C2 输出和审计日志。
## 生产基线
最低建议:
- 强密码 + HTTPS + 内网访问。
- `audit.enabled: true`
- `mcp.auth_header_value` 设置随机值。
- 不需要时关闭 `c2.enabled`
- 外部 MCP 最小化启用。
- 高风险工具不进白名单。
- 定期备份和更新。
## 真实威胁模型
| 威胁 | 攻击路径 | 影响 | 防护点 |
| --- | --- | --- | --- |
| Web 密码泄露 | 登录管理面,调用终端/WebShell/C2 | 完整接管平台能力 | 强密码、HTTPS、内网、反向代理认证、审计 |
| Prompt Injection | 目标页面或文档诱导 Agent 调高权限工具 | 越权执行工具或泄露数据 | 角色边界、HITL、工具最小化、知识库来源标注 |
| 外部 MCP 恶意 | MCP 服务返回误导描述或执行副作用 | 本机或目标系统受影响 | 只接入可信 MCP、独立运行用户、网络隔离 |
| 工具 YAML 被篡改 | 改写命令模板或参数 | Agent 调用时执行恶意命令 | 文件权限、代码审查、工具白名单 |
| C2 滥用 | 生成 payload 或下发任务到非授权目标 | 法律和业务风险 | 默认关闭、审批、事件保留、网络隔离 |
| WebShell 误操作 | AI 或用户在生产目标执行破坏命令 | 业务中断或数据损坏 | 连接命名、人工确认、只读优先、删除过期连接 |
| 数据库泄露 | 复制 `data/*.db` 或上传目录 | 对话、目标、漏洞、连接信息泄露 | 文件权限、加密备份、最小保留 |
## 授权边界写法
每个高风险角色都应把授权边界写进提示词,而不是只依赖用户口头说明。示例:
```text
你只能在用户明确给出的目标范围内行动。若需要执行写入、删除、爆破、持久化、凭证访问、C2、WebShell 或横向移动相关操作,必须先说明目的、影响、目标和回滚方式,并等待 HITL 审批。
```
这段话不能代替技术控制,但能降低 Agent 在模糊任务中扩张行为边界的概率。
## HITL 不是万能保险
HITL 的风险在于审批者看到的是“工具名 + 参数 + 上下文摘要”,不是完整现实世界影响。下面几类情况要特别保守:
- 参数看似只读,但工具本身会触发大量请求或写缓存。
- 命令通过 `bash -c`、脚本、base64 包装隐藏真实动作。
- 外部 MCP 工具描述不可信。
- WebShell 目标名称模糊,无法确认是否生产环境。
- C2 payload 生成和分发链路不在平台内。
审计 Agent 适合筛掉普通低风险请求,不适合替代人类批准破坏性动作。
## 数据最小化原则
不要把这些内容长期留在平台里:
- 真实客户凭证。
- 未脱敏报告。
- 生产数据库导出。
- 长期有效 Cookie。
- 无关目标的扫描输出。
- 已结束项目的 WebShell/C2 会话。
建议按项目结束流程清理:附件、WebShell 连接、C2 payload、临时 workspace、长输出工具记录。
## 源码锚点
- 认证会话:`internal/security/auth_manager.go`
- 认证中间件:`internal/security/auth_middleware.go`
- 限流:`internal/security/ratelimit.go`
- Shell 执行:`internal/security/executor.go`
- HITL 执行:`internal/handler/hitl_execution.go`
- 审计服务:`internal/audit/service.go`
+180
View File
@@ -0,0 +1,180 @@
# Skills 指南
Skills 用于给 Agent 提供可按需加载的专题能力、流程说明、模板和参考资料。它适合承载稳定方法论,而不是一次性任务输入。
## 目录结构
默认目录:
```yaml
skills_dir: skills
```
推荐结构:
```text
skills/
api-security-testing/
SKILL.md
ssrf-testing/
SKILL.md
cyberstrike-eino-demo/
SKILL.md
REFERENCE.md
assets/
```
每个 Skill 至少包含 `SKILL.md`
## SKILL.md
`SKILL.md` 使用 YAML front matter
```markdown
---
name: ssrf-testing
description: SSRF 漏洞识别、验证、绕过和修复建议流程
---
# SSRF Testing
当任务涉及服务端请求伪造、URL 回调、云元数据访问或内网探测时使用本技能。
```
`description` 很重要,Agent 会根据它判断何时加载。
## 渐进式披露
Eino Skills 支持按需加载。配置:
```yaml
multi_agent:
eino_skills:
disable: false
filesystem_tools: true
skill_tool_name: skill
```
Agent 初始只看到技能名称和描述,真正需要时再调用 `skill` 读取详情,减少上下文占用。
## 适合写成 Skill 的内容
- 某类漏洞测试流程。
- 安全审计 checklist。
- 报告模板。
- 工具组合方法。
- 内部规范。
- 常见误报判断。
不适合:
- 临时目标信息。
- API Key、密码、Cookie。
- 经常变化的扫描结果。
- 大量无结构原始日志。
## 附属文件
Skill 可以带附属文件,如 `REFERENCE.md`、模板、字典或示例。`SKILL.md` 中应说明何时读取这些文件。
建议:
- 主文件保持短而清晰。
- 参考资料按主题拆分。
- 大文件只在必要时读取。
## 与角色绑定
角色可以提示 Agent 使用某类 Skill;Skill 也可以通过页面管理和角色形成绑定关系。建议:
- 通用技能保持不绑定,按描述自动触发。
- 高风险技能绑定到专用角色。
- 同类技能不要描述过度重叠。
## 开发建议
Skill 内容结构:
1. 触发场景。
2. 目标和边界。
3. 操作步骤。
4. 工具建议。
5. 输出格式。
6. 风险和禁止事项。
7. 参考资料。
写法要让 Agent 能执行,而不是只给人阅读。
## 排错
Skill 没被使用:
- `description` 过窄或过模糊。
- 任务没有触发关键词。
- `multi_agent.eino_skills.disable: true`
- Skill 文件 front matter 格式错误。
Skill 读取太多:
- 拆分附属文件。
-`SKILL.md` 中明确“只有在需要 X 时读取 Y”。
- 删除重复内容。
## Skill 设计深水区
Skill 的核心价值不是“让 Agent 知道一个概念”,而是让 Agent 在正确时机拿到一套可执行的程序。写 Skill 时要特别关注触发条件和退出条件。
推荐结构:
```markdown
## When to use
明确触发场景。
## Preconditions
需要用户提供什么、目标必须满足什么。
## Procedure
按步骤执行,每步说明工具、输入和判断标准。
## Stop conditions
什么情况下停止、升级审批或转人工。
## Output
最终结果格式。
```
## 反模式
| 反模式 | 后果 | 改法 |
| --- | --- | --- |
| 描述过泛:`用于安全测试` | 几乎所有任务都触发 | 写具体漏洞、场景、信号 |
| 内容像百科 | Agent 不知道下一步做什么 | 改成流程和决策树 |
| 把敏感配置写进 Skill | 泄露和误用 | 用运行时配置或用户输入 |
| 一个 Skill 装所有内容 | 读取成本高,召回混乱 | 按漏洞/任务拆分 |
| 没有停止条件 | Agent 可能持续扩大范围 | 写明何时停止和审批 |
## Skill 与知识库的区别
- Skill:指导 Agent 怎么做,强调流程。
- 知识库:提供事实、案例和参考,强调检索。
例如 SSRF
- Skill 写“如何测试 SSRF、如何判定、何时停止”。
- 知识库写“云厂商 metadata 地址、历史绕过、修复方案”。
## 本地文件工具风险
`filesystem_tools: true` 会暴露读写和执行能力。它对开发和自动化很有用,但也是安全边界。生产环境建议:
- 配合 `workspace_root_dir` 限制工作目录。
- 对写入和执行动作使用 HITL。
- 不把 `execute` 加入全局白名单。
- Skill 中明确禁止读写授权范围外文件。
## 源码锚点
- Skill 包校验:`internal/skillpackage/validate.go`
- Skill 服务:`internal/skillpackage/service.go`
- Eino Skills 接入:`internal/multiagent/eino_skills.go`
- Skills Handler`internal/handler/skills.go`
+191
View File
@@ -0,0 +1,191 @@
# 测试指南
CyberStrikeAI 的测试包括 Go 单测、配置验证、API 手测、MCP 工具验证和前端冒烟测试。
## Go 单测
运行全部内部测试:
```bash
go test ./internal/...
```
运行指定包:
```bash
go test ./internal/workflow
go test ./internal/multiagent
go test ./internal/handler
```
常见重点包:
- `internal/security`
- `internal/mcp`
- `internal/multiagent`
- `internal/workflow`
- `internal/knowledge`
- `internal/project`
- `internal/handler`
- `internal/c2`
## 构建测试
```bash
go build -o cyberstrike-ai ./cmd/server
```
构建通过不代表功能正确,但能发现入口、依赖和静态类型问题。
## 配置验证
启动前检查:
- YAML 缩进。
- 模型配置。
- 数据库路径可写。
- `tools_dir``roles_dir``skills_dir``agents_dir` 是否存在。
- HTTPS 证书路径是否正确。
启动后在 Web 设置页测试:
- OpenAI 兼容模型。
- 视觉模型。
- 工具列表。
- 外部 MCP 状态。
## API 手测
访问:
```text
/api-docs
```
重点验证:
- 登录。
- `/api/eino-agent/stream`
- `/api/config`
- `/api/config/tools`
- `/api/knowledge/search`
- `/api/monitor`
流式接口经过反向代理时要验证输出是否实时。
## 工具测试
新增或修改 `tools/*.yaml` 后:
- 在工具列表中确认 schema。
- 用低风险参数执行。
- 检查错误输出是否可读。
- 检查超时是否生效。
- 检查 HITL 是否按预期拦截。
不要用生产目标测试新工具。
## MCP 测试
外部 MCP
- stdio:先在终端独立运行命令。
- HTTP/SSE:用 curl 检查连通性。
- Web 页面启动后检查 `/api/external-mcp/stats`
- 在对话中确认工具是否可被 `tool_search` 找到。
## 知识库测试
步骤:
1. 放入小型 Markdown 文档。
2. 扫描知识库。
3. 重建索引。
4. 搜索文档中的关键词和同义表达。
5. 查看检索日志。
如果使用真实 embedding API,注意配额和速率限制。
## 前端冒烟
修改前端后至少验证:
- 登录和退出。
- 侧边栏对话列表。
- 新建对话和流式回复。
- 设置页面保存。
- 相关业务页面增删改查。
- 中英文切换。
- 浏览器控制台无明显错误。
## 高风险模块测试
C2、WebShell、终端、批量任务只能在授权测试环境验证。测试前确认:
- 目标是本机、靶机或演练环境。
- 命令无破坏性。
- HITL 策略符合预期。
- 测试后清理会话、payload、上传文件和任务结果。
## 测试金字塔
建议测试分层:
| 层级 | 目标 | 示例 |
| --- | --- | --- |
| 单元测试 | 纯逻辑正确 | 表达式、chunk、脱敏、超时格式 |
| Handler 测试 | HTTP 行为 | 参数校验、状态码、权限 |
| 集成测试 | 多模块协作 | 外部 MCP、知识库索引、HITL |
| 冒烟测试 | 用户路径可用 | 登录、对话、工具、设置 |
| 授权靶场测试 | 高风险能力安全 | C2、WebShell、终端 |
不要用端到端手测代替单元测试,也不要用单元测试代替高风险靶场验证。
## 回归测试重点
修改这些模块时必须扩大测试范围:
- `internal/handler/config.go`:测模型、知识库、MCP、C2、机器人配置应用。
- `internal/multiagent/`:测流式、工具调用、摘要、重试、HITL。
- `internal/security/`:测认证、Shell、超时、无输出。
- `internal/database/`:测旧数据兼容。
- `web/static/js/chat.js`:测对话、过程详情、攻击链、分组。
## 测试数据管理
不要用真实客户数据做测试。建议准备:
- 小型 Markdown 知识库样例。
- 本地假 MCP Server。
- 本地可控 HTTP 目标。
- 无害 WebShell 模拟端。
- 临时 SQLite 数据库。
测试完成后删除临时数据库和上传文件,避免污染开发环境。
## 失败用例比成功用例更重要
至少覆盖:
- 模型 API 401/429/500。
- MCP 进程启动失败。
- 工具超时。
- HITL 拒绝。
- 知识库索引中断。
- 数据库不可写。
- WebShell 目标返回非 200。
- C2 关闭时访问接口。
这些才是用户真实会遇到的问题。
## 源码锚点
已有测试集中在:
- `internal/handler/*_test.go`
- `internal/multiagent/*_test.go`
- `internal/workflow/*_test.go`
- `internal/knowledge/*_test.go`
- `internal/security/*_test.go`
- `internal/mcp/*_test.go`
- `internal/c2/*_test.go`
+224
View File
@@ -0,0 +1,224 @@
# 排错指南
本文按现象列出常见问题。优先查看服务日志、浏览器控制台和 `/api-docs` 中的接口响应。
## 无法访问页面
检查:
- 服务是否启动。
- 端口是否被占用。
- 配置中是否启用 HTTPS。
- 访问协议是否正确。
默认配置常见地址:
```text
https://127.0.0.1:8080/
```
如果使用自签证书,浏览器会提示不受信任,需要手动继续访问。
## 登录失败
检查:
- `config.yaml` 中的 `auth.password`
- 是否修改后未重启或未应用配置。
- 浏览器 Cookie 是否异常,可尝试无痕窗口。
- 审计日志中是否有登录失败节流。
生产环境忘记密码时,需要在服务器上修改 `config.yaml` 并重启服务。
## 模型无响应
检查:
- `openai.base_url` 是否包含正确路径,如 `/v1`
- `openai.api_key` 是否有效。
- `openai.model` 是否存在。
- 服务商是否支持当前 `reasoning` 字段。
可在系统设置中使用模型测试。若网关报 400,先尝试:
```yaml
openai:
reasoning:
mode: off
```
## 流式输出中断
常见原因:
- 反向代理缓冲 SSE。
- 模型网关超时。
- 浏览器网络断开。
- 上下文过大。
Nginx 需要:
```nginx
proxy_buffering off;
proxy_http_version 1.1;
```
## 工具执行失败
检查:
- 工具命令是否已安装到 PATH。
- `tools/*.yaml` 参数 schema 是否正确。
- 是否被 HITL 拒绝。
- 是否超过 `agent.tool_timeout_minutes`
- Shell 长时间无输出是否触发 `shell_no_output_timeout_seconds`
工具配置可参考 `tools/README.md`
## MCP 连不上
内置 MCP
- 检查 `mcp.enabled`
- 检查 `mcp.port`
- 检查 `auth_header``auth_header_value`
外部 MCP
- stdio:检查命令路径、工作目录、环境变量。
- HTTP/SSE:检查 URL、认证、网络连通性。
- 查看 `/api/external-mcp/stats`
## 知识库不可用
检查:
- `knowledge.enabled: true`
- embedding 配置是否正确。
- 是否已经扫描并重建索引。
- `data/knowledge.db` 是否可写。
- 嵌入服务是否 429 或超时。
如果索引大量失败,降低:
```yaml
knowledge:
indexing:
batch_size: 5
rate_limit_delay_ms: 600
```
## 机器人没有回复
检查:
- 对应平台 `robots.<platform>.enabled`
- 平台回调 URL 是否指向 `/api/robot/...`
- Token、secret、verify_token 是否一致。
- 服务器是否可被平台访问。
- 群聊是否需要 @ 机器人。
详细步骤见 [机器人使用说明](robot.md)。
## C2 监听器启动失败
检查:
- `c2.enabled`
- 端口是否被占用。
- 防火墙或安全组。
- 是否需要管理员权限绑定低端口。
关闭 C2 后 `/api/c2/*` 返回 503 是预期行为。
## WebShell 命令乱码
处理:
- 确认目标系统编码。
- 尝试更短命令。
- 使用 base64 包装输出。
- Windows 目标检查代码页。
## 数据库锁或写入失败
检查:
- `data/` 是否可写。
- 是否多个实例共用同一个 SQLite 文件。
- 磁盘是否满。
- 是否异常复制了 WAL/SHM 文件。
生产环境不要让多个进程同时写同一份 SQLite 数据库。
## 前端页面异常
检查:
- 浏览器控制台错误。
- 静态资源是否加载成功。
- 修改前端后是否刷新缓存。
- i18n key 是否缺失。
接口异常时打开 `/api-docs` 对照请求体。
## 诊断顺序
遇到问题时不要直接改配置,先定位层级:
1. 进程:服务是否还在,日志是否有 panic。
2. 网络:端口、HTTPS、反向代理、浏览器控制台。
3. 认证:`/api/auth/validate` 是否 200。
4. 配置:`/api/config` 是否能读,应用后是否报错。
5. 模型:模型测试是否通过。
6. 工具:工具列表和单个 schema 是否正常。
7. 数据库:`data/` 是否可写,有无锁。
8. 业务模块:知识库、MCP、C2、WebShell 分别测最小动作。
先定位层级,再改参数。否则容易把一个代理问题误判成模型问题。
## 最小诊断命令
```bash
# 进程和端口
lsof -i :8080
# 本机 HTTPS 是否通
curl -k -I https://127.0.0.1:8080/
# 静态资源是否通
curl -k -I https://127.0.0.1:8080/static/logo.png
# 查看数据库文件
ls -lh data/
```
如果经过 Nginx,再分别测代理地址和回源地址,确认问题在哪一层。
## 常见误判
- “模型坏了”:实际是 HITL 挂起等待审批。
- “工具没加载”:实际是 tool_search 隐藏了大部分工具。
- “知识库没效果”:实际是索引没重建或 risk_type 过滤过窄。
- “C2 接口坏了”:实际是 `c2.enabled: false`,返回 503 是正常保护。
- “配置保存了但没生效”:实际是监听端口/TLS 需要重启。
- “机器人不回复”:实际是平台侧没有正确配置回调 URL 或验签参数。
## 故障报告模板
提交问题时建议附:
```text
版本/提交:
启动方式:
访问方式:http/https/反向代理:
相关配置段:
复现步骤:
预期结果:
实际结果:
服务端日志:
浏览器控制台:
相关接口响应:
```
有了这些信息,定位速度通常会快很多。
+176
View File
@@ -0,0 +1,176 @@
# WebShell 管理
WebShell 管理用于保存授权目标的 WebShell 连接,并通过 Web 页面或 Agent 工具执行命令、文件操作和上下文分析。
## 基本流程
1. 在 WebShell 页面新增连接。
2. 填写名称、URL、密码或请求参数。
3. 测试连接。
4. 执行命令或文件操作。
5. 在对话中选择 WebShell 连接,让 AI 基于该连接辅助排查。
连接数据保存在 SQLite 中。
## 接口
主要 API
- `GET /api/webshell/connections`
- `POST /api/webshell/connections`
- `PUT /api/webshell/connections/:id`
- `DELETE /api/webshell/connections/:id`
- `GET /api/webshell/connections/:id/state`
- `PUT /api/webshell/connections/:id/state`
- `POST /api/webshell/exec`
- `POST /api/webshell/file`
- `GET /api/webshell/connections/:id/ai-history`
- `GET /api/webshell/connections/:id/ai-conversations`
## MCP 工具
系统会注册 WebShell MCP 工具,例如:
- `webshell_exec`:在连接上执行命令。
- `webshell_file_list`:列目录。
- `webshell_file_read`:读取文件。
- `webshell_file_write`:写文件。
- WebShell 连接管理工具。
Agent 使用这些工具时需要 `connection_id`。前端通常会把当前选中的连接注入上下文。
## 命令执行
执行命令前确认:
- 当前连接属于授权目标。
- 命令不会破坏业务。
- 输出中可能包含敏感信息。
- 长命令和交互式命令不适合 WebShell 通道。
建议先执行只读命令确认环境:
```bash
whoami
pwd
uname -a
id
```
Windows 目标可用:
```cmd
whoami
cd
ver
ipconfig
```
## 文件操作
文件操作包括列目录、读取、写入。建议:
- 写入前先备份原文件。
- 不在生产目标写入未经确认的脚本或二进制。
- 大文件优先通过专用下载/上传通道处理。
- 注意目标编码和换行符。
## AI 辅助
AI 可以帮助:
- 识别操作系统和当前权限。
- 规划只读枚举步骤。
- 分析命令输出。
- 汇总风险和修复建议。
不建议让 AI 自动执行:
- 删除文件。
- 修改业务配置。
- 持久化。
- 凭证抓取。
- 大范围扫描内网。
这些操作应由人工确认,并配合 HITL。
## 安全建议
- 仅保存授权目标连接。
- 给连接命名时包含项目、环境、目标。
- 演练结束后删除连接。
- 不把 WebShell 写入工具加入全局免审批白名单。
- 重要输出及时纳入项目事实或报告,随后清理敏感原始数据。
## 排错
连接失败:
- URL 不可达。
- 参数名或密码错误。
- 目标 WAF 拦截。
- 代理或 TLS 配置异常。
命令乱码:
- 检查目标系统编码。
- 尝试切换命令输出编码或使用 base64 包装。
AI 找不到连接:
- 确认前端已选中 WebShell 连接。
- 确认连接未被删除。
- 检查 `connection_id` 是否正确。
## 操作分层
WebShell 操作建议分成四层,不同层级使用不同审批策略:
| 层级 | 操作 | 风险 | 建议 |
| --- | --- | --- | --- |
| 识别 | `whoami``pwd`、系统版本 | 低 | 可自动 |
| 枚举 | 目录、进程、环境变量 | 中 | 限定路径和命令 |
| 读取 | 配置、日志、源码 | 中高 | 人工确认敏感性 |
| 写入/执行 | 写文件、运行脚本、删除 | 高 | 人工审批,说明回滚 |
不要把“WebShell 已经拿到了”理解成“后续操作都低风险”。WebShell 通常位于业务系统内部,误操作成本很高。
## 连接命名规范
建议命名:
```text
<项目>-<环境>-<目标>-<权限>-<日期>
```
示例:
```text
acme-staging-web01-www-20260707
```
糟糕命名:
```text
test
shell1
客户机器
```
AI 和人类审批都依赖上下文,连接名称含糊会直接放大误操作概率。
## AI 使用约束模板
给 WebShell 相关角色加一段约束:
```text
使用 WebShell 前先确认 connection_id、目标名称、当前目录和权限。默认只执行只读命令。任何写入、删除、上传、权限修改、持久化、凭证读取、内网探测都必须先给出目的、影响和回滚方式,并等待审批。
```
## 源码锚点
- Handler`internal/handler/webshell.go`
- 连接上下文:`internal/handler/webshell_context.go`
- 探测逻辑:`internal/handler/webshell_probe.go`
- OS/编码处理测试:`internal/handler/webshell_os_test.go``internal/handler/webshell_encoding_test.go`
- MCP 工具注册:`internal/app/app.go``registerWebshellTools`
+553
View File
@@ -0,0 +1,553 @@
# CyberStrikeAI 图编排使用说明
[English](../en-US/workflow-graph.md)
本文档说明 **图编排(Graph Orchestration** 的完整使用方式:如何在画布上搭建流程、配置各类型节点、在节点之间传递数据,以及如何将流程绑定到角色并自动运行。
---
## 一、在哪里使用图编排
1. 登录 CyberStrikeAI Web 端
2. 左侧导航进入 **图编排**
3. 在左侧列表选择已有流程,或新建流程
4. 在中央画布拖拽、连线、配置节点
5. 填写流程 **ID**、**名称**、**描述** 后点击 **保存**
保存后的流程可在 **角色管理** 中绑定到某个角色。绑定后,用户与该角色对话时会按流程图自动执行(`workflow_policy: auto`)。
---
## 二、画布基本操作
| 操作 | 说明 |
|------|------|
| 添加节点 | 点击画布上方节点类型按钮(开始、工具、Agent、条件、审批、输出、结束) |
| 连线 | 点击 **连线**,依次点击源节点和目标节点;再次点击 **连线** 退出连线模式 |
| 选中元素 | 单击节点或连线,右侧显示 **节点属性** |
| 删除选中 | 点击 **删除选中** 删除当前节点或连线 |
| 自动布局 | 点击 **自动布局** 整理节点位置 |
| 试运行 | 点击 **试运行** 使用安全 dry-run 验证数据流;工具、Agent、审批不会真实执行 |
| 删除流程 | 点击 **删除** 删除整个流程定义 |
**硬性规则:** 每个流程至少包含 **1 个开始节点****1 个输出节点**;开始节点不能有入边,输出 / 结束节点不能有出边。保存时前端和后端都会执行严格校验。
---
## 三、执行模型(先理解再配置)
图编排按 **有向图** 执行,引擎从 **开始** 节点出发,沿连线依次运行下游节点。
每次运行会维护一份内部状态,模板变量 `{{...}}` 从这里取值:
| 内部状态 | 模板前缀 | 含义 |
|----------|----------|------|
| `inputs` | `{{inputs.xxx}}` | 流程启动时的输入(用户消息、会话 ID 等) |
| `lastOutput` | `{{previous.xxx}}` | **上一个刚执行完** 的节点的输出 |
| `outputs` | `{{outputs.xxx}}` | 全局 **命名变量池**(由节点的「输出变量名」写入) |
| `nodeOutputs` | `{{节点ID.xxx}}` | 指定节点 ID 的完整输出对象 |
| `metrics` | 运行详情中查看 | 节点耗时、工具调用数、可收集到的 token / cost 等指标 |
### 3.1 `previous` 是什么?
`{{previous.output}}` 表示 **紧邻的上一个执行节点**`output` 字段。
- 每执行完一个节点,引擎都会更新 `lastOutput`
- **不是**「画布上画线的上游」,而是 **实际执行顺序上的上一步**
示例:
```text
开始 → Agent A → Agent B
```
Agent B 的 `{{previous.output}}` = Agent A 的输出。
但若中间有条件节点:
```text
开始 → Agent A → 条件 → Agent B
```
Agent B 的 `{{previous.output}}` = **条件节点** 的输出(`true` / `false`),**不是** Agent A 的结果。
如果一个节点有 **多个上游节点** 同时连入,`previous` 会先按该节点的 **汇聚策略** 生成:
| 汇聚策略 | 含义 | 适合场景 |
|----------|------|----------|
| `all_merge` | 合并所有上游输出,`previous.output` 为数组 | 默认推荐,综合多路结果 |
| `last_by_canvas` | 按画布顺序取最后一个上游输出 | 明确只采用一路结果 |
| `first_non_empty` | 取第一个非空输出 | 多路兜底 |
| `fail_fast` | 任一上游失败则中止当前节点 | 关键链路、审批前置、安全检查 |
### 3.2 `outputs` 是什么?
`outputs` 是引擎在运行过程中维护的 **命名变量注册表**
当 Agent、工具、输出 等节点配置了 **输出变量名**(字段 `output_key`)后,节点执行成功会把结果写入:
```text
outputs["你填的变量名"] = 节点输出内容
```
之后 **任意下游节点** 都可以通过 `{{outputs.变量名}}` 引用,不要求两个节点直接相连。
示例:
- Agent A 的 **输出变量名**`agent_result1`
- Agent B 的 **输入来源**`{{outputs.agent_result1}}`
即使 A 和 B 之间隔着条件节点,B 仍能拿到 A 的输出。
### 3.3 什么时候用 `previous`,什么时候用 `outputs`
| 场景 | 推荐写法 |
|------|----------|
| 两个节点 **直连**,只取上一步结果 | `{{previous.output}}` |
| 中间有其他节点(条件、工具、审批等) | `{{outputs.变量名}}` |
| 需要引用 **更早** 的某个节点结果 | `{{outputs.变量名}}``{{节点ID.output}}` |
| 条件判断要基于某 Agent 的输出 | `{{outputs.变量名}} != ""` |
| 读取用户最初输入 | `{{inputs.message}}` |
**记忆口诀:**
- `previous` = 上一步(链式、紧邻)
- `outputs` = 按名字取(跨节点、可回溯)
---
## 四、模板语法
### 4.1 基本格式
```text
{{变量路径}}
```
支持字母、数字、下划线、点、连字符,例如:
```text
{{previous.output}}
{{outputs.agent_result1}}
{{inputs.message}}
{{inputs.conversationId}}
{{previous.matched}}
{{node-abc123.output}}
```
### 4.2 可用路径一览
| 路径 | 说明 |
|------|------|
| `{{inputs.message}}` | 用户消息(开始节点输入) |
| `{{inputs.conversationId}}` | 会话 ID |
| `{{inputs.projectId}}` | 项目 ID |
| `{{previous.output}}` | 上一节点主输出 |
| `{{previous.matched}}` | 上一条件节点的匹配结果(`true` / `false` |
| `{{outputs.变量名}}` | 某节点注册过的命名输出 |
| `{{节点ID.output}}` | 指定节点 ID 的 `output` 字段 |
| `{{previous.kind}}` | 上一节点输出类型,如 `agent` / `tool` / `condition` |
| `{{previous.status}}` | 上一节点状态,如 `completed` / `failed` / `simulated` |
节点输出会保留兼容字段(如 `output``matched`),同时带有结构化字段:
```json
{
"kind": "agent",
"node_id": "node-2",
"node_type": "agent",
"status": "completed",
"output": "..."
}
```
### 4.3 条件表达式
条件节点和连线条件支持比较、文本匹配、正则、逻辑组合与安全 JSONPath/JQ 路径读取:
```text
{{outputs.agent_result1}} != ""
{{previous.output}} == "ok"
{{outputs.count}} >= 100
{{previous.output}} contains "success"
{{previous.output}} matches "^ok"
{{outputs.risk_score}} >= 8 && {{previous.output}} != ""
jsonpath({{previous.output}}, "$.status") == "ok"
jq({{outputs.scan}}, ".severity") == "high"
```
规则:
- 支持 `==``!=``>``>=``<``<=`
- 支持 `contains` 子串匹配与 `matches` 正则匹配
- 支持简单 `&&` / `||`
- 支持 `jsonpath(value, "$.path")``jq(value, ".path")` 的**安全路径子集**,仅做字段读取,不执行任意脚本
- 比较两侧会自动去掉首尾空格和引号
- 无比较符时,非空且不为 `false` / `0` / `null` 视为真
- 保存时会静态校验表达式格式、JSONPath/JQ 路径和正则语法
### 4.4 嵌套字段绑定
节点的字段绑定除 `output``message` 等普通字段外,也支持 JSONPath/JQ 风格路径:
| 绑定配置 | 含义 |
|----------|------|
| `from=previous, field=$.status` | 从上一节点输出对象读取 `status` |
| `from=outputs, field=$.scan.severity` | 从命名输出中读取嵌套字段 |
| `from=node-1, field=.output.items[0]` | 从指定节点输出读取数组元素 |
---
## 五、节点类型与配置
### 5.1 开始(start
流程入口,将用户输入注入 `inputs`
| 字段 | 说明 | 默认值 |
|------|------|--------|
| 输入变量 | 逗号分隔的输入键名 | `message, conversationId, projectId` |
开始节点输出包含:`output``message``conversationId``projectId`
### 5.2 Agentagent
调用大模型 Agent 处理任务,支持多种运行模式。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| Agent 模式 | `eino_single` / `deep` / `plan_execute` / `supervisor` | `eino_single` |
| 输入来源 | 上游数据的模板表达式 | `{{previous.output}}` |
| 节点指令 | 本节点要完成的任务描述 | 空 |
| 输出变量名 | 写入 `outputs` 的键名 | `agent_result` |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
**消息拼装规则:**
- 仅填 **节点指令**:直接把指令发给 Agent
- 仅填 **输入来源**:生成「请基于上游节点输出继续处理:…」
- 两者都填:合并为「上游输入 + 节点指令」
Agent 节点执行后:
- `previous.output` 更新为本节点响应文本
- 若配置了 **输出变量名**,同时写入 `outputs[输出变量名]`
- Agent 子图在 Eino 中拆为 `prepare → execute → finalize`,便于 trace 与后续局部 checkpoint
### 5.3 工具(tool
调用已启用的 MCP 工具。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| MCP 工具 | 工具名称(必填) | — |
| 参数模板 | JSON,支持 `{{...}}` 模板 | `{}` |
| 超时秒数 | 可选 | 空 |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
示例参数模板:
```json
{"target": "{{inputs.message}}", "port": "443"}
```
若配置了 **输出变量名**,工具返回结果会写入 `outputs`
### 5.4 条件(condition
根据表达式计算分支,输出 `matched``true` / `false`)。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| 条件表达式 | 支持 `{{...}}``==` / `!=` | `{{previous.output}} != ""` |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
**分支规则:**
- 从条件节点连出的 **第一条线** 默认为 **「是」** 分支(`matched == true`
- **第二条线** 默认为 **「否」** 分支(`matched == false`
- 连线标签可写 `是` / `否`(或 `yes` / `no``true` / `false`)辅助识别
- 第三条及以后的出边需在 **连线条件** 中自定义表达式
连线条件示例(选中连线后在右侧配置):
```text
{{previous.matched}} == "true"
{{previous.matched}} == "false"
```
### 5.5 审批(hitl
人工确认检查点。流程运行到该节点前会通过 Eino interrupt/checkpoint 暂停,等待 API 或监控面板审批后恢复。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| 审批提示 | 支持模板 | `请审批该步骤是否继续执行` |
| 提示字段绑定 | 留空审批提示时,从绑定字段读取说明 | `previous.output` |
| 审批方 | `human` / `audit_agent` | `human` |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
HITL 等待信息会记录:
- `checkpointId`
- interrupt `beforeNodes`
- resume target / address / path
- resume payload schema`approved``comment`
### 5.6 输出(output
将流程最终结果写入 `outputs`,供结束摘要和对话展示使用。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| 输出变量名 | 必填,最终结果的键名 | `result` |
| 变量来源 | 模板表达式,决定写入的值 | `{{previous.output}}` |
| 固定输出值 | 可选,填写后覆盖变量来源 | 空 |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
**注意:** 输出节点是流程的「出口」,不应再有出边。
### 5.7 结束(end
可选节点,用于生成结束摘要模板(角色绑定流程中较少单独使用)。
| 字段 | 说明 | 默认值 |
|------|------|--------|
| 结束摘要模板 | 支持 `{{outputs.xxx}}` | `{{outputs.result}}` |
| 汇聚策略 | 多上游进入本节点时如何生成 `previous` | `all_merge` |
---
## 六、连线配置
选中 **连线** 后,右侧可配置 **连线条件**
| 场景 | 示例 |
|------|------|
| 普通节点后的过滤 | `{{previous.output}} == "ok"` |
| 条件节点「是」分支 | `{{previous.matched}} == "true"` |
| 条件节点「否」分支 | `{{previous.matched}} == "false"` |
若不填连线条件:
- 非条件节点:连线始终放行
- 条件节点:按出边顺序自动分配是/否分支
---
## 七、完整示例:跨条件节点传递 Agent 输出
### 7.1 流程结构
```text
开始 → Agent(生成初始值)→ 条件 → Agent(加工)→ 输出
↘ 否 → 输出
```
### 7.2 节点配置
**Agent 1(第一个 Agent**
| 字段 | 值 |
|------|-----|
| 节点指令 | 只输出 `123333333` |
| 输出变量名 | `agent_result1` |
**条件**
| 字段 | 值 |
|------|-----|
| 条件表达式 | `{{outputs.agent_result1}} != ""` |
**Agent 2(第二个 Agent**
| 字段 | 值 |
|------|-----|
| 输入来源 | `{{outputs.agent_result1}}` |
| 节点指令 | 在输入基础上加 100,然后输出 |
| 输出变量名 | `agent_result` |
**输出**
| 字段 | 值 |
|------|-----|
| 输出变量名 | `result` |
| 变量来源 | `{{outputs.agent_result}}` |
### 7.3 常见错误
| 错误配置 | 原因 |
|----------|------|
| Agent 2 输入来源写 `{{previous.output}}` | `previous` 指向条件节点,得到的是 `true`/`false`,不是 Agent 1 的文本 |
| 未给 Agent 1 填输出变量名 | `outputs.agent_result1` 不存在,下游取到空值 |
| 条件表达式写 `{{previous.output}}` | 判断的是开始节点或上一节点的输出,而非 Agent 1 的命名变量 |
---
## 八、绑定角色并运行
### 8.1 在角色管理中绑定
1. 进入 **角色管理**,编辑或新建角色
2. 选择 **工作流 / 图编排** 绑定的流程 ID
3. 策略设为 `auto`(默认:有 `workflow_id` 时自动执行)
4. 保存角色
也可在角色 YAML 中直接配置:
```yaml
name: 工作流测试
workflow_id: "1233"
workflow_version: latest
workflow_policy: auto
```
### 8.2 运行效果
用户选择该角色并发送消息后:
1. 引擎加载对应 `graph_json` 并按图执行
2. 对话页可看到 `workflow_start``workflow_node_start`、Agent 推理等进度事件
3. 流程结束后返回摘要,列出 `outputs` 中所有命名输出
若未配置输出节点或条件未命中,`outputs` 可能为空,摘要会提示检查输出节点与分支。
---
## 九、调试、试运行与复盘
### 9.1 安全试运行(dry-run
画布工具栏点击 **试运行**,输入一条测试消息即可模拟执行流程。
dry-run 的安全边界:
- `start` / `condition` / `output` / `end` 会按真实逻辑计算
- `tool` 不会真实调用 MCP,只返回 `[dry-run] tool call skipped`
- `agent` 不会真实调用模型,只返回 `[dry-run] agent execution skipped`
- `hitl` 不会暂停,只模拟通过
相关 API
```http
POST /api/workflows/dry-run
```
请求体:
```json
{
"graph": { "nodes": [], "edges": [], "config": {} },
"inputs": { "message": "ping" }
}
```
响应包含:
- `outputs`
- `nodeOutputs`
- `trace`
- `metrics`
- `replayScript`
### 9.2 运行详情与 replay
运行后可查询完整节点执行轨迹:
```http
GET /api/workflows/runs/{runId}
```
返回 `run``nodeRuns`,每个节点记录包含:
- input 快照
- output 快照
- status / error
- started_at / finished_at
- `duration_ms`
复盘接口:
```http
GET /api/workflows/runs/{runId}/replay
```
该接口只根据已保存的 `nodeRuns` 生成步骤,不会重新执行工具或 Agent。
### 9.3 指标(metrics
工作流会尽量累计:
- `node_count`
- `duration_ms`
- `tool_call_count`
- Agent progress 中可收集到的 `prompt_tokens` / `completion_tokens` / `total_tokens` / `cost`
token 与成本是否存在取决于底层模型/Agent 事件是否上报 usage。
---
## 十、保存前校验规则
保存时系统会自动检查:
| 规则 | 说明 |
|------|------|
| 必须有开始节点 | 至少 1 个 `start` |
| 必须有输出节点 | 至少 1 个 `output`,且填写输出变量名 |
| 连线合法 | 源/目标节点存在,不能自环 |
| 开始节点无入边 | 开始节点不能被指向 |
| 输出 / 结束节点无出边 | 输出 / 结束节点后不应再连线 |
| 非开始节点必须有入边 | 避免孤岛节点 |
| 非输出 / 结束节点必须有出边 | 避免执行到死路 |
| 无环路 | Workflow 编排必须是 DAG |
| 可达性 | 所有节点必须能从开始节点到达,并能最终到达 output/end |
| 工具节点 | 必须选择 MCP 工具;参数 JSON 必须合法;超时必须为正整数 |
| Agent 节点 | 必须填写节点指令或输入绑定;必须填写输出变量名 |
| 条件节点 | 必须填写表达式;需要 1~2 条出边;分支必须标记是/否且不能重复 |
| 连线条件 | 表达式、正则、JSONPath/JQ 路径必须通过静态校验 |
| 汇聚策略 | 必须是 `all_merge` / `last_by_canvas` / `first_non_empty` / `fail_fast` |
---
## 十一、排错指南
| 现象 | 可能原因 | 处理建议 |
|------|----------|----------|
| 下游拿到空值 | 上游未配置输出变量名 | 给上游 Agent/工具填 **输出变量名**,下游用 `{{outputs.xxx}}` |
| 下游拿到 `true`/`false` | 误用 `{{previous.output}}`,上一步是条件节点 | 改用 `{{outputs.xxx}}` |
| 条件总走「否」 | 表达式与真实输出格式不一致 | 检查 Agent 输出是否带引号、换行;用 `!= ""` 先验证 |
| 流程无最终输出 | 未命中输出节点所在分支 | 检查条件分支连线;确保至少一条路径到达 **输出** 节点 |
| 角色对话未跑流程 | 角色未绑定或未启用 | 确认 `workflow_id``workflow_policy: auto`、流程 `enabled: true` |
| 工具节点失败 | 参数 JSON 不合法或工具未启用 | 检查参数模板;在 MCP 中启用对应工具 |
| 保存失败提示分支非法 | 条件节点出边未标记是/否或重复 | 选中连线,设置条件分支为 `true``false` |
| 多上游结果不符合预期 | 汇聚策略不合适 | 根据场景改为 `all_merge` / `first_non_empty` / `last_by_canvas` / `fail_fast` |
| 嵌套字段取不到 | JSONPath/JQ 路径不符合安全子集 | 使用 `$.a.b[0]``.a.b[0]`,不要用通配符/递归/表达式 |
---
## 十二、最佳实践
1. **命名规范**:为每个需要被引用的节点设置有意义的输出变量名,如 `scan_result``parsed_targets`,避免都叫 `agent_result`
2. **跨节点传参优先用 `outputs`**:只要中间可能插入条件、工具、审批节点,就应用命名变量。
3. **`previous` 仅用于直连**:A → B 且无中间节点时,`{{previous.output}}` 最简洁。
4. **条件判断引用源数据**:判断 Agent 输出时用 `{{outputs.xxx}}`,不要用 `{{previous.output}}`(除非条件紧跟在目标 Agent 之后)。
5. **每条路径都要有出口**:确保「是」「否」分支最终都能到达 **输出** 节点(或你期望的终点)。
6. **多上游节点显式选择汇聚策略**:综合结果用 `all_merge`,兜底用 `first_non_empty`,关键链路用 `fail_fast`
7. **嵌套 JSON 用 JSONPath/JQ 安全路径**:例如 `jsonpath({{previous.output}}, "$.status") == "ok"`
8. **保存前先 dry-run**:用简单消息验证数据传递和分支,再绑定角色真实执行。
---
## 十三、相关代码位置(开发者参考)
| 模块 | 路径 |
|------|------|
| 执行引擎 | `internal/workflow/runner.go` |
| Eino 编译 / checkpoint / HITL | `internal/workflow/eino_compile.go` |
| 图校验 | `internal/workflow/validation.go` |
| 表达式 / JSONPath / 汇聚 | `internal/workflow/expression.go``jsonpath.go``join.go` |
| dry-run / replay 数据 | `internal/workflow/dry_run.go``internal/handler/workflow_run.go` |
| 画布前端 | `web/static/js/workflows.js` |
| 流程 API | `internal/handler/workflow.go` |
| 角色绑定 | `internal/config/config.go``workflow_id` 字段) |
+39 -14
View File
@@ -3,31 +3,41 @@ module cyberstrike-ai
// go mod download : go env -w GOPROXY=https://goproxy.cn,direct
// 使 scripts/bootstrap-go.sh
go 1.24.0
toolchain go1.24.4
go 1.25
require (
github.com/bwmarrin/discordgo v0.29.0
github.com/bytedance/sonic v1.15.0
github.com/cloudwego/eino v0.8.8
github.com/cloudwego/eino v0.8.13
github.com/cloudwego/eino-ext/adk/backend/local v0.0.0-20260416081055-0ebab92e14f2
github.com/cloudwego/eino-ext/components/document/loader/file v0.0.0-20260416081055-0ebab92e14f2
github.com/cloudwego/eino-ext/components/document/transformer/splitter/markdown v0.0.0-20260416081055-0ebab92e14f2
github.com/cloudwego/eino-ext/components/document/transformer/splitter/recursive v0.0.0-20260416081055-0ebab92e14f2
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260416081055-0ebab92e14f2
github.com/cloudwego/eino-ext/components/model/openai v0.1.12
github.com/cloudwego/eino-ext/components/document/loader/file v0.0.0-20260427010451-749e3706378b
github.com/cloudwego/eino-ext/components/document/transformer/splitter/markdown v0.0.0-20260427010451-749e3706378b
github.com/cloudwego/eino-ext/components/document/transformer/splitter/recursive v0.0.0-20260427010451-749e3706378b
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260427010451-749e3706378b
github.com/cloudwego/eino-ext/components/model/openai v0.1.13
github.com/creack/pty v1.1.24
github.com/disintegration/imaging v1.6.2
github.com/eino-contrib/jsonschema v1.0.3
github.com/gin-gonic/gin v1.9.1
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.0
github.com/gorilla/websocket v1.5.3
github.com/larksuite/oapi-sdk-go/v3 v3.4.22
github.com/mattn/go-sqlite3 v1.14.18
github.com/modelcontextprotocol/go-sdk v1.2.0
github.com/open-dingtalk/dingtalk-stream-sdk-go v0.9.1
github.com/pkoukk/tiktoken-go v0.1.8
github.com/robfig/cron/v3 v3.0.1
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/slack-go/slack v0.27.0
github.com/tencent-connect/botgo v0.2.1
go.opentelemetry.io/otel v1.34.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.34.0
go.opentelemetry.io/otel/sdk v1.34.0
go.opentelemetry.io/otel/trace v1.34.0
go.uber.org/zap v1.26.0
golang.org/x/net v0.35.0
golang.org/x/text v0.26.0
golang.org/x/time v0.14.0
gopkg.in/yaml.v3 v3.0.1
)
@@ -38,20 +48,25 @@ require (
github.com/buger/jsonparser v1.1.1 // indirect
github.com/bytedance/gopkg v0.1.3 // indirect
github.com/bytedance/sonic/loader v0.5.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.16 // indirect
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.17 // indirect
github.com/dlclark/regexp2 v1.10.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/evanphx/json-patch v0.5.2 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/go-resty/resty/v2 v2.6.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/jsonschema-go v0.3.0 // indirect
github.com/goph/emperror v0.17.2 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
@@ -65,20 +80,30 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f // indirect
github.com/tidwall/gjson v1.9.3 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/yargevad/filepathx v1.0.0 // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.15.0 // indirect
golang.org/x/crypto v0.39.0 // indirect
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.26.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
google.golang.org/grpc v1.69.4 // indirect
google.golang.org/protobuf v1.36.3 // indirect
)
// Stream SDK / "panic: send on closed channel"
+174 -19
View File
@@ -1,3 +1,4 @@
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
github.com/airbrake/gobrake v3.6.1+incompatible/go.mod h1:wM4gu3Cn0W0K7GUuVWnlXZU11AGBXMILnrdOU8Kn00o=
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
@@ -9,6 +10,8 @@ github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMU
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/bugsnag/bugsnag-go v1.4.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/bwmarrin/discordgo v0.29.0 h1:FmWeXFaKUwrcL3Cx65c20bTRW+vOb6k8AnaP+EgjDno=
github.com/bwmarrin/discordgo v0.29.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
github.com/bytedance/mockey v1.3.0 h1:ONLRdvhqmCfr9rTasUB8ZKCfvbdD2tohOg4u+4Q/ed0=
@@ -17,30 +20,38 @@ github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uS
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/certifi/gocertifi v0.0.0-20190105021004-abcd57078448/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
github.com/cloudwego/eino v0.8.8 h1:64NuheQBmxOXe/28Tm85rkBkxXMB5ZhjSu/j0RDFyZU=
github.com/cloudwego/eino v0.8.8/go.mod h1:+2N4nsMPxA6kGBHpH+75JuTfEcGprAMTdsZESrShKpU=
github.com/cloudwego/eino v0.8.13 h1:z5dhaZNN8TWZbP/lgKxGmF26Ii8fPeUlQCGV/NTtms0=
github.com/cloudwego/eino v0.8.13/go.mod h1:+2N4nsMPxA6kGBHpH+75JuTfEcGprAMTdsZESrShKpU=
github.com/cloudwego/eino-ext/adk/backend/local v0.0.0-20260416081055-0ebab92e14f2 h1:v2w9TyLAmNsMWo8NwntCc76uvNf6isTFkHB+oZZ8NqI=
github.com/cloudwego/eino-ext/adk/backend/local v0.0.0-20260416081055-0ebab92e14f2/go.mod h1:os5Tq5FuSoz/MLqAdZER3ip49Oef9prc0kVsKsPYO48=
github.com/cloudwego/eino-ext/components/document/loader/file v0.0.0-20260416081055-0ebab92e14f2 h1:H5Ohr3OWSjiTOe7y9pOPyVCKCNjAVj9YMaWmvZNTYPg=
github.com/cloudwego/eino-ext/components/document/loader/file v0.0.0-20260416081055-0ebab92e14f2/go.mod h1:HnxTQxmhuev6zaBl92EHUy/vEDWCuoE/OE4cTiF5JCg=
github.com/cloudwego/eino-ext/components/document/transformer/splitter/markdown v0.0.0-20260416081055-0ebab92e14f2 h1:PRli0CmPfgUhwMGWGEAwg8nxde8hInC2OWv0vcIuwMk=
github.com/cloudwego/eino-ext/components/document/transformer/splitter/markdown v0.0.0-20260416081055-0ebab92e14f2/go.mod h1:KVOVct4e2BQ7epDONW2QE1qU5+ccoh91FzJTs9vIJj0=
github.com/cloudwego/eino-ext/components/document/transformer/splitter/recursive v0.0.0-20260416081055-0ebab92e14f2 h1:8sOFcDf9MtMVDQyozZtuhrmt+mLQRHEaf6dYC20Vxhs=
github.com/cloudwego/eino-ext/components/document/transformer/splitter/recursive v0.0.0-20260416081055-0ebab92e14f2/go.mod h1:9R0RQrQSpg1JaNnRtw7+RfRAAv0HgdE348YnrlZ6coo=
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260416081055-0ebab92e14f2 h1:OzKPBfGCJhjbtO+WfIMNSSnXxsj6/hUiyYOTaG2LUf4=
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260416081055-0ebab92e14f2/go.mod h1:zyPrZT2bO6LyRJgVksQowR18jVgyLSvqK93hnO53/Lc=
github.com/cloudwego/eino-ext/components/model/openai v0.1.12 h1:vcwNXeT7bpaXMNwUhtcHZwMYY8II2jAihuooyivmEZ0=
github.com/cloudwego/eino-ext/components/model/openai v0.1.12/go.mod h1:ve/+/hLZMvxD5AieQ355xHIFhAZVlsG4rdwTnE16aQU=
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.16 h1:q242n5P5Tx3a2QLaBmkfEpfRs/o17Ac6u3EAgItEEOc=
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.16/go.mod h1:p+l0zBB0GjjX8HTlbTs3g3KfUFwZC11bsCGZOXW/3L0=
github.com/cloudwego/eino-ext/components/document/loader/file v0.0.0-20260427010451-749e3706378b h1:GIOC/VnXuSQx79mnQ3HgMvECjtyqvpJipmSUTFFfVsc=
github.com/cloudwego/eino-ext/components/document/loader/file v0.0.0-20260427010451-749e3706378b/go.mod h1:HnxTQxmhuev6zaBl92EHUy/vEDWCuoE/OE4cTiF5JCg=
github.com/cloudwego/eino-ext/components/document/transformer/splitter/markdown v0.0.0-20260427010451-749e3706378b h1:3owjV4nv+XRplavTeqFlCeAV4v7EHR2tIXDqLEmPc38=
github.com/cloudwego/eino-ext/components/document/transformer/splitter/markdown v0.0.0-20260427010451-749e3706378b/go.mod h1:KVOVct4e2BQ7epDONW2QE1qU5+ccoh91FzJTs9vIJj0=
github.com/cloudwego/eino-ext/components/document/transformer/splitter/recursive v0.0.0-20260427010451-749e3706378b h1:j8sj/5QiooV3LWphFDsJvyD/csWwupz+UKXeG+nqiNg=
github.com/cloudwego/eino-ext/components/document/transformer/splitter/recursive v0.0.0-20260427010451-749e3706378b/go.mod h1:9R0RQrQSpg1JaNnRtw7+RfRAAv0HgdE348YnrlZ6coo=
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260427010451-749e3706378b h1:pOqupZQyc46rw2Z0HeybtTmSMTwqfTrbRuGDuDsNf2A=
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260427010451-749e3706378b/go.mod h1:zyPrZT2bO6LyRJgVksQowR18jVgyLSvqK93hnO53/Lc=
github.com/cloudwego/eino-ext/components/model/openai v0.1.13 h1:5XHRTiTD5bt9KQrMHcfvuWNklEC3tpm3XHejdozt9vM=
github.com/cloudwego/eino-ext/components/model/openai v0.1.13/go.mod h1:mgIoqYYOc0eECCqvLbEYpOJrQNTNxkwXzSJzFU+v5sQ=
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.17 h1:EeVcR1TslRA2IdNW1h/2LaGbPlffwGhQm99jM3zWZiI=
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.17/go.mod h1:Zkcx6DPTR2NfWmtSXbhItswGw6hqUezNPhNcke0pOG8=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
@@ -50,6 +61,7 @@ github.com/eino-contrib/jsonschema v1.0.3/go.mod h1:cpnX4SyKjWjGC7iN2EbhxaTdLqGj
github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
@@ -59,6 +71,11 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@@ -67,6 +84,12 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4=
github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
@@ -75,21 +98,40 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/jsonschema-go v0.3.0 h1:6AH2TxVNtk3IlvkkhjrtbUc4S8AvO0Xii0DxIygDg+Q=
github.com/google/jsonschema-go v0.3.0/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/goph/emperror v0.17.2 h1:yLapQcmEsO0ipe9p5TaN22djm3OFV/TfM/fcYP0/J18=
github.com/goph/emperror v0.17.2/go.mod h1:+ZbQ+fUNO/6FNiUo0ujtMjhgad9Xa6fQL9KhH4LNHic=
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -103,6 +145,8 @@ github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -134,11 +178,19 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nikolalohinski/gonja v1.5.3 h1:GsA+EEaZDZPGJ8JtpeGN78jidhOlxeJROpqMT9fTj9c=
github.com/nikolalohinski/gonja v1.5.3/go.mod h1:RmjwxNiXAEqcq1HeK5SSMmqFJvKOfTfXhkJv6YBtPa4=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -148,12 +200,18 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/rollbar/rollbar-go v1.0.2/go.mod h1:AcFs5f0I+c71bpHlXNNDbOWJiKwjFDtISeXco0L5PKQ=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
github.com/slack-go/slack v0.27.0 h1:VWOpUzOK6UAPCCQlFxl79jhv8a/b+GOSJMnWziDJ8B8=
github.com/slack-go/slack v0.27.0/go.mod h1:UEe+jmo9WLlwHB04qsOrTDvqM7Aa4rQL3O5wF3n0hx4=
github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f h1:Z2cODYsUxQPofhpYRMQVwWz4yUVpHF+vPi+eUdruUYI=
github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f/go.mod h1:JqzWyvTuI2X4+9wOHmKSQCYxybB/8j6Ko43qVmXDuZg=
github.com/smarty/assertions v1.16.0 h1:EvHNkdRA4QHMrn75NZSoUQ/mAUXAYWfatfB01yTCzfY=
@@ -167,14 +225,24 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tencent-connect/botgo v0.2.1 h1:+BrTt9Zh+awL28GWC4g5Na3nQaGRWb0N5IctS8WqBCk=
github.com/tencent-connect/botgo v0.2.1/go.mod h1:oO1sG9ybhXNickvt+CVym5khwQ+uKhTR+IhTqEfOVsI=
github.com/tidwall/gjson v1.9.3 h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E=
github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
@@ -191,6 +259,27 @@ github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zI
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.34.0 h1:jBpDk4HAUsrnVO1FsfCfCOTEc/MkInJmvfCHYLFiT80=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.34.0/go.mod h1:H9LUIM1daaeZaz91vZcfeM0fejXPmgCYE8ZhzqfJuiU=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
@@ -205,38 +294,82 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
@@ -244,22 +377,44 @@ golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA=
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A=
google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU=
google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 832 KiB

After

Width:  |  Height:  |  Size: 941 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 KiB

After

Width:  |  Height:  |  Size: 741 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 420 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 656 KiB

After

Width:  |  Height:  |  Size: 551 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 KiB

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 493 KiB

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 KiB

After

Width:  |  Height:  |  Size: 775 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 451 KiB

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 86 KiB

+136 -1161
View File
File diff suppressed because it is too large Load Diff
+13 -232
View File
@@ -1,286 +1,67 @@
package agent
import (
"os"
"path/filepath"
"strings"
"testing"
"time"
"cyberstrike-ai/internal/config"
"cyberstrike-ai/internal/mcp"
"cyberstrike-ai/internal/storage"
"go.uber.org/zap"
)
// setupTestAgent 创建测试用的Agent
func setupTestAgent(t *testing.T) (*Agent, *storage.FileResultStorage) {
func setupTestAgent(t *testing.T) *Agent {
logger := zap.NewNop()
mcpServer := mcp.NewServer(logger)
openAICfg := &config.OpenAIConfig{
APIKey: "test-key",
BaseURL: "https://api.test.com/v1",
Model: "test-model",
}
agentCfg := &config.AgentConfig{
MaxIterations: 10,
LargeResultThreshold: 100, // 设置较小的阈值便于测试
ResultStorageDir: "",
MaxIterations: 10,
}
agent := NewAgent(openAICfg, agentCfg, mcpServer, nil, logger, 10)
// 创建测试存储
tmpDir := filepath.Join(os.TempDir(), "test_agent_storage_"+time.Now().Format("20060102_150405"))
testStorage, err := storage.NewFileResultStorage(tmpDir, logger)
if err != nil {
t.Fatalf("创建测试存储失败: %v", err)
}
agent.SetResultStorage(testStorage)
return agent, testStorage
}
func TestAgent_FormatMinimalNotification(t *testing.T) {
agent, testStorage := setupTestAgent(t)
_ = testStorage // 避免未使用变量警告
executionID := "test_exec_001"
toolName := "nmap_scan"
size := 50000
lineCount := 1000
filePath := "tmp/test_exec_001.txt"
notification := agent.formatMinimalNotification(executionID, toolName, size, lineCount, filePath)
// 验证通知包含必要信息
if !strings.Contains(notification, executionID) {
t.Errorf("通知中应该包含执行ID: %s", executionID)
}
if !strings.Contains(notification, toolName) {
t.Errorf("通知中应该包含工具名称: %s", toolName)
}
if !strings.Contains(notification, "50000") {
t.Errorf("通知中应该包含大小信息")
}
if !strings.Contains(notification, "1000") {
t.Errorf("通知中应该包含行数信息")
}
if !strings.Contains(notification, "query_execution_result") {
t.Errorf("通知中应该包含查询工具的使用说明")
}
}
func TestAgent_ExecuteToolViaMCP_LargeResult(t *testing.T) {
agent, _ := setupTestAgent(t)
// 创建模拟的MCP工具结果(大结果)
largeResult := &mcp.ToolResult{
Content: []mcp.Content{
{
Type: "text",
Text: strings.Repeat("This is a test line with some content.\n", 1000), // 约50KB
},
},
IsError: false,
}
// 模拟MCP服务器返回大结果
// 由于我们需要模拟CallTool的行为,这里需要创建一个mock或者使用实际的MCP服务器
// 为了简化测试,我们直接测试结果处理逻辑
// 设置阈值
agent.mu.Lock()
agent.largeResultThreshold = 1000 // 设置较小的阈值
agent.mu.Unlock()
// 创建执行ID
executionID := "test_exec_large_001"
toolName := "test_tool"
// 格式化结果
var resultText strings.Builder
for _, content := range largeResult.Content {
resultText.WriteString(content.Text)
resultText.WriteString("\n")
}
resultStr := resultText.String()
resultSize := len(resultStr)
// 检测大结果并保存
agent.mu.RLock()
threshold := agent.largeResultThreshold
storage := agent.resultStorage
agent.mu.RUnlock()
if resultSize > threshold && storage != nil {
// 保存大结果
err := storage.SaveResult(executionID, toolName, resultStr)
if err != nil {
t.Fatalf("保存大结果失败: %v", err)
}
// 生成通知
lines := strings.Split(resultStr, "\n")
filePath := storage.GetResultPath(executionID)
notification := agent.formatMinimalNotification(executionID, toolName, resultSize, len(lines), filePath)
// 验证通知格式
if !strings.Contains(notification, executionID) {
t.Errorf("通知中应该包含执行ID")
}
// 验证结果已保存
savedResult, err := storage.GetResult(executionID)
if err != nil {
t.Fatalf("获取保存的结果失败: %v", err)
}
if savedResult != resultStr {
t.Errorf("保存的结果与原始结果不匹配")
}
} else {
t.Fatal("大结果应该被检测到并保存")
}
}
func TestAgent_ExecuteToolViaMCP_SmallResult(t *testing.T) {
agent, _ := setupTestAgent(t)
// 创建小结果
smallResult := &mcp.ToolResult{
Content: []mcp.Content{
{
Type: "text",
Text: "Small result content",
},
},
IsError: false,
}
// 设置较大的阈值
agent.mu.Lock()
agent.largeResultThreshold = 100000 // 100KB
agent.mu.Unlock()
// 格式化结果
var resultText strings.Builder
for _, content := range smallResult.Content {
resultText.WriteString(content.Text)
resultText.WriteString("\n")
}
resultStr := resultText.String()
resultSize := len(resultStr)
// 检测大结果
agent.mu.RLock()
threshold := agent.largeResultThreshold
storage := agent.resultStorage
agent.mu.RUnlock()
if resultSize > threshold && storage != nil {
t.Fatal("小结果不应该被保存")
}
// 小结果应该直接返回
if resultSize <= threshold {
// 这是预期的行为
if resultStr == "" {
t.Fatal("小结果应该直接返回,不应该为空")
}
}
}
func TestAgent_SetResultStorage(t *testing.T) {
agent, _ := setupTestAgent(t)
// 创建新的存储
tmpDir := filepath.Join(os.TempDir(), "test_new_storage_"+time.Now().Format("20060102_150405"))
newStorage, err := storage.NewFileResultStorage(tmpDir, zap.NewNop())
if err != nil {
t.Fatalf("创建新存储失败: %v", err)
}
// 设置新存储
agent.SetResultStorage(newStorage)
// 验证存储已更新
agent.mu.RLock()
currentStorage := agent.resultStorage
agent.mu.RUnlock()
if currentStorage != newStorage {
t.Fatal("存储未正确更新")
}
// 清理
os.RemoveAll(tmpDir)
return NewAgent(openAICfg, agentCfg, mcpServer, nil, logger, 10)
}
func TestAgent_NewAgent_DefaultValues(t *testing.T) {
logger := zap.NewNop()
mcpServer := mcp.NewServer(logger)
openAICfg := &config.OpenAIConfig{
APIKey: "test-key",
BaseURL: "https://api.test.com/v1",
Model: "test-model",
}
// 测试默认配置
agent := NewAgent(openAICfg, nil, mcpServer, nil, logger, 0)
if agent.maxIterations != 30 {
t.Errorf("默认迭代次数不匹配。期望: 30, 实际: %d", agent.maxIterations)
}
agent.mu.RLock()
threshold := agent.largeResultThreshold
agent.mu.RUnlock()
if threshold != 50*1024 {
t.Errorf("默认阈值不匹配。期望: %d, 实际: %d", 50*1024, threshold)
}
}
func TestAgent_NewAgent_CustomConfig(t *testing.T) {
logger := zap.NewNop()
mcpServer := mcp.NewServer(logger)
openAICfg := &config.OpenAIConfig{
APIKey: "test-key",
BaseURL: "https://api.test.com/v1",
Model: "test-model",
}
agentCfg := &config.AgentConfig{
MaxIterations: 20,
LargeResultThreshold: 100 * 1024, // 100KB
ResultStorageDir: "custom_tmp",
MaxIterations: 20,
}
agent := NewAgent(openAICfg, agentCfg, mcpServer, nil, logger, 15)
if agent.maxIterations != 15 {
t.Errorf("迭代次数不匹配。期望: 15, 实际: %d", agent.maxIterations)
}
agent.mu.RLock()
threshold := agent.largeResultThreshold
agent.mu.RUnlock()
if threshold != 100*1024 {
t.Errorf("阈值不匹配。期望: %d, 实际: %d", 100*1024, threshold)
}
}
+167
View File
@@ -0,0 +1,167 @@
package agent
import (
"encoding/json"
"strings"
)
// ParseTraceMessages 解析落库的 last_react_inputOpenAI 风格 messages JSON 数组)。
func ParseTraceMessages(traceInputJSON string) ([]ChatMessage, error) {
traceInputJSON = strings.TrimSpace(traceInputJSON)
if traceInputJSON == "" {
return nil, nil
}
var raw []map[string]interface{}
if err := json.Unmarshal([]byte(traceInputJSON), &raw); err != nil {
return nil, err
}
out := make([]ChatMessage, 0, len(raw))
for _, msgMap := range raw {
msg := ChatMessage{}
role, _ := msgMap["role"].(string)
if role == "" {
continue
}
msg.Role = role
if content, ok := msgMap["content"].(string); ok {
msg.Content = content
}
if rc, ok := msgMap["reasoning_content"].(string); ok && strings.TrimSpace(rc) != "" {
msg.ReasoningContent = rc
}
if toolCallsRaw, ok := msgMap["tool_calls"]; ok && toolCallsRaw != nil {
if toolCallsArray, ok := toolCallsRaw.([]interface{}); ok {
for _, tcRaw := range toolCallsArray {
tcMap, ok := tcRaw.(map[string]interface{})
if !ok {
continue
}
toolCall := ToolCall{}
if id, ok := tcMap["id"].(string); ok {
toolCall.ID = id
}
if toolType, ok := tcMap["type"].(string); ok {
toolCall.Type = toolType
}
if funcMap, ok := tcMap["function"].(map[string]interface{}); ok {
toolCall.Function = FunctionCall{}
if name, ok := funcMap["name"].(string); ok {
toolCall.Function.Name = name
}
if argsRaw, ok := funcMap["arguments"]; ok {
if argsStr, ok := argsRaw.(string); ok {
var argsMap map[string]interface{}
if err := json.Unmarshal([]byte(argsStr), &argsMap); err == nil {
toolCall.Function.Arguments = argsMap
}
} else if argsMap, ok := argsRaw.(map[string]interface{}); ok {
toolCall.Function.Arguments = argsMap
}
}
}
if toolCall.ID != "" {
msg.ToolCalls = append(msg.ToolCalls, toolCall)
}
}
}
}
if toolCallID, ok := msgMap["tool_call_id"].(string); ok {
msg.ToolCallID = toolCallID
}
if tn, ok := msgMap["tool_name"].(string); ok && strings.TrimSpace(tn) != "" {
msg.ToolName = strings.TrimSpace(tn)
} else if tn, ok := msgMap["name"].(string); ok && strings.TrimSpace(tn) != "" && strings.EqualFold(msg.Role, "tool") {
msg.ToolName = strings.TrimSpace(tn)
}
out = append(out, msg)
}
return out, nil
}
// ExtractLastUserTurnMessages 仅保留最后一次 user 提问起的消息(不含更早的用户轮次;跳过 system)。
// 与「继续对话」续跑所用轨迹范围一致:当前任务轮次,而非整段多轮对话历史。
func ExtractLastUserTurnMessages(msgs []ChatMessage) []ChatMessage {
if len(msgs) == 0 {
return msgs
}
lastUser := -1
for i, m := range msgs {
if strings.EqualFold(m.Role, "user") {
lastUser = i
}
}
if lastUser < 0 {
return msgs
}
trimmed := msgs[lastUser:]
out := make([]ChatMessage, 0, len(trimmed))
for _, m := range trimmed {
if strings.EqualFold(m.Role, "system") {
continue
}
out = append(out, m)
}
return out
}
// ExtractLastUserTurnTraceJSON 在 JSON 轨迹上裁剪为最后一次 user 起的片段(供落库格式直接处理)。
func ExtractLastUserTurnTraceJSON(traceInputJSON string) string {
traceInputJSON = strings.TrimSpace(traceInputJSON)
if traceInputJSON == "" {
return traceInputJSON
}
var arr []map[string]interface{}
if err := json.Unmarshal([]byte(traceInputJSON), &arr); err != nil {
return traceInputJSON
}
lastUser := -1
for i, m := range arr {
if r, _ := m["role"].(string); strings.EqualFold(r, "user") {
lastUser = i
}
}
if lastUser <= 0 {
return traceInputJSON
}
trimmed := arr[lastUser:]
b, err := json.Marshal(trimmed)
if err != nil {
return traceInputJSON
}
return string(b)
}
// MergeAssistantTraceOutput 将 last_react_output 合并进轨迹最后一条 assistant(与 loadHistoryFromAgentTrace 一致)。
func MergeAssistantTraceOutput(msgs []ChatMessage, assistantOut string) []ChatMessage {
assistantOut = strings.TrimSpace(assistantOut)
if assistantOut == "" || len(msgs) == 0 {
return msgs
}
out := append([]ChatMessage(nil), msgs...)
last := &out[len(out)-1]
if strings.EqualFold(last.Role, "assistant") && len(last.ToolCalls) == 0 {
last.Content = assistantOut
return out
}
out = append(out, ChatMessage{
Role: "assistant",
Content: assistantOut,
})
return out
}
// MessagesToTraceJSON 将消息带序列化为 JSON(跳过 system)。
func MessagesToTraceJSON(msgs []ChatMessage) (string, error) {
filtered := make([]ChatMessage, 0, len(msgs))
for _, m := range msgs {
if strings.EqualFold(m.Role, "system") {
continue
}
filtered = append(filtered, m)
}
b, err := json.Marshal(filtered)
if err != nil {
return "", err
}
return string(b), nil
}
+57
View File
@@ -0,0 +1,57 @@
package agent
import (
"encoding/json"
"testing"
)
func TestExtractLastUserTurnTraceJSON(t *testing.T) {
raw := []map[string]interface{}{
{"role": "user", "content": "old question"},
{"role": "assistant", "content": "old answer"},
{"role": "user", "content": "new target 1.1.1.1"},
{"role": "assistant", "tool_calls": []interface{}{map[string]interface{}{
"id": "c1", "type": "function",
"function": map[string]interface{}{"name": "nmap", "arguments": "{}"},
}}},
{"role": "tool", "tool_call_id": "c1", "content": "open ports"},
}
b, _ := json.Marshal(raw)
out := ExtractLastUserTurnTraceJSON(string(b))
var trimmed []map[string]interface{}
if err := json.Unmarshal([]byte(out), &trimmed); err != nil {
t.Fatal(err)
}
if len(trimmed) != 3 {
t.Fatalf("expected 3 messages, got %d", len(trimmed))
}
if trimmed[0]["content"] != "new target 1.1.1.1" {
t.Fatalf("unexpected first message: %v", trimmed[0])
}
}
func TestExtractLastUserTurnMessagesSkipsSystem(t *testing.T) {
msgs := []ChatMessage{
{Role: "system", Content: "sys"},
{Role: "user", Content: "q"},
{Role: "assistant", Content: "a"},
}
out := ExtractLastUserTurnMessages(msgs)
if len(out) != 2 {
t.Fatalf("expected 2, got %d", len(out))
}
if out[0].Role != "user" {
t.Fatal("expected user first")
}
}
func TestMergeAssistantTraceOutput(t *testing.T) {
msgs := []ChatMessage{
{Role: "user", Content: "q"},
{Role: "assistant", Content: "draft"},
}
out := MergeAssistantTraceOutput(msgs, "final summary")
if out[len(out)-1].Content != "final summary" {
t.Fatalf("expected merged output, got %q", out[len(out)-1].Content)
}
}

Some files were not shown because too many files have changed in this diff Show More