lastlight 0.5.1 → 0.6.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/.claude-plugin/marketplace.json +14 -0
- package/README.md +39 -0
- package/agent-context/rules.md +0 -38
- package/agent-context/soul.md +0 -11
- package/dist/cli.js +24 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +3 -3
- package/dist/config.js.map +1 -1
- package/dist/engine/agent-executor.d.ts +2 -139
- package/dist/engine/agent-executor.js +76 -996
- package/dist/engine/agent-executor.js.map +1 -1
- package/dist/engine/executors/backends.d.ts +41 -0
- package/dist/engine/executors/backends.js +541 -0
- package/dist/engine/executors/backends.js.map +1 -0
- package/dist/engine/executors/shared.d.ts +189 -0
- package/dist/engine/executors/shared.js +612 -0
- package/dist/engine/executors/shared.js.map +1 -0
- package/dist/sandbox/index.d.ts +1 -1
- package/dist/sandbox/index.js +1 -1
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/smol.d.ts +162 -0
- package/dist/sandbox/smol.integration.test.d.ts +1 -0
- package/dist/sandbox/smol.integration.test.js +130 -0
- package/dist/sandbox/smol.integration.test.js.map +1 -0
- package/dist/sandbox/smol.js +485 -0
- package/dist/sandbox/smol.js.map +1 -0
- package/dist/skills-install.d.ts +12 -0
- package/dist/skills-install.js +179 -0
- package/dist/skills-install.js.map +1 -0
- package/package.json +4 -2
- package/plugins/lastlight/.claude-plugin/plugin.json +12 -0
- package/plugins/lastlight/README.md +44 -0
- package/plugins/lastlight/skills/lastlight-client/SKILL.md +82 -0
- package/plugins/lastlight/skills/lastlight-evals/SKILL.md +130 -0
- package/plugins/lastlight/skills/lastlight-evals/references/instance-schema.md +84 -0
- package/plugins/lastlight/skills/lastlight-evals/references/models-json.md +42 -0
- package/plugins/lastlight/skills/lastlight-overlay/SKILL.md +72 -0
- package/plugins/lastlight/skills/lastlight-overlay/references/forking.md +55 -0
- package/plugins/lastlight/skills/lastlight-overlay/references/overlay-layout.md +52 -0
- package/plugins/lastlight/skills/lastlight-server/SKILL.md +124 -0
- package/plugins/lastlight/skills/lastlight-server/references/env-schema.md +103 -0
- package/plugins/lastlight/skills/lastlight-server/references/operations.md +60 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import type { RunResult, ThinkingLevel } from "agentic-pi";
|
|
2
|
+
import { type ExecutorConfig, type ExecutionResult, type ExtensionStatusMap, type SkillsStatus } from "../profiles.js";
|
|
3
|
+
import { AgenticShim } from "../event-shim.js";
|
|
4
|
+
import { BuildAssetStore, type BuildAssetRef } from "../../state/build-assets.js";
|
|
5
|
+
/**
|
|
6
|
+
* Shared building blocks for the per-backend executors
|
|
7
|
+
* ({@link ../executors/backends.ts}). These have NO dependency on the
|
|
8
|
+
* executors or the dispatcher, so the import DAG stays acyclic:
|
|
9
|
+
* shared → backends → agent-executor.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEFAULT_MODEL = "anthropic/claude-sonnet-4-6";
|
|
12
|
+
export declare const DOCKER_WORKSPACE_DIR = "/home/agent/workspace";
|
|
13
|
+
export declare const SKILL_BUNDLE_ROOT = ".lastlight-skills";
|
|
14
|
+
export declare const THINKING_LEVELS: ReadonlySet<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Stage this phase's declared skills into a per-phase bundle directory at
|
|
17
|
+
* `<workspaceRoot>/.lastlight-skills/<phaseKey>/<basename>/` and return the
|
|
18
|
+
* staged skill dirs, so the caller can point pi at them explicitly (via
|
|
19
|
+
* `--skill` for docker or `skillPaths` for the in-process backends). Each
|
|
20
|
+
* skill is a directory containing SKILL.md plus any `scripts/` / `references/`
|
|
21
|
+
* / `assets/` — the whole tree comes along.
|
|
22
|
+
*
|
|
23
|
+
* Keyed by phase so concurrent phases in one workspace never touch each
|
|
24
|
+
* other's bundle: only the phase's own `<phaseKey>` subtree is cleared, so a
|
|
25
|
+
* clean slate per phase doesn't disturb a sibling phase mid-run.
|
|
26
|
+
*
|
|
27
|
+
* `mode` controls how each skill lands:
|
|
28
|
+
* - "symlink": one symlink per skill → host source. gondolin/none, where pi
|
|
29
|
+
* reads skill files host-side / through the cwd mount. Zero-copy.
|
|
30
|
+
* - "copy": recursive copy. docker, where the agent's tools run inside the
|
|
31
|
+
* container and host symlink targets wouldn't resolve; the copy lands
|
|
32
|
+
* under the bind-mounted workspace.
|
|
33
|
+
*
|
|
34
|
+
* Returns `undefined` when the phase declares no skills (after clearing its
|
|
35
|
+
* bundle), so a phase with no `skills:` gets no catalogue at all.
|
|
36
|
+
*/
|
|
37
|
+
export declare function stageSkillBundle(workspaceRoot: string, phaseKey: string, skillPaths: string[] | undefined, mode: "symlink" | "copy"): string[] | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Sanitized per-phase key for the skill bundle directory. Phase name first
|
|
40
|
+
* (unique even for loop iterations like `reviewer_fix_1`), then workflow name,
|
|
41
|
+
* then a constant fallback — so the bundle is always isolated per phase.
|
|
42
|
+
*/
|
|
43
|
+
export declare function skillBundleKey(config: ExecutorConfig): string;
|
|
44
|
+
/**
|
|
45
|
+
* Add `entry` to a checkout's local `.git/info/exclude` (idempotent) so the
|
|
46
|
+
* agent's own `git add`/`commit` can never pick it up. This file lives inside
|
|
47
|
+
* `.git/` — it is never tracked, committed, or pushed, and it leaves the repo's
|
|
48
|
+
* real `.gitignore` untouched; the exclusion applies only to this ephemeral
|
|
49
|
+
* sandbox checkout. Used for the gondolin backend, where the skill bundle must
|
|
50
|
+
* be staged under cwd (the only mounted dir) rather than as an out-of-repo
|
|
51
|
+
* sibling. No-op when `repoDir` isn't a git checkout (e.g. the workspace root).
|
|
52
|
+
*/
|
|
53
|
+
export declare function excludeFromGit(repoDir: string, entry: string): void;
|
|
54
|
+
export interface ServerArtifacts {
|
|
55
|
+
store: BuildAssetStore;
|
|
56
|
+
ref: BuildAssetRef;
|
|
57
|
+
/** Host path to `<repo>/.lastlight/<issueKey>` (the staged doc dir). */
|
|
58
|
+
dir: string;
|
|
59
|
+
/** Host path to the repo checkout root. */
|
|
60
|
+
repoDir: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Resolve the server-mode artifact context for a run, or undefined when not in
|
|
64
|
+
* server mode (the default — the whole seam is then skipped and behaviour is
|
|
65
|
+
* byte-for-byte repo mode). `hostRepoDir` is the host-visible repo checkout
|
|
66
|
+
* (for docker that's the bind-mounted workspace path, not the in-container one).
|
|
67
|
+
*/
|
|
68
|
+
export declare function serverArtifacts(config: ExecutorConfig, hostRepoDir: string): ServerArtifacts | undefined;
|
|
69
|
+
/** Stage stored docs into the workspace + exclude the dir from git (server mode). */
|
|
70
|
+
export declare function stageArtifactsIn(art: ServerArtifacts | undefined): void;
|
|
71
|
+
/** Persist docs the phase wrote back to the store (server mode). */
|
|
72
|
+
export declare function harvestArtifactsOut(art: ServerArtifacts | undefined): void;
|
|
73
|
+
export declare class RunResultAccumulator {
|
|
74
|
+
private sessionId?;
|
|
75
|
+
private finalText;
|
|
76
|
+
private agentEnded;
|
|
77
|
+
private toolErrors;
|
|
78
|
+
private maxStepsReached;
|
|
79
|
+
private lastToolError?;
|
|
80
|
+
private lastAssistantHadToolCall;
|
|
81
|
+
private fatalError?;
|
|
82
|
+
private snapshotStats?;
|
|
83
|
+
private messages;
|
|
84
|
+
private assistantMessages;
|
|
85
|
+
private userMessages;
|
|
86
|
+
private toolCalls;
|
|
87
|
+
private toolResults;
|
|
88
|
+
private msgInput;
|
|
89
|
+
private msgOutput;
|
|
90
|
+
private msgCacheRead;
|
|
91
|
+
private msgCacheWrite;
|
|
92
|
+
private msgCost;
|
|
93
|
+
private ext;
|
|
94
|
+
private skillsRaw?;
|
|
95
|
+
feed(r: Record<string, unknown>): void;
|
|
96
|
+
private accumulateUsage;
|
|
97
|
+
/** Stats summed from per-message usage, or undefined if none was seen. */
|
|
98
|
+
private accumulatedStats;
|
|
99
|
+
/**
|
|
100
|
+
* Prefer the per-message accumulation (compaction-proof) over pi's
|
|
101
|
+
* terminal `usage_snapshot`. Fall back to the snapshot only when the
|
|
102
|
+
* accumulation carries no token data — e.g. a provider that doesn't
|
|
103
|
+
* report per-message usage — so a non-compacted snapshot still wins.
|
|
104
|
+
*/
|
|
105
|
+
bestStats(): RunResult["stats"] | undefined;
|
|
106
|
+
build(exitCode: 0 | 1 | 2): RunResult;
|
|
107
|
+
/**
|
|
108
|
+
* Normalized extension status captured from `extension_status` events
|
|
109
|
+
* (file-search / github / web-search), or undefined if none reported.
|
|
110
|
+
* Decoupled from agentic-pi's `RunResult` type, which lags the runtime —
|
|
111
|
+
* the docker sandbox's agentic-pi emits file-search even when the harness's
|
|
112
|
+
* pinned `RunResult` type doesn't yet declare it.
|
|
113
|
+
*/
|
|
114
|
+
extensions(): ExtensionStatusMap | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* Normalized skill-loading status from the gated `skills_status` event, or
|
|
117
|
+
* undefined if none was reported (agentic-pi suppresses it on a run that
|
|
118
|
+
* configured no skills and discovered none). The skill-loading counterpart
|
|
119
|
+
* to {@link extensions}.
|
|
120
|
+
*/
|
|
121
|
+
skills(): SkillsStatus | undefined;
|
|
122
|
+
/**
|
|
123
|
+
* The last tool result that came back with `isError: true`, including the
|
|
124
|
+
* failure text — or undefined if no tool errored. This is what turns a
|
|
125
|
+
* bare `error_tool` stop reason into a human-readable cause.
|
|
126
|
+
*/
|
|
127
|
+
toolError(): {
|
|
128
|
+
tool?: string;
|
|
129
|
+
message: string;
|
|
130
|
+
} | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* True iff the run's final assistant turn ended on a tool call — meaning
|
|
133
|
+
* the agent intended to keep going but the loop stopped before it could
|
|
134
|
+
* respond to the tool result and write its answer. The signal a run was
|
|
135
|
+
* truncated (step-limit) rather than genuinely finished.
|
|
136
|
+
*/
|
|
137
|
+
endedOnToolCall(): boolean;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Detect a provider account error (out of credit, quota, rate-limited, bad key)
|
|
141
|
+
* that pi may have surfaced as plain text rather than a hard failure.
|
|
142
|
+
*
|
|
143
|
+
* Critically, on a **successful** run we scan ONLY the genuine provider-error
|
|
144
|
+
* channel (`agentErrorMessage`, which `extractAgentError` already turns into a
|
|
145
|
+
* non-success stopReason when set — so it's empty here). The agent's own output
|
|
146
|
+
* (`finalText`) and tool results (`fatalError`, `toolError`) are NOT scanned on
|
|
147
|
+
* success: a legitimate `verify`/`qa-test` report or a `curl` probing a 401
|
|
148
|
+
* endpoint routinely contains "unauthorized" / "rate limit" as part of the task
|
|
149
|
+
* itself, and folding that in would wrongly fail a genuinely successful run
|
|
150
|
+
* (and drop its report). Only on a failed run do we fold those in to label why.
|
|
151
|
+
*/
|
|
152
|
+
export declare function detectAccountError(opts: {
|
|
153
|
+
success: boolean;
|
|
154
|
+
fatalErrorMessage?: string;
|
|
155
|
+
agentErrorMessage?: string;
|
|
156
|
+
finalText?: string;
|
|
157
|
+
toolErrorText?: string;
|
|
158
|
+
}): boolean;
|
|
159
|
+
export declare function finalizeFromRunResult(result: RunResult, _prompt: string, shim: AgenticShim, startTime: number, extensions?: ExtensionStatusMap, skills?: SkillsStatus, toolError?: {
|
|
160
|
+
tool?: string;
|
|
161
|
+
message: string;
|
|
162
|
+
}, endedOnToolCall?: boolean): ExecutionResult;
|
|
163
|
+
export declare function mapStopReason(result: RunResult): string;
|
|
164
|
+
/**
|
|
165
|
+
* Scan agent_end's messages for a failed assistant turn. pi-agent-core's
|
|
166
|
+
* `handleRunFailure` catches provider errors, synthesizes an assistant
|
|
167
|
+
* message with stopReason "error"/"aborted" + errorMessage, and emits a
|
|
168
|
+
* normal agent_end — so the only signal that the run actually failed
|
|
169
|
+
* lives on the last assistant message.
|
|
170
|
+
*/
|
|
171
|
+
export declare function extractAgentError(result: RunResult): {
|
|
172
|
+
stopReason: string;
|
|
173
|
+
errorMessage: string;
|
|
174
|
+
} | undefined;
|
|
175
|
+
export declare function coerceThinking(raw: string | undefined): ThinkingLevel | undefined;
|
|
176
|
+
export declare function resolveSessionsDir(config: ExecutorConfig): string;
|
|
177
|
+
export declare function emptyResult(stopReason: string, durationMs: number): {
|
|
178
|
+
finalText: string;
|
|
179
|
+
turns: number;
|
|
180
|
+
costUsd: number;
|
|
181
|
+
inputTokens: number;
|
|
182
|
+
outputTokens: number;
|
|
183
|
+
cacheReadInputTokens: number;
|
|
184
|
+
cacheCreationInputTokens: number;
|
|
185
|
+
stopReason: string;
|
|
186
|
+
durationMs: number;
|
|
187
|
+
};
|
|
188
|
+
/** Splice values into process.env for the duration of a sync block. */
|
|
189
|
+
export declare function applyEnv(env: Record<string, string>): () => void;
|