dsh-a2a-server 0.2.0 → 0.3.0
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 +28 -0
- package/CHANGELOG.zh-CN.md +28 -0
- package/README.md +99 -26
- package/README.zh-CN.md +67 -27
- package/cordis.patch.yml +10 -6
- package/lib/briefing.d.ts +39 -0
- package/lib/briefing.d.ts.map +1 -0
- package/lib/briefing.js +108 -0
- package/lib/briefing.js.map +1 -0
- package/lib/config.d.ts +54 -15
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +70 -5
- package/lib/config.js.map +1 -1
- package/lib/contexts.d.ts +9 -4
- package/lib/contexts.d.ts.map +1 -1
- package/lib/contexts.js +7 -13
- package/lib/contexts.js.map +1 -1
- package/lib/index.d.ts +1 -31
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +418 -439
- package/lib/index.js.map +1 -1
- package/lib/management.d.ts +5 -0
- package/lib/management.d.ts.map +1 -0
- package/lib/management.js +74 -0
- package/lib/management.js.map +1 -0
- package/lib/projection.d.ts +46 -3
- package/lib/projection.d.ts.map +1 -1
- package/lib/projection.js +19 -8
- package/lib/projection.js.map +1 -1
- package/lib/router.d.ts +45 -0
- package/lib/router.d.ts.map +1 -1
- package/lib/router.js +207 -65
- package/lib/router.js.map +1 -1
- package/lib/security.d.ts +4 -2
- package/lib/security.d.ts.map +1 -1
- package/lib/security.js +4 -2
- package/lib/security.js.map +1 -1
- package/lib/state.d.ts +37 -0
- package/lib/state.d.ts.map +1 -0
- package/lib/state.js +146 -0
- package/lib/state.js.map +1 -0
- package/lib/tasks.d.ts +4 -0
- package/lib/tasks.d.ts.map +1 -1
- package/lib/tasks.js +18 -0
- package/lib/tasks.js.map +1 -1
- package/lib/types.d.ts +9 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/workspace-read.d.ts +9 -0
- package/lib/workspace-read.d.ts.map +1 -0
- package/lib/workspace-read.js +152 -0
- package/lib/workspace-read.js.map +1 -0
- package/package.json +39 -30
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
[English](CHANGELOG.md) · [简体中文](CHANGELOG.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
## 0.3.0
|
|
6
|
+
|
|
7
|
+
Requires DeepSeek Harness `>=0.2.1-rc.2 <0.3.0` and speaks A2A 1.0 JSON-RPC.
|
|
8
|
+
|
|
9
|
+
- Restrict visitors to chat and `read_file` within the owner's selected data directory. Block path escapes, links, private plugin state and other tools; separate public prompt context from the owner's runtime context.
|
|
10
|
+
- Move owner RPC and monitoring to authenticated local IPC. Public HTTP accepts visitor credentials only. An empty `trustedPeers` list denies all visitors.
|
|
11
|
+
- Bound concurrent tasks, daily admission, execution time, model calls, outputs and stream buffers. Prevent concurrent tasks in one context from mixing answers; clean up disconnected SSE subscriptions.
|
|
12
|
+
- Persist task results and idle conversation history across eviction and restart within the retention window. Fail interrupted work without replaying it.
|
|
13
|
+
- Add the optional Portal-configured automatic briefing loop: default-on hourly updates, a persistent switch, restart-safe timing, and direct publication to `.hop/handoff.md`.
|
|
14
|
+
- Declare required runtime packages and verify imports without development dependencies. Preserve the guard against malformed Unicode from upstream streaming decoders.
|
|
15
|
+
|
|
16
|
+
Validation: 217 tests in 15 files, TypeScript checking, build and declared-runtime package import check. Models are deterministic test adapters; real-model and cross-network deployment verification remain separate.
|
|
17
|
+
|
|
18
|
+
### Upgrade
|
|
19
|
+
|
|
20
|
+
Stop the agent, update dsh if needed, then install into the existing profile:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
dsh plugin --profile YOUR_PROFILE add dsh-a2a-server@0.3.0
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Replace `YOUR_PROFILE` with the saved profile name and restart the agent. Upgrade the companion [Talk2MyAgent Portal](https://github.com/huangjuhua-aigc/Talk2MyAgent) for the private management endpoint and automatic briefing settings. Do not recreate an existing profile with `--from-default-profile` during an upgrade.
|
|
27
|
+
|
|
28
|
+
Old HTTP owner/monitoring integrations must migrate to local IPC. Review visitor admission and the selected data directory before exposing the service. [Migration details](https://github.com/huangjuhua-aigc/dsh-a2a/blob/main/docs/public-access-hardening.en.md).
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 更新日志
|
|
2
|
+
|
|
3
|
+
[English](CHANGELOG.md) · [简体中文](CHANGELOG.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
## 0.3.0
|
|
6
|
+
|
|
7
|
+
要求 DeepSeek Harness `>=0.2.1-rc.2 <0.3.0`,使用 A2A 1.0 JSON-RPC。
|
|
8
|
+
|
|
9
|
+
- 访客可以聊天,并通过 `read_file` 读取主人指定的资料目录。拦截路径越界、链接、插件私有状态及其他工具;公共模型提示与主人运行时上下文分离。
|
|
10
|
+
- 主人 RPC 和监控迁到需要认证的本机 IPC;公网 HTTP 仅接受访客凭据。空白名单 `trustedPeers: []` 拒绝全部访客。
|
|
11
|
+
- 限制并发、每日任务数、执行时限、模型调用、输出和流缓冲;同一 context 的并发请求不会串答,SSE 断开后释放订阅。
|
|
12
|
+
- 在保留期内持久化任务结果与空闲对话,支持驱逐和重启后的恢复。重启中断的任务标记失败,不自动重放。
|
|
13
|
+
- 增加由 Portal 配置的自动简报循环:默认每小时更新、一个持久化开关、重启去重,完成后直接写入 `.hop/handoff.md`。
|
|
14
|
+
- 补齐运行依赖声明,验证脱离开发依赖后可导入。保留上游流式解码异常的 Unicode 防护。
|
|
15
|
+
|
|
16
|
+
验证:15 个文件共 217 项测试、类型检查、构建和仅使用声明运行依赖的包导入检查。测试使用确定性模型;真实模型与跨网络部署需要单独验收。
|
|
17
|
+
|
|
18
|
+
### 升级
|
|
19
|
+
|
|
20
|
+
停止 agent,必要时升级 dsh,然后更新原有 profile 中的插件:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
dsh plugin --profile YOUR_PROFILE add dsh-a2a-server@0.3.0
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
将 `YOUR_PROFILE` 替换为已保存的 profile 名称,安装后重新启动。配套 [Talk2MyAgent Portal](https://github.com/huangjuhua-aigc/Talk2MyAgent) 也需要更新,以使用私有管理入口和自动简报开关。升级已有 profile 时不要再次使用 `--from-default-profile`。
|
|
27
|
+
|
|
28
|
+
原来的 HTTP 主人/监控调用必须迁移至本机 IPC。部署前检查访客许可与资料目录,详见[迁移指南](https://github.com/huangjuhua-aigc/dsh-a2a/blob/main/docs/public-access-hardening.md)。
|
package/README.md
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
<a href="https://www.npmjs.com/package/dsh-a2a-server"><img src="https://img.shields.io/npm/v/dsh-a2a-server?style=flat&label=npm&color=CB3837" alt="npm version"></a>
|
|
17
17
|
<a href="https://github.com/huangjuhua-aigc/dsh-a2a/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-2EA44F?style=flat" alt="MIT License"></a>
|
|
18
18
|
<img src="https://img.shields.io/badge/A2A-v1.0%20JSON--RPC-4D6BFE?style=flat" alt="A2A v1.0 JSON-RPC binding">
|
|
19
|
-
<img src="https://img.shields.io/badge/DSH-0.1
|
|
20
|
-
<img src="https://img.shields.io/badge/tests-
|
|
19
|
+
<img src="https://img.shields.io/badge/DSH-0.2.1--rc.2-4493F8?style=flat" alt="Built against DSH 0.2.1-rc.2">
|
|
20
|
+
<img src="https://img.shields.io/badge/tests-217-2EA44F?style=flat" alt="217 tests">
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
23
|
`dsh-a2a-server` makes a [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
@@ -30,14 +30,21 @@ The plugin is **inbound only**: it never connects to another agent. There is no
|
|
|
30
30
|
client, no peer directory, and no A2A subagent provider. It is a transport
|
|
31
31
|
adapter over `ctx.agents`, not a capability seam.
|
|
32
32
|
|
|
33
|
+
For a local configuration UI and cross-network access, use the companion
|
|
34
|
+
[Talk2MyAgent setup guide](https://github.com/huangjuhua-aigc/Talk2MyAgent/blob/main/README.en.md).
|
|
35
|
+
See the [deployment and migration guide](https://github.com/huangjuhua-aigc/dsh-a2a/blob/main/docs/public-access-hardening.en.md)
|
|
36
|
+
for visitor permissions, automatic briefings, private owner access and Tailscale.
|
|
37
|
+
|
|
33
38
|
## Install
|
|
34
39
|
|
|
35
40
|
```sh
|
|
36
|
-
dsh plugin --profile web add dsh-a2a-server
|
|
41
|
+
dsh plugin --profile web add dsh-a2a-server@0.3.0
|
|
37
42
|
```
|
|
38
43
|
|
|
39
44
|
`dsh plugin` forwards to pnpm inside the profile directory and appends this
|
|
40
45
|
bundle to `dsh.profile.bundles`, because the package declares `dsh.bundle`.
|
|
46
|
+
Since DSH v0.2.1-alpha.1, `--profile` must come before any pnpm arguments —
|
|
47
|
+
the forms above already do.
|
|
41
48
|
|
|
42
49
|
To work from a checkout instead, point it at the directory:
|
|
43
50
|
|
|
@@ -50,13 +57,28 @@ dsh plugin --profile web add ./path/to/dsh-a2a-server
|
|
|
50
57
|
| `ctx.agents` | `dsh-base` |
|
|
51
58
|
| `ctx.credentials` | `dsh-base` |
|
|
52
59
|
| `ctx.webServer` | **`dsh-web-app`** |
|
|
53
|
-
| `ctx.
|
|
60
|
+
| `ctx.tools` and `ctx.systemPrompt` | required visitor tool and prompt isolation services |
|
|
61
|
+
| `ctx.sessionProjections` (optional) | composition; exposes task lifecycle projections |
|
|
54
62
|
|
|
55
|
-
The plugin stays PENDING until
|
|
63
|
+
The plugin stays PENDING until all required services exist. `ctx.webServer`
|
|
56
64
|
ships in `dsh-web-app` rather than `dsh-base`, so a `headless` profile needs
|
|
57
65
|
`@deepseek-ai/dsh-host-webserver` mounted before this bundle serves anything.
|
|
58
66
|
`dsh --profile <name> --dump-config` prints the composed rows.
|
|
59
67
|
|
|
68
|
+
### Upgrading from 0.2.x
|
|
69
|
+
|
|
70
|
+
Version 0.3.0 requires DSH `>=0.2.1-rc.2 <0.3.0`. Stop the agent, install
|
|
71
|
+
`dsh-a2a-server@0.3.0` into its existing profile, then restart it. Owner RPC and
|
|
72
|
+
monitoring now use authenticated local IPC; update the companion Portal as well.
|
|
73
|
+
Visitors retain chat and scoped workspace reads, while other tools are denied.
|
|
74
|
+
An empty `trustedPeers: []` denies all visitors. Task results persist across
|
|
75
|
+
restart within the configured retention window.
|
|
76
|
+
|
|
77
|
+
The current [Talk2MyAgent Portal](https://github.com/huangjuhua-aigc/Talk2MyAgent)
|
|
78
|
+
configures default-on hourly briefings with one persistent switch. The plugin
|
|
79
|
+
alone does not enable automatic briefing without its `briefing` configuration.
|
|
80
|
+
See the [0.3.0 release notes](https://github.com/huangjuhua-aigc/dsh-a2a/blob/main/CHANGELOG.md).
|
|
81
|
+
|
|
60
82
|
## Quick start
|
|
61
83
|
|
|
62
84
|
The bundled example composition runs a real model and a listening server.
|
|
@@ -103,7 +125,7 @@ curl -s http://127.0.0.1:9922/a2a \
|
|
|
103
125
|
| `A2A_PEERS` | `alice` | `name[:token]` list; a token is required for each |
|
|
104
126
|
| `A2A_PORT` | `9900` | Listening port |
|
|
105
127
|
| `A2A_SEND_MODE` | `block` | `block` or `immediate` |
|
|
106
|
-
| `A2A_WORKSPACE_ROOT` | temp dir |
|
|
128
|
+
| `A2A_WORKSPACE_ROOT` | temp dir | Authorized visitor data root and parent of per-peer working directories |
|
|
107
129
|
| `DEEPSEEK_MODEL` | `deepseek-v4-flash` | Model id requested from the adapter |
|
|
108
130
|
|
|
109
131
|
A one-shot probe runs 67 checks against a live server and exits non-zero on any
|
|
@@ -121,13 +143,14 @@ node example/probe.mjs http://127.0.0.1:9922 demo123
|
|
|
121
143
|
| `/.well-known/agent-card.json` | GET | Public by default |
|
|
122
144
|
| `/.well-known/agent.json` | GET | Public by default |
|
|
123
145
|
| `{basePath}` (default `/a2a`) | POST | Bearer required |
|
|
146
|
+
| `{basePath}/admin/contexts[/<id>]` | GET | Local IPC only + admin token; never registered on public HTTP |
|
|
124
147
|
|
|
125
148
|
| JSON-RPC method | Status |
|
|
126
149
|
| --- | --- |
|
|
127
150
|
| `SendMessage` | Waiting negotiated per request |
|
|
128
151
|
| `SendStreamingMessage` | SSE |
|
|
129
152
|
| `GetTask` | Idempotent; answers after settlement |
|
|
130
|
-
| `ListTasks` | Cursor-paginated, filterable,
|
|
153
|
+
| `ListTasks` | Cursor-paginated, filterable, live and retained tasks |
|
|
131
154
|
| `CancelTask` | Cancels the running turn |
|
|
132
155
|
| `SubscribeToTask` | Live stream; `-32004` on a terminal task |
|
|
133
156
|
| `GetExtendedAgentCard` | Extra skills for an authenticated peer; `-32007` when unconfigured |
|
|
@@ -179,17 +202,17 @@ another peer answers exactly as an absent one.
|
|
|
179
202
|
|
|
180
203
|
card:
|
|
181
204
|
name: dsh-harness
|
|
182
|
-
description:
|
|
205
|
+
description: Answers questions using code and text in the authorized directory.
|
|
183
206
|
public: true
|
|
184
207
|
skills:
|
|
185
208
|
- id: general
|
|
186
209
|
name: general
|
|
187
|
-
description:
|
|
210
|
+
description: Chat and scoped file reading.
|
|
188
211
|
tags: [coding, research]
|
|
189
212
|
extendedSkills: # authenticated peers only
|
|
190
213
|
- id: internal
|
|
191
214
|
name: internal diagnostics
|
|
192
|
-
description:
|
|
215
|
+
description: Explains project documentation from the authorized directory.
|
|
193
216
|
tags: [internal]
|
|
194
217
|
provider:
|
|
195
218
|
organization: Example Inc.
|
|
@@ -226,16 +249,31 @@ another peer answers exactly as an absent one.
|
|
|
226
249
|
| `card.skills` | `[]` | Declared skills; falls back to one `general` entry |
|
|
227
250
|
| `card.extendedSkills` | `[]` | Skills revealed only through `GetExtendedAgentCard` |
|
|
228
251
|
| `peers` | `{}` | Identity → credential **reference name** |
|
|
229
|
-
| `trustedPeers` | all authenticated |
|
|
252
|
+
| `trustedPeers` | all authenticated | Access allow-list for conversation and scoped file reads; `[]` denies everyone |
|
|
230
253
|
| `rateLimitPerMinute` | `60` | Sliding window per identity |
|
|
231
254
|
| `maxContextTurns` | `5` | Messages accepted per context before `rejected` |
|
|
232
255
|
| `sendMode` | `block` | Default when the client sends no `returnImmediately` |
|
|
233
|
-
| `blockTimeoutMs` | `60000` |
|
|
256
|
+
| `blockTimeoutMs` | `60000` | Maximum blocking wait; returns the current task on timeout so the client can poll |
|
|
234
257
|
| `contextIdleTtlMs` | `1800000` | Idle time before a context's agent is released |
|
|
235
258
|
| `maxResidentContexts` | `64` | Ceiling on resident contexts |
|
|
259
|
+
| `maxConcurrentTasks` / `maxConcurrentTasksPerPeer` | `8` / `2` | Atomic task admission; excess requests receive 429 |
|
|
260
|
+
| `maxTasksPerPeerPerDay` | `200` | Persisted task allowance per identity per UTC day |
|
|
261
|
+
| `taskTimeoutMs` | `120000` | Cancels execution when its deadline expires |
|
|
262
|
+
| `maxModelCallsPerTask` / `maxOutputTokens` | `8` / `4096` | Model request and per-request output limits |
|
|
263
|
+
| `maxInputChars` / `maxOutputChars` | `32000` / `64000` | Input/output text limits |
|
|
264
|
+
| `streamHeartbeatMs` / `maxStreamsPerTask` | `15000` / `4` | Heartbeat interval and subscription cap |
|
|
265
|
+
| `maxStreamBufferBytes` | `262144` | Disconnect a stream whose buffered frame exceeds the cap |
|
|
266
|
+
| `storage.directory` | `~/.dsh-a2a/<deployment-key>` | Private checkpoints; one process per directory |
|
|
267
|
+
| `storage.retentionMs` / `storage.maxContexts` | `86400000` / `256` | Retention after last activity, and maximum stored contexts |
|
|
268
|
+
| `storage.maxContextBytes` | `4000000` | Maximum checkpoint bytes per context |
|
|
236
269
|
| `isolation.workspaceMode` | `per-peer` | `per-peer` or `shared` |
|
|
237
|
-
| `isolation.workspaceRoot` | — | Required; parent directory or shared cwd |
|
|
238
|
-
| `isolation.peerWorkspaces` | `{}` | Per-identity
|
|
270
|
+
| `isolation.workspaceRoot` | — | Required; authorized shared read-only data root and parent directory or shared cwd |
|
|
271
|
+
| `isolation.peerWorkspaces` | `{}` | Per-identity cwd and authorized read-root override |
|
|
272
|
+
| `preamble.files` | `[".hop/handoff.md"]` | Host briefing files (**agent-level**: resolved against the workspace root and shared by every visitor; absolute paths pass through), merged into each context's first message; absent files are skipped |
|
|
273
|
+
| `briefing.prompt` | — | Optional single-update instruction executed as the bounded local owner at startup and hourly; configured by Portal, requires owner administration |
|
|
274
|
+
| `briefing.settingsFile` | — | Absolute path to a JSON `{ "enabled": boolean }` preference; absent file means enabled, observed every 5 seconds. Disabling preserves the current briefing and lets active work finish; restart timing is persisted |
|
|
275
|
+
| `admin.tokenEnv` | — | Credential reference for local owner and monitoring requests; rejected by public RPC |
|
|
276
|
+
| `admin.socketPath` | deployment-specific | Windows named pipe or private Unix socket for owner RPC and monitoring |
|
|
239
277
|
| `push.enabled` | `false` | Reserved; see [Boundaries](#boundaries) |
|
|
240
278
|
|
|
241
279
|
Configuration is refused at load when `isolation.workspaceRoot` is absent, a peer
|
|
@@ -254,7 +292,8 @@ peers:
|
|
|
254
292
|
|
|
255
293
|
```yaml
|
|
256
294
|
# ~/.dsh/.credentials.yaml
|
|
257
|
-
|
|
295
|
+
refs:
|
|
296
|
+
A2A_PEER_ALICE: <32-byte-hex-from-openssl-rand>
|
|
258
297
|
```
|
|
259
298
|
|
|
260
299
|
`ctx.credentials` resolves the reference per request across four layers — the
|
|
@@ -270,11 +309,29 @@ identities.
|
|
|
270
309
|
| --- | --- | --- |
|
|
271
310
|
| Model context | One peer's conversation cannot enter another's model request | Separate `contextId` → separate Session → separate log |
|
|
272
311
|
| Protocol access | A peer cannot read, continue, or cancel another's context or task | Ownership by authenticated identity |
|
|
273
|
-
| Tooling |
|
|
312
|
+
| Tooling | Only the scoped `read_file` is available; no writes, shell, network or cross-session tools | Inherited-tool masking, scoped reader, and execution guard |
|
|
313
|
+
| Prompt context | Public agents have a dedicated system prompt and suppress optional host runtime context | Scoped complete prompt and context suppression |
|
|
274
314
|
|
|
275
315
|
`per-peer` (the default) derives each identity's `cwd` from `workspaceRoot`.
|
|
276
|
-
`shared` places every peer in one directory
|
|
277
|
-
|
|
316
|
+
`shared` places every peer in one directory. These are working-directory choices,
|
|
317
|
+
not filesystem sandboxes. `read_file` reads from the owner-selected
|
|
318
|
+
`workspaceRoot`; a `peerWorkspaces` override restricts that peer to the overridden
|
|
319
|
+
directory. Relative tool paths resolve from this **data root**, not the per-peer
|
|
320
|
+
cwd. These files are available to admitted visitors, so choose the data root
|
|
321
|
+
accordingly. The A2A checkpoint directory is always excluded.
|
|
322
|
+
|
|
323
|
+
`read_file({"path":"."})` lists the root's entries. A file path reads UTF-8 text;
|
|
324
|
+
`offset` (1-based) and `limit` page lines or directory entries. Reads are bounded
|
|
325
|
+
to 2 MiB files, 32,000 returned characters and 500 lines/entries per call; directory
|
|
326
|
+
scans cover at most 1,000 entries. Binary/office-document extraction is not yet
|
|
327
|
+
implemented. Canonical path checks refuse escapes; symlinks, junctions, hard
|
|
328
|
+
links and Windows alternate data streams are rejected. No shell is invoked.
|
|
329
|
+
`preamble.files` continues to provide an optional opening briefing.
|
|
330
|
+
|
|
331
|
+
Owner RPC uses the same `/a2a` path on **local IPC**, authenticated with the admin
|
|
332
|
+
token. It retains the standard caretaker preset. The public HTTP listener accepts
|
|
333
|
+
only visitor credentials and never mounts the monitoring API. See the
|
|
334
|
+
[migration and deployment notes](https://github.com/huangjuhua-aigc/dsh-a2a/blob/main/docs/public-access-hardening.en.md).
|
|
278
335
|
|
|
279
336
|
## Boundaries
|
|
280
337
|
|
|
@@ -285,13 +342,20 @@ single repository; under it, files written by one peer are readable by another.
|
|
|
285
342
|
- No `stateTransitionHistory`, protocol extensions, or card signatures.
|
|
286
343
|
- Streaming emits committed assistant messages. Per-chunk streaming is not
|
|
287
344
|
implemented.
|
|
288
|
-
-
|
|
289
|
-
|
|
290
|
-
|
|
345
|
+
- Execution deadlines cancel the agent. Admission remains occupied until the
|
|
346
|
+
underlying adapter finishes cancellation; an adapter ignoring AbortSignal
|
|
347
|
+
needs process-level supervision. These limits are not a currency budget.
|
|
348
|
+
- Only rooted `read_file` is enabled for visitors. Other tools require separate
|
|
349
|
+
capability work; changing the sandbox mode does not grant those tools. This
|
|
350
|
+
application-level file reader is not an OS sandbox against a malicious local
|
|
351
|
+
administrator mutating the filesystem.
|
|
291
352
|
- A token ceiling settles a task as `completed`; the real turn ending travels in
|
|
292
353
|
`Task.metadata.dsh.stopReason`, which A2A's state enum cannot express.
|
|
293
|
-
- Task
|
|
294
|
-
|
|
354
|
+
- Task results and idle conversation history survive eviction/restart within
|
|
355
|
+
the retention window. Interrupted tasks become failed and are never replayed.
|
|
356
|
+
Cold restoration creates a new harness session behind the stable contextId.
|
|
357
|
+
- One task may run per context; concurrent submissions receive 409. Message IDs
|
|
358
|
+
are not deduplication keys: proxies must not blindly retry submissions.
|
|
295
359
|
- `ctx.webServer` provides no TLS. Any non-loopback exposure belongs behind a
|
|
296
360
|
reverse proxy.
|
|
297
361
|
- A configuration change restarts the plugin and cancels in-flight tasks.
|
|
@@ -312,6 +376,10 @@ src/
|
|
|
312
376
|
├── tasks.ts task slots and the three-stage turn correlation
|
|
313
377
|
├── projection.ts the a2aTask fold over the session log
|
|
314
378
|
├── security.ts authentication, rate limiting, defanging, redaction
|
|
379
|
+
├── workspace-read.ts bounded read_file within the authorized data root
|
|
380
|
+
├── management.ts private owner RPC and monitoring over local IPC
|
|
381
|
+
├── state.ts durable task and conversation checkpoints
|
|
382
|
+
├── briefing.ts hourly briefing updates and persistent scheduling
|
|
315
383
|
├── config.ts schema plus the cross-field checks that fail at load
|
|
316
384
|
└── types.ts declaration merges into SessionEventMap / MessageSourceMap
|
|
317
385
|
```
|
|
@@ -327,17 +395,19 @@ carries the committed output, so the fold serves the answer without reaching
|
|
|
327
395
|
back into message history.
|
|
328
396
|
|
|
329
397
|
**Residency is explicit.** HTTP has no connection lifetime, so each `contextId`
|
|
330
|
-
maps to an Activation evicted when idle
|
|
398
|
+
maps to an Activation evicted when idle. Private checkpoints retain task results
|
|
399
|
+
and conversation history; cold restoration creates a new harness session.
|
|
331
400
|
|
|
332
401
|
## Development
|
|
333
402
|
|
|
334
403
|
```sh
|
|
335
404
|
pnpm install
|
|
336
405
|
pnpm typecheck
|
|
337
|
-
pnpm test #
|
|
406
|
+
pnpm test # protocol, lifecycle, security and workspace-read regressions
|
|
338
407
|
pnpm serve # a listening server
|
|
339
408
|
pnpm probe # 67 checks against a running server
|
|
340
409
|
pnpm build # emit lib/
|
|
410
|
+
pnpm test:package # verify imports with only declared runtime packages
|
|
341
411
|
```
|
|
342
412
|
|
|
343
413
|
The end-to-end suites boot a real Cordis composition with a real agent loop and
|
|
@@ -357,7 +427,10 @@ capability seams this plugin consumes. This project supplies:
|
|
|
357
427
|
- Per-peer authentication, isolation, and workspace policy
|
|
358
428
|
|
|
359
429
|
The harness is pre-release and does not promise compatibility across renames or
|
|
360
|
-
repackaging, so
|
|
430
|
+
repackaging, so compatibility is declared through `engines.dsh`
|
|
431
|
+
(`>=0.2.1-rc.2 <0.3.0`) plus range-bounded `@deepseek-ai/dsh-*` peer
|
|
432
|
+
dependencies: an install preflight refuses any combination the plugin was not
|
|
433
|
+
built against, and the range admits every 0.2.x patch that follows.
|
|
361
434
|
|
|
362
435
|
## Community
|
|
363
436
|
|
package/README.zh-CN.md
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
<a href="https://www.npmjs.com/package/dsh-a2a-server"><img src="https://img.shields.io/npm/v/dsh-a2a-server?style=flat&label=npm&color=CB3837" alt="npm 版本"></a>
|
|
17
17
|
<a href="https://github.com/huangjuhua-aigc/dsh-a2a/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-2EA44F?style=flat" alt="MIT License"></a>
|
|
18
18
|
<img src="https://img.shields.io/badge/A2A-v1.0%20JSON--RPC-4D6BFE?style=flat" alt="A2A v1.0 JSON-RPC 绑定">
|
|
19
|
-
<img src="https://img.shields.io/badge/DSH-0.1
|
|
20
|
-
<img src="https://img.shields.io/badge/tests-
|
|
19
|
+
<img src="https://img.shields.io/badge/DSH-0.2.1--rc.2-4493F8?style=flat" alt="基于 DSH 0.2.1-rc.2 构建">
|
|
20
|
+
<img src="https://img.shields.io/badge/tests-217-2EA44F?style=flat" alt="217 项测试">
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
23
|
`dsh-a2a-server` 让 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
@@ -30,12 +30,16 @@ subagent provider。它是 `ctx.agents` 之上的传输适配层,不是能力
|
|
|
30
30
|
|
|
31
31
|
## 安装
|
|
32
32
|
|
|
33
|
+
需要本机配置界面或跨网络访问时,先看配套 [Talk2MyAgent 使用说明](https://github.com/huangjuhua-aigc/Talk2MyAgent)。
|
|
34
|
+
访客读取权限、自动简报、主人 IPC 与 Tailscale 部署详见[部署与迁移指南](https://github.com/huangjuhua-aigc/dsh-a2a/blob/main/docs/public-access-hardening.md)。
|
|
35
|
+
|
|
33
36
|
```sh
|
|
34
|
-
dsh plugin --profile web add dsh-a2a-server
|
|
37
|
+
dsh plugin --profile web add dsh-a2a-server@0.3.0
|
|
35
38
|
```
|
|
36
39
|
|
|
37
40
|
`dsh plugin` 会在 profile 目录里转发给 pnpm,并把这个 bundle 追加进
|
|
38
|
-
`dsh.profile.bundles`——因为包中声明了 `dsh.bundle
|
|
41
|
+
`dsh.profile.bundles`——因为包中声明了 `dsh.bundle`。自 DSH v0.2.1-alpha.1 起,
|
|
42
|
+
`--profile` 必须放在所有 pnpm 参数之前——上面的写法已经是正确的。
|
|
39
43
|
|
|
40
44
|
若想直接使用本地检出,把路径指过去即可:
|
|
41
45
|
|
|
@@ -48,12 +52,25 @@ dsh plugin --profile web add ./path/to/dsh-a2a-server
|
|
|
48
52
|
| `ctx.agents` | `dsh-base` |
|
|
49
53
|
| `ctx.credentials` | `dsh-base` |
|
|
50
54
|
| `ctx.webServer` | **`dsh-web-app`** |
|
|
51
|
-
| `ctx.
|
|
55
|
+
| `ctx.tools` 和 `ctx.systemPrompt` | 必需的访客工具及提示词隔离服务 |
|
|
56
|
+
| `ctx.sessionProjections`(可选) | 组合层;提供任务生命周期投影 |
|
|
52
57
|
|
|
53
|
-
|
|
58
|
+
必需服务齐备之前,插件保持 PENDING。`ctx.webServer` 由 `dsh-web-app` 提供而不在
|
|
54
59
|
`dsh-base` 中,因此 `headless` profile 需要先挂载 `@deepseek-ai/dsh-host-webserver`。
|
|
55
60
|
`dsh --profile <name> --dump-config` 可以打印组合出来的配置行。
|
|
56
61
|
|
|
62
|
+
### 从 0.2.x 升级
|
|
63
|
+
|
|
64
|
+
0.3.0 适配 DSH `>=0.2.1-rc.2 <0.3.0`。先停止 agent,将
|
|
65
|
+
`dsh-a2a-server@0.3.0` 安装到原有 profile,再重新启动;配套 Portal 也需更新。
|
|
66
|
+
主人 RPC 和监控已改为需要认证的本机 IPC,公网 HTTP 不接受主人凭据。
|
|
67
|
+
访客可聊天并读取授权目录,其他工具关闭;空白名单 `trustedPeers: []` 拒绝所有访客。
|
|
68
|
+
任务结果与空闲会话在保留期内可跨驱逐和重启恢复。
|
|
69
|
+
|
|
70
|
+
新版 [Talk2MyAgent Portal](https://github.com/huangjuhua-aigc/Talk2MyAgent) 默认开启每小时简报更新,
|
|
71
|
+
用一个开关控制,完成后直接写入 `.hop/handoff.md`。单独安装协议插件而未配置 `briefing`
|
|
72
|
+
不会自动执行简报任务。详见 [0.3.0 发布说明](https://github.com/huangjuhua-aigc/dsh-a2a/blob/main/CHANGELOG.zh-CN.md)。
|
|
73
|
+
|
|
57
74
|
## 快速开始
|
|
58
75
|
|
|
59
76
|
仓库自带的示例组合会运行真实模型并启动一个监听服务。
|
|
@@ -99,7 +116,7 @@ curl -s http://127.0.0.1:9922/a2a \
|
|
|
99
116
|
| `A2A_PEERS` | `alice` | `名字[:token]` 列表;每个 peer 都必须有 token |
|
|
100
117
|
| `A2A_PORT` | `9900` | 监听端口 |
|
|
101
118
|
| `A2A_SEND_MODE` | `block` | `block` 或 `immediate` |
|
|
102
|
-
| `A2A_WORKSPACE_ROOT` | 临时目录 | per-peer 工作目录的父目录 |
|
|
119
|
+
| `A2A_WORKSPACE_ROOT` | 临时目录 | 访客授权资料目录,同时作为 per-peer 工作目录的父目录 |
|
|
103
120
|
| `DEEPSEEK_MODEL` | `deepseek-v4-flash` | 向适配器请求的模型 id |
|
|
104
121
|
|
|
105
122
|
一次性探针会对运行中的服务执行 67 项检查,任何一项不符即以非零码退出:
|
|
@@ -116,13 +133,14 @@ node example/probe.mjs http://127.0.0.1:9922 demo123
|
|
|
116
133
|
| `/.well-known/agent-card.json` | GET | 默认公开 |
|
|
117
134
|
| `/.well-known/agent.json` | GET | 默认公开 |
|
|
118
135
|
| `{basePath}`(默认 `/a2a`) | POST | 必须携带 Bearer |
|
|
136
|
+
| `{basePath}/admin/contexts[/<id>]` | GET | 仅本机 IPC + admin token,公网 HTTP 不挂载 |
|
|
119
137
|
|
|
120
138
|
| JSON-RPC 方法 | 状态 |
|
|
121
139
|
| --- | --- |
|
|
122
140
|
| `SendMessage` | 是否等待逐请求协商 |
|
|
123
141
|
| `SendStreamingMessage` | SSE |
|
|
124
142
|
| `GetTask` | 幂等;结算后仍可应答 |
|
|
125
|
-
| `ListTasks` |
|
|
143
|
+
| `ListTasks` | 游标分页、可过滤;包括保留期内的持久化任务 |
|
|
126
144
|
| `CancelTask` | 取消正在执行的 turn |
|
|
127
145
|
| `SubscribeToTask` | 续订活任务;终态任务返回 `-32004` |
|
|
128
146
|
| `GetExtendedAgentCard` | 已认证 peer 可见的额外 skill;未配置时 `-32007` |
|
|
@@ -171,12 +189,12 @@ part 是被**删除**而不是做了别名:本服务写出的每一个回包
|
|
|
171
189
|
|
|
172
190
|
card:
|
|
173
191
|
name: dsh-harness
|
|
174
|
-
description:
|
|
192
|
+
description: 读取授权目录中的代码和资料,回答访客问题。
|
|
175
193
|
public: true
|
|
176
194
|
skills:
|
|
177
195
|
- id: general
|
|
178
196
|
name: general
|
|
179
|
-
description:
|
|
197
|
+
description: 对话与授权目录内的文件读取。
|
|
180
198
|
tags: [coding, research]
|
|
181
199
|
provider:
|
|
182
200
|
organization: Example Inc.
|
|
@@ -213,16 +231,21 @@ part 是被**删除**而不是做了别名:本服务写出的每一个回包
|
|
|
213
231
|
| `card.skills` | `[]` | 声明的 skills;为空时回退到一条 `general` |
|
|
214
232
|
| `card.extendedSkills` | `[]` | 只对已认证 peer 经 `GetExtendedAgentCard` 公开的 skills |
|
|
215
233
|
| `peers` | `{}` | 身份 → 凭据**引用名** |
|
|
216
|
-
| `trustedPeers` | 全部已认证身份 |
|
|
234
|
+
| `trustedPeers` | 全部已认证身份 | 对话与受限文件读取白名单;`[]` 拒绝所有访客 |
|
|
217
235
|
| `rateLimitPerMinute` | `60` | 按身份的滑动窗口 |
|
|
218
236
|
| `maxContextTurns` | `5` | 单个 context 接受的消息数上限,超出后 `rejected` |
|
|
219
237
|
| `sendMode` | `block` | 客户端未表态时的默认行为 |
|
|
220
|
-
| `blockTimeoutMs` | `60000` |
|
|
238
|
+
| `blockTimeoutMs` | `60000` | 最长阻塞等待;到期返回任务当前状态,客户端可继续查询 |
|
|
221
239
|
| `contextIdleTtlMs` | `1800000` | context 的 agent 被释放前的空闲时长 |
|
|
222
240
|
| `maxResidentContexts` | `64` | 常驻 context 数量上限 |
|
|
223
241
|
| `isolation.workspaceMode` | `per-peer` | `per-peer` 或 `shared` |
|
|
224
|
-
| `isolation.workspaceRoot` | — |
|
|
225
|
-
| `isolation.peerWorkspaces` | `{}` |
|
|
242
|
+
| `isolation.workspaceRoot` | — | 必填;授权资料目录,同时作为访客 cwd 的父目录或共享 cwd |
|
|
243
|
+
| `isolation.peerWorkspaces` | `{}` | 按身份覆盖工作目录和授权读取范围 |
|
|
244
|
+
| `preamble.files` | `[".hop/handoff.md"]` | 主人背景简报文件(**agent 级**:相对工作区根目录解析,全体访客共用一份;绝对路径直通),合并进每个 context 的首条访客消息;文件不存在则跳过 |
|
|
245
|
+
| `briefing.prompt` | — | 可选的单次简报更新指令,由 Portal 配置,通过有执行预算的主人 agent 每小时运行 |
|
|
246
|
+
| `briefing.settingsFile` | — | 绝对路径;读取 `{ "enabled": boolean }` 设置,缺省开启,每 5 秒检查 |
|
|
247
|
+
| `admin.tokenEnv` | — | 本机主人 RPC 和监控的凭据引用,公网 RPC 拒绝此凭据 |
|
|
248
|
+
| `admin.socketPath` | 按部署生成 | Windows 命名管道或私有 Unix socket |
|
|
226
249
|
| `push.enabled` | `false` | 保留字段,见[边界](#边界) |
|
|
227
250
|
|
|
228
251
|
以下情况在加载期即被拒绝:缺少 `isolation.workspaceRoot`;peer 名不匹配
|
|
@@ -240,7 +263,8 @@ peers:
|
|
|
240
263
|
|
|
241
264
|
```yaml
|
|
242
265
|
# ~/.dsh/.credentials.yaml
|
|
243
|
-
|
|
266
|
+
refs:
|
|
267
|
+
A2A_PEER_ALICE: <32-byte-hex-from-openssl-rand>
|
|
244
268
|
```
|
|
245
269
|
|
|
246
270
|
`ctx.credentials` 在每次请求时跨四层解析该引用——进程环境、托管文档、`<cwd>/.env`、
|
|
@@ -254,11 +278,18 @@ A2A_PEER_ALICE: <32-byte-hex-from-openssl-rand>
|
|
|
254
278
|
| --- | --- | --- |
|
|
255
279
|
| 模型上下文 | 一个 peer 的对话不会进入另一个 peer 的模型请求 | 不同 `contextId` → 不同 Session → 不同 log |
|
|
256
280
|
| 协议访问 | peer 无法读取、续接或取消他人的 context 与任务 | 按认证身份判定归属 |
|
|
257
|
-
| 工具层 |
|
|
281
|
+
| 工具层 | 仅提供受控 `read_file`,不开放写入、命令、联网或跨会话工具 | 屏蔽继承工具、专用读取工具、执行校验 |
|
|
282
|
+
| 提示词 | 访客不继承可选的主人个性化提示与运行时上下文 | 独立的公共系统提示词 |
|
|
283
|
+
|
|
284
|
+
`per-peer`(默认)依据 `workspaceRoot` 为每个身份派生独立 `cwd`;`shared` 使用同一个目录。
|
|
285
|
+
这只是工作目录策略,不是文件系统沙箱。`read_file` 的读取范围默认是用户选择的
|
|
286
|
+
`workspaceRoot`,有 `peerWorkspaces` 覆盖时限制为该访客的专属目录。工具相对路径从
|
|
287
|
+
这个资料目录解析;插件私有状态目录始终排除。
|
|
258
288
|
|
|
259
|
-
`
|
|
260
|
-
|
|
261
|
-
|
|
289
|
+
`read_file({"path":"."})` 列出资料目录;文件支持 UTF-8 文本,按 `offset`/`limit`
|
|
290
|
+
分页。单文件上限 2 MiB,单次最多 32000 字符、500 行/项,目录扫描最多 1000 项。
|
|
291
|
+
拒绝越界、符号链接/junction、硬链接和 Windows ADS。主人维护能力使用独立本机 IPC,
|
|
292
|
+
保留可信管理工具,不能从公网入口调用。资源配额的完整配置表见英文 README。
|
|
262
293
|
|
|
263
294
|
## 边界
|
|
264
295
|
|
|
@@ -268,12 +299,14 @@ A2A_PEER_ALICE: <32-byte-hex-from-openssl-rand>
|
|
|
268
299
|
`pushNotifications: false`。
|
|
269
300
|
- 不支持 `stateTransitionHistory`、协议扩展与 Card 签名。
|
|
270
301
|
- 流式只推送已提交的 assistant 消息,未实现逐 chunk 推送。
|
|
271
|
-
-
|
|
272
|
-
|
|
302
|
+
- 有并发准入、任务期限及模型调用预算;超时后等待底层适配器完成取消才释放执行名额。
|
|
303
|
+
不响应取消的适配器仍需进程级监管,这些额度不是按货币计费的预算。
|
|
304
|
+
- 访客仅能使用有目录边界的 `read_file`;改变沙箱模式不会自动开放其他工具。
|
|
305
|
+
该工具边界不替代针对恶意本机管理员的操作系统隔离。
|
|
273
306
|
- 触及 token 上限的任务结算为 `completed`,真实的 turn 结束原因放在
|
|
274
307
|
`Task.metadata.dsh.stopReason`——A2A 的状态枚举无法表达它。
|
|
275
|
-
-
|
|
276
|
-
|
|
308
|
+
- 任务结果与空闲会话在保留期内可跨进程重启恢复;中断的任务标记失败,不重放。
|
|
309
|
+
- 每个 context 同时只允许一个任务,并发提交返回 409;messageId 不是提交去重键。
|
|
277
310
|
- `ctx.webServer` 不提供 TLS。任何非回环地址的暴露都应置于反向代理之后。
|
|
278
311
|
- 修改配置会重启插件并取消进行中的任务。
|
|
279
312
|
|
|
@@ -293,6 +326,10 @@ src/
|
|
|
293
326
|
├── tasks.ts 任务槽位与三段式 turn 关联
|
|
294
327
|
├── projection.ts 在 session log 上折叠出的 a2aTask 读模型
|
|
295
328
|
├── security.ts 认证、限流、注入去势、外发脱敏
|
|
329
|
+
├── workspace-read.ts 授权目录内受限的 read_file
|
|
330
|
+
├── management.ts 本机 IPC 主人 RPC 与监控
|
|
331
|
+
├── state.ts 持久化任务及对话 checkpoint
|
|
332
|
+
├── briefing.ts 每小时简报更新与持久化调度
|
|
296
333
|
├── config.ts schema,以及加载期就会拒绝的跨字段校验
|
|
297
334
|
└── types.ts 向 SessionEventMap / MessageSourceMap 的声明合并
|
|
298
335
|
```
|
|
@@ -306,17 +343,18 @@ src/
|
|
|
306
343
|
历史。
|
|
307
344
|
|
|
308
345
|
**驻留是显式管理的。** HTTP 没有连接生命周期,因此每个 `contextId` 对应一个 Activation,
|
|
309
|
-
|
|
346
|
+
空闲后被驱逐。私有 checkpoint 保留任务结果与对话历史,冷恢复时创建新的 harness session。
|
|
310
347
|
|
|
311
348
|
## 开发
|
|
312
349
|
|
|
313
350
|
```sh
|
|
314
351
|
pnpm install
|
|
315
352
|
pnpm typecheck
|
|
316
|
-
pnpm test #
|
|
353
|
+
pnpm test # 15 个文件共 217 项测试
|
|
317
354
|
pnpm serve # 启动监听服务
|
|
318
355
|
pnpm probe # 对运行中的服务执行 67 项检查
|
|
319
356
|
pnpm build # 产出 lib/
|
|
357
|
+
pnpm test:package # 仅声明运行依赖时验证构建产物导入
|
|
320
358
|
```
|
|
321
359
|
|
|
322
360
|
端到端测试会启动真实的 Cordis 组合与真实的 agent loop,并通过 HTTP 驱动它;模型使用
|
|
@@ -333,8 +371,10 @@ pnpm build # 产出 lib/
|
|
|
333
371
|
- A2A task 与 harness turn 之间的映射
|
|
334
372
|
- 按 peer 的认证、隔离与工作目录策略
|
|
335
373
|
|
|
336
|
-
harness 处于 pre-release
|
|
337
|
-
|
|
374
|
+
harness 处于 pre-release 阶段,不承诺跨重命名或重新打包的兼容性,因此兼容性通过
|
|
375
|
+
`engines.dsh`(`>=0.2.1-rc.2 <0.3.0`)加上按 range 声明的 `@deepseek-ai/dsh-*`
|
|
376
|
+
peer 依赖来表达:安装预检会拒绝任何插件未曾适配过的组合,而这个 range 也放行后续
|
|
377
|
+
所有的 0.2.x 补丁版本。
|
|
338
378
|
|
|
339
379
|
## 社区交流
|
|
340
380
|
|
package/cordis.patch.yml
CHANGED
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
# REQUIRES ctx.webServer, which ships in `dsh-web-app`, NOT in `dsh-base`. On a
|
|
8
8
|
# profile without it this row loads but stays PENDING (Cordis holds a plugin
|
|
9
9
|
# whose injected services are absent), so nothing serves and nothing errors.
|
|
10
|
+
#
|
|
11
|
+
# NOTE: keep this file plain YAML — the installer's package validation parses
|
|
12
|
+
# it with a strict loader that rejects `!!js` expressions, even though the
|
|
13
|
+
# runtime overlay loader accepts them.
|
|
10
14
|
- insert:
|
|
11
15
|
- id: a2a-server
|
|
12
16
|
name: dsh-a2a-server
|
|
13
17
|
config:
|
|
14
18
|
basePath: /a2a
|
|
15
|
-
protocolVersion: '0.3.0'
|
|
16
19
|
card:
|
|
17
20
|
name: dsh-harness
|
|
18
21
|
description: A DeepSeek Harness agent reachable over A2A.
|
|
@@ -20,11 +23,12 @@
|
|
|
20
23
|
skills: []
|
|
21
24
|
peers: {}
|
|
22
25
|
isolation:
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
26
|
+
# Each peer gets its own working directory. This is not a filesystem
|
|
27
|
+
# sandbox: read_file separately restricts reads to the selected root,
|
|
28
|
+
# or to a peerWorkspaces override. Other visitor tools are disabled.
|
|
29
|
+
# This placeholder is overridden by any real deployment layer (the
|
|
30
|
+
# console's overlay sets it per agent); supply an absolute path.
|
|
27
31
|
workspaceMode: per-peer
|
|
28
|
-
workspaceRoot:
|
|
32
|
+
workspaceRoot: /srv/dsh/a2a
|
|
29
33
|
push:
|
|
30
34
|
enabled: false
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const BRIEFING_INTERVAL_MS: number;
|
|
2
|
+
interface LegacyBriefingScheduler {
|
|
3
|
+
catalog(): Promise<Array<{
|
|
4
|
+
id: string;
|
|
5
|
+
sessionId: string;
|
|
6
|
+
title: string;
|
|
7
|
+
prompt: string;
|
|
8
|
+
}>>;
|
|
9
|
+
delete(request: {
|
|
10
|
+
id: string;
|
|
11
|
+
sessionId: string;
|
|
12
|
+
}): Promise<unknown>;
|
|
13
|
+
}
|
|
14
|
+
/** Retire only the old Portal-generated job for this exact project. */
|
|
15
|
+
export declare function retireLegacyBriefing(scheduler: LegacyBriefingScheduler | undefined, root: string): Promise<void>;
|
|
16
|
+
export declare class AutomaticBriefing {
|
|
17
|
+
private readonly options;
|
|
18
|
+
private timer;
|
|
19
|
+
private closed;
|
|
20
|
+
private running;
|
|
21
|
+
private enabled;
|
|
22
|
+
private nextRunAt;
|
|
23
|
+
private readonly stateFile;
|
|
24
|
+
constructor(options: {
|
|
25
|
+
settingsFile: string;
|
|
26
|
+
stateDirectory: string;
|
|
27
|
+
run: () => Promise<void>;
|
|
28
|
+
warn: (message: string) => void;
|
|
29
|
+
now?: () => number;
|
|
30
|
+
});
|
|
31
|
+
private save;
|
|
32
|
+
private readEnabled;
|
|
33
|
+
/** Polling also observes an off/on switch without restarting the agent. */
|
|
34
|
+
tick(): Promise<void>;
|
|
35
|
+
start(): void;
|
|
36
|
+
stop(): void;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=briefing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"briefing.d.ts","sourceRoot":"","sources":["../src/briefing.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,oBAAoB,QAAiB,CAAA;AAGlD,UAAU,uBAAuB;IAC/B,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAA;IAC3F,MAAM,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACrE;AAED,uEAAuE;AACvE,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,uBAAuB,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtH;AAED,qBAAa,iBAAiB;IAQhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAPpC,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,OAAO,CAAO;IACtB,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEL,OAAO,EAAE;QACpC,YAAY,EAAE,MAAM,CAAA;QACpB,cAAc,EAAE,MAAM,CAAA;QACtB,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;QACxB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;QAC/B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;KACnB;IAWD,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,WAAW;IAWnB,2EAA2E;IACrE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB3B,KAAK,IAAI,IAAI;IAOb,IAAI,IAAI,IAAI;CAIb"}
|