@ftai/dsh-plugin-acn 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -1
- package/README.md +31 -4
- package/README_EN.md +31 -4
- package/docs/architecture.md +1 -0
- package/docs/assets/acn-claim-reuse.png +0 -0
- package/docs/config.md +19 -9
- package/docs/development.md +4 -4
- package/docs/dsh-compat.md +2 -2
- package/docs/user_guide.md +3 -1
- package/lib/{activities-LRoCwpzw.js → activities-B8U-iW4-.js} +84 -4
- package/lib/{checkpoint-Bmt8q2vB.js → checkpoint-CPFPOxBM.js} +2 -2
- package/lib/{checkpoint-RgcdqifN.js → checkpoint-c7aI4D-X.js} +1 -1
- package/lib/client.js +220 -223
- package/lib/{deliver-BuYQaPRW.js → deliver-C-dmhkfm.js} +1 -1
- package/lib/{delivery-status-D5m3178s.js → delivery-status-M7-Rwoyj.js} +4 -2
- package/lib/{dream-agent-DBszTHXY.js → dream-agent-BVqxbKFc.js} +3 -3
- package/lib/dream.js +3 -3
- package/lib/{effects-DJ4Xa7Tx.js → effects-DX1iy6FM.js} +2 -2
- package/lib/{evidence-store-DLFvSuNa.js → evidence-store-DW7kj20i.js} +1 -1
- package/lib/{formation-replay-CEOy5FkI.js → formation-replay-Bf4TSBiz.js} +1 -1
- package/lib/formation.js +5 -5
- package/lib/history-DPMHX3ZE.js +214 -0
- package/lib/inbox.js +2 -2
- package/lib/index.js +43 -47
- package/lib/{paths-CDYV5UH9.js → paths-B7NI9Ano.js} +6 -3
- package/lib/plugins/commands.js +3 -3
- package/lib/plugins/dream.js +4 -4
- package/lib/plugins/formation.js +3 -3
- package/lib/plugins/inbox.js +3 -3
- package/lib/plugins/knowledge.js +21 -23
- package/lib/plugins/prompt.js +1 -1
- package/lib/plugins/tools.js +1 -1
- package/lib/{prepare-DwHZudbA.js → prepare-CGXwBEcu.js} +2 -2
- package/lib/{scheduler-MaUEbXr3.js → scheduler-BfJSY1eq.js} +1 -1
- package/lib/{service-C_i3BzdP.js → service-BPwaZzFF.js} +3 -3
- package/lib/{service-B7AI5jds.js → service-BQaszW_v.js} +1 -1
- package/lib/{service-BcHV5mc7.js → service-BhniAHLo.js} +5 -5
- package/lib/{service-CNjqHCBR.js → service-C2lXoygJ.js} +4 -4
- package/lib/session-binding-zCSuizHs.js +342 -0
- package/lib/store.js +1 -1
- package/lib/{structured-lyQCK-Zk.js → structured-C9byFuzm.js} +1 -0
- package/lib/team.js +1 -1
- package/lib/types/activities.d.ts +2 -0
- package/lib/types/client/ActivityCard.d.ts +14 -0
- package/lib/types/client/ActivityDetails.d.ts +1 -1
- package/lib/types/client/SourceSessionLink.d.ts +2 -1
- package/lib/types/client/TeamSettingsPage.d.ts +0 -2
- package/lib/types/client/interaction-styles.d.ts +1 -1
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/config.d.ts +1 -12
- package/lib/types/configuration.d.ts +0 -24
- package/lib/types/credentials.d.ts +0 -6
- package/lib/types/dsh-adapter/session-binding.d.ts +1 -1
- package/lib/types/interaction.d.ts +6 -15
- package/lib/types/store/delivery-status.d.ts +1 -0
- package/lib/types/store/history.d.ts +65 -0
- package/lib/types/store/library-directory.d.ts +4 -0
- package/lib/types/store/paths.d.ts +1 -1
- package/lib/upload.js +2 -2
- package/lib/{team-credentials-C9xHrPIi.js → upstreams-DEi-56tD.js} +164 -248
- package/lib/{worker-BBTYP2RE.js → worker-HMGzJFWd.js} +1 -1
- package/package.json +1 -1
- package/lib/presentation-BlLjgDjP.js +0 -47
- package/lib/session-binding-BQrOGhZI.js +0 -151
|
@@ -1,273 +1,153 @@
|
|
|
1
|
-
import { S as timestampNanos,
|
|
2
|
-
import { R as nextClaimUpdateAt } from "./evidence-store-
|
|
1
|
+
import { S as timestampNanos, i as effectiveUpdatedAt, x as nowSeconds } from "./claim-DOAGe8ZK.js";
|
|
2
|
+
import { R as nextClaimUpdateAt } from "./evidence-store-DW7kj20i.js";
|
|
3
3
|
import { n as claimRevision } from "./revision-DeoL_IUN.js";
|
|
4
4
|
import { n as RevisionConflict, t as KnowledgeError } from "./errors-Bp_2WXBr.js";
|
|
5
5
|
import { n as validateClaimText } from "./regular-file-BFpqMoub.js";
|
|
6
|
-
import { C as StoreError, S as LockTimeoutError, d as removeFile, n as withFileLock, u as cleanupAtomicTemps, w as hasCode } from "./lock-DbmlKOoX.js";
|
|
6
|
+
import { C as StoreError, S as LockTimeoutError, d as removeFile, f as writeTextAtomic, n as withFileLock, u as cleanupAtomicTemps, w as hasCode } from "./lock-DbmlKOoX.js";
|
|
7
7
|
import { n as AnalysisReadBoundary, r as KnowledgeBusy } from "./alignment-CwH0nBf-.js";
|
|
8
8
|
import { i as ClaimStore } from "./reported-sets-DdEKdeVb.js";
|
|
9
9
|
import { t as TraceStore } from "./traces-CHBo8y1z.js";
|
|
10
10
|
import { r as UploadStore } from "./uploads-BCA2p92b.js";
|
|
11
|
-
import { t as DreamStore } from "./checkpoint-
|
|
12
|
-
import {
|
|
11
|
+
import { t as DreamStore } from "./checkpoint-c7aI4D-X.js";
|
|
12
|
+
import { C as resolveConfig, S as activeUpstream, b as UpstreamNameSchema, v as ConfigError, w as upstreamsOf, x as UpstreamSchema } from "./session-binding-zCSuizHs.js";
|
|
13
|
+
import { a as assertStorageName, n as agentHomePath, r as expandHomePath, t as AgentPaths } from "./paths-B7NI9Ano.js";
|
|
13
14
|
import { n as ClaimEditStore } from "./disputes-ByEmi43j.js";
|
|
14
|
-
import { n as FormationStore } from "./checkpoint-
|
|
15
|
-
import { n as InboxEffectStore } from "./effects-
|
|
16
|
-
import { t as TeamFacade } from "./service-
|
|
17
|
-
import { t as DurableWorker } from "./worker-
|
|
15
|
+
import { n as FormationStore } from "./checkpoint-CPFPOxBM.js";
|
|
16
|
+
import { n as InboxEffectStore } from "./effects-DX1iy6FM.js";
|
|
17
|
+
import { t as TeamFacade } from "./service-BQaszW_v.js";
|
|
18
|
+
import { t as DurableWorker } from "./worker-HMGzJFWd.js";
|
|
18
19
|
import { r as MAX_TRACE_TASK_PAGE_LIMIT, t as ClaimUpdateSchema } from "./types-C2ST2Zdg.js";
|
|
19
20
|
import { a as validatePage, n as claimListPage, r as page } from "./pages-BEWC3kmZ.js";
|
|
20
|
-
import {
|
|
21
|
+
import { n as PresentationStore, t as historicalKnowledge } from "./history-DPMHX3ZE.js";
|
|
21
22
|
import { z } from "zod";
|
|
22
|
-
import { createHash } from "node:crypto";
|
|
23
|
-
import fs, { realpath } from "node:fs/promises";
|
|
23
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
24
|
+
import fs, { readFile, realpath } from "node:fs/promises";
|
|
24
25
|
import { join, resolve } from "node:path";
|
|
25
|
-
//#region src/
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
//#region src/store/library-directory.ts
|
|
27
|
+
const Summary = z.object({
|
|
28
|
+
id: UpstreamNameSchema,
|
|
29
|
+
name: UpstreamSchema.shape.name,
|
|
30
|
+
agentId: UpstreamSchema.shape.agentId,
|
|
31
|
+
enabled: UpstreamSchema.shape.enabled,
|
|
32
|
+
maintainerEndpoint: UpstreamSchema.shape.maintainerEndpoint,
|
|
33
|
+
routerEndpoint: UpstreamSchema.shape.routerEndpoint
|
|
34
|
+
});
|
|
35
|
+
const Index = z.object({
|
|
36
|
+
schemaVersion: z.literal(1),
|
|
37
|
+
upstreams: z.array(z.object({ summary: Summary })),
|
|
38
|
+
preferences: z.object({ defaultUpstream: z.string().nullable().optional() }).optional()
|
|
39
|
+
});
|
|
40
|
+
const ObjectRecord = z.record(z.string(), z.unknown());
|
|
41
|
+
async function sameDirectory(left, right) {
|
|
42
|
+
const a = resolve(expandHomePath(left));
|
|
43
|
+
const b = resolve(expandHomePath(right));
|
|
44
|
+
if (a === b) return true;
|
|
30
45
|
try {
|
|
31
|
-
const
|
|
32
|
-
return
|
|
46
|
+
const [first, second] = await Promise.all([realpath(a), realpath(b)]);
|
|
47
|
+
return process.platform === "win32" ? first.toLowerCase() === second.toLowerCase() : first === second;
|
|
33
48
|
} catch {
|
|
34
49
|
return false;
|
|
35
50
|
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
".git"
|
|
45
|
-
].includes(value));
|
|
46
|
-
const UpstreamSchema = z.strictObject({
|
|
47
|
-
name: z.string().trim().max(80).default(""),
|
|
48
|
-
agentId: AgentIdSchema,
|
|
49
|
-
enabled: z.boolean().default(true),
|
|
50
|
-
routerEndpoint: endpoint.default(""),
|
|
51
|
-
maintainerEndpoint: endpoint.default(""),
|
|
52
|
-
keyEnv: z.string().regex(/^(?:[A-Za-z_][A-Za-z0-9_]*)?$/).default(""),
|
|
53
|
-
timeoutMs: positive().default(15e3),
|
|
54
|
-
legacyStorage: z.enum([
|
|
55
|
-
"base",
|
|
56
|
-
"personal",
|
|
57
|
-
"connection"
|
|
58
|
-
]).optional(),
|
|
59
|
-
legacyKey: z.string().regex(/^[a-zA-Z0-9_-]{1,80}$/).optional()
|
|
60
|
-
}).superRefine((value, ctx) => {
|
|
61
|
-
if (Boolean(value.routerEndpoint) !== Boolean(value.maintainerEndpoint)) ctx.addIssue({
|
|
62
|
-
code: "custom",
|
|
63
|
-
path: ["routerEndpoint"],
|
|
64
|
-
message: "Configure both team endpoints or neither."
|
|
65
|
-
});
|
|
66
|
-
if (value.legacyStorage === "connection" !== (value.legacyKey !== void 0)) ctx.addIssue({
|
|
67
|
-
code: "custom",
|
|
68
|
-
path: ["legacyStorage"],
|
|
69
|
-
message: "Invalid legacy storage mapping."
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
const ConnectionSchema = z.strictObject({
|
|
73
|
-
id: z.string().regex(/^[a-zA-Z0-9_-]{1,80}$/).refine((id) => !["personal", "legacy"].includes(id)),
|
|
74
|
-
name: z.string().trim().min(1).max(80),
|
|
75
|
-
enabled: z.boolean().default(true),
|
|
76
|
-
agentId: AgentIdSchema,
|
|
77
|
-
routerEndpoint: endpoint.refine(Boolean),
|
|
78
|
-
maintainerEndpoint: endpoint.refine(Boolean),
|
|
79
|
-
keyEnv: z.string().regex(/^(?:[A-Za-z_][A-Za-z0-9_]*)?$/).default(""),
|
|
80
|
-
timeoutMs: positive().default(15e3)
|
|
81
|
-
});
|
|
82
|
-
const ConfigSchema = z.strictObject({
|
|
83
|
-
upstream: z.string().default(""),
|
|
84
|
-
upstreams: z.record(UpstreamNameSchema, UpstreamSchema).optional(),
|
|
85
|
-
agentId: z.union([z.literal(""), AgentIdSchema]).default(""),
|
|
86
|
-
home: z.string().trim().min(1).default("~/.acn-dsh"),
|
|
87
|
-
sessionEpoch: nonnegative().default(0),
|
|
88
|
-
connections: z.array(ConnectionSchema).max(50).default([]),
|
|
89
|
-
defaultConnection: z.string().default(""),
|
|
90
|
-
legacyEnabled: z.boolean().default(true),
|
|
91
|
-
showCompletion: z.boolean().default(true),
|
|
92
|
-
team: z.strictObject({
|
|
93
|
-
routerEndpoint: endpoint.default(""),
|
|
94
|
-
maintainerEndpoint: endpoint.default(""),
|
|
95
|
-
keyEnv: z.string().regex(/^(?:[A-Za-z_][A-Za-z0-9_]*)?$/).default(""),
|
|
96
|
-
timeoutMs: positive().default(15e3),
|
|
97
|
-
routerTimeoutMs: positive().default(5e4),
|
|
98
|
-
retryCount: nonnegative().default(3),
|
|
99
|
-
retryBaseDelayMs: positive().default(500),
|
|
100
|
-
retryMaxDelayMs: positive().default(8e3)
|
|
101
|
-
}).prefault({}),
|
|
102
|
-
llm: z.strictObject({
|
|
103
|
-
provider: z.string().default(""),
|
|
104
|
-
model: z.string().default(""),
|
|
105
|
-
maxOutputTokens: positive().default(32768),
|
|
106
|
-
timeoutMs: positive().default(6e5),
|
|
107
|
-
structuredRetries: positive().default(5)
|
|
108
|
-
}).prefault({}),
|
|
109
|
-
catalog: z.strictObject({
|
|
110
|
-
maxClaims: positive().default(20),
|
|
111
|
-
maxChars: positive().default(24e3)
|
|
112
|
-
}).prefault({}),
|
|
113
|
-
formation: z.strictObject({
|
|
114
|
-
recapOnCompaction: z.boolean().default(true),
|
|
115
|
-
idleRecap: z.boolean().default(true),
|
|
116
|
-
recapMinTurns: positive().default(10),
|
|
117
|
-
recapMinTokens: positive().default(1e5),
|
|
118
|
-
recapBatchIdleMinutes: positive().default(5),
|
|
119
|
-
recapTailIdleMinutes: positive().default(60),
|
|
120
|
-
recapScanSeconds: positive().default(30),
|
|
121
|
-
finalizeIdleMinutes: nonnegative().default(0),
|
|
122
|
-
finalizeOnDispose: z.boolean().default(false)
|
|
123
|
-
}).prefault({}),
|
|
124
|
-
inbox: z.strictObject({
|
|
125
|
-
pullOnSessionStart: z.boolean().default(true),
|
|
126
|
-
processingStaleAfterSecs: positive().default(600)
|
|
127
|
-
}).prefault({}),
|
|
128
|
-
dream: z.strictObject({
|
|
129
|
-
enabled: z.boolean().default(true),
|
|
130
|
-
minIntervalHours: positive().default(24),
|
|
131
|
-
minChangedClaims: positive().default(5),
|
|
132
|
-
checkIntervalHours: positive().default(4),
|
|
133
|
-
evidenceCalibration: z.boolean().default(false),
|
|
134
|
-
maxModelSteps: positive().max(128).default(24),
|
|
135
|
-
maxWrapUpSteps: positive().max(8).default(3),
|
|
136
|
-
evidenceMaxCalls: positive().max(256).default(32),
|
|
137
|
-
evidenceMaxSteps: positive().max(128).default(24),
|
|
138
|
-
evidenceMaxBytes: positive().max(16777216).default(1048576),
|
|
139
|
-
evidenceMaxChars: positive().max(64e3).default(16e3),
|
|
140
|
-
evidenceMaxFiles: positive().max(4096).default(256)
|
|
141
|
-
}).prefault({})
|
|
142
|
-
}).superRefine((config, ctx) => {
|
|
143
|
-
if (config.upstreams !== void 0) {
|
|
144
|
-
if (config.upstream !== "" && config.upstreams[config.upstream]?.enabled !== true) ctx.addIssue({
|
|
145
|
-
code: "custom",
|
|
146
|
-
path: ["upstream"],
|
|
147
|
-
message: "Select an enabled upstream."
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
if (new Set(config.connections.map((item) => item.id)).size !== config.connections.length) ctx.addIssue({
|
|
151
|
-
code: "custom",
|
|
152
|
-
path: ["connections"],
|
|
153
|
-
message: "Connection identifiers must be unique."
|
|
154
|
-
});
|
|
155
|
-
if (config.defaultConnection !== "" && config.defaultConnection !== "legacy" && !config.connections.some((item) => item.id === config.defaultConnection && item.enabled)) ctx.addIssue({
|
|
156
|
-
code: "custom",
|
|
157
|
-
path: ["defaultConnection"],
|
|
158
|
-
message: "Default connection must be enabled."
|
|
159
|
-
});
|
|
160
|
-
if (Boolean(config.team.routerEndpoint) !== Boolean(config.team.maintainerEndpoint)) ctx.addIssue({
|
|
161
|
-
code: "custom",
|
|
162
|
-
path: ["team"],
|
|
163
|
-
message: "Configure both team endpoints or neither."
|
|
164
|
-
});
|
|
165
|
-
if (Boolean(config.llm.provider.trim()) !== Boolean(config.llm.model.trim())) ctx.addIssue({
|
|
166
|
-
code: "custom",
|
|
167
|
-
path: ["llm"],
|
|
168
|
-
message: "Configure both provider and model or neither."
|
|
169
|
-
});
|
|
170
|
-
if (config.team.retryMaxDelayMs < config.team.retryBaseDelayMs) ctx.addIssue({
|
|
171
|
-
code: "custom",
|
|
172
|
-
path: ["team", "retryMaxDelayMs"],
|
|
173
|
-
message: "Maximum retry delay must not be smaller than the base delay."
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
var ConfigError = class extends Error {
|
|
177
|
-
fields;
|
|
178
|
-
kind = "config";
|
|
179
|
-
constructor(fields) {
|
|
180
|
-
super(`Invalid ACN configuration: ${fields.join(", ")}`);
|
|
181
|
-
this.fields = fields;
|
|
182
|
-
this.name = "ConfigError";
|
|
51
|
+
}
|
|
52
|
+
async function readIndex(home) {
|
|
53
|
+
let text;
|
|
54
|
+
try {
|
|
55
|
+
text = await readFile(join(expandHomePath(home), "settings.json"), "utf8");
|
|
56
|
+
} catch (error) {
|
|
57
|
+
if (hasCode(error, "ENOENT")) return null;
|
|
58
|
+
throw new ConfigError(["libraryIndex"]);
|
|
183
59
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
60
|
+
try {
|
|
61
|
+
const raw = ObjectRecord.parse(JSON.parse(text));
|
|
62
|
+
const known = Index.parse(raw);
|
|
63
|
+
if (new Set(known.upstreams.map((item) => item.summary.id)).size !== known.upstreams.length) throw new ConfigError(["libraryIndex"]);
|
|
64
|
+
return {
|
|
65
|
+
raw,
|
|
66
|
+
known
|
|
67
|
+
};
|
|
68
|
+
} catch {
|
|
69
|
+
throw new ConfigError(["libraryIndex"]);
|
|
192
70
|
}
|
|
193
|
-
const parsed = ConfigSchema.safeParse(value);
|
|
194
|
-
if (!parsed.success) throw new ConfigError([...new Set(parsed.error.issues.map((issue) => issue.path.join(".") || "config"))]);
|
|
195
|
-
return parsed.data;
|
|
196
71
|
}
|
|
197
|
-
function
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
if (
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
routerEndpoint: config.team.routerEndpoint,
|
|
211
|
-
maintainerEndpoint: config.team.maintainerEndpoint,
|
|
212
|
-
keyEnv: config.team.keyEnv,
|
|
213
|
-
timeoutMs: config.team.timeoutMs,
|
|
214
|
-
legacyStorage: "base"
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
for (const connection of config.connections) {
|
|
218
|
-
const { id, ...value } = connection;
|
|
219
|
-
let key = id.toLowerCase();
|
|
220
|
-
while (items[key] !== void 0 || [
|
|
221
|
-
"data",
|
|
222
|
-
"skills",
|
|
223
|
-
"logs",
|
|
224
|
-
"tmp"
|
|
225
|
-
].includes(key)) key = `${key}_copy`;
|
|
226
|
-
items[key] = UpstreamSchema.parse({
|
|
72
|
+
async function prepareLibraryDirectory(previous, next) {
|
|
73
|
+
const before = resolveConfig(previous);
|
|
74
|
+
const after = resolveConfig(next);
|
|
75
|
+
if ((before.upstreams !== void 0 || before.agentId !== "" || after.upstreams !== void 0) && await sameDirectory(before.home, after.home)) return {
|
|
76
|
+
...next,
|
|
77
|
+
home: before.home
|
|
78
|
+
};
|
|
79
|
+
const index = await readIndex(after.home);
|
|
80
|
+
if (index === null) return next;
|
|
81
|
+
const upstreams = {};
|
|
82
|
+
for (const { summary } of index.known.upstreams) {
|
|
83
|
+
const { id, ...value } = summary;
|
|
84
|
+
const parsed = UpstreamSchema.safeParse({
|
|
227
85
|
...value,
|
|
228
|
-
|
|
229
|
-
|
|
86
|
+
timeoutMs: after.team.timeoutMs
|
|
87
|
+
});
|
|
88
|
+
if (!parsed.success) throw new ConfigError(["libraryIndex"]);
|
|
89
|
+
Object.defineProperty(upstreams, id, {
|
|
90
|
+
value: parsed.data,
|
|
91
|
+
enumerable: true,
|
|
92
|
+
writable: true,
|
|
93
|
+
configurable: true
|
|
230
94
|
});
|
|
231
95
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (profile === void 0 || !profile.enabled && !includeDisabled) return void 0;
|
|
239
|
-
assertStorageName(key);
|
|
240
|
-
if (profile.legacyKey !== void 0) assertStorageName(profile.legacyKey);
|
|
241
|
-
const home = profile.legacyStorage === "base" ? config.home : profile.legacyStorage === "personal" ? join(config.home, "personal") : profile.legacyStorage === "connection" ? join(config.home, "connections", profile.legacyKey ?? "") : join(config.home, key, "data");
|
|
242
|
-
return resolveConfig({
|
|
243
|
-
...config,
|
|
244
|
-
upstreams: void 0,
|
|
245
|
-
upstream: "",
|
|
96
|
+
const preferred = index.known.preferences?.defaultUpstream ?? "";
|
|
97
|
+
return {
|
|
98
|
+
...next,
|
|
99
|
+
upstreams,
|
|
100
|
+
upstream: upstreams[preferred]?.enabled ? preferred : "",
|
|
101
|
+
agentId: "",
|
|
246
102
|
connections: [],
|
|
247
|
-
defaultConnection: ""
|
|
248
|
-
|
|
249
|
-
home,
|
|
250
|
-
agentId: profile.agentId,
|
|
251
|
-
legacyEnabled: true,
|
|
252
|
-
team: {
|
|
253
|
-
...config.team,
|
|
254
|
-
routerEndpoint: profile.routerEndpoint,
|
|
255
|
-
maintainerEndpoint: profile.maintainerEndpoint,
|
|
256
|
-
keyEnv: profile.keyEnv,
|
|
257
|
-
timeoutMs: profile.timeoutMs
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
function defaultUpstream(config) {
|
|
262
|
-
return config.upstreams === void 0 ? config.agentId ? "personal" : "" : config.upstream;
|
|
103
|
+
defaultConnection: ""
|
|
104
|
+
};
|
|
263
105
|
}
|
|
264
|
-
async function
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
|
|
106
|
+
async function syncLibraryIndex(config, logger) {
|
|
107
|
+
const profiles = upstreamsOf(config);
|
|
108
|
+
if (config.upstreams === void 0 && Object.keys(profiles).length === 0) return;
|
|
109
|
+
const path = join(expandHomePath(config.home), "settings.json");
|
|
110
|
+
await withFileLock(`${path}.lock`, async () => {
|
|
111
|
+
const index = await readIndex(config.home);
|
|
112
|
+
const previous = index?.known.upstreams ?? [];
|
|
113
|
+
const summaries = Object.entries(profiles).map(([id, item]) => Summary.parse({
|
|
114
|
+
id,
|
|
115
|
+
...item
|
|
116
|
+
}));
|
|
117
|
+
const selected = config.upstreams === void 0 ? config.agentId ? "personal" : "" : config.upstream;
|
|
118
|
+
const expected = {
|
|
119
|
+
upstreams: summaries,
|
|
120
|
+
defaultUpstream: selected || null
|
|
121
|
+
};
|
|
122
|
+
if (index !== null && JSON.stringify({
|
|
123
|
+
upstreams: previous.map((item) => item.summary),
|
|
124
|
+
defaultUpstream: index.known.preferences?.defaultUpstream ?? null
|
|
125
|
+
}) === JSON.stringify(expected)) return;
|
|
126
|
+
const stored = z.array(ObjectRecord).parse(index?.raw.upstreams ?? []);
|
|
127
|
+
const upstreams = summaries.map((summary) => {
|
|
128
|
+
const position = previous.findIndex((item) => item.summary.id === summary.id);
|
|
129
|
+
const old = position < 0 ? void 0 : previous[position]?.summary;
|
|
130
|
+
const fields = position < 0 ? {} : stored[position] ?? {};
|
|
131
|
+
const sameTarget = old !== void 0 && old.agentId === summary.agentId && old.maintainerEndpoint === summary.maintainerEndpoint;
|
|
132
|
+
return {
|
|
133
|
+
...fields,
|
|
134
|
+
summary,
|
|
135
|
+
maintainerRevision: sameTarget && typeof fields.maintainerRevision === "string" ? fields.maintainerRevision : randomUUID(),
|
|
136
|
+
identityEpoch: old?.agentId === summary.agentId && typeof fields.identityEpoch === "string" ? fields.identityEpoch : randomUUID()
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
const preferences = ObjectRecord.parse(index?.raw.preferences ?? {});
|
|
140
|
+
await writeTextAtomic(path, JSON.stringify({
|
|
141
|
+
...index?.raw,
|
|
142
|
+
schemaVersion: 1,
|
|
143
|
+
revision: randomUUID(),
|
|
144
|
+
upstreams,
|
|
145
|
+
preferences: {
|
|
146
|
+
...preferences,
|
|
147
|
+
defaultUpstream: selected || null
|
|
148
|
+
}
|
|
149
|
+
}, null, 2) + "\n", logger);
|
|
150
|
+
});
|
|
271
151
|
}
|
|
272
152
|
//#endregion
|
|
273
153
|
//#region src/knowledge/service.ts
|
|
@@ -291,7 +171,7 @@ var AcnKnowledge = class {
|
|
|
291
171
|
this.mode = config.team.routerEndpoint ? "team" : "solo";
|
|
292
172
|
this.storeContext = this.agentId === null ? null : {
|
|
293
173
|
agentId: this.agentId,
|
|
294
|
-
paths: new AgentPaths(agentHomePath(config.home, this.agentId)),
|
|
174
|
+
paths: new AgentPaths(agentHomePath(config.home, this.agentId, activeUpstream(config))),
|
|
295
175
|
mode: this.mode,
|
|
296
176
|
logger
|
|
297
177
|
};
|
|
@@ -317,6 +197,7 @@ var AcnKnowledge = class {
|
|
|
317
197
|
}
|
|
318
198
|
async initialize() {
|
|
319
199
|
if (!this.configured) return;
|
|
200
|
+
if ((await historicalKnowledge(this.context())).applications.some((record) => record.state === "prepared")) throw new KnowledgeError("conflict", "知识目录还有未完成的历史提交,请先在原程序完成处理;当前插件不会重放旧任务。");
|
|
320
201
|
await new PresentationStore(this.context()).initialize();
|
|
321
202
|
await cleanupAtomicTemps(this.context().paths.root, this.logger);
|
|
322
203
|
await new DreamStore(this.context()).recover();
|
|
@@ -576,4 +457,39 @@ function teamCredentials(ctx) {
|
|
|
576
457
|
};
|
|
577
458
|
}
|
|
578
459
|
//#endregion
|
|
579
|
-
|
|
460
|
+
//#region src/upstreams.ts
|
|
461
|
+
function resolveUpstream(config, key, includeDisabled = false) {
|
|
462
|
+
const profile = upstreamsOf(config)[key];
|
|
463
|
+
if (profile === void 0 || !profile.enabled && !includeDisabled) return void 0;
|
|
464
|
+
assertStorageName(key);
|
|
465
|
+
return resolveConfig({
|
|
466
|
+
...config,
|
|
467
|
+
upstreams: void 0,
|
|
468
|
+
upstream: key,
|
|
469
|
+
connections: [],
|
|
470
|
+
defaultConnection: "",
|
|
471
|
+
sessionEpoch: 0,
|
|
472
|
+
agentId: profile.agentId,
|
|
473
|
+
legacyEnabled: true,
|
|
474
|
+
team: {
|
|
475
|
+
...config.team,
|
|
476
|
+
routerEndpoint: profile.routerEndpoint,
|
|
477
|
+
maintainerEndpoint: profile.maintainerEndpoint,
|
|
478
|
+
keyEnv: profile.keyEnv,
|
|
479
|
+
timeoutMs: profile.timeoutMs
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
function defaultUpstream(config) {
|
|
484
|
+
return config.upstreams === void 0 ? config.agentId ? "personal" : "" : config.upstream;
|
|
485
|
+
}
|
|
486
|
+
async function canonicalProjectPath(cwd) {
|
|
487
|
+
const path = resolve(cwd);
|
|
488
|
+
try {
|
|
489
|
+
return await realpath(path);
|
|
490
|
+
} catch {
|
|
491
|
+
return path;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
//#endregion
|
|
495
|
+
export { teamCredentials as a, syncLibraryIndex as c, credentialReference as i, defaultUpstream as n, AcnKnowledge as o, resolveUpstream as r, prepareLibraryDirectory as s, canonicalProjectPath as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { S as LockTimeoutError, _ as JobError, b as Preempted, g as DreamYield, h as DreamStopped, t as acquireFileLease, x as jobPriority } from "./lock-DbmlKOoX.js";
|
|
2
|
-
import { t as DreamStore } from "./checkpoint-
|
|
2
|
+
import { t as DreamStore } from "./checkpoint-c7aI4D-X.js";
|
|
3
3
|
import { n as runnableJob, t as JobQueue } from "./queue-M917xHPS.js";
|
|
4
4
|
//#region src/worker/worker.ts
|
|
5
5
|
var DurableWorker = class {
|
package/package.json
CHANGED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { c as readYamlOr, l as writeYamlAtomic, n as withFileLock } from "./lock-DbmlKOoX.js";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
//#region src/store/presentation.ts
|
|
5
|
-
const Schema = z.object({
|
|
6
|
-
schemaVersion: z.literal(1),
|
|
7
|
-
baselineAt: z.number(),
|
|
8
|
-
seen: z.record(z.string(), z.number())
|
|
9
|
-
});
|
|
10
|
-
var PresentationStore = class {
|
|
11
|
-
context;
|
|
12
|
-
path;
|
|
13
|
-
constructor(context) {
|
|
14
|
-
this.context = context;
|
|
15
|
-
this.path = join(context.paths.root, "presentation.yaml");
|
|
16
|
-
}
|
|
17
|
-
read() {
|
|
18
|
-
return readYamlOr(this.path, Schema, () => null);
|
|
19
|
-
}
|
|
20
|
-
async initialize() {
|
|
21
|
-
await withFileLock(`${this.path}.lock`, async () => {
|
|
22
|
-
if (await this.read() === null) await writeYamlAtomic(this.path, {
|
|
23
|
-
schemaVersion: 1,
|
|
24
|
-
baselineAt: Date.now(),
|
|
25
|
-
seen: {}
|
|
26
|
-
}, Schema, this.context.logger);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
async acknowledge(id, version) {
|
|
30
|
-
await withFileLock(`${this.path}.lock`, async () => {
|
|
31
|
-
const current = await this.read() ?? {
|
|
32
|
-
schemaVersion: 1,
|
|
33
|
-
baselineAt: Date.now(),
|
|
34
|
-
seen: {}
|
|
35
|
-
};
|
|
36
|
-
await writeYamlAtomic(this.path, {
|
|
37
|
-
...current,
|
|
38
|
-
seen: {
|
|
39
|
-
...current.seen,
|
|
40
|
-
[id]: Math.max(version, current.seen[id] ?? 0)
|
|
41
|
-
}
|
|
42
|
-
}, Schema, this.context.logger);
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
//#endregion
|
|
47
|
-
export { PresentationStore as t };
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { n as agentHomePath } from "./paths-CDYV5UH9.js";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { createHash } from "node:crypto";
|
|
4
|
-
import { appendPluginRecord, pluginRecordOf } from "@deepseek-ai/dsh-session";
|
|
5
|
-
//#region src/dsh-adapter/session-binding.ts
|
|
6
|
-
const BindingSchema = z.strictObject({
|
|
7
|
-
schemaVersion: z.literal(1),
|
|
8
|
-
identity: z.string().regex(/^[0-9a-f]{64}$/)
|
|
9
|
-
});
|
|
10
|
-
const EligibilitySchema = z.strictObject({ schemaVersion: z.literal(1) });
|
|
11
|
-
const emptyIdentity = createHash("sha256").update("").digest("hex");
|
|
12
|
-
const SelectionSchema = z.strictObject({
|
|
13
|
-
schemaVersion: z.literal(1),
|
|
14
|
-
key: z.string(),
|
|
15
|
-
identity: z.string().regex(/^[0-9a-f]{64}$/),
|
|
16
|
-
prepared: z.boolean().optional()
|
|
17
|
-
});
|
|
18
|
-
const bindings = /* @__PURE__ */ new WeakMap();
|
|
19
|
-
const identityOf = (config) => createHash("sha256").update(config.agentId === "" ? "" : agentHomePath(config.home, config.agentId)).digest("hex");
|
|
20
|
-
const selections = /* @__PURE__ */ new WeakMap();
|
|
21
|
-
const runningConfigurations = /* @__PURE__ */ new WeakMap();
|
|
22
|
-
const activations = /* @__PURE__ */ new WeakMap();
|
|
23
|
-
let activationSequence = 0;
|
|
24
|
-
const configurationActivation = (header) => activations.get(header) ?? 0;
|
|
25
|
-
function runningConfiguration(header) {
|
|
26
|
-
return runningConfigurations.get(header);
|
|
27
|
-
}
|
|
28
|
-
function rememberConfiguration(header, config) {
|
|
29
|
-
runningConfigurations.set(header, config);
|
|
30
|
-
activations.set(header, ++activationSequence);
|
|
31
|
-
}
|
|
32
|
-
function forgetConfiguration(header) {
|
|
33
|
-
runningConfigurations.delete(header);
|
|
34
|
-
activations.delete(header);
|
|
35
|
-
}
|
|
36
|
-
function decodeSelection(value) {
|
|
37
|
-
const parsed = SelectionSchema.safeParse(value);
|
|
38
|
-
return parsed.success ? parsed.data : {
|
|
39
|
-
schemaVersion: 1,
|
|
40
|
-
key: "invalid",
|
|
41
|
-
identity: "0".repeat(64)
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function observeSelection(header, event) {
|
|
45
|
-
const record = pluginRecordOf(event);
|
|
46
|
-
if (record?.type === "plugin:acn/team-selection") selections.set(header, decodeSelection(record.data));
|
|
47
|
-
}
|
|
48
|
-
function restoreSessionBinding(header, events) {
|
|
49
|
-
const records = events.map(pluginRecordOf);
|
|
50
|
-
const values = records.filter((record) => record?.type === "plugin:acn/session-binding").map((record) => BindingSchema.safeParse(record?.data));
|
|
51
|
-
const first = values[0];
|
|
52
|
-
bindings.set(header, first?.success && values.every((value) => value.success && value.data.identity === first.data.identity) ? first.data.identity : null);
|
|
53
|
-
const selected = records.filter((record) => record?.type === "plugin:acn/team-selection").at(-1);
|
|
54
|
-
selections.set(header, selected === void 0 ? void 0 : decodeSelection(selected.data));
|
|
55
|
-
}
|
|
56
|
-
function sessionSelection(ctx, header) {
|
|
57
|
-
if (selections.has(header)) return selections.get(header);
|
|
58
|
-
const last = (ctx.sessions.get(header.id)?.snapshotEvents().map(pluginRecordOf).filter((record) => record?.type === "plugin:acn/team-selection") ?? []).at(-1);
|
|
59
|
-
const value = last === void 0 ? void 0 : decodeSelection(last.data);
|
|
60
|
-
selections.set(header, value);
|
|
61
|
-
return value;
|
|
62
|
-
}
|
|
63
|
-
function sessionHasWork(events) {
|
|
64
|
-
return events.some((event) => event.type === "request/header" || event.type === "assistant/message" || event.type === "tool/result" || event.type === "turn/start" || event.type === "user/message" && event.data.source.kind === "user");
|
|
65
|
-
}
|
|
66
|
-
function sessionEligible(ctx, header, events = ctx.sessions.get(header.id)?.snapshotEvents()) {
|
|
67
|
-
return events?.some((event) => {
|
|
68
|
-
const record = pluginRecordOf(event);
|
|
69
|
-
return record?.type === "plugin:acn/session-eligibility" && EligibilitySchema.safeParse(record.data).success || record?.type === "plugin:acn/session-binding" && BindingSchema.safeParse(record.data).data?.identity === emptyIdentity;
|
|
70
|
-
}) ?? false;
|
|
71
|
-
}
|
|
72
|
-
function markSessionEligible(ctx, header) {
|
|
73
|
-
const session = ctx.sessions.get(header.id);
|
|
74
|
-
if (session === void 0 || session.firstLiveSeq > 0 || header.isSeeded || header.parentSession !== void 0 || sessionHasWork(session.snapshotEvents()) || sessionEligible(ctx, header)) return;
|
|
75
|
-
appendPluginRecord(session, "plugin:acn/session-eligibility", { schemaVersion: 1 });
|
|
76
|
-
}
|
|
77
|
-
function sessionUnbound(ctx, header, events) {
|
|
78
|
-
const seen = /* @__PURE__ */ new Set();
|
|
79
|
-
let current = header;
|
|
80
|
-
while (current !== void 0) {
|
|
81
|
-
if (seen.has(current.id)) return false;
|
|
82
|
-
seen.add(current.id);
|
|
83
|
-
const history = current === header && events !== void 0 ? events : ctx.sessions.get(current.id)?.snapshotEvents();
|
|
84
|
-
if (history === void 0) return current !== header;
|
|
85
|
-
for (const event of history) {
|
|
86
|
-
const record = pluginRecordOf(event);
|
|
87
|
-
if (record?.type === "plugin:acn/team-selection") return false;
|
|
88
|
-
if (record?.type === "plugin:acn/session-binding" && BindingSchema.safeParse(record.data).data?.identity !== emptyIdentity) return false;
|
|
89
|
-
}
|
|
90
|
-
current = current.parentSession === void 0 ? void 0 : ctx.sessions.get(current.parentSession)?.header;
|
|
91
|
-
}
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
94
|
-
function bindSession(ctx, config, header) {
|
|
95
|
-
if (config.agentId === "") return;
|
|
96
|
-
if (bindings.has(header)) return;
|
|
97
|
-
const session = ctx.sessions.get(header.id);
|
|
98
|
-
if (session === void 0) {
|
|
99
|
-
bindings.set(header, null);
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
const records = session.snapshotEvents().map(pluginRecordOf).filter((record) => record?.type === "plugin:acn/session-binding");
|
|
103
|
-
if (records.length > 0) {
|
|
104
|
-
const values = records.map((record) => BindingSchema.safeParse(record?.data));
|
|
105
|
-
const first = values[0];
|
|
106
|
-
bindings.set(header, first?.success && values.every((value) => value.success && value.data.identity === first.data.identity) ? first.data.identity : null);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const parent = header.parentSession === void 0 ? void 0 : ctx.sessions.get(header.parentSession);
|
|
110
|
-
const parentSelection = parent === void 0 ? void 0 : sessionSelection(ctx, parent.header);
|
|
111
|
-
if (session.firstLiveSeq === 0 && sessionSelection(ctx, header) === void 0 && parentSelection !== void 0) appendPluginRecord(session, "plugin:acn/team-selection", parentSelection);
|
|
112
|
-
const verifiedParent = parent !== void 0 && sessionAllowed(ctx, config, parent.header);
|
|
113
|
-
if (session.firstLiveSeq > 0 || !verifiedParent && (!sessionEligible(ctx, header) || sessionHasWork(session.snapshotEvents()) || header.parentSession !== void 0 || header.isSeeded)) {
|
|
114
|
-
bindings.set(header, null);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
const identity = identityOf(config);
|
|
118
|
-
bindings.set(header, identity);
|
|
119
|
-
try {
|
|
120
|
-
appendPluginRecord(session, "plugin:acn/session-binding", {
|
|
121
|
-
schemaVersion: 1,
|
|
122
|
-
identity
|
|
123
|
-
});
|
|
124
|
-
} catch (error) {
|
|
125
|
-
bindings.set(header, null);
|
|
126
|
-
throw error;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
const sessionChanged = "ACN 会话身份与当前配置不一致,或缺少可验证的历史身份记录,请新建会话。旧会话不能访问当前身份的知识。";
|
|
130
|
-
const configurationBusy = "ACN 配置正在应用,请稍后重试。";
|
|
131
|
-
const unboundSession = "本会话未启用 ACN,聊天仍可继续。只有安装插件后新建且尚未发送消息的会话可选择工作配置;如需使用 ACN,请新建会话。";
|
|
132
|
-
function sessionAllowed(ctx, config, header) {
|
|
133
|
-
if (config.agentId === "") return true;
|
|
134
|
-
if (config.team.routerEndpoint && !config.legacyEnabled) return false;
|
|
135
|
-
const identity = identityOf(config);
|
|
136
|
-
const selected = sessionSelection(ctx, header);
|
|
137
|
-
if (selected !== void 0) return selected.identity === identity;
|
|
138
|
-
if (bindings.get(header) !== identity) return false;
|
|
139
|
-
if (config.sessionEpoch === 0) return true;
|
|
140
|
-
const seen = /* @__PURE__ */ new Set();
|
|
141
|
-
let current = header;
|
|
142
|
-
while (current !== void 0) {
|
|
143
|
-
if (current.createdAt <= config.sessionEpoch || seen.has(current.id)) return false;
|
|
144
|
-
seen.add(current.id);
|
|
145
|
-
if (current.parentSession === void 0) return true;
|
|
146
|
-
current = ctx.sessions.get(current.parentSession)?.header;
|
|
147
|
-
}
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
//#endregion
|
|
151
|
-
export { unboundSession as _, identityOf as a, rememberConfiguration as c, sessionAllowed as d, sessionChanged as f, sessionUnbound as g, sessionSelection as h, forgetConfiguration as i, restoreSessionBinding as l, sessionHasWork as m, configurationActivation as n, markSessionEligible as o, sessionEligible as p, configurationBusy as r, observeSelection as s, bindSession as t, runningConfiguration as u };
|