@jangts/agent-core 0.2.0 → 0.2.5
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/CHANGELOG.md +14 -0
- package/LICENSE +55 -0
- package/NOTICE +6 -0
- package/README.md +8 -0
- package/development/docs/README.en.md +70 -0
- package/development/docs/README.md +1 -1
- package/development/docs/acceptance.en.md +34 -0
- package/development/docs/agent-development.en.md +42 -0
- package/development/docs/api/README.en.md +62 -0
- package/development/docs/api/advanced-agents.en.md +135 -0
- package/development/docs/api/context-processing.en.md +110 -0
- package/development/docs/api/core.en.md +274 -0
- package/development/docs/api/examples.en.md +118 -0
- package/development/docs/api/kits.en.md +183 -0
- package/development/docs/api/knowledge-answering.en.md +166 -0
- package/development/docs/api/mock.en.md +186 -0
- package/development/docs/api/observability.en.md +166 -0
- package/development/docs/api/reference.en.md +2235 -0
- package/development/docs/api/reference.md +290 -257
- package/development/docs/api/support.en.md +252 -0
- package/development/docs/api/types.en.md +181 -0
- package/development/docs/api/workflow.en.md +198 -0
- package/development/docs/api/workflow.md +22 -0
- package/development/docs/basic-usage.en.md +78 -0
- package/development/docs/create-app.en.md +76 -0
- package/development/docs/examples/offline-agent.en.md +273 -0
- package/development/docs/examples.en.md +36 -0
- package/development/docs/flows/knowledge-maintenance.en.md +38 -0
- package/development/docs/getting-started.en.md +71 -0
- package/development/docs/knowledge.en.md +89 -0
- package/development/docs/maintenance.en.md +62 -0
- package/development/docs/materials.en.md +38 -0
- package/development/docs/mechanisms.en.md +227 -0
- package/development/docs/memory-and-learning.en.md +42 -0
- package/development/docs/operations.en.md +51 -0
- package/development/docs/records.en.md +63 -0
- package/development/docs/registration.en.md +63 -0
- package/development/skills/agent-core-app/SKILL.md +4 -0
- package/development/skills/agent-core-app/scripts/create-app.mjs +19 -0
- package/development/skills/agent-core-app/scripts/lib/knowledge.mjs +37 -1
- package/development/skills/agent-core-app/scripts/plan.mjs +9 -0
- package/development/skills/agent-core-app/scripts/resources.mjs +17 -0
- package/dist/cjs/diagnostics/catalog.js +6 -0
- package/dist/cjs/execution/cache.js +162 -0
- package/dist/cjs/execution/engine.js +10 -0
- package/dist/cjs/kits/vector-search.js +4 -7
- package/dist/cjs/structs/execution/cache.js +6 -0
- package/dist/cjs/support/model/chat-completions.js +1 -1
- package/dist/cjs/support/model/completion/default.js +1 -0
- package/dist/cjs/support/model/completion/session.js +5 -0
- package/dist/esm/diagnostics/catalog.d.ts +6 -0
- package/dist/esm/diagnostics/catalog.js +6 -0
- package/dist/esm/execution/cache.d.ts +20 -0
- package/dist/esm/execution/cache.js +156 -0
- package/dist/esm/execution/engine.d.ts +5 -0
- package/dist/esm/execution/engine.js +10 -0
- package/dist/esm/kits/vector-search.js +4 -7
- package/dist/esm/structs/execution/cache.d.ts +54 -0
- package/dist/esm/structs/execution/cache.js +5 -0
- package/dist/esm/structs/execution/engine.d.ts +6 -1
- package/dist/esm/structs/execution/workflow.d.ts +2 -1
- package/dist/esm/structs/index.d.ts +1 -0
- package/dist/esm/structs/kits/retrieval.d.ts +1 -0
- package/dist/esm/structs/kits/search.d.ts +2 -0
- package/dist/esm/structs/model/messages.d.ts +4 -0
- package/dist/esm/structs/support/model/messages.d.ts +2 -0
- package/dist/esm/support/context/nodes.d.ts +16 -0
- package/dist/esm/support/context/processing.d.ts +7 -0
- package/dist/esm/support/model/chat-completions.js +1 -1
- package/dist/esm/support/model/children.d.ts +2 -0
- package/dist/esm/support/model/completion/default.d.ts +1 -0
- package/dist/esm/support/model/completion/default.js +1 -0
- package/dist/esm/support/model/completion/session.d.ts +5 -0
- package/dist/esm/support/model/completion/session.js +5 -0
- package/dist/esm/support/model/preview-rules.d.ts +6 -0
- package/dist/esm/support/model/reply-preview.d.ts +7 -0
- package/dist/esm/support/model/strategies.d.ts +4 -0
- package/package.json +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
本文件记录 `@jangts/agent-core` 的行为变更。接口合同与使用方式见[API 手册](development/docs/api/README.md)。
|
|
4
4
|
|
|
5
|
+
## 0.2.5
|
|
6
|
+
|
|
7
|
+
- Engine-owned, bounded LRU `context.cache` with node partitions and optional write TTL.
|
|
8
|
+
- Optional asynchronous App-owned `context.agentCache`; persistent and volatile spaces are explicit, independent and never silently fall back.
|
|
9
|
+
- Both workflow and `$step` contexts expose the same cache operations; forks have fresh memory and only use an explicitly restored App cache port.
|
|
10
|
+
- Vector filter, grouping and returned-hit metadata use independent snapshots so callback mutations cannot affect later consumers.
|
|
11
|
+
|
|
12
|
+
## 0.2.1
|
|
13
|
+
|
|
14
|
+
### 变更
|
|
15
|
+
|
|
16
|
+
- 许可调整为 Apache License 2.0,补充 `LICENSE` 与 `NOTICE`。
|
|
17
|
+
- 运行依赖 `@jangts/streaming` 更新为 `^0.1.2`。
|
|
18
|
+
|
|
5
19
|
## 0.2.0
|
|
6
20
|
|
|
7
21
|
### 新增
|
package/LICENSE
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
|
|
5
|
+
http://www.apache.org/licenses/
|
|
6
|
+
|
|
7
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
8
|
+
|
|
9
|
+
1. Definitions.
|
|
10
|
+
|
|
11
|
+
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
|
16
|
+
|
|
17
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
|
18
|
+
|
|
19
|
+
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
|
20
|
+
|
|
21
|
+
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
|
22
|
+
|
|
23
|
+
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
|
24
|
+
|
|
25
|
+
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
|
26
|
+
|
|
27
|
+
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
|
28
|
+
|
|
29
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
|
30
|
+
|
|
31
|
+
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
|
32
|
+
|
|
33
|
+
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
|
34
|
+
|
|
35
|
+
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
|
36
|
+
|
|
37
|
+
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
|
38
|
+
|
|
39
|
+
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
|
40
|
+
|
|
41
|
+
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
|
42
|
+
|
|
43
|
+
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
|
44
|
+
|
|
45
|
+
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
|
46
|
+
|
|
47
|
+
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
|
48
|
+
|
|
49
|
+
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
|
50
|
+
|
|
51
|
+
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
|
52
|
+
|
|
53
|
+
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
|
54
|
+
|
|
55
|
+
END OF TERMS AND CONDITIONS
|
package/NOTICE
ADDED
package/README.md
CHANGED
|
@@ -51,6 +51,10 @@ Bind fixed model definitions, Workflows, and tools ahead of time, passing only p
|
|
|
51
51
|
|
|
52
52
|
In this repository, `npm run test:agent-audit` builds Agent Core and MockGPT and runs logic, security, and performance regressions. Use `-- --repeat=2` for two consecutive rounds or `--no-build` to reuse existing builds. Coverage merges V8 ranges with c8/Istanbul and includes every generated ESM module, including modules not imported by existing tests. Statements, lines, functions, and branches must all reach 100%; uncovered logic fails the audit even if assertions pass. Reports are written to root `.tmp/agent-audit/`. Builds remove stale package output so moved sources cannot leave obsolete modules. Regressions use offline resources, injected ports, and loopback HTTP, without real models or public websites; they do not verify real-model comprehension or decision quality.
|
|
53
53
|
|
|
54
|
+
## License
|
|
55
|
+
|
|
56
|
+
Apache License 2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
|
|
57
|
+
|
|
54
58
|
---
|
|
55
59
|
|
|
56
60
|
<a id="中文"></a>
|
|
@@ -103,3 +107,7 @@ Core 与 Support 从包根调用。Kit 默认按模块引入,也保留独立
|
|
|
103
107
|
`ModelRunner.sink.output` 可在保留调用预算、取消和协议校验的同时接收真实生成分片,`invoke` 仍返回完整结果。App 可选用 `Support.createReplyPreview` 登记允许预览的函数与正文 JSON 路径,配合 `Support.streamEvents` 发送生成中预览;业务校验通过后再确认正式正文,失败时撤回。预览不能用作授权、工具执行或正式历史,详见[Core API](development/docs/api/core.md)。
|
|
104
108
|
|
|
105
109
|
仓库内运行 `npm run test:agent-audit` 可构建 Agent Core 与 MockGPT 并执行逻辑、安全和性能回归;`-- --repeat=2` 连续执行两轮,`--no-build` 复用已有构建。覆盖统计通过 c8/Istanbul 合并 V8 区间,包含全部生成的 ESM 模块,未被现有测试导入的模块也参与统计;语句、行、函数与分支覆盖率均以 100% 为通过门槛,存在未覆盖逻辑即失败,测试断言通过不能替代此门槛;报告写入根 `.tmp/agent-audit/`。构建清理本包旧产物,避免源码移动后残留失效模块。回归使用离线资料、注入端口与本机回环 HTTP,不调用真实模型或公网网站;不验证真实模型的理解与决策质量。
|
|
110
|
+
|
|
111
|
+
## 许可
|
|
112
|
+
|
|
113
|
+
Apache License 2.0,见 [LICENSE](LICENSE) 与 [NOTICE](NOTICE)。
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Third-party App development handbook
|
|
2
|
+
|
|
3
|
+
This handbook explains how to build Apps with the public interfaces of Agent Core, covering APIs, integration examples, Skills, and App knowledge maintenance. The Chinese edition starts at [中文](README.md); each page has a corresponding `*.en.md` file in the same directory.
|
|
4
|
+
|
|
5
|
+
> [API handbook](api/README.md) · [Public symbol reference](api/reference.md)
|
|
6
|
+
|
|
7
|
+
Agent Core integrates with applications through public interfaces and works with different service frameworks, databases, model providers, and front ends.
|
|
8
|
+
|
|
9
|
+
The API reference is also part of this development documentation: [API home](api/README.md), [Core](api/core.md), [Support](api/support.md), [Kit](api/kits.md). This handbook explains how to combine these interfaces and take on application responsibilities; signatures, parameters, returns, and exceptions are governed by the corresponding API pages.
|
|
10
|
+
|
|
11
|
+
## Start from the task to be completed
|
|
12
|
+
|
|
13
|
+
First read [How the mechanism works](mechanisms.md) to understand overall collaboration, the difference between tasks and nodes, workflow progression, the timing of model and tool calls, and the App knowledge answering example.
|
|
14
|
+
|
|
15
|
+
Start by providing a ChatProvider, then call `new ModelRunner({ provider }).invoke('你好')`. Core itself provides the plain text path and default run settings; Support and Kit are optional. Tools, context processing, persistence, and complex orchestration are integrated step by step as needed.
|
|
16
|
+
|
|
17
|
+
| Task | Recommended entry |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| Create a runnable Agent App from an empty directory | [Create an App](create-app.md) |
|
|
20
|
+
| Install into an existing project, configure the model connection | [Installation and integration](getting-started.md) |
|
|
21
|
+
| Generate one reply | [Model calls](basic-usage.md#one-model-call) |
|
|
22
|
+
| Declare tools, authorization, execution in one place and return results | [Tool integration](basic-usage.md#tools-are-declared-only-once) |
|
|
23
|
+
| Understand the difference between raw model streams and complete delivery | [Stream boundaries](basic-usage.md#streams-previews-and-logs) |
|
|
24
|
+
| Orchestrate conditional loops and multi-stage tasks | [Registration and orchestration](registration.md) |
|
|
25
|
+
| Control context length and compression | [Context policy](api/context-processing.md) |
|
|
26
|
+
| Generate and check answers from existing knowledge | [Knowledge documents](knowledge.md), [Knowledge answering contract](api/knowledge-answering.md) |
|
|
27
|
+
| Handle user materials and persistence | [Material boundaries](materials.md), [Memory and continuous accumulation](memory-and-learning.md) |
|
|
28
|
+
| Integrate logs, cancellation, and failure handling | [Delivery and operations](operations.md) |
|
|
29
|
+
| Verify a complete integration | [Integration checks](acceptance.md) |
|
|
30
|
+
|
|
31
|
+
For partial integration approaches see [Examples](examples.md); for App data field design see [Record examples](records.md). For manual preparation and iteration see the [Maintenance handbook](maintenance.md); for the shared workflow and Skill used by coding Agents see [Agent-assisted development](agent-development.md). These assets are not automatically scanned, installed, published, or written to a database by the library.
|
|
32
|
+
|
|
33
|
+
## How the three kinds of interfaces collaborate
|
|
34
|
+
|
|
35
|
+
Core owns the execution service and the calling/callback contracts, such as workflow state commits, model call budget, tool input → execution → output, and real call receipts. Support helps the App construct these calls and the implementations that get scheduled. Kit is chosen by the App on its own and owns its own local business models and specifications.
|
|
36
|
+
|
|
37
|
+
`Support` is the unified namespace for integration support and contains multiple modules. A single optional capability module is called a Kit; multiple Kits are aggregated by `/kits`. A Kit may have its own helper functions and shared utilities internally.
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
App authentication, storage, knowledge loading, and run configuration
|
|
41
|
+
→ Support assembles model and context
|
|
42
|
+
→ Core executes registered workflows, model calls, and tools
|
|
43
|
+
→ App handler calls Knowledge / Answering / Presentation Kits as needed
|
|
44
|
+
→ App checks and delivers the result
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Names, parameters, and conclusions proposed by the model are not authentication, persistence authorization, or execution receipts. An App may skip a given Kit but still has to comply with the Core interfaces it actually uses. After adopting a Kit, comply with that Kit's local input and output constraints.
|
|
48
|
+
|
|
49
|
+
## What a new App must provide
|
|
50
|
+
|
|
51
|
+
- **Basic run**: the Provider's model connection and the actual input. Core provides the default budget, single-call timeout, signals, and plain text transport; override as needed.
|
|
52
|
+
- **When enabling tools**: the business implementation plus the required identity, access control, parameter, and result constraints.
|
|
53
|
+
- **When enabling persistence**: sources, user ownership, storage and retention policy, and failure recovery.
|
|
54
|
+
- **When enabling complex orchestration**: associations among declared nodes, tools, model capabilities, knowledge, checks, and output.
|
|
55
|
+
|
|
56
|
+
No default need to enable long-term memory, user profiles, experience libraries, vector databases, or dynamic tool loading. Deliver a read-only, single-round App with explicit sources first, then integrate each item according to real requirements.
|
|
57
|
+
|
|
58
|
+
## Provided versus still-App-owned capabilities
|
|
59
|
+
|
|
60
|
+
| Provided by the library | Still to be implemented by the App |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| Knowledge document parsing, in-memory catalogs, section selection, and snapshots | Reading files/databases, knowledge authorization, version computation, persistent import/modification/deletion |
|
|
63
|
+
| Answering task lists, checks, and bounded local repair | Task business definition, fact reading, model calls, business validation, and allowed fallback |
|
|
64
|
+
| Support context assembly and model call format adaptation | Request data, server-side identity, source trustworthiness, storage, and model connection configuration |
|
|
65
|
+
| TextSkills text catalog loading and metadata validation | Actual file reading, tool reference verification, update publishing, and reload timing |
|
|
66
|
+
| Core run records and optional diagnostics, Support's optional Provider observer | Log output, storage, sensitive content policy, queries, and operations |
|
|
67
|
+
|
|
68
|
+
For copy-and-run offline complete code see [Service answering example](examples/offline-agent.md). parse/define parse and compile knowledge in memory. For knowledge preparation and updates see [Knowledge maintenance flow](flows/knowledge-maintenance.md).
|
|
69
|
+
|
|
70
|
+
Profile merging, experience learning, long-term memory storage, document persistence, vector index storage, and file ingestion are implemented by the App. The relevant chapters provide integration boundaries and templates.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# App integration checks
|
|
2
|
+
|
|
3
|
+
[Back to development handbook](README.md) · [API reference](api/README.md)
|
|
4
|
+
|
|
5
|
+
The following are the evidence expected for an integration, chosen by developers according to the capabilities actually enabled; they are not a full command suite to run on every change. Review what the source can confirm first, and run the minimum relevant checks when a concrete question exists. Success with an offline stand-in does not prove real model behavior, and being executable by the framework does not prove the business facts are correct.
|
|
6
|
+
|
|
7
|
+
| Boundary | What should be proven | Minimal example |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Independent consumption | Usable from the delivery package, dependencies, and documentation alone | Import from the public exports in a standalone directory, with no application path aliases |
|
|
10
|
+
| Empty knowledge preparation | Knowledge stays empty when there are no facts | With no sources in an existing project, knowledge files are empty and the manifest contains no fabricated content |
|
|
11
|
+
| Source import | Fidelity of sources and versions | supplied-source bytes match; illegal anchors, duplicate sections, or exceeding limits are rejected |
|
|
12
|
+
| Registration and references | The manifest truly drives execution and references resolve | Unknown node/tool/reader/section/check fails explicitly |
|
|
13
|
+
| Protocol parsing | Schema is consistent with the actual input checks | Unknown fields, invalid values, and wrong output are rejected; parse has no business side effects |
|
|
14
|
+
| Execution | Only the permitted scope is executed, and receipts are real | When the model claims success but nothing ran, success must not be returned |
|
|
15
|
+
| Knowledge selection | self/subtree/document boundaries are correct | Child sections excluded/included, unknown IDs, limits, and version changes |
|
|
16
|
+
| Isolation | Identity and state do not leak across users | Another user ID is rejected; an old request does not mix into a new catalog |
|
|
17
|
+
| Cancellation and budget | Both I/O and retries are bounded | Timeout, cancellation, broken stream, and exhausted repair budget end correctly |
|
|
18
|
+
| Output | References and action states are bound by the program | Numbers, sources, links, and incomplete results are checked |
|
|
19
|
+
| Growth and maintenance | Candidates are never automatically promoted | Preparing a candidate does not change the effective source; failures keep the old version; broken references are rejected |
|
|
20
|
+
| Diagnostics | Errors are locatable and records do not change execution | The same request correlates stage, code, and duration, with no credentials or unauthorized body text |
|
|
21
|
+
|
|
22
|
+
When long-term memory is chosen, additionally verify message watermarks, concurrent versions, lease recovery, idempotency, deletion propagation, and source priority; if not enabled, these services need not be built. When cross-end operation is chosen, verify the actual peer handler and receipts; not using the Interaction Kit does not prevent integration with Core.
|
|
23
|
+
|
|
24
|
+
When reviewing similar capabilities, compare horizontally the ordinary loop, Workflow, standalone Runner, tool catalog, hand-written port, and the Kit in use, and confirm the same guarantee is enforced by the actual entry, not only by validating the recommended Support style. For cancellation, check pre-cancellation, mid-flight cancellation, late returns, and cancellation during persistence separately; for input, check illegal budgets, replacement after registration, and mutable references across awaits; for publication, check validity before and after verification and before commit.
|
|
25
|
+
|
|
26
|
+
Cancellation cases should also cover cancellation triggered inside synchronous callbacks such as counters, checkers, and observers, plus multiple processing stages within the same node. A Provider stand-in should record both the ordinary `stream()` method entry and reads through the async iterator, so that tests with only a generator do not mask entering an I/O factory after cancellation. Readers ignoring cancellation, evidence expiring during reading, discovery leaving no partially readable range after a pagination failure, and iterator cleanup exceptions not overwriting the original result all need to be verified against their own boundaries.
|
|
27
|
+
|
|
28
|
+
Reports should distinguish run defects under a normal contract, insufficient rejection of illegal configuration/integration misuse, and internal hardening or performance optimization. Passing regression proves only the boundaries it covers; it cannot replace App permission facts, real storage atomicity, external side-effect receipts, or real model behavior verification, nor does it prove the absence of defects overall.
|
|
29
|
+
|
|
30
|
+
## Explicit scope of the current template
|
|
31
|
+
|
|
32
|
+
The development kit provides an existing-project integration guide, plus section parsing and catalog compilation, candidate preparation, a read-only plan, and a shared validation entry. During knowledge preparation, organize actual sources faithfully when they exist and keep empty files when no source exists. The production App's identity system, knowledge permissions, upload parsing, storage transactions, profile merging, experience publishing, and indexing still need to be implemented by the App itself.
|
|
33
|
+
|
|
34
|
+
For partial code examples see [Quick integration](getting-started.md) and [Examples](examples.md). The [Offline complete example](examples/offline-agent.md) contains copy-and-run service answering code that uses the Support tool catalog and an offline Provider, so no model credentials are required. Verifying real model behavior requires an available model service and App configuration, checking semantic results, tool selection, and completeness separately.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Agent-assisted development for coding Agents
|
|
2
|
+
|
|
3
|
+
[Back to development handbook](README.md) · [Manual maintenance](maintenance.md) · [Skill](../skills/agent-core-app/SKILL.md)
|
|
4
|
+
|
|
5
|
+
The Agent here is a coding assistant that helps developers write applications; it is separate from the product Agent running in production. It needs to read public contracts, use maintenance tools, organize candidates, and implement App adaptation; it does not thereby gain permission to scan user disks, publish knowledge, or automatically install business code.
|
|
6
|
+
|
|
7
|
+
## How to adopt it
|
|
8
|
+
|
|
9
|
+
The package ships `development/skills/agent-core-app/SKILL.md`. Developers can hand its path to an assistant that supports Skills, or explicitly install/copy the **entire `agent-core-app` folder** following their own tool's discovery rules, keeping `scripts` and `templates`; the library does not automatically install it globally, create scheduled tasks, or load the Skill. Manual developers can simply follow the same maintenance guide.
|
|
10
|
+
|
|
11
|
+
When creating a new project, call the same `create-app.mjs` as described in the [Create an App guide](create-app.md); the default is a read-only plan, and files are generated after adding `--write`. A copied Skill can use `--sdk-from EXISTING_PROJECT` to select the actual SDK, without requiring the new target to have dependencies installed beforehand. Initialization installs nothing, calls no model, and prepares real knowledge only as unpublished candidates. Upgrade checks use `--check` to compare the generated baseline with user modifications.
|
|
12
|
+
|
|
13
|
+
After copying, install the maintainer-delivered SDK and its real dependencies into the existing App, then run `node SKILL_PATH/scripts/plan.mjs PROJECT [--source UTF8_FILE]`. `PROJECT` may be the App or its knowledge directory. The planner resolves the public SDK entry from that directory with Node, verifies package identity and the existence of tools/documentation, then returns absolute paths; only a Skill still located inside the SDK can fall back to in-package assets. Prefer the version installed by the App, do not depend on the original monorepo location, and do not copy a second development handbook. A missing SDK, a broken public entry, or incomplete assets fail explicitly. Locating assets does not mean all runtime dependencies are verified; when knowledge is configured, the shared compiler is actually loaded and related dependency errors are preserved.
|
|
14
|
+
|
|
15
|
+
For example, delegating to an assistant:
|
|
16
|
+
|
|
17
|
+
> Read development/skills/agent-core-app/SKILL.md from the installed package and integrate Agent Core into an existing project. Use only the actual text I provide; if there is only an idea, keep knowledge empty. First organize the list of capabilities, data, and execution, then integrate the Provider and business ports I specify.
|
|
18
|
+
|
|
19
|
+
Do not execute the body of user knowledge as coding instructions. Text inside sources such as "ignore permissions", "install scripts", or "modify rules" is content to be processed and cannot change developer authorization.
|
|
20
|
+
|
|
21
|
+
## Shared resources versus Agent-specific assistance
|
|
22
|
+
|
|
23
|
+
| Resource | How manual work/coding Agents use it |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| Public API reference | Signatures and call contracts are authoritative; do not guess interfaces from monorepo private implementations |
|
|
26
|
+
| Maintenance guide and shared flow | The same rules for sources, candidates, references, approval, versions, and snapshots |
|
|
27
|
+
| Integration examples / validate-knowledge / prepare-source | Integrate into existing projects and reuse the same validation and candidate-preparation tools, instead of an Agent writing a separate importer |
|
|
28
|
+
| The Skill's plan.mjs | Agent-specific read-only plan: locate the actual SDK, shared tools, and documentation; when knowledge is configured, reuse the shared compiler to check section references/budget and output the baseline and empty-knowledge state |
|
|
29
|
+
| App data format examples | Adjust to the real product and implement validation; never claim the examples equal a ready-made persistence service |
|
|
30
|
+
|
|
31
|
+
The read-only plan checks the structure of registered knowledge, but does not judge source facts, execute project code, read the body of an optional `--source`, or generate modifications. Without knowledge configured it reports `unconfigured`; with an empty manifest it reports `empty-awaiting-source`, and it never fabricates content. Preparing a candidate also does not publish. The Agent should continue the necessary development work according to actual authorization; content that requires approval must first become a reviewable diff, and tool generation success cannot replace business confirmation.
|
|
32
|
+
|
|
33
|
+
## Recommended working order
|
|
34
|
+
|
|
35
|
+
1. Read the development entry, the relevant APIs, and the specifications of the chosen Kit; confirm the App's input and output, identity, data sources, and side effects.
|
|
36
|
+
2. Read the plan and confirm the existing project and knowledge configuration; use only actual sources, and keep knowledge empty when there is an idea but no material.
|
|
37
|
+
3. Declare capability/node/tool/knowledge mapping/checks/output manifests first. When shared input organization is needed, a unified context may be used; do not invent a dispatch abstraction merely to remove a single if.
|
|
38
|
+
4. Integrate the adaptation inside the project, organize code by responsibility, and preserve existing configuration. For knowledge iteration, use the candidate tools and the knowledge compilation entry.
|
|
39
|
+
5. Implement App-owned Providers, storage, permissions, and business validation, keeping model proposal, execution, and delivery separate.
|
|
40
|
+
6. Perform minimal verification for concrete questions and report actual results and unverified scope; do not treat offline fixtures as real model acceptance.
|
|
41
|
+
|
|
42
|
+
Multiple short conditions may stay clearly parallel; complex validation should be grouped semantically, and the differences among OR predicate arrays in `occur`, multiple check objects, and multiple calls affect tags and observation. Do not merge all branches merely because the output is identical, and do not impose pattern-matching tools on a single judgment that is already readable.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Agent Core API
|
|
2
|
+
|
|
3
|
+
This handbook describes the current SDK module by module. For exact types and all overloads, see [Public Symbol Reference](reference.md).
|
|
4
|
+
|
|
5
|
+
Core defines runtime interfaces and execution guarantees, Support provides recommended implementations and configuration strategies, and Kit provides optional business capabilities for Apps. Pure algorithms use their own input and output contracts.
|
|
6
|
+
|
|
7
|
+
## Start with these seven rules
|
|
8
|
+
|
|
9
|
+
1. Entities use `id`; references to entities use `toolId`, `documentId`, etc.; `name` is the display name.
|
|
10
|
+
2. `jsonSchema` is always a read-only JSON Schema; `inputSchema` is always `SchemaAdapter<T>`, whose `parse` performs the actual parsing.
|
|
11
|
+
3. `is/can/has` return booleans; `assert/authorize` return void on success and throw on failure; `check` returns an issue report; `parse` returns the converted value.
|
|
12
|
+
4. `define` compiles a static declaration; `create/new` create an adapter or runtime instance. Request state, signal, and budget are bound at runtime.
|
|
13
|
+
5. Input first, context second. Complex calls use named requests; `get(id)` returns undefined when missing, `require(id)` throws when missing.
|
|
14
|
+
6. A successful invoke uniformly returns `{ value, invocation }`; the short input form only normalizes input, both text and structured values are placed in value, and failures uniformly throw.
|
|
15
|
+
7. An observer is non-blocking observation of the business; a sink is delivery that must be awaited. They do not have the same semantics just because both return Promises.
|
|
16
|
+
|
|
17
|
+
## Imports and reading order
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { AgentCoreEngine, ModelRunner, Support } from '@jangts/agent-core';
|
|
21
|
+
import { defineKnowledgeCatalog } from '@jangts/agent-core/kits/knowledge';
|
|
22
|
+
import { defineAnswerFlow } from '@jangts/agent-core/kits/answering';
|
|
23
|
+
import type { SchemaAdapter, OperationContext, Issue } from '@jangts/agent-core';
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Use Core services and common contracts from the root entry, integration helpers from `Support`, and Kits from their own entries with named functions or constructors. The full `/kits` entry and the individual entries export the same implementations.
|
|
27
|
+
|
|
28
|
+
| Order | Document | What you learn |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| 1 | [Common types and rules](types.md) | Identity, schema, validation, errors, context, collections, ownership |
|
|
31
|
+
| | [Workflow primer](workflow.md) | Agent binding, nodes, routes, and derivation |
|
|
32
|
+
| 2 | [Core](core.md) | Model calls, capabilities, tool execution, workflow, and events |
|
|
33
|
+
| 3 | [Support](support.md) | Schema, tool and capability catalogs, transport, and context assembly |
|
|
34
|
+
| | [Context processing](context-processing.md) | Budget, watermarks, compression, and original-text protection |
|
|
35
|
+
| 4 | [Knowledge, answering, and presentation](knowledge-answering.md) | Evidence gathering, checks, local repair, program-bound output |
|
|
36
|
+
| 5 | [Remaining Kits](kits.md) | Intent, interaction, retrieval, rules, artifacts, and persistent tasks |
|
|
37
|
+
| | [Retrospectives, branches, and material publishing](advanced-agents.md) | Bounded subtasks, metadata evidence, persistent versions, and source validation |
|
|
38
|
+
| 6 | [End-to-end examples](examples.md) | Declare tools, invoke models, and perform real operations with one set of contracts |
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
For the unified source of truth for logs and Journal, call-chain correlation, and relationship table mapping, see [Requests, call chains, and Journal](observability.md).
|
|
42
|
+
|
|
43
|
+
## One-page quick reference
|
|
44
|
+
|
|
45
|
+
| Task | Preferred interface | Result |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| A single model call | `runner.invoke({ stageId, input, transport })` | ModelResult: value is the complete parsed value; raw chunks only go to the sink |
|
|
48
|
+
| Execute a tool | `tools.invoke({ toolId, input })` | ToolResult: value is the actual result that has been parsed, authorized, executed, and checked |
|
|
49
|
+
| Compile a workflow | `defineWorkflow(definition)` | A `Workflow` not bound to a request |
|
|
50
|
+
| Run a workflow | `agent.run(state)` | A value that satisfies the final result contract |
|
|
51
|
+
| Declare a tool | `Support.defineTool(definition)` | A typed definition sharing its source with the model schema |
|
|
52
|
+
| Create a request tool instance | `catalog.bind({ app, execution })` | A `ToolRuntime` whose lifetime is limited to this request |
|
|
53
|
+
| Obtain a registered entry | `catalog.get(id)` / `catalog.require(id)` | Optional lookup / mandatory lookup |
|
|
54
|
+
| Check a value | `checker.check(value, context)` | `CheckResult`, not a boolean or an error alias |
|
|
55
|
+
| Read material | `knowledge.read({ documentId, selection })` | A snapshot with version, selection, and identity |
|
|
56
|
+
| Resume a persistent task | `task.run({ taskId, store }, context)` | A copy of the confirmed result; write operations are not replayed automatically |
|
|
57
|
+
|
|
58
|
+
Synchronous algorithms remain synchronous. Source schema, permissions, budget, cancellation, and final commit checks are not relaxed by adopting these helper interfaces. The App's own business state is not promoted to a required field of every Kit.
|
|
59
|
+
|
|
60
|
+
## Mock model
|
|
61
|
+
|
|
62
|
+
The [MockGPT Kit](mock.md) describes `@jangts/agent-core/mock` and its `/node` and `/web` entries: rules and generators, direct return values, HTTP/SSE, tool proposals, web sources, errors, cancellation, and budget.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Reflection, Branches, and Knowledge Publication
|
|
2
|
+
|
|
3
|
+
[Core](core.md) provides the model invocation, execution, branch identity, and cancellation contract. [Kit](kits.md) handles reflection, data versions, and durable tasks on the authorization and storage ports supplied by the App.
|
|
4
|
+
|
|
5
|
+
The authorize, Family.validate, and verifySources callbacks of these Kits are assertion-style callbacks: they return void on success and throw on rejection; returning any other value synchronously or asynchronously, such as false, true, or null, is treated as a contract error, and execution or saving does not continue.
|
|
6
|
+
|
|
7
|
+
Family and knowledge publication fix the request identity, target, and serializable data before entering asynchronous authorization or reads; later modifications to the original request do not change this operation. Family read validation and authorization obtain isolated data; a check callback cannot be used to rewrite stored originals or pending records. Source references must not contain missing entries, and validity is still checked before commit.
|
|
8
|
+
|
|
9
|
+
## Bounded Subtask Composition
|
|
10
|
+
|
|
11
|
+
Ordinary tasks call the same `createChild` entry point. When composing multiple independent tasks, `Support.runChildren` starts child runners according to the capacity of the root runner, isolating the journal, signal, and output; each task still uses its own ordinary handler or Workflow.
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import { ModelRunner, Support } from '@jangts/agent-core';
|
|
15
|
+
|
|
16
|
+
export async function analyze(provider, inputs, signal) {
|
|
17
|
+
const model = new ModelRunner({ provider, maxCalls: 8, execution: { signal },
|
|
18
|
+
children: { maxDepth: 2, maxConcurrentCalls: 2, maxChildren: 8 } });
|
|
19
|
+
return Support.runChildren(model, inputs.map((text, index) => ({
|
|
20
|
+
id: `part-${index}`, maxCalls: 2, reserveCalls: 1, timeoutMs: 30000,
|
|
21
|
+
transports: [],
|
|
22
|
+
async run(child) { return (await child.invoke(text)).value; },
|
|
23
|
+
})), {
|
|
24
|
+
concurrency: 2,
|
|
25
|
+
accept(value) { if (typeof value !== 'string' || !value.trim()) throw Error('Empty analysis'); },
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Both `accept` and `commit` return void on success; rejection is expressed by throwing, not by a boolean return value. The transport list of subtasks is fixed when the group starts. `accept` checks each result, and waiting remains subject to that subtask's cancellation and deadline; only after all results are accepted is the optional `commit(value, id)` called in declaration order. Failure of any task or acceptance check cancels the tasks in the same group, and late results cannot enter the commit. `commit` is the App's real side-effect port; a commit that has already happened cannot pretend to roll back because of cancellation. When whole-group atomicity is required, the App commits the entire returned array in a real transaction. Role and tool lists are registered explicitly; subtask execution does not inherit permissions automatically.
|
|
31
|
+
|
|
32
|
+
accept likewise follows the assertion contract: it returns void on success and rejects any other return value, so false cannot be treated as a successful check.
|
|
33
|
+
|
|
34
|
+
## Metadata Reflection
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { defineReflection } from '@jangts/agent-core/kits/reflection';
|
|
38
|
+
import type { ReflectionSource } from '@jangts/agent-core/kits/reflection';
|
|
39
|
+
import type { ModelRunner, OperationContext } from '@jangts/agent-core';
|
|
40
|
+
|
|
41
|
+
export function review<App>(model: ModelRunner, source: ReflectionSource<App>,
|
|
42
|
+
authorize: (question: string, context: OperationContext<App>) => Promise<void>) {
|
|
43
|
+
return defineReflection({ model, source, authorize,
|
|
44
|
+
maxCalls: 4, reserveCalls: 1, maxPages: 4, maxEvents: 64, maxEvidenceChars: 12000 });
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`run(question, context)` obtains evidence through the registered `history.query` tool, and the model can choose to discover runs, read events, or submit a report. The Source validates the real account and scope for every query; the output exposes fixed metadata fields and does not carry log bodies. Reports distinguish observed, hypothesis, and recommendation; observed entries must reference evidence IDs actually returned in this operation. Incomplete reads, expiration, insufficient budget, or protocol failure all preserve the real limitation, and reports default to `persisted: false`.
|
|
49
|
+
|
|
50
|
+
`defineReflectionLogSource({ reader, id, traceId, authorize })` can adapt an App-owned structured log reader: it fixes the trace scope, reads only the runs discovered in this operation, and projects only Core metadata. Actual time, span/parent span, and invocation and branch identity are preserved through a fixed list so the report can reference real relationships. Coverage information keeps only consistency, complete, and gaps; other fields attached by the source are not forwarded. The App owns the catalog, account validation, closing of the reader, and log retention. Additional tools must be read-only, with their list and canonical methods fixed at construction time, and they still follow the ordinary tool input, authorization, and output contract.
|
|
51
|
+
|
|
52
|
+
Logs read metadata according to event declarations: model.end uses payload.state, workflow.event uses payload.event, and loop.event uses its own payload. The actual lifecycle of workflows and loops is mapped to running/success/error/cancelled; error codes and durations are preserved along the same projection, and raw error text is not sent to the model.
|
|
53
|
+
|
|
54
|
+
Read permission, handing data to the model, and disclosing results are independent decisions. A missing log cannot prove that nothing ran, and the sub-steps of a dynamic report cannot prove the real internal scheduling. Delivery is refused when the source data expires before it is returned.
|
|
55
|
+
|
|
56
|
+
The report's `createdAtMs`, and the evidence's and report's `expiresAtMs`, are absolute millisecond times, using the same unit as the event's `occurredAtMs`.
|
|
57
|
+
|
|
58
|
+
## Durable Branches and Explicit Promotion
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { defineAgentFamily } from '@jangts/agent-core/kits/family';
|
|
62
|
+
import type { FamilyStore } from '@jangts/agent-core/kits/family';
|
|
63
|
+
import type { OperationContext } from '@jangts/agent-core';
|
|
64
|
+
|
|
65
|
+
type State = { goal: string; sourceRevision: string };
|
|
66
|
+
export function family<App>(store: FamilyStore<State>,
|
|
67
|
+
authorize: (context: OperationContext<App>) => Promise<void>,
|
|
68
|
+
verify: (state: State) => Promise<void>) {
|
|
69
|
+
return defineAgentFamily<State, App>({
|
|
70
|
+
store, maxVersions: 16, retentionMs: 7 * 86400000,
|
|
71
|
+
isState: (value): value is State => !!value && typeof (value as State).goal === 'string'
|
|
72
|
+
&& typeof (value as State).sourceRevision === 'string',
|
|
73
|
+
authorize: (_operation, _record, context) => authorize(context),
|
|
74
|
+
validate: candidate => verify(candidate.state),
|
|
75
|
+
async merge({ base, target, source }) {
|
|
76
|
+
if (target.goal !== base.goal && source.goal !== base.goal && target.goal !== source.goal)
|
|
77
|
+
return { conflicts: ['goal'] };
|
|
78
|
+
return { value: target.goal === base.goal ? source : target, conflicts: [] };
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`create` establishes the initial version; `fork` receives the real parent branch identity and the cloned state; `merge` requires a common base and relies on the App's three-way merger to report conflicts. A new version is first saved as a candidate. `promote({ id, revision, candidateId, expectedActiveId }, context)` rechecks the current source and approval responsibility and explicitly switches activeId. Only candidates whose base is the current active version may be promoted.
|
|
85
|
+
|
|
86
|
+
`FamilyStore.compareAndSwap` must atomically commit the complete version set and activeId in real storage; only a true return is a success receipt. Read permission is enforced by the bound store, while mutations go through authorize separately. Branch data does not restore identity, budget authorization, tool instances, or running functions; the App rebinds current dependencies when it uses a selected version. When the Engine has already bound request-level model or tool runtime instances, `fork`'s `resume` must supply the corresponding instances; if they are missing, it rejects during derivation. The Engine's `exportCheckpoint`/`restoreCheckpoint` handle serializable checkpoints, and Family manages the App's version set.
|
|
87
|
+
|
|
88
|
+
Versions use `createdAtMs`, and sets use `expiresAtMs`, both absolute millisecond times. App-owned database fields can be mapped to these contract fields at the store boundary.
|
|
89
|
+
|
|
90
|
+
## Durable Professional Tasks
|
|
91
|
+
|
|
92
|
+
```js
|
|
93
|
+
import { defineDurableTask } from '@jangts/agent-core/kits/durable';
|
|
94
|
+
|
|
95
|
+
export function professionalTask(store, isState, authorize, analyze) {
|
|
96
|
+
return defineDurableTask({ id: 'app.review', revision: '1', isState, authorize,
|
|
97
|
+
steps: [{ id: 'analyze', replayPolicy: 'safe',
|
|
98
|
+
async run(state, context) {
|
|
99
|
+
// analyze binds its real model runner to context.maxModelCalls.
|
|
100
|
+
return analyze(state, context);
|
|
101
|
+
},
|
|
102
|
+
}],
|
|
103
|
+
}, { store });
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The App creates a version=2 checkpoint and sets definitionId/revision, state, nextStepIndex=0, attemptCount=0, maxAttempts, a fixed deadlineAtMs, and status=ready. When a cumulative model limit is needed, `modelBudget` is saved as well. A task runs only when the App explicitly calls `run({ taskId }, context)`.
|
|
108
|
+
|
|
109
|
+
Resume first acquires the exclusive lock and re-authorizes, checks the source version and execution deadline, and then saves the attempt count and model reservation. The App binds each reservation to the real runner; reads, reviews, and their sub-calls all stay within this budget. Failures do not return the reservation, and completed steps are not re-run. Steps that may already have committed side effects use reconcile and provide real receipt queries; commit status cannot be guessed from chat text.
|
|
110
|
+
|
|
111
|
+
After a checkpoint is read, authorization is also bound by the fixed deadlineAtMs. Cancellation or expiration can stop waiting for authorization and the work handler; a checkpoint save that has already started must still await confirmation before the store's exclusive lock is released.
|
|
112
|
+
|
|
113
|
+
## Candidate Knowledge and Publication
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
import { Knowledge } from '@jangts/agent-core/kits/knowledge';
|
|
117
|
+
|
|
118
|
+
export function publication(store, authorize, verifySources) {
|
|
119
|
+
return Knowledge.defineKnowledgePublication({ store, authorize, verifySources,
|
|
120
|
+
maxCandidates: 32, candidateRetentionMs: 7 * 86400000,
|
|
121
|
+
requiredReads: [{ documentId: 'guide', selection: { mode: 'document' } }],
|
|
122
|
+
maxReadChars: 12000,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`propose({ revision, document, sources }, context)` uses the same Knowledge compiler to check the complete post-replacement document set and requiredReads, and writes only a candidate. `publish({ revision, candidateId }, context)` re-authorizes and verifies the source versions, validity periods, and publishedRevision, then replaces the official set once with CAS and removes the candidate. `reject` explicitly deletes the candidate. Changing body text or metadata requires a new revision for the document.
|
|
128
|
+
|
|
129
|
+
Candidate and source deadlines are checked again after asynchronous verification, document compilation, and preparation of the commit snapshot, and only after that check passes does CAS start; a storage commit that has already started keeps waiting for the real receipt and does not falsely claim a rollback because of a deadline passing midway.
|
|
130
|
+
|
|
131
|
+
The store's revision coordinates all writes, and publishedRevision specifically identifies changes to the official set; a candidate based on an outdated official version must be prepared again. Ordinary knowledge reads build the catalog from record.documents and do not mix candidates in as facts. Human-authored material, cumulative preferences, and experience candidates each have their own sources, permissions, and lifecycles; publication is explicitly authorized by the App, and the model does not obtain permission on its own.
|
|
132
|
+
|
|
133
|
+
The same instance caches the compile-check result of the most recent record, with a key containing revision, publishedRevision, and the full document content; content changes under the same version number are still re-checked. The cache does not replace store reads, operation authorization, source verification, or validity checks.
|
|
134
|
+
|
|
135
|
+
A candidate's `createdAtMs`/`expiresAtMs` and a source's optional `expiresAtMs` use absolute millisecond times; `candidateRetentionMs` is a duration. Source expiration cannot be extended by candidate retention.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Context node
|
|
2
|
+
|
|
3
|
+
Core accepts text, messages, BuiltContext, or ContextPlan, and is responsible for generic input assembly, trust and structure constraints, actual request measurement, and the final budget. Assembly strategy, selection, grouped trimming, summarization, and retention policies are owned by ordinary Workflow nodes in the App; Support provides recommended implementations.
|
|
4
|
+
|
|
5
|
+
## Progressive configuration from a single call
|
|
6
|
+
|
|
7
|
+
When no processing is needed, call `runner.invoke({ input })` or `context.model.invoke({ input })` directly. An over-limit ContextPlan is rejected; processing steps are never inserted implicitly.
|
|
8
|
+
|
|
9
|
+
When processing is needed, register a Support node in the same Workflow:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const processing = Support.createContextProcessingNode({
|
|
13
|
+
id: 'context', description: '处理本轮上下文',
|
|
14
|
+
plan: state => state.plan,
|
|
15
|
+
request: { stageId: 'reply', transport, maxOutputTokens: 1000 },
|
|
16
|
+
policy: { mode: 'reduce', steps: [
|
|
17
|
+
{ id: 'summary', kind: 'compress', fragmentId: 'history',
|
|
18
|
+
targetChars: 4000, handlerId: 'summary' },
|
|
19
|
+
] },
|
|
20
|
+
compressors: [compressor],
|
|
21
|
+
update: result => ({ input: result.input, prepared: result.prepared }),
|
|
22
|
+
routes: [route.to('answer')],
|
|
23
|
+
});
|
|
24
|
+
// answer 是普通节点:
|
|
25
|
+
// (await context.model.invoke({ input: state.input, prepared: state.prepared })).value
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The generator returns an ordinary WorkflowNode, configured through defineWorkflow and executed by agent.run. A custom implementation may supply the node's run directly. The canonical methods of plan, request, prepared, and update bind their receiver at assembly time, and the policy and handler lists form a snapshot; the App service keeps its original identity.
|
|
29
|
+
|
|
30
|
+
## Explicit selection and compression
|
|
31
|
+
|
|
32
|
+
When selection, compression, and assembly must be observed separately on the main graph, use three ordinary nodes and let App routing decide the execution order:
|
|
33
|
+
|
|
34
|
+
| Generator | Actual work | Result |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| createContextSelectionNode | Validates candidates and protection boundaries, selects affordable registered steps by policy | ContextSelectionResult: plan, prepared, stepIds, report |
|
|
37
|
+
| createContextReductionNode | Executes one trim or compression specified by stepId, audits the result | ContextStageResult: processed plan, prepared, report |
|
|
38
|
+
| createContextProcessingNode | Processes according to configuration and completes assembly; the default validate only checks and assembles | ContextNodeResult: input, prepared, report |
|
|
39
|
+
|
|
40
|
+
The three generators use the same base node fields, plan/prepared/request inputs, and update output mapping. Subsequent nodes reuse the previous node's handle through the prepared callback, avoiding a second dynamic prepare. The App chooses its own state fields; these Support results do not become global state required by Core. An independent implementation still only needs to satisfy the input/output contract of the corresponding Workflow.
|
|
41
|
+
|
|
42
|
+
The same over-limit data is rejected when processing is not enabled; adding selection, reduction, and assembly nodes allows it to continue. When replacing the reduction node, a standalone class only needs to provide the same id, run, and routes and preserve the plan's audit input; Core's enter facts prove that the node was actually entered.
|
|
43
|
+
|
|
44
|
+
## Scenario recommendations and precise overrides
|
|
45
|
+
|
|
46
|
+
`createContextStrategy` generates the same node configuration from registered fragments:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
const strategy = Support.createContextStrategy({
|
|
50
|
+
kind: 'continuity', fragment: historyDefinition, field: 'history', compressor,
|
|
51
|
+
targetChars: 4000, keepGroups: 3,
|
|
52
|
+
});
|
|
53
|
+
const node = Support.createContextProcessingNode({
|
|
54
|
+
...strategy,
|
|
55
|
+
id: 'context', description: '保留近期原文并整理旧历史',
|
|
56
|
+
plan: state => state.plan,
|
|
57
|
+
update: result => ({ input: result.input, prepared: result.prepared }),
|
|
58
|
+
routes: [route.to('answer')],
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
recent generates a local window of complete rounds without calling the model; continuity generates a summary of the old segment plus protection of recent raw text, and model cost depends on the supplied compressor. Step IDs, handlerIds, and the registration array are generated from the same input. targetChars defaults to the fragment's maxChars, grouping defaults to user-turn, and keepGroups defaults to 1; explicit values take precedence, and 0 is not treated as a default. When a model selector or a fully custom policy is needed, add the same node's policy or selectors, or replace the node implementation directly, without switching the dispatch protocol.
|
|
63
|
+
|
|
64
|
+
## Low-level configuration of recommended strategies
|
|
65
|
+
|
|
66
|
+
Support.ContextPolicy has three modes:
|
|
67
|
+
|
|
68
|
+
| Mode | Behavior |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| validate | No reduction; only validate and assemble |
|
|
71
|
+
| reduce | Select limited processing operations by steps and selection |
|
|
72
|
+
| audit | Inspect fragments before and after App processing; only mutableFragmentIds may change values |
|
|
73
|
+
|
|
74
|
+
reduce selection methods are sequence, fixed, auto, and model. Without a configured selection, steps run in order; fixed restricts to trim or compress; auto previews trim loss for complete groups, prefers safe trimming, and otherwise chooses affordable compression; model calls a registered selector that returns a step ID. Selectors cannot provide new tools, handlers, permissions, or budget.
|
|
75
|
+
|
|
76
|
+
auto's maxTrimLossRatio defaults to 0.25; it is a JSON character-reduction heuristic, not semantic loss or an optimal-quality guarantee. Multiple trims of the same fragment accumulate, and small steps cannot bypass the limit. An empty selection means there is no safe processing item; a final over-limit is still rejected and is not disguised as successful processing.
|
|
77
|
+
|
|
78
|
+
triggerChars/triggerTokens are early trigger watermarks; targetInputChars/targetInputTokens are soft targets. Each step runs at most once; if the soft target is not reached but the final hard limit is satisfied, execution continues, while exceeding the hard limit is rejected. Trim targets use the full JSON length of the fragment value and cannot cut a single message.
|
|
79
|
+
|
|
80
|
+
## Protection, grouping, and raw text
|
|
81
|
+
|
|
82
|
+
Fragments keep id, sourceId, trust, role, lifetime, maxChars, and structured top-level fields. Fragments from system, instruction, and those outside the processing list are immutable. Reduction results cannot grow longer, and low-trust history is never promoted to instructions. Auditing can only prove structure and boundaries, not that summary facts are correct.
|
|
83
|
+
|
|
84
|
+
History supports fixed complete groups or user-turn grouping. user-turn starts at a user message and keeps the multiple assistant messages after it plus a user round that has not yet been answered; isolated openings, unknown roles, and non-text entries are rejected for processing. Recent raw-text retention is configured in the compression step:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
{
|
|
88
|
+
id: 'summary', kind: 'compress', fragmentId: 'history', targetChars: 8000,
|
|
89
|
+
handlerId: 'summary',
|
|
90
|
+
preserve: { field: 'history', keepGroups: 3, grouping: { kind: 'user-turn' } },
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Support passes only the old segment to the handler and stitches the recent tail back unchanged. The return value must maintain fields and legitimate grouping. If the preserved content itself exceeds the limit, it is rejected rather than deleted; with no old segment, the summary model is not called. The App decides the retention count, fact checking, and whether to persist the summary; this capability does not modify history storage.
|
|
95
|
+
|
|
96
|
+
Core's ContextPlan can provide trusted originalFragments and mutableFragmentIds for generic diff auditing; it does not send the original fragments to the model. Additional image messages are retained through additionalMessages, and their text counts toward the body budget. Image binaries continue to follow a separate input boundary.
|
|
97
|
+
|
|
98
|
+
## Actual measurement and quota
|
|
99
|
+
|
|
100
|
+
The node prepares one real transport and reuses the same snapshot for measurement and sending. The body is constrained by maxInputChars, and transport instructions and declarations by maxSchemaChars; if a JSON Schema is embedded in the instructions, it is not double-counted in the actual total. When tokenBudget is configured, the counter receives the actual neutral request fields including instructions, Schema, and images, and deducts the output reservation and safety margin; Core does not guess the character-to-token ratio or provider capacity.
|
|
101
|
+
|
|
102
|
+
Actual input continues to be validated before the final Provider call. Node estimates, processing reports, and withinBudget are not release credentials. The prepared handle belongs to this Runner/Workflow request and can be consumed only once.
|
|
103
|
+
|
|
104
|
+
The selector/compressor maxCalls declares the model calls available per handler, defaulting to 1, with 0 for pure local implementations. Support enforces callModel and shares the same total quota of the Runner/Workflow. auto/model reserveCalls default to at least 1 to protect the final answer; candidate budgets are judged conservatively by the declared maximum call count. Core still deducts actual calls atomically and does not refund failures.
|
|
105
|
+
|
|
106
|
+
Node processing deadlines default to Core's basic single-run limit and can be precisely overridden with timeoutMs; they combine with the parent signal and do not extend the deadline. Internal model requests also receive that signal. Handlers that ignore cancellation, late results, and suspended content sinks must not commit success.
|
|
107
|
+
|
|
108
|
+
## Process observation
|
|
109
|
+
|
|
110
|
+
Selection, compression, and assembly use the start, transition, completion, failure, and duration facts of ordinary nodes. context.report adds an approved processing report; nodes do not create spans, write logs, or manage diagnostics. Listening and persistent log switches are independent; see [Process observation](observability.md#state-and-output-during-a-run) for details.
|