@qilin-agent/schedule 3.1.5 → 3.1.6
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.i18n.yaml +12 -12
- package/README.md +5 -4
- package/README.zh.md +5 -4
- package/lib/index.js +36 -5
- package/lib/typert.host.js +424 -296
- package/lib/typert.remote-client.d.ts +9 -2
- package/lib/typert.remote-client.js +415 -292
- package/lib/types/domain.d.ts +3 -3
- package/lib/types/domain.js +1 -1
- package/lib/types/index.d.ts +23 -3
- package/lib/types/index.js +39 -4
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +36 -32
package/README.i18n.yaml
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
en: 23386452a66b2fbd
|
|
16
16
|
zh: 4a8d91b2f313fead
|
|
17
17
|
/qilin-agent-schedule/use-this-package:
|
|
18
|
-
en:
|
|
19
|
-
zh:
|
|
18
|
+
en: 7ae00b23b2ece8a6
|
|
19
|
+
zh: af5737593f499f59
|
|
20
20
|
/qilin-agent-schedule/understand-the-implementation:
|
|
21
21
|
en: 611c89f03a2e478f
|
|
22
22
|
zh: 2b7ebdb078899a5c
|
|
@@ -26,16 +26,16 @@
|
|
|
26
26
|
/qilin-agent-schedule/model-experience:
|
|
27
27
|
en: 215e7ba838619b7b
|
|
28
28
|
zh: a311da3843709f90
|
|
29
|
-
/qilin-agent-schedule/model-experience/tool-schemas-
|
|
30
|
-
en:
|
|
31
|
-
zh:
|
|
32
|
-
/qilin-agent-schedule/model-experience/tool-schemas-
|
|
33
|
-
en:
|
|
34
|
-
zh:
|
|
35
|
-
/qilin-agent-schedule/model-experience/tool-schemas-
|
|
29
|
+
/qilin-agent-schedule/model-experience/tool-schemas-in-mounted-presets:
|
|
30
|
+
en: 097a655a88e2a9f2
|
|
31
|
+
zh: 6612c58808186b1e
|
|
32
|
+
/qilin-agent-schedule/model-experience/tool-schemas-in-mounted-presets/what-the-model-sees:
|
|
33
|
+
en: 6151fbc60051cc23
|
|
34
|
+
zh: d65a12834b19273d
|
|
35
|
+
/qilin-agent-schedule/model-experience/tool-schemas-in-mounted-presets/token-effect:
|
|
36
36
|
en: ae0eb4d2609d4329
|
|
37
37
|
zh: 4fe0a26e37c272dc
|
|
38
|
-
/qilin-agent-schedule/model-experience/tool-schemas-
|
|
38
|
+
/qilin-agent-schedule/model-experience/tool-schemas-in-mounted-presets/kv-cache-effect:
|
|
39
39
|
en: 7bf33bbe17e1da03
|
|
40
40
|
zh: 2af9a2f842b4f430
|
|
41
41
|
/qilin-agent-schedule/model-experience/tool-results-after-management-calls:
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
en: 1006325fa610366d
|
|
70
70
|
zh: 476215d8a3c70fe4
|
|
71
71
|
/qilin-agent-schedule/known-limitations-and-deferred-work:
|
|
72
|
-
en:
|
|
73
|
-
zh:
|
|
72
|
+
en: fe970030579f8853
|
|
73
|
+
zh: cd6fad3d006a111a
|
|
74
74
|
/qilin-agent-schedule/known-limitations-and-deferred-work/dev-note:
|
|
75
75
|
en: e67f633dc6fe7773
|
|
76
76
|
zh: 8ec3e73528ddb1a6
|
package/README.md
CHANGED
|
@@ -23,9 +23,9 @@ Schedule delivers one-shot, fixed-rate, daily, weekly, and cron wall-clock remin
|
|
|
23
23
|
<a id="use-this-package"></a>
|
|
24
24
|
## Use this package
|
|
25
25
|
|
|
26
|
-
The shipped Web
|
|
26
|
+
The shipped Web composition mounts the service alongside storage-domain and the Session controller. Its `Config` states `deliveryHistoryDays` (default 30) and `deliveryHistoryRecords` (default 200). Storage backend routing belongs to storage-domain; Session model and preset restoration belong to the Session controller. Schedule cannot be mounted alone in a headless or SDK-only composition: delivery requires the Host Web Session controller and a Session persistence backend, because a delivery commits only after the Session acknowledges `session/flush`.
|
|
27
27
|
|
|
28
|
-
The
|
|
28
|
+
The reminder tools `schedule_create`, `schedule_list`, `schedule_delete`, and `schedule_update` come from [`@qilin-agent/tool-schedule`](../tool-schedule/README.md), which a preset mounts; this package contributes the Host service those tools call. Update replaces the name, instruction, or timing of one reminder in place and keeps its id and saved records; it is not offered for the relative `after` delay. Creation requires a non-empty prompt, a title, and exactly one of six selectors:
|
|
29
29
|
|
|
30
30
|
| Selector | Example | Timing |
|
|
31
31
|
|---|---|---|
|
|
@@ -90,11 +90,11 @@ The `schedule.archiveAdmission()` effect answers the Workspace registry's archiv
|
|
|
90
90
|
<a id="model-experience"></a>
|
|
91
91
|
## Model Experience
|
|
92
92
|
|
|
93
|
-
### Tool schemas
|
|
93
|
+
### Tool schemas in mounted presets
|
|
94
94
|
|
|
95
95
|
#### What the model sees
|
|
96
96
|
|
|
97
|
-
The [generated tool catalog](../../../docs/tool-catalog.md#qilin-agenttool-schedule) contains the descriptions and schemas for `schedule_create`, `schedule_list`, `schedule_delete`, and `schedule_update`,
|
|
97
|
+
The [generated tool catalog](../../../docs/tool-catalog.md#qilin-agenttool-schedule) contains the descriptions and schemas for `schedule_create`, `schedule_list`, `schedule_delete`, and `schedule_update`, which [`@qilin-agent/tool-schedule`](../tool-schedule/README.md) contributes to the presets that mount it.
|
|
98
98
|
|
|
99
99
|
#### Token effect
|
|
100
100
|
|
|
@@ -155,6 +155,7 @@ Reminder messages append to the original Session's history and preserve earlier
|
|
|
155
155
|
- Deletion removes the task row together with its saved delivery records: future delivery stops, the task leaves `list` and `catalog`, and `history` no longer resolves it.
|
|
156
156
|
- Old Session-log reminders require explicit recreation. Previously physically deleted tasks are not restored or fabricated.
|
|
157
157
|
- Management edits are limited to active tasks. Pause, execution status, delivery outside the original Session, and a new Session for each run are not supported. Name, instruction, and timing updates are available to the model through `schedule_update` for its own Session, and to the Web detail for the selected task; a cross-Session relay workflow is not supported, product permission policy remains undecided, and the Session-binding check is not caller authorization.
|
|
158
|
+
- `create` and `update` refuse a Session a delegated child owns with `subagent_session` when the Agent's delegation depth is above zero — the accounting the delegation cap itself enforces, read from the persisted session header so it survives a cold resume. Delivery resolves the bound Session through the Session controller, which rejects the live Agent of a delegated child, so a task bound there could never be delivered. Restricting the caller belongs to the tool layer: `@qilin-agent/tool-schedule` refuses all four of its tools for a delegated caller. `list`, `catalog`, `history`, and `delete` keep serving that Session, so a task stored before this rule stays removable.
|
|
158
159
|
- Cron uses the five-field Vixie dialect, so the smallest interval is one minute and sub-minute scheduling is unsupported. Secondary expressions are not accepted: `L`, `W`, `#`, month or weekday names, `@daily`-style macros, and a seconds field are rejected. The stored record keeps only the canonical expression, so the exact spelling supplied at creation is not retained.
|
|
159
160
|
- Daily, weekly, and cron future targets use the Host's current IANA data; decoding and restarting never recompute an already committed target. Only UTC target years 0001–9999 are supported; exhaustion retains the task as inactive after delivery.
|
|
160
161
|
- Saved delivery records are pruned on append to the configured `deliveryHistoryDays` window, measured back from each receipt's `deliveredAt`, and to the `deliveryHistoryRecords` cap; the appended latest receipt always survives, and a pruned window marks the task's earlier records unavailable. The JSON backend stores the Schedule domain in one `schedule.json` document, so every task mutation rewrites all retained tasks and their histories, and the Host loads all retained history into memory. History pagination bounds returned record count, not storage growth, retained memory, prompt bytes, or write cost.
|
package/README.zh.md
CHANGED
|
@@ -23,9 +23,9 @@ Schedule 将一次性、固定周期、按每日、按每周以及 cron 本地
|
|
|
23
23
|
<a id="use-this-package"></a>
|
|
24
24
|
## 使用此包
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
随发行版交付的 Web 组合把此服务与 storage-domain、Session controller 一起挂载。其 `Config` 声明 `deliveryHistoryDays`(默认 30)与 `deliveryHistoryRecords`(默认 200)。存储后端路由由 storage-domain 管理;会话模型与 preset 恢复由 Session controller 管理。Schedule 无法在 headless 或仅 SDK 的组合中单独挂载:投递需要 Host 的 Web Session controller 和 Session 持久化后端,因为只有在 Session 确认 `session/flush` 之后一次投递才会提交。
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
提醒工具 `schedule_create`、`schedule_list`、`schedule_delete` 和 `schedule_update` 来自 [`@qilin-agent/tool-schedule`](../tool-schedule/README.zh.md),由 preset 挂载;本包提供这些工具调用的宿主服务。更新原地替换一条提醒的名称、指令或时间,保留其 id 与已保存记录;相对的 `after` 延迟不支持更新。创建时需要非空提示文本、标题,且必须只提供以下六个选择器之一:
|
|
29
29
|
|
|
30
30
|
| 选择器 | 示例 | 时间语义 |
|
|
31
31
|
|---|---|---|
|
|
@@ -90,11 +90,11 @@ Schedule domain 声明整 unit 布局,因为任务是权威数据。路由到
|
|
|
90
90
|
<a id="model-experience"></a>
|
|
91
91
|
## 模型体验
|
|
92
92
|
|
|
93
|
-
###
|
|
93
|
+
### 挂载 preset 中的工具 schema
|
|
94
94
|
|
|
95
95
|
#### 模型看到什么
|
|
96
96
|
|
|
97
|
-
[生成的工具目录](../../../docs/tool-catalog.zh.md#qilin-agenttool-schedule) 包含 `schedule_create`、`schedule_list`、`schedule_delete` 和 `schedule_update` 的描述与 schema;这些工具由
|
|
97
|
+
[生成的工具目录](../../../docs/tool-catalog.zh.md#qilin-agenttool-schedule) 包含 `schedule_create`、`schedule_list`、`schedule_delete` 和 `schedule_update` 的描述与 schema;这些工具由 [`@qilin-agent/tool-schedule`](../tool-schedule/README.zh.md) 贡献给挂载它的 preset。
|
|
98
98
|
|
|
99
99
|
#### Token 影响
|
|
100
100
|
|
|
@@ -155,6 +155,7 @@ This is a scheduled message from the user
|
|
|
155
155
|
- 删除会移除任务行及其已保存的投递记录:后续投递停止,任务离开 `list` 与 `catalog`,`history` 也不再解析到它。
|
|
156
156
|
- 旧会话日志提醒需要明确重新创建。此前已物理删除的任务不会被恢复或虚构。
|
|
157
157
|
- 仅可修改活动任务的管理字段。不支持暂停、执行状态、原会话以外的投递或每次运行新建会话。名称、指令和时间更新可由模型通过 `schedule_update` 修改其自身 Session 内的提醒,也可在 Web 详情中对所选任务修改;不支持跨会话转交工作流,产品权限策略尚未确定,会话绑定校验不等于调用者鉴权。
|
|
158
|
+
- 对由被委派子 agent 拥有的 Session,当该 Agent 的委派深度大于零时,`create` 与 `update` 会以 `subagent_session` 拒绝(这正是委派封顶本身执行的记账,读取自持久化 session header,因此冷恢复后仍然成立)。投递会经由 Session controller 解析该绑定 Session,而后者拒绝被委派子 agent 的活跃 Agent,因此绑定到那里的任务永远无法投递。调用方限制属于工具层:`@qilin-agent/tool-schedule` 会拒绝被委派调用方的每一个工具。`list`、`catalog`、`history` 与 `delete` 仍服务该 Session,所以在这条规则之前存储的任务仍可删除。
|
|
158
159
|
- Cron 使用五字段 Vixie 方言,因此最小间隔为一分钟,不支持亚分钟级调度。不接受扩展表达式:`L`、`W`、`#`、月份或星期名称、`@daily` 风格宏以及秒字段都会被拒绝。存储记录只保留规范化表达式,创建时提供的原始拼写不会被保留。
|
|
159
160
|
- Daily、Weekly 与 Cron 的未来目标使用宿主当前的 IANA 数据;解码和重启绝不重新计算已提交的目标。UTC 目标仅支持 0001–9999 年;没有后续目标时,任务在投递后保留为未运行状态。
|
|
160
161
|
- 已保存的发送记录在追加确认时按配置的 `deliveryHistoryDays` 窗口(以每条回执的 `deliveredAt` 向前计算)与 `deliveryHistoryRecords` 条数上限裁剪;新追加的最近一次回执始终保留,发生裁剪时任务标记更早记录不可用。JSON 后端把 Schedule domain 存在一个 `schedule.json` 文档中,因此每次任务变更都会重写全部保留任务及其历史,宿主也会把全部保留历史加载到内存。历史分页仅限制返回的记录数,不限制存储增长、保留的内存、提示文本字节数或写入成本。
|
package/lib/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import z from "@qilin-agent/schemastery";
|
|
3
3
|
import { Service } from "@qilin-agent/kylin";
|
|
4
4
|
import { Remote, TypertRemoteService } from "@qilin-agent/typert-protocol";
|
|
5
|
+
import { delegationDepthOf } from "@qilin-agent/subagent";
|
|
5
6
|
import { createUserMessage } from "@qilin-agent/llm";
|
|
6
7
|
import { Temporal } from "@js-temporal/polyfill";
|
|
7
8
|
import { SessionId, SessionLogOffset } from "@qilin-agent/session";
|
|
@@ -41,7 +42,7 @@ var ScheduleLogError = class extends Error {
|
|
|
41
42
|
this.name = "ScheduleLogError";
|
|
42
43
|
}
|
|
43
44
|
};
|
|
44
|
-
/** Error from a model-supplied Schedule rule that cannot become a record. */
|
|
45
|
+
/** Error from a model-supplied Schedule rule or target Session that cannot become a record. */
|
|
45
46
|
var ScheduleInputError = class extends Error {
|
|
46
47
|
/** Stable public Schedule input code. */
|
|
47
48
|
code;
|
|
@@ -1968,7 +1969,6 @@ let ScheduleService = (() => {
|
|
|
1968
1969
|
static inject = [
|
|
1969
1970
|
"agents",
|
|
1970
1971
|
"sessions",
|
|
1971
|
-
"tools",
|
|
1972
1972
|
"storageDomain",
|
|
1973
1973
|
"sessionController",
|
|
1974
1974
|
"sessionPersistence"
|
|
@@ -2070,6 +2070,8 @@ let ScheduleService = (() => {
|
|
|
2070
2070
|
*
|
|
2071
2071
|
* The request must supply a title; a missing, blank-after-trim, or over-long
|
|
2072
2072
|
* title rejects with `invalid_prompt` instead of deriving one from the prompt.
|
|
2073
|
+
* A Session a delegated child owns rejects with `subagent_session`, because delivery
|
|
2074
|
+
* can never reach it: the child is one whose delegation depth is above zero.
|
|
2073
2075
|
* The record is built from the clock reading taken before the request joins the
|
|
2074
2076
|
* serialized queue, so a create that waits behind a longer operation keeps its
|
|
2075
2077
|
* request-time anchor and may already be due when the queue reaches it.
|
|
@@ -2092,6 +2094,8 @@ let ScheduleService = (() => {
|
|
|
2092
2094
|
else if (request.cron !== void 0) record = createCronScheduleRecord(id, request.prompt, request.cron, now, title);
|
|
2093
2095
|
else throw new ScheduleInputError("invalid_selector", "Exactly one reminder selector is required.");
|
|
2094
2096
|
return this.serialize(async () => {
|
|
2097
|
+
const refusal = this.reminderTargetRefusal(sessionId);
|
|
2098
|
+
if (refusal !== void 0) throw new ScheduleInputError("subagent_session", refusal.message);
|
|
2095
2099
|
const domain = await this.getDomain();
|
|
2096
2100
|
signal?.throwIfAborted();
|
|
2097
2101
|
await domain.table("tasks").put(id, {
|
|
@@ -2150,7 +2154,9 @@ let ScheduleService = (() => {
|
|
|
2150
2154
|
* Delete one task belonging to the selected Session, leaving queued messages intact.
|
|
2151
2155
|
*
|
|
2152
2156
|
* The row is removed: the task no longer schedules, leaves `list` and `catalog`, and its
|
|
2153
|
-
* saved delivery records go with it.
|
|
2157
|
+
* saved delivery records go with it. A task bound to a Session a delegated child owns
|
|
2158
|
+
* stays deletable even though creation and timing edits refuse that binding, so a task
|
|
2159
|
+
* stored before that rule existed remains removable.
|
|
2154
2160
|
* @param request - Session and exact task identity.
|
|
2155
2161
|
* @param signal - Optional cancellation checked before persistence begins, including after FIFO waits.
|
|
2156
2162
|
* @returns Whether that Session owned a deleted task. Cancellation does not roll back an in-flight write.
|
|
@@ -2179,14 +2185,19 @@ let ScheduleService = (() => {
|
|
|
2179
2185
|
* binding without activating the Session or changing saved deliveries.
|
|
2180
2186
|
*
|
|
2181
2187
|
* Each supplied field replaces its stored value; an omitted field keeps it. A name or
|
|
2182
|
-
* instruction change alone does not reset the committed target.
|
|
2188
|
+
* instruction change alone does not reset the committed target. A Session a delegated
|
|
2189
|
+
* child owns returns the non-mutating `subagent_session` result, so an edit cannot
|
|
2190
|
+
* re-arm a task bound to a Session delivery can never reach, and the Web editor can
|
|
2191
|
+
* explain the refusal through the ordinary result it already renders.
|
|
2183
2192
|
* @param request - Task binding, complete observed record, and any combination of timing, name, and instruction.
|
|
2184
2193
|
* @param signal - Cancellation checked after domain readiness and FIFO waits, before persistence begins.
|
|
2185
|
-
* @returns The committed record, unchanged record for a no-op, or a non-mutating input/lookup/conflict result.
|
|
2194
|
+
* @returns The committed record, unchanged record for a no-op, or a non-mutating input/lookup/conflict/refusal result.
|
|
2186
2195
|
* Storage and lifecycle failures reject; cancellation after a write starts does not roll it back.
|
|
2187
2196
|
*/
|
|
2188
2197
|
async update(request, signal) {
|
|
2189
2198
|
return this.serialize(async () => {
|
|
2199
|
+
const refusal = this.reminderTargetRefusal(request.sessionId);
|
|
2200
|
+
if (refusal !== void 0) return refusal;
|
|
2190
2201
|
const tasks = (await this.getDomain()).table("tasks");
|
|
2191
2202
|
signal?.throwIfAborted();
|
|
2192
2203
|
const current = tasks.get(request.id);
|
|
@@ -2229,6 +2240,26 @@ let ScheduleService = (() => {
|
|
|
2229
2240
|
return this.ready;
|
|
2230
2241
|
}
|
|
2231
2242
|
/**
|
|
2243
|
+
* Refuse a Session no delivery can reach because a delegated child owns it.
|
|
2244
|
+
*
|
|
2245
|
+
* Delivery resolves the bound Session through `ctx.sessionController.resolveAgent`,
|
|
2246
|
+
* which rejects the live Agent of a delegated child; a stored task for such a Session
|
|
2247
|
+
* would stay permanently overdue and retry on every drive. Both operations that can
|
|
2248
|
+
* arm a delivery read that same fact here instead of restating it: a delegated child
|
|
2249
|
+
* is one whose {@link delegationDepthOf} is above zero, the accounting the delegation
|
|
2250
|
+
* cap itself enforces, which survives a cold resume through the persisted header.
|
|
2251
|
+
* @param sessionId - Session the task would be bound to.
|
|
2252
|
+
* @returns The stable refusal for a delegated child's Session, or undefined when the Session is eligible.
|
|
2253
|
+
*/
|
|
2254
|
+
reminderTargetRefusal(sessionId) {
|
|
2255
|
+
const agent = this.ctx.agents.get(sessionId);
|
|
2256
|
+
if (agent === void 0 || delegationDepthOf(agent) === 0) return void 0;
|
|
2257
|
+
return {
|
|
2258
|
+
code: "subagent_session",
|
|
2259
|
+
message: "This Session belongs to subagent routing, which never receives reminder delivery."
|
|
2260
|
+
};
|
|
2261
|
+
}
|
|
2262
|
+
/**
|
|
2232
2263
|
* Remove every active task stored for one Session, inside the queue the tools
|
|
2233
2264
|
* use.
|
|
2234
2265
|
*
|