@leuduan/lagent 0.0.0-stage → 0.1.2
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/LICENSE +16 -0
- package/README.md +144 -2
- package/dist/chunks/2O7ZGEIT.js +1 -0
- package/dist/chunks/2OSESBIL.js +1 -0
- package/dist/chunks/34KW6VNQ.js +1 -0
- package/dist/chunks/37YOGDGY.js +1 -0
- package/dist/chunks/3LQHQRIU.js +6 -0
- package/dist/chunks/3QCW4WDJ.js +1 -0
- package/dist/chunks/4XVRUSCQ.js +1 -0
- package/dist/chunks/6ECI2GGV.js +1 -0
- package/dist/chunks/74HKUGRR.js +1 -0
- package/dist/chunks/ADHERZLW.js +2 -0
- package/dist/chunks/AP6Q4EPT.js +36 -0
- package/dist/chunks/BM3S37EZ.js +1 -0
- package/dist/chunks/C5LYCXJG.js +1 -0
- package/dist/chunks/CDQG7RKA.js +1 -0
- package/dist/chunks/D7E6EWIE.js +3 -0
- package/dist/chunks/DDANMY45.js +3 -0
- package/dist/chunks/DRYAN665.js +1 -0
- package/dist/chunks/DXFXAYDN.js +17 -0
- package/dist/chunks/EGZI4XQX.js +24 -0
- package/dist/chunks/ENWFSU27.js +41 -0
- package/dist/chunks/G6RXC3AL.js +1 -0
- package/dist/chunks/G74AGRAJ.js +15 -0
- package/dist/chunks/GQGNVSKB.js +1 -0
- package/dist/chunks/IJ2WNMD5.js +7 -0
- package/dist/chunks/J5S4URAW.js +1 -0
- package/dist/chunks/JPZFKSWT.js +1 -0
- package/dist/chunks/KESCTXGO.js +5 -0
- package/dist/chunks/L3N4FIEN.js +1 -0
- package/dist/chunks/NAOUTU7A.js +4 -0
- package/dist/chunks/NDIM7MEW.js +1 -0
- package/dist/chunks/O4PPOM5Z.js +2 -0
- package/dist/chunks/OVZFGILJ.js +1 -0
- package/dist/chunks/P5ZHHOOM.js +6 -0
- package/dist/chunks/PUSUPTAT.js +1 -0
- package/dist/chunks/QMMLQJBS.js +1 -0
- package/dist/chunks/RK3VP2Q4.js +3 -0
- package/dist/chunks/SGGMBSBA.js +1 -0
- package/dist/chunks/SL2YLB2F.js +1 -0
- package/dist/chunks/TOOIB6J2.js +1 -0
- package/dist/chunks/TYTQRLTX.js +1 -0
- package/dist/chunks/UC3FVVJ2.js +5 -0
- package/dist/chunks/UCTEU62F.js +1 -0
- package/dist/chunks/UD3VJER6.js +1 -0
- package/dist/chunks/UKXMCHHT.js +1 -0
- package/dist/chunks/WUUKTSRT.js +7 -0
- package/dist/chunks/X65X4KP5.js +7 -0
- package/dist/chunks/YIR5MYGU.js +1 -0
- package/dist/chunks/YLNJXQ3Z.js +1 -0
- package/dist/context.d.ts +101 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +77 -0
- package/dist/journal/catalog.d.ts +112 -0
- package/dist/journal/forkChain.d.ts +16 -0
- package/dist/journal/index.d.ts +15 -0
- package/dist/journal/journal.d.ts +475 -0
- package/dist/journal/projection.d.ts +87 -0
- package/dist/journal/store.d.ts +181 -0
- package/dist/kit/claim.d.ts +13 -0
- package/dist/kit/drain.d.ts +10 -0
- package/dist/kit/extension.d.ts +180 -0
- package/dist/kit/grants.d.ts +9 -0
- package/dist/kit/modes.d.ts +65 -0
- package/dist/kit/retries.d.ts +25 -0
- package/dist/kit/scope.d.ts +32 -0
- package/dist/kit/service.d.ts +7 -0
- package/dist/kit/strategy.d.ts +10 -0
- package/dist/kit/timers.d.ts +43 -0
- package/dist/kit/tool.d.ts +72 -0
- package/dist/llm/client.d.ts +135 -0
- package/dist/llm/content.d.ts +52 -0
- package/dist/llm/door.d.ts +21 -0
- package/dist/llm/door.js +1 -0
- package/dist/llm/failure.d.ts +82 -0
- package/dist/llm/index.d.ts +16 -0
- package/dist/llm/primitives.d.ts +286 -0
- package/dist/llm/prompt.d.ts +21 -0
- package/dist/llm/provider.d.ts +63 -0
- package/dist/llm/readLedger.d.ts +24 -0
- package/dist/llm/request.d.ts +58 -0
- package/dist/loop/agent.d.ts +134 -0
- package/dist/loop/auxiliary.d.ts +54 -0
- package/dist/loop/chain.d.ts +46 -0
- package/dist/loop/chunks.d.ts +27 -0
- package/dist/loop/continuation.d.ts +166 -0
- package/dist/loop/decide.d.ts +64 -0
- package/dist/loop/errors.d.ts +162 -0
- package/dist/loop/forks.d.ts +61 -0
- package/dist/loop/holds.d.ts +104 -0
- package/dist/loop/hooks.d.ts +241 -0
- package/dist/loop/inbox.d.ts +188 -0
- package/dist/loop/index.d.ts +37 -0
- package/dist/loop/limits.d.ts +14 -0
- package/dist/loop/opening.d.ts +42 -0
- package/dist/loop/prepare.d.ts +30 -0
- package/dist/loop/projections.d.ts +307 -0
- package/dist/loop/replace.d.ts +33 -0
- package/dist/loop/requests.d.ts +129 -0
- package/dist/loop/route.d.ts +53 -0
- package/dist/loop/runtime.d.ts +85 -0
- package/dist/loop/state.d.ts +70 -0
- package/dist/loop/strategy.d.ts +71 -0
- package/dist/loop/summary.d.ts +3 -0
- package/dist/loop/surface.d.ts +153 -0
- package/dist/loop/threadState.d.ts +72 -0
- package/dist/loop/tool.d.ts +101 -0
- package/dist/loop/toolCalls.d.ts +42 -0
- package/dist/loop/wake.d.ts +32 -0
- package/dist/models/config/agent.d.ts +18 -0
- package/dist/models/config/prompt.d.ts +18 -0
- package/dist/models/door.d.ts +12 -0
- package/dist/models/door.js +1 -0
- package/dist/models/index.d.ts +7 -0
- package/dist/models/jsonSchema.d.ts +7 -0
- package/dist/models/wire/journal.d.ts +2772 -0
- package/dist/models/wire/primitives.d.ts +65 -0
- package/dist/plugin.d.ts +53 -0
- package/dist/plugin.js +1 -0
- package/dist/plugins/agentsMd.d.ts +76 -0
- package/dist/plugins/agentsMd.js +1 -0
- package/dist/plugins/ask/askQuestion.d.ts +9 -0
- package/dist/plugins/ask/index.d.ts +26 -0
- package/dist/plugins/ask/index.js +1 -0
- package/dist/plugins/ask/service.d.ts +125 -0
- package/dist/plugins/commands/background.d.ts +8 -0
- package/dist/plugins/commands/foreground.d.ts +4 -0
- package/dist/plugins/commands/index.d.ts +40 -0
- package/dist/plugins/commands/index.js +1 -0
- package/dist/plugins/commands/output.d.ts +115 -0
- package/dist/plugins/commands/record.d.ts +549 -0
- package/dist/plugins/commands/service.d.ts +314 -0
- package/dist/plugins/commands/shell.d.ts +25 -0
- package/dist/plugins/compaction/checkpoint.d.ts +91 -0
- package/dist/plugins/compaction/config.d.ts +133 -0
- package/dist/plugins/compaction/estimate.d.ts +29 -0
- package/dist/plugins/compaction/index.d.ts +2 -0
- package/dist/plugins/compaction/index.js +7 -0
- package/dist/plugins/compaction/log.d.ts +61 -0
- package/dist/plugins/compaction/planner.d.ts +207 -0
- package/dist/plugins/compaction/preset.d.ts +86 -0
- package/dist/plugins/compaction/prune.d.ts +9 -0
- package/dist/plugins/compaction/records.d.ts +227 -0
- package/dist/plugins/compaction/segments.d.ts +23 -0
- package/dist/plugins/compaction/shared.d.ts +14 -0
- package/dist/plugins/compaction/summarize.d.ts +13 -0
- package/dist/plugins/dateAndBranch.d.ts +47 -0
- package/dist/plugins/dateAndBranch.js +1 -0
- package/dist/plugins/delegations/answers.d.ts +39 -0
- package/dist/plugins/delegations/assignmentKey.d.ts +22 -0
- package/dist/plugins/delegations/cleanup.d.ts +161 -0
- package/dist/plugins/delegations/constraint.d.ts +76 -0
- package/dist/plugins/delegations/index.d.ts +39 -0
- package/dist/plugins/delegations/index.js +1 -0
- package/dist/plugins/delegations/notices.d.ts +261 -0
- package/dist/plugins/delegations/obligations.d.ts +210 -0
- package/dist/plugins/delegations/record.d.ts +632 -0
- package/dist/plugins/delegations/request.d.ts +381 -0
- package/dist/plugins/delegations/role.d.ts +30 -0
- package/dist/plugins/delegations/service.d.ts +562 -0
- package/dist/plugins/delegations/standing.d.ts +19 -0
- package/dist/plugins/delegations/stopCheck.d.ts +21 -0
- package/dist/plugins/delegations/testing.d.ts +16 -0
- package/dist/plugins/delegations/tools.d.ts +71 -0
- package/dist/plugins/delegations/waitBook.d.ts +116 -0
- package/dist/plugins/delegations/waits.d.ts +118 -0
- package/dist/plugins/diagnostics/digest.d.ts +14 -0
- package/dist/plugins/diagnostics/index.d.ts +68 -0
- package/dist/plugins/diagnostics/index.js +1 -0
- package/dist/plugins/historyRecall/history.d.ts +9 -0
- package/dist/plugins/historyRecall/index.d.ts +31 -0
- package/dist/plugins/historyRecall/index.js +1 -0
- package/dist/plugins/historyRecall/render.d.ts +34 -0
- package/dist/plugins/historyRecall/tools.d.ts +4 -0
- package/dist/plugins/mcp/catalog.d.ts +36 -0
- package/dist/plugins/mcp/config.d.ts +63 -0
- package/dist/plugins/mcp/connection.d.ts +53 -0
- package/dist/plugins/mcp/errors.d.ts +32 -0
- package/dist/plugins/mcp/index.d.ts +33 -0
- package/dist/plugins/mcp/index.js +5 -0
- package/dist/plugins/mcp/mount.d.ts +98 -0
- package/dist/plugins/mcp/names.d.ts +25 -0
- package/dist/plugins/mcp/render.d.ts +29 -0
- package/dist/plugins/mcp/slots.d.ts +15 -0
- package/dist/plugins/mcp/stdio.d.ts +49 -0
- package/dist/plugins/mcp/tool.d.ts +41 -0
- package/dist/plugins/providers/anthropic.d.ts +175 -0
- package/dist/plugins/providers/anthropicMessages.d.ts +65 -0
- package/dist/plugins/providers/codex.d.ts +60 -0
- package/dist/plugins/providers/codexAuth.d.ts +116 -0
- package/dist/plugins/providers/deepseek.d.ts +55 -0
- package/dist/plugins/providers/door.d.ts +61 -0
- package/dist/plugins/providers/door.js +1 -0
- package/dist/plugins/providers/failure.d.ts +23 -0
- package/dist/plugins/providers/gateway.d.ts +23 -0
- package/dist/plugins/providers/index.d.ts +6 -0
- package/dist/plugins/providers/openaiChat.d.ts +62 -0
- package/dist/plugins/providers/openaiResponses.d.ts +100 -0
- package/dist/plugins/providers/opencodeCopilot.d.ts +23 -0
- package/dist/plugins/providers/opencodeGo.d.ts +98 -0
- package/dist/plugins/providers/shared.d.ts +104 -0
- package/dist/plugins/providers/stream.d.ts +154 -0
- package/dist/plugins/routeContext.d.ts +22 -0
- package/dist/plugins/routeContext.js +1 -0
- package/dist/plugins/schedules/index.d.ts +21 -0
- package/dist/plugins/schedules/index.js +5 -0
- package/dist/plugins/schedules/record.d.ts +396 -0
- package/dist/plugins/schedules/service.d.ts +120 -0
- package/dist/plugins/schedules/time.d.ts +26 -0
- package/dist/plugins/schedules/tools.d.ts +6 -0
- package/dist/plugins/skills/discovery.d.ts +54 -0
- package/dist/plugins/skills/index.d.ts +31 -0
- package/dist/plugins/skills/index.js +1 -0
- package/dist/plugins/skills/tool.d.ts +11 -0
- package/dist/plugins/store/durableObject.d.ts +23 -0
- package/dist/plugins/store/durableObject.js +1 -0
- package/dist/plugins/store/durableObjectConnection.d.ts +27 -0
- package/dist/plugins/store/memory.d.ts +29 -0
- package/dist/plugins/store/sql.d.ts +59 -0
- package/dist/plugins/store/sqlite.d.ts +31 -0
- package/dist/plugins/store/sqlite.js +1 -0
- package/dist/plugins/subAgents/availableRoutes.d.ts +53 -0
- package/dist/plugins/subAgents/fork.d.ts +32 -0
- package/dist/plugins/subAgents/index.d.ts +67 -0
- package/dist/plugins/subAgents/index.js +1 -0
- package/dist/plugins/subAgents/tool.d.ts +38 -0
- package/dist/plugins/toolPolicy/index.d.ts +61 -0
- package/dist/plugins/toolPolicy/index.js +1 -0
- package/dist/plugins/tools/editFiles.d.ts +128 -0
- package/dist/plugins/tools/fsRead.d.ts +17 -0
- package/dist/plugins/tools/html.d.ts +23 -0
- package/dist/plugins/tools/index.d.ts +59 -0
- package/dist/plugins/tools/index.js +1 -0
- package/dist/plugins/tools/network.d.ts +23 -0
- package/dist/plugins/tools/ripgrep.d.ts +20 -0
- package/dist/plugins/tools/textEdit.d.ts +67 -0
- package/dist/plugins/tools/web.d.ts +32 -0
- package/dist/plugins/truncateToolOutput.d.ts +26 -0
- package/dist/plugins/truncateToolOutput.js +1 -0
- package/dist/plugins/usage/index.d.ts +24 -0
- package/dist/plugins/usage/index.js +1 -0
- package/dist/plugins/usage/tracker.d.ts +34 -0
- package/dist/plugins/verify/facts.d.ts +356 -0
- package/dist/plugins/verify/index.d.ts +75 -0
- package/dist/plugins/verify/index.js +1 -0
- package/dist/plugins/verify/service.d.ts +90 -0
- package/dist/plugins/workflows/assignment.d.ts +16 -0
- package/dist/plugins/workflows/bindings.d.ts +95 -0
- package/dist/plugins/workflows/cleanup.d.ts +38 -0
- package/dist/plugins/workflows/definition.d.ts +184 -0
- package/dist/plugins/workflows/fold.d.ts +373 -0
- package/dist/plugins/workflows/index.d.ts +28 -0
- package/dist/plugins/workflows/index.js +6 -0
- package/dist/plugins/workflows/observations.d.ts +81 -0
- package/dist/plugins/workflows/participants.d.ts +143 -0
- package/dist/plugins/workflows/policy.d.ts +112 -0
- package/dist/plugins/workflows/providers.d.ts +146 -0
- package/dist/plugins/workflows/record.d.ts +2863 -0
- package/dist/plugins/workflows/routing.d.ts +116 -0
- package/dist/plugins/workflows/schema.d.ts +26 -0
- package/dist/plugins/workflows/service.d.ts +477 -0
- package/dist/plugins/workflows/submit.d.ts +8 -0
- package/dist/plugins/workflows/view.d.ts +103 -0
- package/dist/plugins/workflows/work.d.ts +21 -0
- package/dist/plugins/workspaceContext.d.ts +38 -0
- package/dist/plugins/workspaceContext.js +1 -0
- package/dist/presets/agents.d.ts +7 -0
- package/dist/presets/base.d.ts +10 -0
- package/dist/presets/codex.d.ts +60 -0
- package/dist/presets/index.d.ts +4 -0
- package/dist/presets/prompts.d.ts +56 -0
- package/dist/sandbox/absent.d.ts +32 -0
- package/dist/sandbox/client.d.ts +39 -0
- package/dist/sandbox/files.d.ts +28 -0
- package/dist/sandbox/index.d.ts +49 -0
- package/dist/sandbox/index.js +4 -0
- package/dist/sandbox/mode.d.ts +57 -0
- package/dist/sandbox/policy.d.ts +86 -0
- package/dist/sandbox/protocol.d.ts +107 -0
- package/dist/sandbox/service.d.ts +143 -0
- package/dist/sandbox/worker.d.ts +12 -0
- package/dist/sandbox/worker.js +1 -0
- package/dist/services/admission.d.ts +174 -0
- package/dist/services/agents.d.ts +37 -0
- package/dist/services/birth.d.ts +220 -0
- package/dist/services/contributions.d.ts +73 -0
- package/dist/services/core.d.ts +34 -0
- package/dist/services/journal.d.ts +26 -0
- package/dist/services/launches.d.ts +104 -0
- package/dist/services/llm.d.ts +80 -0
- package/dist/services/owner.d.ts +367 -0
- package/dist/services/preset.d.ts +154 -0
- package/dist/services/presets.d.ts +139 -0
- package/dist/services/prompts.d.ts +67 -0
- package/dist/services/runEvents.d.ts +79 -0
- package/dist/services/thread.d.ts +267 -0
- package/dist/services/threadActivation.d.ts +100 -0
- package/dist/services/threadDirs.d.ts +38 -0
- package/dist/services/threadView.d.ts +92 -0
- package/dist/services/threads.d.ts +449 -0
- package/dist/services/tools.d.ts +41 -0
- package/dist/sys/environment.d.ts +47 -0
- package/dist/sys/git.d.ts +60 -0
- package/dist/sys/paths.d.ts +56 -0
- package/dist/sys/spawn.d.ts +176 -0
- package/dist/testing/clock.d.ts +17 -0
- package/dist/testing/fakeLlm.d.ts +74 -0
- package/dist/testing/fedLlm.d.ts +32 -0
- package/dist/testing/helpers.d.ts +344 -0
- package/dist/testing/index.d.ts +13 -0
- package/dist/testing/index.js +1 -0
- package/dist/testing/processes.d.ts +13 -0
- package/dist/testing/sandbox.d.ts +71 -0
- package/dist/testing/settlement.d.ts +6 -0
- package/dist/testing/tmpDirs.d.ts +17 -0
- package/dist/util/async.d.ts +8 -0
- package/dist/util/diff.d.ts +25 -0
- package/dist/util/dispatch.d.ts +8 -0
- package/dist/util/errors.d.ts +28 -0
- package/dist/util/foldState.d.ts +17 -0
- package/dist/util/freeze.d.ts +2 -0
- package/dist/util/ids.d.ts +2 -0
- package/dist/util/json.d.ts +37 -0
- package/dist/util/log.d.ts +6 -0
- package/dist/util/text.d.ts +21 -0
- package/dist/util/version.d.ts +2 -0
- package/package.json +175 -3
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import type { JsonValue, Seq, ThreadSummary } from '../models/index.js';
|
|
2
|
+
import type { ReadonlyJsonValue } from '../util/json.js';
|
|
3
|
+
import { type Continuation, type ConstraintAnswer, type DecisionTurn, type Hold, type HoldBasis, type TurnLimits, type WaitDeclaration } from '../loop/index.js';
|
|
4
|
+
import type { Journal, OriginBreak } from '../journal/index.js';
|
|
5
|
+
import type { Admission, AdmittedOperation, OperationKind } from './admission.js';
|
|
6
|
+
import { type RunEvent, type RunState } from './runEvents.js';
|
|
7
|
+
/**
|
|
8
|
+
* Which run requests pending at boot `start` runs, judged by the age of each request's newest
|
|
9
|
+
* cause: every one, none, or those newer than `newerThanMs`. The rest are held (`startup`) until a
|
|
10
|
+
* releasing cause.
|
|
11
|
+
*/
|
|
12
|
+
export type StartupPolicy = 'all' | 'none' | {
|
|
13
|
+
readonly newerThanMs: number;
|
|
14
|
+
};
|
|
15
|
+
export type StartOptions = {
|
|
16
|
+
readonly resume: StartupPolicy;
|
|
17
|
+
/** How many runs execute at once; the rest wait in memory, in order, for one to end. */
|
|
18
|
+
readonly startLimit: number;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* A feature's registration as an owner: its say over when the threads it applies to run, and its
|
|
22
|
+
* part in startup. `owner` is the
|
|
23
|
+
* name a thread's `requires` lists; such a thread, and every thread created under it by origin, is
|
|
24
|
+
* held `missing` while no registration under it is ready. What a thread records in `requires` stays
|
|
25
|
+
* its own: a constraint's `applies` reads it, and only readiness passes down. `repair` runs at
|
|
26
|
+
* `start`, awaited before the startup policy classifies what is pending, so the causes it writes are
|
|
27
|
+
* judged with the rest; registered once started, it runs at once, and its causes are admitted like
|
|
28
|
+
* any later one. The owner's threads stay `missing` until it resolves, held with its error if it
|
|
29
|
+
* rejects; a rejection is reported and never fails `start`.
|
|
30
|
+
* `constraint`'s `applies` and `evaluate` are synchronous; a throw is a hold on that thread with the
|
|
31
|
+
* error as its reason. A registration with no `constraint` constrains no thread: one carrying only a
|
|
32
|
+
* `repair` is a startup participant, such as a feature firing the work that fell due while the
|
|
33
|
+
* process was down, or the owner of waits, whose repair resolves what was satisfied while the
|
|
34
|
+
* process was down.
|
|
35
|
+
*
|
|
36
|
+
* The registration is also what a call's wait names (`waitFor`'s `owner`): a call may declare one
|
|
37
|
+
* only while a registration under that owner is live, and only its handle resolves it.
|
|
38
|
+
*/
|
|
39
|
+
export type OwnerRegistration = {
|
|
40
|
+
readonly owner: string;
|
|
41
|
+
/** Which threads the registration governs, and what it says of each; none when omitted. */
|
|
42
|
+
readonly constraint?: {
|
|
43
|
+
applies(summary: ThreadSummary): boolean;
|
|
44
|
+
/** What it says about a thread it applies to. */
|
|
45
|
+
evaluate(threadId: string): ConstraintAnswer;
|
|
46
|
+
};
|
|
47
|
+
repair?(): Promise<void>;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* What `build` resolves a wait with: its `value`, a JSON object the owner versions and the waiting
|
|
51
|
+
* tool reads; the `chain` of the turn it asks for, `person` for a person's answer and `reactive`
|
|
52
|
+
* otherwise; and the rows the resolution cites as `evidence` beside the declaration.
|
|
53
|
+
*/
|
|
54
|
+
export type WaitValue = {
|
|
55
|
+
readonly value: {
|
|
56
|
+
readonly [key: string]: JsonValue;
|
|
57
|
+
};
|
|
58
|
+
readonly chain?: 'person';
|
|
59
|
+
readonly evidence?: readonly Seq[];
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* What `resolveWait` did: `resolved`; `declined` when `build` returned `null`; `resolved-before`
|
|
63
|
+
* with the value recorded first, which an answer-once check reports; `closed` when the call was
|
|
64
|
+
* answered without a value (cancelled, denied, aborted); `unknown` when no wait is declared for the
|
|
65
|
+
* call (yet), or one is, under another owner.
|
|
66
|
+
*/
|
|
67
|
+
export type WaitResolution = {
|
|
68
|
+
readonly status: 'resolved';
|
|
69
|
+
} | {
|
|
70
|
+
readonly status: 'declined';
|
|
71
|
+
} | {
|
|
72
|
+
readonly status: 'resolved-before';
|
|
73
|
+
readonly value: {
|
|
74
|
+
readonly [key: string]: ReadonlyJsonValue;
|
|
75
|
+
};
|
|
76
|
+
} | {
|
|
77
|
+
readonly status: 'closed';
|
|
78
|
+
} | {
|
|
79
|
+
readonly status: 'unknown';
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* An owner registration's handle: `changed` asks for the thread to be evaluated again; `dispose` withdraws
|
|
83
|
+
* it. `resolveWait` resolves a wait a call of `threadId` declared under this registration's owner,
|
|
84
|
+
* in one write on that thread: `build`, run inside it with the declaration, gives the value, and the
|
|
85
|
+
* write records it with an inputless cause that releases nothing, so the call is dispatched again
|
|
86
|
+
* once nothing else holds the thread. Racing resolutions serialize: the first wins. A disposed
|
|
87
|
+
* handle refuses it.
|
|
88
|
+
*/
|
|
89
|
+
export type OwnerHandle = {
|
|
90
|
+
changed(threadId: string): void;
|
|
91
|
+
resolveWait(wait: {
|
|
92
|
+
readonly threadId: string;
|
|
93
|
+
readonly callSeq: Seq;
|
|
94
|
+
}, build: (declaration: WaitDeclaration) => WaitValue | null): Promise<WaitResolution>;
|
|
95
|
+
dispose(): void;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* A constraint owner a thread's run needs that is not ready: `absent` when no registration serves
|
|
99
|
+
* it, `repairing` until its repair finishes, `failed` with why when that repair failed.
|
|
100
|
+
* `introducedBy` is the threads that require it: the thread itself, or callers above it.
|
|
101
|
+
*/
|
|
102
|
+
export type OwnerReadiness = {
|
|
103
|
+
readonly owner: string;
|
|
104
|
+
readonly state: 'absent' | 'repairing' | {
|
|
105
|
+
readonly failed: string;
|
|
106
|
+
};
|
|
107
|
+
readonly introducedBy: readonly string[];
|
|
108
|
+
};
|
|
109
|
+
/** What stands behind a `missing` hold: the owners not ready, and whether the callers above it could be read. */
|
|
110
|
+
export type MissingDetail = {
|
|
111
|
+
readonly owners: readonly OwnerReadiness[];
|
|
112
|
+
readonly chain: 'complete' | OriginBreak;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Where a thread stands, from `threads.inspect`: `idle` with no run pending; `requested` while its
|
|
116
|
+
* pending run waits to be admitted, a failed attempt to prepare it included, which backs off before
|
|
117
|
+
* the next; `running` while an execution serves it; `held` with `hold`. `operation` names an
|
|
118
|
+
* exclusive operation other than a run holding the thread now. `missing` says what is behind a
|
|
119
|
+
* `missing` hold and is `null` for any other. `approvalBlocked` is a screening read from the
|
|
120
|
+
* catalog whatever the state: the thread's last turn ended blocked and a confirmation waits on it
|
|
121
|
+
* or on a thread created under it. The run's actual hold (`approval`) is decided from the thread's
|
|
122
|
+
* folds, which can pass an answer the screening still counts. `basis` is the look it was computed on.
|
|
123
|
+
*/
|
|
124
|
+
export type ThreadInspection = {
|
|
125
|
+
readonly state: 'idle' | 'requested' | 'running' | 'held';
|
|
126
|
+
readonly operation: Exclude<OperationKind, 'run'> | null;
|
|
127
|
+
readonly hold: Hold | null;
|
|
128
|
+
readonly missing: MissingDetail | null;
|
|
129
|
+
readonly approvalBlocked: boolean;
|
|
130
|
+
readonly basis: HoldBasis;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* One execution of a run request, the owner's record of it from admission to the publication of
|
|
134
|
+
* where the run stands: what its finalization settles the run by, and the decision it asks as it
|
|
135
|
+
* goes. `execute` records on it as it decides; the finalization and the publication read it.
|
|
136
|
+
*/
|
|
137
|
+
export type RunExecution = {
|
|
138
|
+
readonly runId: string;
|
|
139
|
+
/**
|
|
140
|
+
* The journal's head as the execution was admitted; a recovered ending's execution's, when the run
|
|
141
|
+
* settles from that ending.
|
|
142
|
+
*/
|
|
143
|
+
attemptCutoff: Seq;
|
|
144
|
+
/** The last continuation decision: what the finalization settles by, unless a cancel captured it. */
|
|
145
|
+
final: Continuation | null;
|
|
146
|
+
/** Why the run failed in setup, for its settlement. */
|
|
147
|
+
errorText: string | null;
|
|
148
|
+
/**
|
|
149
|
+
* The continuation decision for the run, for the cancel that captured the operation serving it:
|
|
150
|
+
* asked at the execution's entry, after every turn and when an abort ends it.
|
|
151
|
+
*/
|
|
152
|
+
readonly decide: (turn: DecisionTurn) => Continuation;
|
|
153
|
+
};
|
|
154
|
+
/** What the owner needs of the threads service. */
|
|
155
|
+
export type OwnerHost = {
|
|
156
|
+
readonly journal: Journal;
|
|
157
|
+
readonly admission: Admission;
|
|
158
|
+
/** Aborts once lagent is closing. */
|
|
159
|
+
readonly signal: AbortSignal;
|
|
160
|
+
/**
|
|
161
|
+
* The execution of `run` under its admitted `operation`: the entry decision, the turns it opens
|
|
162
|
+
* and the decision after the last, recorded on `run`. A failure before it opens a turn is its
|
|
163
|
+
* setup's, which settles the run failed and resolves; only a failure past its setup rejects.
|
|
164
|
+
*/
|
|
165
|
+
execute(run: RunExecution, operation: AdmittedOperation): Promise<void>;
|
|
166
|
+
/**
|
|
167
|
+
* The operation's cleanup, still under its admission: releases the activation a failed or stale
|
|
168
|
+
* setup left, which could not be released while the operation held the thread.
|
|
169
|
+
*/
|
|
170
|
+
cleanup(operation: AdmittedOperation): Promise<void> | undefined;
|
|
171
|
+
/** Loads what an execution of the thread reads and keeps it held, under the application's retention policy. */
|
|
172
|
+
retain(threadId: string): Promise<{
|
|
173
|
+
release(): void;
|
|
174
|
+
}>;
|
|
175
|
+
report(error: unknown): void;
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* The one owner of when threads run: it admits a thread's pending run request once nothing holds
|
|
179
|
+
* it, runs the request's envelope (the execution through the threads service, its finalization
|
|
180
|
+
* under the same admission) and publishes each run's state. It makes every continuation decision,
|
|
181
|
+
* from the folds and the registered constraints. Nothing is admitted before `start`. A committed
|
|
182
|
+
* write, an operation settling or a constraint's `changed` re-evaluates the threads it touches,
|
|
183
|
+
* coalesced on a microtask, reading the catalog first and loading a thread only when it may be
|
|
184
|
+
* eligible; the decision is made again, authoritatively and with nothing awaited before admission,
|
|
185
|
+
* once the thread is loaded. A thread that failed to load backs off before the next try.
|
|
186
|
+
*/
|
|
187
|
+
export declare class RunOwner {
|
|
188
|
+
private started;
|
|
189
|
+
private starting;
|
|
190
|
+
private limit;
|
|
191
|
+
/** Runs executing that count against the limit. */
|
|
192
|
+
private counted;
|
|
193
|
+
/** Threads the startup policy declined, until a releasing cause lands on them. */
|
|
194
|
+
private readonly startupDeclined;
|
|
195
|
+
private readonly owners;
|
|
196
|
+
/** The serial the next registration gets. */
|
|
197
|
+
private nextSerial;
|
|
198
|
+
private readonly dirty;
|
|
199
|
+
private scheduled;
|
|
200
|
+
/** Threads being loaded for admission. */
|
|
201
|
+
private readonly admitting;
|
|
202
|
+
/** Every admission from its entry to the end of its cleanup, which shutdown waits for. */
|
|
203
|
+
private readonly preparations;
|
|
204
|
+
/** The execution serving each executing thread's run. */
|
|
205
|
+
private readonly executing;
|
|
206
|
+
/** Threads waiting for a slot under the limit, in order. */
|
|
207
|
+
private readonly waiting;
|
|
208
|
+
/** The hold last decided for each thread's pending run, which its state reads and its events say. */
|
|
209
|
+
private readonly holds;
|
|
210
|
+
private readonly listeners;
|
|
211
|
+
/** The threads whose pending run failed to be prepared for admission, and their backoff. */
|
|
212
|
+
private readonly preparation;
|
|
213
|
+
private readonly host;
|
|
214
|
+
private readonly limits;
|
|
215
|
+
constructor(host: OwnerHost, limits: TurnLimits);
|
|
216
|
+
/** Starts admitting; see `Threads.start`. */
|
|
217
|
+
start(options: StartOptions): Promise<void>;
|
|
218
|
+
registerOwner(registration: OwnerRegistration): OwnerHandle;
|
|
219
|
+
private repair;
|
|
220
|
+
/**
|
|
221
|
+
* Decides again every thread requiring `owner`, itself or through a thread above it by origin, or
|
|
222
|
+
* with a call waiting on it, resolved or not, whose registration or repair changed: a resolved call
|
|
223
|
+
* waiting to be dispatched again is not stranded. A change worth a new look does not wait out a
|
|
224
|
+
* preparation's backoff.
|
|
225
|
+
*/
|
|
226
|
+
private scheduleRequiring;
|
|
227
|
+
/** Whether a registration under `owner` is live now. */
|
|
228
|
+
isRegistered(owner: string): boolean;
|
|
229
|
+
/** `OwnerHandle.resolveWait` for a live registration under `owner`. */
|
|
230
|
+
private resolveWait;
|
|
231
|
+
/**
|
|
232
|
+
* Re-evaluates the thread a row landed on, and the threads above it, whose holds can read it. A
|
|
233
|
+
* releasing cause re-authorizes the subtree the startup policy declined under the thread: each
|
|
234
|
+
* thread in it is decided again, which never overrides a person's stop of a child, a cancellation
|
|
235
|
+
* hold or a stopped task, neither of which is the startup decline. A releasing cause on the
|
|
236
|
+
* thread, and the release of a descendant's decline, forget a preparation's backoff: a person
|
|
237
|
+
* asked, or what held the thread is gone. Any other row waits it out.
|
|
238
|
+
*/
|
|
239
|
+
onRow(threadId: string, row: {
|
|
240
|
+
readonly type: string;
|
|
241
|
+
readonly data: unknown;
|
|
242
|
+
}): void;
|
|
243
|
+
/**
|
|
244
|
+
* An operation on the thread settled, published as it released the thread: a run an execution
|
|
245
|
+
* served is held or settled to its waiters from this moment; and the thread is looked at again.
|
|
246
|
+
*/
|
|
247
|
+
onSettled(threadId: string, kind: OperationKind): void;
|
|
248
|
+
/** Resolves once every admission begun has finished, its cleanup included; none begins once closing. */
|
|
249
|
+
whenIdle(): Promise<void>;
|
|
250
|
+
/** Tells every waiter on a pending run that lagent is closing. */
|
|
251
|
+
close(): void;
|
|
252
|
+
onRunEvent(listener: (event: RunEvent) => void): () => void;
|
|
253
|
+
runState(threadId: string, runId: string): RunState | null;
|
|
254
|
+
/**
|
|
255
|
+
* Where the thread stands, `null` for a thread the catalog does not hold. Admits nothing, changes
|
|
256
|
+
* no backoff and publishes nothing. On the `loaded` basis the thread and the callers above it must
|
|
257
|
+
* be loaded, and the hold is decided from their folds; otherwise it throws.
|
|
258
|
+
*/
|
|
259
|
+
inspect(threadId: string, basis: HoldBasis): ThreadInspection | null;
|
|
260
|
+
/** The `loaded` basis needs what a run reads: the thread and every caller above it, in memory. */
|
|
261
|
+
private requireLoaded;
|
|
262
|
+
/**
|
|
263
|
+
* The hold admission would record for the thread's pending run now: the entry continuation
|
|
264
|
+
* decision, from the folds, that `admit` asks. A decision that advances, repairs or settles the
|
|
265
|
+
* run is no hold; none either while the run is being admitted.
|
|
266
|
+
*/
|
|
267
|
+
private loadedHold;
|
|
268
|
+
/**
|
|
269
|
+
* Whether the thread's last turn ended blocked and a confirmation waits on it or under it: the
|
|
270
|
+
* one rule of the approval screening, from the catalog, which `inspect` reports and the owner's
|
|
271
|
+
* look at a pending run applies. It scans the thread's subtree only for a blocked ending.
|
|
272
|
+
*/
|
|
273
|
+
private approvalBlocked;
|
|
274
|
+
/**
|
|
275
|
+
* Where the idle pending run `runId` stands, the one rule `runState` and `inspect` read: the hold
|
|
276
|
+
* decided for it; none while it is being loaded to be admitted, or is about to be decided whatever
|
|
277
|
+
* the catalog holds (obsolete, or captured by a cancel a crash left unsettled); otherwise the hold
|
|
278
|
+
* the catalog shows, then the constraint's, as `consider` would record them; or none, requested.
|
|
279
|
+
*/
|
|
280
|
+
private idleHold;
|
|
281
|
+
/** Whether the startup policy declined the thread's pending run, and nothing released it since. */
|
|
282
|
+
private declined;
|
|
283
|
+
/**
|
|
284
|
+
* The constraint owners the thread's run needs that are not registered and repaired, with why: what
|
|
285
|
+
* its own `requires` names and what every thread above it by origin requires, read from the
|
|
286
|
+
* catalog. Only readiness is inherited, never a caller's holds or what its constraints say. A
|
|
287
|
+
* caller chain that stops short of its root, at a caller the catalog does not hold or a cycle,
|
|
288
|
+
* cannot say what is required, and holds the thread.
|
|
289
|
+
*/
|
|
290
|
+
private missing;
|
|
291
|
+
/** The owners `missing` counts, not ready, with the threads that require each, and the chain read. */
|
|
292
|
+
private missingDetail;
|
|
293
|
+
/**
|
|
294
|
+
* The registrations the thread's run needs, as one token: every owner its own `requires` names
|
|
295
|
+
* or a thread above it by origin requires, each with the registration serving it. Equal tokens
|
|
296
|
+
* mean the same registrations, all ready; `null` while one is missing. What a judged turn ending
|
|
297
|
+
* is fenced on (`LoopServices.requiredRegistrations`): a registration that left or was replaced
|
|
298
|
+
* during the judgment may be a checker that did not judge the answer.
|
|
299
|
+
*/
|
|
300
|
+
requiredRegistrations(threadId: string): string | null;
|
|
301
|
+
/**
|
|
302
|
+
* What the registered constraints that apply to the thread say, combined, a hold stamped with the
|
|
303
|
+
* owner that gave it; `allow` with none.
|
|
304
|
+
*/
|
|
305
|
+
private verdict;
|
|
306
|
+
/**
|
|
307
|
+
* The continuation decision for the thread's pending run, from its folds and catalog as they
|
|
308
|
+
* stand: how the last turn ended (`ending`, opened at `start`), the holds derived on it, what the
|
|
309
|
+
* registered constraints say, and the cancel that captured the execution (`cancel`), or that a
|
|
310
|
+
* crash left recorded against the run. The one place a run's next step is decided: before
|
|
311
|
+
* admitting it, at an execution's entry, after each turn and as it lets go.
|
|
312
|
+
*/
|
|
313
|
+
private decide;
|
|
314
|
+
/** The decision for the thread's pending run as no execution serves it, from where its last turn stands. */
|
|
315
|
+
private entryDecision;
|
|
316
|
+
/** The holds on the thread's pending request, derived from its folds as `deriveHolds` orders them. */
|
|
317
|
+
private derivedHolds;
|
|
318
|
+
private schedule;
|
|
319
|
+
/** From the catalog: leaves the thread, holds it, queues it for a slot, or loads it to admit it. */
|
|
320
|
+
private consider;
|
|
321
|
+
/**
|
|
322
|
+
* The first hold the catalog alone shows, by the order the folds' decision reads them
|
|
323
|
+
* (`deriveHolds`), or `null` when the thread may be eligible.
|
|
324
|
+
*/
|
|
325
|
+
private catalogHold;
|
|
326
|
+
/**
|
|
327
|
+
* Loads what the thread's run reads, decides again from the folds, and admits the pending run
|
|
328
|
+
* with nothing awaited between that decision and the admission; then serves it, finalizes it
|
|
329
|
+
* under its admission and, once the execution has let the thread go, publishes where the run
|
|
330
|
+
* stands and looks at the thread again. The reads stay held until all of that is done.
|
|
331
|
+
*/
|
|
332
|
+
private admit;
|
|
333
|
+
/**
|
|
334
|
+
* An execution's finalization, under its admission: settles the run as its last decision said,
|
|
335
|
+
* in one write with the successor request its residual causes open. The settlement is built
|
|
336
|
+
* inside the write, which is the irrevocable boundary: a cancel that captured the execution before
|
|
337
|
+
* then settles it by the cancel's intent, whatever was decided, a hold included; after, what was
|
|
338
|
+
* built stands, and a cancel that captures it later has admission finalize it again, which settles
|
|
339
|
+
* a run the build left pending. A run settled meanwhile, or left pending (a hold, a shutdown),
|
|
340
|
+
* writes nothing.
|
|
341
|
+
*/
|
|
342
|
+
private finalize;
|
|
343
|
+
/**
|
|
344
|
+
* Records a failed preparation of the thread's pending run and looks at the thread again once its
|
|
345
|
+
* backoff is due, from half a second to a minute, so a store that fails to read is neither given
|
|
346
|
+
* up on nor hammered. Until then `consider` admits nothing: no row retries it, but the causes
|
|
347
|
+
* listed at `forgetPreparation`'s callers.
|
|
348
|
+
*/
|
|
349
|
+
private retryLater;
|
|
350
|
+
/** Forgets the thread's preparation failures and its pending retry: the next look may admit it at once. */
|
|
351
|
+
private forgetPreparation;
|
|
352
|
+
/** Publishes where a run stands once its execution let the thread go. */
|
|
353
|
+
private afterExecution;
|
|
354
|
+
/**
|
|
355
|
+
* Records a hold, and publishes it unless it is the one already published (`always` publishes it
|
|
356
|
+
* again). Published as read from the folds (`loaded`) when it stands as decided or `basis` says
|
|
357
|
+
* so, from the catalog otherwise.
|
|
358
|
+
*/
|
|
359
|
+
private hold;
|
|
360
|
+
/** Forgets a decided hold of `reason` on the thread, so the next look decides again. */
|
|
361
|
+
private forgetDecided;
|
|
362
|
+
/** Starts what waits for a slot, in order, while slots are free. */
|
|
363
|
+
private drain;
|
|
364
|
+
private durable;
|
|
365
|
+
private publishState;
|
|
366
|
+
private publish;
|
|
367
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { type Context, type Fiber, type Inject, type Plugin } from '@leuduan/cordis';
|
|
2
|
+
import type { z } from 'zod';
|
|
3
|
+
import type { InstallationLifetime } from '../models/index.js';
|
|
4
|
+
import { type JsonValue } from '../util/json.js';
|
|
5
|
+
import { type AgentSelector } from '../kit/scope.js';
|
|
6
|
+
import type { Thread } from './thread.js';
|
|
7
|
+
/** What a preset's setup is told when it is mounted as one thread's recorded installation. */
|
|
8
|
+
export type PresetInstallation = {
|
|
9
|
+
readonly kind: 'installation';
|
|
10
|
+
readonly thread: Thread;
|
|
11
|
+
readonly installationId: string;
|
|
12
|
+
/**
|
|
13
|
+
* `defining` when the thread's spawn row recorded it so (`create`'s `installations`, or a
|
|
14
|
+
* hand-down), on this thread or on the one a fork inherited it from, and it can never be removed;
|
|
15
|
+
* `configurable` otherwise. Read from the record.
|
|
16
|
+
*/
|
|
17
|
+
readonly lifetime: InstallationLifetime;
|
|
18
|
+
/**
|
|
19
|
+
* Aborts when this run of `setup` is unloaded, before its cleanups: when the thread's activation
|
|
20
|
+
* is released, which every application or removal on the thread does, when the application shuts
|
|
21
|
+
* down, and when an injected service goes away once `setup` has returned, after which `setup` runs
|
|
22
|
+
* again with a new signal. A `setup` still pending when a service goes away is not interrupted:
|
|
23
|
+
* it is unloaded, and run again, once it returns. A setup that rejects with the reason it was
|
|
24
|
+
* aborted with, or with an error whose `cause` is that reason, as Node's abortable APIs do, is not
|
|
25
|
+
* a failure, since the installation is going away; any other error is reported.
|
|
26
|
+
*/
|
|
27
|
+
readonly signal: AbortSignal;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* What a preset's setup is told when a root mount for an agent selector runs it on a thread whose
|
|
31
|
+
* agent it selects: the thread, never recorded. A selected setup hands nothing down: a hand-down
|
|
32
|
+
* belongs to a thread's recorded installation, so a setup that hands down checks its place first.
|
|
33
|
+
*/
|
|
34
|
+
export type PresetSelection = {
|
|
35
|
+
readonly kind: 'selected';
|
|
36
|
+
readonly thread: Thread;
|
|
37
|
+
/**
|
|
38
|
+
* Aborts when this run of `setup` is unloaded, before its cleanups: when the activation goes,
|
|
39
|
+
* when the root mount is disposed, and when an injected service goes away. A setup that rejects
|
|
40
|
+
* with the reason it was aborted with is not a failure, as for an installation.
|
|
41
|
+
*/
|
|
42
|
+
readonly signal: AbortSignal;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Where a setup runs: a thread's installation, or a thread a root mount for an agent selector chose.
|
|
46
|
+
* Every setup runs in its thread's scope, where the agent it equips is `[place.thread.agentName]`.
|
|
47
|
+
* A preset mounted from a setup is told the same place, with a signal that also aborts when that
|
|
48
|
+
* setup is unloaded.
|
|
49
|
+
*
|
|
50
|
+
* A setup still pending is not interrupted by its own unload: cordis defers a `dispose`, `update`
|
|
51
|
+
* or `restart` until the setup returns, and only then aborts its signal and runs its cleanups. So a
|
|
52
|
+
* setup that waits for its signal ends only on an abort from outside: the activation going, or an
|
|
53
|
+
* enclosing setup that has returned being unloaded.
|
|
54
|
+
*/
|
|
55
|
+
export type PresetPlace = PresetInstallation | PresetSelection;
|
|
56
|
+
/**
|
|
57
|
+
* Where a preset may be placed. `thread`: applied to one thread at any time, or mounted on the root
|
|
58
|
+
* for an agent selector, once per installation or selected activation, so only for members safe to mount many times
|
|
59
|
+
* (agents with scoped names, tools, grants, prompt contributions and listeners; no services,
|
|
60
|
+
* installers or nested scopes). `creation`: recorded only with a thread's spawn row as a defining
|
|
61
|
+
* installation, never mounted or applied later, and never removable.
|
|
62
|
+
*/
|
|
63
|
+
export type PresetPlacement = 'thread' | 'creation';
|
|
64
|
+
/**
|
|
65
|
+
* A preset: a named, configurable set of plugins, as plain data and a `setup`. `mountPreset`
|
|
66
|
+
* mounts it directly, and the presets service mounts it as a thread's recorded installation;
|
|
67
|
+
* declare it with `definePreset`, which checks it.
|
|
68
|
+
*/
|
|
69
|
+
export type Preset<Schema extends z.ZodType = z.ZodType> = {
|
|
70
|
+
/**
|
|
71
|
+
* What a thread's installation records and is restored by. Give the preset a new id (convention:
|
|
72
|
+
* a `#N` suffix, `codex#2`) when the configuration it records changes shape or meaning, so an
|
|
73
|
+
* old installation is refused as an unknown preset; behaviour and prompt changes keep the id.
|
|
74
|
+
*/
|
|
75
|
+
readonly id: string;
|
|
76
|
+
/**
|
|
77
|
+
* JSON in and JSON out: validate strictly (`z.strictObject`), apply defaults, and leave runtime
|
|
78
|
+
* transformations to `setup`. The parsed result is what a thread records, and restoring parses it
|
|
79
|
+
* again, so it must parse back to itself. An omitted configuration parses as `{}`, so give fields
|
|
80
|
+
* defaults rather than the schema a top-level `.default()`.
|
|
81
|
+
*/
|
|
82
|
+
readonly schema: Schema;
|
|
83
|
+
readonly placement: PresetPlacement;
|
|
84
|
+
/**
|
|
85
|
+
* For a creation preset that defines the agent its thread runs on: the agent name its
|
|
86
|
+
* configuration defines. A creation checks it against the thread's agent before anything is
|
|
87
|
+
* recorded. Refused on any other placement, where nothing would check it.
|
|
88
|
+
*/
|
|
89
|
+
readonly definesAgent?: (config: z.output<Schema>) => string;
|
|
90
|
+
/** The services `setup` uses directly, as for any plugin; members declare their own. */
|
|
91
|
+
readonly inject?: Inject;
|
|
92
|
+
/**
|
|
93
|
+
* Mounts the preset's members through `ctx`, in the scope of the thread `place` names: one
|
|
94
|
+
* thread's recorded installation, or a thread a root mount for an agent selector chose. A preset
|
|
95
|
+
* mounted from another's setup is told that one's place.
|
|
96
|
+
*/
|
|
97
|
+
setup(ctx: Context, config: z.output<Schema>, place: PresetPlace): void | Promise<void>;
|
|
98
|
+
};
|
|
99
|
+
/** A preset whatever its schema, where presets of every schema are kept or passed through. */
|
|
100
|
+
export type AnyPreset = Preset<any>;
|
|
101
|
+
/** Checks `preset`, which is otherwise used as it is given. */
|
|
102
|
+
export declare function definePreset<Schema extends z.ZodType>(preset: Preset<Schema>): Preset<Schema>;
|
|
103
|
+
/** Where a mount places a preset. */
|
|
104
|
+
export type PresetMountOptions = {
|
|
105
|
+
/**
|
|
106
|
+
* Runs the setup in the scope of each activation whose agent this selects, from then on;
|
|
107
|
+
* disposing the mount disposes it on live threads too. Required on the untagged application
|
|
108
|
+
* context, and refused anywhere else.
|
|
109
|
+
*/
|
|
110
|
+
readonly agents?: AgentSelector;
|
|
111
|
+
};
|
|
112
|
+
/** Optional exactly when the schema accepts an empty object, which is what an omitted one parses as. */
|
|
113
|
+
type MountArguments<Schema extends z.ZodType> = {} extends z.input<Schema> ? [config?: z.input<Schema>, options?: PresetMountOptions] : [config: z.input<Schema>, options?: PresetMountOptions];
|
|
114
|
+
/**
|
|
115
|
+
* Mounts `preset` with `config`, validated by its schema. With `agents`, on the root for those
|
|
116
|
+
* agents: the setup runs in each selected activation's scope, told the thread (`PresetSelection`),
|
|
117
|
+
* the one way to put a per-thread capability on every thread of some agents. Without, from another
|
|
118
|
+
* preset's setup, beside its members: told that setup's place, it serves the same thread for as long
|
|
119
|
+
* as that setup runs. Refused anywhere else, since a setup always serves one thread. Nothing is
|
|
120
|
+
* recorded either way; a thread keeps a preset across reopening and forks only through
|
|
121
|
+
* `thread.configure`. A creation preset cannot be mounted. Resolves like `ctx.plugin`, and fails the
|
|
122
|
+
* same way when the configuration is refused or the setup throws.
|
|
123
|
+
*/
|
|
124
|
+
export declare function mountPreset<Schema extends z.ZodType>(ctx: Context, preset: Preset<Schema>, ...[config, options]: MountArguments<Schema>): Fiber & PromiseLike<Fiber>;
|
|
125
|
+
declare const kInstalled: unique symbol;
|
|
126
|
+
/**
|
|
127
|
+
* How the presets service mounts a thread's installation through {@link presetPlugin}: the recorded
|
|
128
|
+
* configuration with the installation, under a key no caller's configuration carries, so a direct
|
|
129
|
+
* mount's configuration stays the caller's own, `fiber.update()` included.
|
|
130
|
+
*/
|
|
131
|
+
export declare const installedMount: (config: JsonValue, installation: Omit<PresetInstallation, "kind">) => {
|
|
132
|
+
[kInstalled]: {
|
|
133
|
+
config: z.core.util.JSONType;
|
|
134
|
+
installation: Omit<PresetInstallation, "kind">;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* The one plugin that mounts `preset`, as a thread's installation, for a selected thread, or from
|
|
139
|
+
* another preset's setup: one per preset, named after it, injecting what its setup declares.
|
|
140
|
+
*/
|
|
141
|
+
export declare function presetPlugin(preset: AnyPreset): Plugin.Object<unknown>;
|
|
142
|
+
/**
|
|
143
|
+
* Validates `input` with the preset's schema, defaults applied, and returns the result as frozen
|
|
144
|
+
* JSON: the value both a direct mount and a thread installation hand to `setup`, and the one a
|
|
145
|
+
* thread records. Throws when the schema rejects the input or its result is not JSON.
|
|
146
|
+
*/
|
|
147
|
+
export declare function parsePresetConfig(preset: AnyPreset, input: unknown): JsonValue;
|
|
148
|
+
/**
|
|
149
|
+
* Throws `message` unless `config`, a configuration the schema produced, parses back to itself: all
|
|
150
|
+
* that restoring a recorded installation relies on. Checked before recording, so a schema that
|
|
151
|
+
* transforms its output fails when applied rather than every time the thread reopens.
|
|
152
|
+
*/
|
|
153
|
+
export declare function assertRereadable(preset: AnyPreset, config: JsonValue, message: string): void;
|
|
154
|
+
export {};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Service, type Context, type ScopeKey } from '@leuduan/cordis';
|
|
2
|
+
import type { InitialInstallation, Installation, InstallationLifetime } from '../models/index.js';
|
|
3
|
+
import { type AnyPreset } from './preset.js';
|
|
4
|
+
import type { Thread } from './thread.js';
|
|
5
|
+
/**
|
|
6
|
+
* An installation a caller asks for, at creation (as an {@link InitialInstallationInput}) or later
|
|
7
|
+
* (`Thread.configure`).
|
|
8
|
+
*/
|
|
9
|
+
export type InstallationInput = {
|
|
10
|
+
readonly presetId: string;
|
|
11
|
+
readonly config?: unknown;
|
|
12
|
+
/**
|
|
13
|
+
* Unique within the change or the creation; generated when omitted. Given, it makes a retried
|
|
14
|
+
* application idempotent. A removed id is never accepted again.
|
|
15
|
+
*/
|
|
16
|
+
readonly installationId?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* An installation a thread is created with (`create`'s `installations`), with how long it lasts:
|
|
20
|
+
* `defining` ones are never removed, `configurable` ones are installations like any applied later.
|
|
21
|
+
* A creation preset is only ever `defining`.
|
|
22
|
+
*/
|
|
23
|
+
export type InitialInstallationInput = InstallationInput & {
|
|
24
|
+
readonly lifetime: InstallationLifetime;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* An installation a thread's scope hands down to every thread a call there creates; see
|
|
28
|
+
* {@link handDown}. The id is required: it is what keeps a hand-down from colliding with another in
|
|
29
|
+
* its layer or with the child's own installations.
|
|
30
|
+
*/
|
|
31
|
+
export type HandDown = {
|
|
32
|
+
readonly presetId: string;
|
|
33
|
+
readonly config?: unknown;
|
|
34
|
+
readonly installationId: string;
|
|
35
|
+
};
|
|
36
|
+
/** What a configuration change records, decided against the thread's installations as they stand. */
|
|
37
|
+
export type ConfigurationPlan = {
|
|
38
|
+
readonly rows: readonly ({
|
|
39
|
+
type: 'installation/applied';
|
|
40
|
+
data: Installation;
|
|
41
|
+
options: {
|
|
42
|
+
threadId: string;
|
|
43
|
+
};
|
|
44
|
+
} | {
|
|
45
|
+
type: 'installation/removed';
|
|
46
|
+
data: {
|
|
47
|
+
installation_id: string;
|
|
48
|
+
};
|
|
49
|
+
options: {
|
|
50
|
+
threadId: string;
|
|
51
|
+
};
|
|
52
|
+
})[];
|
|
53
|
+
/** Every installation the change applies, an earlier application of the same id included. */
|
|
54
|
+
readonly applied: readonly string[];
|
|
55
|
+
/** The installations it takes off; an id not installed is none. */
|
|
56
|
+
readonly removed: readonly string[];
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* What a preset installation means: the registry of presets a thread can install, how an
|
|
60
|
+
* installation is validated, an agent-defining one against its thread's agent included, which
|
|
61
|
+
* installations a thread's scope hands down to the children its calls create, and how a thread's
|
|
62
|
+
* recorded installations are mounted when it activates. A core service: the thread owner
|
|
63
|
+
* orchestrates creation, configuration and activation, and hands this service the thread, the scope
|
|
64
|
+
* or the state each question is about. Registrations do not survive a reload.
|
|
65
|
+
*/
|
|
66
|
+
export declare class PresetsService extends Service {
|
|
67
|
+
static inject: string[];
|
|
68
|
+
private readonly registry;
|
|
69
|
+
/** Each thread scope's hand-downs, in declaration order; the global layer stays empty. */
|
|
70
|
+
private readonly handDowns;
|
|
71
|
+
constructor(ctx: Context);
|
|
72
|
+
/** Makes `preset` installable on threads; returns the unregister function. */
|
|
73
|
+
register(preset: AnyPreset): () => void;
|
|
74
|
+
/** Whether a preset is registered under `presetId`. */
|
|
75
|
+
has(presetId: string): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* The installations `entries` record, validated before anything is appended: a registered
|
|
78
|
+
* preset whose placement allows the use, a configuration its schema accepts and parses back to
|
|
79
|
+
* itself, and ids unique among them. At a creation on `agentName`, a preset that defines its
|
|
80
|
+
* thread's agent must define that one. Reads no thread state, so it fails only on a composition
|
|
81
|
+
* bug.
|
|
82
|
+
*/
|
|
83
|
+
installationsFor(entries: readonly InstallationInput[], use: 'creation' | 'change', agentName?: string): Installation[];
|
|
84
|
+
/**
|
|
85
|
+
* The installations a creation on `agentName` records, each with its lifetime: validated as
|
|
86
|
+
* {@link installationsFor} validates a creation's, and a creation preset refused unless it is
|
|
87
|
+
* `defining`, since it can never be applied again once removed.
|
|
88
|
+
*/
|
|
89
|
+
initialInstallations(entries: readonly InitialInstallationInput[], agentName: string): InitialInstallation[];
|
|
90
|
+
/**
|
|
91
|
+
* What a change records on `threadId`, decided against its installations as they stand:
|
|
92
|
+
* removals first, then applications, each id once. Removing an id not installed is no change; a
|
|
93
|
+
* defining installation is never removed. An application whose id is already this very
|
|
94
|
+
* installation, compared after defaults, is no change, which makes a retry idempotent; one whose
|
|
95
|
+
* id names another installation, or a removed one, is refused. The owner calls this before
|
|
96
|
+
* admitting the change and again inside its write.
|
|
97
|
+
*/
|
|
98
|
+
plan(threadId: string, apply: readonly Installation[], remove: readonly string[]): ConfigurationPlan;
|
|
99
|
+
/**
|
|
100
|
+
* Declares in `scope` that every thread a call there creates is born with `handDown` installed,
|
|
101
|
+
* as a defining installation; returns the withdraw function. Use {@link handDown}, which ties it
|
|
102
|
+
* to the declaring plugin. Refused in the global layer, where it would reach the children of every
|
|
103
|
+
* conversation; for a preset that is not registered, since a child restores it from the registry
|
|
104
|
+
* whether or not its parent is live; for a configuration its preset would not record; and for an
|
|
105
|
+
* installation id already handed down in the same layer, so no rule has to choose between two
|
|
106
|
+
* declarations.
|
|
107
|
+
*/
|
|
108
|
+
handDown(scope: ScopeKey | undefined, handDown: HandDown): () => void;
|
|
109
|
+
/**
|
|
110
|
+
* The installations a new thread on `agentName` is born with because the scope of the call
|
|
111
|
+
* creating it hands them down, each defining: from the closest layer out, each in declaration
|
|
112
|
+
* order, a closer declaration winning an id. Validated as the creation's own installations are,
|
|
113
|
+
* and refused when an id is also one of those: two owners for one installation is a composition
|
|
114
|
+
* bug, not something to resolve.
|
|
115
|
+
*/
|
|
116
|
+
handedDown(scope: ScopeKey, threadId: string, agentName: string, own: readonly Installation[]): InitialInstallation[];
|
|
117
|
+
/**
|
|
118
|
+
* Mounts every recorded installation of `thread`, one at a time in recorded order so that
|
|
119
|
+
* registration order is stable across reopening; the owner calls it once the activation's
|
|
120
|
+
* listeners have settled, so installations follow the listeners' own plugins. Any failure fails
|
|
121
|
+
* the activation, which a run turns into a rejection with the input kept.
|
|
122
|
+
*/
|
|
123
|
+
restore(thread: Thread): Promise<void>;
|
|
124
|
+
private requireRegistered;
|
|
125
|
+
/**
|
|
126
|
+
* Whether `installation`'s id is already this very installation. Throws when the id names a
|
|
127
|
+
* different installation, or one that was removed.
|
|
128
|
+
*/
|
|
129
|
+
private alreadyApplied;
|
|
130
|
+
}
|
|
131
|
+
/** Makes `preset` installable on threads for the lifetime of the calling plugin. */
|
|
132
|
+
export declare const registerPreset: (ctx: Context, preset: AnyPreset) => (() => void | Promise<void>);
|
|
133
|
+
/**
|
|
134
|
+
* Hands `handDown` down, for the lifetime of the calling plugin, from the thread scope it is
|
|
135
|
+
* mounted in to every new thread a call there creates: each child is born with it as a defining
|
|
136
|
+
* installation, recorded with its spawn row. See {@link PresetsService.handDown} for what is
|
|
137
|
+
* refused. Looks the service up, so a caller need not inject it.
|
|
138
|
+
*/
|
|
139
|
+
export declare function handDown(ctx: Context, handDown: HandDown): () => void | Promise<void>;
|