oh-my-opencode-cohub 1.18.6 → 1.18.7
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 +26 -18
- package/dist/cli/index.js +1 -1
- package/dist/context/extractor.d.ts.map +1 -1
- package/dist/context/types.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +104 -60
- package/dist/orchestration/contract.d.ts +11 -3
- package/dist/orchestration/contract.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,22 +23,21 @@ OpenCode 中文智能体编排插件 CoHub——纯调度模式、全中文提
|
|
|
23
23
|
### 前置条件
|
|
24
24
|
|
|
25
25
|
- [OpenCode](https://opencode.ai) 已安装
|
|
26
|
-
- [Bun](https://bun.sh)
|
|
26
|
+
- [Bun](https://bun.sh) 已安装(隔离 HOME 检验与源码构建需要;官方插件安装不需要)
|
|
27
27
|
|
|
28
|
-
###
|
|
28
|
+
### 方式一:官方插件安装(推荐,真实 HOME)
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
|
|
31
|
+
opencode plugin oh-my-opencode-cohub@<精确版本号> --global --force
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
> 安装前先对 `~/.config/opencode/opencode.json` 与 `~/.config/opencode/tui.json` 做**时间戳备份**;命令只写入插件相关条目,**保留其他配置**。
|
|
35
35
|
|
|
36
|
-
1. 将 `oh-my-opencode-cohub
|
|
37
|
-
2.
|
|
38
|
-
3.
|
|
39
|
-
4. 写入默认配置文件 `~/.config/opencode/oh-my-opencode-cohub.json`
|
|
36
|
+
1. 将 `oh-my-opencode-cohub@<精确版本号>` 注册到全局 `plugin` 配置(`--global --force` 覆盖为指定精确版本)
|
|
37
|
+
2. 插件运行时写入默认配置文件 `~/.config/opencode/oh-my-opencode-cohub.json`
|
|
38
|
+
3. **重启 OpenCode 后生效**——已运行的会话不会热切加载新版本,需用户重启
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
> **bunx 包 CLI 仅用于隔离 HOME 检验**:`bunx oh-my-opencode-cohub install/uninstall` 等包自带 CLI 只在隔离 HOME 环境中验证安装/卸载流程,**不要在真实 HOME 上整文件重写配置**。
|
|
42
41
|
|
|
43
42
|
### 方式二:npm 安装 + 手动配置
|
|
44
43
|
|
|
@@ -328,14 +327,19 @@ CoHub 内置轻量编排引擎(`src/orchestration/`,6 模块),**诚实
|
|
|
328
327
|
|
|
329
328
|
### 上下文共享
|
|
330
329
|
|
|
331
|
-
ContextEngine(`src/context
|
|
330
|
+
ContextEngine(`src/context/`)默认**不注入**历史上下文——所有代理默认策略为 `none`,每次委派不会自动读取父会话历史(避免无谓的上下文膨胀与 token 消耗)。需要历史上下文时由调度者显式 opt-in:
|
|
331
|
+
|
|
332
|
+
- **任务级 opt-in**:`task` 调用传 `context_override` 参数(如 `context_override="relevant"`);
|
|
333
|
+
- **配置级 opt-in**:在 `oh-my-opencode-cohub.json` 的 `context.strategy` 中为指定代理显式配置非 `none` 策略。
|
|
332
334
|
|
|
333
|
-
| 策略 |
|
|
334
|
-
|
|
335
|
-
| `none` |
|
|
336
|
-
| `relevant` |
|
|
337
|
-
| `summary` |
|
|
338
|
-
| `full` |
|
|
335
|
+
| 策略 | 注入内容 |
|
|
336
|
+
|------|---------|
|
|
337
|
+
| `none` | 不注入上下文(默认) |
|
|
338
|
+
| `relevant` | 相关文件路径 + 前置决策 + 近期错误 |
|
|
339
|
+
| `summary` | 同上,且文件正文按 token 预算(2000)截断后注入 |
|
|
340
|
+
| `full` | 完整正文(预留) |
|
|
341
|
+
|
|
342
|
+
**依赖传播(`context.dependencyPropagation`,默认 `false`)**:子代理结果默认不自动传播到后续子代理;需要依赖历史摘要时显式配置 `"context": { "dependencyPropagation": true }`。关闭时 `captureResult` 仍照常返回结果与质量/复用预算采样(任务追踪、质量回送不受影响),仅不做依赖缓存写入与注入。
|
|
339
343
|
|
|
340
344
|
**summary 文件读取模式(`context.summaryReadMode`,默认 `bounded`)**:控制 `summary` 策略下**文件正文的读取方式**,与上面的上下文策略 `full` 是**两个不同维度**,不要混淆:
|
|
341
345
|
|
|
@@ -346,7 +350,11 @@ ContextEngine(`src/context/`)按四种策略自动向子代理注入上下
|
|
|
346
350
|
|
|
347
351
|
```json
|
|
348
352
|
{
|
|
349
|
-
"context": {
|
|
353
|
+
"context": {
|
|
354
|
+
"strategy": { "co-fixer": "relevant", "co-oracle": "summary" },
|
|
355
|
+
"dependencyPropagation": true,
|
|
356
|
+
"summaryReadMode": "bounded"
|
|
357
|
+
}
|
|
350
358
|
}
|
|
351
359
|
```
|
|
352
360
|
|
|
@@ -370,7 +378,7 @@ ContextEngine(`src/context/`)按四种策略自动向子代理注入上下
|
|
|
370
378
|
### 注入膨胀防护
|
|
371
379
|
|
|
372
380
|
- **prompt 预算兜底**:拼接超 12,000 token 时降级为裸用户 prompt,防止 JSON 超长截断
|
|
373
|
-
- **CONTRACT 去重**:`stripExistingContracts`
|
|
381
|
+
- **CONTRACT 去重**:`stripExistingContracts` 仅清理插件自生成的 goal-only 空壳契约块,含约束/前置/其他内容的契约块(含用户手写)保守保留;新契约非空才追加且不重复追加
|
|
374
382
|
- **错误截断**:单条 ≤200 字符 + 渲染总量 ≤600
|
|
375
383
|
- **Job Board 折叠**:展示上限 15 条 + `pruneTerminalJobs` 每 30 分钟清理终态任务
|
|
376
384
|
|
package/dist/cli/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/context/extractor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/context/extractor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAyB5C,yBAAyB;AACzB,UAAU,OAAO;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,sBAAsB;AACtB,UAAU,UAAU;IAClB,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,UAAU,EAAE,EACtB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,YAAY,EAAE,CAmGhB;AAUD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,UAAU,EAAE,EACtB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CAqBV;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,UAAU,EAAE,EACtB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CAwBV;AAID,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/context/types.ts"],"names":[],"mappings":"AAEA,cAAc;AACd,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;AAEvE,eAAe;AACf,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,iBAAiB;AACjB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,oBAAoB;AACpB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,cAAc;AACd,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1C,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,uBAAuB;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,eAAe,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACrC,4BAA4B;IAC5B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,2BAA2B;IAC3B,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED,WAAW;AACX,eAAO,MAAM,sBAAsB,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/context/types.ts"],"names":[],"mappings":"AAEA,cAAc;AACd,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;AAEvE,eAAe;AACf,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,iBAAiB;AACjB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,oBAAoB;AACpB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,cAAc;AACd,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1C,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,uBAAuB;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,eAAe,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACrC,4BAA4B;IAC5B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,2BAA2B;IAC3B,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED,WAAW;AACX,eAAO,MAAM,sBAAsB,EAAE,aA4BpC,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAe;AACf,eAAO,MAAM,2BAA2B,EAAE,iBAGzC,CAAC"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAsIlD,QAAA,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAsIlD,QAAA,MAAM,WAAW,EAAE,MAuqClB,CAAC;AAEF,eAAO,MAAM,MAAM,QAAc,CAAC;AAClC,eAAe,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -832,11 +832,11 @@ var DEFAULT_CONTEXT_CONFIG = {
|
|
|
832
832
|
"co-explorer": "none",
|
|
833
833
|
"co-librarian": "none",
|
|
834
834
|
"co-observer": "none",
|
|
835
|
-
"co-fixer": "
|
|
836
|
-
"co-designer": "
|
|
837
|
-
"co-planner": "
|
|
838
|
-
"co-oracle": "
|
|
839
|
-
"co-council": "
|
|
835
|
+
"co-fixer": "none",
|
|
836
|
+
"co-designer": "none",
|
|
837
|
+
"co-planner": "none",
|
|
838
|
+
"co-oracle": "none",
|
|
839
|
+
"co-council": "none",
|
|
840
840
|
"co-rule-user": "none",
|
|
841
841
|
"co-rule-project": "none",
|
|
842
842
|
"co-rule-app": "none"
|
|
@@ -845,7 +845,7 @@ var DEFAULT_CONTEXT_CONFIG = {
|
|
|
845
845
|
maxDecisions: 10,
|
|
846
846
|
maxErrors: 5,
|
|
847
847
|
maxDependencies: 8,
|
|
848
|
-
dependencyPropagation:
|
|
848
|
+
dependencyPropagation: false,
|
|
849
849
|
summarizeMaxTokens: 2000,
|
|
850
850
|
summaryReadMode: "bounded",
|
|
851
851
|
relevantMessageWindow: 20,
|
|
@@ -1639,7 +1639,7 @@ var KNOWN_EXTENSIONS = new Set([
|
|
|
1639
1639
|
"gitignore",
|
|
1640
1640
|
"editorconfig"
|
|
1641
1641
|
]);
|
|
1642
|
-
var FILE_PATH_RE = /`?((?:[A-Za-z]:[\\\/]|\.{1,2}[\\\/]|~\/|\/|[\w
|
|
1642
|
+
var FILE_PATH_RE = /`?((?:[A-Za-z]:[\\\/]|\.{1,2}[\\\/]|~\/|\/|[\w\-~]+[\\\/])[\w\-\.\\\/~]+\.\w{1,10})`?/g;
|
|
1643
1643
|
function extractRelevantFiles(messages, maxFiles, windowSize) {
|
|
1644
1644
|
const recent = messages.slice(-windowSize);
|
|
1645
1645
|
const fileMap = new Map;
|
|
@@ -3774,7 +3774,15 @@ class OrchestrationEngine {
|
|
|
3774
3774
|
var CONTRACT_PATTERN = /<!-- CONTRACT_BEGIN -->\n([\s\S]*?)<!-- CONTRACT_END -->/;
|
|
3775
3775
|
var CONTRACT_STRIP_PATTERN = /<!-- CONTRACT_BEGIN -->[\s\S]*?<!-- CONTRACT_END -->/g;
|
|
3776
3776
|
function stripExistingContracts(text) {
|
|
3777
|
-
return text.replace(CONTRACT_STRIP_PATTERN,
|
|
3777
|
+
return text.replace(CONTRACT_STRIP_PATTERN, (match) => {
|
|
3778
|
+
const inner = match.replace(/<!-- CONTRACT_BEGIN -->/, "").replace(/<!-- CONTRACT_END -->/, "").trim();
|
|
3779
|
+
const lines = inner.split(`
|
|
3780
|
+
`).map((l) => l.trim()).filter(Boolean);
|
|
3781
|
+
if (lines.length === 2 && lines[0] === "## 本任务前置上下文" && lines[1].startsWith("- 目标:")) {
|
|
3782
|
+
return "";
|
|
3783
|
+
}
|
|
3784
|
+
return match;
|
|
3785
|
+
});
|
|
3778
3786
|
}
|
|
3779
3787
|
|
|
3780
3788
|
class ContractManager {
|
|
@@ -3806,8 +3814,7 @@ class ContractManager {
|
|
|
3806
3814
|
};
|
|
3807
3815
|
}
|
|
3808
3816
|
buildPrompt(context) {
|
|
3809
|
-
const lines = [
|
|
3810
|
-
lines.push(`- 目标: ${context.goal}`);
|
|
3817
|
+
const lines = [];
|
|
3811
3818
|
if (context.constraints.length) {
|
|
3812
3819
|
lines.push("- 约束:");
|
|
3813
3820
|
context.constraints.forEach((c) => lines.push(` - ${c}`));
|
|
@@ -3824,8 +3831,9 @@ class ContractManager {
|
|
|
3824
3831
|
}
|
|
3825
3832
|
});
|
|
3826
3833
|
}
|
|
3827
|
-
lines.
|
|
3828
|
-
|
|
3834
|
+
if (lines.length === 0)
|
|
3835
|
+
return "";
|
|
3836
|
+
return ["<!-- CONTRACT_BEGIN -->", "## 本任务前置上下文", ...lines, "<!-- CONTRACT_END -->"].join(`
|
|
3829
3837
|
`);
|
|
3830
3838
|
}
|
|
3831
3839
|
summarize(contracts) {
|
|
@@ -4263,12 +4271,12 @@ var CoHubPlugin = async (input, options) => {
|
|
|
4263
4271
|
const aliasAtCall = job.alias;
|
|
4264
4272
|
const childId = job.sessionId;
|
|
4265
4273
|
if (!childId)
|
|
4266
|
-
return;
|
|
4274
|
+
return false;
|
|
4267
4275
|
const verdict = await verifyChildTerminal(pluginClient, childId, job.createdAt);
|
|
4268
4276
|
const nowJob = callAtCall ? tracker.getJobByCall(parentAtCall, callAtCall) : tracker.getJobBySessionId(childId);
|
|
4269
4277
|
if (!nowJob || nowJob.alias !== aliasAtCall || nowJob.sessionId !== childId || nowJob.status !== "running") {
|
|
4270
4278
|
appendSafeLog("event", `收尾竞态:候选已变更,不更新新调用 (session=${childId.slice(0, 20)})`);
|
|
4271
|
-
return;
|
|
4279
|
+
return false;
|
|
4272
4280
|
}
|
|
4273
4281
|
if (verdict === "completed" || verdict === "errored" || verdict === "cancelled") {
|
|
4274
4282
|
const term = verdict === "completed" ? "completed" : verdict === "cancelled" ? "cancelled" : "errored";
|
|
@@ -4287,6 +4295,7 @@ var CoHubPlugin = async (input, options) => {
|
|
|
4287
4295
|
durationMs: Date.now() - job.createdAt,
|
|
4288
4296
|
lastActivityAt: Date.now()
|
|
4289
4297
|
});
|
|
4298
|
+
return verdict === "completed" && up.ok;
|
|
4290
4299
|
} else {
|
|
4291
4300
|
appendSafeLog("event", `无终态证据,保持 running (session=${childId.slice(0, 20)})`);
|
|
4292
4301
|
taskDiag({
|
|
@@ -4297,8 +4306,46 @@ var CoHubPlugin = async (input, options) => {
|
|
|
4297
4306
|
status: "running",
|
|
4298
4307
|
lastActivityAt: Date.now()
|
|
4299
4308
|
});
|
|
4309
|
+
return false;
|
|
4300
4310
|
}
|
|
4301
4311
|
}
|
|
4312
|
+
function captureAndWriteBack(opts) {
|
|
4313
|
+
contextEngine.captureResult(opts.childSessionId, opts.alias, opts.agent, { notBefore: opts.createdAt }).then((captured) => {
|
|
4314
|
+
if (samplingSeq.get(opts.alias) !== opts.seq)
|
|
4315
|
+
return;
|
|
4316
|
+
if (!captured)
|
|
4317
|
+
return;
|
|
4318
|
+
const wantQuality = isQualityEnabled(userConfig.quality);
|
|
4319
|
+
const wantReuse = reuseBudget.enabled;
|
|
4320
|
+
if (!wantQuality && !wantReuse)
|
|
4321
|
+
return;
|
|
4322
|
+
const now = opts.callID ? tracker.getJobByCall(opts.parentSessionId, opts.callID) : tracker.getJobBySessionId(opts.childSessionId);
|
|
4323
|
+
if (!now || now.alias !== opts.alias || now.sessionId !== opts.childSessionId) {
|
|
4324
|
+
appendSafeLog("event", "质量回送竞态:候选已变更,不写回复用/新调用");
|
|
4325
|
+
return;
|
|
4326
|
+
}
|
|
4327
|
+
const freshSample = wantReuse && captured.reuseInput && captured.reuseInput.sampledAt >= opts.createdAt ? captured.reuseInput : undefined;
|
|
4328
|
+
if (wantQuality) {
|
|
4329
|
+
const quality = assessQuality({
|
|
4330
|
+
output: captured.output,
|
|
4331
|
+
decisions: captured.decisions,
|
|
4332
|
+
latencyMs: Date.now() - opts.createdAt,
|
|
4333
|
+
tokens: captured.tokens
|
|
4334
|
+
});
|
|
4335
|
+
tracker.updateQualityByAlias(opts.alias, {
|
|
4336
|
+
score: quality.score,
|
|
4337
|
+
...quality.failureCategory ? { failureCategory: quality.failureCategory } : {},
|
|
4338
|
+
...quality.latencyMs !== undefined ? { latencyMs: quality.latencyMs } : {},
|
|
4339
|
+
...quality.tokens ? { tokens: quality.tokens } : {},
|
|
4340
|
+
...freshSample ? { reuseInput: freshSample } : {}
|
|
4341
|
+
});
|
|
4342
|
+
} else if (wantReuse) {
|
|
4343
|
+
const prev = tracker.getJobByAlias(opts.alias)?.quality;
|
|
4344
|
+
tracker.updateQualityByAlias(opts.alias, { ...prev ?? {}, reuseInput: freshSample });
|
|
4345
|
+
}
|
|
4346
|
+
syncTrackerState(tracker.currentParentSessionId);
|
|
4347
|
+
}).catch((err) => appendSafeLog("event", "质量回送失败", err));
|
|
4348
|
+
}
|
|
4302
4349
|
const cleanupTimer = setInterval(() => {
|
|
4303
4350
|
try {
|
|
4304
4351
|
const staleSessions = tracker.cleanupStaleJobs(STALE_TASK_MS);
|
|
@@ -4427,12 +4474,15 @@ var CoHubPlugin = async (input, options) => {
|
|
|
4427
4474
|
const targetField = output.args?.prompt ? "prompt" : "description";
|
|
4428
4475
|
if (output.args?.[targetField] && typeof output.args[targetField] === "string") {
|
|
4429
4476
|
output.args[targetField] = stripExistingContracts(output.args[targetField]);
|
|
4430
|
-
|
|
4431
|
-
` + orchestrationLayer.contractMgr.buildPrompt({
|
|
4477
|
+
const contractText = orchestrationLayer.contractMgr.buildPrompt({
|
|
4432
4478
|
goal: description,
|
|
4433
4479
|
prerequisites: [],
|
|
4434
4480
|
constraints: []
|
|
4435
4481
|
});
|
|
4482
|
+
if (contractText && !output.args[targetField].includes("<!-- CONTRACT_BEGIN -->")) {
|
|
4483
|
+
output.args[targetField] += `
|
|
4484
|
+
` + contractText;
|
|
4485
|
+
}
|
|
4436
4486
|
}
|
|
4437
4487
|
const lr = orchestrationLayer.engine.applyLifecycleEvent(alias, "running");
|
|
4438
4488
|
if (!lr.ok) {
|
|
@@ -4466,19 +4516,13 @@ var CoHubPlugin = async (input, options) => {
|
|
|
4466
4516
|
if (strategy !== "none") {
|
|
4467
4517
|
const contextId = contextEngine.registerContext({ description });
|
|
4468
4518
|
output.args ??= {};
|
|
4469
|
-
const contextBlock = `
|
|
4470
|
-
|
|
4471
|
-
### \uD83D\uDCCB 任务上下文 (CoHub 自动注入)
|
|
4472
|
-
` + "**当前任务**: " + description + `
|
|
4473
|
-
`;
|
|
4474
4519
|
const targetField = typeof output.args.prompt === "string" ? "prompt" : "description";
|
|
4475
|
-
output.args[targetField] = ((targetField === "prompt" ? output.args.prompt : description) ?? "") + contextBlock;
|
|
4476
4520
|
await contextEngine.fillContextAsync(contextId, input.sessionID, {
|
|
4477
4521
|
strategy
|
|
4478
4522
|
});
|
|
4479
4523
|
const details = contextEngine.formatContextDetails(contextId);
|
|
4480
4524
|
if (details) {
|
|
4481
|
-
output.args[targetField]
|
|
4525
|
+
output.args[targetField] = ((targetField === "prompt" ? output.args.prompt : description) ?? "") + details;
|
|
4482
4526
|
}
|
|
4483
4527
|
contextEngine.releaseContext(contextId);
|
|
4484
4528
|
if (ctxDiag.enabled) {
|
|
@@ -4590,6 +4634,13 @@ var CoHubPlugin = async (input, options) => {
|
|
|
4590
4634
|
lastActivityAt: Date.now()
|
|
4591
4635
|
});
|
|
4592
4636
|
} else {
|
|
4637
|
+
const snapAlias = job0.alias;
|
|
4638
|
+
const snapParent = job0.parentSessionId;
|
|
4639
|
+
const snapCall = job0.callID;
|
|
4640
|
+
const snapChild = childSessionId ?? job0.sessionId;
|
|
4641
|
+
const snapCreatedAt = job0.createdAt;
|
|
4642
|
+
const snapAgent = job0.agent;
|
|
4643
|
+
const wasRunningAtAfter = job0.status === "running";
|
|
4593
4644
|
taskDiag({
|
|
4594
4645
|
t: "task",
|
|
4595
4646
|
callID: input.callID,
|
|
@@ -4599,7 +4650,26 @@ var CoHubPlugin = async (input, options) => {
|
|
|
4599
4650
|
status: "running",
|
|
4600
4651
|
lastActivityAt: Date.now()
|
|
4601
4652
|
});
|
|
4602
|
-
|
|
4653
|
+
const seqAtAfter = samplingSeq.get(snapAlias) ?? 0;
|
|
4654
|
+
const finalizedByThis = await reconcileJobTerminal(job0);
|
|
4655
|
+
if (finalizedByThis && wasRunningAtAfter && snapChild) {
|
|
4656
|
+
if ((samplingSeq.get(snapAlias) ?? 0) === seqAtAfter) {
|
|
4657
|
+
const nowJob = snapCall ? tracker.getJobByCall(snapParent, snapCall) : tracker.getJobBySessionId(snapChild);
|
|
4658
|
+
if (nowJob && nowJob.status === "completed" && nowJob.alias === snapAlias && nowJob.sessionId === snapChild) {
|
|
4659
|
+
const seq = seqAtAfter + 1;
|
|
4660
|
+
samplingSeq.set(snapAlias, seq);
|
|
4661
|
+
captureAndWriteBack({
|
|
4662
|
+
alias: snapAlias,
|
|
4663
|
+
parentSessionId: snapParent,
|
|
4664
|
+
callID: snapCall,
|
|
4665
|
+
childSessionId: snapChild,
|
|
4666
|
+
agent: snapAgent,
|
|
4667
|
+
createdAt: snapCreatedAt,
|
|
4668
|
+
seq
|
|
4669
|
+
});
|
|
4670
|
+
}
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4603
4673
|
}
|
|
4604
4674
|
} catch (e) {
|
|
4605
4675
|
appendSafeLog("orchestration", "afterTask engine 同步失败", e);
|
|
@@ -4632,48 +4702,22 @@ var CoHubPlugin = async (input, options) => {
|
|
|
4632
4702
|
const qAlias = job.alias;
|
|
4633
4703
|
const qParent = job.parentSessionId;
|
|
4634
4704
|
const qCall = job.callID;
|
|
4635
|
-
const qChild = sessionId;
|
|
4636
4705
|
const qCreatedAt = job.createdAt;
|
|
4706
|
+
const qAgent = job.agent;
|
|
4637
4707
|
const seq = (samplingSeq.get(qAlias) ?? 0) + 1;
|
|
4638
4708
|
samplingSeq.set(qAlias, seq);
|
|
4639
4709
|
await reconcileJobTerminal(job);
|
|
4640
4710
|
if (samplingSeq.get(qAlias) !== seq)
|
|
4641
4711
|
return;
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
const now = qCall ? tracker.getJobByCall(qParent, qCall) : tracker.getJobBySessionId(qChild);
|
|
4652
|
-
if (!now || now.alias !== qAlias || now.sessionId !== qChild) {
|
|
4653
|
-
appendSafeLog("event", "质量回送竞态:候选已变更,不写回复用/新调用");
|
|
4654
|
-
return;
|
|
4655
|
-
}
|
|
4656
|
-
const freshSample = wantReuse && captured.reuseInput && captured.reuseInput.sampledAt >= qCreatedAt ? captured.reuseInput : undefined;
|
|
4657
|
-
if (wantQuality) {
|
|
4658
|
-
const quality = assessQuality({
|
|
4659
|
-
output: captured.output,
|
|
4660
|
-
decisions: captured.decisions,
|
|
4661
|
-
latencyMs: Date.now() - qCreatedAt,
|
|
4662
|
-
tokens: captured.tokens
|
|
4663
|
-
});
|
|
4664
|
-
tracker.updateQualityByAlias(qAlias, {
|
|
4665
|
-
score: quality.score,
|
|
4666
|
-
...quality.failureCategory ? { failureCategory: quality.failureCategory } : {},
|
|
4667
|
-
...quality.latencyMs !== undefined ? { latencyMs: quality.latencyMs } : {},
|
|
4668
|
-
...quality.tokens ? { tokens: quality.tokens } : {},
|
|
4669
|
-
...freshSample ? { reuseInput: freshSample } : {}
|
|
4670
|
-
});
|
|
4671
|
-
} else if (wantReuse) {
|
|
4672
|
-
const prev = tracker.getJobByAlias(qAlias)?.quality;
|
|
4673
|
-
tracker.updateQualityByAlias(qAlias, { ...prev ?? {}, reuseInput: freshSample });
|
|
4674
|
-
}
|
|
4675
|
-
syncTrackerState(tracker.currentParentSessionId);
|
|
4676
|
-
}).catch((err) => appendSafeLog("event", "质量回送失败", err));
|
|
4712
|
+
captureAndWriteBack({
|
|
4713
|
+
alias: qAlias,
|
|
4714
|
+
parentSessionId: qParent,
|
|
4715
|
+
callID: qCall,
|
|
4716
|
+
childSessionId: sessionId,
|
|
4717
|
+
agent: qAgent,
|
|
4718
|
+
createdAt: qCreatedAt,
|
|
4719
|
+
seq
|
|
4720
|
+
});
|
|
4677
4721
|
} else if (e.type === "session.deleted") {
|
|
4678
4722
|
if (!sessionId)
|
|
4679
4723
|
return;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import type { AgentContract } from './types';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* 清理历史残留的插件自生成「goal-only 空壳」契约块。
|
|
4
|
+
*
|
|
5
|
+
* 背景:旧版 buildPrompt 在无约束/无前置时仍输出 `## 本任务前置上下文 + - 目标: xxx`,
|
|
6
|
+
* 目标已随本任务 prompt 传递、无独立信息价值,同一次 task() 重复 before 会累积这些空壳块。
|
|
7
|
+
* 仅严格匹配该空壳形态(标题 + 仅一行 `- 目标:`、无任何其他内容)才清除;
|
|
8
|
+
* 含约束/前置结果/其他内容的契约块(含用户手写契约、调度显式约束)**保守保留**——
|
|
9
|
+
* 绝不按中文标题宽泛删除用户内容。
|
|
5
10
|
* 无匹配时原样返回。
|
|
6
11
|
*/
|
|
7
12
|
export declare function stripExistingContracts(text: string): string;
|
|
@@ -17,7 +22,10 @@ export declare class ContractManager {
|
|
|
17
22
|
*/
|
|
18
23
|
private parseLines;
|
|
19
24
|
/**
|
|
20
|
-
*
|
|
25
|
+
* 构建传递给子代理的提示词,包含约束和显式前置任务结果交接。
|
|
26
|
+
* 目标不再重复输出(任务目标已在本任务 prompt 中,避免重复膨胀);
|
|
27
|
+
* 仅当存在真正约束或显式前置依赖交接时才生成契约块,否则返回空字符串
|
|
28
|
+
* (入口仅在非空时追加,保证重复 before 不堆积空壳契约)。
|
|
21
29
|
* 输出包含 CONTRACT_BEGIN/END 标记,子代理可追加自己的契约。
|
|
22
30
|
*/
|
|
23
31
|
buildPrompt(context: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/orchestration/contract.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/orchestration/contract.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY3D;AAED,qBAAa,eAAe;IAC1B;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAM7C;;;OAGG;IACH,OAAO,CAAC,UAAU;IAqBlB;;;;;;OAMG;IACH,WAAW,CAAC,OAAO,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,aAAa,CAAA;SAAE,EAAE,CAAC;QAC3D,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB,GAAG,MAAM;IAsBV;;OAEG;IACH,SAAS,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,MAAM;CAY9C"}
|