geo-ai-search-optimization 1.2.17 → 1.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -0
- package/package.json +1 -1
- package/resources/geo-ai-search-optimization/references/skill-bundle-map.md +20 -0
- package/resources/geo-ai-search-optimization-agent-orchestrator/SKILL.md +23 -0
- package/resources/geo-ai-search-optimization-agent-orchestrator/agents/openai.yaml +4 -0
- package/resources/geo-ai-search-optimization-agent-resume/SKILL.md +24 -0
- package/resources/geo-ai-search-optimization-agent-resume/agents/openai.yaml +4 -0
- package/resources/geo-ai-search-optimization-usage/SKILL.md +36 -26
- package/src/agent-orchestrator.js +191 -0
- package/src/agent-resume.js +329 -0
- package/src/agent-session.js +10 -0
- package/src/auto-flow.js +47 -29
- package/src/cli.js +68 -0
- package/src/index.js +2 -0
- package/src/skills.js +6 -0
package/README.md
CHANGED
|
@@ -42,6 +42,48 @@ geo-ai-search-optimization skills --json
|
|
|
42
42
|
- agent 执行闭环相关 skills
|
|
43
43
|
- 分享 / 导出 / 最终交付相关 skills
|
|
44
44
|
|
|
45
|
+
## Agent Orchestrator 命令
|
|
46
|
+
|
|
47
|
+
如果你希望 agent 不要看长链路,而是直接拿到“现在唯一该跑哪条命令”,可以直接用 `agent-orchestrator`:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
geo-ai-search-optimization agent-orchestrator "继续这个 GEO 任务"
|
|
51
|
+
geo-ai-search-optimization agent-orchestrator https://example.com
|
|
52
|
+
geo-ai-search-optimization agent-orchestrator ./your-site
|
|
53
|
+
geo-ai-search-optimization agent-orchestrator ./reports/agent-playbook-pack.json --format json --out ./reports/agent-orchestrator.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
它会输出:
|
|
57
|
+
|
|
58
|
+
- 当前阶段
|
|
59
|
+
- 为什么现在该做这一步
|
|
60
|
+
- 现在只该跑哪条命令
|
|
61
|
+
- 预期产物
|
|
62
|
+
- 什么时候先停下
|
|
63
|
+
- 做完之后下一条是什么
|
|
64
|
+
- 可直接复制给 agent 的 orchestrator prompt
|
|
65
|
+
|
|
66
|
+
## Agent Resume 命令
|
|
67
|
+
|
|
68
|
+
如果 GEO 工作已经做过一轮或多轮,你不想让下一个 agent 从头重新判断,而是想让它从最近一个可靠恢复点继续,可以直接用 `agent-resume`:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
geo-ai-search-optimization agent-resume "继续这个 GEO 任务"
|
|
72
|
+
geo-ai-search-optimization agent-resume https://example.com
|
|
73
|
+
geo-ai-search-optimization agent-resume ./your-site
|
|
74
|
+
geo-ai-search-optimization agent-resume ./reports/agent-playbook-pack.json --format json --out ./reports/agent-resume.json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
它会输出:
|
|
78
|
+
|
|
79
|
+
- 恢复模式
|
|
80
|
+
- 从哪里恢复
|
|
81
|
+
- 现在只恢复哪一条命令
|
|
82
|
+
- 恢复前要先确认什么
|
|
83
|
+
- 恢复时不要重置什么
|
|
84
|
+
- 恢复后下一条是什么
|
|
85
|
+
- 可直接复制给 agent 的 resume prompt
|
|
86
|
+
|
|
45
87
|
## Auto Flow 命令
|
|
46
88
|
|
|
47
89
|
如果你希望 agent 不用自己判断现在该用哪个 skill、该跑哪个命令,可以直接用 `auto-flow`:
|
|
@@ -660,6 +702,8 @@ geo-ai-search-optimization onboard --url https://example.com --json --out ./repo
|
|
|
660
702
|
geo-ai-search-optimization
|
|
661
703
|
geo-ai-search-optimization install
|
|
662
704
|
geo-ai-search-optimization install --target ./tmp/custom-skills --json
|
|
705
|
+
geo-ai-search-optimization agent-orchestrator ./your-site
|
|
706
|
+
geo-ai-search-optimization agent-resume ./your-site
|
|
663
707
|
geo-ai-search-optimization auto-flow "audit this site and tell me the next skill"
|
|
664
708
|
geo-ai-search-optimization agent-session ./your-site
|
|
665
709
|
geo-ai-search-optimization agent-runbook ./your-site
|
|
@@ -741,6 +785,22 @@ geo-ai-search-optimization help
|
|
|
741
785
|
- 输出 do-now checklist、stop checklist、success checklist、验证命令和回报模板
|
|
742
786
|
- 新增 `geo-ai-search-optimization-agent-executor` skill
|
|
743
787
|
|
|
788
|
+
## New in 1.2.19
|
|
789
|
+
|
|
790
|
+
- 新增 `agent-resume`
|
|
791
|
+
- 把 `agent-orchestrator + agent-playbook-pack` 收敛成“从最近一个可靠恢复点继续”的恢复入口
|
|
792
|
+
- 输出 `resume_mode`、`resume_from`、`resume_command`、`verify_before_resume`、`do_not_reset`、`after_resume`
|
|
793
|
+
- `auto-flow`、`agent-session`、`skills` 已经把 `agent-resume` 视为正式恢复链路
|
|
794
|
+
- 新增 `geo-ai-search-optimization-agent-resume` skill
|
|
795
|
+
|
|
796
|
+
## New in 1.2.18
|
|
797
|
+
|
|
798
|
+
- 新增 `agent-orchestrator`
|
|
799
|
+
- 把 `auto-flow + agent-session` 收敛成一个“现在只该做哪条命令”的总入口
|
|
800
|
+
- 输出固定 contract:`current_stage`、`why_now`、`next_command`、`expected_artifact`、`stop_if`、`after_that`
|
|
801
|
+
- 更适合 PM 把任务直接交给 agent,或 agent 接着前一个工件继续做
|
|
802
|
+
- 新增 `geo-ai-search-optimization-agent-orchestrator` skill
|
|
803
|
+
|
|
744
804
|
## New in 1.2.17
|
|
745
805
|
|
|
746
806
|
- 新增 `agent-playbook-pack`
|
|
@@ -978,6 +1038,8 @@ The installed package now includes a bundled GEO skill pack, including:
|
|
|
978
1038
|
|
|
979
1039
|
- `geo-ai-search-optimization`
|
|
980
1040
|
- `geo-ai-search-optimization-auto-flow`
|
|
1041
|
+
- `geo-ai-search-optimization-agent-orchestrator`
|
|
1042
|
+
- `geo-ai-search-optimization-agent-resume`
|
|
981
1043
|
- `geo-ai-search-optimization-agent-session`
|
|
982
1044
|
- `geo-ai-search-optimization-agent-runbook`
|
|
983
1045
|
- `geo-ai-search-optimization-agent-executor`
|
package/package.json
CHANGED
|
@@ -32,6 +32,26 @@ Best for:
|
|
|
32
32
|
- turning one-line task briefs into a concrete command sequence
|
|
33
33
|
- deciding whether the work should move into diagnosis, execution, closeout, or delivery
|
|
34
34
|
|
|
35
|
+
### `geo-ai-search-optimization-agent-orchestrator`
|
|
36
|
+
|
|
37
|
+
Use this when the next agent should get one immediate next command instead of reading a full command chain.
|
|
38
|
+
|
|
39
|
+
Best for:
|
|
40
|
+
|
|
41
|
+
- deciding the one command to run now
|
|
42
|
+
- returning a short contract with expected artifact, stop conditions, and follow-up command
|
|
43
|
+
- reducing ambiguity for PM-to-agent or agent-to-agent handoffs
|
|
44
|
+
|
|
45
|
+
### `geo-ai-search-optimization-agent-resume`
|
|
46
|
+
|
|
47
|
+
Use this when the next agent should continue from the latest reliable GEO checkpoint instead of restarting the whole chain.
|
|
48
|
+
|
|
49
|
+
Best for:
|
|
50
|
+
|
|
51
|
+
- resuming from a playbook pack, decision log, status board, checkpoint, or similar GEO artifact
|
|
52
|
+
- telling the next agent exactly where to continue and what not to reset
|
|
53
|
+
- turning a previously interrupted GEO chain into one resume command plus one follow-up command
|
|
54
|
+
|
|
35
55
|
### `geo-ai-search-optimization-agent-session`
|
|
36
56
|
|
|
37
57
|
Use this when the next agent needs a runnable session plan, not just a routing answer.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: geo-ai-search-optimization-agent-orchestrator
|
|
3
|
+
description: Choose the one next GEO command an agent should run right now. Use when an agent, PM, or another workflow has a GEO URL, codebase, task brief, or artifact and wants a single next command, expected artifact, stop conditions, and follow-up command instead of a full chain.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GEO Agent Orchestrator
|
|
7
|
+
|
|
8
|
+
Use this skill when the next agent should not browse a long command chain.
|
|
9
|
+
|
|
10
|
+
`GEO = Generative Engine Optimization`
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
- turns a GEO input into one immediate next command
|
|
15
|
+
- explains why this command should run now
|
|
16
|
+
- shows what artifact should come out of that command
|
|
17
|
+
- tells the next agent when to stop and what to run after that
|
|
18
|
+
|
|
19
|
+
## Best use
|
|
20
|
+
|
|
21
|
+
- when PM wants the next agent to start without reading the whole GEO stack
|
|
22
|
+
- when another agent says "just tell me the next command"
|
|
23
|
+
- when GEO work should continue from a URL, codebase, playbook pack, decision log, or other GEO artifact with minimal ambiguity
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "GEO Agent Orchestrator"
|
|
3
|
+
short_description: "Choose the one next GEO command to run now"
|
|
4
|
+
default_prompt: "Use $geo-ai-search-optimization-agent-orchestrator to pick the one next GEO command to run now, explain why, define the expected artifact, and list stop conditions plus the follow-up command."
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: geo-ai-search-optimization-agent-resume
|
|
3
|
+
description: Resume a GEO workflow from the latest reliable point instead of restarting the whole chain. Use when an agent, PM, or another workflow has a GEO URL, codebase, playbook pack, decision log, status board, checkpoint, or related artifact and needs the exact resume command, pre-resume checks, and a clear list of what should not be reset.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GEO Agent Resume
|
|
7
|
+
|
|
8
|
+
Use this skill when the next agent should continue, not restart.
|
|
9
|
+
|
|
10
|
+
`GEO = Generative Engine Optimization`
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
- finds the latest reliable GEO recovery point
|
|
15
|
+
- tells the next agent which one command to resume now
|
|
16
|
+
- explains what to verify before resuming
|
|
17
|
+
- lists what should not be reset while continuing the chain
|
|
18
|
+
- keeps the agent aligned with the current packet, next packet, and follow-up command
|
|
19
|
+
|
|
20
|
+
## Best use
|
|
21
|
+
|
|
22
|
+
- when GEO work was interrupted and another agent needs to continue safely
|
|
23
|
+
- when PM wants to say "pick up from where the last agent left off"
|
|
24
|
+
- when there are already GEO artifacts and the risk is restarting the chain from the wrong place
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "GEO Agent Resume"
|
|
3
|
+
short_description: "Resume GEO work from the latest reliable point"
|
|
4
|
+
default_prompt: "Use $geo-ai-search-optimization-agent-resume to continue this GEO workflow from the latest reliable checkpoint, identify the one resume command to run now, list what to verify first, and explain what must not be reset."
|
|
@@ -13,38 +13,42 @@ Treat this tool as a PM-friendly GEO workflow for websites.
|
|
|
13
13
|
|
|
14
14
|
`GEO = Generative Engine Optimization`
|
|
15
15
|
|
|
16
|
-
The package is best explained as twenty-
|
|
17
|
-
|
|
18
|
-
1. `
|
|
19
|
-
2. `agent-
|
|
20
|
-
3. `
|
|
21
|
-
4. `agent-
|
|
22
|
-
5. `agent-
|
|
23
|
-
6. `agent-
|
|
24
|
-
7. `agent-
|
|
25
|
-
8. `agent-
|
|
26
|
-
9. `agent-
|
|
27
|
-
10. `agent-
|
|
28
|
-
11. `agent-
|
|
29
|
-
12. `
|
|
30
|
-
13. `
|
|
31
|
-
14. `
|
|
32
|
-
15. `
|
|
33
|
-
16. `
|
|
34
|
-
17. `
|
|
35
|
-
18. `
|
|
36
|
-
19. `
|
|
37
|
-
20. `
|
|
38
|
-
21. `
|
|
39
|
-
22. `
|
|
40
|
-
23. `
|
|
41
|
-
24. `
|
|
16
|
+
The package is best explained as twenty-six layers:
|
|
17
|
+
|
|
18
|
+
1. `agent-orchestrator`: choose the one next GEO command to run right now
|
|
19
|
+
2. `agent-resume`: resume from the latest reliable GEO checkpoint instead of restarting the whole chain
|
|
20
|
+
3. `auto-flow`: auto-select the next skill and command chain
|
|
21
|
+
4. `agent-session`: build a runnable session for the next agent
|
|
22
|
+
5. `agent-runbook`: execution manual and checklist for the next agent
|
|
23
|
+
6. `agent-executor`: choose one packet to execute right now
|
|
24
|
+
7. `agent-batch-executor`: queue the first few packets, but still advance one packet at a time
|
|
25
|
+
8. `agent-progress-tracker`: track which packet is done, which one is active, and what comes next
|
|
26
|
+
9. `agent-status-board`: turn the execution state into a board view for PM and agents
|
|
27
|
+
10. `agent-checkpoint`: freeze the current round into a continue / unblock / closeout decision
|
|
28
|
+
11. `agent-decision-log`: preserve why each round continued, paused, or closed out
|
|
29
|
+
12. `agent-retrospective`: explain multi-round patterns, lessons, and next-round advice
|
|
30
|
+
13. `agent-playbook-pack`: compress retrospective, decision history, and handoff into one resume entrypoint
|
|
31
|
+
14. `skills`: inspect the bundled skill package
|
|
32
|
+
15. `onboard-url` / `onboard`: first look
|
|
33
|
+
16. `scan`: raw signal check
|
|
34
|
+
17. `audit` / `report`: diagnosis
|
|
35
|
+
18. `fix-plan` / `owner-board`: execution planning
|
|
36
|
+
19. `agent-handoff`: agent takeover package
|
|
37
|
+
20. `apply-plan`: execution loop
|
|
38
|
+
21. `completion-report`: closeout
|
|
39
|
+
22. `handoff-bundle`: all-in-one package
|
|
40
|
+
23. `share-pack`: audience-ready delivery
|
|
41
|
+
24. `export-pack`: folder export
|
|
42
|
+
25. `html-pack` / `publish-pack`: browsable and final delivery output
|
|
43
|
+
26. `pm-brief` / `roadmap`: stakeholder alignment
|
|
42
44
|
|
|
43
45
|
## Recommended command order
|
|
44
46
|
|
|
45
47
|
If the user only has a website URL:
|
|
46
48
|
|
|
47
49
|
```bash
|
|
50
|
+
npx geo-ai-search-optimization agent-orchestrator https://example.com
|
|
51
|
+
npx geo-ai-search-optimization agent-resume https://example.com
|
|
48
52
|
npx geo-ai-search-optimization auto-flow https://example.com
|
|
49
53
|
npx geo-ai-search-optimization agent-session https://example.com
|
|
50
54
|
npx geo-ai-search-optimization agent-runbook https://example.com
|
|
@@ -64,6 +68,8 @@ npx geo-ai-search-optimization roadmap https://example.com
|
|
|
64
68
|
If the user has the website codebase:
|
|
65
69
|
|
|
66
70
|
```bash
|
|
71
|
+
npx geo-ai-search-optimization agent-orchestrator ./your-site
|
|
72
|
+
npx geo-ai-search-optimization agent-resume ./your-site
|
|
67
73
|
npx geo-ai-search-optimization auto-flow ./your-site
|
|
68
74
|
npx geo-ai-search-optimization agent-session ./your-site
|
|
69
75
|
npx geo-ai-search-optimization agent-runbook ./your-site
|
|
@@ -92,6 +98,8 @@ npx geo-ai-search-optimization roadmap ./your-site
|
|
|
92
98
|
|
|
93
99
|
## When to recommend each command
|
|
94
100
|
|
|
101
|
+
- `agent-orchestrator`: choose the one next GEO command to run now, plus expected artifact, stop conditions, and follow-up command
|
|
102
|
+
- `agent-resume`: resume from the latest reliable checkpoint, confirm what not to reset, and tell the next agent the one resume command to run
|
|
95
103
|
- `auto-flow`: auto-select the next skill and command order from a task brief, URL, project path, or GEO artifact
|
|
96
104
|
- `agent-session`: build a step-by-step session packet for the next agent from the same kinds of inputs
|
|
97
105
|
- `agent-runbook`: build a checklist-driven runbook with preflight, validation, and reporting rules
|
|
@@ -127,6 +135,8 @@ npx geo-ai-search-optimization roadmap ./your-site
|
|
|
127
135
|
When explaining the tool to a user:
|
|
128
136
|
|
|
129
137
|
- prefer telling them which command to run next, not listing every command
|
|
138
|
+
- if the user or next agent wants just one next command, move them to `agent-orchestrator`
|
|
139
|
+
- if the user or next agent needs to continue from the latest reliable checkpoint without restarting, move them to `agent-resume`
|
|
130
140
|
- if the user or the next agent is unsure where to start, move them to `auto-flow` first
|
|
131
141
|
- if the user wants something the next agent can follow step by step, move them to `agent-session`
|
|
132
142
|
- if the user wants the next agent to follow a checklist and execution manual, move them to `agent-runbook`
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { createAgentSession } from "./agent-session.js";
|
|
2
|
+
import { writeScanOutput } from "./scan.js";
|
|
3
|
+
|
|
4
|
+
const VALID_FORMATS = new Set(["markdown", "json"]);
|
|
5
|
+
|
|
6
|
+
function normalizeFormat(format) {
|
|
7
|
+
const resolved = (format || "markdown").toLowerCase();
|
|
8
|
+
if (!VALID_FORMATS.has(resolved)) {
|
|
9
|
+
throw new Error(`不支持的 agent-orchestrator 格式:${format}。可选值:${Array.from(VALID_FORMATS).join(", ")}`);
|
|
10
|
+
}
|
|
11
|
+
return resolved;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function inferOrchestrationMode(session) {
|
|
15
|
+
if (session.status === "needs-context") {
|
|
16
|
+
return "needs-context";
|
|
17
|
+
}
|
|
18
|
+
if (session.intent === "share") {
|
|
19
|
+
return "delivery";
|
|
20
|
+
}
|
|
21
|
+
if (session.intent === "closeout") {
|
|
22
|
+
return "closeout";
|
|
23
|
+
}
|
|
24
|
+
if (session.intent === "execute") {
|
|
25
|
+
return "execution";
|
|
26
|
+
}
|
|
27
|
+
if (session.intent === "guide") {
|
|
28
|
+
return "guidance";
|
|
29
|
+
}
|
|
30
|
+
return "diagnosis";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function buildWhyNow(session, nextStep) {
|
|
34
|
+
if (!nextStep) {
|
|
35
|
+
return "当前还没有足够上下文来确定下一步命令,先补输入。";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (session.artifactKind === "geo-agent-playbook-pack") {
|
|
39
|
+
return "当前已经有单入口 playbook,不应该重新规划整条链,直接沿着既有恢复点继续最稳。";
|
|
40
|
+
}
|
|
41
|
+
if (session.artifactKind === "geo-agent-decision-log") {
|
|
42
|
+
return "当前已经有跨轮决策历史,下一步应沿着最近一次决策继续,而不是重新做全量判断。";
|
|
43
|
+
}
|
|
44
|
+
if (session.artifactKind === "geo-agent-retrospective") {
|
|
45
|
+
return "当前已经有多轮复盘,下一步应该把复盘结论转成正式动作,而不是回到最前面的扫描阶段。";
|
|
46
|
+
}
|
|
47
|
+
if (session.sourceType === "url" && session.intent === "execute") {
|
|
48
|
+
return "当前只有公开网址,最重要的是先把建议型执行入口建立好,再决定是否需要仓库上下文。";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return `${session.whyThisSkill} 当前最该先跑的是 ${nextStep.commandName},因为它会直接产出下一阶段需要的关键工件。`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function buildStopIf(session, nextStep) {
|
|
55
|
+
const items = [...session.contextNeeded];
|
|
56
|
+
|
|
57
|
+
if (session.sourceType === "url" && session.intent === "execute") {
|
|
58
|
+
items.push("只有网址时,不要宣称已经完成代码级修复。");
|
|
59
|
+
}
|
|
60
|
+
if (session.artifactKind === "geo-agent-playbook-pack") {
|
|
61
|
+
items.push("不要绕开 playbook 重新拆一条新链,除非当前 playbook 已明显过时。");
|
|
62
|
+
}
|
|
63
|
+
if (nextStep?.commandName === "agent-executor") {
|
|
64
|
+
items.push("不要同时展开多个任务包;这一轮先推进当前单包。");
|
|
65
|
+
}
|
|
66
|
+
if (nextStep?.commandName === "completion-report") {
|
|
67
|
+
items.push("如果这一轮还没有完成或没有明确验证结果,不要过早进入 closeout。");
|
|
68
|
+
}
|
|
69
|
+
if (nextStep?.commandName === "publish-pack") {
|
|
70
|
+
items.push("如果前面的 completion-report 或 share 结果还不完整,不要直接产出最终交付包。");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return Array.from(new Set(items));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function buildAfterThat(session) {
|
|
77
|
+
return session.steps[1]?.command || null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function buildOrchestratorPrompt(orchestrator) {
|
|
81
|
+
const lines = [
|
|
82
|
+
`Use $${orchestrator.selectedSkill.name} to continue this GEO task.`,
|
|
83
|
+
`当前输入:${orchestrator.source}`,
|
|
84
|
+
`当前阶段:${orchestrator.current_stage}`,
|
|
85
|
+
`当前模式:${orchestrator.orchestration_mode}`,
|
|
86
|
+
`为什么现在做这一步:${orchestrator.why_now}`
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
if (orchestrator.next_command) {
|
|
90
|
+
lines.push(`现在只运行这一条命令:${orchestrator.next_command}`);
|
|
91
|
+
}
|
|
92
|
+
if (orchestrator.expected_artifact) {
|
|
93
|
+
lines.push(`预期产物:${orchestrator.expected_artifact}`);
|
|
94
|
+
}
|
|
95
|
+
if (orchestrator.after_that) {
|
|
96
|
+
lines.push(`完成后下一条:${orchestrator.after_that}`);
|
|
97
|
+
}
|
|
98
|
+
if (orchestrator.stop_if.length > 0) {
|
|
99
|
+
lines.push("出现以下情况就先停下:");
|
|
100
|
+
for (const item of orchestrator.stop_if) {
|
|
101
|
+
lines.push(`- ${item}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
lines.push("输出时先说明为什么执行这一步,再说明得到什么,以及之后怎么继续。");
|
|
106
|
+
return lines.join("\n");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export async function createAgentOrchestrator(input, options = {}) {
|
|
110
|
+
const format = normalizeFormat(options.format);
|
|
111
|
+
const session = await createAgentSession(input, {
|
|
112
|
+
intent: options.intent
|
|
113
|
+
});
|
|
114
|
+
const nextStep = session.steps[0] || null;
|
|
115
|
+
|
|
116
|
+
const orchestrator = {
|
|
117
|
+
kind: "geo-agent-orchestrator",
|
|
118
|
+
input,
|
|
119
|
+
source: session.source,
|
|
120
|
+
sourceType: session.sourceType,
|
|
121
|
+
artifactKind: session.artifactKind,
|
|
122
|
+
format,
|
|
123
|
+
orchestration_mode: inferOrchestrationMode(session),
|
|
124
|
+
current_stage: session.stage,
|
|
125
|
+
why_now: buildWhyNow(session, nextStep),
|
|
126
|
+
next_command: nextStep?.command || null,
|
|
127
|
+
expected_artifact: nextStep?.expectedArtifact || null,
|
|
128
|
+
stop_if: buildStopIf(session, nextStep),
|
|
129
|
+
after_that: buildAfterThat(session),
|
|
130
|
+
selectedSkill: session.selectedSkill,
|
|
131
|
+
next_skill: nextStep?.suggestedSkill || session.selectedSkill.name,
|
|
132
|
+
session_status: session.status,
|
|
133
|
+
next_action: session.nextAction,
|
|
134
|
+
session,
|
|
135
|
+
orchestrator_prompt: ""
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
orchestrator.orchestrator_prompt = buildOrchestratorPrompt(orchestrator);
|
|
139
|
+
return orchestrator;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function renderAgentOrchestratorMarkdown(orchestrator) {
|
|
143
|
+
const lines = [
|
|
144
|
+
"# GEO Agent Orchestrator",
|
|
145
|
+
"",
|
|
146
|
+
`- 输入:\`${orchestrator.source}\``,
|
|
147
|
+
`- 输入类型:\`${orchestrator.sourceType}\``,
|
|
148
|
+
`- 工件类型:\`${orchestrator.artifactKind}\``,
|
|
149
|
+
`- 当前阶段:${orchestrator.current_stage}`,
|
|
150
|
+
`- orchestration mode:\`${orchestrator.orchestration_mode}\``,
|
|
151
|
+
`- 当前建议 skill:\`${orchestrator.next_skill}\``,
|
|
152
|
+
"",
|
|
153
|
+
"## 为什么现在做这一步",
|
|
154
|
+
"",
|
|
155
|
+
`- ${orchestrator.why_now}`,
|
|
156
|
+
"",
|
|
157
|
+
"## 现在只做这一条",
|
|
158
|
+
"",
|
|
159
|
+
`- 命令:\`${orchestrator.next_command || "先补输入"}\``,
|
|
160
|
+
`- 预期产物:${orchestrator.expected_artifact || "先明确需要什么上下文"}`,
|
|
161
|
+
""
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
if (orchestrator.after_that) {
|
|
165
|
+
lines.push("## 做完之后", "", `- 下一条:\`${orchestrator.after_that}\``, "");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
lines.push("## 什么时候先停下", "");
|
|
169
|
+
if (orchestrator.stop_if.length === 0) {
|
|
170
|
+
lines.push("- 当前没有额外 stop 条件。");
|
|
171
|
+
} else {
|
|
172
|
+
for (const item of orchestrator.stop_if) {
|
|
173
|
+
lines.push(`- ${item}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
lines.push(
|
|
178
|
+
"",
|
|
179
|
+
"## 可直接复制给 Agent 的 Orchestrator Prompt",
|
|
180
|
+
"",
|
|
181
|
+
"```text",
|
|
182
|
+
orchestrator.orchestrator_prompt,
|
|
183
|
+
"```"
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
return `${lines.join("\n")}\n`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export async function writeAgentOrchestratorOutput(outputPath, content) {
|
|
190
|
+
return writeScanOutput(outputPath, content);
|
|
191
|
+
}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createAgentOrchestrator } from "./agent-orchestrator.js";
|
|
4
|
+
import { createAgentPlaybookPack } from "./agent-playbook-pack.js";
|
|
5
|
+
import { writeScanOutput } from "./scan.js";
|
|
6
|
+
|
|
7
|
+
const VALID_FORMATS = new Set(["markdown", "json"]);
|
|
8
|
+
|
|
9
|
+
function normalizeFormat(format) {
|
|
10
|
+
const resolved = (format || "markdown").toLowerCase();
|
|
11
|
+
if (!VALID_FORMATS.has(resolved)) {
|
|
12
|
+
throw new Error(`不支持的 agent-resume 格式:${format}。可选值:${Array.from(VALID_FORMATS).join(", ")}`);
|
|
13
|
+
}
|
|
14
|
+
return resolved;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function pathExists(targetPath) {
|
|
18
|
+
try {
|
|
19
|
+
await fs.access(targetPath);
|
|
20
|
+
return true;
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function tryReadExistingPlaybookPack(input) {
|
|
27
|
+
const resolvedPath = path.resolve(String(input));
|
|
28
|
+
if (!(await pathExists(resolvedPath)) || path.extname(resolvedPath).toLowerCase() !== ".json") {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const parsed = JSON.parse(await fs.readFile(resolvedPath, "utf8"));
|
|
34
|
+
if (parsed.kind === "geo-agent-playbook-pack") {
|
|
35
|
+
return parsed;
|
|
36
|
+
}
|
|
37
|
+
if (parsed.kind === "geo-agent-resume" && parsed.playbookPack) {
|
|
38
|
+
return parsed.playbookPack;
|
|
39
|
+
}
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function tryCreatePlaybookPack(input) {
|
|
48
|
+
const existing = await tryReadExistingPlaybookPack(input);
|
|
49
|
+
if (existing) {
|
|
50
|
+
return existing;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
return await createAgentPlaybookPack(input, { format: "json" });
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function inferResumeMode(orchestrator, playbookPack) {
|
|
60
|
+
if (orchestrator.orchestration_mode === "needs-context") {
|
|
61
|
+
return "needs-context";
|
|
62
|
+
}
|
|
63
|
+
if (playbookPack?.playbookStatus === "closeout-ready") {
|
|
64
|
+
return "resume-closeout";
|
|
65
|
+
}
|
|
66
|
+
if (playbookPack?.playbookStatus === "unblock-first") {
|
|
67
|
+
return "resume-after-unblock";
|
|
68
|
+
}
|
|
69
|
+
if (playbookPack?.playbookStatus === "advice-ready") {
|
|
70
|
+
return "resume-advice";
|
|
71
|
+
}
|
|
72
|
+
if (playbookPack?.currentPacket) {
|
|
73
|
+
return "resume-current-packet";
|
|
74
|
+
}
|
|
75
|
+
return "resume-workflow";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function buildResumeFrom(orchestrator, playbookPack) {
|
|
79
|
+
if (playbookPack?.playbookStatus === "closeout-ready") {
|
|
80
|
+
return "从 closeout 阶段继续";
|
|
81
|
+
}
|
|
82
|
+
if (playbookPack?.playbookStatus === "unblock-first") {
|
|
83
|
+
return `先从解除阻塞继续,再回到 ${playbookPack.currentPacket?.id || "当前包"}`;
|
|
84
|
+
}
|
|
85
|
+
if (playbookPack?.currentPacket) {
|
|
86
|
+
return `从 ${playbookPack.currentPacket.id}|${playbookPack.currentPacket.title} 继续`;
|
|
87
|
+
}
|
|
88
|
+
if (orchestrator.next_command) {
|
|
89
|
+
return `从下一条命令继续:${orchestrator.next_command}`;
|
|
90
|
+
}
|
|
91
|
+
return "先补输入后再恢复";
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function buildResumeSummary(orchestrator, playbookPack) {
|
|
95
|
+
if (orchestrator.orchestration_mode === "needs-context") {
|
|
96
|
+
return "当前还没有足够上下文恢复上一轮工作,先补网址、目录或 GEO 工件。";
|
|
97
|
+
}
|
|
98
|
+
if (playbookPack?.playbookStatus === "closeout-ready") {
|
|
99
|
+
return "当前已经进入或接近收尾,恢复时不要重新回到执行第一包。";
|
|
100
|
+
}
|
|
101
|
+
if (playbookPack?.playbookStatus === "unblock-first") {
|
|
102
|
+
return "当前恢复重点不是继续改动,而是先清掉重复阻塞项,再回到当前包。";
|
|
103
|
+
}
|
|
104
|
+
if (playbookPack?.currentPacket) {
|
|
105
|
+
return `当前最稳的恢复点是 ${playbookPack.currentPacket.id},不要把前面已经排好的链重新拆掉。`;
|
|
106
|
+
}
|
|
107
|
+
return orchestrator.why_now;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function shouldUnwrapResumeCommand(orchestrator) {
|
|
111
|
+
return /\bagent-resume\b/.test(orchestrator.next_command || "");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function buildResumeCommand(orchestrator, playbookPack) {
|
|
115
|
+
if (shouldUnwrapResumeCommand(orchestrator) && playbookPack?.startCommand) {
|
|
116
|
+
return playbookPack.startCommand;
|
|
117
|
+
}
|
|
118
|
+
return orchestrator.next_command;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function buildAfterResume(orchestrator, playbookPack, resumeCommand) {
|
|
122
|
+
if (shouldUnwrapResumeCommand(orchestrator) && Array.isArray(playbookPack?.followupCommands)) {
|
|
123
|
+
return playbookPack.followupCommands.find((command) => command && command !== resumeCommand) || orchestrator.after_that;
|
|
124
|
+
}
|
|
125
|
+
return orchestrator.after_that;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function inferExpectedArtifactFromCommand(command) {
|
|
129
|
+
const normalized = String(command || "").toLowerCase();
|
|
130
|
+
|
|
131
|
+
if (normalized.includes("completion-report")) {
|
|
132
|
+
return "复盘工件";
|
|
133
|
+
}
|
|
134
|
+
if (normalized.includes("agent-executor")) {
|
|
135
|
+
return "agent 单任务执行包";
|
|
136
|
+
}
|
|
137
|
+
if (normalized.includes("agent-batch-executor")) {
|
|
138
|
+
return "agent 多任务批次执行包";
|
|
139
|
+
}
|
|
140
|
+
if (normalized.includes("agent-runbook")) {
|
|
141
|
+
return "agent 执行手册";
|
|
142
|
+
}
|
|
143
|
+
if (normalized.includes("agent-status-board")) {
|
|
144
|
+
return "agent 执行状态看板";
|
|
145
|
+
}
|
|
146
|
+
if (normalized.includes("agent-progress-tracker")) {
|
|
147
|
+
return "agent 执行进度追踪工件";
|
|
148
|
+
}
|
|
149
|
+
if (normalized.includes("agent-decision-log")) {
|
|
150
|
+
return "agent 决策历史工件";
|
|
151
|
+
}
|
|
152
|
+
if (normalized.includes("fix-plan")) {
|
|
153
|
+
return "待办清单与优先级";
|
|
154
|
+
}
|
|
155
|
+
if (normalized.includes("audit")) {
|
|
156
|
+
return "GEO 审计结果";
|
|
157
|
+
}
|
|
158
|
+
if (normalized.includes("scan")) {
|
|
159
|
+
return "基础信号扫描结果";
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function buildExpectedArtifact(orchestrator, playbookPack, resumeCommand) {
|
|
165
|
+
if (shouldUnwrapResumeCommand(orchestrator)) {
|
|
166
|
+
return inferExpectedArtifactFromCommand(resumeCommand) || playbookPack?.resumeSummary || "阶段性 GEO 输出";
|
|
167
|
+
}
|
|
168
|
+
return orchestrator.expected_artifact;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function buildVerifyBeforeResume(orchestrator, playbookPack) {
|
|
172
|
+
const items = [];
|
|
173
|
+
|
|
174
|
+
if (playbookPack) {
|
|
175
|
+
items.push(...playbookPack.readOrder.slice(0, 2));
|
|
176
|
+
if (playbookPack.currentPacket) {
|
|
177
|
+
items.push(`确认当前包仍然是 ${playbookPack.currentPacket.id},不要在恢复时改成别的包。`);
|
|
178
|
+
}
|
|
179
|
+
} else if (orchestrator.sourceType === "task-text") {
|
|
180
|
+
items.push("先确认是否已经有网址、目录或 JSON 工件,否则无法恢复上一轮。");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
items.push(...orchestrator.stop_if);
|
|
184
|
+
return Array.from(new Set(items));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function buildDoNotReset(playbookPack) {
|
|
188
|
+
if (!playbookPack) {
|
|
189
|
+
return ["没有恢复工件时,不要假装已经知道上一轮做到哪里。"];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const items = ["不要从第一步重新跑整条链,除非当前工件已经明显过时。", ...playbookPack.avoidNowChecklist];
|
|
193
|
+
return Array.from(new Set(items));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function buildResumePrompt(resume) {
|
|
197
|
+
const lines = [
|
|
198
|
+
`Use $${resume.selectedSkill.name} to resume this GEO task without restarting the chain.`,
|
|
199
|
+
`当前输入:${resume.source}`,
|
|
200
|
+
`恢复模式:${resume.resume_mode}`,
|
|
201
|
+
`恢复点:${resume.resume_from}`,
|
|
202
|
+
`恢复摘要:${resume.resume_summary}`
|
|
203
|
+
];
|
|
204
|
+
|
|
205
|
+
if (resume.resume_command) {
|
|
206
|
+
lines.push(`现在只恢复这一条命令:${resume.resume_command}`);
|
|
207
|
+
}
|
|
208
|
+
if (resume.expected_artifact) {
|
|
209
|
+
lines.push(`预期恢复产物:${resume.expected_artifact}`);
|
|
210
|
+
}
|
|
211
|
+
if (resume.after_resume) {
|
|
212
|
+
lines.push(`恢复后下一条:${resume.after_resume}`);
|
|
213
|
+
}
|
|
214
|
+
if (resume.verify_before_resume.length > 0) {
|
|
215
|
+
lines.push("恢复前先确认:");
|
|
216
|
+
for (const item of resume.verify_before_resume) {
|
|
217
|
+
lines.push(`- ${item}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (resume.do_not_reset.length > 0) {
|
|
221
|
+
lines.push("恢复时不要做这些事:");
|
|
222
|
+
for (const item of resume.do_not_reset) {
|
|
223
|
+
lines.push(`- ${item}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
lines.push("输出时先说明你是从哪里恢复的,再说明为什么不需要重新规划整条链。");
|
|
228
|
+
return lines.join("\n");
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export async function createAgentResume(input, options = {}) {
|
|
232
|
+
const format = normalizeFormat(options.format);
|
|
233
|
+
const [orchestrator, playbookPack] = await Promise.all([
|
|
234
|
+
createAgentOrchestrator(input, { format: "json", intent: options.intent }),
|
|
235
|
+
tryCreatePlaybookPack(input)
|
|
236
|
+
]);
|
|
237
|
+
const resumeCommand = buildResumeCommand(orchestrator, playbookPack);
|
|
238
|
+
const afterResume = buildAfterResume(orchestrator, playbookPack, resumeCommand);
|
|
239
|
+
const expectedArtifact = buildExpectedArtifact(orchestrator, playbookPack, resumeCommand);
|
|
240
|
+
|
|
241
|
+
const resume = {
|
|
242
|
+
kind: "geo-agent-resume",
|
|
243
|
+
input,
|
|
244
|
+
source: orchestrator.source,
|
|
245
|
+
sourceType: orchestrator.sourceType,
|
|
246
|
+
artifactKind: orchestrator.artifactKind,
|
|
247
|
+
format,
|
|
248
|
+
resume_mode: inferResumeMode(orchestrator, playbookPack),
|
|
249
|
+
resume_from: buildResumeFrom(orchestrator, playbookPack),
|
|
250
|
+
resume_summary: buildResumeSummary(orchestrator, playbookPack),
|
|
251
|
+
resume_command: resumeCommand,
|
|
252
|
+
expected_artifact: expectedArtifact,
|
|
253
|
+
verify_before_resume: buildVerifyBeforeResume(orchestrator, playbookPack),
|
|
254
|
+
do_not_reset: buildDoNotReset(playbookPack),
|
|
255
|
+
after_resume: afterResume,
|
|
256
|
+
selectedSkill: {
|
|
257
|
+
name: "geo-ai-search-optimization-agent-resume",
|
|
258
|
+
displayName: "GEO Agent Resume"
|
|
259
|
+
},
|
|
260
|
+
next_skill: orchestrator.next_skill || orchestrator.selectedSkill?.name || "geo-ai-search-optimization",
|
|
261
|
+
contextNeeded: orchestrator.session?.contextNeeded || [],
|
|
262
|
+
currentPacket: playbookPack?.currentPacket || null,
|
|
263
|
+
nextPacket: playbookPack?.nextPacket || null,
|
|
264
|
+
playbookStatus: playbookPack?.playbookStatus || null,
|
|
265
|
+
orchestrator,
|
|
266
|
+
playbookPack,
|
|
267
|
+
resume_prompt: ""
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
resume.resume_prompt = buildResumePrompt(resume);
|
|
271
|
+
return resume;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export function renderAgentResumeMarkdown(resume) {
|
|
275
|
+
const lines = [
|
|
276
|
+
"# GEO Agent Resume",
|
|
277
|
+
"",
|
|
278
|
+
`- 输入:\`${resume.source}\``,
|
|
279
|
+
`- 输入类型:\`${resume.sourceType}\``,
|
|
280
|
+
`- 工件类型:\`${resume.artifactKind}\``,
|
|
281
|
+
`- 恢复模式:\`${resume.resume_mode}\``,
|
|
282
|
+
`- 当前建议 skill:\`${resume.next_skill}\``,
|
|
283
|
+
"",
|
|
284
|
+
"## 从哪里恢复",
|
|
285
|
+
"",
|
|
286
|
+
`- ${resume.resume_from}`,
|
|
287
|
+
`- ${resume.resume_summary}`,
|
|
288
|
+
"",
|
|
289
|
+
"## 现在恢复这一条",
|
|
290
|
+
"",
|
|
291
|
+
`- 命令:\`${resume.resume_command || "先补输入"}\``,
|
|
292
|
+
`- 预期产物:${resume.expected_artifact || "先补输入再恢复"}`,
|
|
293
|
+
""
|
|
294
|
+
];
|
|
295
|
+
|
|
296
|
+
if (resume.currentPacket) {
|
|
297
|
+
lines.push("## 当前包", "", `- ${resume.currentPacket.id}|${resume.currentPacket.title}`, "");
|
|
298
|
+
}
|
|
299
|
+
if (resume.nextPacket) {
|
|
300
|
+
lines.push("## 下一包", "", `- ${resume.nextPacket.id}|${resume.nextPacket.title}`, "");
|
|
301
|
+
}
|
|
302
|
+
if (resume.after_resume) {
|
|
303
|
+
lines.push("## 恢复后下一条", "", `- \`${resume.after_resume}\``, "");
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
lines.push("## 恢复前先确认", "");
|
|
307
|
+
for (const item of resume.verify_before_resume) {
|
|
308
|
+
lines.push(`- ${item}`);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
lines.push("", "## 恢复时不要重置", "");
|
|
312
|
+
for (const item of resume.do_not_reset) {
|
|
313
|
+
lines.push(`- ${item}`);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (resume.contextNeeded.length > 0) {
|
|
317
|
+
lines.push("", "## 还缺什么", "");
|
|
318
|
+
for (const item of resume.contextNeeded) {
|
|
319
|
+
lines.push(`- ${item}`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
lines.push("", "## 可直接复制给 Agent 的 Resume Prompt", "", "```text", resume.resume_prompt, "```");
|
|
324
|
+
return `${lines.join("\n")}\n`;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export async function writeAgentResumeOutput(outputPath, content) {
|
|
328
|
+
return writeScanOutput(outputPath, content);
|
|
329
|
+
}
|
package/src/agent-session.js
CHANGED
|
@@ -46,6 +46,9 @@ function inferSkillForCommand(commandName, flow) {
|
|
|
46
46
|
if (commandName === "auto-flow") {
|
|
47
47
|
return "geo-ai-search-optimization-auto-flow";
|
|
48
48
|
}
|
|
49
|
+
if (commandName === "agent-resume") {
|
|
50
|
+
return "geo-ai-search-optimization-agent-resume";
|
|
51
|
+
}
|
|
49
52
|
if (commandName === "agent-runbook") {
|
|
50
53
|
return "geo-ai-search-optimization-agent-runbook";
|
|
51
54
|
}
|
|
@@ -114,6 +117,8 @@ function inferStepPurpose(commandName, flow) {
|
|
|
114
117
|
return "先理解当前技能包结构,避免 agent 选错链路。";
|
|
115
118
|
case "quick-start":
|
|
116
119
|
return "快速建立从 0 到 1 的执行顺序。";
|
|
120
|
+
case "agent-resume":
|
|
121
|
+
return "从最近一个可靠恢复点继续,而不是把整条 GEO 链重新跑一遍。";
|
|
117
122
|
case "onboard":
|
|
118
123
|
case "onboard-url":
|
|
119
124
|
return "先从网址或引导流程拿到首轮 GEO 判断。";
|
|
@@ -191,6 +196,8 @@ function inferExpectedArtifact(commandName) {
|
|
|
191
196
|
return "阶段路线图";
|
|
192
197
|
case "agent-handoff":
|
|
193
198
|
return "agent 交接工件";
|
|
199
|
+
case "agent-resume":
|
|
200
|
+
return "agent 恢复入口工件";
|
|
194
201
|
case "agent-runbook":
|
|
195
202
|
return "agent 执行手册";
|
|
196
203
|
case "agent-executor":
|
|
@@ -238,6 +245,9 @@ function buildStepInstructions(parsedCommand, flow) {
|
|
|
238
245
|
if (parsedCommand.commandName === "publish-pack") {
|
|
239
246
|
lines.push("完成后把 `START-HERE.md` 和 `AGENT-START.md` 当作最终入口。");
|
|
240
247
|
}
|
|
248
|
+
if (parsedCommand.commandName === "agent-resume") {
|
|
249
|
+
lines.push("先确认恢复点、当前包和不要重置的内容,再继续执行。");
|
|
250
|
+
}
|
|
241
251
|
if (parsedCommand.commandName === "apply-plan") {
|
|
242
252
|
lines.push("执行包出来后,优先从第一包开始,不要同时展开太多任务。");
|
|
243
253
|
}
|
package/src/auto-flow.js
CHANGED
|
@@ -41,6 +41,9 @@ function detectArtifactKindFromParsedJson(parsed) {
|
|
|
41
41
|
function inferTaskTextMode(text) {
|
|
42
42
|
const normalized = String(text).toLowerCase();
|
|
43
43
|
|
|
44
|
+
if (/(agent-resume|resume|恢复继续|从中断处继续|接着上次继续|从最近恢复点继续)/i.test(normalized)) {
|
|
45
|
+
return "execute";
|
|
46
|
+
}
|
|
44
47
|
if (/(share-pack|export-pack|html-pack|publish-pack|分享|导出|交付|外发|报告包)/i.test(normalized)) {
|
|
45
48
|
return "share";
|
|
46
49
|
}
|
|
@@ -171,6 +174,9 @@ function resolveEffectiveIntent(intent, detected) {
|
|
|
171
174
|
if (detected.artifactKind === "geo-agent-playbook-pack") {
|
|
172
175
|
return detected.parsed?.playbookStatus === "closeout-ready" ? "closeout" : "execute";
|
|
173
176
|
}
|
|
177
|
+
if (detected.artifactKind === "geo-agent-resume") {
|
|
178
|
+
return detected.parsed?.resume_mode === "resume-closeout" ? "closeout" : "execute";
|
|
179
|
+
}
|
|
174
180
|
if (
|
|
175
181
|
[
|
|
176
182
|
"geo-share-pack",
|
|
@@ -338,79 +344,79 @@ function buildCommandChain(detected, intent) {
|
|
|
338
344
|
case "geo-agent-progress-tracker":
|
|
339
345
|
return detected.parsed?.status === "completed"
|
|
340
346
|
? [
|
|
347
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
341
348
|
`geo-ai-search-optimization completion-report ${source}`,
|
|
342
349
|
`geo-ai-search-optimization handoff-bundle ${source}`,
|
|
343
350
|
`geo-ai-search-optimization publish-pack ${source}`
|
|
344
351
|
]
|
|
345
352
|
: detected.parsed?.currentTaskId
|
|
346
353
|
? [
|
|
347
|
-
`geo-ai-search-optimization agent-
|
|
348
|
-
`geo-ai-search-optimization
|
|
349
|
-
`geo-ai-search-optimization
|
|
354
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
355
|
+
`geo-ai-search-optimization agent-progress-tracker ${source}`,
|
|
356
|
+
`geo-ai-search-optimization agent-decision-log ${source}`
|
|
350
357
|
]
|
|
351
358
|
: [
|
|
359
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
352
360
|
`geo-ai-search-optimization agent-batch-executor ${source}`,
|
|
353
|
-
`geo-ai-search-optimization
|
|
354
|
-
`geo-ai-search-optimization handoff-bundle ${source}`
|
|
361
|
+
`geo-ai-search-optimization agent-progress-tracker ${source}`
|
|
355
362
|
];
|
|
356
363
|
case "geo-agent-status-board":
|
|
357
364
|
return detected.parsed?.boardStatus === "completed"
|
|
358
365
|
? [
|
|
366
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
359
367
|
`geo-ai-search-optimization completion-report ${source}`,
|
|
360
368
|
`geo-ai-search-optimization handoff-bundle ${source}`,
|
|
361
369
|
`geo-ai-search-optimization publish-pack ${source}`
|
|
362
370
|
]
|
|
363
371
|
: detected.parsed?.tracker?.currentTaskId
|
|
364
372
|
? [
|
|
365
|
-
`geo-ai-search-optimization agent-
|
|
373
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
366
374
|
`geo-ai-search-optimization agent-progress-tracker ${source}`,
|
|
367
|
-
`geo-ai-search-optimization
|
|
375
|
+
`geo-ai-search-optimization agent-decision-log ${source}`
|
|
368
376
|
]
|
|
369
377
|
: [
|
|
378
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
370
379
|
`geo-ai-search-optimization agent-progress-tracker ${source}`,
|
|
371
|
-
`geo-ai-search-optimization
|
|
372
|
-
`geo-ai-search-optimization handoff-bundle ${source}`
|
|
380
|
+
`geo-ai-search-optimization agent-decision-log ${source}`
|
|
373
381
|
];
|
|
374
382
|
case "geo-agent-checkpoint":
|
|
375
383
|
return detected.parsed?.decision === "move-to-closeout"
|
|
376
384
|
? [
|
|
385
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
377
386
|
`geo-ai-search-optimization completion-report ${source}`,
|
|
378
387
|
`geo-ai-search-optimization handoff-bundle ${source}`,
|
|
379
388
|
`geo-ai-search-optimization publish-pack ${source}`
|
|
380
389
|
]
|
|
381
390
|
: detected.parsed?.decision === "resolve-blockers"
|
|
382
391
|
? [
|
|
383
|
-
|
|
392
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
384
393
|
`geo-ai-search-optimization agent-status-board ${source}`,
|
|
385
394
|
`geo-ai-search-optimization agent-progress-tracker ${source}`
|
|
386
395
|
]
|
|
387
396
|
: [
|
|
388
|
-
|
|
397
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
389
398
|
`geo-ai-search-optimization agent-progress-tracker ${source}`,
|
|
390
|
-
`geo-ai-search-optimization
|
|
399
|
+
`geo-ai-search-optimization agent-decision-log ${source}`
|
|
391
400
|
];
|
|
392
401
|
case "geo-agent-decision-log": {
|
|
393
402
|
const baseSource = detected.parsed?.latestCheckpoint?.source || detected.parsed?.source || source;
|
|
394
403
|
const latestDecision = detected.parsed?.latestDecision;
|
|
395
|
-
const suggestedNext =
|
|
396
|
-
detected.parsed?.suggestedNextCommand ||
|
|
397
|
-
detected.parsed?.latestCheckpoint?.suggestedNextCommand ||
|
|
398
|
-
`geo-ai-search-optimization agent-executor ${baseSource}`;
|
|
399
404
|
|
|
400
405
|
return latestDecision === "move-to-closeout"
|
|
401
406
|
? [
|
|
407
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
402
408
|
`geo-ai-search-optimization completion-report ${baseSource}`,
|
|
403
409
|
`geo-ai-search-optimization handoff-bundle ${baseSource}`,
|
|
404
410
|
`geo-ai-search-optimization publish-pack ${baseSource}`
|
|
405
411
|
]
|
|
406
412
|
: latestDecision === "resolve-blockers"
|
|
407
413
|
? [
|
|
408
|
-
|
|
414
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
409
415
|
`geo-ai-search-optimization agent-status-board ${source}`,
|
|
410
416
|
`geo-ai-search-optimization agent-decision-log ${baseSource} --append-from ${source}`
|
|
411
417
|
]
|
|
412
418
|
: [
|
|
413
|
-
|
|
419
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
414
420
|
`geo-ai-search-optimization agent-progress-tracker ${source}`,
|
|
415
421
|
`geo-ai-search-optimization agent-decision-log ${baseSource} --append-from ${source}`
|
|
416
422
|
];
|
|
@@ -425,16 +431,21 @@ function buildCommandChain(detected, intent) {
|
|
|
425
431
|
const baseSource = detected.parsed?.source || source;
|
|
426
432
|
return detected.parsed?.playbookStatus === "closeout-ready"
|
|
427
433
|
? [
|
|
428
|
-
|
|
434
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
429
435
|
`geo-ai-search-optimization meeting-pack ${baseSource}`,
|
|
430
436
|
`geo-ai-search-optimization publish-pack ${baseSource}`
|
|
431
437
|
]
|
|
432
438
|
: [
|
|
433
|
-
|
|
439
|
+
`geo-ai-search-optimization agent-resume ${source}`,
|
|
434
440
|
`geo-ai-search-optimization agent-status-board ${baseSource}`,
|
|
435
441
|
`geo-ai-search-optimization agent-decision-log ${baseSource}`
|
|
436
442
|
];
|
|
437
443
|
}
|
|
444
|
+
case "geo-agent-resume": {
|
|
445
|
+
const resumeCommand = detected.parsed?.resume_command;
|
|
446
|
+
const afterResume = detected.parsed?.after_resume;
|
|
447
|
+
return [resumeCommand, afterResume].filter(Boolean);
|
|
448
|
+
}
|
|
438
449
|
case "geo-apply-plan":
|
|
439
450
|
return [
|
|
440
451
|
`geo-ai-search-optimization agent-executor ${source}`,
|
|
@@ -511,17 +522,14 @@ function pickSkillName(detected, intent) {
|
|
|
511
522
|
case "geo-agent-batch-executor":
|
|
512
523
|
return "geo-ai-search-optimization-agent-batch-executor";
|
|
513
524
|
case "geo-agent-progress-tracker":
|
|
514
|
-
return "geo-ai-search-optimization-agent-progress-tracker";
|
|
515
525
|
case "geo-agent-status-board":
|
|
516
|
-
return "geo-ai-search-optimization-agent-status-board";
|
|
517
526
|
case "geo-agent-checkpoint":
|
|
518
|
-
return "geo-ai-search-optimization-agent-checkpoint";
|
|
519
527
|
case "geo-agent-decision-log":
|
|
520
|
-
|
|
528
|
+
case "geo-agent-playbook-pack":
|
|
529
|
+
case "geo-agent-resume":
|
|
530
|
+
return "geo-ai-search-optimization-agent-resume";
|
|
521
531
|
case "geo-agent-retrospective":
|
|
522
532
|
return "geo-ai-search-optimization-agent-retrospective";
|
|
523
|
-
case "geo-agent-playbook-pack":
|
|
524
|
-
return "geo-ai-search-optimization-agent-playbook-pack";
|
|
525
533
|
case "geo-completion-report":
|
|
526
534
|
return "geo-ai-search-optimization-completion-report";
|
|
527
535
|
case "geo-handoff-bundle":
|
|
@@ -563,12 +571,14 @@ function buildSecondarySkillNames(primarySkill, intent, detected) {
|
|
|
563
571
|
"geo-agent-status-board",
|
|
564
572
|
"geo-agent-checkpoint",
|
|
565
573
|
"geo-agent-decision-log",
|
|
574
|
+
"geo-agent-resume",
|
|
566
575
|
"geo-agent-playbook-pack",
|
|
567
576
|
"geo-apply-plan"
|
|
568
577
|
].includes(
|
|
569
578
|
detected.artifactKind
|
|
570
579
|
)
|
|
571
580
|
) {
|
|
581
|
+
names.add("geo-ai-search-optimization-agent-resume");
|
|
572
582
|
names.add("geo-ai-search-optimization-agent-batch-executor");
|
|
573
583
|
names.add("geo-ai-search-optimization-agent-progress-tracker");
|
|
574
584
|
names.add("geo-ai-search-optimization-agent-status-board");
|
|
@@ -590,6 +600,9 @@ function buildSecondarySkillNames(primarySkill, intent, detected) {
|
|
|
590
600
|
}
|
|
591
601
|
|
|
592
602
|
function buildStage(intent, detected) {
|
|
603
|
+
if (detected.artifactKind === "geo-agent-resume") {
|
|
604
|
+
return "恢复继续";
|
|
605
|
+
}
|
|
593
606
|
if (intent === "guide") {
|
|
594
607
|
return "使用引导";
|
|
595
608
|
}
|
|
@@ -610,6 +623,7 @@ function buildStage(intent, detected) {
|
|
|
610
623
|
"geo-agent-status-board",
|
|
611
624
|
"geo-agent-checkpoint",
|
|
612
625
|
"geo-agent-decision-log",
|
|
626
|
+
"geo-agent-resume",
|
|
613
627
|
"geo-agent-playbook-pack",
|
|
614
628
|
"geo-agent-retrospective",
|
|
615
629
|
"geo-apply-plan",
|
|
@@ -629,6 +643,7 @@ function buildStage(intent, detected) {
|
|
|
629
643
|
"geo-agent-status-board",
|
|
630
644
|
"geo-agent-checkpoint",
|
|
631
645
|
"geo-agent-decision-log",
|
|
646
|
+
"geo-agent-resume",
|
|
632
647
|
"geo-agent-playbook-pack",
|
|
633
648
|
"geo-agent-retrospective",
|
|
634
649
|
"geo-apply-plan",
|
|
@@ -717,14 +732,17 @@ function buildNextAction(detected, intent, commands) {
|
|
|
717
732
|
return `先运行 \`${commands[0]}\` 生成适合外发或交接的结果。`;
|
|
718
733
|
}
|
|
719
734
|
if (intent === "execute") {
|
|
735
|
+
if (detected.artifactKind === "geo-agent-resume") {
|
|
736
|
+
return `先运行 \`${commands[0]}\`,从最近一个可靠恢复点继续,不要把整条 GEO 链重新跑一遍。`;
|
|
737
|
+
}
|
|
720
738
|
if (detected.artifactKind === "geo-agent-progress-tracker") {
|
|
721
|
-
return `先运行 \`${commands[0]}
|
|
739
|
+
return `先运行 \`${commands[0]}\`,先确认最近一个可靠恢复点,再继续当前执行包。`;
|
|
722
740
|
}
|
|
723
741
|
if (detected.artifactKind === "geo-agent-decision-log") {
|
|
724
|
-
return `先运行 \`${commands[0]}
|
|
742
|
+
return `先运行 \`${commands[0]}\`,沿着最近一次阶段决策恢复,而不是重新判断整条链。`;
|
|
725
743
|
}
|
|
726
744
|
if (detected.artifactKind === "geo-agent-playbook-pack") {
|
|
727
|
-
return `先运行 \`${commands[0]}
|
|
745
|
+
return `先运行 \`${commands[0]}\`,直接从 playbook 对应的恢复点继续,不要重新拆链。`;
|
|
728
746
|
}
|
|
729
747
|
return `先运行 \`${commands[0]}\`,把当前输入推进到 agent 可执行状态。`;
|
|
730
748
|
}
|
package/src/cli.js
CHANGED
|
@@ -16,6 +16,12 @@ import {
|
|
|
16
16
|
} from "./agent-progress-tracker.js";
|
|
17
17
|
import { createAgentCheckpoint, renderAgentCheckpointMarkdown, writeAgentCheckpointOutput } from "./agent-checkpoint.js";
|
|
18
18
|
import { createAgentDecisionLog, renderAgentDecisionLogMarkdown, writeAgentDecisionLogOutput } from "./agent-decision-log.js";
|
|
19
|
+
import {
|
|
20
|
+
createAgentOrchestrator,
|
|
21
|
+
renderAgentOrchestratorMarkdown,
|
|
22
|
+
writeAgentOrchestratorOutput
|
|
23
|
+
} from "./agent-orchestrator.js";
|
|
24
|
+
import { createAgentResume, renderAgentResumeMarkdown, writeAgentResumeOutput } from "./agent-resume.js";
|
|
19
25
|
import {
|
|
20
26
|
createAgentPlaybookPack,
|
|
21
27
|
renderAgentPlaybookPackMarkdown,
|
|
@@ -80,6 +86,8 @@ function printHelp() {
|
|
|
80
86
|
"Usage:",
|
|
81
87
|
" geo-ai-search-optimization",
|
|
82
88
|
" geo-ai-search-optimization install [--target <dir>] [--json]",
|
|
89
|
+
" geo-ai-search-optimization agent-orchestrator <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--format <markdown|json>] [--out <file>]",
|
|
90
|
+
" geo-ai-search-optimization agent-resume <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--format <markdown|json>] [--out <file>]",
|
|
83
91
|
" geo-ai-search-optimization auto-flow <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--json] [--out <file>]",
|
|
84
92
|
" geo-ai-search-optimization agent-session <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--json] [--out <file>]",
|
|
85
93
|
" geo-ai-search-optimization agent-runbook <input> [--intent <auto|diagnose|guide|execute|share|closeout>] [--task <id>] [--format <markdown|json>] [--out <file>]",
|
|
@@ -183,6 +191,56 @@ async function handleAutoFlow(args) {
|
|
|
183
191
|
process.stdout.write(renderedOutput);
|
|
184
192
|
}
|
|
185
193
|
|
|
194
|
+
async function handleAgentOrchestrator(args) {
|
|
195
|
+
const input = args.find((value) => !value.startsWith("-"));
|
|
196
|
+
if (!input) {
|
|
197
|
+
throw new Error("agent-orchestrator 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
|
|
201
|
+
const orchestrator = await createAgentOrchestrator(input, {
|
|
202
|
+
intent: getFlagValue(args, "--intent"),
|
|
203
|
+
format
|
|
204
|
+
});
|
|
205
|
+
const outputJson = orchestrator.format === "json";
|
|
206
|
+
const renderedOutput = outputJson
|
|
207
|
+
? `${JSON.stringify(orchestrator, null, 2)}\n`
|
|
208
|
+
: renderAgentOrchestratorMarkdown(orchestrator);
|
|
209
|
+
|
|
210
|
+
const outputPath = getFlagValue(args, "--out");
|
|
211
|
+
if (outputPath) {
|
|
212
|
+
const resolvedOutputPath = await writeAgentOrchestratorOutput(outputPath, renderedOutput);
|
|
213
|
+
process.stdout.write(`已保存 agent-orchestrator 结果:${resolvedOutputPath}\n`);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
process.stdout.write(renderedOutput);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async function handleAgentResume(args) {
|
|
221
|
+
const input = args.find((value) => !value.startsWith("-"));
|
|
222
|
+
if (!input) {
|
|
223
|
+
throw new Error("agent-resume 需要一个输入值,可以是任务描述、项目路径、网站网址或已导出的工件");
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const format = getFlagValue(args, "--format") || (hasFlag(args, "--json") ? "json" : undefined);
|
|
227
|
+
const resume = await createAgentResume(input, {
|
|
228
|
+
intent: getFlagValue(args, "--intent"),
|
|
229
|
+
format
|
|
230
|
+
});
|
|
231
|
+
const outputJson = resume.format === "json";
|
|
232
|
+
const renderedOutput = outputJson ? `${JSON.stringify(resume, null, 2)}\n` : renderAgentResumeMarkdown(resume);
|
|
233
|
+
|
|
234
|
+
const outputPath = getFlagValue(args, "--out");
|
|
235
|
+
if (outputPath) {
|
|
236
|
+
const resolvedOutputPath = await writeAgentResumeOutput(outputPath, renderedOutput);
|
|
237
|
+
process.stdout.write(`已保存 agent-resume 结果:${resolvedOutputPath}\n`);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
process.stdout.write(renderedOutput);
|
|
242
|
+
}
|
|
243
|
+
|
|
186
244
|
async function handleAgentSession(args) {
|
|
187
245
|
const input = args.find((value) => !value.startsWith("-"));
|
|
188
246
|
if (!input) {
|
|
@@ -999,6 +1057,16 @@ export async function runCli(args = []) {
|
|
|
999
1057
|
return;
|
|
1000
1058
|
}
|
|
1001
1059
|
|
|
1060
|
+
if (command === "agent-orchestrator") {
|
|
1061
|
+
await handleAgentOrchestrator(rest);
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
if (command === "agent-resume") {
|
|
1066
|
+
await handleAgentResume(rest);
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1002
1070
|
if (command === "agent-session") {
|
|
1003
1071
|
await handleAgentSession(rest);
|
|
1004
1072
|
return;
|
package/src/index.js
CHANGED
|
@@ -7,6 +7,8 @@ export {
|
|
|
7
7
|
} from "./interactive-onboarding.js";
|
|
8
8
|
export { createAutoFlow, renderAutoFlowMarkdown, writeAutoFlowOutput } from "./auto-flow.js";
|
|
9
9
|
export { createApplyPlan, renderApplyPlanMarkdown, writeApplyPlanOutput } from "./apply-plan.js";
|
|
10
|
+
export { createAgentOrchestrator, renderAgentOrchestratorMarkdown, writeAgentOrchestratorOutput } from "./agent-orchestrator.js";
|
|
11
|
+
export { createAgentResume, renderAgentResumeMarkdown, writeAgentResumeOutput } from "./agent-resume.js";
|
|
10
12
|
export { createAgentBatchExecutor, renderAgentBatchExecutorMarkdown, writeAgentBatchExecutorOutput } from "./agent-batch-executor.js";
|
|
11
13
|
export { createAgentCheckpoint, renderAgentCheckpointMarkdown, writeAgentCheckpointOutput } from "./agent-checkpoint.js";
|
|
12
14
|
export { createAgentDecisionLog, renderAgentDecisionLogMarkdown, writeAgentDecisionLogOutput } from "./agent-decision-log.js";
|
package/src/skills.js
CHANGED
|
@@ -5,6 +5,8 @@ import { getPackageRoot } from "./paths.js";
|
|
|
5
5
|
const SKILL_ORDER = [
|
|
6
6
|
"geo-ai-search-optimization",
|
|
7
7
|
"geo-ai-search-optimization-auto-flow",
|
|
8
|
+
"geo-ai-search-optimization-agent-orchestrator",
|
|
9
|
+
"geo-ai-search-optimization-agent-resume",
|
|
8
10
|
"geo-ai-search-optimization-agent-session",
|
|
9
11
|
"geo-ai-search-optimization-agent-runbook",
|
|
10
12
|
"geo-ai-search-optimization-agent-executor",
|
|
@@ -29,6 +31,8 @@ const SKILL_ORDER = [
|
|
|
29
31
|
const SKILL_CATEGORY = {
|
|
30
32
|
"geo-ai-search-optimization": "core",
|
|
31
33
|
"geo-ai-search-optimization-auto-flow": "routing",
|
|
34
|
+
"geo-ai-search-optimization-agent-orchestrator": "routing",
|
|
35
|
+
"geo-ai-search-optimization-agent-resume": "routing",
|
|
32
36
|
"geo-ai-search-optimization-agent-session": "routing",
|
|
33
37
|
"geo-ai-search-optimization-agent-runbook": "execution",
|
|
34
38
|
"geo-ai-search-optimization-agent-executor": "execution",
|
|
@@ -171,6 +175,8 @@ export function renderBundledSkillsMarkdown(bundle) {
|
|
|
171
175
|
"## 推荐理解顺序",
|
|
172
176
|
"",
|
|
173
177
|
"- 先看核心 GEO skill。",
|
|
178
|
+
"- 如果你只想让 agent 立刻知道现在唯一该跑哪条命令,先跑 agent-orchestrator。",
|
|
179
|
+
"- 如果工作中断后要从最近一个可靠恢复点继续,先跑 agent-resume。",
|
|
174
180
|
"- 如果 agent 需要自动选 skill,先跑 auto-flow。",
|
|
175
181
|
"- 如果要给 agent 明确步骤,继续进入 agent-session。",
|
|
176
182
|
"- 如果要给 agent 一份执行手册和检查表,再进入 agent-runbook。",
|