@yaag/cli 0.9.0 → 0.11.0
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/assets/types/runtime/agent/agent-compaction.d.ts +29 -0
- package/assets/types/runtime/agent/agent-usage.d.ts +8 -0
- package/assets/types/runtime/agent/agent.d.ts +11 -2
- package/assets/types/runtime/agent/fork.d.ts +43 -0
- package/assets/types/runtime/agent/index.d.ts +1 -0
- package/assets/types/runtime/agent/spawn-open.d.ts +31 -0
- package/assets/types/runtime/agent/spawn-parent.d.ts +11 -0
- package/assets/types/runtime/agent/spawn-request.d.ts +9 -1
- package/assets/types/runtime/agent/spawn.d.ts +1 -1
- package/assets/types/runtime/cassette/cassette-replay.d.ts +9 -1
- package/assets/types/runtime/cassette/cassette-schema.d.ts +23 -0
- package/assets/types/runtime/cassette/cassette.d.ts +27 -1
- package/assets/types/runtime/cassette/index.d.ts +1 -1
- package/assets/types/runtime/cassette/replay-divergence.d.ts +3 -2
- package/assets/types/runtime/errors.d.ts +1 -1
- package/assets/types/runtime/events.d.ts +33 -0
- package/assets/types/runtime/index.d.ts +5 -5
- package/assets/types/runtime/summary/index.d.ts +1 -1
- package/assets/types/runtime/summary/summary-agent.d.ts +29 -2
- package/assets/types/runtime/summary/summary.d.ts +3 -1
- package/assets/types/runtime/transport/fake-transport.d.ts +8 -1
- package/assets/types/runtime/transport/index.d.ts +2 -2
- package/assets/types/runtime/transport/pi-state.d.ts +8 -1
- package/assets/types/runtime/transport/transport.d.ts +63 -0
- package/assets/types/runtime/types.d.ts +51 -1
- package/package.json +3 -3
- package/src/terminal/render.ts +9 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { EventSink } from "../events.ts";
|
|
2
|
+
import type { AgentTransport, CompactionResult, Connection } from "../transport/index.ts";
|
|
3
|
+
import type { AgentUsage } from "./agent-usage.ts";
|
|
4
|
+
/** One compaction of one Agent's context (ADR-0043). */
|
|
5
|
+
export interface CompactionExchange {
|
|
6
|
+
readonly agent: string;
|
|
7
|
+
readonly connection: Connection;
|
|
8
|
+
readonly transport: AgentTransport;
|
|
9
|
+
/** Monotonic per Agent, from 0. */
|
|
10
|
+
readonly index: number;
|
|
11
|
+
/** Settled Asks of this Agent at the compaction point. */
|
|
12
|
+
readonly afterAsks: number;
|
|
13
|
+
/** pi `customInstructions`; the text never rides the wire (ticket 09). */
|
|
14
|
+
readonly instructions?: string;
|
|
15
|
+
readonly emit: EventSink;
|
|
16
|
+
readonly usage: AgentUsage;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Compacts one Agent's context and reports what the summary call cost.
|
|
20
|
+
*
|
|
21
|
+
* Playback answers from the Cassette and emits the same event, but folds no
|
|
22
|
+
* usage: a replayed Run never reports live accounting.
|
|
23
|
+
*/
|
|
24
|
+
export declare function compactAgent(exchange: CompactionExchange): Promise<CompactionResult>;
|
|
25
|
+
/**
|
|
26
|
+
* Identity of one compaction: where it sits in the Agent's conversation, and
|
|
27
|
+
* whether the program steered it. The instruction text is hashed, never stored.
|
|
28
|
+
*/
|
|
29
|
+
export declare function compactionHash(afterAsks: number, instructions: string | undefined): string;
|
|
@@ -13,4 +13,12 @@ export declare class AgentUsage {
|
|
|
13
13
|
constructor(report: (snapshot: AgentUsageSnapshot) => void);
|
|
14
14
|
/** Observes one raw Agent frame and reports after each valid assistant completion. */
|
|
15
15
|
observe(frame: Frame): void;
|
|
16
|
+
/**
|
|
17
|
+
* Folds one completion yaag observed outside the frame stream, and reports.
|
|
18
|
+
*
|
|
19
|
+
* A compaction's summary call is the only such completion today: pi answers
|
|
20
|
+
* it on the `compact` response instead of an assistant `message_end`, so the
|
|
21
|
+
* live accounting would lose that spend (ADR-0043).
|
|
22
|
+
*/
|
|
23
|
+
add(usage: AgentUsageSnapshot): void;
|
|
16
24
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Static, TSchema } from "typebox";
|
|
2
2
|
import type { EventSink } from "../events.ts";
|
|
3
3
|
import type { ModelErrorHistory, ModelResolution } from "../model/index.ts";
|
|
4
|
-
import type { AgentStats, AgentTransport } from "../transport/index.ts";
|
|
5
|
-
import type { AskOptions, Handle, ResolvedSpawnOptions, StructuredAskOptions } from "../types.ts";
|
|
4
|
+
import type { AgentStats, AgentTransport, CompactionResult } from "../transport/index.ts";
|
|
5
|
+
import type { AskOptions, ForkOptions, Handle, ResolvedSpawnOptions, StructuredAskOptions } from "../types.ts";
|
|
6
|
+
import type { ForkSpawner } from "./fork.ts";
|
|
6
7
|
/** The mid-Ask Model Resolution one Agent's spawn handed it (ADR-0038). */
|
|
7
8
|
export interface AgentModelFallback {
|
|
8
9
|
readonly resolution: ModelResolution;
|
|
@@ -24,6 +25,10 @@ export interface AgentOptions {
|
|
|
24
25
|
* Absent when the spawn named no candidate: there is nothing to fall back from.
|
|
25
26
|
*/
|
|
26
27
|
readonly modelFallback?: AgentModelFallback;
|
|
28
|
+
/** pi's session file for this Agent; a fork copies it. Absent during playback. */
|
|
29
|
+
readonly sessionFile?: string;
|
|
30
|
+
/** Opens a fork of this Agent through the Run's spawn gate (ADR-0044). */
|
|
31
|
+
readonly fork?: ForkSpawner;
|
|
27
32
|
/** Definition-owned defaults merged below explicit per-Ask options. */
|
|
28
33
|
readonly askDefaults?: AskOptions;
|
|
29
34
|
/** Definition identity recorded on its Asks, outside replay identity. */
|
|
@@ -46,6 +51,10 @@ export declare class Agent implements Handle {
|
|
|
46
51
|
get model(): string;
|
|
47
52
|
ask<Schema extends TSchema>(prompt: string, options: StructuredAskOptions<Schema>): Promise<Static<Schema>>;
|
|
48
53
|
ask(prompt: string, options?: AskOptions): Promise<string>;
|
|
54
|
+
/** Replaces this Agent's context with a summary of it (ADR-0043). */
|
|
55
|
+
compact(instructions?: string): Promise<CompactionResult>;
|
|
56
|
+
/** Spawns a new Agent from a copy of this Agent's session (ADR-0044). */
|
|
57
|
+
fork(overrides?: ForkOptions): Promise<Handle>;
|
|
49
58
|
/** True when the Agent was killed mid-Ask, so its cost is a floor (ADR-0012). */
|
|
50
59
|
get incomplete(): boolean;
|
|
51
60
|
/** Shuts the Agent down and reports its cost. Idempotent. */
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { WorktreeResolution } from "../transport/index.ts";
|
|
2
|
+
import type { ForkOptions, Handle, ResolvedSpawnOptions, SpawnOptions } from "../types.ts";
|
|
3
|
+
/** What one Agent hands the spawn gate when it is forked (ADR-0044). */
|
|
4
|
+
export interface ForkSource {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
/** The options the source settled on; the verbatim inheritance base. */
|
|
7
|
+
readonly spawnOptions: ResolvedSpawnOptions;
|
|
8
|
+
/** pi's session file for the source; a fork without one is refused. */
|
|
9
|
+
readonly sessionFile: string | undefined;
|
|
10
|
+
readonly worktree: WorktreeResolution | undefined;
|
|
11
|
+
/** Settled Asks of the source at the fork point. */
|
|
12
|
+
readonly settledAsks: number;
|
|
13
|
+
/** The source Handle itself, which becomes the fork's default Parent Link. */
|
|
14
|
+
readonly handle: Handle;
|
|
15
|
+
}
|
|
16
|
+
/** Opens one fork. The spawn gate owns it, so a fork walks the normal spawn path. */
|
|
17
|
+
export type ForkSpawner = (source: ForkSource, overrides?: ForkOptions) => Promise<Handle>;
|
|
18
|
+
/** Spawn identity and launch facts that only a fork carries. */
|
|
19
|
+
export interface ForkIdentity {
|
|
20
|
+
readonly forkOf: string;
|
|
21
|
+
readonly forkAsks: number;
|
|
22
|
+
/** The session pi copies with `--fork`; machine-specific, never identity. */
|
|
23
|
+
readonly forkSession: string;
|
|
24
|
+
readonly worktreeFrom?: WorktreeResolution;
|
|
25
|
+
}
|
|
26
|
+
/** One fork request: what to spawn, whose child it is, and whether to compact it. */
|
|
27
|
+
export interface ForkRequest {
|
|
28
|
+
/** Inherited options with the overrides applied; never carries `name`. */
|
|
29
|
+
readonly spawnOptions: SpawnOptions;
|
|
30
|
+
/** The raw Parent Link, defaulting to the fork source. */
|
|
31
|
+
readonly parent: unknown;
|
|
32
|
+
readonly fork: ForkIdentity;
|
|
33
|
+
readonly compact: boolean | string | undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Merges a fork source with explicit overrides into one spawn request.
|
|
37
|
+
*
|
|
38
|
+
* Inheritance is verbatim, with two deliberate exceptions: `name` is dropped,
|
|
39
|
+
* so the child gets a fresh auto-name unless the overrides give it one, and
|
|
40
|
+
* `compact` never reaches the spawn options, because it is a fork verb rather
|
|
41
|
+
* than a property of the Agent.
|
|
42
|
+
*/
|
|
43
|
+
export declare function forkRequest(source: ForkSource, overrides?: ForkOptions): ForkRequest;
|
|
@@ -4,4 +4,5 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { Agent } from "./agent.ts";
|
|
6
6
|
export { type AgentConfig, type AgentDefinition, agentDefinitionConfig, defineAgent, isAgentDefinition, } from "./define-agent.ts";
|
|
7
|
+
export { type ForkSource, type ForkSpawner, forkRequest } from "./fork.ts";
|
|
7
8
|
export { makeSpawn } from "./spawn.ts";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AskOptions, Handle, SpawnOptions } from "../types.ts";
|
|
2
|
+
import type { ForkIdentity, ForkSpawner } from "./fork.ts";
|
|
3
|
+
import type { SpawnDependencies } from "./spawn.ts";
|
|
4
|
+
/** One request the open path serves: a plain spawn, or a fork of another Agent. */
|
|
5
|
+
export interface OpenAgentRequest {
|
|
6
|
+
/** Never carries `parent`: a Handle must not reach the recorded options. */
|
|
7
|
+
readonly spawnOptions: SpawnOptions;
|
|
8
|
+
/** The raw Parent Link option, validated by `resolveParent`. */
|
|
9
|
+
readonly parent: unknown;
|
|
10
|
+
readonly askDefaults: AskOptions | undefined;
|
|
11
|
+
/** Definition identity stays separate from a topology-overridden Agent name. */
|
|
12
|
+
readonly definitionName: string | undefined;
|
|
13
|
+
/** Present only for a fork; adds `origin: "fork"` and the `--fork` source. */
|
|
14
|
+
readonly fork?: ForkIdentity;
|
|
15
|
+
}
|
|
16
|
+
/** What the open path needs beyond the Run's spawn dependencies. */
|
|
17
|
+
export interface OpenAgentContext extends SpawnDependencies {
|
|
18
|
+
/** Agent names already allocated in this Run. */
|
|
19
|
+
readonly taken: Set<string>;
|
|
20
|
+
/** How an opened Agent forks itself later. */
|
|
21
|
+
readonly forkSpawner: ForkSpawner;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Opens one Agent: resolves extensions and a model, starts its transport, and
|
|
25
|
+
* emits `agent_spawn`.
|
|
26
|
+
*
|
|
27
|
+
* A fork walks this very path, so the Tool Contract probe, Model Resolution,
|
|
28
|
+
* the worktree wrapper and the Cassette identity cannot drift between a spawn
|
|
29
|
+
* and a fork (ADR-0044).
|
|
30
|
+
*/
|
|
31
|
+
export declare function openAgent(deps: OpenAgentContext, request: OpenAgentRequest): Promise<Handle>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Agent } from "./agent.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Resolves a Parent Link to the parent Agent's name.
|
|
4
|
+
*
|
|
5
|
+
* Only a Handle this Run already spawned is accepted, which is what makes a
|
|
6
|
+
* lineage cycle impossible by construction: a Handle exists only after its own
|
|
7
|
+
* spawn resolved. Liveness is deliberately not checked — a cleanly exited Agent
|
|
8
|
+
* remains a valid parent, because the link states tree position, not a
|
|
9
|
+
* dependency on a live process.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveParent(parent: unknown, agents: readonly Agent[]): string | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ModelSelection } from "../model/index.ts";
|
|
2
|
-
import type { OpenOptions } from "../transport/index.ts";
|
|
2
|
+
import type { OpenOptions, WorktreeResolution } from "../transport/index.ts";
|
|
3
3
|
import type { ResolvedSpawnOptions, SpawnOptions } from "../types.ts";
|
|
4
4
|
/** Everything one spawn needs to build its open request, before a model settles. */
|
|
5
5
|
export interface OpenRequestOptions {
|
|
@@ -8,6 +8,14 @@ export interface OpenRequestOptions {
|
|
|
8
8
|
readonly spawnOptions: SpawnOptions;
|
|
9
9
|
readonly resolvedExtensionPaths?: readonly string[];
|
|
10
10
|
readonly declaredExtensions?: readonly string[];
|
|
11
|
+
/** Resolved parent Agent name (Parent Link); spawn identity only, never argv. */
|
|
12
|
+
readonly parent?: string;
|
|
13
|
+
/** Fork facts (ADR-0044); the first three are spawn identity, the rest are not. */
|
|
14
|
+
readonly origin?: "fork";
|
|
15
|
+
readonly forkOf?: string;
|
|
16
|
+
readonly forkAsks?: number;
|
|
17
|
+
readonly forkSession?: string;
|
|
18
|
+
readonly worktreeFrom?: WorktreeResolution;
|
|
11
19
|
readonly sessionDir: string | undefined;
|
|
12
20
|
}
|
|
13
21
|
/**
|
|
@@ -2,7 +2,7 @@ import type { ConfigExtension } from "../config/index.ts";
|
|
|
2
2
|
import type { EventSink } from "../events.ts";
|
|
3
3
|
import type { RunContext } from "../run/index.ts";
|
|
4
4
|
import type { TransportFactory } from "../transport/index.ts";
|
|
5
|
-
import { Agent } from "./agent.ts";
|
|
5
|
+
import type { Agent } from "./agent.ts";
|
|
6
6
|
/** Dependencies for one Run's Agent-spawn gate. */
|
|
7
7
|
export interface SpawnDependencies {
|
|
8
8
|
readonly factory: TransportFactory;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentStats, AskMarker, AskPlayback, Frame } from "../transport/index.ts";
|
|
1
|
+
import type { AgentStats, AskMarker, AskPlayback, CompactionMarker, CompactionPlayback, Frame } from "../transport/index.ts";
|
|
2
2
|
import type { CassetteAgent } from "./cassette.ts";
|
|
3
3
|
/**
|
|
4
4
|
* Replays one Cassette Agent's frame streams at the transport seam.
|
|
@@ -19,6 +19,14 @@ export declare class CassetteReplay {
|
|
|
19
19
|
frames(): AsyncIterable<Frame>;
|
|
20
20
|
/** Moves playback to an Ask that its caller has already identity-checked. */
|
|
21
21
|
beginAsk(marker: AskMarker): AskPlayback;
|
|
22
|
+
/**
|
|
23
|
+
* Moves playback to a compaction its caller has already identity-checked.
|
|
24
|
+
*
|
|
25
|
+
* A compaction lives between two Asks, and `beginAsk` never switches the
|
|
26
|
+
* cursors back to the Agent-level streams, so the recorded compaction owns
|
|
27
|
+
* its own streams (ADR-0043).
|
|
28
|
+
*/
|
|
29
|
+
beginCompaction(marker: CompactionMarker): CompactionPlayback;
|
|
22
30
|
/** Ends the stream cleanly, allowing a caller to switch to another source. */
|
|
23
31
|
finish(): void;
|
|
24
32
|
}
|
|
@@ -31,6 +31,10 @@ export declare const CassetteSchema: Type.TObject<{
|
|
|
31
31
|
cwd: Type.TString;
|
|
32
32
|
worktree: Type.TOptional<Type.TLiteral<true>>;
|
|
33
33
|
declaredExtensions: Type.TOptional<Type.TArray<Type.TString>>;
|
|
34
|
+
parent: Type.TOptional<Type.TString>;
|
|
35
|
+
origin: Type.TOptional<Type.TLiteral<"fork">>;
|
|
36
|
+
forkOf: Type.TOptional<Type.TString>;
|
|
37
|
+
forkAsks: Type.TOptional<Type.TNumber>;
|
|
34
38
|
}>;
|
|
35
39
|
model: Type.TString;
|
|
36
40
|
sessionFile: Type.TOptional<Type.TString>;
|
|
@@ -99,6 +103,25 @@ export declare const CassetteSchema: Type.TObject<{
|
|
|
99
103
|
}>>;
|
|
100
104
|
recovered: Type.TOptional<Type.TLiteral<true>>;
|
|
101
105
|
}>>;
|
|
106
|
+
compactions: Type.TOptional<Type.TArray<Type.TObject<{
|
|
107
|
+
index: Type.TNumber;
|
|
108
|
+
hash: Type.TString;
|
|
109
|
+
afterAsks: Type.TNumber;
|
|
110
|
+
result: Type.TOptional<Type.TObject<{
|
|
111
|
+
tokensBefore: Type.TUnion<[Type.TNull, Type.TNumber]>;
|
|
112
|
+
tokensAfter: Type.TUnion<[Type.TNull, Type.TNumber]>;
|
|
113
|
+
tokens: Type.TUnion<[Type.TNull, Type.TObject<{
|
|
114
|
+
input: Type.TNumber;
|
|
115
|
+
output: Type.TNumber;
|
|
116
|
+
cacheRead: Type.TNumber;
|
|
117
|
+
cacheWrite: Type.TNumber;
|
|
118
|
+
total: Type.TNumber;
|
|
119
|
+
}>]>;
|
|
120
|
+
cost: Type.TUnion<[Type.TNull, Type.TNumber]>;
|
|
121
|
+
}>>;
|
|
122
|
+
sentFrames: Type.TArray<Type.TUnsafe<Frame>>;
|
|
123
|
+
receivedFrames: Type.TArray<Type.TUnsafe<Frame>>;
|
|
124
|
+
}>>>;
|
|
102
125
|
stats: Type.TObject<{
|
|
103
126
|
tokens: Type.TUnion<[Type.TNull, Type.TObject<{
|
|
104
127
|
input: Type.TNumber;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CanonicalJsonObject } from "../ask-contract/index.ts";
|
|
2
2
|
import type { AskLimitOutcome, AskStalledOutcome } from "../errors.ts";
|
|
3
3
|
import type { RunOutcome } from "../events.ts";
|
|
4
|
-
import type { AgentStats, AskCompletion, AskInvalidOutputPlayback, AskMarker, AskMarkerContext, Frame, OpenOptions, WorktreeResolution } from "../transport/index.ts";
|
|
4
|
+
import type { AgentStats, AskCompletion, AskInvalidOutputPlayback, AskMarker, AskMarkerContext, CompactionMarker, CompactionResult, Frame, OpenOptions, WorktreeResolution } from "../transport/index.ts";
|
|
5
5
|
import type { ThinkingLevel } from "../types.ts";
|
|
6
6
|
/** The Cassette format this runtime writes; the loader also reads version 1. */
|
|
7
7
|
export declare const CASSETTE_VERSION: 2;
|
|
@@ -45,8 +45,21 @@ export interface CassetteAgent {
|
|
|
45
45
|
readonly sentFrames: readonly Frame[];
|
|
46
46
|
readonly receivedFrames: readonly Frame[];
|
|
47
47
|
readonly asks: readonly CassetteAsk[];
|
|
48
|
+
/** Compactions between this Agent's Asks; absent for an Agent that compacted none. */
|
|
49
|
+
readonly compactions?: readonly CassetteCompaction[];
|
|
48
50
|
readonly stats: AgentStats;
|
|
49
51
|
}
|
|
52
|
+
/** The frames attributed to one compaction marker (ADR-0043). */
|
|
53
|
+
export interface CassetteCompaction {
|
|
54
|
+
readonly index: number;
|
|
55
|
+
readonly hash: string;
|
|
56
|
+
/** Settled Asks of this Agent at the compaction point. */
|
|
57
|
+
readonly afterAsks: number;
|
|
58
|
+
/** What the recorded compaction reported; absent when the exchange failed. */
|
|
59
|
+
readonly result?: CompactionResult;
|
|
60
|
+
readonly sentFrames: readonly Frame[];
|
|
61
|
+
readonly receivedFrames: readonly Frame[];
|
|
62
|
+
}
|
|
50
63
|
/** Behavioural identity supplied when opening a recorded Agent. */
|
|
51
64
|
export interface CassetteSpawn {
|
|
52
65
|
readonly name: string;
|
|
@@ -72,6 +85,17 @@ export interface CassetteSpawn {
|
|
|
72
85
|
* across machines (ADR-0040). Absent when the Agent ran no extension.
|
|
73
86
|
*/
|
|
74
87
|
readonly declaredExtensions?: readonly string[];
|
|
88
|
+
/**
|
|
89
|
+
* Resolved name of the Agent named as this Agent's parent (Parent Link).
|
|
90
|
+
* Part of spawn identity; absent for a root Agent and for older Cassettes.
|
|
91
|
+
*/
|
|
92
|
+
readonly parent?: string;
|
|
93
|
+
/** How the Agent came to be; absent means an ordinary spawn. Spawn identity. */
|
|
94
|
+
readonly origin?: "fork";
|
|
95
|
+
/** Name of the Agent this one was forked from. Spawn identity. */
|
|
96
|
+
readonly forkOf?: string;
|
|
97
|
+
/** Settled Asks of the fork source at the fork point. Spawn identity. */
|
|
98
|
+
readonly forkAsks?: number;
|
|
75
99
|
}
|
|
76
100
|
/** The frames attributed to one Ask marker. */
|
|
77
101
|
export interface CassetteAsk {
|
|
@@ -117,6 +141,8 @@ export interface CassetteRecorder {
|
|
|
117
141
|
received(frame: Frame): void;
|
|
118
142
|
beginAsk(marker: AskMarker): void;
|
|
119
143
|
finishAsk(completion: AskCompletion): void;
|
|
144
|
+
beginCompaction(marker: CompactionMarker): void;
|
|
145
|
+
finishCompaction(result: CompactionResult | undefined): void;
|
|
120
146
|
closed(stats: AgentStats): void;
|
|
121
147
|
}
|
|
122
148
|
/** Collects a Cassette in memory; `executeRun` serializes it at Run settlement. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Public surface of the `cassette/` module: record, replay, checkpoint, and resume.
|
|
3
3
|
* Files inside this directory import each other directly.
|
|
4
4
|
*/
|
|
5
|
-
export { CASSETTE_VERSION, type Cassette, type CassetteAgent, type CassetteArtifact, type CassetteAsk, CassetteCollector, type CassetteGit, type CassetteRun, type CassetteSink, type CassetteSpawn, } from "./cassette.ts";
|
|
5
|
+
export { CASSETTE_VERSION, type Cassette, type CassetteAgent, type CassetteArtifact, type CassetteAsk, CassetteCollector, type CassetteCompaction, type CassetteGit, type CassetteRun, type CassetteSink, type CassetteSpawn, } from "./cassette.ts";
|
|
6
6
|
export { assertReplayable, interruptedResumeWarning, loadCassette } from "./cassette-loader.ts";
|
|
7
7
|
export { publishCassette } from "./cassette-publish.ts";
|
|
8
8
|
export { checkpointFileName, cleanStaleCheckpointTemp, resolveCheckpointDirectory, } from "./checkpoint-dir.ts";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { AskMarker, OpenOptions, RecordedSpawnSelection } from "../transport/index.ts";
|
|
1
|
+
import type { AskMarker, CompactionMarker, OpenOptions, RecordedSpawnSelection } from "../transport/index.ts";
|
|
2
2
|
import type { CassetteAgent, CassetteSpawn } from "./cassette.ts";
|
|
3
3
|
/** A pure description of the first strict replay identity mismatch. */
|
|
4
4
|
export interface ReplayMismatch {
|
|
5
|
-
readonly kind: "unexpected-spawn" | "spawn-options" | "changed-ask" | "extra-ask";
|
|
5
|
+
readonly kind: "unexpected-spawn" | "spawn-options" | "changed-ask" | "extra-ask" | "changed-compaction" | "extra-compaction";
|
|
6
6
|
readonly agent: string;
|
|
7
7
|
readonly index?: number;
|
|
8
8
|
readonly expectedHash: string;
|
|
@@ -14,6 +14,7 @@ export interface ReplayMismatch {
|
|
|
14
14
|
export declare const replayMismatch: {
|
|
15
15
|
spawn(expected: CassetteAgent | null, actual: OpenOptions): ReplayMismatch | null;
|
|
16
16
|
ask(agent: CassetteAgent, cursor: number, actual: AskMarker): ReplayMismatch | null;
|
|
17
|
+
compaction(agent: CassetteAgent, cursor: number, actual: CompactionMarker): ReplayMismatch | null;
|
|
17
18
|
};
|
|
18
19
|
/** Converts a detected mismatch into strict replay's public failure. */
|
|
19
20
|
export declare function strictReplay(mismatch: ReplayMismatch): never;
|
|
@@ -30,7 +30,7 @@ export interface ModelResolutionOutcome {
|
|
|
30
30
|
readonly modelErrors: readonly ModelError[];
|
|
31
31
|
}
|
|
32
32
|
/** Why an Ask, spawn, or Run failed. Programs may branch on this; most won't. */
|
|
33
|
-
export type YaagErrorCode = "AGENT_FAILED" | "AGENT_DIED" | "AGENT_BUSY" | "ASK_TIMEOUT" | "ASK_LIMIT" | "ASK_STALLED" | "ASK_INVALID_OUTPUT" | "ARGS_INVALID" | "CONFIG_INVALID" | "OPTIONS_CONFLICT" | "RECORD_PATH_UNUSABLE" | "REPLAY_DIVERGED" | "RESUME_REFUSED" | "RUN_CLOSED" | "RUN_STOPPED" | "WORKTREE_REFUSED" | "MODEL_RESOLUTION_FAILED" | "SPAWN_FAILED";
|
|
33
|
+
export type YaagErrorCode = "AGENT_FAILED" | "AGENT_DIED" | "AGENT_BUSY" | "ASK_TIMEOUT" | "ASK_LIMIT" | "ASK_STALLED" | "COMPACT_DURING_ASK" | "COMPACT_FAILED" | "FORK_DURING_ASK" | "FORK_REFUSED" | "ASK_INVALID_OUTPUT" | "ARGS_INVALID" | "CONFIG_INVALID" | "OPTIONS_CONFLICT" | "RECORD_PATH_UNUSABLE" | "REPLAY_DIVERGED" | "RESUME_REFUSED" | "RUN_CLOSED" | "RUN_STOPPED" | "WORKTREE_REFUSED" | "MODEL_RESOLUTION_FAILED" | "SPAWN_FAILED";
|
|
34
34
|
/** The single error class of the runtime (ADR-0003). */
|
|
35
35
|
export declare class YaagError extends Error {
|
|
36
36
|
readonly code: YaagErrorCode;
|
|
@@ -17,6 +17,11 @@ export type { ModelErrorReason } from "./model/index.ts";
|
|
|
17
17
|
* settled Run never writes it (ADR-0031).
|
|
18
18
|
*/
|
|
19
19
|
export type RunOutcome = "completed" | "failed" | "stopped" | "paused" | "interrupted";
|
|
20
|
+
/**
|
|
21
|
+
* How an Agent came to be. An absent value on an event means "spawn"; "fork"
|
|
22
|
+
* marks an Agent created from a copy of another Agent's session (ADR-0044).
|
|
23
|
+
*/
|
|
24
|
+
export type SpawnOrigin = "spawn" | "fork";
|
|
20
25
|
/** The current, Ask-scoped observer projection derived from Agent frames. */
|
|
21
26
|
export type AgentActivity = {
|
|
22
27
|
readonly type: "thinking";
|
|
@@ -65,6 +70,10 @@ export type LifecycleEventBody = {
|
|
|
65
70
|
* Cassette-playback Agents and events from older CLIs.
|
|
66
71
|
*/
|
|
67
72
|
readonly sessionFile?: string;
|
|
73
|
+
/** Resolved name of the Agent named as this Agent's parent (Parent Link). */
|
|
74
|
+
readonly parent?: string;
|
|
75
|
+
/** How the Agent came to be; absent means "spawn". */
|
|
76
|
+
readonly origin?: SpawnOrigin;
|
|
68
77
|
} | {
|
|
69
78
|
readonly type: "ask_start";
|
|
70
79
|
readonly agent: string;
|
|
@@ -150,6 +159,30 @@ export type LifecycleEventBody = {
|
|
|
150
159
|
readonly tokens: TokenBreakdown;
|
|
151
160
|
/** Cumulative assistant-completion cost observed so far. */
|
|
152
161
|
readonly cost: number;
|
|
162
|
+
} | {
|
|
163
|
+
/**
|
|
164
|
+
* One compaction of an Agent's context (ADR-0043).
|
|
165
|
+
*
|
|
166
|
+
* It carries the summary call's own spend, so a Run Summary does not
|
|
167
|
+
* silently lose it. `agent_exit` stays authoritative for the Agent's
|
|
168
|
+
* total: pi's `get_session_stats` already includes compaction spend.
|
|
169
|
+
* The custom instructions never ride the wire (ticket 09); only the
|
|
170
|
+
* `custom` flag says that the program supplied some.
|
|
171
|
+
*/
|
|
172
|
+
readonly type: "agent_compaction";
|
|
173
|
+
readonly agent: string;
|
|
174
|
+
/** Monotonic per Agent, from 0. */
|
|
175
|
+
readonly index: number;
|
|
176
|
+
/** Context tokens before the summary replaced the transcript; null when unknown. */
|
|
177
|
+
readonly tokensBefore: number | null;
|
|
178
|
+
/** Estimated context tokens after the summary; null when unknown. */
|
|
179
|
+
readonly tokensAfter: number | null;
|
|
180
|
+
/** The summary call's own token breakdown; null when unknown. */
|
|
181
|
+
readonly tokens: TokenBreakdown | null;
|
|
182
|
+
/** The summary call's own cost; null when unknown. */
|
|
183
|
+
readonly cost: number | null;
|
|
184
|
+
/** The program supplied custom compaction instructions. */
|
|
185
|
+
readonly custom: boolean;
|
|
153
186
|
} | {
|
|
154
187
|
readonly type: "agent_exit";
|
|
155
188
|
readonly agent: string;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
export type { AgentConfig, AgentDefinition } from "./agent/index.ts";
|
|
2
2
|
export { agentDefinitionConfig, defineAgent, isAgentDefinition } from "./agent/index.ts";
|
|
3
|
-
export type { Cassette, CassetteAgent, CassetteArtifact, CassetteAsk, CassetteGit, CassetteRun, CassetteSink, CassetteSpawn, } from "./cassette/index.ts";
|
|
3
|
+
export type { Cassette, CassetteAgent, CassetteArtifact, CassetteAsk, CassetteCompaction, CassetteGit, CassetteRun, CassetteSink, CassetteSpawn, } from "./cassette/index.ts";
|
|
4
4
|
export { assertReplayable, CASSETTE_VERSION, loadCassette, recordingTransport, replayTransport, resumeTransport, } from "./cassette/index.ts";
|
|
5
5
|
export type { ConfigEnvironment, ConfigExtension, ConfigLayerName, EffectiveConfig, EffectiveConfigRequest, } from "./config/index.ts";
|
|
6
6
|
export { EMPTY_EFFECTIVE_CONFIG, loadEffectiveConfig, PROJECT_CONFIG_DIR, } from "./config/index.ts";
|
|
7
7
|
export type { AskInvalidOutputOutcome, AskLimitKind, AskLimitOutcome, AskStalledOutcome, ModelResolutionOutcome, YaagErrorCode, } from "./errors.ts";
|
|
8
8
|
export { isYaagError, YaagError } from "./errors.ts";
|
|
9
|
-
export type { AgentActivity, AskOutputChannel, EventSink, LifecycleEvent, LifecycleEventBody, NodeState, NodeUsage, StampedEventSink, } from "./events.ts";
|
|
9
|
+
export type { AgentActivity, AskOutputChannel, EventSink, LifecycleEvent, LifecycleEventBody, NodeState, NodeUsage, SpawnOrigin, StampedEventSink, } from "./events.ts";
|
|
10
10
|
export type { ModelError, ModelErrorReason, ModelResolver, ModelSelection, ModelSpec, ThinkingResolver, ThinkingSpec, } from "./model/index.ts";
|
|
11
11
|
export type { DecodedNode, NodeDecoder, NodePath, NodeSnapshot } from "./node/index.ts";
|
|
12
12
|
export { agentAskPath, childPath, DEFAULT_NODE_DECODERS, NodeTracker, sanitizeNodeName, } from "./node/index.ts";
|
|
13
13
|
export { prompt, promptGist } from "./prompt/index.ts";
|
|
14
14
|
export type { OrchestrationProgram, ProgramDefinition, RunContext, RunOptions, } from "./run/index.ts";
|
|
15
15
|
export { defineRun, executeRun, isOrchestrationProgram, programDefinition } from "./run/index.ts";
|
|
16
|
-
export type { AgentInfo, AgentState, AskingAgentInfo, EndedRunSummary, ExitedAgentInfo, IdleAgentInfo, ModelFallbackInfo, NodeInfo, RunningRunSummary, RunOutcome, RunState, RunSummary, } from "./summary/index.ts";
|
|
16
|
+
export type { AgentInfo, AgentState, AskingAgentInfo, CompactionInfo, EndedRunSummary, ExitedAgentInfo, IdleAgentInfo, ModelFallbackInfo, NodeInfo, RunningRunSummary, RunOutcome, RunState, RunSummary, } from "./summary/index.ts";
|
|
17
17
|
export { applyEvent, initialSummary } from "./summary/index.ts";
|
|
18
|
-
export type { AgentStats, AgentTransport, AskMarker, AskMarkerContext, AskPlayback, DiscoveredSkill, Frame, ReapPath, ReapTarget, SkillProbeFactory, TokenBreakdown, TransportFactory, TransportStartup, TransportStartupObserver, WorktreeResolution, } from "./transport/index.ts";
|
|
18
|
+
export type { AgentStats, AgentTransport, AskMarker, AskMarkerContext, AskPlayback, CompactionMarker, CompactionPlayback, CompactionResult, DiscoveredSkill, Frame, ReapPath, ReapTarget, SkillProbeFactory, TokenBreakdown, TransportFactory, TransportStartup, TransportStartupObserver, WorktreeResolution, } from "./transport/index.ts";
|
|
19
19
|
export { readSystemPromptSidecar, reap, worktreeTransport } from "./transport/index.ts";
|
|
20
|
-
export type { AskOptions, Handle, ResolvedSpawnOptions, SpawnOptions, SpawnOverrides, StructuredAskOptions, ThinkingLevel, } from "./types.ts";
|
|
20
|
+
export type { AskOptions, ForkOptions, Handle, ResolvedSpawnOptions, SpawnOptions, SpawnOverrides, StructuredAskOptions, ThinkingLevel, } from "./types.ts";
|
|
21
21
|
export { AGENT_NODE_TABLE_MAX, ASK_OUTPUT_FLUSH_INTERVAL_MS, ASK_OUTPUT_MAX_BYTES, ASK_OUTPUT_TRUNCATION_MARKER, NODE_GIST_MAX_CHARS, PROMPT_GIST_MAX_CHARS, TOOL_ARGS_GIST_MAX_CHARS, } from "./wire-constants.ts";
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* Files inside this directory import each other directly.
|
|
4
4
|
*/
|
|
5
5
|
export { applyEvent, type EndedRunSummary, initialSummary, type RunningRunSummary, type RunOutcome, type RunState, type RunSummary, } from "./summary.ts";
|
|
6
|
-
export type { AgentInfo, AgentState, AskingAgentInfo, ExitedAgentInfo, IdleAgentInfo, ModelFallbackInfo, NodeInfo, } from "./summary-agent.ts";
|
|
6
|
+
export type { AgentInfo, AgentState, AskingAgentInfo, CompactionInfo, ExitedAgentInfo, IdleAgentInfo, ModelFallbackInfo, NodeInfo, SpawnOrigin, } from "./summary-agent.ts";
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import type { AgentActivity } from "../events.ts";
|
|
1
|
+
import type { AgentActivity, SpawnOrigin } from "../events.ts";
|
|
2
2
|
import type { TokenBreakdown, WorktreeResolution } from "../transport/index.ts";
|
|
3
3
|
import type { ModelFallbackInfo } from "./summary-fallbacks.ts";
|
|
4
4
|
import type { NodeInfo } from "./summary-nodes.ts";
|
|
5
|
-
export type { AgentActivity } from "../events.ts";
|
|
5
|
+
export type { AgentActivity, SpawnOrigin } from "../events.ts";
|
|
6
6
|
export type { ModelFallbackInfo } from "./summary-fallbacks.ts";
|
|
7
7
|
export type { NodeInfo } from "./summary-nodes.ts";
|
|
8
|
+
/** What one compaction of an Agent's context reported (ADR-0043). */
|
|
9
|
+
export interface CompactionInfo {
|
|
10
|
+
readonly tokensBefore: number | null;
|
|
11
|
+
readonly tokensAfter: number | null;
|
|
12
|
+
/** The summary call's own cost, already included in `agent_exit` accounting. */
|
|
13
|
+
readonly cost: number | null;
|
|
14
|
+
readonly at: number | null;
|
|
15
|
+
}
|
|
8
16
|
/** The observer-facing lifecycle state of an Agent. */
|
|
9
17
|
export type AgentState = "idle" | "asking" | "exited";
|
|
10
18
|
/** Identity and accounting facts that apply in every observer Agent state. */
|
|
@@ -19,6 +27,10 @@ interface AgentInfoBase {
|
|
|
19
27
|
readonly branch: string | null;
|
|
20
28
|
/** pi's session file for this Agent, when the spawn reported one; a Peek reads it. */
|
|
21
29
|
readonly sessionFile: string | null;
|
|
30
|
+
/** The Agent named as this one's parent (Parent Link), or null for a root Agent. */
|
|
31
|
+
readonly parent: string | null;
|
|
32
|
+
/** How the Agent came to be; "spawn" until forking ships. */
|
|
33
|
+
readonly origin: SpawnOrigin;
|
|
22
34
|
readonly activity: AgentActivity | null;
|
|
23
35
|
readonly tokens: TokenBreakdown | null;
|
|
24
36
|
readonly cost: number | null;
|
|
@@ -27,6 +39,10 @@ interface AgentInfoBase {
|
|
|
27
39
|
/** Timestamp ordering only cumulative live accounting, never lifecycle state. */
|
|
28
40
|
readonly usageUpdatedAt: number | null;
|
|
29
41
|
readonly askStartedAt: number | null;
|
|
42
|
+
/** Compactions of this Agent's context so far (ADR-0043). */
|
|
43
|
+
readonly compactions: number;
|
|
44
|
+
/** What the newest compaction reported, or null when the Agent compacted none. */
|
|
45
|
+
readonly lastCompaction: CompactionInfo | null;
|
|
30
46
|
/** This Agent's bounded Nested Node table, in first-seen order (spec §3). */
|
|
31
47
|
readonly nodes: readonly NodeInfo[];
|
|
32
48
|
/** Exited Nested Nodes dropped to keep the table bounded. */
|
|
@@ -90,6 +106,8 @@ export declare function spawnAgent(current: AgentRecord | undefined, identity: {
|
|
|
90
106
|
readonly cwd: string;
|
|
91
107
|
readonly branch?: string;
|
|
92
108
|
readonly sessionFile?: string;
|
|
109
|
+
readonly parent?: string;
|
|
110
|
+
readonly origin?: SpawnOrigin;
|
|
93
111
|
}, at: number | null): AgentRecord;
|
|
94
112
|
/**
|
|
95
113
|
* Folds an Ask start into the asking arm when it is not older than the folded
|
|
@@ -123,6 +141,15 @@ export declare function endAsk(current: AgentRecord | undefined, settlement: Ask
|
|
|
123
141
|
* stream order while older stamped observations are ignored.
|
|
124
142
|
*/
|
|
125
143
|
export declare function setUsage(current: AgentRecord | undefined, observation: AgentUsageObservation, at: number | null): AgentRecord;
|
|
144
|
+
/**
|
|
145
|
+
* Counts one compaction and keeps what it reported.
|
|
146
|
+
*
|
|
147
|
+
* It folds no cost: the summary call's spend reaches the Summary through
|
|
148
|
+
* `agent_usage`, and `agent_exit` stays authoritative (ADR-0043). A terminal
|
|
149
|
+
* Agent still counts a late compaction, because the count is a fact about the
|
|
150
|
+
* conversation rather than a lifecycle state.
|
|
151
|
+
*/
|
|
152
|
+
export declare function compactAgent(current: AgentRecord | undefined, observation: CompactionInfo, at: number | null): AgentRecord;
|
|
126
153
|
/**
|
|
127
154
|
* Folds authoritative shutdown accounting into the terminal Agent state.
|
|
128
155
|
*
|
|
@@ -2,7 +2,7 @@ import type { LifecycleEvent, LifecycleEventBody, RunOutcome } from "../events.t
|
|
|
2
2
|
import type { TokenBreakdown } from "../transport/index.ts";
|
|
3
3
|
import type { AgentInfo } from "./summary-agent.ts";
|
|
4
4
|
export type { NodeState, NodeUsage, RunOutcome } from "../events.ts";
|
|
5
|
-
export type { AgentActivity, AgentInfo, AgentState, AskingAgentInfo, ExitedAgentInfo, IdleAgentInfo, ModelFallbackInfo, NodeInfo, } from "./summary-agent.ts";
|
|
5
|
+
export type { AgentActivity, AgentInfo, AgentState, AskingAgentInfo, CompactionInfo, ExitedAgentInfo, IdleAgentInfo, ModelFallbackInfo, NodeInfo, SpawnOrigin, } from "./summary-agent.ts";
|
|
6
6
|
/** The observer-facing lifecycle state of a Run. */
|
|
7
7
|
export type RunState = "running" | "ended";
|
|
8
8
|
/** Accounting and identity facts shared by all Run observer states. */
|
|
@@ -24,6 +24,8 @@ interface RunSummaryBase {
|
|
|
24
24
|
readonly worstFrameGapMs: number;
|
|
25
25
|
/** Run-wide Model Resolution fallbacks, pruned per-Agent entries included. */
|
|
26
26
|
readonly modelFallbacks: number;
|
|
27
|
+
/** Compactions across every Agent of this Run (ADR-0043). */
|
|
28
|
+
readonly compactions: number;
|
|
27
29
|
}
|
|
28
30
|
/** A Run that has not settled; it has neither outcome nor compatibility result. */
|
|
29
31
|
export interface RunningRunSummary extends RunSummaryBase {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AvailableModel } from "../model/index.ts";
|
|
2
|
-
import type { AgentStats, AgentTransport, AskMarker, Frame } from "./transport.ts";
|
|
2
|
+
import type { AgentStats, AgentTransport, AskMarker, CompactionMarker, Frame } from "./transport.ts";
|
|
3
3
|
/**
|
|
4
4
|
* Scripted frame playback for one prompt sent through a FakeTransport.
|
|
5
5
|
*
|
|
@@ -41,6 +41,10 @@ export interface FakeTransportOptions extends FakePromptScript {
|
|
|
41
41
|
readonly steerError?: string;
|
|
42
42
|
/** Makes an abort RPC response fail without embedding a limit decision in playback. */
|
|
43
43
|
readonly abortError?: string;
|
|
44
|
+
/** Payload of a `compact` command response; omission answers a bare success. */
|
|
45
|
+
readonly compaction?: Record<string, unknown>;
|
|
46
|
+
/** Makes a `compact` command response fail, as pi does when it cannot summarize. */
|
|
47
|
+
readonly compactError?: string;
|
|
44
48
|
/** Makes the private report_result schema command fail. */
|
|
45
49
|
readonly schemaCommandError?: string;
|
|
46
50
|
/** The snapshot answered to `get_available_models`; defaults to this fake's own model. */
|
|
@@ -73,11 +77,14 @@ export declare class FakeTransport implements AgentTransport {
|
|
|
73
77
|
/** Everything the runtime wrote, in order. */
|
|
74
78
|
readonly sent: Frame[];
|
|
75
79
|
readonly asks: AskMarker[];
|
|
80
|
+
readonly compactions: CompactionMarker[];
|
|
76
81
|
constructor(options?: FakeTransportOptions);
|
|
77
82
|
send(frame: Frame): void;
|
|
78
83
|
frames(): AsyncIterable<Frame>;
|
|
79
84
|
beginAsk(marker: AskMarker): undefined;
|
|
80
85
|
finishAsk(): void;
|
|
86
|
+
beginCompaction(marker: CompactionMarker): undefined;
|
|
87
|
+
finishCompaction(): void;
|
|
81
88
|
/** True once the runtime shut this Agent down. */
|
|
82
89
|
get closed(): boolean;
|
|
83
90
|
/** Number of times this fake actually began close work. */
|
|
@@ -9,11 +9,11 @@ export { FrameGapTracker } from "./frame-gap.ts";
|
|
|
9
9
|
export { FrameQueue } from "./frame-queue.ts";
|
|
10
10
|
export { decodeFrames } from "./jsonl.ts";
|
|
11
11
|
export { liveTransport } from "./live-transport.ts";
|
|
12
|
-
export { type AgentProgress, piCommand, readAgentProgress } from "./pi-state.ts";
|
|
12
|
+
export { type AgentProgress, piCommand, readAgentProgress, readCompaction, } from "./pi-state.ts";
|
|
13
13
|
export { type ReapPath, type ReapTarget, reap } from "./reap.ts";
|
|
14
14
|
export { type DiscoveredSkill, liveSkillProbe, type SkillProbeFactory } from "./skill-probe.ts";
|
|
15
15
|
export { skillRestrictionTransport } from "./skill-restriction-transport.ts";
|
|
16
16
|
export { readSystemPromptSidecar } from "./system-prompt-recorder.ts";
|
|
17
17
|
export { SYSTEM_PROMPT_SIDECAR_SUFFIX, systemPromptSidecarPath, } from "./system-prompt-recorder-extension.ts";
|
|
18
|
-
export type { AgentStats, AgentTransport, AskCompletion, AskInvalidOutputPlayback, AskMarker, AskMarkerContext, AskPlayback, Frame, OpenOptions, TokenBreakdown, TransportFactory, TransportStartup, TransportStartupObserver, WorktreeResolution, } from "./transport.ts";
|
|
18
|
+
export type { AgentStats, AgentTransport, AskCompletion, AskInvalidOutputPlayback, AskMarker, AskMarkerContext, AskPlayback, CompactionMarker, CompactionPlayback, CompactionResult, Frame, OpenOptions, TokenBreakdown, TransportFactory, TransportStartup, TransportStartupObserver, WorktreeResolution, } from "./transport.ts";
|
|
19
19
|
export { worktreeTransport } from "./worktree-transport.ts";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentStats, Frame, OpenOptions } from "./transport.ts";
|
|
1
|
+
import type { AgentStats, CompactionResult, Frame, OpenOptions } from "./transport.ts";
|
|
2
2
|
/** What the Agent reported about its own work, read from a `get_state` probe. */
|
|
3
3
|
export interface AgentProgress {
|
|
4
4
|
/** True while pi streams a completion, compacts its context, or holds a queued prompt. */
|
|
@@ -49,3 +49,10 @@ export declare function readSessionFile(response: Frame): string | null;
|
|
|
49
49
|
* distinguishable (ADR-0012); a partial breakdown is treated as unknown.
|
|
50
50
|
*/
|
|
51
51
|
export declare function readStats(response: Frame): AgentStats;
|
|
52
|
+
/**
|
|
53
|
+
* What a `compact` response reports (ADR-0043).
|
|
54
|
+
*
|
|
55
|
+
* A missing field becomes null rather than 0, so "unknown" and "free" stay
|
|
56
|
+
* distinguishable: a custom compaction handler may answer without usage.
|
|
57
|
+
*/
|
|
58
|
+
export declare function readCompaction(response: Frame): CompactionResult;
|
|
@@ -29,6 +29,22 @@ export interface AgentStats {
|
|
|
29
29
|
readonly tokens: TokenBreakdown | null;
|
|
30
30
|
readonly cost: number | null;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* What one compaction of an Agent's context reported (ADR-0043).
|
|
34
|
+
*
|
|
35
|
+
* Every field is null when pi reported nothing for it: a custom compaction
|
|
36
|
+
* handler may answer without usage, and "unknown" must stay distinct from 0.
|
|
37
|
+
*/
|
|
38
|
+
export interface CompactionResult {
|
|
39
|
+
/** Context tokens before the summary replaced the transcript. */
|
|
40
|
+
readonly tokensBefore: number | null;
|
|
41
|
+
/** Estimated context tokens after the summary replaced the transcript. */
|
|
42
|
+
readonly tokensAfter: number | null;
|
|
43
|
+
/** Token breakdown of the summary call itself. */
|
|
44
|
+
readonly tokens: TokenBreakdown | null;
|
|
45
|
+
/** Cost of the summary call itself. */
|
|
46
|
+
readonly cost: number | null;
|
|
47
|
+
}
|
|
32
48
|
/** Recorded inputs used to explain an Ask-hash mismatch without changing identity. */
|
|
33
49
|
export interface AskMarkerContext {
|
|
34
50
|
readonly prompt: string;
|
|
@@ -72,6 +88,25 @@ export interface AskCompletion {
|
|
|
72
88
|
/** The Stall Watchdog settled this Ask from observed state (ADR-0029). */
|
|
73
89
|
readonly recovered?: true;
|
|
74
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Opaque marker naming one compaction of an Agent's context.
|
|
93
|
+
*
|
|
94
|
+
* A compaction sits between two Asks, so it cannot ride the Agent-level frame
|
|
95
|
+
* streams: a Cassette replay switches those cursors to an Ask and never
|
|
96
|
+
* switches back. The marker gives the exchange its own recorded streams.
|
|
97
|
+
*/
|
|
98
|
+
export interface CompactionMarker {
|
|
99
|
+
/** Monotonic per Agent, from 0. */
|
|
100
|
+
readonly index: number;
|
|
101
|
+
/** sha256 of the settled-Ask count and the custom instructions, when given. */
|
|
102
|
+
readonly hash: string;
|
|
103
|
+
/** Settled Asks of this Agent at the compaction point. */
|
|
104
|
+
readonly afterAsks: number;
|
|
105
|
+
}
|
|
106
|
+
/** Presence identifies Cassette playback of one compaction. */
|
|
107
|
+
export interface CompactionPlayback {
|
|
108
|
+
readonly result: CompactionResult;
|
|
109
|
+
}
|
|
75
110
|
/** Presence identifies Cassette playback, including recorded successful Asks. */
|
|
76
111
|
export interface AskPlayback {
|
|
77
112
|
/** Limit outcome recorded for this Ask, if it rejected with ASK_LIMIT. */
|
|
@@ -116,6 +151,13 @@ export interface AgentTransport {
|
|
|
116
151
|
beginAsk(marker: AskMarker): AskPlayback | undefined;
|
|
117
152
|
/** Reports surfaced live outcomes; replay ignores completion. */
|
|
118
153
|
finishAsk(completion: AskCompletion): void;
|
|
154
|
+
/**
|
|
155
|
+
* Begins one compaction. Live transports return undefined; replay transports
|
|
156
|
+
* return the recorded result.
|
|
157
|
+
*/
|
|
158
|
+
beginCompaction(marker: CompactionMarker): CompactionPlayback | undefined;
|
|
159
|
+
/** Ends the compaction exchange, so later frames belong to the Agent again. */
|
|
160
|
+
finishCompaction(result: CompactionResult | undefined): void;
|
|
119
161
|
/**
|
|
120
162
|
* The extraction policy recorded for the Ask at `index`, when a Cassette
|
|
121
163
|
* backs it. An Ask recorded under an older policy keeps that policy, so its
|
|
@@ -162,10 +204,31 @@ export interface OpenOptions {
|
|
|
162
204
|
* Spawn identity only: it never becomes argv, and it is absent when empty.
|
|
163
205
|
*/
|
|
164
206
|
readonly declaredExtensions?: readonly string[];
|
|
207
|
+
/**
|
|
208
|
+
* Resolved name of the Agent named as this Agent's parent (Parent Link).
|
|
209
|
+
* Spawn identity only: it never becomes argv.
|
|
210
|
+
*/
|
|
211
|
+
readonly parent?: string;
|
|
165
212
|
/** Session storage directory. Used by the e2e suite to stay out of ~/.pi (ticket 06). */
|
|
166
213
|
readonly sessionDir?: string;
|
|
167
214
|
/** Resumes an existing pi session, translated to `--session <path>`. */
|
|
168
215
|
readonly sessionFile?: string;
|
|
216
|
+
/** How the Agent came to be; absent means an ordinary spawn. Spawn identity. */
|
|
217
|
+
readonly origin?: "fork";
|
|
218
|
+
/** Name of the Agent this one was forked from. Spawn identity; never argv. */
|
|
219
|
+
readonly forkOf?: string;
|
|
220
|
+
/** Settled Asks of the fork source at the fork point. Spawn identity. */
|
|
221
|
+
readonly forkAsks?: number;
|
|
222
|
+
/**
|
|
223
|
+
* The fork source's session file, translated to `pi --fork <path>`.
|
|
224
|
+
* Never spawn identity: the path is machine-specific.
|
|
225
|
+
*/
|
|
226
|
+
readonly forkSession?: string;
|
|
227
|
+
/**
|
|
228
|
+
* The fork source's worktree, so the fork branches from it instead of from a
|
|
229
|
+
* clean base tree. Never spawn identity.
|
|
230
|
+
*/
|
|
231
|
+
readonly worktreeFrom?: WorktreeResolution;
|
|
169
232
|
}
|
|
170
233
|
/** Nondeterministic worktree identity resolved below the transport seam. */
|
|
171
234
|
export interface WorktreeResolution {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Static, TSchema } from "typebox";
|
|
2
2
|
import type { ModelSpec, ThinkingLevel, ThinkingSpec } from "./model/index.ts";
|
|
3
|
+
import type { CompactionResult } from "./transport/index.ts";
|
|
3
4
|
export type { ThinkingLevel } from "./model/index.ts";
|
|
5
|
+
export type { CompactionResult } from "./transport/index.ts";
|
|
4
6
|
/** Options for spawning one Agent (ADR-0001, ADR-0009, ADR-0026). */
|
|
5
7
|
export interface SpawnOptions {
|
|
6
8
|
/** Working directory. Defaults to the Orchestrator's cwd. */
|
|
@@ -64,17 +66,44 @@ export interface SpawnOptions {
|
|
|
64
66
|
readonly name?: string;
|
|
65
67
|
/** Request a fresh Git worktree. The requested cwd remains the base until spawn resolves. */
|
|
66
68
|
readonly worktree?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Names this Agent's parent in the Run tree (Parent Link). Data only: it is
|
|
71
|
+
* no conversation channel and no lifetime rule.
|
|
72
|
+
*/
|
|
73
|
+
readonly parent?: Handle;
|
|
67
74
|
}
|
|
68
75
|
/**
|
|
69
76
|
* Spawn options after Model Resolution has settled one model and thinking level.
|
|
70
77
|
*
|
|
71
78
|
* This is the settled shape, and it is what the Cassette identity hashes
|
|
72
79
|
* (ADR-0039).
|
|
80
|
+
*
|
|
81
|
+
* `parent` is omitted on purpose: a Handle must never reach this shape, because
|
|
82
|
+
* an Ask records these options into the Cassette. Spawn resolves the Parent
|
|
83
|
+
* Link to a name, which travels in `OpenOptions` and stays out of Ask identity.
|
|
73
84
|
*/
|
|
74
|
-
export interface ResolvedSpawnOptions extends Omit<SpawnOptions, "model" | "thinking"> {
|
|
85
|
+
export interface ResolvedSpawnOptions extends Omit<SpawnOptions, "model" | "thinking" | "parent"> {
|
|
75
86
|
readonly model?: string;
|
|
76
87
|
readonly thinking?: ThinkingLevel;
|
|
77
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* What a fork may change about the Agent it copies (ADR-0044).
|
|
91
|
+
*
|
|
92
|
+
* A fork inherits the source's resolved spawn options verbatim: model,
|
|
93
|
+
* thinking, tools, skills, system prompt, extensions and Ask defaults. `name`
|
|
94
|
+
* is the exception — the child always gets a fresh auto-name unless this object
|
|
95
|
+
* names one. The fork source becomes the child's default `parent`.
|
|
96
|
+
*
|
|
97
|
+
* The inherited model is the concrete one the source settled on, so the child
|
|
98
|
+
* never re-runs the source's fallback list; `fork({ model })` is the way out.
|
|
99
|
+
* A fork of a Worktree Agent gets its own fresh worktree, branched from the
|
|
100
|
+
* source's branch, so only committed state transfers. The child re-runs the
|
|
101
|
+
* ADR-0026 Tool Contract probe against its own effective options.
|
|
102
|
+
*/
|
|
103
|
+
export interface ForkOptions extends SpawnOptions {
|
|
104
|
+
/** true = pi's default compaction; a string = pi custom instructions. */
|
|
105
|
+
readonly compact?: boolean | string;
|
|
106
|
+
}
|
|
78
107
|
/** Topology-only fields that may change when spawning an Agent Definition. */
|
|
79
108
|
export interface SpawnOverrides {
|
|
80
109
|
/** Log and event label. Defaults to the definition's name; duplicates are suffixed. */
|
|
@@ -83,6 +112,8 @@ export interface SpawnOverrides {
|
|
|
83
112
|
readonly cwd?: string;
|
|
84
113
|
/** Request a fresh Git worktree. */
|
|
85
114
|
readonly worktree?: boolean;
|
|
115
|
+
/** Names this Agent's parent in the Run tree (Parent Link). Data only. */
|
|
116
|
+
readonly parent?: Handle;
|
|
86
117
|
}
|
|
87
118
|
/**
|
|
88
119
|
* Options for one Ask (ADR-0003).
|
|
@@ -179,4 +210,23 @@ export interface Handle {
|
|
|
179
210
|
*/
|
|
180
211
|
ask<Schema extends TSchema>(prompt: string, options: StructuredAskOptions<Schema>): Promise<Static<Schema>>;
|
|
181
212
|
ask(prompt: string, options?: AskOptions): Promise<string>;
|
|
213
|
+
/**
|
|
214
|
+
* Spawns a new Agent from a copy of this Agent's session (ADR-0044).
|
|
215
|
+
*
|
|
216
|
+
* The fork point is a settled Ask boundary: a call while an Ask is in flight
|
|
217
|
+
* rejects with `FORK_DURING_ASK`. An Agent that died mid-Ask, or that holds
|
|
218
|
+
* no session file, rejects with `FORK_REFUSED`. An Agent that exited cleanly
|
|
219
|
+
* stays forkable, so a program can build context, let the Agent exit, then
|
|
220
|
+
* fork its final state many times.
|
|
221
|
+
*/
|
|
222
|
+
fork(overrides?: ForkOptions): Promise<Handle>;
|
|
223
|
+
/**
|
|
224
|
+
* Replaces this Agent's context with a summary of it (ADR-0043).
|
|
225
|
+
*
|
|
226
|
+
* `instructions` becomes pi's `customInstructions`. A call while an Ask is in
|
|
227
|
+
* flight rejects with `COMPACT_DURING_ASK`; a refusal from pi rejects with
|
|
228
|
+
* `COMPACT_FAILED`. The result reports what the summary call cost; each field
|
|
229
|
+
* is null when pi reported nothing for it.
|
|
230
|
+
*/
|
|
231
|
+
compact(instructions?: string): Promise<CompactionResult>;
|
|
182
232
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yaag/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@earendil-works/pi-tui": "^0.84.0",
|
|
24
|
-
"@yaag/runtime": "0.
|
|
25
|
-
"@yaag/tui": "0.
|
|
24
|
+
"@yaag/runtime": "0.11.0",
|
|
25
|
+
"@yaag/tui": "0.11.0",
|
|
26
26
|
"typebox": "1.3.7"
|
|
27
27
|
}
|
|
28
28
|
}
|
package/src/terminal/render.ts
CHANGED
|
@@ -24,7 +24,7 @@ function renderPlainEvent(event: LifecycleEventBody, mode: PlainRenderMode): str
|
|
|
24
24
|
case "run_start":
|
|
25
25
|
return `[yaag] run ${event.program}`;
|
|
26
26
|
case "agent_spawn":
|
|
27
|
-
return `[${event.agent}] spawned ${event.model} in ${event.cwd}`;
|
|
27
|
+
return `[${event.agent}] ${event.origin === "fork" ? "forked" : "spawned"} ${event.model} in ${event.cwd}${event.parent === undefined ? "" : ` under ${event.parent}`}`;
|
|
28
28
|
case "ask_start":
|
|
29
29
|
return `[${event.agent}] ask #${event.index + 1}${event.replayed === true ? " (replayed)" : ""}${event.promptGist === "" ? "" : ` — ${event.promptGist}`}`;
|
|
30
30
|
case "ask_activity":
|
|
@@ -43,6 +43,8 @@ function renderPlainEvent(event: LifecycleEventBody, mode: PlainRenderMode): str
|
|
|
43
43
|
return `[${event.agent}] model ${event.failedModel} ${event.reason} — falling back to ${event.resolvedModel}`;
|
|
44
44
|
case "agent_model":
|
|
45
45
|
return `[${event.agent}] model \u2014 now running ${event.model}`;
|
|
46
|
+
case "agent_compaction":
|
|
47
|
+
return `[${event.agent}] compacted ${contextTokens(event.tokensBefore)} → ${contextTokens(event.tokensAfter)}${event.custom ? " (custom)" : ""} ${cost(event.cost)}`;
|
|
46
48
|
case "agent_exit":
|
|
47
49
|
return `[${event.agent}] exit ${tokens(event.tokens)} ${cost(event.cost)}${event.incomplete ? " (killed mid-ask, cost incomplete)" : ""}`;
|
|
48
50
|
case "run_end": {
|
|
@@ -64,6 +66,7 @@ function minimalEvent(type: LifecycleEventBody["type"]): boolean {
|
|
|
64
66
|
type === "ask_end" ||
|
|
65
67
|
type === "model_fallback" ||
|
|
66
68
|
type === "agent_model" ||
|
|
69
|
+
type === "agent_compaction" ||
|
|
67
70
|
type === "agent_exit" ||
|
|
68
71
|
type === "run_end"
|
|
69
72
|
);
|
|
@@ -97,6 +100,11 @@ function tokens(value: TokenBreakdown | null): string {
|
|
|
97
100
|
return value === null ? "tokens unknown" : `${value.total} tokens`;
|
|
98
101
|
}
|
|
99
102
|
|
|
103
|
+
/** Context size at one end of a compaction; a compaction may report neither. */
|
|
104
|
+
function contextTokens(value: number | null): string {
|
|
105
|
+
return value === null ? "?" : `${value} tokens`;
|
|
106
|
+
}
|
|
107
|
+
|
|
100
108
|
function cost(value: number | null): string {
|
|
101
109
|
return value === null ? "cost unknown" : `$${value.toFixed(4)}`;
|
|
102
110
|
}
|