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/lib/briefing.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/** One automatic briefing loop owned by the online agent, independent of Portal. */
|
|
2
|
+
import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
export const BRIEFING_INTERVAL_MS = 60 * 60 * 1000;
|
|
5
|
+
const CHECK_INTERVAL_MS = 5000;
|
|
6
|
+
/** Retire only the old Portal-generated job for this exact project. */
|
|
7
|
+
export async function retireLegacyBriefing(scheduler, root) {
|
|
8
|
+
if (!scheduler?.catalog || !scheduler.delete)
|
|
9
|
+
return;
|
|
10
|
+
const prefix = `【简报维护任务】受信任的项目范围只有一个:\n ${root}\n`;
|
|
11
|
+
for (const task of await scheduler.catalog()) {
|
|
12
|
+
if (task.title === '简报维护' && task.prompt.startsWith(prefix)
|
|
13
|
+
&& (task.prompt.includes('4. 把简报写入当前工作目录的 handoff.draft.md')
|
|
14
|
+
|| task.prompt.includes('4. 完整生成并检查上述内容后,直接覆盖写入当前工作目录的 handoff.md。'))) {
|
|
15
|
+
await scheduler.delete({ id: task.id, sessionId: task.sessionId });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class AutomaticBriefing {
|
|
20
|
+
options;
|
|
21
|
+
timer;
|
|
22
|
+
closed = false;
|
|
23
|
+
running = false;
|
|
24
|
+
enabled = true;
|
|
25
|
+
nextRunAt = 0;
|
|
26
|
+
stateFile;
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.options = options;
|
|
29
|
+
mkdirSync(options.stateDirectory, { recursive: true, mode: 0o700 });
|
|
30
|
+
this.stateFile = join(options.stateDirectory, 'briefing-state.json');
|
|
31
|
+
try {
|
|
32
|
+
const state = JSON.parse(readFileSync(this.stateFile, 'utf8'));
|
|
33
|
+
if (typeof state.enabled !== 'boolean' || !Number.isSafeInteger(state.nextRunAt) || state.nextRunAt < 0)
|
|
34
|
+
throw new Error('invalid briefing state');
|
|
35
|
+
this.enabled = state.enabled;
|
|
36
|
+
this.nextRunAt = state.nextRunAt;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (error.code !== 'ENOENT')
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
save() {
|
|
44
|
+
const temporary = `${this.stateFile}.tmp`;
|
|
45
|
+
try {
|
|
46
|
+
writeFileSync(temporary, JSON.stringify({ enabled: this.enabled, nextRunAt: this.nextRunAt }), { mode: 0o600 });
|
|
47
|
+
renameSync(temporary, this.stateFile);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
rmSync(temporary, { force: true });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
readEnabled() {
|
|
54
|
+
try {
|
|
55
|
+
const value = JSON.parse(readFileSync(this.options.settingsFile, 'utf8'));
|
|
56
|
+
if (typeof value.enabled !== 'boolean')
|
|
57
|
+
throw new Error('invalid automatic briefing setting');
|
|
58
|
+
return value.enabled;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error.code === 'ENOENT')
|
|
62
|
+
return true;
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Polling also observes an off/on switch without restarting the agent. */
|
|
67
|
+
async tick() {
|
|
68
|
+
if (this.closed)
|
|
69
|
+
return;
|
|
70
|
+
try {
|
|
71
|
+
const enabled = this.readEnabled();
|
|
72
|
+
const now = this.options.now?.() ?? Date.now();
|
|
73
|
+
if (enabled !== this.enabled) {
|
|
74
|
+
this.enabled = enabled;
|
|
75
|
+
if (enabled)
|
|
76
|
+
this.nextRunAt = now;
|
|
77
|
+
this.save();
|
|
78
|
+
}
|
|
79
|
+
if (!enabled || this.running || now < this.nextRunAt)
|
|
80
|
+
return;
|
|
81
|
+
// Persist before paid work: restarting must not immediately repeat a run.
|
|
82
|
+
this.nextRunAt = now + BRIEFING_INTERVAL_MS;
|
|
83
|
+
this.save();
|
|
84
|
+
this.running = true;
|
|
85
|
+
try {
|
|
86
|
+
await this.options.run();
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
this.running = false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
this.options.warn(`a2a: automatic briefing failed: ${String(error)}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
start() {
|
|
97
|
+
if (this.closed || this.timer)
|
|
98
|
+
return;
|
|
99
|
+
this.timer = setInterval(() => { void this.tick(); }, CHECK_INTERVAL_MS);
|
|
100
|
+
this.timer.unref();
|
|
101
|
+
void this.tick();
|
|
102
|
+
}
|
|
103
|
+
stop() {
|
|
104
|
+
this.closed = true;
|
|
105
|
+
clearInterval(this.timer);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=briefing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"briefing.js","sourceRoot":"","sources":["../src/briefing.ts"],"names":[],"mappings":"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"}
|
package/lib/config.d.ts
CHANGED
|
@@ -15,26 +15,16 @@ export interface PeerConfig {
|
|
|
15
15
|
/** Credential reference name, NOT the token itself. */
|
|
16
16
|
tokenEnv: string;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
* How peers are kept from reaching each other.
|
|
20
|
-
*
|
|
21
|
-
* DEFERRED — a tool deny-list (`session_search`, `session_event_search`,
|
|
22
|
-
* `session_trace`, `session_event_trace`, `session_event_read`, `list_agents`)
|
|
23
|
-
* plus a named `unsafeAllowCrossSessionSearch` escape hatch for single-peer
|
|
24
|
-
* deployments. Both were designed as defense in depth behind `workspaceMode`,
|
|
25
|
-
* and neither is declared here until it is enforced: a security knob that
|
|
26
|
-
* silently does nothing is worse than no knob at all.
|
|
27
|
-
*/
|
|
18
|
+
/** Working directories and the data roots exposed through the scoped reader. */
|
|
28
19
|
export interface IsolationConfig {
|
|
29
20
|
/**
|
|
30
|
-
* `per-peer` gives each identity its own cwd
|
|
31
|
-
*
|
|
32
|
-
* `shared` is the collaborative posture and must be chosen deliberately.
|
|
21
|
+
* `per-peer` gives each identity its own cwd. Neither mode is a filesystem
|
|
22
|
+
* security boundary. read_file enforces its own canonical data-root boundary.
|
|
33
23
|
*/
|
|
34
24
|
workspaceMode: 'per-peer' | 'shared';
|
|
35
|
-
/**
|
|
25
|
+
/** Shared read-only data root; also the cwd parent in `per-peer` mode. */
|
|
36
26
|
workspaceRoot: string;
|
|
37
|
-
/**
|
|
27
|
+
/** Overrides both a peer's cwd and its authorized read root. */
|
|
38
28
|
peerWorkspaces: Record<string, string>;
|
|
39
29
|
}
|
|
40
30
|
/** One declared skill, as it appears on the Agent Card. */
|
|
@@ -82,6 +72,28 @@ export interface PushConfig {
|
|
|
82
72
|
*/
|
|
83
73
|
enabled: boolean;
|
|
84
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* The host's background briefing, injected when a visitor's context opens.
|
|
77
|
+
*
|
|
78
|
+
* The files are read once per Activation (best effort: an absent file is the
|
|
79
|
+
* normal "nothing to hand over" case) and merged into the context's FIRST
|
|
80
|
+
* visitor message rather than sent as their own turn — one model call is
|
|
81
|
+
* spared, and the turn counters stay about the visitor's messages only.
|
|
82
|
+
*/
|
|
83
|
+
export interface PreambleConfig {
|
|
84
|
+
/** Publication-safe paths relative to the workspace root; absolute paths pass through. */
|
|
85
|
+
files: string[];
|
|
86
|
+
}
|
|
87
|
+
/** Local-only monitoring surface credentials. */
|
|
88
|
+
export interface AdminConfig {
|
|
89
|
+
/**
|
|
90
|
+
* Credential REFERENCE name holding the admin token, NOT the token itself.
|
|
91
|
+
* Empty or absent means the monitoring surface stays unmounted.
|
|
92
|
+
*/
|
|
93
|
+
tokenEnv: string;
|
|
94
|
+
/** Local named pipe / Unix socket. Never served on the public HTTP carrier. */
|
|
95
|
+
socketPath?: string;
|
|
96
|
+
}
|
|
85
97
|
/** The whole plugin configuration. */
|
|
86
98
|
export interface A2AServerConfig {
|
|
87
99
|
basePath: string;
|
|
@@ -103,7 +115,34 @@ export interface A2AServerConfig {
|
|
|
103
115
|
blockTimeoutMs: number;
|
|
104
116
|
contextIdleTtlMs: number;
|
|
105
117
|
maxResidentContexts: number;
|
|
118
|
+
maxConcurrentTasks: number;
|
|
119
|
+
maxConcurrentTasksPerPeer: number;
|
|
120
|
+
maxTasksPerPeerPerDay: number;
|
|
121
|
+
taskTimeoutMs: number;
|
|
122
|
+
maxModelCallsPerTask: number;
|
|
123
|
+
maxOutputTokens: number;
|
|
124
|
+
maxInputChars: number;
|
|
125
|
+
maxOutputChars: number;
|
|
126
|
+
streamHeartbeatMs: number;
|
|
127
|
+
maxStreamsPerTask: number;
|
|
128
|
+
maxStreamBufferBytes: number;
|
|
129
|
+
storage: {
|
|
130
|
+
directory?: string;
|
|
131
|
+
retentionMs: number;
|
|
132
|
+
maxContexts: number;
|
|
133
|
+
maxContextBytes: number;
|
|
134
|
+
};
|
|
106
135
|
isolation: IsolationConfig;
|
|
136
|
+
preamble: PreambleConfig;
|
|
137
|
+
/** Optional Portal-managed automatic updates; omission leaves the transport inert. */
|
|
138
|
+
briefing?: {
|
|
139
|
+
settingsFile: string;
|
|
140
|
+
prompt: string;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Enables owner RPC and monitoring on private local IPC, never public HTTP.
|
|
144
|
+
*/
|
|
145
|
+
admin?: AdminConfig;
|
|
107
146
|
push: PushConfig;
|
|
108
147
|
}
|
|
109
148
|
export declare const Config: Schema<A2AServerConfig>;
|
package/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,MAAM,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/lib/config.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* @module dsh-a2a/config
|
|
11
11
|
*/
|
|
12
12
|
import Schema from '@deepseek-ai/schemastery';
|
|
13
|
+
import { isAbsolute } from 'node:path';
|
|
13
14
|
/** A credential reference name: the shape `ctx.credentials` addresses. */
|
|
14
15
|
const CREDENTIAL_REF = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
15
16
|
/** A peer name: also the workspace directory component, so no separators. */
|
|
@@ -20,10 +21,7 @@ const PEER_NAME = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
|
|
|
20
21
|
* - `streamGranularity: 'message' | 'chunk'` — streaming currently emits only
|
|
21
22
|
* committed assistant messages. The `chunk` mode needs an `assistant/chunk`
|
|
22
23
|
* subscription and a decision about retried text reaching a peer.
|
|
23
|
-
*
|
|
24
|
-
* non-terminal. Nothing sweeps for those yet.
|
|
25
|
-
*
|
|
26
|
-
* Both were in the design; neither is wired. They return with their code.
|
|
24
|
+
* This option returns with its implementation.
|
|
27
25
|
*/
|
|
28
26
|
export const Config = Schema.object({
|
|
29
27
|
basePath: Schema.string().default('/a2a'),
|
|
@@ -57,18 +55,51 @@ export const Config = Schema.object({
|
|
|
57
55
|
peers: Schema.dict(Schema.object({
|
|
58
56
|
tokenEnv: Schema.string().required(),
|
|
59
57
|
})).default({}),
|
|
60
|
-
|
|
58
|
+
// An array schema implicitly defaults to []; the wrapper preserves omission.
|
|
59
|
+
trustedPeers: Schema.union([Schema.array(Schema.string())]),
|
|
61
60
|
rateLimitPerMinute: Schema.natural().default(60),
|
|
62
61
|
maxContextTurns: Schema.natural().default(5),
|
|
63
62
|
sendMode: Schema.union(['block', 'immediate']).default('block'),
|
|
64
63
|
blockTimeoutMs: Schema.natural().default(60_000),
|
|
65
64
|
contextIdleTtlMs: Schema.natural().default(1_800_000),
|
|
66
65
|
maxResidentContexts: Schema.natural().default(64),
|
|
66
|
+
maxConcurrentTasks: Schema.natural().default(8),
|
|
67
|
+
maxConcurrentTasksPerPeer: Schema.natural().default(2),
|
|
68
|
+
maxTasksPerPeerPerDay: Schema.natural().default(200),
|
|
69
|
+
taskTimeoutMs: Schema.natural().default(120_000),
|
|
70
|
+
maxModelCallsPerTask: Schema.natural().default(8),
|
|
71
|
+
maxOutputTokens: Schema.natural().default(4096),
|
|
72
|
+
maxInputChars: Schema.natural().default(32_000),
|
|
73
|
+
maxOutputChars: Schema.natural().default(64_000),
|
|
74
|
+
streamHeartbeatMs: Schema.natural().default(15_000),
|
|
75
|
+
maxStreamsPerTask: Schema.natural().default(4),
|
|
76
|
+
maxStreamBufferBytes: Schema.natural().default(262_144),
|
|
77
|
+
storage: Schema.object({
|
|
78
|
+
directory: Schema.string(),
|
|
79
|
+
retentionMs: Schema.natural().default(86_400_000),
|
|
80
|
+
maxContexts: Schema.natural().default(256),
|
|
81
|
+
maxContextBytes: Schema.natural().default(4_000_000),
|
|
82
|
+
}),
|
|
67
83
|
isolation: Schema.object({
|
|
68
84
|
workspaceMode: Schema.union(['per-peer', 'shared']).default('per-peer'),
|
|
69
85
|
workspaceRoot: Schema.string().required(),
|
|
70
86
|
peerWorkspaces: Schema.dict(Schema.string()).default({}),
|
|
71
87
|
}).required(),
|
|
88
|
+
preamble: Schema.object({
|
|
89
|
+
files: Schema.array(Schema.string()).default(['.hop/handoff.md']),
|
|
90
|
+
}),
|
|
91
|
+
briefing: Schema.object({
|
|
92
|
+
settingsFile: Schema.string().default(''),
|
|
93
|
+
prompt: Schema.string().default(''),
|
|
94
|
+
}),
|
|
95
|
+
// Schemastery instantiates a nested object even when the deployment omits
|
|
96
|
+
// it, so `required()` here would make every admin-less config fail at load.
|
|
97
|
+
// An empty tokenEnv instead reads as "not configured", and the coherence
|
|
98
|
+
// check below is what keeps a non-empty one a valid REFERENCE name.
|
|
99
|
+
admin: Schema.object({
|
|
100
|
+
tokenEnv: Schema.string().default(''),
|
|
101
|
+
socketPath: Schema.string(),
|
|
102
|
+
}),
|
|
72
103
|
push: Schema.object({
|
|
73
104
|
enabled: Schema.boolean().default(false),
|
|
74
105
|
}),
|
|
@@ -90,7 +121,33 @@ export class A2AConfigError extends Error {
|
|
|
90
121
|
* @throws {A2AConfigError} when a peer name, credential reference, or path is unusable.
|
|
91
122
|
*/
|
|
92
123
|
export function assertConfigCoherent(config) {
|
|
124
|
+
if (config.briefing?.prompt || config.briefing?.settingsFile) {
|
|
125
|
+
if (!config.admin?.tokenEnv || !config.briefing.prompt.trim() || !isAbsolute(config.briefing.settingsFile)) {
|
|
126
|
+
throw new A2AConfigError('automatic briefing requires owner administration, a prompt, and an absolute settingsFile');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
for (const key of ['maxResidentContexts', 'maxConcurrentTasks', 'maxConcurrentTasksPerPeer',
|
|
130
|
+
'maxTasksPerPeerPerDay', 'taskTimeoutMs', 'maxModelCallsPerTask', 'maxOutputTokens',
|
|
131
|
+
'maxInputChars', 'maxOutputChars', 'streamHeartbeatMs', 'maxStreamsPerTask',
|
|
132
|
+
'maxStreamBufferBytes']) {
|
|
133
|
+
if (!Number.isSafeInteger(config[key]) || config[key] <= 0)
|
|
134
|
+
throw new A2AConfigError(`${key} must be positive`);
|
|
135
|
+
}
|
|
136
|
+
for (const [key, value] of Object.entries(config.storage)) {
|
|
137
|
+
if (key !== 'directory' && (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0)) {
|
|
138
|
+
throw new A2AConfigError(`storage.${key} must be positive`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (config.publicUrl !== undefined) {
|
|
142
|
+
const url = new URL(config.publicUrl);
|
|
143
|
+
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash) {
|
|
144
|
+
throw new A2AConfigError('publicUrl must be an HTTP(S) RPC URL without credentials, query, or fragment');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
93
147
|
for (const [peer, entry] of Object.entries(config.peers)) {
|
|
148
|
+
if (peer === 'owner') {
|
|
149
|
+
throw new A2AConfigError('peer name "owner" is reserved for the deployment owner (the local console)');
|
|
150
|
+
}
|
|
94
151
|
if (!PEER_NAME.test(peer)) {
|
|
95
152
|
throw new A2AConfigError(`peer name "${peer}" must match ${String(PEER_NAME)}: it becomes a workspace directory component`);
|
|
96
153
|
}
|
|
@@ -108,6 +165,14 @@ export function assertConfigCoherent(config) {
|
|
|
108
165
|
throw new A2AConfigError(`isolation.peerWorkspaces names "${peer}", which is not declared in peers`);
|
|
109
166
|
}
|
|
110
167
|
}
|
|
168
|
+
const adminTokenEnv = config.admin === undefined
|
|
169
|
+
|| typeof config.admin.tokenEnv !== 'string'
|
|
170
|
+
|| config.admin.tokenEnv.length === 0
|
|
171
|
+
? undefined
|
|
172
|
+
: config.admin.tokenEnv;
|
|
173
|
+
if (adminTokenEnv !== undefined && !CREDENTIAL_REF.test(adminTokenEnv)) {
|
|
174
|
+
throw new A2AConfigError(`admin.tokenEnv must be a credential REFERENCE name (${String(CREDENTIAL_REF)}), not a token value`);
|
|
175
|
+
}
|
|
111
176
|
if (!config.basePath.startsWith('/')) {
|
|
112
177
|
throw new A2AConfigError(`basePath must start with "/": ${config.basePath}`);
|
|
113
178
|
}
|
package/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,MAAM,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/lib/contexts.d.ts
CHANGED
|
@@ -23,8 +23,14 @@ export interface Activation {
|
|
|
23
23
|
readonly peer: string;
|
|
24
24
|
/** The resolved working directory this context's agent runs in. */
|
|
25
25
|
readonly cwd: string;
|
|
26
|
-
/** In-flight tasks, keyed by task id.
|
|
26
|
+
/** In-flight tasks, keyed by task id. The transport admits one per context. */
|
|
27
27
|
readonly slots: Map<A2ATaskId, TaskSlot>;
|
|
28
|
+
/**
|
|
29
|
+
* The host briefing read at activation, merged into this context's FIRST
|
|
30
|
+
* visitor message and then cleared — a one-shot, so `undefined` means both
|
|
31
|
+
* "nothing was configured" and "already delivered".
|
|
32
|
+
*/
|
|
33
|
+
preambleText?: string | undefined;
|
|
28
34
|
/** Last time a request touched this context, for idle eviction. */
|
|
29
35
|
lastTouchedAt: number;
|
|
30
36
|
}
|
|
@@ -74,9 +80,8 @@ export declare class ContextRegistry {
|
|
|
74
80
|
* Select Activations that may be evicted right now.
|
|
75
81
|
*
|
|
76
82
|
* An Activation is evictable only when nothing is owed: no in-flight task and
|
|
77
|
-
* no recent touch.
|
|
78
|
-
*
|
|
79
|
-
* dropping work a peer is waiting on is worse than exceeding a soft ceiling.
|
|
83
|
+
* no recent touch. Admission separately evicts the oldest quiet activation
|
|
84
|
+
* BEFORE creating a new agent. A busy context is never evicted for capacity.
|
|
80
85
|
* @returns Activations the caller should dispose and remove.
|
|
81
86
|
*/
|
|
82
87
|
evictable(): Activation[];
|
package/lib/contexts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contexts.d.ts","sourceRoot":"","sources":["../src/contexts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C,8BAA8B;AAC9B,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAA;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,mEAAmE;IACnE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB
|
|
1
|
+
{"version":3,"file":"contexts.d.ts","sourceRoot":"","sources":["../src/contexts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C,8BAA8B;AAC9B,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAA;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,mEAAmE;IACnE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;IACxC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,mEAAmE;IACnE,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,0DAA0D;AAC1D,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,CAAA;AAEnD,8DAA8D;AAC9D,qBAAa,eAAe;IASxB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAVtB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAElE;;;;OAIG;gBAEgB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,MAAiB;IAG/C,qDAAqD;IACrD,MAAM,IAAI,UAAU,EAAE;IAItB,gDAAgD;IAChD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa;IAQzE;;;OAGG;IACH,GAAG,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAMjC;;;;OAIG;IACH,MAAM,CAAC,SAAS,EAAE,YAAY,GAAG,UAAU,GAAG,SAAS;IAMvD,yEAAyE;IACzE,KAAK,IAAI,UAAU,EAAE;IAMrB;;;;;;;OAOG;IACH,SAAS,IAAI,UAAU,EAAE;CAI1B"}
|
package/lib/contexts.js
CHANGED
|
@@ -59,6 +59,10 @@ export class ContextRegistry {
|
|
|
59
59
|
* @param activation - the Activation to hold.
|
|
60
60
|
*/
|
|
61
61
|
add(activation) {
|
|
62
|
+
if (this.activations.has(activation.contextId))
|
|
63
|
+
throw new Error('context is already resident');
|
|
64
|
+
if (this.activations.size >= this.maxResident)
|
|
65
|
+
throw new Error('resident context capacity reached');
|
|
62
66
|
this.activations.set(activation.contextId, activation);
|
|
63
67
|
}
|
|
64
68
|
/**
|
|
@@ -81,23 +85,13 @@ export class ContextRegistry {
|
|
|
81
85
|
* Select Activations that may be evicted right now.
|
|
82
86
|
*
|
|
83
87
|
* An Activation is evictable only when nothing is owed: no in-flight task and
|
|
84
|
-
* no recent touch.
|
|
85
|
-
*
|
|
86
|
-
* dropping work a peer is waiting on is worse than exceeding a soft ceiling.
|
|
88
|
+
* no recent touch. Admission separately evicts the oldest quiet activation
|
|
89
|
+
* BEFORE creating a new agent. A busy context is never evicted for capacity.
|
|
87
90
|
* @returns Activations the caller should dispose and remove.
|
|
88
91
|
*/
|
|
89
92
|
evictable() {
|
|
90
93
|
const cutoff = this.now() - this.idleTtlMs;
|
|
91
|
-
|
|
92
|
-
const expired = quiet.filter(a => a.lastTouchedAt <= cutoff);
|
|
93
|
-
if (this.activations.size <= this.maxResident)
|
|
94
|
-
return expired;
|
|
95
|
-
const overflow = this.activations.size - this.maxResident;
|
|
96
|
-
const byOldest = quiet
|
|
97
|
-
.filter(a => !expired.includes(a))
|
|
98
|
-
.sort((a, b) => a.lastTouchedAt - b.lastTouchedAt)
|
|
99
|
-
.slice(0, Math.max(0, overflow - expired.length));
|
|
100
|
-
return [...expired, ...byOldest];
|
|
94
|
+
return this.values().filter(a => a.slots.size === 0 && a.lastTouchedAt <= cutoff);
|
|
101
95
|
}
|
|
102
96
|
}
|
|
103
97
|
//# sourceMappingURL=contexts.js.map
|
package/lib/contexts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contexts.js","sourceRoot":"","sources":["../src/contexts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"contexts.js","sourceRoot":"","sources":["../src/contexts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA8BH,8DAA8D;AAC9D,MAAM,OAAO,eAAe;IASP;IACA;IACA;IAVF,WAAW,GAAG,IAAI,GAAG,EAA4B,CAAA;IAElE;;;;OAIG;IACH,YACmB,WAAmB,EACnB,SAAiB,EACjB,MAAoB,IAAI,CAAC,GAAG;QAF5B,gBAAW,GAAX,WAAW,CAAQ;QACnB,cAAS,GAAT,SAAS,CAAQ;QACjB,QAAG,GAAH,GAAG,CAAyB;IAC5C,CAAC;IAEJ,qDAAqD;IACrD,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAA;IACvC,CAAC;IAED,gDAAgD;IAChD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAA;IAC9B,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,SAAuB,EAAE,IAAY;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAClD,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;QAC9C,IAAI,UAAU,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,WAAW,CAAA;QAChD,UAAU,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACrC,OAAO,UAAU,CAAA;IACnB,CAAC;IAED;;;OAGG;IACH,GAAG,CAAC,UAAsB;QACxB,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAC9F,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;QACnG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;IACxD,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,SAAuB;QAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAClD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAClC,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,yEAAyE;IACzE,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAA;QACzB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAA;QACxB,OAAO,GAAG,CAAA;IACZ,CAAC;IAED;;;;;;;OAOG;IACH,SAAS;QACP,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAA;QAC1C,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,aAAa,IAAI,MAAM,CAAC,CAAA;IACnF,CAAC;CACF"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,38 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Inbound A2A protocol server for DeepSeek Harness.
|
|
3
|
-
*
|
|
4
|
-
* Publishes an Agent Card at a well-known URI and serves the A2A v1.0 JSON-RPC
|
|
5
|
-
* binding, so any compliant peer that knows this deployment's URL can discover
|
|
6
|
-
* it and submit tasks to a harness agent. There is no outbound client: this
|
|
7
|
-
* plugin never connects to another agent.
|
|
8
|
-
*
|
|
9
|
-
* v1.0 is the ONLY protocol version served. The v0.3 method names, `kind`
|
|
10
|
-
* discriminators, and lowercase enums are gone rather than aliased: a reply
|
|
11
|
-
* this server produces is v1.0 JSON, and a v0.3 client could not read it, so
|
|
12
|
-
* answering a v0.3 request would fail further from its cause than refusing it.
|
|
13
|
-
*
|
|
14
|
-
* It is a TRANSPORT ADAPTER, not a capability seam — the same self-limitation
|
|
15
|
-
* `dsh-acp` states. It exposes no editor navigation, transcript replay,
|
|
16
|
-
* commands, modes, or tool presentation.
|
|
17
|
-
*
|
|
18
|
-
* @module dsh-a2a-server
|
|
19
|
-
*/
|
|
20
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
21
2
|
import { Config, type A2AServerConfig } from './config.ts';
|
|
22
3
|
export { Config };
|
|
23
4
|
export type { A2AServerConfig };
|
|
24
5
|
export declare const name = "a2a-server";
|
|
25
|
-
/**
|
|
26
|
-
* The server creates and owns agents, needs an HTTP carrier for its routes, and
|
|
27
|
-
* cannot authenticate a single request without the credential seam. Everything
|
|
28
|
-
* else it uses is probed with `ctx.get()` so a composition missing an optional
|
|
29
|
-
* capability still boots with A2A serving.
|
|
30
|
-
*/
|
|
31
6
|
export declare const inject: string[];
|
|
32
|
-
|
|
33
|
-
* Mount the inbound A2A server.
|
|
34
|
-
* @param ctx - the Cordis context carrying the agent factory, HTTP carrier, and credentials.
|
|
35
|
-
* @param config - the validated plugin configuration.
|
|
36
|
-
*/
|
|
37
|
-
export declare function apply(ctx: Context, config: A2AServerConfig): void;
|
|
7
|
+
export declare function apply(ctx: Context, config: A2AServerConfig): Promise<void>;
|
|
38
8
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AASlD,OAAO,EAAwB,MAAM,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AAkBhF,OAAO,EAAE,MAAM,EAAE,CAAA;AACjB,YAAY,EAAE,eAAe,EAAE,CAAA;AAC/B,eAAO,MAAM,IAAI,eAAe,CAAA;AAGhC,eAAO,MAAM,MAAM,UAAkE,CAAA;AAKrF,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwZhF"}
|