ytdb-slate 0.1.0 → 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/README.md +44 -1
- package/docs/design-principles.md +13 -0
- package/extension/state.ts +1 -1
- package/extension/threads.ts +1 -1
- package/extension/worker.ts +7 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,49 @@ Slate is a thread-weaving orchestration extension for the [pi coding agent](http
|
|
|
4
4
|
|
|
5
5
|
The orchestrator (your main pi session) dispatches **bounded actions** to persistent **worker threads**. Each completed action is compressed by an LLM into an **episode** — a durable, structured record (intent, actions, findings, artifacts, open issues, handoff notes) that the orchestrator composes into further dispatches instead of re-reading raw transcripts. On top of that, Slate injects a mandatory workflow doctrine: research before design, design review, adversarial review, and track review — with optional umbrella **draft-PR publishing** for tracks.
|
|
6
6
|
|
|
7
|
+
## Why Slate?
|
|
8
|
+
|
|
9
|
+
Long-horizon agentic work fails on context management, not model capability. Existing architectures each solve a piece of the problem and trade away the rest. Compaction is unpredictably lossy; naive subagents isolate context but hand back only a single response string; markdown plans go stale and get under-executed. Rigid task trees can't adapt to information discovered mid-task, and planner/executor stacks synchronize through compress-and-return boundaries that risk dropping critical state.
|
|
10
|
+
|
|
11
|
+
Slate's answer is the **thread**: the orchestrator dispatches one bounded action at a time; the worker executes it and returns an **episode**. The orchestrator keeps the reactivity of a plain agent loop while gaining the context isolation, compaction, and parallelism that the single-context loop lacks.
|
|
12
|
+
|
|
13
|
+
| Aspect | ReAct | Markdown plan | Task trees | RLM (Recursive Language Models) | Devin / Manus / Altera | Claude Code / Codex subagents | Slate |
|
|
14
|
+
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
15
|
+
| Planning | implicit | file | explicit tree | REPL | planning agent | plan mode | implicit / adaptive — no upfront static plan |
|
|
16
|
+
| Decomposition | none | none | direct tree | REPL functions | task-based | subagent delegation | implicit |
|
|
17
|
+
| Synchronization | single thread | single thread | gated steps | REPL return | reduce & return | message passing | episodes |
|
|
18
|
+
| Intermediate feedback | per step | per step | on task failure | on execution end | after compress | message passing | per episode |
|
|
19
|
+
| Context isolation | none | none | per subtask | per subcall | subagent | subagent | per thread |
|
|
20
|
+
| Context compaction | none | none | task-based | REPL slicing | subagent compress | compaction | episode compress |
|
|
21
|
+
| Parallel execution | none | none | none | in REPL | Altera only | native | native |
|
|
22
|
+
| Expressivity | high | high | low | high | medium | medium | high |
|
|
23
|
+
| Adaptability | yes | if plan updated | no | limited — no mid-run course correction | yes | limited by message passing | yes |
|
|
24
|
+
|
|
25
|
+
Characterizations of third-party systems reflect their publicly described designs at the time of writing. The taxonomy is adapted from the Random Labs technical report introducing the thread-weaving "Slate" architecture (its agent ships as the npm package `@randomlabs/slate`); ytdb-slate is an independent implementation of that architecture for pi.
|
|
26
|
+
|
|
27
|
+
**Threads are not subagents:**
|
|
28
|
+
|
|
29
|
+
- **Per-episode feedback.** Each thread executes one bounded action and hands control back. The orchestrator adapts after every episode — reactive like a ReAct loop — instead of firing off a subagent and hoping the result comes back usable.
|
|
30
|
+
- **Compaction at a chosen boundary.** Compression happens at a predictable point — action completion — instead of mid-stream when context overflows. The compression itself is still LLM-performed and lossy, but the boundary is chosen, not forced.
|
|
31
|
+
- **Episodes compose.** One thread's episode can seed another thread's context, so conclusions travel across the system by reference. Subagents pass back a single response string; episodes are durable, structured, reusable records.
|
|
32
|
+
|
|
33
|
+
Full rationale: [`docs/design-principles.md`](docs/design-principles.md), shipped in the package — if this summary and that document disagree, the document wins.
|
|
34
|
+
|
|
35
|
+
## Feature development workflow
|
|
36
|
+
|
|
37
|
+
In orchestrator mode, Slate injects a track-based development workflow as doctrine — it is not optional; project configuration can extend it (`doctrineExtraPath`) but never replace it. The flow:
|
|
38
|
+
|
|
39
|
+
1. **Research** — interactive exploration; a research log opens lazily when defined triggers fire (non-trivial decisions, surprises, risky invariants, session boundaries).
|
|
40
|
+
2. **User design review** — the user approves the design direction before any machine review.
|
|
41
|
+
3. **Adversarial review** — a fresh-context reviewer attacks the design pre-implementation; findings are triaged with the user.
|
|
42
|
+
4. **Track split approval** — the user approves how the change splits into independently reviewable tracks.
|
|
43
|
+
5. **Per-track loop** — implement → agent code review → fixes → mandatory user review → marker commit (an empty commit marking the track's boundary in history).
|
|
44
|
+
6. **Delivery** — with draft-PR publishing enabled, the squash-merge is performed by the user; the agent never merges. With it disabled (the default), the change lands as a squashed commit that carries the workflow log's key content in its message.
|
|
45
|
+
|
|
46
|
+
The workflow scales with change size: multi-track changes get the full flow, single-track changes skip the split and the marker commits, and trivial changes shrink the pre-implementation reviews to consent plus a micro-review (skippable with explicit user consent) — the agent code review and the mandatory user review still apply at every tier. Umbrella draft-PR publishing activates only when `workflow.draftPRs` is `true`.
|
|
47
|
+
|
|
48
|
+
This summary is orientation only; the shipped docs listed below are normative.
|
|
49
|
+
|
|
7
50
|
## Install
|
|
8
51
|
|
|
9
52
|
Install into a project (pinned, project-scoped — recorded in `.pi/settings.json`):
|
|
@@ -23,7 +66,7 @@ Optional config file: `slate.json` in the project's pi config dir (`.pi/slate.js
|
|
|
23
66
|
| `orchestratorModeDefault` | boolean | `false` | Start fresh interactive sessions with orchestrator mode ON. |
|
|
24
67
|
| `episodeModel` | string | newest available Anthropic Sonnet, else the worker's own model | Model (`provider/id`) used to compress a finished action into an episode. |
|
|
25
68
|
| `workerTools` | string[] | `["read", "bash", "edit", "write", "grep", "find", "ls"]` | Tools available to worker threads (an empty list also falls back to the default). |
|
|
26
|
-
| `maxConcurrent` | number | `4` | Maximum number of worker actions running concurrently. |
|
|
69
|
+
| `maxConcurrent` | number | `4` | Maximum number of worker actions running concurrently (must be ≥ 1 — unenforced: a value of 0 or less silently hangs all dispatches). Excess dispatches wait in a queue; actions on the same thread always run in dispatch order. Default rationale: shipped `docs/design-principles.md` §5 (repo-local note). |
|
|
27
70
|
| `pauseThresholdPercent` | number | `40` | Orchestrator context budget (percent, in `(0, 100]`) at which Slate auto-pauses and prepares a fresh-session handoff. |
|
|
28
71
|
| `orchestratorPromptDocs` | string[] | `[]` | Project markdown files (paths relative to the project root) whose **contents** are appended to the orchestrator system prompt. |
|
|
29
72
|
| `workerPromptDocs` | string[] | `[]` | Project markdown files whose **contents** are appended to every worker-thread system prompt. |
|
|
@@ -151,6 +151,19 @@ or two problems for the others:
|
|
|
151
151
|
| P9 parallelism | `threads.ts` `maxConcurrent` queueing; doctrine rule 2 in `mode.ts` |
|
|
152
152
|
| P10 context as RAM | `handoff.ts` context-budget auto-pause + fresh-session handoff |
|
|
153
153
|
|
|
154
|
+
Repo-local note (not from the report): the `maxConcurrent` cap defaults
|
|
155
|
+
to 4. Its failure modes are asymmetric: excess dispatches wait for a
|
|
156
|
+
slot (actions on the same thread additionally serialize in dispatch
|
|
157
|
+
order), so a low cap costs only latency, while a cap above the
|
|
158
|
+
provider's effective rate limits turns rate-limit exhaustion into
|
|
159
|
+
FAILED episodes and raises the unattended cost burn rate. Over its
|
|
160
|
+
lifetime a slot covers a multi-turn worker conversation followed by its
|
|
161
|
+
episode-compression call. The default is sized to cover typical
|
|
162
|
+
parallel batches (recon fan-outs, a review wave of a few perspectives)
|
|
163
|
+
while staying safe on common consumer API tiers; wider fan-outs only
|
|
164
|
+
pay tail latency, and projects with higher-tier keys raise the cap in
|
|
165
|
+
`slate.json`.
|
|
166
|
+
|
|
154
167
|
## 6. Runtime knowledge: what the orchestrator knows, and when
|
|
155
168
|
|
|
156
169
|
The orchestrator's knowledge of these principles is two-tier, following
|
package/extension/state.ts
CHANGED
|
@@ -45,7 +45,7 @@ export interface SlateSnapshot {
|
|
|
45
45
|
export interface SlateConfig {
|
|
46
46
|
episodeModel?: string; // "provider/id" for the episode compressor (D5)
|
|
47
47
|
workerTools?: string[];
|
|
48
|
-
maxConcurrent?: number;
|
|
48
|
+
maxConcurrent?: number; // global cap on concurrently running worker actions (default 4; must be ≥ 1 — unenforced, ≤ 0 silently hangs all dispatches; rationale: docs/design-principles.md §5 repo-local note)
|
|
49
49
|
pauseThresholdPercent?: number; // orchestrator context budget for auto-pause (default 40)
|
|
50
50
|
orchestratorModeDefault?: boolean; // seed orchestrator mode ON for fresh interactive sessions (unsaved until first real mutation)
|
|
51
51
|
orchestratorPromptDocs?: string[]; // role-guideline docs appended to the orchestrator prompt (cwd-relative paths, default none)
|
package/extension/threads.ts
CHANGED
|
@@ -83,7 +83,7 @@ export class ThreadManager {
|
|
|
83
83
|
private store: SlateStore,
|
|
84
84
|
private config: SlateConfig,
|
|
85
85
|
) {
|
|
86
|
-
this.semaphore = new Semaphore(config.maxConcurrent ?? 4);
|
|
86
|
+
this.semaphore = new Semaphore(config.maxConcurrent ?? 4); // default rationale: docs/design-principles.md §5 repo-local note
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
getConfig(): SlateConfig {
|
package/extension/worker.ts
CHANGED
|
@@ -14,12 +14,10 @@
|
|
|
14
14
|
import { mkdirSync } from "node:fs";
|
|
15
15
|
import { resolve } from "node:path";
|
|
16
16
|
import {
|
|
17
|
-
AuthStorage,
|
|
18
17
|
CONFIG_DIR_NAME,
|
|
19
18
|
createAgentSession,
|
|
20
19
|
DefaultResourceLoader,
|
|
21
20
|
getAgentDir,
|
|
22
|
-
ModelRegistry,
|
|
23
21
|
SessionManager,
|
|
24
22
|
SettingsManager,
|
|
25
23
|
type ExtensionContext,
|
|
@@ -66,8 +64,6 @@ export async function openWorkerSession(opts: {
|
|
|
66
64
|
mkdirSync(dir, { recursive: true });
|
|
67
65
|
|
|
68
66
|
const agentDir = getAgentDir();
|
|
69
|
-
const authStorage = AuthStorage.create();
|
|
70
|
-
const modelRegistry = ModelRegistry.create(authStorage);
|
|
71
67
|
|
|
72
68
|
// Trust propagation (mirrors vanilla pi's runtime SettingsManager): when no
|
|
73
69
|
// settingsManager is passed, the SDK default-constructs one with
|
|
@@ -104,11 +100,16 @@ export async function openWorkerSession(opts: {
|
|
|
104
100
|
? SessionManager.open(opts.sessionFile)
|
|
105
101
|
: SessionManager.create(ctx.cwd, dir);
|
|
106
102
|
|
|
103
|
+
// No modelRuntime passed: createAgentSession (pi >= 0.80.8) defaults to a
|
|
104
|
+
// ModelRuntime replacing the AuthStorage + ModelRegistry setup this code
|
|
105
|
+
// hand-built before those SDK options were removed. Credential/config
|
|
106
|
+
// sources are unchanged — global agentDir auth.json + models.json, never
|
|
107
|
+
// project-local — but the default is a superset: it also reads/writes
|
|
108
|
+
// agentDir/models-store.json and may run a throttled (~4h-cached)
|
|
109
|
+
// create-time network catalog refresh (disabled by PI_OFFLINE).
|
|
107
110
|
const { session } = await createAgentSession({
|
|
108
111
|
cwd: ctx.cwd,
|
|
109
112
|
agentDir,
|
|
110
|
-
authStorage,
|
|
111
|
-
modelRegistry,
|
|
112
113
|
model: model ?? undefined,
|
|
113
114
|
tools: opts.tools && opts.tools.length > 0 ? opts.tools : DEFAULT_WORKER_TOOLS,
|
|
114
115
|
resourceLoader: loader,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ytdb-slate",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Slate: a thread-weaving orchestration extension for the pi coding agent — bounded worker actions, compressed episodes, mandatory research/design/adversarial/track review workflow, optional draft-PR publishing.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|