@ftai/dsh-plugin-acn 0.0.0-stage → 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 +90 -0
- package/LICENSE-APACHE +201 -0
- package/LICENSE-MIT +19 -0
- package/README.md +82 -2
- package/README_EN.md +83 -0
- package/cordis.patch.yml +29 -0
- package/docs/acn-compat.md +33 -0
- package/docs/architecture.md +130 -0
- package/docs/assets/acn-claim-reuse.png +0 -0
- package/docs/assets/activity-view.png +0 -0
- package/docs/assets/install-package.png +0 -0
- package/docs/assets/knowledge-model.png +0 -0
- package/docs/assets/knowledge-view.png +0 -0
- package/docs/assets/personal-configuration.png +0 -0
- package/docs/assets/session-upstream.png +0 -0
- package/docs/assets/upstream-settings.png +0 -0
- package/docs/assets/upstream-team.png +0 -0
- package/docs/command-reference.md +201 -0
- package/docs/config.md +253 -0
- package/docs/development.md +197 -0
- package/docs/dsh-compat.md +59 -0
- package/docs/index.md +16 -0
- package/docs/outstanding-issues.md +61 -0
- package/docs/user_guide.md +185 -0
- package/icon.svg +8 -0
- package/lib/activities-B8U-iW4-.js +407 -0
- package/lib/alignment-CwH0nBf-.js +80 -0
- package/lib/auth-DFI9yowX.js +71 -0
- package/lib/checkpoint-CPFPOxBM.js +188 -0
- package/lib/checkpoint-c7aI4D-X.js +318 -0
- package/lib/claim-DOAGe8ZK.js +168 -0
- package/lib/client.js +18417 -0
- package/lib/deliver-C-dmhkfm.js +168 -0
- package/lib/delivery-status-M7-Rwoyj.js +89 -0
- package/lib/dispute-CtrInHzf.js +20 -0
- package/lib/disputes-ByEmi43j.js +51 -0
- package/lib/dream-agent-BVqxbKFc.js +249 -0
- package/lib/dream.js +4 -0
- package/lib/effects-DX1iy6FM.js +268 -0
- package/lib/errors-Bp_2WXBr.js +19 -0
- package/lib/errors-pPumDOGD.js +18 -0
- package/lib/evidence-store-DW7kj20i.js +1030 -0
- package/lib/formation-D4LO31WW.js +187 -0
- package/lib/formation-replay-Bf4TSBiz.js +87 -0
- package/lib/formation.js +9 -0
- package/lib/history-DPMHX3ZE.js +214 -0
- package/lib/inbox-2CugZZQm.js +188 -0
- package/lib/inbox-DFtE2fOp.js +71 -0
- package/lib/inbox.js +3 -0
- package/lib/index.js +1373 -0
- package/lib/lock-DbmlKOoX.js +332 -0
- package/lib/pages-BEWC3kmZ.js +51 -0
- package/lib/paths-B7NI9Ano.js +157 -0
- package/lib/plugins/commands.js +590 -0
- package/lib/plugins/dream.js +66 -0
- package/lib/plugins/formation.js +66 -0
- package/lib/plugins/inbox.js +53 -0
- package/lib/plugins/knowledge.js +1109 -0
- package/lib/plugins/prompt.js +102 -0
- package/lib/plugins/tools.js +280 -0
- package/lib/policy-DnyHh7Bl.js +16 -0
- package/lib/prepare-CGXwBEcu.js +134 -0
- package/lib/protocol.js +8 -0
- package/lib/queue-M917xHPS.js +153 -0
- package/lib/regular-file-BFpqMoub.js +136 -0
- package/lib/render-CJaVcKKC.js +48 -0
- package/lib/reported-sets-DdEKdeVb.js +122 -0
- package/lib/revision-DeoL_IUN.js +11 -0
- package/lib/scheduler-BfJSY1eq.js +64 -0
- package/lib/service-BPwaZzFF.js +1106 -0
- package/lib/service-BQaszW_v.js +344 -0
- package/lib/service-BhniAHLo.js +305 -0
- package/lib/service-C2lXoygJ.js +505 -0
- package/lib/session-binding-zCSuizHs.js +342 -0
- package/lib/session-state-CYqUhC95.js +38 -0
- package/lib/sessions-C2xuPFQv.js +218 -0
- package/lib/store.js +16 -0
- package/lib/structured-C9byFuzm.js +453 -0
- package/lib/subagent-yJsFxHmH.js +9 -0
- package/lib/team.js +3 -0
- package/lib/tool-schema-3b4gH1zf.js +28 -0
- package/lib/trace-Da0RnL5R.js +14 -0
- package/lib/traces-CHBo8y1z.js +11 -0
- package/lib/types/activities.d.ts +73 -0
- package/lib/types/advanced-configuration.d.ts +11 -0
- package/lib/types/client/ActivityCard.d.ts +14 -0
- package/lib/types/client/ActivityDetails.d.ts +18 -0
- package/lib/types/client/AdvancedPreferences.d.ts +8 -0
- package/lib/types/client/BlankCommandFeedback.d.ts +10 -0
- package/lib/types/client/ComposerMenu.d.ts +24 -0
- package/lib/types/client/ConfigurationPage.d.ts +11 -0
- package/lib/types/client/ConnectionCheckDialog.d.ts +12 -0
- package/lib/types/client/KnowledgeDetail.d.ts +6 -0
- package/lib/types/client/KnowledgeDirectoryField.d.ts +11 -0
- package/lib/types/client/KnowledgePanel.d.ts +12 -0
- package/lib/types/client/KnowledgeReference.d.ts +13 -0
- package/lib/types/client/SessionToolbar.d.ts +16 -0
- package/lib/types/client/SettingsToast.d.ts +3 -0
- package/lib/types/client/SourceSessionLink.d.ts +16 -0
- package/lib/types/client/TeamCredentialField.d.ts +16 -0
- package/lib/types/client/TeamSettingsPage.d.ts +28 -0
- package/lib/types/client/configuration-errors.d.ts +2 -0
- package/lib/types/client/interaction-styles.d.ts +1 -0
- package/lib/types/client/interaction-ui.d.ts +30 -0
- package/lib/types/client/knowledge-labels.d.ts +5 -0
- package/lib/types/client/locales.d.ts +51 -0
- package/lib/types/commands/claim.d.ts +4 -0
- package/lib/types/commands/import.d.ts +10 -0
- package/lib/types/commands/status.d.ts +5 -0
- package/lib/types/config.d.ts +111 -0
- package/lib/types/configuration.d.ts +235 -0
- package/lib/types/credentials.d.ts +59 -0
- package/lib/types/dream/audit.d.ts +4 -0
- package/lib/types/dream/autonomous.d.ts +185 -0
- package/lib/types/dream/candidates.d.ts +34 -0
- package/lib/types/dream/checkpoint.d.ts +35 -0
- package/lib/types/dream/evidence-files.d.ts +10 -0
- package/lib/types/dream/evidence-store.d.ts +103 -0
- package/lib/types/dream/evidence.d.ts +30 -0
- package/lib/types/dream/index.d.ts +10 -0
- package/lib/types/dream/plan.d.ts +18 -0
- package/lib/types/dream/preservation.d.ts +6 -0
- package/lib/types/dream/review.d.ts +10 -0
- package/lib/types/dream/schema.d.ts +1475 -0
- package/lib/types/dream/service.d.ts +56 -0
- package/lib/types/dream/sync.d.ts +147 -0
- package/lib/types/dsh-adapter/configuration-remote.d.ts +1 -0
- package/lib/types/dsh-adapter/configuration-service.d.ts +28 -0
- package/lib/types/dsh-adapter/dream-agent.d.ts +4 -0
- package/lib/types/dsh-adapter/dream-evidence.d.ts +3 -0
- package/lib/types/dsh-adapter/formation-archive.d.ts +3 -0
- package/lib/types/dsh-adapter/formation-replay.d.ts +5 -0
- package/lib/types/dsh-adapter/formation.d.ts +4 -0
- package/lib/types/dsh-adapter/interaction-service.d.ts +13 -0
- package/lib/types/dsh-adapter/knowledge-paths.d.ts +3 -0
- package/lib/types/dsh-adapter/llm.d.ts +10 -0
- package/lib/types/dsh-adapter/project-upstream.d.ts +4 -0
- package/lib/types/dsh-adapter/runtime-pool.d.ts +110 -0
- package/lib/types/dsh-adapter/session-binding.d.ts +43 -0
- package/lib/types/dsh-adapter/source-sessions.d.ts +3 -0
- package/lib/types/dsh-adapter/team-credentials.d.ts +5 -0
- package/lib/types/dsh-adapter/tool-schema.d.ts +4 -0
- package/lib/types/dsh-adapter/tools.d.ts +5 -0
- package/lib/types/formation/capture.d.ts +19 -0
- package/lib/types/formation/checkpoint.d.ts +136 -0
- package/lib/types/formation/index.d.ts +10 -0
- package/lib/types/formation/prepare.d.ts +16 -0
- package/lib/types/formation/schema.d.ts +45 -0
- package/lib/types/formation/service.d.ts +58 -0
- package/lib/types/formation/transcript.d.ts +75 -0
- package/lib/types/formation/triggers.d.ts +3 -0
- package/lib/types/inbox/cascade.d.ts +3 -0
- package/lib/types/inbox/effects.d.ts +275 -0
- package/lib/types/inbox/index.d.ts +5 -0
- package/lib/types/inbox/prepare.d.ts +380 -0
- package/lib/types/inbox/service.d.ts +26 -0
- package/lib/types/inbox/sync.d.ts +9 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/interaction-messages.d.ts +69 -0
- package/lib/types/interaction.d.ts +541 -0
- package/lib/types/knowledge/alignment.d.ts +49 -0
- package/lib/types/knowledge/catalog.d.ts +5 -0
- package/lib/types/knowledge/changes.d.ts +32 -0
- package/lib/types/knowledge/disputes.d.ts +3 -0
- package/lib/types/knowledge/errors.d.ts +9 -0
- package/lib/types/knowledge/ordering.d.ts +7 -0
- package/lib/types/knowledge/pages.d.ts +7 -0
- package/lib/types/knowledge/safety.d.ts +2 -0
- package/lib/types/knowledge/service.d.ts +52 -0
- package/lib/types/knowledge/sessions.d.ts +59 -0
- package/lib/types/knowledge/sources.d.ts +2 -0
- package/lib/types/knowledge/timestamps.d.ts +1 -0
- package/lib/types/knowledge/types.d.ts +84 -0
- package/lib/types/llm/response.d.ts +1 -0
- package/lib/types/llm/structured.d.ts +27 -0
- package/lib/types/local-name.d.ts +1 -0
- package/lib/types/plugins/client.d.ts +9 -0
- package/lib/types/plugins/commands.d.ts +11 -0
- package/lib/types/plugins/configuration.d.ts +8 -0
- package/lib/types/plugins/dream.d.ts +16 -0
- package/lib/types/plugins/formation.d.ts +16 -0
- package/lib/types/plugins/inbox.d.ts +16 -0
- package/lib/types/plugins/knowledge.d.ts +19 -0
- package/lib/types/plugins/prompt.d.ts +17 -0
- package/lib/types/plugins/tools.d.ts +10 -0
- package/lib/types/prompt/render.d.ts +2 -0
- package/lib/types/protocol/arbitration.d.ts +154 -0
- package/lib/types/protocol/auth.d.ts +31 -0
- package/lib/types/protocol/claim.d.ts +36 -0
- package/lib/types/protocol/dispute.d.ts +17 -0
- package/lib/types/protocol/ids.d.ts +20 -0
- package/lib/types/protocol/inbox.d.ts +141 -0
- package/lib/types/protocol/index.d.ts +11 -0
- package/lib/types/protocol/policy.d.ts +21 -0
- package/lib/types/protocol/revision.d.ts +2 -0
- package/lib/types/protocol/router.d.ts +114 -0
- package/lib/types/protocol/schema.d.ts +4 -0
- package/lib/types/protocol/time.d.ts +5 -0
- package/lib/types/protocol/trace.d.ts +11 -0
- package/lib/types/store/atomic.d.ts +8 -0
- package/lib/types/store/claim-edits.d.ts +33 -0
- package/lib/types/store/claims.d.ts +7 -0
- package/lib/types/store/context.d.ts +13 -0
- package/lib/types/store/delivery-status.d.ts +48 -0
- package/lib/types/store/disputes.d.ts +6 -0
- package/lib/types/store/entities.d.ts +16 -0
- package/lib/types/store/errors.d.ts +8 -0
- package/lib/types/store/history.d.ts +65 -0
- package/lib/types/store/inbox.d.ts +27 -0
- package/lib/types/store/index.d.ts +16 -0
- package/lib/types/store/jobs.d.ts +5 -0
- package/lib/types/store/library-directory.d.ts +4 -0
- package/lib/types/store/lock.d.ts +11 -0
- package/lib/types/store/path-names.d.ts +2 -0
- package/lib/types/store/paths.d.ts +45 -0
- package/lib/types/store/presentation.d.ts +13 -0
- package/lib/types/store/regular-file.d.ts +2 -0
- package/lib/types/store/rejected-disputes.d.ts +18 -0
- package/lib/types/store/rename.d.ts +1 -0
- package/lib/types/store/reported-sets.d.ts +24 -0
- package/lib/types/store/session-state.d.ts +17 -0
- package/lib/types/store/traces.d.ts +6 -0
- package/lib/types/store/uploads.d.ts +312 -0
- package/lib/types/store/yaml.d.ts +8 -0
- package/lib/types/team/errors.d.ts +10 -0
- package/lib/types/team/http.d.ts +20 -0
- package/lib/types/team/index.d.ts +5 -0
- package/lib/types/team/maintainer-client.d.ts +18 -0
- package/lib/types/team/router-client.d.ts +14 -0
- package/lib/types/team/service.d.ts +28 -0
- package/lib/types/team/system-proxy.d.ts +9 -0
- package/lib/types/tools/claim.d.ts +63 -0
- package/lib/types/tools/consult-router.d.ts +11 -0
- package/lib/types/tools/subagent.d.ts +8 -0
- package/lib/types/tools/validation.d.ts +2 -0
- package/lib/types/upload/consolidation.d.ts +63 -0
- package/lib/types/upload/deliver.d.ts +15 -0
- package/lib/types/upload/index.d.ts +2 -0
- package/lib/types/upload/scheduler.d.ts +19 -0
- package/lib/types/upstreams.d.ts +5 -0
- package/lib/types/worker/queue.d.ts +17 -0
- package/lib/types/worker/types.d.ts +51 -0
- package/lib/types/worker/worker.d.ts +39 -0
- package/lib/types-C2ST2Zdg.js +17 -0
- package/lib/upload.js +3 -0
- package/lib/uploads-BCA2p92b.js +210 -0
- package/lib/upstreams-DEi-56tD.js +495 -0
- package/lib/worker-HMGzJFWd.js +185 -0
- package/locale/commands/en.json +1 -0
- package/locale/commands/zh.json +1 -0
- package/locale/dream/en.json +1 -0
- package/locale/dream/zh.json +1 -0
- package/locale/en.json +7 -0
- package/locale/formation/en.json +1 -0
- package/locale/formation/zh.json +1 -0
- package/locale/inbox/en.json +1 -0
- package/locale/inbox/zh.json +1 -0
- package/locale/knowledge/en.json +1 -0
- package/locale/knowledge/zh.json +1 -0
- package/locale/prompt/en.json +1 -0
- package/locale/prompt/zh.json +1 -0
- package/locale/tools/en.json +1 -0
- package/locale/tools/zh.json +1 -0
- package/locale/zh.json +7 -0
- package/package.json +262 -3
- package/prompts/claim_dream.j2 +77 -0
- package/prompts/claim_dream_legacy.j2 +63 -0
- package/prompts/dream_compaction.j2 +11 -0
- package/prompts/dream_evidence.j2 +5 -0
- package/prompts/inbox_claim_attribute_update_internalize.j2 +112 -0
- package/prompts/inbox_policy_update_internalize.j2 +87 -0
- package/prompts/knowledge.j2 +38 -0
- package/prompts/session_recap.j2 +113 -0
- package/prompts/what_is_claim.j2 +51 -0
- package/prompts/what_is_dispute.j2 +21 -0
- package/prompts/what_is_policy.j2 +22 -0
|
@@ -0,0 +1,495 @@
|
|
|
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
|
+
import { n as claimRevision } from "./revision-DeoL_IUN.js";
|
|
4
|
+
import { n as RevisionConflict, t as KnowledgeError } from "./errors-Bp_2WXBr.js";
|
|
5
|
+
import { n as validateClaimText } from "./regular-file-BFpqMoub.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
|
+
import { n as AnalysisReadBoundary, r as KnowledgeBusy } from "./alignment-CwH0nBf-.js";
|
|
8
|
+
import { i as ClaimStore } from "./reported-sets-DdEKdeVb.js";
|
|
9
|
+
import { t as TraceStore } from "./traces-CHBo8y1z.js";
|
|
10
|
+
import { r as UploadStore } from "./uploads-BCA2p92b.js";
|
|
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";
|
|
14
|
+
import { n as ClaimEditStore } from "./disputes-ByEmi43j.js";
|
|
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";
|
|
19
|
+
import { r as MAX_TRACE_TASK_PAGE_LIMIT, t as ClaimUpdateSchema } from "./types-C2ST2Zdg.js";
|
|
20
|
+
import { a as validatePage, n as claimListPage, r as page } from "./pages-BEWC3kmZ.js";
|
|
21
|
+
import { n as PresentationStore, t as historicalKnowledge } from "./history-DPMHX3ZE.js";
|
|
22
|
+
import { z } from "zod";
|
|
23
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
24
|
+
import fs, { readFile, realpath } from "node:fs/promises";
|
|
25
|
+
import { join, resolve } from "node:path";
|
|
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;
|
|
45
|
+
try {
|
|
46
|
+
const [first, second] = await Promise.all([realpath(a), realpath(b)]);
|
|
47
|
+
return process.platform === "win32" ? first.toLowerCase() === second.toLowerCase() : first === second;
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
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"]);
|
|
59
|
+
}
|
|
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"]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
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({
|
|
85
|
+
...value,
|
|
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
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const preferred = index.known.preferences?.defaultUpstream ?? "";
|
|
97
|
+
return {
|
|
98
|
+
...next,
|
|
99
|
+
upstreams,
|
|
100
|
+
upstream: upstreams[preferred]?.enabled ? preferred : "",
|
|
101
|
+
agentId: "",
|
|
102
|
+
connections: [],
|
|
103
|
+
defaultConnection: ""
|
|
104
|
+
};
|
|
105
|
+
}
|
|
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
|
+
});
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region src/knowledge/service.ts
|
|
154
|
+
function missing(error) {
|
|
155
|
+
return hasCode(error, "ENOENT") || error instanceof StoreError && error.kind === "io" && hasCode(error.cause, "ENOENT");
|
|
156
|
+
}
|
|
157
|
+
var AcnKnowledge = class {
|
|
158
|
+
config;
|
|
159
|
+
logger;
|
|
160
|
+
agentId;
|
|
161
|
+
mode;
|
|
162
|
+
storeContext;
|
|
163
|
+
team;
|
|
164
|
+
jobs;
|
|
165
|
+
cache;
|
|
166
|
+
listeners = /* @__PURE__ */ new Set();
|
|
167
|
+
constructor(config, logger, credential) {
|
|
168
|
+
this.config = config;
|
|
169
|
+
this.logger = logger;
|
|
170
|
+
this.agentId = config.agentId || null;
|
|
171
|
+
this.mode = config.team.routerEndpoint ? "team" : "solo";
|
|
172
|
+
this.storeContext = this.agentId === null ? null : {
|
|
173
|
+
agentId: this.agentId,
|
|
174
|
+
paths: new AgentPaths(agentHomePath(config.home, this.agentId, activeUpstream(config))),
|
|
175
|
+
mode: this.mode,
|
|
176
|
+
logger
|
|
177
|
+
};
|
|
178
|
+
this.team = this.agentId !== null && this.mode === "team" ? new TeamFacade(config.team, this.agentId, logger, credential) : null;
|
|
179
|
+
this.jobs = this.storeContext === null ? null : new DurableWorker(this.storeContext);
|
|
180
|
+
}
|
|
181
|
+
get active() {
|
|
182
|
+
return this.mode === "solo" || this.config.legacyEnabled;
|
|
183
|
+
}
|
|
184
|
+
get configured() {
|
|
185
|
+
return this.agentId !== null;
|
|
186
|
+
}
|
|
187
|
+
teamStatus() {
|
|
188
|
+
return this.team?.status() ?? {
|
|
189
|
+
mode: "solo",
|
|
190
|
+
router: { state: "unknown" },
|
|
191
|
+
maintainer: { state: "unknown" }
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
context() {
|
|
195
|
+
if (this.storeContext === null) throw new KnowledgeError("unconfigured", "Configure agentId on the acn-knowledge row first.");
|
|
196
|
+
return this.storeContext;
|
|
197
|
+
}
|
|
198
|
+
async initialize() {
|
|
199
|
+
if (!this.configured) return;
|
|
200
|
+
if ((await historicalKnowledge(this.context())).applications.some((record) => record.state === "prepared")) throw new KnowledgeError("conflict", "知识目录还有未完成的历史提交,请先在原程序完成处理;当前插件不会重放旧任务。");
|
|
201
|
+
await new PresentationStore(this.context()).initialize();
|
|
202
|
+
await cleanupAtomicTemps(this.context().paths.root, this.logger);
|
|
203
|
+
await new DreamStore(this.context()).recover();
|
|
204
|
+
await new ClaimEditStore(this.context()).recover();
|
|
205
|
+
await new FormationStore(this.context()).recover();
|
|
206
|
+
await new InboxEffectStore(this.context()).recover();
|
|
207
|
+
}
|
|
208
|
+
async snapshot(signal, lockTimeoutMs) {
|
|
209
|
+
return this.consistentRead(async () => {
|
|
210
|
+
const context = this.context();
|
|
211
|
+
let stamp;
|
|
212
|
+
try {
|
|
213
|
+
const stat = await fs.stat(context.paths.claims, { bigint: true });
|
|
214
|
+
stamp = `${stat.mtimeNs}:${stat.ctimeNs}`;
|
|
215
|
+
} catch (error) {
|
|
216
|
+
if (!hasCode(error, "ENOENT")) throw error;
|
|
217
|
+
stamp = "missing";
|
|
218
|
+
}
|
|
219
|
+
if (this.cache !== void 0 && this.cache.stamp === stamp && performance.now() - this.cache.checked < 2e3) return structuredClone({
|
|
220
|
+
claims: this.cache.claims,
|
|
221
|
+
version: this.cache.version
|
|
222
|
+
});
|
|
223
|
+
const claims = await new ClaimStore(context).list();
|
|
224
|
+
const revisions = [...claims].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0).map((claim) => `${claim.id}:${claimRevision(claim)}`).join("\n");
|
|
225
|
+
const version = { claimsDigest: createHash("sha256").update(revisions).digest("hex") };
|
|
226
|
+
this.cache = {
|
|
227
|
+
stamp,
|
|
228
|
+
checked: performance.now(),
|
|
229
|
+
claims,
|
|
230
|
+
version
|
|
231
|
+
};
|
|
232
|
+
return structuredClone({
|
|
233
|
+
claims,
|
|
234
|
+
version
|
|
235
|
+
});
|
|
236
|
+
}, signal, lockTimeoutMs);
|
|
237
|
+
}
|
|
238
|
+
async knowledgeVersion(signal, lockTimeoutMs) {
|
|
239
|
+
return (await this.snapshot(signal, lockTimeoutMs)).version;
|
|
240
|
+
}
|
|
241
|
+
async listClaims(query = {}, signal) {
|
|
242
|
+
return this.consistentRead(async () => {
|
|
243
|
+
return claimListPage(await new ClaimStore(this.context()).list(), query);
|
|
244
|
+
}, signal);
|
|
245
|
+
}
|
|
246
|
+
async readClaim(id, signal) {
|
|
247
|
+
return this.consistentRead(async () => {
|
|
248
|
+
const claim = await this.readOwnedClaim(id);
|
|
249
|
+
return {
|
|
250
|
+
claim,
|
|
251
|
+
revision: claimRevision(claim)
|
|
252
|
+
};
|
|
253
|
+
}, signal);
|
|
254
|
+
}
|
|
255
|
+
async readOwnedClaim(id) {
|
|
256
|
+
let claim;
|
|
257
|
+
try {
|
|
258
|
+
claim = await new ClaimStore(this.context()).read(id);
|
|
259
|
+
} catch (error) {
|
|
260
|
+
if (missing(error)) throw new KnowledgeError("not_found", `Claim ${id} was not found.`);
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
if (claim.holder !== this.agentId) throw new KnowledgeError("ownership", `Claim ${id} is not held by this agent.`);
|
|
264
|
+
return claim;
|
|
265
|
+
}
|
|
266
|
+
async updateClaim(input, signal) {
|
|
267
|
+
const parsed = ClaimUpdateSchema.safeParse(input);
|
|
268
|
+
if (!parsed.success) throw new KnowledgeError("validation", "Invalid Claim update fields.");
|
|
269
|
+
const { id, expected_revision, ...fields } = parsed.data;
|
|
270
|
+
if (!Object.values(fields).some((value) => value !== void 0)) throw new KnowledgeError("validation", "Claim update requires at least one editable field.");
|
|
271
|
+
const context = this.context();
|
|
272
|
+
const result = await withFileLock(context.paths.knowledgeLock, async () => {
|
|
273
|
+
signal?.throwIfAborted();
|
|
274
|
+
await new DreamStore(context).recoverLocked();
|
|
275
|
+
await new ClaimEditStore(context).recoverLocked();
|
|
276
|
+
await new FormationStore(context).recoverLocked();
|
|
277
|
+
await new InboxEffectStore(context).recoverLocked();
|
|
278
|
+
const current = await this.readOwnedClaim(id);
|
|
279
|
+
const revision = claimRevision(current);
|
|
280
|
+
if (expected_revision !== revision) throw new RevisionConflict(revision);
|
|
281
|
+
const next = { ...current };
|
|
282
|
+
for (const key of [
|
|
283
|
+
"name",
|
|
284
|
+
"statement",
|
|
285
|
+
"scope",
|
|
286
|
+
"evidence_summary",
|
|
287
|
+
"confidence",
|
|
288
|
+
"status"
|
|
289
|
+
]) {
|
|
290
|
+
const value = fields[key];
|
|
291
|
+
if (value !== void 0) Object.assign(next, { [key]: value });
|
|
292
|
+
}
|
|
293
|
+
validateClaimText({
|
|
294
|
+
name: next.name,
|
|
295
|
+
statement: next.statement,
|
|
296
|
+
scope: next.scope,
|
|
297
|
+
evidence_summary: next.evidence_summary
|
|
298
|
+
});
|
|
299
|
+
next.updated_at = nextClaimUpdateAt(nowSeconds(), effectiveUpdatedAt(current));
|
|
300
|
+
signal?.throwIfAborted();
|
|
301
|
+
if (context.mode === "team") await new ClaimEditStore(context).write({
|
|
302
|
+
expected_revision: revision,
|
|
303
|
+
target: next
|
|
304
|
+
});
|
|
305
|
+
await new ClaimStore(context).write(next);
|
|
306
|
+
if (context.mode === "team") {
|
|
307
|
+
await new UploadStore(context).enqueue([next], [], true);
|
|
308
|
+
await removeFile(context.paths.claimEditPending, this.logger);
|
|
309
|
+
}
|
|
310
|
+
this.cache = void 0;
|
|
311
|
+
return {
|
|
312
|
+
claim: next,
|
|
313
|
+
revision: claimRevision(next),
|
|
314
|
+
sync_pending: context.mode === "team",
|
|
315
|
+
...context.mode === "team" ? { sync_warning: "Claim 已保存到本地,等待团队同步。" } : {}
|
|
316
|
+
};
|
|
317
|
+
}, {
|
|
318
|
+
signal,
|
|
319
|
+
timeoutMs: context.lockTimeoutMs
|
|
320
|
+
});
|
|
321
|
+
await this.notifyChanged(signal);
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
async listTraces(query = {}, signal) {
|
|
325
|
+
return this.consistentRead(async () => {
|
|
326
|
+
const offset = query.offset ?? 0;
|
|
327
|
+
const limit = query.limit ?? 20;
|
|
328
|
+
validatePage(offset, limit);
|
|
329
|
+
const traces = (await new TraceStore(this.context()).list()).filter((trace) => trace.agent === this.agentId && (query.claimId === void 0 || trace.input_claims.includes(query.claimId) || trace.output_claims.includes(query.claimId)));
|
|
330
|
+
traces.sort((a, b) => {
|
|
331
|
+
const delta = timestampNanos(b.created_at) - timestampNanos(a.created_at);
|
|
332
|
+
return delta === 0n ? a.id < b.id ? -1 : a.id > b.id ? 1 : 0 : delta > 0n ? 1 : -1;
|
|
333
|
+
});
|
|
334
|
+
return page(traces.map(({ id, name, created_at, input_claims, output_claims }) => ({
|
|
335
|
+
id,
|
|
336
|
+
name,
|
|
337
|
+
created_at,
|
|
338
|
+
input_claims,
|
|
339
|
+
output_claims
|
|
340
|
+
})), offset, limit);
|
|
341
|
+
}, signal);
|
|
342
|
+
}
|
|
343
|
+
async readTrace(id, options = {}, signal) {
|
|
344
|
+
return this.consistentRead(async () => {
|
|
345
|
+
const offset = options.taskOffset ?? 0;
|
|
346
|
+
const limit = options.taskLimit ?? 4e3;
|
|
347
|
+
validatePage(offset, limit, MAX_TRACE_TASK_PAGE_LIMIT);
|
|
348
|
+
let trace;
|
|
349
|
+
try {
|
|
350
|
+
trace = await new TraceStore(this.context()).read(id);
|
|
351
|
+
} catch (error) {
|
|
352
|
+
if (missing(error)) throw new KnowledgeError("not_found", `Trace ${id} was not found.`);
|
|
353
|
+
throw error;
|
|
354
|
+
}
|
|
355
|
+
if (trace.agent !== this.agentId) throw new KnowledgeError("ownership", `Trace ${id} is not owned by this agent.`);
|
|
356
|
+
const chars = Array.from(trace.task);
|
|
357
|
+
const end = Math.min(offset + limit, chars.length);
|
|
358
|
+
return {
|
|
359
|
+
...trace,
|
|
360
|
+
task: chars.slice(offset, end).join(""),
|
|
361
|
+
task_offset: offset,
|
|
362
|
+
task_limit: limit,
|
|
363
|
+
task_omitted: chars.length - end,
|
|
364
|
+
next_task_offset: end < chars.length ? end : null
|
|
365
|
+
};
|
|
366
|
+
}, signal);
|
|
367
|
+
}
|
|
368
|
+
onClaimsChanged(listener) {
|
|
369
|
+
this.listeners.add(listener);
|
|
370
|
+
return () => {
|
|
371
|
+
this.listeners.delete(listener);
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
async applyFormation(...args) {
|
|
375
|
+
const result = await new FormationStore(this.context()).commit(...args);
|
|
376
|
+
if (result.applied) await this.notifyChanged(args[1].signal);
|
|
377
|
+
return result;
|
|
378
|
+
}
|
|
379
|
+
async applyInboxEffect(...args) {
|
|
380
|
+
const result = await new InboxEffectStore(this.context()).commit(...args);
|
|
381
|
+
if (result.applied > 0) await this.notifyChanged(args[3].signal);
|
|
382
|
+
return result;
|
|
383
|
+
}
|
|
384
|
+
async consistentRead(action, signal, lockTimeoutMs) {
|
|
385
|
+
const context = this.context();
|
|
386
|
+
try {
|
|
387
|
+
return await withFileLock(context.paths.knowledgeLock, async () => {
|
|
388
|
+
signal?.throwIfAborted();
|
|
389
|
+
await new DreamStore(context).recoverLocked();
|
|
390
|
+
await new ClaimEditStore(context).recoverLocked();
|
|
391
|
+
await new FormationStore(context).recoverLocked();
|
|
392
|
+
await new InboxEffectStore(context).recoverLocked();
|
|
393
|
+
const boundary = await AnalysisReadBoundary.begin(context.paths.root);
|
|
394
|
+
const result = await action();
|
|
395
|
+
await boundary.finish(context.paths.root);
|
|
396
|
+
signal?.throwIfAborted();
|
|
397
|
+
return result;
|
|
398
|
+
}, {
|
|
399
|
+
signal,
|
|
400
|
+
timeoutMs: lockTimeoutMs ?? context.lockTimeoutMs
|
|
401
|
+
});
|
|
402
|
+
} catch (error) {
|
|
403
|
+
signal?.throwIfAborted();
|
|
404
|
+
if (error instanceof LockTimeoutError) throw new KnowledgeBusy();
|
|
405
|
+
throw error;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
async notifyChanged(signal) {
|
|
409
|
+
this.cache = void 0;
|
|
410
|
+
try {
|
|
411
|
+
const version = await this.knowledgeVersion(signal);
|
|
412
|
+
for (const listener of this.listeners) try {
|
|
413
|
+
listener(version);
|
|
414
|
+
} catch {
|
|
415
|
+
this.logger.warn("Claim change observer failed.");
|
|
416
|
+
}
|
|
417
|
+
} catch {
|
|
418
|
+
this.logger.warn("Knowledge was committed; its change notice will be checked on the next foreground step.");
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
dreamStore() {
|
|
422
|
+
return new DreamStore(this.context(), async () => {
|
|
423
|
+
await new ClaimEditStore(this.context()).recoverLocked();
|
|
424
|
+
await new FormationStore(this.context()).recoverLocked();
|
|
425
|
+
await new InboxEffectStore(this.context()).recoverLocked();
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
async dreamSnapshot(signal) {
|
|
429
|
+
return withFileLock(this.context().paths.knowledgeLock, async () => {
|
|
430
|
+
await new DreamStore(this.context()).recoverLocked();
|
|
431
|
+
await new ClaimEditStore(this.context()).recoverLocked();
|
|
432
|
+
await new FormationStore(this.context()).recoverLocked();
|
|
433
|
+
await new InboxEffectStore(this.context()).recoverLocked();
|
|
434
|
+
signal.throwIfAborted();
|
|
435
|
+
return new ClaimStore(this.context()).list();
|
|
436
|
+
}, {
|
|
437
|
+
signal,
|
|
438
|
+
timeoutMs: this.context().lockTimeoutMs
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
async applyDreamGroup(...args) {
|
|
442
|
+
const result = await this.dreamStore().commitGroup(...args);
|
|
443
|
+
await this.notifyChanged(args[6].signal);
|
|
444
|
+
return result;
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
//#endregion
|
|
448
|
+
//#region src/dsh-adapter/team-credentials.ts
|
|
449
|
+
function credentialReference(reference) {
|
|
450
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(reference)) throw new ConfigError(["team.keyEnv"]);
|
|
451
|
+
return reference;
|
|
452
|
+
}
|
|
453
|
+
function teamCredentials(ctx) {
|
|
454
|
+
return async (reference) => {
|
|
455
|
+
const provider = ctx.get("credentials");
|
|
456
|
+
return provider === void 0 ? process.env[reference] : (await provider.resolve(credentialReference(reference)))?.value;
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
//#endregion
|
|
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 };
|
|
@@ -0,0 +1,185 @@
|
|
|
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-c7aI4D-X.js";
|
|
3
|
+
import { n as runnableJob, t as JobQueue } from "./queue-M917xHPS.js";
|
|
4
|
+
//#region src/worker/worker.ts
|
|
5
|
+
var DurableWorker = class {
|
|
6
|
+
context;
|
|
7
|
+
options;
|
|
8
|
+
queue;
|
|
9
|
+
handlers = /* @__PURE__ */ new Map();
|
|
10
|
+
lease;
|
|
11
|
+
active;
|
|
12
|
+
timer;
|
|
13
|
+
ticking;
|
|
14
|
+
closed = false;
|
|
15
|
+
started = false;
|
|
16
|
+
nextAcquire = 0;
|
|
17
|
+
constructor(context, options = {}) {
|
|
18
|
+
this.context = context;
|
|
19
|
+
this.options = options;
|
|
20
|
+
this.queue = new JobQueue(context);
|
|
21
|
+
}
|
|
22
|
+
register(kind, handler) {
|
|
23
|
+
this.handlers.set(kind, handler);
|
|
24
|
+
this.wake(true);
|
|
25
|
+
return () => {
|
|
26
|
+
if (this.handlers.get(kind) !== handler) return;
|
|
27
|
+
this.handlers.delete(kind);
|
|
28
|
+
if (this.active?.job.kind === kind && !this.active.prepared) this.active.abort.abort(new JobError("suspended", "后台处理器已暂停,任务保留。"));
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
supports(kind) {
|
|
32
|
+
return this.handlers.has(kind);
|
|
33
|
+
}
|
|
34
|
+
canRun(job) {
|
|
35
|
+
return runnableJob(job, this.handlers);
|
|
36
|
+
}
|
|
37
|
+
async start() {
|
|
38
|
+
if (this.started || this.closed) return;
|
|
39
|
+
this.started = true;
|
|
40
|
+
this.timer = setInterval(() => {
|
|
41
|
+
this.wake();
|
|
42
|
+
}, this.options.pollMs ?? 1e3);
|
|
43
|
+
this.timer.unref();
|
|
44
|
+
this.wake();
|
|
45
|
+
await Promise.resolve();
|
|
46
|
+
}
|
|
47
|
+
wake(force = false) {
|
|
48
|
+
if (!this.started || this.closed || this.ticking !== void 0) return;
|
|
49
|
+
if (force) this.nextAcquire = 0;
|
|
50
|
+
const tick = this.tick().catch(() => {
|
|
51
|
+
this.context.logger.warn("Background worker could not read or commit its local queue.");
|
|
52
|
+
});
|
|
53
|
+
this.ticking = tick;
|
|
54
|
+
tick.finally(() => {
|
|
55
|
+
if (this.ticking === tick) this.ticking = void 0;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async enqueue(kind, payload, sessionId) {
|
|
59
|
+
const job = await this.queue.enqueue(kind, payload, sessionId);
|
|
60
|
+
if (this.canRun(job) && this.active?.job.kind === "dream" && !this.active.prepared && jobPriority[kind] < jobPriority.dream) this.active.abort.abort(new DreamYield());
|
|
61
|
+
if (this.canRun(job) && kind === "finalize" && this.active?.job.kind === "recap" && this.active.job.sessionId === sessionId && !this.active.prepared) this.active.abort.abort(new Preempted());
|
|
62
|
+
this.wake(true);
|
|
63
|
+
return job;
|
|
64
|
+
}
|
|
65
|
+
async retry(id) {
|
|
66
|
+
const job = await this.queue.retry(id);
|
|
67
|
+
this.wake(true);
|
|
68
|
+
return job;
|
|
69
|
+
}
|
|
70
|
+
cancelDream(reason = new DreamStopped()) {
|
|
71
|
+
if (this.active?.job.kind === "dream") this.active.abort.abort(reason);
|
|
72
|
+
}
|
|
73
|
+
async tick() {
|
|
74
|
+
if (this.lease === void 0) {
|
|
75
|
+
if (Date.now() < this.nextAcquire) return;
|
|
76
|
+
try {
|
|
77
|
+
this.lease = await acquireFileLease(this.context.paths.workerLock, {
|
|
78
|
+
timeoutMs: 0,
|
|
79
|
+
staleMs: this.options.staleMs
|
|
80
|
+
});
|
|
81
|
+
await this.queue.recoverRunning();
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (this.lease !== void 0) {
|
|
84
|
+
await this.lease.release();
|
|
85
|
+
this.lease = void 0;
|
|
86
|
+
}
|
|
87
|
+
this.nextAcquire = Date.now() + (this.options.takeoverMs ?? 6e4);
|
|
88
|
+
if (!(error instanceof LockTimeoutError)) throw error;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
while (!this.closed) {
|
|
93
|
+
this.lease.check();
|
|
94
|
+
await new DreamStore(this.context).recover();
|
|
95
|
+
const job = await this.queue.claim(new Set(this.handlers.keys()));
|
|
96
|
+
if (job === null) return;
|
|
97
|
+
const handler = this.handlers.get(job.kind);
|
|
98
|
+
if (handler === void 0) {
|
|
99
|
+
await this.queue.settle(job, "queued");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const active = {
|
|
103
|
+
job,
|
|
104
|
+
abort: new AbortController(),
|
|
105
|
+
prepared: false
|
|
106
|
+
};
|
|
107
|
+
this.active = active;
|
|
108
|
+
let checking = false;
|
|
109
|
+
const monitor = setInterval(() => {
|
|
110
|
+
if (checking || active.prepared || job.kind !== "recap" && job.kind !== "dream") return;
|
|
111
|
+
checking = true;
|
|
112
|
+
this.queue.list().then((jobs) => {
|
|
113
|
+
if (job.kind === "recap" && jobs.some((candidate) => candidate.kind === "finalize" && candidate.sessionId === job.sessionId && this.canRun(candidate))) active.abort.abort(new Preempted());
|
|
114
|
+
if (job.kind === "dream" && jobs.some((candidate) => candidate.id === job.id && candidate.payload["paused"] === true)) active.abort.abort(new DreamStopped());
|
|
115
|
+
if (job.kind === "dream" && jobs.some((candidate) => this.canRun(candidate) && jobPriority[candidate.kind] < jobPriority.dream)) active.abort.abort(new DreamYield());
|
|
116
|
+
}).catch(() => {
|
|
117
|
+
active.abort.abort(new JobError("storage", "Cannot inspect preemption queue."));
|
|
118
|
+
}).finally(() => {
|
|
119
|
+
checking = false;
|
|
120
|
+
});
|
|
121
|
+
}, this.options.pollMs ?? 1e3);
|
|
122
|
+
monitor.unref();
|
|
123
|
+
try {
|
|
124
|
+
const result = await handler(job, {
|
|
125
|
+
signal: active.abort.signal,
|
|
126
|
+
prepared: () => {
|
|
127
|
+
active.prepared = true;
|
|
128
|
+
},
|
|
129
|
+
committed: () => {
|
|
130
|
+
active.prepared = false;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
this.lease.check();
|
|
134
|
+
await this.queue.settle(job, "succeeded", result === void 0 ? {} : { result });
|
|
135
|
+
} catch (error) {
|
|
136
|
+
const reason = active.abort.signal.aborted ? active.abort.signal.reason : error;
|
|
137
|
+
if (active.prepared) await this.queue.settle(job, job.attempts < 5 ? "queued" : "failed", {
|
|
138
|
+
lastErrorKind: "storage",
|
|
139
|
+
lastError: "本地提交待 checkpoint 恢复;请检查存储后重试任务。",
|
|
140
|
+
nextRunAt: Date.now() + 1e3
|
|
141
|
+
});
|
|
142
|
+
else if (reason instanceof DreamStopped || reason instanceof DreamYield) await this.queue.settle(job, "queued", { attempts: Math.max(0, job.attempts - 1) });
|
|
143
|
+
else if (this.closed || reason instanceof JobError && reason.kind === "suspended") await this.queue.settle(job, "queued");
|
|
144
|
+
else if (reason instanceof Preempted) await this.queue.settle(job, "succeeded", { result: { skipped: "superseded" } });
|
|
145
|
+
else {
|
|
146
|
+
const retryable = reason instanceof JobError && reason.retryable && job.attempts < 5;
|
|
147
|
+
await this.queue.settle(job, retryable ? "queued" : "failed", {
|
|
148
|
+
lastErrorKind: reason instanceof JobError ? reason.kind : "storage",
|
|
149
|
+
lastError: reason instanceof JobError ? reason.message + (reason.retryable && !retryable ? " 已达到自动重试上限,请修正原因后手动重试任务。" : "") : "后台任务失败;请检查本地存储和模型路由后重试。",
|
|
150
|
+
...retryable ? { nextRunAt: Date.now() + Math.max((this.options.retryBaseMs ?? 500) * 2 ** (job.attempts - 1), reason instanceof JobError ? reason.retryAfterMs ?? 0 : 0) } : {}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
} finally {
|
|
154
|
+
clearInterval(monitor);
|
|
155
|
+
this.active = void 0;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async close() {
|
|
160
|
+
this.closed = true;
|
|
161
|
+
if (this.timer !== void 0) clearInterval(this.timer);
|
|
162
|
+
this.active?.abort.abort(new JobError("disposed", "Worker disposed."));
|
|
163
|
+
const finish = async () => {
|
|
164
|
+
await this.ticking;
|
|
165
|
+
if (this.lease !== void 0) {
|
|
166
|
+
await this.lease.release();
|
|
167
|
+
this.lease = void 0;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
const completion = finish();
|
|
171
|
+
let timer;
|
|
172
|
+
await Promise.race([completion, new Promise((resolve) => {
|
|
173
|
+
timer = setTimeout(() => {
|
|
174
|
+
this.context.logger.warn("Worker is still reaching a safe point; lease retained until completion.");
|
|
175
|
+
resolve();
|
|
176
|
+
}, 1e4);
|
|
177
|
+
})]);
|
|
178
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
179
|
+
completion.catch(() => {
|
|
180
|
+
this.context.logger.warn("Worker lease cleanup failed.");
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
//#endregion
|
|
185
|
+
export { DurableWorker as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"meta":{"title":"ACN Commands","description":"Inspect and import knowledge, check and retry jobs, and control background work."}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"meta":{"title":"ACN 管理命令","description":"提供知识查询、导入、任务状态、重试和后台处理命令。"}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"meta":{"title":"ACN Dream","description":"Clean up and consolidate knowledge, with optional bounded evidence calibration."}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"meta":{"title":"ACN 知识整理","description":"清理与整合已有知识,可选启用受限证据校准。"}}
|