@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,449 @@
|
|
|
1
|
+
import { Context, Service, type ScopeKey } from '@leuduan/cordis';
|
|
2
|
+
import type { PromptBlock } from '../llm/index.js';
|
|
3
|
+
import type { ChainStanding, CompactOptions, ConfirmationState, RouteAuthority, StreamedChunk, SurfacePrepareOutcome, Target, TurnLimits, BirthConflict, BirthSpec, HoldBasis } from '../loop/index.js';
|
|
4
|
+
import { ChunkChannel } from '../loop/index.js';
|
|
5
|
+
import type { ThreadOrigin } from '../models/index.js';
|
|
6
|
+
import { type DeepReadonly } from '../util/json.js';
|
|
7
|
+
import { type OwnerHandle, type OwnerRegistration, type StartOptions, type ThreadInspection } from './owner.js';
|
|
8
|
+
import type { RunEvent, RunState } from './runEvents.js';
|
|
9
|
+
import type { InstallationInput } from './presets.js';
|
|
10
|
+
import { type CreateThreadOptions, type ForkOptions } from './birth.js';
|
|
11
|
+
import { Thread } from './thread.js';
|
|
12
|
+
import { ThreadView } from './threadView.js';
|
|
13
|
+
export type ThreadsConfig = {
|
|
14
|
+
/** Default `environment.cwd` for threads created without one; absolute. */
|
|
15
|
+
cwd: string;
|
|
16
|
+
/** The turn limits, resolved once by `core`, which hands the journal the same ones. */
|
|
17
|
+
limits: TurnLimits;
|
|
18
|
+
/**
|
|
19
|
+
* What becomes of a thread the owner loaded to run once its execution lets go and nothing else
|
|
20
|
+
* holds it: `retire` takes it out of memory, `keep` leaves it loaded. The application's choice.
|
|
21
|
+
*/
|
|
22
|
+
retention: RetainOptions['lastRelease'];
|
|
23
|
+
/** How many reactive turns in a row a thread may run before its chain is at the limit. */
|
|
24
|
+
chainLimit: number;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* A change to one thread's preset installations; see `Thread.configure`. Removals are recorded
|
|
28
|
+
* before applications, so a change that replaces an installation lists the old id in `remove` and
|
|
29
|
+
* the new one in `apply`.
|
|
30
|
+
*/
|
|
31
|
+
export type ConfigurationChange = {
|
|
32
|
+
readonly apply?: readonly InstallationInput[];
|
|
33
|
+
/** Installation ids to take off; one not installed is no change. */
|
|
34
|
+
readonly remove?: readonly string[];
|
|
35
|
+
/**
|
|
36
|
+
* Render the recorded prompt again once the change is restored, the one way a preset's prompt
|
|
37
|
+
* sections reach a thread that has already run. A thread with no recorded prompt records one on
|
|
38
|
+
* its first run anyway.
|
|
39
|
+
*/
|
|
40
|
+
readonly rebuildPrompt?: boolean;
|
|
41
|
+
};
|
|
42
|
+
/** What a configuration change did. */
|
|
43
|
+
export type ConfigurationResult = {
|
|
44
|
+
/** The id of every installation the change applies, in order, one applied before included. */
|
|
45
|
+
readonly applied: readonly string[];
|
|
46
|
+
/** The installations it took off. */
|
|
47
|
+
readonly removed: readonly string[];
|
|
48
|
+
};
|
|
49
|
+
export type ThreadFilter = {
|
|
50
|
+
/** Threads whose `origin` is this one, caller and cause alike. */
|
|
51
|
+
origin?: ThreadOrigin;
|
|
52
|
+
/** Threads a caller thread created, by any cause. */
|
|
53
|
+
callerThreadId?: string;
|
|
54
|
+
agentName?: string;
|
|
55
|
+
/**
|
|
56
|
+
* This thread, and every thread created under it at any depth, by `origin`, in spawn order. One
|
|
57
|
+
* catalog read; an unknown thread has nothing under it.
|
|
58
|
+
*/
|
|
59
|
+
under?: string;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* `ctx.threads` as an application sees it: the questions about the set of threads, and what starts
|
|
63
|
+
* one. Everything about one thread is on its {@link Thread}.
|
|
64
|
+
*/
|
|
65
|
+
export interface Threads {
|
|
66
|
+
/**
|
|
67
|
+
* Aborts once lagent is closing: no thread is created, run or released after that. A refusal
|
|
68
|
+
* because lagent is closing throws `signal.reason` itself, so a host recognizes it by identity
|
|
69
|
+
* (`error === threads.signal.reason`), never by message.
|
|
70
|
+
*/
|
|
71
|
+
readonly signal: AbortSignal;
|
|
72
|
+
/** The `environment.cwd` a thread created without one gets. */
|
|
73
|
+
readonly defaultCwd: string;
|
|
74
|
+
create(agentName: string, options: CreateThreadOptions): Promise<Thread>;
|
|
75
|
+
fork(sourceId: string, options: ForkOptions): Promise<Thread>;
|
|
76
|
+
get(threadId: string): Thread | undefined;
|
|
77
|
+
list(filter?: ThreadFilter): Thread[];
|
|
78
|
+
liveThreads(): Thread[];
|
|
79
|
+
/**
|
|
80
|
+
* Starts running threads, once, after the application composed its plugins and attached its
|
|
81
|
+
* observers: nothing runs before. Repairs the registered constraints' owners first, then runs the
|
|
82
|
+
* requests pending at boot that `resume` accepts, at most `startLimit` at once; the rest are held
|
|
83
|
+
* (`startup`) until a releasing cause. A second call is refused.
|
|
84
|
+
*/
|
|
85
|
+
start(options: StartOptions): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Where a thread stands: its state, current operation and primary hold, and what is behind a
|
|
88
|
+
* `missing` hold; `null` for an unknown thread. Synchronous: it admits nothing, changes no backoff
|
|
89
|
+
* and publishes nothing. `catalog` loads and activates nothing and reports the screening the
|
|
90
|
+
* catalog shows with this process's owners; `loaded` decides the hold from the thread's folds and
|
|
91
|
+
* throws unless the thread and the callers above it are loaded already.
|
|
92
|
+
*/
|
|
93
|
+
inspect(threadId: string, options: {
|
|
94
|
+
readonly basis: HoldBasis;
|
|
95
|
+
}): ThreadInspection | null;
|
|
96
|
+
/** Every run's state changes, as {@link RunEvent}s. Returns the unsubscribe. */
|
|
97
|
+
onRunEvent(listener: (event: RunEvent) => void): () => void;
|
|
98
|
+
/**
|
|
99
|
+
* Where run `runId` of the thread stands, by the rule its events follow; `null` for a run it never
|
|
100
|
+
* had. Out of memory, a thread answers from its catalog entry, which knows its pending run and its
|
|
101
|
+
* latest settlement only: an older run reads `null` until the thread is loaded (a read or a hold).
|
|
102
|
+
*/
|
|
103
|
+
runState(threadId: string, runId: string): RunState | null;
|
|
104
|
+
/**
|
|
105
|
+
* Where the thread's chain of unattended work stands: whether its open turn has a person's
|
|
106
|
+
* authority, how many reactive turns in a row it has run, and whether that reached the configured
|
|
107
|
+
* limit, which a producer of more unattended work (a background start, a notifying command)
|
|
108
|
+
* refuses at. Synchronous, by a caller that holds the thread, as `view` is.
|
|
109
|
+
*/
|
|
110
|
+
chain(threadId: string): ChainStanding;
|
|
111
|
+
/**
|
|
112
|
+
* What differs between thread `threadId`'s recorded birth and `request`'s: the agent, that the
|
|
113
|
+
* thread is a fresh one and not a fork, then the route, environment, installations and `requires`
|
|
114
|
+
* its spawn row recorded, against the {@link BirthSpec} asked for. Empty when it is the same birth.
|
|
115
|
+
* The origin is not compared: an owner continuing its child on a later assignment checks the
|
|
116
|
+
* configuration it pinned for the participant. This is **birth** equality, read from the immutable
|
|
117
|
+
* spawn row outside any write, not the equality of the thread's current configuration. An unknown
|
|
118
|
+
* thread throws `UnknownThreadError`.
|
|
119
|
+
*/
|
|
120
|
+
birthConflicts(threadId: string, request: {
|
|
121
|
+
agent: string;
|
|
122
|
+
spec: BirthSpec;
|
|
123
|
+
}): Promise<BirthConflict[]>;
|
|
124
|
+
/** Registers a feature as an owner, with its say over when its threads run; see {@link OwnerRegistration}. */
|
|
125
|
+
registerOwner(registration: OwnerRegistration): OwnerHandle;
|
|
126
|
+
pendingConfirmations(options?: {
|
|
127
|
+
under?: string;
|
|
128
|
+
}): Promise<DeepReadonly<ConfirmationState[]>>;
|
|
129
|
+
onChunk(listener: (chunk: StreamedChunk) => void): () => void;
|
|
130
|
+
retain(members: RetainedMembers, options: RetainOptions): Promise<Retention>;
|
|
131
|
+
/**
|
|
132
|
+
* What a thread's folds say, read synchronously by a caller that already holds the thread: inside
|
|
133
|
+
* a journal write or a contributor running for it, during its run, or under a retention. Loads
|
|
134
|
+
* nothing; a caller that holds nothing reads through `thread.read`. A view of a thread nothing
|
|
135
|
+
* holds may find it unloaded and throws `ThreadNotLoadedError`.
|
|
136
|
+
*/
|
|
137
|
+
view(threadId: string): ThreadView;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* A set of threads held in memory until `release()`; see `ctx.threads.retain`. Its members are
|
|
141
|
+
* read through `ctx.threads.view` while it holds them.
|
|
142
|
+
*/
|
|
143
|
+
export interface Retention {
|
|
144
|
+
/** Gives the set back; see `RetainOptions.lastRelease`. Releasing twice does nothing. */
|
|
145
|
+
release(): void;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* The threads a retention keeps in memory, as a function the engine asks for them: read at the
|
|
149
|
+
* start, to load them, and again at release and by every other retention's check, since the set a
|
|
150
|
+
* host means (a conversation and what it delegated to, say) can grow while it is held. A constant
|
|
151
|
+
* set is `() => ids`. A member that appears later is covered by the live check, not loaded.
|
|
152
|
+
*/
|
|
153
|
+
export type RetainedMembers = () => Iterable<string>;
|
|
154
|
+
export type RetainOptions = {
|
|
155
|
+
/**
|
|
156
|
+
* What releasing this retention does to its members that no other retention covers: `retire`
|
|
157
|
+
* takes them out of memory, as `close()` does, once any operation holding one has settled; `keep`
|
|
158
|
+
* leaves them loaded. Named by the caller, since what to cache is the host's choice.
|
|
159
|
+
*/
|
|
160
|
+
readonly lastRelease: 'retire' | 'keep';
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Durable handles, live activations, and application-wide shutdown. Registry lookups stay live;
|
|
164
|
+
* journal operations never require an execution runtime. Every question about the set of threads —
|
|
165
|
+
* listing, finding, lineage, what needs resuming — is answered from the journal's catalog, so a
|
|
166
|
+
* thread's rows are in memory only once something reads or runs it.
|
|
167
|
+
*/
|
|
168
|
+
export declare class ThreadsService extends Service<ThreadsConfig> {
|
|
169
|
+
static inject: string[];
|
|
170
|
+
readonly chunks: ChunkChannel;
|
|
171
|
+
readonly limits: TurnLimits;
|
|
172
|
+
readonly defaultCwd: string;
|
|
173
|
+
private readonly live;
|
|
174
|
+
/** The retentions not yet released, each with its membership as it reads now. */
|
|
175
|
+
private readonly retentions;
|
|
176
|
+
/** Retirements in flight, by thread: a new retention waits for one before it loads. */
|
|
177
|
+
private readonly retiring;
|
|
178
|
+
/** Which operation holds each thread; the handle and the activation are given its view at construction. */
|
|
179
|
+
private readonly admission;
|
|
180
|
+
/** When threads run: see {@link RunOwner}. */
|
|
181
|
+
private readonly owner;
|
|
182
|
+
private readonly retention;
|
|
183
|
+
private readonly chainLimit;
|
|
184
|
+
private readonly handles;
|
|
185
|
+
/** Threads whose corrupt history was reported; see `reportCorrupt`. */
|
|
186
|
+
private readonly reportedCorrupt;
|
|
187
|
+
private readonly controller;
|
|
188
|
+
private closing;
|
|
189
|
+
constructor(ctx: Context, config: ThreadsConfig);
|
|
190
|
+
/** See {@link Threads.signal}: refusals because lagent is closing throw this signal's reason itself. */
|
|
191
|
+
get signal(): AbortSignal;
|
|
192
|
+
/** Close execution admission and abort every loop before waiting for any one to finish. */
|
|
193
|
+
private shutdown;
|
|
194
|
+
/** Every thread in creation order, or those matching `filter`; from the catalog, loading nothing. */
|
|
195
|
+
list(filter?: ThreadFilter): Thread[];
|
|
196
|
+
get(threadId: string): Thread | undefined;
|
|
197
|
+
/** Threads with a live activation, running or not, in the order they activated. */
|
|
198
|
+
liveThreads(): Thread[];
|
|
199
|
+
start(options: StartOptions): Promise<void>;
|
|
200
|
+
inspect(threadId: string, { basis }: {
|
|
201
|
+
readonly basis: HoldBasis;
|
|
202
|
+
}): ThreadInspection | null;
|
|
203
|
+
onRunEvent(listener: (event: RunEvent) => void): () => void;
|
|
204
|
+
runState(threadId: string, runId: string): RunState | null;
|
|
205
|
+
chain(threadId: string): ChainStanding;
|
|
206
|
+
registerOwner(registration: OwnerRegistration): OwnerHandle;
|
|
207
|
+
/** The release as an admitted operation: the activation goes, then `after` runs, under one admission. */
|
|
208
|
+
private releaseUnder;
|
|
209
|
+
/**
|
|
210
|
+
* Keeps `members` loaded until the returned function is called. Releasing a `retire` retention
|
|
211
|
+
* then retires each of its members, its membership read again, that no other retention's current
|
|
212
|
+
* membership covers; releasing a `keep` one retires nothing. Waits for a retirement already in
|
|
213
|
+
* flight on a member before loading it, so a thread is never read as it is being dropped. A
|
|
214
|
+
* thread whose operation is admitted is retired once it settles; an ancestor a retained fork folds
|
|
215
|
+
* through stays, as the journal keeps it. Releasing twice does nothing, and once lagent is
|
|
216
|
+
* closing releasing only gives the hold back. `waitOn`, for the engine's own acquisition alone and
|
|
217
|
+
* not part of {@link RetainOptions}, names the members whose retirement in flight is waited for,
|
|
218
|
+
* all of them when omitted.
|
|
219
|
+
*/
|
|
220
|
+
retain(members: RetainedMembers, options: RetainOptions & {
|
|
221
|
+
readonly waitOn?: readonly string[];
|
|
222
|
+
}): Promise<Retention>;
|
|
223
|
+
view(threadId: string): ThreadView;
|
|
224
|
+
/** The threads the retentions not yet released cover, by their membership as it reads now. */
|
|
225
|
+
private covered;
|
|
226
|
+
/**
|
|
227
|
+
* Takes a thread no retention covers out of memory: one retirement at a time per thread, after the
|
|
228
|
+
* operation admitted on it settles, and only if no retention covers it by then; refused quietly
|
|
229
|
+
* when an operation is admitted again meanwhile, since that operation's caller is reading it.
|
|
230
|
+
*/
|
|
231
|
+
private retire;
|
|
232
|
+
/**
|
|
233
|
+
* Takes the thread out of the working set: releases an idle activation, then drops the thread's
|
|
234
|
+
* rows and folds from memory under the same admission, so nothing runs it in between; the catalog
|
|
235
|
+
* entry stays, and the next touch loads the thread again. The rows stay while a retention covers
|
|
236
|
+
* the thread, or a covered fork folds through it. Refused busy while an operation holds the
|
|
237
|
+
* thread. The threads it inherited from or delegated to are their own, closed on their own.
|
|
238
|
+
*/
|
|
239
|
+
close(threadId: string): Promise<void>;
|
|
240
|
+
/**
|
|
241
|
+
* Starts a thread that continues `sourceId`'s conversation from the row `at`, on the same agent.
|
|
242
|
+
*
|
|
243
|
+
* The fork is one spawn row that names its source and cut; the journal folds the source's lineage
|
|
244
|
+
* up to there into every thread-scoped projection, so the fork inherits the conversation, the
|
|
245
|
+
* prompt, the route and plugin state without a copy, and nothing its source does later. What
|
|
246
|
+
* described the source's execution — queued input, calls in flight, usage — starts fresh.
|
|
247
|
+
*
|
|
248
|
+
* With `input`, the first input is queued in the same append, so the fork never exists without
|
|
249
|
+
* its task, and `rows` adds a plugin's rows to it or refuses it (see {@link Opening}). A cut at
|
|
250
|
+
* a row the source inherited is redirected to the thread that owns the row. Forking only reads
|
|
251
|
+
* the journal; the source may be running.
|
|
252
|
+
*
|
|
253
|
+
* Get-or-create, as `create` is: the recorded fork is returned when it matches by `reuse`, its
|
|
254
|
+
* resolved cut, agent and origin under `identity`, and also its own environment and `requires`
|
|
255
|
+
* under `configuration`; any other holder of the id throws `BirthConflictError`. Nothing else is
|
|
256
|
+
* compared or written.
|
|
257
|
+
*/
|
|
258
|
+
fork(sourceId: string, options: ForkOptions): Promise<Thread>;
|
|
259
|
+
private forkHeld;
|
|
260
|
+
/** A fork found under its id: returned when it is the fork asked for, by its {@link Reuse}, else a conflict. */
|
|
261
|
+
private reuseFork;
|
|
262
|
+
/**
|
|
263
|
+
* A new thread's one group: its spawn row; its first input, if any, queued for a turn of its own
|
|
264
|
+
* and citing the spawn row, which is how a fork's folds tell its task from what it inherited; the
|
|
265
|
+
* cause its `wake` asks for, opening the thread's first run request; and last the rows the
|
|
266
|
+
* caller's `rows` adds, built inside the write. A veto of those rejects the creation, as a
|
|
267
|
+
* callback that threw does: the thread is never recorded.
|
|
268
|
+
*/
|
|
269
|
+
private openingGroup;
|
|
270
|
+
/**
|
|
271
|
+
* Starts a thread on `agentName`, with its first input and a plugin's rows in the same append
|
|
272
|
+
* when given (see {@link Opening}). Get-or-create, the idempotent entry point a re-dispatched
|
|
273
|
+
* delegating call relies on.
|
|
274
|
+
*
|
|
275
|
+
* Two explicit choices say what is created and what an existing id must match. `birth.from` says
|
|
276
|
+
* where the thread's configuration comes from: `defaults` fills what is left out from core's
|
|
277
|
+
* configuration; `caller` from the origin's caller, whose live activation it requires, plus the
|
|
278
|
+
* installations its scope hands down; `exact` takes a whole spec and reads nothing. `reuse` says
|
|
279
|
+
* what an existing thread under the id must match to be returned: `identity`, its agent, origin and
|
|
280
|
+
* that it is not a fork, checked before anything of the request is resolved, or `configuration`,
|
|
281
|
+
* which also resolves the request and compares its birth with the recorded spawn row. A thread
|
|
282
|
+
* that does not match is never adopted: it throws {@link BirthConflictError}. Metadata, input,
|
|
283
|
+
* wake and rows apply to a new thread only; a write-time veto throws {@link WriteRefusedError}.
|
|
284
|
+
*/
|
|
285
|
+
create(agentName: string, options: CreateThreadOptions): Promise<Thread>;
|
|
286
|
+
/** What resolving `threadId`'s birth reads beyond its options; see {@link BirthContext}. */
|
|
287
|
+
private birthContext;
|
|
288
|
+
/**
|
|
289
|
+
* A fresh creation's id already taken: the thread is returned when it is the one asked for. Its
|
|
290
|
+
* identity is always compared, and returned on, before the request is resolved or a live caller
|
|
291
|
+
* touched; under `configuration` reuse the request is resolved and its birth compared with the
|
|
292
|
+
* spawn row.
|
|
293
|
+
*/
|
|
294
|
+
private reuseFresh;
|
|
295
|
+
/** What differs between `summary`'s recorded spawn row and the birth `spec`; read outside any write. */
|
|
296
|
+
private specConflictsOf;
|
|
297
|
+
birthConflicts(threadId: string, request: {
|
|
298
|
+
agent: string;
|
|
299
|
+
spec: BirthSpec;
|
|
300
|
+
}): Promise<BirthConflict[]>;
|
|
301
|
+
/**
|
|
302
|
+
* Requests waiting on the user: across every thread, or only on `under` and the threads created
|
|
303
|
+
* beneath it — the set one conversation's driver is responsible for answering. The threads that
|
|
304
|
+
* have any are found in the flushed catalog; only those are retained for the requests themselves,
|
|
305
|
+
* without activating plugins. Returns owned frozen snapshots and releases its retention even on failure.
|
|
306
|
+
*/
|
|
307
|
+
pendingConfirmations(options?: {
|
|
308
|
+
under?: string;
|
|
309
|
+
}): Promise<DeepReadonly<ConfirmationState[]>>;
|
|
310
|
+
/**
|
|
311
|
+
* Loads a thread so its synchronous reads answer: its lineage — its own rows and those of the
|
|
312
|
+
* threads it was forked from — and the threads that called it, whose policies a running thread
|
|
313
|
+
* may read. A run, `compact()` and every write load what they need themselves; a host loads what
|
|
314
|
+
* it reads.
|
|
315
|
+
*/
|
|
316
|
+
load(threadId: string): Promise<void>;
|
|
317
|
+
/**
|
|
318
|
+
* Reports, once per thread and process, a loaded thread whose surface refused a replacement: where
|
|
319
|
+
* its corrupt history is first seen. Nothing executes on it (`requireExecutable`).
|
|
320
|
+
*/
|
|
321
|
+
private reportCorrupt;
|
|
322
|
+
/** Refuses to execute on a thread whose surface refused a replacement; it stays readable. */
|
|
323
|
+
private requireExecutable;
|
|
324
|
+
/** A thread and the threads that called it, out to its origin root: what a run of it reads. */
|
|
325
|
+
private readSet;
|
|
326
|
+
/**
|
|
327
|
+
* What an execution of `threadId`, a run or a compaction, reads, loaded and held for the whole of
|
|
328
|
+
* it: the thread and the callers out to its origin root, as they stand now, held by one retention
|
|
329
|
+
* that releases with `keep`, so the end of a child's run never retires a caller's activation. The
|
|
330
|
+
* callers are held loaded, never waited on: a retirement in flight is waited for on the thread
|
|
331
|
+
* alone, since a caller's own teardown may be waiting for this very execution. The release, once
|
|
332
|
+
* only, then retires the thread alone when the application's policy is `retire` and `retiring`
|
|
333
|
+
* says so, as a run's does; so does a failed acquisition, once the retention undid its holds. A
|
|
334
|
+
* compaction passes `retiring: false`: it releases every member with `keep`, so it never starts a
|
|
335
|
+
* retirement its own cleanup, or an activation's teardown reading the thread, could wait on. A
|
|
336
|
+
* retirement waits for the operation admitted on the thread to settle and is not started before.
|
|
337
|
+
* The one acquisition for an execution's reads: a storage or load failure is the caller's, a
|
|
338
|
+
* corrupt thread is `requireExecutable`'s to refuse.
|
|
339
|
+
*/
|
|
340
|
+
private retainExecutionReads;
|
|
341
|
+
/** The model's output as it streams, on every thread. Returns the unsubscribe function. */
|
|
342
|
+
onChunk(listener: (chunk: StreamedChunk) => void): () => void;
|
|
343
|
+
/** `ancestorId` and every thread under it by `origin`, from the catalog. */
|
|
344
|
+
private subtreeIds;
|
|
345
|
+
/**
|
|
346
|
+
* The installations a new child is born with because its caller's scope hands them down, read
|
|
347
|
+
* from the caller's live activation, so only what the caller's own plugins declared applies.
|
|
348
|
+
*/
|
|
349
|
+
private handedDown;
|
|
350
|
+
/**
|
|
351
|
+
* Changes a thread's preset installations as one operation; see `Thread.configure`. Validated,
|
|
352
|
+
* then admitted before anything is awaited (busy while another operation holds the thread,
|
|
353
|
+
* refused with `ThreadActivatingError` while the activation is still getting ready, and after
|
|
354
|
+
* shutdown), then decided against the installations as they stand: a change that records nothing,
|
|
355
|
+
* such as a retry, returns without touching the thread, even with a confirmation unfinished.
|
|
356
|
+
* Otherwise it is refused with `ThreadUnsettledError` for an unfinished confirmation, releases the live activation, records every installation change in
|
|
357
|
+
* one write decided again inside it, and restores the thread when it should.
|
|
358
|
+
*/
|
|
359
|
+
configure(threadId: string, change: ConfigurationChange): Promise<ConfigurationResult>;
|
|
360
|
+
/** What a change may not be recorded under: shutdown, or a confirmation still unfinished (`ThreadUnsettledError`). */
|
|
361
|
+
private refuseRecording;
|
|
362
|
+
/**
|
|
363
|
+
* Throws `UnknownAgentError` for a global agent name that is not registered. A scoped name passes:
|
|
364
|
+
* only the thread's own installations can define it, and they are known once it is ready.
|
|
365
|
+
*/
|
|
366
|
+
private requireGlobalAgent;
|
|
367
|
+
/**
|
|
368
|
+
* The origin `threadId` records, validated: a known caller within the delegation depth, citing a row
|
|
369
|
+
* of its lineage that is the cause it claims (`origins.validate`).
|
|
370
|
+
*/
|
|
371
|
+
private originFor;
|
|
372
|
+
/** The prompt `threadId` would record if rendered now from `scope`, with the thread's plugins in it. */
|
|
373
|
+
private renderPrompt;
|
|
374
|
+
/** Records the thread's prompt the first time it is about to run; later turns reuse it. */
|
|
375
|
+
recordPromptOnce(scope: ScopeKey): Promise<void>;
|
|
376
|
+
/** Re-renders through the thread's activation, waiting for its plugins, and records the result. */
|
|
377
|
+
rebuildPrompt(threadId: string): Promise<PromptBlock[]>;
|
|
378
|
+
/**
|
|
379
|
+
* Activates the thread if need be and waits for its plugins. Readiness is a barrier, not an
|
|
380
|
+
* exclusive operation: a release or a configuration change in progress is waited for, since an
|
|
381
|
+
* activation on its way out is not ready, and the fresh one is then activated.
|
|
382
|
+
*/
|
|
383
|
+
whenReady(threadId: string): Promise<void>;
|
|
384
|
+
/** The thread's live context, activating it; see `Thread.ctx`. */
|
|
385
|
+
contextOf(threadId: string): Context;
|
|
386
|
+
/** The current activation's signal, activating the thread; see `Thread.signal`. */
|
|
387
|
+
signalOf(threadId: string): AbortSignal;
|
|
388
|
+
private activate;
|
|
389
|
+
/**
|
|
390
|
+
* One execution of a run request under its admitted operation, the owner's to call: whatever the
|
|
391
|
+
* run reads is held (`retainExecutionReads`), and an interrupted turn is closed first, as a write,
|
|
392
|
+
* so it lands after any `send()` queued before this run, and what the run decides from is what
|
|
393
|
+
* that send left. The owner's continuation decision is asked at its entry and after every turn and
|
|
394
|
+
* recorded on `execution`, which the owner's finalization settles the request by. Resolves once
|
|
395
|
+
* the work is done, however it ended, a setup failure, settled as one, included; only a failure
|
|
396
|
+
* past its setup rejects.
|
|
397
|
+
*/
|
|
398
|
+
private execute;
|
|
399
|
+
/**
|
|
400
|
+
* The thread's route as a statement is checked against, read where it is called: inside a write,
|
|
401
|
+
* as the write's rows stand. A route change is accepted only while no run serving the pending
|
|
402
|
+
* request holds the thread (a compaction does not count), and while no request is pending, the
|
|
403
|
+
* route cannot run, or the request is held by a failure or a cancellation (whatever else holds it):
|
|
404
|
+
* such a request runs only on a releasing cause, so changing its route moves nothing that is
|
|
405
|
+
* running or about to run. A runnable pending request is never moved under itself.
|
|
406
|
+
*/
|
|
407
|
+
target(threadId: string): Target;
|
|
408
|
+
/** What checks every route statement, inside the write that records it: the one guard on route changes. */
|
|
409
|
+
readonly routes: RouteAuthority;
|
|
410
|
+
/**
|
|
411
|
+
* One request to prepare the surface; see `Thread.compact`. Cancellation owns it from this call:
|
|
412
|
+
* `cancel()`, the caller's signal or shutdown ends it at any point, and it then resolves
|
|
413
|
+
* `cancelled`, with nothing dispatched if it had not yet begun.
|
|
414
|
+
*/
|
|
415
|
+
compact(threadId: string, options: CompactOptions): Promise<SurfacePrepareOutcome>;
|
|
416
|
+
/**
|
|
417
|
+
* Releases an activation whose setup failed while no operation held the thread; one that fails
|
|
418
|
+
* while an operation holds the thread is released by that operation as it settles. An operation
|
|
419
|
+
* admitted meanwhile waits for the disposal (`settledLive`) before it activates the thread again,
|
|
420
|
+
* so a retry never finds the failed scope's resources still held.
|
|
421
|
+
*/
|
|
422
|
+
releaseFailed(threadId: string): Promise<void>;
|
|
423
|
+
/**
|
|
424
|
+
* The thread's activation for `operation`: one whose plugins changed since it was ready is
|
|
425
|
+
* released first, under the operation, marked as releasing so the scope's unload guard does not
|
|
426
|
+
* wait for it, and a fresh one is activated from the thread's listeners and installations.
|
|
427
|
+
*/
|
|
428
|
+
private activationFor;
|
|
429
|
+
/** Resolves once the thread's activation, if one is being released, is gone: what every operation awaits before activating. */
|
|
430
|
+
private settledLive;
|
|
431
|
+
/** The loop's view of the registries, bound to one activation's scope. */
|
|
432
|
+
private loopServices;
|
|
433
|
+
/** The journal with core's writes, which the thread owner and the loop record through; never handed to a plugin. */
|
|
434
|
+
private get journal();
|
|
435
|
+
/**
|
|
436
|
+
* Runs `work` as an admitted operation other than a run, whose envelope is the owner's; see
|
|
437
|
+
* `Admission.hold`. An activation whose setup failed, or that went stale, could not be released
|
|
438
|
+
* while this operation held the thread: it is released as the operation's cleanup (`cleanup`).
|
|
439
|
+
*/
|
|
440
|
+
private under;
|
|
441
|
+
/**
|
|
442
|
+
* The cleanup of every admitted operation, a run included, still under its admission: an
|
|
443
|
+
* activation whose setup failed, or that went stale, is released so a run meanwhile is busy and
|
|
444
|
+
* nothing activates afresh, in the releasing phase so the scope's unload guard does not wait for it.
|
|
445
|
+
*/
|
|
446
|
+
private cleanup;
|
|
447
|
+
private requireThread;
|
|
448
|
+
private handle;
|
|
449
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Context, Service, type ScopeKey } from '@leuduan/cordis';
|
|
2
|
+
import { type AgentSelector } from '../kit/scope.js';
|
|
3
|
+
import type { Tool, ToolEntry } from '../loop/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* The tools this process can offer, and who may call them. Live: a tool or a grant lasts
|
|
6
|
+
* exactly as long as the plugin that registered it, and an agent's reachable set is resolved when a
|
|
7
|
+
* request is built, never captured earlier. Untagged registrations are global; scoped registrations
|
|
8
|
+
* are visible from that scope and its descendants. The closest definition of a name wins.
|
|
9
|
+
*
|
|
10
|
+
* What an agent may call is exactly what it is granted. A grant holds the selector it was made
|
|
11
|
+
* with and is matched against the agent asking, so a grant to `'global'` or `'all'` keeps up with
|
|
12
|
+
* agents registered after it, and a grant may name a tool or an agent that does not exist yet; it
|
|
13
|
+
* simply resolves to nothing until they do. A scoped agent is reached only by grants naming it or
|
|
14
|
+
* by `'all'` (`selects`).
|
|
15
|
+
*/
|
|
16
|
+
export declare class ToolsService extends Service {
|
|
17
|
+
static inject: string[];
|
|
18
|
+
private readonly layers;
|
|
19
|
+
constructor(ctx: Context);
|
|
20
|
+
/** Registered tool names visible from `scope`, sorted and deduplicated. */
|
|
21
|
+
names(scope: ScopeKey | undefined): string[];
|
|
22
|
+
has(scope: ScopeKey | undefined, name: string): boolean;
|
|
23
|
+
/** The closest registered definition of `name`, then the global fallback. */
|
|
24
|
+
get(scope: ScopeKey | undefined, name: string): ToolEntry | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Adds a tool to one layer; returns the unregister function. Duplicates fail within that layer,
|
|
27
|
+
* and so does a tool that does not say what a re-dispatch after an interruption may do: the
|
|
28
|
+
* declaration has no default, and a missing one would surface as a schema error mid-turn.
|
|
29
|
+
*/
|
|
30
|
+
register(scope: ScopeKey | undefined, name: string, tool: Tool): () => void;
|
|
31
|
+
/** Lets the agents `agents` selects call `toolName` in one layer; returns the revoke function. */
|
|
32
|
+
grant(scope: ScopeKey | undefined, agents: AgentSelector, toolName: string): () => void;
|
|
33
|
+
/**
|
|
34
|
+
* What `agentName` may call right now: its global-to-local grants in registration order, each name
|
|
35
|
+
* once, names nothing answers to skipped. Throws for an agent unknown from `scope`.
|
|
36
|
+
*/
|
|
37
|
+
toolsFor(scope: ScopeKey | undefined, agentName: string): ToolEntry[];
|
|
38
|
+
/** One tool `agentName` may call, or `undefined` when it is unknown or not granted. */
|
|
39
|
+
toolFor(scope: ScopeKey | undefined, agentName: string, toolName: string): ToolEntry | undefined;
|
|
40
|
+
mayCall(scope: ScopeKey | undefined, agentName: string, toolName: string): boolean;
|
|
41
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* What a process lagent spawns may see, and which programs lagent itself runs: both chosen by the
|
|
4
|
+
* host, never read from lagent's own process. A plugin that spawns takes them as required
|
|
5
|
+
* configuration; the helpers here only build them from what the host hands in.
|
|
6
|
+
*/
|
|
7
|
+
/** A spawned process's whole environment, as configuration: every variable it gets, nothing else. */
|
|
8
|
+
export declare const SpawnEnvironmentSchema: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
9
|
+
/**
|
|
10
|
+
* The overrides for a process with no terminal: colour and pagers off, and an editor that fails at
|
|
11
|
+
* once rather than sitting until the deadline. `CI` is deliberately not set, since test runners
|
|
12
|
+
* change more than interactivity under it.
|
|
13
|
+
*/
|
|
14
|
+
export declare const NON_INTERACTIVE_ENVIRONMENT: Readonly<Record<string, string>>;
|
|
15
|
+
/** How a host derives a spawn environment from its own. */
|
|
16
|
+
export type SpawnEnvironmentPolicy = {
|
|
17
|
+
/**
|
|
18
|
+
* Variables whose names match one of these patterns are dropped. A pattern matches a whole name,
|
|
19
|
+
* case-insensitively; `*` stands for any run of characters.
|
|
20
|
+
*/
|
|
21
|
+
readonly drop: readonly string[];
|
|
22
|
+
/** Set over what remains. */
|
|
23
|
+
readonly set: Readonly<Record<string, string>>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Codex's policy: variables that look like credentials are dropped, the locale is fixed to UTF-8,
|
|
27
|
+
* and the {@link NON_INTERACTIVE_ENVIRONMENT} overrides are set.
|
|
28
|
+
*/
|
|
29
|
+
export declare const CODEX_ENVIRONMENT_POLICY: SpawnEnvironmentPolicy;
|
|
30
|
+
/** `source` filtered and overridden by `policy`: the whole environment a spawned process gets. */
|
|
31
|
+
export declare function buildSpawnEnvironment(source: Readonly<Record<string, string | undefined>>, policy: SpawnEnvironmentPolicy): Record<string, string>;
|
|
32
|
+
/**
|
|
33
|
+
* The programs lagent runs itself, by absolute path: never looked up through a spawned process's
|
|
34
|
+
* `PATH`, which a workspace can reach. `rg` is `null` when there is none; the search tools, which
|
|
35
|
+
* run it, are then not provided.
|
|
36
|
+
*/
|
|
37
|
+
export declare const TrustedProgramsSchema: z.ZodObject<{
|
|
38
|
+
git: z.ZodString;
|
|
39
|
+
rg: z.ZodNullable<z.ZodString>;
|
|
40
|
+
}, z.core.$strict>;
|
|
41
|
+
export type TrustedPrograms = z.output<typeof TrustedProgramsSchema>;
|
|
42
|
+
/**
|
|
43
|
+
* Each trusted program as the first executable file of its name in `searchPath`'s directories, in
|
|
44
|
+
* order. Relative directories are skipped: what they name depends on the working directory. Throws
|
|
45
|
+
* when `git` is not found; `rg` is `null` when it is not.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveTrustedPrograms(searchPath: string): TrustedPrograms;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Variables that select a repository, an index or an object store other than the working directory's. */
|
|
2
|
+
export declare const GIT_REPOSITORY_VARIABLES: readonly ["GIT_DIR", "GIT_WORK_TREE", "GIT_INDEX_FILE", "GIT_OBJECT_DIRECTORY", "GIT_ALTERNATE_OBJECT_DIRECTORIES", "GIT_COMMON_DIR", "GIT_NAMESPACE"];
|
|
3
|
+
/**
|
|
4
|
+
* Where a repository keeps its metadata, as found from a path in its working tree. Read from the
|
|
5
|
+
* filesystem alone, without running git, so it costs a few `stat`s and runs nothing the repository
|
|
6
|
+
* configures.
|
|
7
|
+
*/
|
|
8
|
+
export type RepositoryLocation = {
|
|
9
|
+
/** The working tree's top directory: the one holding `.git`. */
|
|
10
|
+
readonly worktree: string;
|
|
11
|
+
/**
|
|
12
|
+
* The `.git` entry itself, with its symbolic links resolved: the git directory, or the pointer
|
|
13
|
+
* file a linked worktree or a submodule has, under whatever name it really has.
|
|
14
|
+
*/
|
|
15
|
+
readonly dotGit: string;
|
|
16
|
+
/** The git directory: `.git` itself, or the `gitdir:` target its pointer file names. */
|
|
17
|
+
readonly gitDir: string;
|
|
18
|
+
/**
|
|
19
|
+
* The shared git directory the git directory's `commondir` names, as a linked worktree's does;
|
|
20
|
+
* else `null`.
|
|
21
|
+
*/
|
|
22
|
+
readonly commonDir: string | null;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* The repository containing `path`: the nearest directory at or above it holding a `.git` entry,
|
|
26
|
+
* so a nested repository is found before the one around it. `path` need not exist. The walk starts
|
|
27
|
+
* from `path` with its symbolic links resolved, as git's own discovery does from the physical
|
|
28
|
+
* working directory, so a workspace reached through a link is found in the repository it lives in,
|
|
29
|
+
* not among the link's own parents; the worktree, git and common directories are given resolved
|
|
30
|
+
* too. A `.git` file that names no git directory is taken as its own, so it still marks the
|
|
31
|
+
* repository. `null` outside every repository.
|
|
32
|
+
*/
|
|
33
|
+
export declare function findRepository(path: string): RepositoryLocation | null;
|
|
34
|
+
/**
|
|
35
|
+
* Read roots for a thread working in `cwd`: the top of the git repository holding it, when that is
|
|
36
|
+
* above it, so the file tools reach the code around a package and every `AGENTS.md` from the
|
|
37
|
+
* repository root down; none outside a repository, nor at its top. Never more than the repository: a
|
|
38
|
+
* sibling checkout stays out of reach. A host's choice to record when it creates a thread; lagent
|
|
39
|
+
* applies it nowhere itself.
|
|
40
|
+
*/
|
|
41
|
+
export declare function repositoryReadRoots(cwd: string): string[];
|
|
42
|
+
/**
|
|
43
|
+
* `path` with its symbolic links resolved, the part that does not exist yet kept as named; the
|
|
44
|
+
* lexical path when it cannot be resolved, such as behind a directory that may not be listed.
|
|
45
|
+
*/
|
|
46
|
+
export declare function physical(path: string): string;
|
|
47
|
+
/** What a repository's `HEAD` names: a branch, or a commit it is detached at. */
|
|
48
|
+
export type GitHead = {
|
|
49
|
+
readonly kind: 'branch';
|
|
50
|
+
readonly name: string;
|
|
51
|
+
} | {
|
|
52
|
+
readonly kind: 'detached';
|
|
53
|
+
readonly commit: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* The `HEAD` of the worktree `repository` locates, read from its git directory without running git:
|
|
57
|
+
* a branch by its short name (`ref: refs/heads/main` is `main`, another ref its full name), a commit
|
|
58
|
+
* id as a detached head at its first seven digits; `null` when it cannot be read or says neither.
|
|
59
|
+
*/
|
|
60
|
+
export declare function readHead(repository: RepositoryLocation): GitHead | null;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { InvocationContext } from '../loop/index.js';
|
|
2
|
+
import type { ThreadEnvironment } from '../models/index.js';
|
|
3
|
+
import type { DeepReadonly } from '../util/json.js';
|
|
4
|
+
/**
|
|
5
|
+
* What a file tool does with a path. `write` is for anything that can modify what the path reaches.
|
|
6
|
+
*/
|
|
7
|
+
export type PathAccess = 'read' | 'write';
|
|
8
|
+
/**
|
|
9
|
+
* Where one call of a tool may reach: the thread's workspace and the application's data directory,
|
|
10
|
+
* and for a read also the read roots its environment names.
|
|
11
|
+
*
|
|
12
|
+
* Every comparison is made between real locations: the roots and each path checked against them
|
|
13
|
+
* have their symlinks resolved first, so a link inside a root cannot carry a read or a write
|
|
14
|
+
* outside it. A path that does not exist yet, such as a file about to be created, is located
|
|
15
|
+
* through its nearest existing ancestor, and a dangling link through its target.
|
|
16
|
+
*/
|
|
17
|
+
export type PathBoundary = {
|
|
18
|
+
/** The thread's working directory, which relative paths are resolved against. */
|
|
19
|
+
readonly cwd: string;
|
|
20
|
+
/**
|
|
21
|
+
* `pathValue` resolved against the cwd: the path a tool then opens, without its symlinks
|
|
22
|
+
* resolved, so results name what the model named. Throws when its real location is outside
|
|
23
|
+
* every root.
|
|
24
|
+
*/
|
|
25
|
+
resolve(pathValue: string): string;
|
|
26
|
+
/** Whether the real location of an absolute path is inside a root: for the entries a walk finds. */
|
|
27
|
+
contains(path: string): Promise<boolean>;
|
|
28
|
+
/** `contains` for a caller that cannot await, such as a step listener; tools use `contains`. */
|
|
29
|
+
containsSync(path: string): boolean;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* What a boundary is drawn from: a tool call's context, or the same facts about a thread for a
|
|
33
|
+
* plugin that reads on the thread's behalf, as `agentsMd` does.
|
|
34
|
+
*/
|
|
35
|
+
export type BoundaryScope = Pick<InvocationContext, 'ctx'> & {
|
|
36
|
+
readonly environment: DeepReadonly<ThreadEnvironment>;
|
|
37
|
+
};
|
|
38
|
+
export declare function pathBoundary(context: BoundaryScope, access: PathAccess): PathBoundary;
|
|
39
|
+
/**
|
|
40
|
+
* Where an absolute path really is: its symlinks resolved, for a path that exists. For one that
|
|
41
|
+
* does not, its nearest existing ancestor's real location with the rest appended, following a
|
|
42
|
+
* dangling link to its target, since opening it to write would create that target. What the
|
|
43
|
+
* boundary compares, and what a tool that must tell two names of one file apart compares too.
|
|
44
|
+
*/
|
|
45
|
+
export declare function realLocation(path: string): string;
|
|
46
|
+
/** `realLocation` without blocking the event loop, for a walk that checks every entry it finds. */
|
|
47
|
+
export declare function realLocationAsync(path: string): Promise<string>;
|
|
48
|
+
/** Whether `candidate` is `root` or a path inside it, by whole segments: `/a/bc` is not inside `/a/b`. Both normalized. */
|
|
49
|
+
export declare const isWithin: (candidate: string, root: string) => boolean;
|
|
50
|
+
/** A path as results show it: relative to the cwd inside it, absolute outside it. */
|
|
51
|
+
export declare function displayPath(cwd: string, path: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* `path` normalized, refused when relative: a relative path would mean the process's directory,
|
|
54
|
+
* which is the host's to choose. `what` names the setting in the error.
|
|
55
|
+
*/
|
|
56
|
+
export declare function absolutePath(path: string, what: string): string;
|