@deepseek-ai/dsh-tool-goal 0.0.1-rc.1
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/LICENSE +28 -0
- package/README.i18n.yaml +6 -0
- package/README.md +80 -0
- package/README.zh.md +80 -0
- package/lib/index.js +372 -0
- package/lib/invariant.js +23 -0
- package/lib/types/authority.d.ts +44 -0
- package/lib/types/index.d.ts +19 -0
- package/lib/types/invariant.d.ts +16 -0
- package/lib/types/wrapup.d.ts +12 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, DeepSeek
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/goal/tool-goal/README.md
|
|
5
|
+
README.md: b93da1ced1cfbea0b4cdc2a7e253b9a515e75b21
|
|
6
|
+
README.zh.md: 2c813c6406b170f93ee0b90939904d3570425ec3
|
package/README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-tool-goal
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
The model-facing control surface for [`ctx.goals`](../goal/README.md): `get_goal`, `create_goal`, and `update_goal`. The [goal-tool Agent Note](../../../.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.md) owns the authority split and Codex-shaped UX.
|
|
6
|
+
|
|
7
|
+
## Tools
|
|
8
|
+
|
|
9
|
+
- `get_goal()` returns the current goal or `null`, including the compare-and-set id/revision, durable phase, admitted/capped goal rounds, any blocker reason, and current process-local activation.
|
|
10
|
+
- `create_goal(objective, max_goal_rounds?)` creates one goal from a direct top-level human turn. The model may infer long-running goal intent without an exact command phrase; non-human turns and subagents are rejected at execution.
|
|
11
|
+
- `update_goal(goal_id, revision, action, objective?, max_goal_rounds?, blocked_reason?)` supports `edit`, `pause`, `resume`, `complete`, and `blocked`. Replacements belong only to `edit`; `blocked_reason` is required only for `blocked` and is persisted with the stable code `model-reported`. Strict-schema empty-string and zero fillers count as omitted, while meaningful values remain limited to their action.
|
|
12
|
+
|
|
13
|
+
All calls are exclusive, so a model-ordered batch observes earlier mutations and their new revisions. UI clients receive pure generic cards: read for `get_goal`, other for mutations. Mutation cards select the first meaningful action value and otherwise show the goal id, so accepted fillers never produce blank input.
|
|
14
|
+
|
|
15
|
+
All three canonical values match the compact JSON already rendered to Native callers: `{ goal: null }` or `{ goal: { id, revision, objective, phase, roundsStarted, maxGoalRounds, blockedReason? }, activation }`. Programmatic consumers therefore receive the same domain structure without parsing the rendered JSON.
|
|
16
|
+
|
|
17
|
+
An autonomous goal round that successfully reports `complete` or `blocked` marks that tool execution with `concludeTurn()` so the physical turn stops after the step. Direct-human mutations never contribute this stop: the assistant may acknowledge the change and concurrent human steering remains available to the loop.
|
|
18
|
+
|
|
19
|
+
## Authority
|
|
20
|
+
|
|
21
|
+
Execution requires the exact live `exec.agent`, its inherited `AgentRegistry` initiator, running status, and an open turn. Create, edit, pause, and resume additionally require an accepted `{ kind: 'user' }` message or steering event in a runtime-root agent's current turn. Durable fork lineage does not demote a resumed root; live subagent ownership does.
|
|
22
|
+
|
|
23
|
+
`{ kind: 'user' }` is a host attestation. `Agent.followup()` and `steer()` assign it when their caller omits a source, so plugins, schedulers, and other non-human producers must pass their own source rather than inheriting human authority.
|
|
24
|
+
|
|
25
|
+
Complete and blocked also accept the exact current goal round: a goal-sourced `user/message` whose id, revision, and round equal the folded current goal. A goal-round blocked call is mechanically rejected until `blockedAfterConsecutiveRounds`; the model judges whether the same condition actually persisted and must describe it in `blocked_reason`. Direct human authority may stop a goal immediately.
|
|
26
|
+
|
|
27
|
+
## Config
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
- id: tool-goal
|
|
31
|
+
name: '@deepseek-ai/dsh-tool-goal'
|
|
32
|
+
config:
|
|
33
|
+
blockedAfterConsecutiveRounds: 3
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The value must be a positive safe integer. It supplies both the hard lower bound on model self-blocking and the number named in model guidance.
|
|
37
|
+
|
|
38
|
+
## Model Experience
|
|
39
|
+
|
|
40
|
+
### System prompt
|
|
41
|
+
|
|
42
|
+
#### What the model sees
|
|
43
|
+
|
|
44
|
+
A fixed goal policy says when semantic human intent warrants creation, requires exact read-before-update refs, explains rearming after resume/fork, and limits completion/blocking claims. The configured threshold is interpolated into that guidance.
|
|
45
|
+
|
|
46
|
+
##### Goal policy
|
|
47
|
+
|
|
48
|
+
```markdown
|
|
49
|
+
Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
#### Token effect
|
|
53
|
+
|
|
54
|
+
Small fixed input cost on every request where this plugin's prompt registration is in scope.
|
|
55
|
+
|
|
56
|
+
#### KV Cache effect
|
|
57
|
+
|
|
58
|
+
Prefix-stable while the plugin scope, configured threshold, and guidance text are unchanged. Activation, disposal, or configuration changes may invalidate reuse from this prompt section.
|
|
59
|
+
|
|
60
|
+
### Tool schemas and results
|
|
61
|
+
|
|
62
|
+
#### What the model sees
|
|
63
|
+
|
|
64
|
+
The generated [`get_goal`, `create_goal`, and `update_goal` schemas](../../../docs/tool-catalog.md#deepseek-aidsh-tool-goal). Successful results are compact JSON. A mutation appends the goal domain's durable `goal/change` event without queuing model context. `activation` in a result is a live observation and never becomes replay authority.
|
|
65
|
+
|
|
66
|
+
#### Token effect
|
|
67
|
+
|
|
68
|
+
Fixed schema cost plus one compact result per call. The durable mutation adds no separate model-visible context.
|
|
69
|
+
|
|
70
|
+
#### KV Cache effect
|
|
71
|
+
|
|
72
|
+
Schemas are prefix-stable while their definitions and visibility are unchanged. Calls and results append after the reusable request prefix without invalidating earlier entries.
|
|
73
|
+
|
|
74
|
+
## Known Limitations and Deferred Work
|
|
75
|
+
|
|
76
|
+
- **Semantic intent remains model judgment** — execution can prove that the current turn contains a direct human message, not whether the request is substantial enough to merit a goal.
|
|
77
|
+
- **Same-condition blocking remains model judgment** — the runtime enforces distinct admitted-round count, not semantic equivalence of obstacles; an independent evaluator is deferred.
|
|
78
|
+
- **No scheduling or direct human rendering** — these tools mutate state only; the same-session driver and [`dsh-command-goal`](../command-goal/README.md) are independent consumers of the same domain.
|
|
79
|
+
- **Goal-round authority requires a driver** — the autonomous `complete`/`blocked` path is dormant unless a continuation driver admits goal-sourced user turns; mounting this tool package alone does not create them.
|
|
80
|
+
- **Prompt registration is independent of filtering** — a scope may hide the tools while retaining their guidance unless the deployment scopes both registrations together.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-tool-goal
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
[`ctx.goals`](../goal/README.md) 的面向模型控制接口:`get_goal`、`create_goal` 和 `update_goal`。[goal 工具 Agent Note](../../../.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.md) 负责权限拆分与 Codex 风格用户体验。
|
|
6
|
+
|
|
7
|
+
## 工具
|
|
8
|
+
|
|
9
|
+
- `get_goal()` 返回当前 goal 或 `null`,包括比较并设置 id/revision、持久 phase、Goal Round 的已准入数/上限、任何 blocker reason,以及当前进程本地续行启用状态。
|
|
10
|
+
- `create_goal(objective, max_goal_rounds?)` 根据顶层人类直接发起的轮次创建一个 goal。模型可以推断长期运行的 goal 意图,而无需精确命令短语;非人类轮次和 subagent 会在执行时被拒绝。
|
|
11
|
+
- `update_goal(goal_id, revision, action, objective?, max_goal_rounds?, blocked_reason?)` 支持 `edit`、`pause`、`resume`、`complete` 和 `blocked`。替换值只属于 `edit`;`blocked_reason` 只有在 action 为 `blocked` 时才必填,并以稳定代码 `model-reported` 持久化。严格 schema 下的空字符串和零填充值视为省略,而有意义的值仍限定到各自 action。
|
|
12
|
+
|
|
13
|
+
所有调用都互斥,因此模型排序的批次能观察到更早变更及其新 revision。UI 客户端会收到纯通用卡片:`get_goal` 使用 read,变更使用 other。变更卡片选择第一个有意义的 action 值,否则显示 goal id,因此已接受的填充值绝不会产生空输入。
|
|
14
|
+
|
|
15
|
+
3 个规范值都与已经渲染给 Native 调用方的紧凑 JSON 一致:`{ goal: null }` 或 `{ goal: { id, revision, objective, phase, roundsStarted, maxGoalRounds, blockedReason? }, activation }`。因此,编程消费方无需解析渲染后的 JSON,即可收到相同领域结构。
|
|
16
|
+
|
|
17
|
+
自主 Goal Round 成功报告 `complete` 或 `blocked` 时,会用 `concludeTurn()` 标记该次工具执行,使物理轮次在该步骤后停止。人类直接变更绝不会导致这种停止:assistant 可以确认变更,循环仍可接收并发的人类 steering(中途引导)。
|
|
18
|
+
|
|
19
|
+
## 权限
|
|
20
|
+
|
|
21
|
+
执行要求完全相同的活跃 `exec.agent`、其继承的 `AgentRegistry` initiator、running 状态与开放轮次。create、edit、pause 和 resume 还要求运行时根 agent(智能体)的当前轮次中存在已接受的 `{ kind: 'user' }` 消息或 steering 事件。持久 fork 谱系不会降低已恢复根 agent 的等级;活跃 subagent 所有权会降低。
|
|
22
|
+
|
|
23
|
+
`{ kind: 'user' }` 是宿主证明。`Agent.followup()` 与 `steer()` 会在调用方省略 source 时分配该值,因此插件、调度器与其他非人类生产方必须传入自己的 source,不能继承用户权限。
|
|
24
|
+
|
|
25
|
+
complete 与 blocked 还接受完全一致的当前 Goal Round:来源为 goal 的 `user/message`,其 id、revision 和 Round 编号与折叠后的当前 goal 相等。在达到 `blockedAfterConsecutiveRounds` 前,Goal Round 的 blocked 调用会被机械拒绝;模型判断同一条件是否确实持续,并必须在 `blocked_reason` 中说明。人类直接授权可以立即停止 goal。
|
|
26
|
+
|
|
27
|
+
## 配置
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
- id: tool-goal
|
|
31
|
+
name: '@deepseek-ai/dsh-tool-goal'
|
|
32
|
+
config:
|
|
33
|
+
blockedAfterConsecutiveRounds: 3
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
该值必须是正的安全整数。它既提供模型自行报告阻塞的硬下限,也决定模型指引中指明的数值。
|
|
37
|
+
|
|
38
|
+
## 模型体验
|
|
39
|
+
|
|
40
|
+
### 系统提示词
|
|
41
|
+
|
|
42
|
+
#### 模型看到的内容
|
|
43
|
+
|
|
44
|
+
固定 goal 策略说明何种用户语义意图值得创建 goal,要求更新前先精确读取 ref,解释会话 resume/fork 后如何重新启用续行,并限制完成/阻塞声明。配置的阈值会插入该指引。
|
|
45
|
+
|
|
46
|
+
##### Goal 策略
|
|
47
|
+
|
|
48
|
+
```markdown
|
|
49
|
+
Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
#### Token 影响
|
|
53
|
+
|
|
54
|
+
此插件的提示词注册位于请求范围内时,每次请求都会产生少量固定输入成本。
|
|
55
|
+
|
|
56
|
+
#### KV Cache 影响
|
|
57
|
+
|
|
58
|
+
插件范围、配置阈值和指引文本不变时,前缀保持稳定。启用、dispose(资源释放)或配置变更可能使此提示词章节的复用失效。
|
|
59
|
+
|
|
60
|
+
### 工具 schema 与结果
|
|
61
|
+
|
|
62
|
+
#### 模型看到的内容
|
|
63
|
+
|
|
64
|
+
生成的 [`get_goal`、`create_goal` 和 `update_goal` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-goal)。成功结果是紧凑 JSON。变更会追加 goal 领域的持久 `goal/change` 事件,而不会把模型上下文排队。结果中的 `activation` 是实时观察值,绝不会成为回放权限依据。
|
|
65
|
+
|
|
66
|
+
#### Token 影响
|
|
67
|
+
|
|
68
|
+
固定 schema 成本,加上每次调用的一条紧凑结果。持久变更不会增加单独的模型可见上下文。
|
|
69
|
+
|
|
70
|
+
#### KV Cache 影响
|
|
71
|
+
|
|
72
|
+
schema 的定义与可见性不变时,前缀保持稳定。调用和结果会追加到可复用请求前缀之后,不会使更早条目失效。
|
|
73
|
+
|
|
74
|
+
## 已知限制与暂缓事项
|
|
75
|
+
|
|
76
|
+
- **语义意图仍由模型判断**:执行只能证明当前轮次包含一条人类直接发送的消息,无法证明请求是否足够重大而值得创建 goal。
|
|
77
|
+
- **阻塞条件是否相同仍由模型判断**:运行时强制统计互不重复的已准入 Goal Round,而不判断障碍在语义上是否等价;独立评估器的实现暂缓。
|
|
78
|
+
- **不负责调度或直接面向人类呈现**:这些工具只变更状态;同会话驱动器与 [`dsh-command-goal`](../command-goal/README.md) 是同一领域的独立消费方。
|
|
79
|
+
- **Goal Round 权限需要驱动器**:除非续行驱动器准入 goal 来源的用户轮次,否则自主 `complete`/`blocked` 路径不会启用;只挂载这个包不会创建这些轮次。
|
|
80
|
+
- **提示词注册与过滤相互独立**:某个范围可能隐藏工具,却保留指引,除非部署将两项注册限定在同一范围。
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
import { GoalId } from "@deepseek-ai/dsh-goal";
|
|
3
|
+
import { HarnessError, boundContextSummary, createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
4
|
+
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
5
|
+
//#region lib/types/authority.js
|
|
6
|
+
/** Execution-time authority checks for the model-facing goal tools. */
|
|
7
|
+
/** Throw one structured tool-policy failure. */
|
|
8
|
+
function reject(message, code = "GOAL_TOOL_AUTHORITY_REQUIRED") {
|
|
9
|
+
throw new HarnessError(message, code);
|
|
10
|
+
}
|
|
11
|
+
/** Locate the open turn enclosing a model tool call. */
|
|
12
|
+
function openTurn(agent) {
|
|
13
|
+
const events = agent.session.events;
|
|
14
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
15
|
+
const boundary = events[index];
|
|
16
|
+
if (boundary?.type === "turn/end") reject("goal tools require an open model turn", "GOAL_TOOL_DRIVER_REQUIRED");
|
|
17
|
+
if (boundary?.type === "turn/start") return {
|
|
18
|
+
start: boundary,
|
|
19
|
+
events: events.slice(index + 1)
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return reject("goal tools require an open model turn", "GOAL_TOOL_DRIVER_REQUIRED");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolve and authenticate the calling agent and its driver boundary.
|
|
26
|
+
* @param ctx - Context carrying the live agent registry.
|
|
27
|
+
* @param exec - Tool execution metadata supplied by the registry.
|
|
28
|
+
* @returns The authenticated agent and its current turn window.
|
|
29
|
+
*/
|
|
30
|
+
function goalToolExecution(ctx, exec) {
|
|
31
|
+
const agent = exec.agent;
|
|
32
|
+
if (agent === void 0) return reject("goal tools require a calling agent", "GOAL_TOOL_AGENT_REQUIRED");
|
|
33
|
+
if (ctx.agents.get(agent.id) !== agent || agent.status !== "running" || ctx.agents.currentInitiator() !== agent) return reject("goal tools require the exact live calling agent inside its active driver", "GOAL_TOOL_DRIVER_REQUIRED");
|
|
34
|
+
return {
|
|
35
|
+
agent,
|
|
36
|
+
...openTurn(agent)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Whether host-attested human input appears in the current root-agent turn.
|
|
41
|
+
* An omitted `Agent.followup()` / `steer()` source resolves to `user`, so non-human
|
|
42
|
+
* producers must supply their own source rather than inheriting this authority.
|
|
43
|
+
*/
|
|
44
|
+
function hasDirectHumanInput(ctx, execution) {
|
|
45
|
+
if (!ctx.agents.roots().includes(execution.agent)) return false;
|
|
46
|
+
return execution.events.some((event) => event.type === "user/message" && event.data.source.kind === "user");
|
|
47
|
+
}
|
|
48
|
+
/** Whether this turn is the current goal's exact admitted round. */
|
|
49
|
+
function isMatchingGoalRound(execution, goal) {
|
|
50
|
+
return execution.events.some((event) => event.type === "user/message" && event.data.source.kind === "goal" && event.data.source.goalId === goal.id && event.data.source.revision === goal.revision && event.data.source.round === goal.roundsStarted);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Require authority originating in a human message accepted by a runtime root.
|
|
54
|
+
* @param ctx - Context carrying the live agent graph.
|
|
55
|
+
* @param execution - Authenticated current tool execution.
|
|
56
|
+
*/
|
|
57
|
+
function requireDirectHuman(ctx, execution) {
|
|
58
|
+
if (hasDirectHumanInput(ctx, execution)) return;
|
|
59
|
+
reject("this goal operation requires a direct human turn on a top-level agent");
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Resolve completion authority from either direct human input or the exact goal round.
|
|
63
|
+
* @param ctx - Context carrying live agents and goal state.
|
|
64
|
+
* @param execution - Authenticated current tool execution.
|
|
65
|
+
* @returns The direct-human or exact-goal-round authority grant.
|
|
66
|
+
*/
|
|
67
|
+
function completionAuthority(ctx, execution) {
|
|
68
|
+
if (hasDirectHumanInput(ctx, execution)) return { kind: "direct-human" };
|
|
69
|
+
const goal = ctx.goals.get(execution.agent);
|
|
70
|
+
if (goal !== void 0 && isMatchingGoalRound(execution, goal)) return {
|
|
71
|
+
kind: "goal-round",
|
|
72
|
+
goal
|
|
73
|
+
};
|
|
74
|
+
return reject("complete and blocked require a direct human turn or the current goal round");
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region lib/types/wrapup.js
|
|
78
|
+
/**
|
|
79
|
+
* Render the closing-message instruction injected after an autonomous goal
|
|
80
|
+
* round reports `complete` or `blocked`, replacing the former hard turn stop
|
|
81
|
+
* so the model still addresses the user once before the turn ends.
|
|
82
|
+
* @param objective - the terminal goal's objective, echoed for grounding.
|
|
83
|
+
* @param blockedReason - the validated report for `blocked`; omitted for `complete`.
|
|
84
|
+
* @returns a fresh one-block context for `ToolRunContext.deferContext()`.
|
|
85
|
+
*/
|
|
86
|
+
function renderWrapupContext(objective, blockedReason) {
|
|
87
|
+
const heading = `Objective: ${JSON.stringify(objective)}\n`;
|
|
88
|
+
return [{
|
|
89
|
+
type: "text",
|
|
90
|
+
text: blockedReason === void 0 ? "<goal_complete>\n" + heading + "The goal is marked complete and this autonomous run is ending. Write the closing message to the user now: state the outcome, summarize what was done and how it was verified, and point to the concrete results (files, commits, or other artifacts). Report only what earlier rounds and tool results in this session actually establish; when a detail is not in the session, say so instead of inventing it. Note anything the user should review or do next. Address the user directly. Do not call any more tools in this run; further work waits for the user's next instruction.\n</goal_complete>" : "<goal_blocked>\n" + heading + `Blocked: ${JSON.stringify(blockedReason)}\nThe goal is marked blocked and this autonomous run is ending. Write the closing message to the user now: state what has been completed so far, describe the concrete blocking condition and what you tried, and say exactly what you need from the user to continue. Report only what earlier rounds and tool results in this session actually establish; when a detail is not in the session, say so instead of inventing it. Address the user directly. Do not call any more tools in this run; further work waits for the user's next instruction.
|
|
91
|
+
</goal_blocked>`
|
|
92
|
+
}];
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
//#region lib/types/index.js
|
|
96
|
+
/**
|
|
97
|
+
* Model-facing `get_goal`, `create_goal`, and `update_goal` tools over the
|
|
98
|
+
* persisted same-session goal domain.
|
|
99
|
+
* @module @deepseek-ai/dsh-tool-goal
|
|
100
|
+
*/
|
|
101
|
+
const name = "tool-goal";
|
|
102
|
+
const inject = [
|
|
103
|
+
"agents",
|
|
104
|
+
"goals",
|
|
105
|
+
"tools",
|
|
106
|
+
"systemPrompt"
|
|
107
|
+
];
|
|
108
|
+
/** Schemastery config for the goal-tool policy. */
|
|
109
|
+
const Config = z.object({ blockedAfterConsecutiveRounds: z.number().step(1).min(1).default(3) });
|
|
110
|
+
const UPDATE_ACTIONS = [
|
|
111
|
+
"edit",
|
|
112
|
+
"pause",
|
|
113
|
+
"resume",
|
|
114
|
+
"complete",
|
|
115
|
+
"blocked"
|
|
116
|
+
];
|
|
117
|
+
const CREATE_DESCRIPTION = "Create one persisted same-session completion goal when the current direct human request is a long-running objective that should continue across autonomous goal rounds. You may infer that intent without requiring the user to say \"create a goal\". Do not use this for trivial single-turn work. Execution rejects non-human and subagent authority.";
|
|
118
|
+
const GET_DESCRIPTION = "Read the current same-session goal, including its exact id/revision, objective, phase, completed continuation rounds, round limit, blocker reason when present, and whether another continuation is armed. Call this before updating a goal.";
|
|
119
|
+
const GOAL_VALUE_SCHEMA = { oneOf: [{
|
|
120
|
+
type: "object",
|
|
121
|
+
additionalProperties: false,
|
|
122
|
+
properties: { goal: {
|
|
123
|
+
type: "null",
|
|
124
|
+
required: true
|
|
125
|
+
} }
|
|
126
|
+
}, {
|
|
127
|
+
type: "object",
|
|
128
|
+
additionalProperties: false,
|
|
129
|
+
properties: {
|
|
130
|
+
goal: {
|
|
131
|
+
type: "object",
|
|
132
|
+
additionalProperties: false,
|
|
133
|
+
required: true,
|
|
134
|
+
properties: {
|
|
135
|
+
id: {
|
|
136
|
+
type: "string",
|
|
137
|
+
required: true
|
|
138
|
+
},
|
|
139
|
+
revision: {
|
|
140
|
+
type: "integer",
|
|
141
|
+
required: true
|
|
142
|
+
},
|
|
143
|
+
objective: {
|
|
144
|
+
type: "string",
|
|
145
|
+
required: true
|
|
146
|
+
},
|
|
147
|
+
phase: {
|
|
148
|
+
type: "string",
|
|
149
|
+
required: true,
|
|
150
|
+
enum: [
|
|
151
|
+
"active",
|
|
152
|
+
"paused",
|
|
153
|
+
"blocked",
|
|
154
|
+
"complete"
|
|
155
|
+
]
|
|
156
|
+
},
|
|
157
|
+
roundsStarted: {
|
|
158
|
+
type: "integer",
|
|
159
|
+
required: true
|
|
160
|
+
},
|
|
161
|
+
maxGoalRounds: {
|
|
162
|
+
type: "integer",
|
|
163
|
+
required: true
|
|
164
|
+
},
|
|
165
|
+
blockedReason: {
|
|
166
|
+
type: "object",
|
|
167
|
+
additionalProperties: false,
|
|
168
|
+
properties: {
|
|
169
|
+
code: {
|
|
170
|
+
type: "string",
|
|
171
|
+
required: true
|
|
172
|
+
},
|
|
173
|
+
message: {
|
|
174
|
+
type: "string",
|
|
175
|
+
required: true
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
activation: {
|
|
182
|
+
type: "string",
|
|
183
|
+
required: true,
|
|
184
|
+
enum: ["armed", "disarmed"]
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}] };
|
|
188
|
+
/** Render policy guidance with its deployment-selected blocked threshold. */
|
|
189
|
+
function guidance(blockedAfter) {
|
|
190
|
+
return `Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least ${blockedAfter} consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked.`;
|
|
191
|
+
}
|
|
192
|
+
/** Validate config even when apply is called directly outside Loader normalization. */
|
|
193
|
+
function resolveConfig(config) {
|
|
194
|
+
const blockedAfter = config.blockedAfterConsecutiveRounds ?? 3;
|
|
195
|
+
if (!Number.isSafeInteger(blockedAfter) || blockedAfter < 1) throw new TypeError("blockedAfterConsecutiveRounds must be a positive safe integer");
|
|
196
|
+
return { blockedAfterConsecutiveRounds: blockedAfter };
|
|
197
|
+
}
|
|
198
|
+
/** Whether optional text is meaningful rather than a strict-schema empty filler. */
|
|
199
|
+
function hasText(value) {
|
|
200
|
+
return value !== void 0 && value !== "";
|
|
201
|
+
}
|
|
202
|
+
/** Whether an optional round cap is meaningful rather than a strict-schema zero filler. */
|
|
203
|
+
function hasRoundCap(value) {
|
|
204
|
+
return value !== void 0 && value !== 0;
|
|
205
|
+
}
|
|
206
|
+
/** Build the exact compare-and-set ref from model arguments. */
|
|
207
|
+
function goalRef(goalId, revision) {
|
|
208
|
+
if (goalId.length === 0 || goalId !== goalId.trim() || !Number.isSafeInteger(revision) || revision < 1) throw new HarnessError("goal_id must be non-empty and revision must be a positive safe integer", "GOAL_TOOL_INVALID_UPDATE");
|
|
209
|
+
return {
|
|
210
|
+
id: GoalId(goalId),
|
|
211
|
+
revision
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/** Stable compact model result; activation is an observation, not replay state. */
|
|
215
|
+
function goalValue(goal) {
|
|
216
|
+
if (goal === void 0) return { goal: null };
|
|
217
|
+
return {
|
|
218
|
+
goal: {
|
|
219
|
+
id: goal.id,
|
|
220
|
+
revision: goal.revision,
|
|
221
|
+
objective: goal.objective,
|
|
222
|
+
phase: goal.phase,
|
|
223
|
+
roundsStarted: goal.roundsStarted,
|
|
224
|
+
maxGoalRounds: goal.maxGoalRounds,
|
|
225
|
+
...goal.blockedReason === void 0 ? {} : { blockedReason: {
|
|
226
|
+
code: goal.blockedReason.code,
|
|
227
|
+
message: goal.blockedReason.message
|
|
228
|
+
} }
|
|
229
|
+
},
|
|
230
|
+
activation: goal.activation
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/** Reusable canonical output declaration for all three goal controls. */
|
|
234
|
+
const GOAL_OUTPUT = {
|
|
235
|
+
schema: GOAL_VALUE_SCHEMA,
|
|
236
|
+
render: (_args, value) => [{
|
|
237
|
+
type: "text",
|
|
238
|
+
text: JSON.stringify(value)
|
|
239
|
+
}]
|
|
240
|
+
};
|
|
241
|
+
/** Generic, args-only pending presentation shared by the goal tools. */
|
|
242
|
+
function present(title, kind, rawInput) {
|
|
243
|
+
return {
|
|
244
|
+
card: "generic",
|
|
245
|
+
title,
|
|
246
|
+
kind,
|
|
247
|
+
...rawInput === void 0 ? {} : { rawInput }
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
/** Register the three Codex-shaped goal tools and their shared policy section. */
|
|
251
|
+
function apply(ctx, config) {
|
|
252
|
+
const resolved = resolveConfig(config);
|
|
253
|
+
ctx.systemPrompt.section({
|
|
254
|
+
name: "tool:goal",
|
|
255
|
+
order: 114,
|
|
256
|
+
text: guidance(resolved.blockedAfterConsecutiveRounds)
|
|
257
|
+
});
|
|
258
|
+
ctx.tools.register(defineTool({
|
|
259
|
+
name: "get_goal",
|
|
260
|
+
description: GET_DESCRIPTION,
|
|
261
|
+
parameters: {},
|
|
262
|
+
output: GOAL_OUTPUT,
|
|
263
|
+
execute(_args, exec) {
|
|
264
|
+
const execution = goalToolExecution(ctx, exec);
|
|
265
|
+
return Promise.resolve(goalValue(ctx.goals.get(execution.agent)));
|
|
266
|
+
},
|
|
267
|
+
presentCall: () => present("Read current goal", "read")
|
|
268
|
+
}));
|
|
269
|
+
ctx.tools.register(defineTool({
|
|
270
|
+
name: "create_goal",
|
|
271
|
+
description: CREATE_DESCRIPTION,
|
|
272
|
+
parameters: {
|
|
273
|
+
objective: {
|
|
274
|
+
type: "string",
|
|
275
|
+
required: true,
|
|
276
|
+
description: "The concrete completion objective inferred from the direct human request."
|
|
277
|
+
},
|
|
278
|
+
max_goal_rounds: {
|
|
279
|
+
type: "number",
|
|
280
|
+
description: "Optional positive safe-integer limit on automatic continuation rounds."
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
output: GOAL_OUTPUT,
|
|
284
|
+
execute(args, exec) {
|
|
285
|
+
const execution = goalToolExecution(ctx, exec);
|
|
286
|
+
requireDirectHuman(ctx, execution);
|
|
287
|
+
const goal = ctx.goals.create(execution.agent, {
|
|
288
|
+
objective: args.objective,
|
|
289
|
+
...args.max_goal_rounds === void 0 ? {} : { maxGoalRounds: args.max_goal_rounds }
|
|
290
|
+
});
|
|
291
|
+
return Promise.resolve(goalValue(goal));
|
|
292
|
+
},
|
|
293
|
+
presentCall: (args) => present("Create goal", "other", args.objective)
|
|
294
|
+
}));
|
|
295
|
+
ctx.tools.register(defineTool({
|
|
296
|
+
name: "update_goal",
|
|
297
|
+
description: "Update the exact current goal revision. edit, pause, and resume require a direct top-level human request. During an automatic continuation of the current goal, complete and blocked are also allowed. blocked is rejected before the configured minimum round count; the model remains responsible for judging that the same condition persisted across those rounds and must explain it in blocked_reason.",
|
|
298
|
+
parameters: {
|
|
299
|
+
goal_id: {
|
|
300
|
+
type: "string",
|
|
301
|
+
required: true,
|
|
302
|
+
description: "Exact id returned by get_goal."
|
|
303
|
+
},
|
|
304
|
+
revision: {
|
|
305
|
+
type: "number",
|
|
306
|
+
required: true,
|
|
307
|
+
description: "Exact positive revision returned by get_goal."
|
|
308
|
+
},
|
|
309
|
+
action: {
|
|
310
|
+
type: "string",
|
|
311
|
+
required: true,
|
|
312
|
+
enum: UPDATE_ACTIONS,
|
|
313
|
+
description: "edit | pause | resume | complete | blocked"
|
|
314
|
+
},
|
|
315
|
+
objective: {
|
|
316
|
+
type: "string",
|
|
317
|
+
description: "Replacement objective; valid only with action edit."
|
|
318
|
+
},
|
|
319
|
+
max_goal_rounds: {
|
|
320
|
+
type: "number",
|
|
321
|
+
description: "Replacement cap; valid only with action edit."
|
|
322
|
+
},
|
|
323
|
+
blocked_reason: {
|
|
324
|
+
type: "string",
|
|
325
|
+
description: "Concrete blocking condition; required only with action blocked."
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
output: GOAL_OUTPUT,
|
|
329
|
+
execute(args, exec) {
|
|
330
|
+
const execution = goalToolExecution(ctx, exec);
|
|
331
|
+
const ref = goalRef(args.goal_id, args.revision);
|
|
332
|
+
const replacements = {
|
|
333
|
+
...hasText(args.objective) ? { objective: args.objective } : {},
|
|
334
|
+
...hasRoundCap(args.max_goal_rounds) ? { maxGoalRounds: args.max_goal_rounds } : {}
|
|
335
|
+
};
|
|
336
|
+
if (args.action === "edit") {
|
|
337
|
+
requireDirectHuman(ctx, execution);
|
|
338
|
+
if (hasText(args.blocked_reason)) throw new HarnessError("blocked_reason is valid only with action blocked", "GOAL_TOOL_INVALID_UPDATE");
|
|
339
|
+
const goal = ctx.goals.edit(execution.agent, ref, replacements);
|
|
340
|
+
return Promise.resolve(goalValue(goal));
|
|
341
|
+
}
|
|
342
|
+
if (args.action === "pause" || args.action === "resume") {
|
|
343
|
+
requireDirectHuman(ctx, execution);
|
|
344
|
+
if (hasText(args.objective) || hasRoundCap(args.max_goal_rounds) || hasText(args.blocked_reason)) throw new HarnessError("objective and max_goal_rounds are valid only with action edit; blocked_reason is valid only with action blocked", "GOAL_TOOL_INVALID_UPDATE");
|
|
345
|
+
const goal = args.action === "pause" ? ctx.goals.pause(execution.agent, ref) : ctx.goals.resume(execution.agent, ref);
|
|
346
|
+
return Promise.resolve(goalValue(goal));
|
|
347
|
+
}
|
|
348
|
+
const authority = completionAuthority(ctx, execution);
|
|
349
|
+
if (hasText(args.objective) || hasRoundCap(args.max_goal_rounds)) throw new HarnessError("objective and max_goal_rounds are valid only with action edit", "GOAL_TOOL_INVALID_UPDATE");
|
|
350
|
+
if (args.action === "complete" && hasText(args.blocked_reason)) throw new HarnessError("blocked_reason is valid only with action blocked", "GOAL_TOOL_INVALID_UPDATE");
|
|
351
|
+
if (args.action === "blocked" && (args.blocked_reason === void 0 || args.blocked_reason.trim().length === 0)) throw new HarnessError("blocked_reason is required with action blocked", "GOAL_TOOL_INVALID_UPDATE");
|
|
352
|
+
if (args.action === "blocked" && authority.kind === "goal-round" && authority.goal.roundsStarted < resolved.blockedAfterConsecutiveRounds) throw new HarnessError(`blocked requires at least ${resolved.blockedAfterConsecutiveRounds} consecutive goal rounds; current round is ${authority.goal.roundsStarted}`, "GOAL_TOOL_BLOCK_THRESHOLD");
|
|
353
|
+
const goal = args.action === "complete" ? ctx.goals.complete(execution.agent, ref) : ctx.goals.block(execution.agent, ref, {
|
|
354
|
+
code: "model-reported",
|
|
355
|
+
message: args.blocked_reason
|
|
356
|
+
});
|
|
357
|
+
if (authority.kind === "goal-round") exec.deferContext(createUserMessage({
|
|
358
|
+
content: args.action === "complete" ? renderWrapupContext(goal.objective) : renderWrapupContext(goal.objective, args.blocked_reason),
|
|
359
|
+
source: {
|
|
360
|
+
kind: "plugin",
|
|
361
|
+
plugin: "tool-goal",
|
|
362
|
+
form: "notice",
|
|
363
|
+
summary: boundContextSummary(`${args.action}: ${goal.objective}`)
|
|
364
|
+
}
|
|
365
|
+
}));
|
|
366
|
+
return Promise.resolve(goalValue(goal));
|
|
367
|
+
},
|
|
368
|
+
presentCall: (args) => present(`${args.action === "blocked" ? "Mark" : args.action.charAt(0).toUpperCase() + args.action.slice(1)} goal`, "other", hasText(args.blocked_reason) ? args.blocked_reason : hasText(args.objective) ? args.objective : hasRoundCap(args.max_goal_rounds) ? args.max_goal_rounds : args.goal_id)
|
|
369
|
+
}));
|
|
370
|
+
}
|
|
371
|
+
//#endregion
|
|
372
|
+
export { Config, apply, inject, name };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/**
|
|
3
|
+
* Package-owned invariant companion for `@deepseek-ai/dsh-tool-goal`.
|
|
4
|
+
* @module @deepseek-ai/dsh-tool-goal/invariant
|
|
5
|
+
*/
|
|
6
|
+
const PACKAGE_NAME = "@deepseek-ai/dsh-tool-goal";
|
|
7
|
+
/** Cordis companion plugin name. */
|
|
8
|
+
const name = "tool-goal-invariant";
|
|
9
|
+
/** Service required before the companion can reserve package ownership. */
|
|
10
|
+
const inject = ["invariants"];
|
|
11
|
+
/**
|
|
12
|
+
* No runtime invariant: this model-facing adapter owns no independent state or event protocol;
|
|
13
|
+
* accepted mutations are checked by the goal domain and authority behavior is package-tested.
|
|
14
|
+
*/
|
|
15
|
+
const install = () => {};
|
|
16
|
+
/**
|
|
17
|
+
* Register this package's invariant companion.
|
|
18
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
19
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
20
|
+
*/
|
|
21
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
22
|
+
//#endregion
|
|
23
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Execution-time authority checks for the model-facing goal tools. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
4
|
+
import type { GoalView } from '@deepseek-ai/dsh-goal';
|
|
5
|
+
import type { SessionEvent } from '@deepseek-ai/dsh-session';
|
|
6
|
+
import type { ToolRunContext } from '@deepseek-ai/dsh-tools';
|
|
7
|
+
type TurnStartEvent = Extract<SessionEvent, {
|
|
8
|
+
type: 'turn/start';
|
|
9
|
+
}>;
|
|
10
|
+
/** Current open turn plus the events accepted after its start boundary. */
|
|
11
|
+
export interface GoalToolExecution {
|
|
12
|
+
readonly agent: Agent;
|
|
13
|
+
readonly start: TurnStartEvent;
|
|
14
|
+
readonly events: readonly SessionEvent[];
|
|
15
|
+
}
|
|
16
|
+
/** Hard authority granted to one state-changing call. */
|
|
17
|
+
export type GoalToolAuthority = {
|
|
18
|
+
readonly kind: 'direct-human';
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: 'goal-round';
|
|
21
|
+
readonly goal: GoalView;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Resolve and authenticate the calling agent and its driver boundary.
|
|
25
|
+
* @param ctx - Context carrying the live agent registry.
|
|
26
|
+
* @param exec - Tool execution metadata supplied by the registry.
|
|
27
|
+
* @returns The authenticated agent and its current turn window.
|
|
28
|
+
*/
|
|
29
|
+
export declare function goalToolExecution(ctx: Context, exec: ToolRunContext): GoalToolExecution;
|
|
30
|
+
/**
|
|
31
|
+
* Require authority originating in a human message accepted by a runtime root.
|
|
32
|
+
* @param ctx - Context carrying the live agent graph.
|
|
33
|
+
* @param execution - Authenticated current tool execution.
|
|
34
|
+
*/
|
|
35
|
+
export declare function requireDirectHuman(ctx: Context, execution: GoalToolExecution): void;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve completion authority from either direct human input or the exact goal round.
|
|
38
|
+
* @param ctx - Context carrying live agents and goal state.
|
|
39
|
+
* @param execution - Authenticated current tool execution.
|
|
40
|
+
* @returns The direct-human or exact-goal-round authority grant.
|
|
41
|
+
*/
|
|
42
|
+
export declare function completionAuthority(ctx: Context, execution: GoalToolExecution): GoalToolAuthority;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=authority.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-facing `get_goal`, `create_goal`, and `update_goal` tools over the
|
|
3
|
+
* persisted same-session goal domain.
|
|
4
|
+
* @module @deepseek-ai/dsh-tool-goal
|
|
5
|
+
*/
|
|
6
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
7
|
+
import z from '@deepseek-ai/schemastery';
|
|
8
|
+
export declare const name = "tool-goal";
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/** Model policy and hard lower bounds for goal-state updates. */
|
|
11
|
+
export interface Config {
|
|
12
|
+
/** Minimum admitted goal rounds before the model may self-report `blocked`. */
|
|
13
|
+
blockedAfterConsecutiveRounds?: number;
|
|
14
|
+
}
|
|
15
|
+
/** Schemastery config for the goal-tool policy. */
|
|
16
|
+
export declare const Config: z<Config>;
|
|
17
|
+
/** Register the three Codex-shaped goal tools and their shared policy section. */
|
|
18
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@deepseek-ai/dsh-tool-goal`.
|
|
3
|
+
* @module @deepseek-ai/dsh-tool-goal/invariant
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export declare const name = "tool-goal-invariant";
|
|
8
|
+
/** Service required before the companion can reserve package ownership. */
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Register this package's invariant companion.
|
|
12
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
13
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
14
|
+
*/
|
|
15
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
+
//# sourceMappingURL=invariant.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Model-visible wrap-up instruction for a terminal autonomous goal update. */
|
|
2
|
+
import type { ContentBlock } from '@deepseek-ai/dsh-llm';
|
|
3
|
+
/**
|
|
4
|
+
* Render the closing-message instruction injected after an autonomous goal
|
|
5
|
+
* round reports `complete` or `blocked`, replacing the former hard turn stop
|
|
6
|
+
* so the model still addresses the user once before the turn ends.
|
|
7
|
+
* @param objective - the terminal goal's objective, echoed for grounding.
|
|
8
|
+
* @param blockedReason - the validated report for `blocked`; omitted for `complete`.
|
|
9
|
+
* @returns a fresh one-block context for `ToolRunContext.deferContext()`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderWrapupContext(objective: string, blockedReason?: string): ContentBlock[];
|
|
12
|
+
//# sourceMappingURL=wrapup.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deepseek-ai/dsh-tool-goal",
|
|
3
|
+
"description": "Model-facing same-session goal tools with execution-time authority checks",
|
|
4
|
+
"version": "0.0.1-rc.1",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "restricted"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
|
11
|
+
"directory": "packages/goal/tool-goal"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./invariant": {
|
|
22
|
+
"types": "./lib/types/invariant.d.ts",
|
|
23
|
+
"default": "./lib/invariant.js"
|
|
24
|
+
},
|
|
25
|
+
"./src/*": "./src/*",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"lib/index.js",
|
|
30
|
+
"lib/invariant.js",
|
|
31
|
+
"lib/types/**/*.d.ts"
|
|
32
|
+
],
|
|
33
|
+
"license": "BSD-3-Clause",
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
|
|
36
|
+
"@deepseek-ai/dsh-session": "^0.0.1-rc.1",
|
|
37
|
+
"@deepseek-ai/dsh-goal": "^0.0.1-rc.1",
|
|
38
|
+
"@deepseek-ai/dsh-agent": "^0.0.1-rc.1",
|
|
39
|
+
"@deepseek-ai/dsh-system-prompt": "^0.0.1-rc.1",
|
|
40
|
+
"@deepseek-ai/dsh-tools": "^0.0.1-rc.1",
|
|
41
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1",
|
|
42
|
+
"@deepseek-ai/dsh-llm": "^0.0.1-rc.1"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@deepseek-ai/schemastery": "^3.18.1-rc.1"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@deepseek-ai/cordis-plugin-loader": "^1.0.1-rc.1",
|
|
49
|
+
"@deepseek-ai/dsh-agent": "^0.0.1-rc.1",
|
|
50
|
+
"@deepseek-ai/dsh-goal": "^0.0.1-rc.1",
|
|
51
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
|
|
52
|
+
"@deepseek-ai/dsh-llm": "^0.0.1-rc.1",
|
|
53
|
+
"@deepseek-ai/dsh-session": "^0.0.1-rc.1",
|
|
54
|
+
"@deepseek-ai/dsh-system-prompt": "^0.0.1-rc.1",
|
|
55
|
+
"@deepseek-ai/dsh-tools": "^0.0.1-rc.1",
|
|
56
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1"
|
|
57
|
+
}
|
|
58
|
+
}
|