dsh-parallel-tools-prompt 0.2.1-rc.2 → 0.2.1-rc.4
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 +11 -3
- package/cordis.patch.yml +3 -2
- package/lib/client.js +112 -0
- package/lib/index.d.ts +18 -6
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +51 -25
- package/lib/index.js.map +1 -1
- package/lib/prompt.d.ts +4 -1
- package/lib/prompt.d.ts.map +1 -1
- package/lib/prompt.js +4 -5
- package/lib/prompt.js.map +1 -1
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +14 -3
- package/skills/batch-tool-calls/SKILL.md +17 -0
package/README.md
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
- 使用公开 `agent/created`、`agents.roots()`、session projection 与 `systemPrompt.section()`,不替换 preset。
|
|
11
11
|
- 固定 section 名称 `parallel-tools:guidance`、order 1050、禁止插值;不注入时间戳、工具列表或每轮变化的数据。
|
|
12
12
|
- 同一 Agent 幂等注册;插件卸载与 Agent 释放都清理 section。插件重载时为仍存活的目标根 Agent 补挂 section;源码更新建议重启宿主加载新模块。
|
|
13
|
-
-
|
|
13
|
+
- 两个独立开关选择注入通道(默认只走系统提示词):`systemPromptSection`(默认 `true`,注册 `systemPrompt.section()`)与 `contextReminder`(默认 `false`)。后者通过 `agent/pre-step` 在下一步骤追加一条带独立 `source.kind: parallel-tools-scheduling` 的 CONTEXT 提醒,写入会话历史并渲染为 CONTEXT 块,与宿主 `time-context` 同一机制;已持久化的 source 用于避免重复注入,每个 Agent 只交付一次。两者可同时开启;同时关闭则插件不注入任何内容。提醒进入历史,卸载不会删除。这不是每轮重复提醒,也不保证长期遵循。
|
|
14
|
+
- 插件详情页(Plugins → 本插件)在描述与组件列表之间提供这两个开关的设置表单,开关即时写入当前 profile 的 patch。两个字段声明为 `.volatile()`,修改不重启插件:`contextReminder` 在下一步骤生效;系统提示词开关对修改之后重新组装提示词的会话生效(已建立的会话沿用旧提示词)。浏览器端由 `src/client` 经 `scripts/build-client.mjs` 构建为 `lib/client.js`,按宿主客户端模块格式封装;表单要求 profile 里条目 id 为 `parallel-tools-prompt`。
|
|
14
15
|
- 单次调用合理时仍单次;路径、ID等参数必须已知;读后写、共享文件冲突、权限审批保持依赖顺序。不发明batch工具或额外规划轮次。
|
|
15
16
|
- 同轮多个工具调用不代表真正同时执行;执行并发仍由DSH调度器决定。
|
|
16
17
|
|
|
@@ -22,6 +23,12 @@
|
|
|
22
23
|
|
|
23
24
|
建议使用 `npm ci` 配合 npm lock,避免交替更新两种锁文件。包发布白名单包含构建产物、bundle patch、README、许可证与分析脚本,不包含测试、原始会话或调试捕获。`prepack` 自动构建;预发布默认 `next` tag。确认版本未占用后由维护者执行 `npm publish`;已发布版本不能覆盖。
|
|
24
25
|
|
|
26
|
+
## 作为 skill 分发(其他 agent 工具)
|
|
27
|
+
|
|
28
|
+
[`skills/batch-tool-calls/SKILL.md`](skills/batch-tool-calls/SKILL.md) 把规则直接写进 `description`:skill 目录里只有这一行描述常驻上下文,因此核心规则无需模型主动加载 skill 就可见;正文是同一规则的展开。复制该目录到支持 skill 的 agent 的 skills 目录即可。
|
|
29
|
+
|
|
30
|
+
边界:描述在目录中可能被截断,规则放在最前面;是否遵循取决于模型与工具对 skill 目录的处理,尚未在 DSH 之外验证。不支持 skill 的工具,可把正文复制进 `AGENTS.md` / `CLAUDE.md` 等常驻指令文件。
|
|
31
|
+
|
|
25
32
|
## 开发与安装
|
|
26
33
|
|
|
27
34
|
尚未发布 npm;已在本地 Web profile 链接安装并进行人工观察。一次探索任务出现连续多调用批次,但模型同时发生切换,不能据此归因于插件或宣称 token/费用节省。
|
|
@@ -40,11 +47,12 @@ npm pack --dry-run
|
|
|
40
47
|
|
|
41
48
|
```yaml
|
|
42
49
|
enabled: true
|
|
43
|
-
|
|
50
|
+
systemPromptSection: true # 默认;系统提示词通道
|
|
51
|
+
contextReminder: false # 默认;设为 true 启用 CONTEXT 提醒通道
|
|
44
52
|
presetIds: [standard]
|
|
45
53
|
```
|
|
46
54
|
|
|
47
|
-
**注意:profile 的 `cordis.patch.yml` 覆盖本插件时,`config` 是整体替换、不与 bundle 默认值深合并。** 覆盖项必须写全需要的字段(至少 `enabled: true`、`presetIds`),否则 `enabled` 回落为默认 `false
|
|
55
|
+
**注意:profile 的 `cordis.patch.yml` 覆盖本插件时,`config` 是整体替换、不与 bundle 默认值深合并。** 覆盖项必须写全需要的字段(至少 `enabled: true`、`presetIds`),否则 `enabled` 回落为默认 `false`,插件静默不注入。验收方式:系统提示词通道看新会话 `system/message` 中是否出现 `Tool-call scheduling:`;CONTEXT 通道看会话里是否出现 `source.kind` 为 `parallel-tools-scheduling` 的消息。
|
|
48
56
|
|
|
49
57
|
`presetIds` 是精确ID列表,不是正则。自定义目标仅适用于原生工具调用preset;不要把PTC加入以免对专用执行模式施加不合适的指导。根会话fork可以保留历史parentSession,不会仅因此被当作子智能体。
|
|
50
58
|
|
package/cordis.patch.yml
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Installing/enabling this bundle is the explicit opt-in. Direct plugin use
|
|
2
|
-
# defaults to enabled:false.
|
|
2
|
+
# defaults to enabled:false. Guidance goes into the system prompt by default;
|
|
3
|
+
# add `contextReminder: true` for the CONTEXT-message channel (or
|
|
4
|
+
# `systemPromptSection: false` to use only that channel). No preset replacement or scheduler changes.
|
|
3
5
|
- insert:
|
|
4
6
|
- id: parallel-tools-prompt
|
|
5
7
|
name: dsh-parallel-tools-prompt
|
|
6
8
|
config:
|
|
7
9
|
enabled: true
|
|
8
|
-
contextReminder: true
|
|
9
10
|
presetIds: [standard]
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "dsh-parallel-tools-prompt",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
"use strict";
|
|
8
|
+
var __defProp = Object.defineProperty;
|
|
9
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
10
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
11
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __export = (target, all) => {
|
|
13
|
+
for (var name in all)
|
|
14
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
15
|
+
};
|
|
16
|
+
var __copyProps = (to, from, except, desc) => {
|
|
17
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
|
+
for (let key of __getOwnPropNames(from))
|
|
19
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
20
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
25
|
+
|
|
26
|
+
// src/client/index.ts
|
|
27
|
+
var index_exports = {};
|
|
28
|
+
__export(index_exports, {
|
|
29
|
+
apply: () => apply,
|
|
30
|
+
inject: () => inject
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(index_exports);
|
|
33
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
34
|
+
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
35
|
+
var inject = ["slots", "locale", "configForms"];
|
|
36
|
+
var PACKAGE = "dsh-parallel-tools-prompt";
|
|
37
|
+
var NAMESPACE = "parallel-tools-prompt";
|
|
38
|
+
var LOCALE = "settings.parallelToolsPrompt";
|
|
39
|
+
var en = {
|
|
40
|
+
systemPrompt: "Inject into system prompt",
|
|
41
|
+
systemPromptHint: "Static guidance section in the system prompt (default on). Applies to sessions that assemble their prompt after the change.",
|
|
42
|
+
context: "Inject as context message",
|
|
43
|
+
contextHint: "One-time CONTEXT message delivered at the next step, kept in the session history.",
|
|
44
|
+
note: "Both can be on together; with both off the plugin injects nothing.",
|
|
45
|
+
unavailable: "The plugin is not loaded or its settings are not served, so it cannot be configured right now.",
|
|
46
|
+
readOnly: "This deployment stores settings read-only."
|
|
47
|
+
};
|
|
48
|
+
var zh = {
|
|
49
|
+
systemPrompt: "\u6CE8\u5165\u5230\u7CFB\u7EDF\u63D0\u793A\u8BCD",
|
|
50
|
+
systemPromptHint: "\u5728\u7CFB\u7EDF\u63D0\u793A\u8BCD\u4E2D\u52A0\u5165\u56FA\u5B9A\u7684\u8C03\u5EA6\u6307\u5F15\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF09\u3002\u5BF9\u4FEE\u6539\u4E4B\u540E\u91CD\u65B0\u7EC4\u88C5\u63D0\u793A\u8BCD\u7684\u4F1A\u8BDD\u751F\u6548\u3002",
|
|
51
|
+
context: "\u4EE5 CONTEXT \u6D88\u606F\u6CE8\u5165",
|
|
52
|
+
contextHint: "\u5728\u4E0B\u4E00\u6B65\u9AA4\u9001\u8FBE\u4E00\u6761 CONTEXT \u6D88\u606F\uFF0C\u5E76\u4FDD\u7559\u5728\u4F1A\u8BDD\u5386\u53F2\u4E2D\u3002",
|
|
53
|
+
note: "\u4E24\u8005\u53EF\u540C\u65F6\u5F00\u542F\uFF1B\u90FD\u5173\u95ED\u65F6\u63D2\u4EF6\u4E0D\u6CE8\u5165\u4EFB\u4F55\u5185\u5BB9\u3002",
|
|
54
|
+
unavailable: "\u63D2\u4EF6\u672A\u52A0\u8F7D\u6216\u5176\u8BBE\u7F6E\u672A\u63D0\u4F9B\uFF0C\u6682\u65F6\u65E0\u6CD5\u914D\u7F6E\u3002",
|
|
55
|
+
readOnly: "\u672C\u90E8\u7F72\u7684\u8BBE\u7F6E\u4E3A\u53EA\u8BFB\u3002"
|
|
56
|
+
};
|
|
57
|
+
var rowStyle = { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, padding: "10px 0" };
|
|
58
|
+
var hintStyle = { fontSize: 12, opacity: 0.7, marginTop: 2 };
|
|
59
|
+
function Row(props) {
|
|
60
|
+
return (0, import_jsx_runtime.jsxs)("div", {
|
|
61
|
+
style: rowStyle,
|
|
62
|
+
children: [
|
|
63
|
+
(0, import_jsx_runtime.jsxs)("div", { children: [(0, import_jsx_runtime.jsx)("div", { children: props.title }), (0, import_jsx_runtime.jsx)("div", { style: hintStyle, children: props.hint })] }),
|
|
64
|
+
(0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Switch, { checked: props.checked, label: props.title, disabled: props.disabled, onChange: props.onChange })
|
|
65
|
+
]
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function Card(props) {
|
|
69
|
+
const { t } = props;
|
|
70
|
+
const form = props.useConfig((view) => view);
|
|
71
|
+
if (form.status !== "ready") return (0, import_jsx_runtime.jsx)("div", { style: hintStyle, children: t("unavailable") });
|
|
72
|
+
const values = form.value ?? {};
|
|
73
|
+
const disabled = form.writable !== true;
|
|
74
|
+
return (0, import_jsx_runtime.jsxs)("div", {
|
|
75
|
+
children: [
|
|
76
|
+
Row({
|
|
77
|
+
title: t("systemPrompt"),
|
|
78
|
+
hint: t("systemPromptHint"),
|
|
79
|
+
disabled,
|
|
80
|
+
checked: values["systemPromptSection"] !== false,
|
|
81
|
+
onChange: (checked) => props.setField("systemPromptSection", checked)
|
|
82
|
+
}),
|
|
83
|
+
Row({
|
|
84
|
+
title: t("context"),
|
|
85
|
+
hint: t("contextHint"),
|
|
86
|
+
disabled,
|
|
87
|
+
checked: values["contextReminder"] === true,
|
|
88
|
+
onChange: (checked) => props.setField("contextReminder", checked)
|
|
89
|
+
}),
|
|
90
|
+
(0, import_jsx_runtime.jsx)("div", { style: hintStyle, children: disabled ? t("readOnly") : t("note") })
|
|
91
|
+
]
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function apply(ctx) {
|
|
95
|
+
ctx.effect(() => ctx.locale.register(LOCALE, { en, zh }));
|
|
96
|
+
const form = ctx.configForms.get(NAMESPACE);
|
|
97
|
+
const face = () => ({
|
|
98
|
+
hooks: { config: form },
|
|
99
|
+
setField: (field, value) => {
|
|
100
|
+
void form.set(field, value);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
ctx.effect(() => ctx.configForms.whileServed([NAMESPACE], () => ctx.slots.inject("plugins.bundle.config", () => ctx.slots.register({
|
|
104
|
+
name: "plugins.bundle.config",
|
|
105
|
+
key: PACKAGE,
|
|
106
|
+
locale: LOCALE,
|
|
107
|
+
inject: face
|
|
108
|
+
}, Card))));
|
|
109
|
+
}
|
|
110
|
+
return module.exports;
|
|
111
|
+
}
|
|
112
|
+
});
|
package/lib/index.d.ts
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
2
|
import z from '@deepseek-ai/schemastery';
|
|
3
|
-
export { PARALLEL_TOOLS_PROMPT, SECTION_NAME, SECTION_ORDER } from './prompt.js';
|
|
3
|
+
export { BATCH_RULE, PARALLEL_TOOLS_PROMPT, SECTION_NAME, SECTION_ORDER } from './prompt.js';
|
|
4
4
|
export declare const name = "parallel-tools-prompt";
|
|
5
5
|
export declare const inject: string[];
|
|
6
|
-
/**
|
|
7
|
-
export declare const
|
|
8
|
-
|
|
6
|
+
/** Model-facing text of the optional context-channel reminder. */
|
|
7
|
+
export declare const CONTEXT_REMINDER = "Every response: before answering, check what else the current subgoal already has ready and issue ALL ready, independent tool calls together in this one response \u2014 same-tool calls on different targets, parallel reads, independent searches and checks. Each response is one model round trip; issuing ready work one call at a time spends one round trip per call. Hold a call only for real dependencies: its arguments need an earlier result, read-before-edit, shared-file or approval ordering. A single call is fine when nothing else is ready; never invent calls to fill a batch.";
|
|
8
|
+
/** Source kind of the reminder message; the host renders unknown context kinds as CONTEXT blocks. */
|
|
9
|
+
export declare const CONTEXT_SOURCE_KIND = "parallel-tools-scheduling";
|
|
10
|
+
declare module '@deepseek-ai/dsh-llm' {
|
|
11
|
+
interface MessageSourceMap {
|
|
12
|
+
[CONTEXT_SOURCE_KIND]: {
|
|
13
|
+
kind: typeof CONTEXT_SOURCE_KIND;
|
|
14
|
+
form: 'notice';
|
|
15
|
+
summary: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
9
19
|
export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
10
20
|
debugEnabled: z<boolean, boolean, "defined">;
|
|
11
21
|
debugSessionId: z<string, string, "defined">;
|
|
12
22
|
debugOutputDir: z<string, string, "defined">;
|
|
13
23
|
debugMaxCalls: z<number, number, "defined">;
|
|
14
24
|
enabled: z<boolean, boolean, "defined">;
|
|
15
|
-
|
|
25
|
+
systemPromptSection: z<boolean, boolean, "volatile-defined">;
|
|
26
|
+
contextReminder: z<boolean, boolean, "volatile-defined">;
|
|
16
27
|
presetIds: z<string[], string[], "defined">;
|
|
17
28
|
}>>, Schemastery.ObjectT<NoInfer<{
|
|
18
29
|
debugEnabled: z<boolean, boolean, "defined">;
|
|
@@ -20,7 +31,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
20
31
|
debugOutputDir: z<string, string, "defined">;
|
|
21
32
|
debugMaxCalls: z<number, number, "defined">;
|
|
22
33
|
enabled: z<boolean, boolean, "defined">;
|
|
23
|
-
|
|
34
|
+
systemPromptSection: z<boolean, boolean, "volatile-defined">;
|
|
35
|
+
contextReminder: z<boolean, boolean, "volatile-defined">;
|
|
24
36
|
presetIds: z<string[], string[], "defined">;
|
|
25
37
|
}>>, "plain">;
|
|
26
38
|
export type Config = ReturnType<typeof Config>;
|
package/lib/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,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAMnD,OAAO,CAAC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAMnD,OAAO,CAAC,MAAM,0BAA0B,CAAC;AAKzC,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7F,eAAO,MAAM,IAAI,0BAA0B,CAAC;AAC5C,eAAO,MAAM,MAAM,UAAmD,CAAC;AAEvE,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,ykBAAokB,CAAC;AAElmB,qGAAqG;AACrG,eAAO,MAAM,mBAAmB,8BAA8B,CAAC;AAE/D,OAAO,QAAQ,sBAAsB,CAAC;IACpC,UAAU,gBAAgB;QACxB,CAAC,mBAAmB,CAAC,EAAE;YAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC;YAAC,IAAI,EAAE,QAAQ,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;KAC9F;CACF;AASD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;aAkBjB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AAuD/C,8EAA8E;AAC9E,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAyDxD"}
|
package/lib/index.js
CHANGED
|
@@ -2,29 +2,40 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
|
2
2
|
import z from '@deepseek-ai/schemastery';
|
|
3
3
|
import { PARALLEL_TOOLS_PROMPT, SECTION_NAME, SECTION_ORDER } from './prompt.js';
|
|
4
4
|
import { installPromptDebug } from './debug.js';
|
|
5
|
-
export { PARALLEL_TOOLS_PROMPT, SECTION_NAME, SECTION_ORDER } from './prompt.js';
|
|
5
|
+
export { BATCH_RULE, PARALLEL_TOOLS_PROMPT, SECTION_NAME, SECTION_ORDER } from './prompt.js';
|
|
6
6
|
export const name = 'parallel-tools-prompt';
|
|
7
7
|
export const inject = ['agents', 'systemPrompt', 'sessionProjections'];
|
|
8
|
-
/**
|
|
9
|
-
export const
|
|
10
|
-
|
|
8
|
+
/** Model-facing text of the optional context-channel reminder. */
|
|
9
|
+
export const CONTEXT_REMINDER = 'Every response: before answering, check what else the current subgoal already has ready and issue ALL ready, independent tool calls together in this one response — same-tool calls on different targets, parallel reads, independent searches and checks. Each response is one model round trip; issuing ready work one call at a time spends one round trip per call. Hold a call only for real dependencies: its arguments need an earlier result, read-before-edit, shared-file or approval ordering. A single call is fine when nothing else is ready; never invent calls to fill a batch.';
|
|
10
|
+
/** Source kind of the reminder message; the host renders unknown context kinds as CONTEXT blocks. */
|
|
11
|
+
export const CONTEXT_SOURCE_KIND = 'parallel-tools-scheduling';
|
|
12
|
+
/** True when the session transcript already carries our sourced reminder. */
|
|
13
|
+
function hasReminder(agent) {
|
|
14
|
+
return agent.session.snapshotEvents().some(event => event.type === 'user/message'
|
|
15
|
+
&& event.data?.source?.kind === CONTEXT_SOURCE_KIND);
|
|
16
|
+
}
|
|
11
17
|
export const Config = z.object({
|
|
12
18
|
debugEnabled: z.boolean().default(false).description('Capture normalized LLM system prompts locally, only with an explicit session and enable sentinel. Sensitive: disable after diagnosis.'),
|
|
13
19
|
debugSessionId: z.string().default(''),
|
|
14
20
|
debugOutputDir: z.string().default(''),
|
|
15
21
|
debugMaxCalls: z.natural().min(1).max(10).default(3),
|
|
16
22
|
enabled: z.boolean().default(false).description('Enable static tool-call scheduling guidance. The bundle explicitly opts in; direct plugin use is disabled by default.'),
|
|
17
|
-
|
|
23
|
+
systemPromptSection: z.boolean().default(true).volatile().description('Inject the static scheduling guidance as a system-prompt section (default true). May be combined with contextReminder; with both off the plugin injects nothing.'),
|
|
24
|
+
contextReminder: z.boolean().default(false).volatile().description('Inject a one-time scheduling reminder as a CONTEXT message at the next step boundary (default false). Persists in the session transcript; never duplicated across reloads. Independent of systemPromptSection.'),
|
|
18
25
|
presetIds: z.array(z.string().pattern(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/))
|
|
19
26
|
.max(32).default(['standard']).description('Exact preset IDs to target at agent creation. Root agents only; use native-tool presets, not PTC. An empty list disables all targets.'),
|
|
20
27
|
});
|
|
28
|
+
/** Read a switch live: volatile fields are references whose value may change without a reload. */
|
|
29
|
+
function flag(value) {
|
|
30
|
+
return typeof value === 'boolean' ? value : value.get();
|
|
31
|
+
}
|
|
21
32
|
/**
|
|
22
33
|
* Attach or re-attach the guidance section to one already-eligible live agent.
|
|
23
34
|
* Idempotent via the registration guard; shared by `agent/created` and
|
|
24
35
|
* reload-time catch-up, so a plugin reload cannot silently drop guidance from
|
|
25
36
|
* agents that survive it (the old instance's disposal removed its sections).
|
|
26
37
|
*/
|
|
27
|
-
function attach(ctx, agent, config, presetIds, registrations, active) {
|
|
38
|
+
function attach(ctx, agent, config, presetIds, registrations, active, reminderAgents) {
|
|
28
39
|
if (registrations.has(agent))
|
|
29
40
|
return;
|
|
30
41
|
const { header } = agent.session;
|
|
@@ -38,34 +49,24 @@ function attach(ctx, agent, config, presetIds, registrations, active) {
|
|
|
38
49
|
?? header.agentPreset;
|
|
39
50
|
if (preset === undefined || !presetIds.has(preset))
|
|
40
51
|
return;
|
|
41
|
-
// Conversation-level reminder:
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
if (config.contextReminder) {
|
|
45
|
-
try {
|
|
46
|
-
const already = agent.session.snapshotEvents().some(event => event.type === 'user/message' && JSON.stringify(event.data?.content ?? '').includes(CONTEXT_MARKER));
|
|
47
|
-
if (!already) {
|
|
48
|
-
agent.inject(createUserMessage({
|
|
49
|
-
content: [{ type: 'text', text: CONTEXT_REMINDER }],
|
|
50
|
-
source: { kind: 'user' },
|
|
51
|
-
}));
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
catch { /* reminder must never break attach */ }
|
|
55
|
-
}
|
|
52
|
+
// Conversation-level reminder: appended by the pre-step listener below once
|
|
53
|
+
// this agent is eligible (agent.inject only accepts user-kind messages).
|
|
54
|
+
reminderAgents.add(agent);
|
|
56
55
|
const registration = {};
|
|
57
56
|
// Returning the disposer is essential: ctx.effect does not implicitly adopt
|
|
58
57
|
// arbitrary registrations executed inside its callback on another fiber.
|
|
59
58
|
registration.release = agent.ctx.effect(() => {
|
|
59
|
+
// Registered unconditionally; the text is resolved at assembly time, so the
|
|
60
|
+
// switch applies the next time the host assembles a system prompt.
|
|
60
61
|
const disposeSection = agent.ctx.systemPrompt.section({
|
|
61
62
|
name: SECTION_NAME,
|
|
62
63
|
order: SECTION_ORDER,
|
|
63
64
|
interpolate: false,
|
|
64
|
-
text: PARALLEL_TOOLS_PROMPT,
|
|
65
|
+
text: () => (flag(config.systemPromptSection) ? PARALLEL_TOOLS_PROMPT : ''),
|
|
65
66
|
});
|
|
66
67
|
return () => {
|
|
67
68
|
try {
|
|
68
|
-
return disposeSection();
|
|
69
|
+
return disposeSection?.();
|
|
69
70
|
}
|
|
70
71
|
finally {
|
|
71
72
|
registrations.delete(agent);
|
|
@@ -87,6 +88,7 @@ export function apply(ctx, config) {
|
|
|
87
88
|
const presetIds = new Set(config.presetIds);
|
|
88
89
|
const registrations = new WeakMap();
|
|
89
90
|
const active = new Set();
|
|
91
|
+
const reminderAgents = new WeakSet();
|
|
90
92
|
// Agent contexts are not children of this plugin's fiber. Explicitly give the
|
|
91
93
|
// plugin ownership of their effect disposers as well as agent-local ownership.
|
|
92
94
|
ctx.effect(() => async () => {
|
|
@@ -94,8 +96,32 @@ export function apply(ctx, config) {
|
|
|
94
96
|
await registration.release?.();
|
|
95
97
|
active.clear();
|
|
96
98
|
});
|
|
99
|
+
// Same channel the host's own context plugins (e.g. time-context) use: after
|
|
100
|
+
// downstream listeners accept the step, append one sourced message to the
|
|
101
|
+
// step's messages; the host persists it and renders it as a CONTEXT block.
|
|
102
|
+
{
|
|
103
|
+
const delivered = new WeakSet();
|
|
104
|
+
ctx.on('agent/pre-step', async ({ agent, signal }, next) => {
|
|
105
|
+
const decision = await next();
|
|
106
|
+
if (decision.kind === 'reject' || signal.aborted)
|
|
107
|
+
return decision;
|
|
108
|
+
if (!flag(config.contextReminder) || !reminderAgents.has(agent) || delivered.has(agent))
|
|
109
|
+
return decision;
|
|
110
|
+
const present = hasReminder(agent) || decision.messages.some(m => m.source.kind === CONTEXT_SOURCE_KIND);
|
|
111
|
+
delivered.add(agent);
|
|
112
|
+
if (present)
|
|
113
|
+
return decision;
|
|
114
|
+
return {
|
|
115
|
+
...decision,
|
|
116
|
+
messages: [...decision.messages, createUserMessage({
|
|
117
|
+
content: [{ type: 'text', text: CONTEXT_REMINDER }],
|
|
118
|
+
source: { kind: CONTEXT_SOURCE_KIND, form: 'notice', summary: 'Parallel tool-call scheduling reminder' },
|
|
119
|
+
})],
|
|
120
|
+
};
|
|
121
|
+
}, { prepend: true });
|
|
122
|
+
}
|
|
97
123
|
ctx.on('agent/created', ({ agent }) => {
|
|
98
|
-
attach(ctx, agent, config, presetIds, registrations, active);
|
|
124
|
+
attach(ctx, agent, config, presetIds, registrations, active, reminderAgents);
|
|
99
125
|
});
|
|
100
126
|
// A plugin reload disposes the previous instance's section registrations, and
|
|
101
127
|
// the host does not replay `agent/created` for agents that stay alive. Attach
|
|
@@ -106,7 +132,7 @@ export function apply(ctx, config) {
|
|
|
106
132
|
// previous instance's disposal. The no-op disposer satisfies the effect
|
|
107
133
|
// contract; per-agent cleanup is owned by each registration instead.
|
|
108
134
|
for (const agent of ctx.agents.roots())
|
|
109
|
-
attach(ctx, agent, config, presetIds, registrations, active);
|
|
135
|
+
attach(ctx, agent, config, presetIds, registrations, active, reminderAgents);
|
|
110
136
|
return () => { };
|
|
111
137
|
});
|
|
112
138
|
}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,CAAC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,CAAC,MAAM,0BAA0B,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7F,MAAM,CAAC,MAAM,IAAI,GAAG,uBAAuB,CAAC;AAC5C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,cAAc,EAAE,oBAAoB,CAAC,CAAC;AAEvE,kEAAkE;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAG,ikBAAikB,CAAC;AAElmB,qGAAqG;AACrG,MAAM,CAAC,MAAM,mBAAmB,GAAG,2BAA2B,CAAC;AAQ/D,6EAA6E;AAC7E,SAAS,WAAW,CAAC,KAAY;IAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACjD,KAAK,CAAC,IAAI,KAAK,cAAc;WACzB,KAAK,CAAC,IAAmD,EAAE,MAAM,EAAE,IAAI,KAAK,mBAAmB,CAAC,CAAC;AACzG,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,uIAAuI,CAAC;IAC7L,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACtC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACtC,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACpD,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAC7C,uHAAuH,CACxH;IACD,mBAAmB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,WAAW,CACnE,kKAAkK,CACnK;IACD,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,WAAW,CAChE,gNAAgN,CACjN;IACD,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;SACzE,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CACxC,uIAAuI,CACxI;CACJ,CAAC,CAAC;AAIH,kGAAkG;AAClG,SAAS,IAAI,CAAC,KAAkC;IAC9C,OAAO,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;AAC1D,CAAC;AAID;;;;;GAKG;AACH,SAAS,MAAM,CAAC,GAAY,EAAE,KAAY,EAAE,MAAc,EAAE,SAAsB,EAAE,aAA2C,EAAE,MAAyB,EAAE,cAA8B;IACxL,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO;IACrC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IACjC,yEAAyE;IACzE,4EAA4E;IAC5E,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,CAAC;QAAE,OAAO;IAC9E,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO;IAChD,MAAM,MAAM,GAAG,GAAG,CAAC,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC;WACtE,MAAM,CAAC,WAAW,CAAC;IACxB,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO;IAE3D,4EAA4E;IAC5E,yEAAyE;IACzE,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAE1B,MAAM,YAAY,GAAiB,EAAE,CAAC;IACtC,4EAA4E;IAC5E,yEAAyE;IACzE,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE;QAC3C,4EAA4E;QAC5E,mEAAmE;QACnE,MAAM,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC;YACpD,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,aAAa;YACpB,WAAW,EAAE,KAAK;YAClB,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,IAAI,CAAC;gBACH,OAAO,cAAc,EAAE,EAAE,CAAC;YAC5B,CAAC;oBAAS,CAAC;gBACT,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAC3B,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,MAAc;IAChD,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,kBAAkB,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,cAAc;YACvE,SAAS,EAAE,MAAM,CAAC,cAAc,EAAE,QAAQ,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO;IAE5B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,IAAI,OAAO,EAAuB,CAAC;IACzD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgB,CAAC;IACvC,MAAM,cAAc,GAAG,IAAI,OAAO,EAAS,CAAC;IAE5C,8EAA8E;IAC9E,+EAA+E;IAC/E,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;QAC1B,KAAK,MAAM,YAAY,IAAI,CAAC,GAAG,MAAM,CAAC;YAAE,MAAM,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;QACvE,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;IAGH,6EAA6E;IAC7E,0EAA0E;IAC1E,2EAA2E;IAC3E,CAAC;QACC,MAAM,SAAS,GAAG,IAAI,OAAO,EAAS,CAAC;QACvC,GAAG,CAAC,EAAE,CAAC,gBAAgB,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE;YACzD,MAAM,QAAQ,GAAG,MAAM,IAAI,EAAE,CAAC;YAC9B,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,QAAQ,CAAC;YAClE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,OAAO,QAAQ,CAAC;YACzG,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,mBAAmB,CAAC,CAAC;YACzG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,OAAO;gBAAE,OAAO,QAAQ,CAAC;YAC7B,OAAO;gBACL,GAAG,QAAQ;gBACX,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;wBACjD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;wBACnD,MAAM,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,wCAAwC,EAAE;qBACzG,CAAC,CAAC;aACJ,CAAC;QACJ,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,GAAG,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,EAAa,EAAE;QAC/C,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,8EAA8E;IAC9E,2EAA2E;IAC3E,6DAA6D;IAC7D,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE;QACd,wEAAwE;QACxE,wEAAwE;QACxE,qEAAqE;QACrE,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE;YAAE,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACrH,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/lib/prompt.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/** Stable prompt bytes: no runtime interpolation, tool inventory, or per-turn state. */
|
|
2
2
|
export declare const SECTION_NAME = "parallel-tools:guidance";
|
|
3
3
|
export declare const SECTION_ORDER = 1050;
|
|
4
|
-
|
|
4
|
+
/** Single source of truth: also the description of skills/batch-tool-calls/SKILL.md (a test keeps them identical). */
|
|
5
|
+
export declare const BATCH_RULE = "Before every response that uses tools, (1) list what the current subgoal already has ready, (2) issue ALL ready, independent calls together in one response (parallel reads, searches, checks), (3) split only for real dependencies (needs an earlier result, read-before-edit, shared-file or approval order). One call per response wastes a model round trip; a single call is fine when nothing else is ready, so never invent calls to fill a batch. No planning-only turn, no shell wrappers or delegation to simulate batching.";
|
|
6
|
+
/** The "Tool-call scheduling:" prefix is the verification marker searched for in system/message. */
|
|
7
|
+
export declare const PARALLEL_TOOLS_PROMPT = "Tool-call scheduling: Before every response that uses tools, (1) list what the current subgoal already has ready, (2) issue ALL ready, independent calls together in one response (parallel reads, searches, checks), (3) split only for real dependencies (needs an earlier result, read-before-edit, shared-file or approval order). One call per response wastes a model round trip; a single call is fine when nothing else is ready, so never invent calls to fill a batch. No planning-only turn, no shell wrappers or delegation to simulate batching.";
|
|
5
8
|
//# sourceMappingURL=prompt.d.ts.map
|
package/lib/prompt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,eAAO,MAAM,YAAY,4BAA4B,CAAC;AACtD,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,eAAO,MAAM,YAAY,4BAA4B,CAAC;AACtD,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC,sHAAsH;AACtH,eAAO,MAAM,UAAU,4gBAA4gB,CAAC;AAEpiB,oGAAoG;AACpG,eAAO,MAAM,qBAAqB,kiBAAwC,CAAC"}
|
package/lib/prompt.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/** Stable prompt bytes: no runtime interpolation, tool inventory, or per-turn state. */
|
|
2
2
|
export const SECTION_NAME = 'parallel-tools:guidance';
|
|
3
3
|
export const SECTION_ORDER = 1050;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
- Several calls in one response do not force simultaneous execution; the host scheduler, permissions, and all safety rules still apply.`;
|
|
4
|
+
/** Single source of truth: also the description of skills/batch-tool-calls/SKILL.md (a test keeps them identical). */
|
|
5
|
+
export const BATCH_RULE = `Before every response that uses tools, (1) list what the current subgoal already has ready, (2) issue ALL ready, independent calls together in one response (parallel reads, searches, checks), (3) split only for real dependencies (needs an earlier result, read-before-edit, shared-file or approval order). One call per response wastes a model round trip; a single call is fine when nothing else is ready, so never invent calls to fill a batch. No planning-only turn, no shell wrappers or delegation to simulate batching.`;
|
|
6
|
+
/** The "Tool-call scheduling:" prefix is the verification marker searched for in system/message. */
|
|
7
|
+
export const PARALLEL_TOOLS_PROMPT = `Tool-call scheduling: ${BATCH_RULE}`;
|
|
9
8
|
//# sourceMappingURL=prompt.js.map
|
package/lib/prompt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,CAAC,MAAM,YAAY,GAAG,yBAAyB,CAAC;AACtD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAElC,MAAM,CAAC,MAAM,qBAAqB,GAAG
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,CAAC,MAAM,YAAY,GAAG,yBAAyB,CAAC;AACtD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAElC,sHAAsH;AACtH,MAAM,CAAC,MAAM,UAAU,GAAG,ygBAAygB,CAAC;AAEpiB,oGAAoG;AACpG,MAAM,CAAC,MAAM,qBAAqB,GAAG,yBAAyB,UAAU,EAAE,CAAC"}
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-parallel-tools-prompt",
|
|
3
|
-
"version": "0.2.1-rc.
|
|
3
|
+
"version": "0.2.1-rc.4",
|
|
4
4
|
"description": "Plan ready tool-call batches to reduce model round trips in DeepSeek Harness",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
"types": "./lib/index.d.ts",
|
|
21
21
|
"import": "./lib/index.js"
|
|
22
22
|
},
|
|
23
|
+
"./client": "./lib/client.js",
|
|
24
|
+
"./locale/*.json": "./locale/*.json",
|
|
23
25
|
"./package.json": "./package.json"
|
|
24
26
|
},
|
|
25
|
-
"files": ["lib", "cordis.patch.yml", "README.md", "LICENSE", "scripts/analyze-session.mjs"],
|
|
27
|
+
"files": ["lib", "locale", "cordis.patch.yml", "README.md", "LICENSE", "skills", "scripts/analyze-session.mjs"],
|
|
26
28
|
"engines": {
|
|
27
29
|
"node": ">=24.9.0",
|
|
28
30
|
"dsh": ">=0.2.1-rc.3"
|
|
@@ -30,10 +32,18 @@
|
|
|
30
32
|
"dsh": {
|
|
31
33
|
"bundle": {
|
|
32
34
|
"patch": "./cordis.patch.yml"
|
|
35
|
+
},
|
|
36
|
+
"client": {
|
|
37
|
+
"inject": [
|
|
38
|
+
"@deepseek-ai/dsh-client-locale",
|
|
39
|
+
"@deepseek-ai/dsh-client-ui-settings",
|
|
40
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager"
|
|
41
|
+
],
|
|
42
|
+
"platform": "web"
|
|
33
43
|
}
|
|
34
44
|
},
|
|
35
45
|
"scripts": {
|
|
36
|
-
"build": "tsc -p tsconfig.build.json",
|
|
46
|
+
"build": "tsc -p tsconfig.build.json && node scripts/build-client.mjs",
|
|
37
47
|
"typecheck": "tsc --noEmit",
|
|
38
48
|
"test": "vitest run",
|
|
39
49
|
"prepack": "npm run build"
|
|
@@ -61,6 +71,7 @@
|
|
|
61
71
|
"@deepseek-ai/cordis-plugin-loader": "1.0.6",
|
|
62
72
|
"@types/node": "^24.0.0",
|
|
63
73
|
"@types/js-yaml": "^4.0.9",
|
|
74
|
+
"esbuild": "^0.28.2",
|
|
64
75
|
"js-yaml": "^4.1.1",
|
|
65
76
|
"typescript": "^5.9.3",
|
|
66
77
|
"vitest": "^4.1.0"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: batch-tool-calls
|
|
3
|
+
description: "Before every response that uses tools, (1) list what the current subgoal already has ready, (2) issue ALL ready, independent calls together in one response (parallel reads, searches, checks), (3) split only for real dependencies (needs an earlier result, read-before-edit, shared-file or approval order). One call per response wastes a model round trip; a single call is fine when nothing else is ready, so never invent calls to fill a batch. No planning-only turn, no shell wrappers or delegation to simulate batching."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Batch ready tool calls
|
|
7
|
+
|
|
8
|
+
Each response is one model round trip. Issuing ready work one call at a time spends one round trip per call.
|
|
9
|
+
|
|
10
|
+
Before each response:
|
|
11
|
+
|
|
12
|
+
1. Check what else the current subgoal already has ready: same-tool calls on different targets, parallel reads, independent searches and checks.
|
|
13
|
+
2. Issue every ready, independent call together in this one response.
|
|
14
|
+
3. Hold a call only for real dependencies: its arguments need an earlier result, read-before-edit, shared-file or approval ordering.
|
|
15
|
+
4. A single call is fine when nothing else is ready. Never invent calls to fill a batch.
|
|
16
|
+
|
|
17
|
+
Plan the next batch after the results return; do not add a separate planning round.
|