@chopin-ai/harness-pi 0.2.0 → 0.3.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/dist/acp.d.ts +1 -8
- package/dist/acp.js +7 -10
- package/dist/acp.js.map +1 -1
- package/dist/auth.d.ts +1 -9
- package/dist/auth.js +3 -23
- package/dist/auth.js.map +1 -1
- package/dist/bridge.js +2 -2
- package/dist/bridge.js.map +1 -1
- package/dist/client-context.d.ts +7 -0
- package/dist/client-context.js +20 -0
- package/dist/client-context.js.map +1 -0
- package/dist/continuation.d.ts +34 -0
- package/dist/continuation.js +171 -0
- package/dist/continuation.js.map +1 -0
- package/dist/http.d.ts +3 -3
- package/dist/http.js +8 -67
- package/dist/http.js.map +1 -1
- package/dist/idle-compaction.d.ts +25 -0
- package/dist/idle-compaction.js +173 -0
- package/dist/idle-compaction.js.map +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/layer.d.ts +14 -3
- package/dist/layer.js +65 -10
- package/dist/layer.js.map +1 -1
- package/dist/mcp.d.ts +14 -0
- package/dist/mcp.js +77 -4
- package/dist/mcp.js.map +1 -1
- package/dist/mode.js +2 -0
- package/dist/mode.js.map +1 -1
- package/dist/protocol.d.ts +293 -1
- package/dist/protocol.js +176 -3
- package/dist/protocol.js.map +1 -1
- package/dist/server.d.ts +9 -7
- package/dist/server.js +155 -22
- package/dist/server.js.map +1 -1
- package/dist/service.d.ts +42 -2
- package/dist/service.js +169 -27
- package/dist/service.js.map +1 -1
- package/dist/submissions.d.ts +1 -1
- package/dist/submissions.js +2 -1
- package/dist/submissions.js.map +1 -1
- package/package.json +10 -9
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { BACKGROUND_CONTEXT, withAbortSignal } from "@earendil-works/chord/context";
|
|
2
|
+
import { calculateContextTokens } from "@earendil-works/pi-ai/utils/estimate";
|
|
3
|
+
import { CompactionTask, defineEntry, defineExtension, GenerationTask, hook, ProviderDoc, UsageDoc, } from "@earendil-works/pi-durable";
|
|
4
|
+
/** Where a conversation was compacted for being idle; the model never reads it. */
|
|
5
|
+
export const IdleCompactionEntry = defineEntry("chopin.idle-compaction");
|
|
6
|
+
/** How much of its prompt cache's lifetime an idle conversation waits before it is compacted. */
|
|
7
|
+
const WAIT = 0.9;
|
|
8
|
+
/** Below this much context, a summary costs more than rewriting the cache on return would. */
|
|
9
|
+
const WORTH_TOKENS = 64_000;
|
|
10
|
+
const PROMPT = `Summarize this conversation so far as a checkpoint another model will continue the work from. Do not call tools and \
|
|
11
|
+
do not answer anything in it; reply with the summary alone. If it starts with an earlier summary, fold that in.
|
|
12
|
+
|
|
13
|
+
Use this format:
|
|
14
|
+
|
|
15
|
+
## Goal
|
|
16
|
+
## Constraints & Preferences
|
|
17
|
+
## Progress
|
|
18
|
+
### Done
|
|
19
|
+
### In Progress
|
|
20
|
+
### Blocked
|
|
21
|
+
## Key Decisions
|
|
22
|
+
## Next Steps
|
|
23
|
+
## Critical Context
|
|
24
|
+
|
|
25
|
+
Keep each section short. Preserve exact file paths, function names and error messages.`;
|
|
26
|
+
/**
|
|
27
|
+
* Compacts a conversation left idle just before its prompt cache expires. The summary is asked for in a request that
|
|
28
|
+
* repeats the conversation's own and adds one message, so the provider reads all but that from its cache.
|
|
29
|
+
*/
|
|
30
|
+
export class IdleCompaction {
|
|
31
|
+
extension;
|
|
32
|
+
#options;
|
|
33
|
+
/** Each conversation's timer, and what stops the compaction it starts. */
|
|
34
|
+
#waiting = new Map();
|
|
35
|
+
/** Summaries ready to be placed, each with the newest entry it covers. */
|
|
36
|
+
#summaries = new Map();
|
|
37
|
+
#harness;
|
|
38
|
+
#closed = false;
|
|
39
|
+
constructor(options) {
|
|
40
|
+
this.#options = options;
|
|
41
|
+
this.extension = defineExtension({
|
|
42
|
+
name: "chopin-idle-compaction",
|
|
43
|
+
hooks: [
|
|
44
|
+
hook(GenerationTask, {
|
|
45
|
+
beforeRequest: (_request, api) => void this.cancel(api.conversationId),
|
|
46
|
+
afterResponse: (message, api) => this.#schedule(api.conversationId, message),
|
|
47
|
+
}),
|
|
48
|
+
hook(CompactionTask, {
|
|
49
|
+
beforeCompact: (compaction, api) => {
|
|
50
|
+
const ready = this.#summaries.get(api.conversationId);
|
|
51
|
+
if (ready === undefined || compaction.instructions !== undefined)
|
|
52
|
+
return undefined;
|
|
53
|
+
this.#summaries.delete(api.conversationId);
|
|
54
|
+
// An entry newer than the summarized request is not in the summary.
|
|
55
|
+
return compaction.entries.every((entry) => entry.id <= ready.tail) ? { summary: ready.summary } : { decline: true };
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/** Starts on `harness`, which runs this extension. */
|
|
62
|
+
attach(harness) {
|
|
63
|
+
this.#harness = harness;
|
|
64
|
+
}
|
|
65
|
+
/** Drops what is scheduled for `conversation`, and stops its compaction if one is asking for a summary. */
|
|
66
|
+
cancel(conversation) {
|
|
67
|
+
const waiting = this.#waiting.get(conversation);
|
|
68
|
+
if (waiting === undefined)
|
|
69
|
+
return;
|
|
70
|
+
this.#waiting.delete(conversation);
|
|
71
|
+
clearTimeout(waiting.timer);
|
|
72
|
+
waiting.stop.abort();
|
|
73
|
+
}
|
|
74
|
+
close() {
|
|
75
|
+
this.#closed = true;
|
|
76
|
+
for (const conversation of [...this.#waiting.keys()])
|
|
77
|
+
this.cancel(conversation);
|
|
78
|
+
}
|
|
79
|
+
/** After a final answer worth compacting, from a model whose cache lifetime is known and that did use its cache. */
|
|
80
|
+
#schedule(conversation, answer) {
|
|
81
|
+
if (this.#closed || answer.stopReason !== "stop")
|
|
82
|
+
return;
|
|
83
|
+
if (calculateContextTokens(answer.usage) < WORTH_TOKENS || answer.usage.cacheRead + answer.usage.cacheWrite === 0)
|
|
84
|
+
return;
|
|
85
|
+
// Requests keep the default retention, the short one.
|
|
86
|
+
const lifetime = this.#options.models.getModel(answer.provider, answer.model)?.promptCache?.short;
|
|
87
|
+
if (lifetime === undefined)
|
|
88
|
+
return;
|
|
89
|
+
const delay = answer.timestamp + lifetime * 1_000 * WAIT - Date.now();
|
|
90
|
+
if (delay <= 0)
|
|
91
|
+
return;
|
|
92
|
+
this.cancel(conversation);
|
|
93
|
+
const stop = new AbortController();
|
|
94
|
+
const timer = setTimeout(() => {
|
|
95
|
+
this.#compact(conversation, answer, stop.signal)
|
|
96
|
+
.catch((error) => void (this.#closed || stop.signal.aborted || this.#options.report?.(error)))
|
|
97
|
+
.finally(() => {
|
|
98
|
+
if (this.#waiting.get(conversation)?.stop === stop)
|
|
99
|
+
this.#waiting.delete(conversation);
|
|
100
|
+
});
|
|
101
|
+
}, delay);
|
|
102
|
+
timer.unref();
|
|
103
|
+
this.#waiting.set(conversation, { timer, stop });
|
|
104
|
+
}
|
|
105
|
+
async #compact(id, answer, signal) {
|
|
106
|
+
const harness = this.#harness;
|
|
107
|
+
if (harness === undefined || !(await this.#options.eligible(id)))
|
|
108
|
+
return;
|
|
109
|
+
const context = withAbortSignal(signal, BACKGROUND_CONTEXT);
|
|
110
|
+
const conversation = await harness.conversation(id, context);
|
|
111
|
+
if (conversation === undefined)
|
|
112
|
+
return;
|
|
113
|
+
const [view, agent, provider] = await Promise.all([
|
|
114
|
+
conversation.context(context),
|
|
115
|
+
conversation.agent(context),
|
|
116
|
+
harness.snapshot(ProviderDoc, id, context),
|
|
117
|
+
]);
|
|
118
|
+
// Only while that answer is still the last word, with the model that gave it, is its cache this request's.
|
|
119
|
+
const last = view.messages.at(-1);
|
|
120
|
+
const tail = view.entries.at(-1);
|
|
121
|
+
const model = agent.model === undefined ? undefined : this.#options.models.getModel(agent.model.provider, agent.model.modelId);
|
|
122
|
+
if (last?.role !== "assistant" || last.timestamp !== answer.timestamp || tail === undefined || provider === undefined)
|
|
123
|
+
return;
|
|
124
|
+
if (model === undefined || model.provider !== answer.provider || model.id !== answer.model)
|
|
125
|
+
return;
|
|
126
|
+
const ask = { role: "user", content: [{ type: "text", text: PROMPT }], timestamp: Date.now() };
|
|
127
|
+
const reply = await this.#options.models.completeSimple(model, { messages: [...view.messages, ask] }, {
|
|
128
|
+
signal,
|
|
129
|
+
sessionId: provider.sessionId,
|
|
130
|
+
...(agent.thinkingLevel === "off" ? {} : { reasoning: agent.thinkingLevel }),
|
|
131
|
+
});
|
|
132
|
+
await conversation.commit(async (tx) => charge(await tx.doc(UsageDoc, id), reply), BACKGROUND_CONTEXT);
|
|
133
|
+
const summary = summaryOf(reply);
|
|
134
|
+
if (summary === undefined || signal.aborted)
|
|
135
|
+
return;
|
|
136
|
+
// Past this point the summary is placed whoever comes back, so nothing waits on `signal`.
|
|
137
|
+
this.#summaries.set(id, { summary, tail: tail.id });
|
|
138
|
+
try {
|
|
139
|
+
const settled = await harness.waitForTask(await conversation.compact(undefined, BACKGROUND_CONTEXT), BACKGROUND_CONTEXT);
|
|
140
|
+
const outcome = settled.state.outcome;
|
|
141
|
+
if (outcome.status === "completed" && (outcome.result.entryId !== undefined || outcome.result.submissionId !== undefined)) {
|
|
142
|
+
await conversation.submit({ type: "write", entry: { kind: IdleCompactionEntry.kind } }, BACKGROUND_CONTEXT);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
this.#summaries.delete(id);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/** The text of a clean stop that calls no tool; anything else is no summary. */
|
|
151
|
+
function summaryOf(reply) {
|
|
152
|
+
if (reply.stopReason !== "stop" || reply.content.some((content) => content.type === "toolCall"))
|
|
153
|
+
return undefined;
|
|
154
|
+
const text = reply.content.flatMap((content) => (content.type === "text" ? [content.text] : [])).join("\n").trim();
|
|
155
|
+
return text === "" ? undefined : text;
|
|
156
|
+
}
|
|
157
|
+
/** Adds what `reply` used to the conversation's ledger, under its model as its answers are. */
|
|
158
|
+
function charge(ledger, reply) {
|
|
159
|
+
const key = `${reply.provider}/${reply.model}`;
|
|
160
|
+
const total = ledger.models[key];
|
|
161
|
+
if (total === undefined)
|
|
162
|
+
return void (ledger.models[key] = structuredClone(reply.usage));
|
|
163
|
+
for (const field of ["input", "output", "cacheRead", "cacheWrite", "totalTokens"])
|
|
164
|
+
total[field] += reply.usage[field];
|
|
165
|
+
for (const field of ["cacheWrite1h", "reasoning"]) {
|
|
166
|
+
const used = reply.usage[field];
|
|
167
|
+
if (used !== undefined)
|
|
168
|
+
total[field] = (total[field] ?? 0) + used;
|
|
169
|
+
}
|
|
170
|
+
for (const field of ["input", "output", "cacheRead", "cacheWrite", "total"])
|
|
171
|
+
total.cost[field] += reply.usage.cost[field];
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=idle-compaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idle-compaction.js","sourceRoot":"","sources":["../src/idle-compaction.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
export { compactionFailure, entryTranscript, entryUpdates, inputText, inWrittenOrder, isCompacting, isRunning, liveUpdates, runInputs, toolText, userText, } from "./acp.js";
|
|
2
2
|
export { serveAcp } from "./bridge.js";
|
|
3
|
+
export { continueAt, conversationProblems, stepText, transcriptMessages } from "./continuation.js";
|
|
4
|
+
export type { ContinuationInput } from "./continuation.js";
|
|
3
5
|
export type { BridgeOptions } from "./bridge.js";
|
|
4
|
-
export {
|
|
6
|
+
export { IdleCompactionEntry } from "./idle-compaction.js";
|
|
7
|
+
export { layerExtension, pinLayerVersions } from "./layer.js";
|
|
8
|
+
export type { LayerSource } from "./layer.js";
|
|
5
9
|
export { McpServers } from "./mcp.js";
|
|
6
10
|
export { AgentService, DAEMON_PATH } from "./service.js";
|
|
7
|
-
export type { AgentServiceOptions } from "./service.js";
|
|
11
|
+
export type { AgentServiceOptions, Changed } from "./service.js";
|
|
8
12
|
export { integratorTokens, launchToken } from "./auth.js";
|
|
9
13
|
export type { Authenticate, IntegratorTokenOptions } from "./auth.js";
|
|
10
14
|
export { ModeDoc } from "./mode.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { compactionFailure, entryTranscript, entryUpdates, inputText, inWrittenOrder, isCompacting, isRunning, liveUpdates, runInputs, toolText, userText, } from "./acp.js";
|
|
2
2
|
export { serveAcp } from "./bridge.js";
|
|
3
|
-
export {
|
|
3
|
+
export { continueAt, conversationProblems, stepText, transcriptMessages } from "./continuation.js";
|
|
4
|
+
export { IdleCompactionEntry } from "./idle-compaction.js";
|
|
5
|
+
export { layerExtension, pinLayerVersions } from "./layer.js";
|
|
4
6
|
export { McpServers } from "./mcp.js";
|
|
5
7
|
export { AgentService, DAEMON_PATH } from "./service.js";
|
|
6
8
|
export { integratorTokens, launchToken } from "./auth.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,SAAS,EACT,cAAc,EACd,YAAY,EACZ,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,QAAQ,GACT,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,SAAS,EACT,cAAc,EACd,YAAY,EACZ,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,QAAQ,GACT,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGnG,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/layer.d.ts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { type Extension } from "@earendil-works/pi-durable";
|
|
2
|
-
import { type Layer } from "@chopin-ai/core";
|
|
2
|
+
import { type Layer, type LayerVersions } from "@chopin-ai/core";
|
|
3
|
+
import type { ConversationRecord, Tx } from "@earendil-works/pi-durable";
|
|
4
|
+
/** The loop's versions a session layers over the hand-written layer: those for every project, and this project's. */
|
|
5
|
+
export interface LayerSource {
|
|
6
|
+
global?: LayerVersions;
|
|
7
|
+
project?: LayerVersions;
|
|
8
|
+
/** When true, an item applies on every model, not only those it passed the gate on. */
|
|
9
|
+
anyModel?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Pins the versions in use to a conversation made without them; a fork keeps the ones it was copied with. */
|
|
12
|
+
export declare function pinLayerVersions(source: LayerSource): (tx: Tx, conversation: ConversationRecord) => Promise<void>;
|
|
3
13
|
/**
|
|
4
14
|
* The portable layer as an extension. Skills and instructions are served from here, outside the workspace, so the
|
|
5
|
-
* agent can read them but never edit them; only evaluation changes the layer. A
|
|
15
|
+
* agent can read them but never edit them; only evaluation changes the layer. A conversation sees the hand-written
|
|
16
|
+
* `layer` with the loop's items for its pinned versions and its model laid over it. A refused call names any required
|
|
6
17
|
* tool missing from `registered`, such as one whose MCP server did not answer.
|
|
7
18
|
*/
|
|
8
|
-
export declare function layerExtension(layer: Layer, registered: ReadonlySet<string
|
|
19
|
+
export declare function layerExtension(layer: Layer, registered: ReadonlySet<string>, source?: LayerSource): Extension;
|
package/dist/layer.js
CHANGED
|
@@ -2,7 +2,27 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import { relative, resolve, sep } from "node:path";
|
|
3
3
|
import { Type } from "@earendil-works/pi-ai";
|
|
4
4
|
import { defineDoc, defineExtension, defineTool, hook, section, ToolTask, } from "@earendil-works/pi-durable";
|
|
5
|
-
import { gateRefusal, skillBody, unmetGates } from "@chopin-ai/core";
|
|
5
|
+
import { effectiveLayer, gateRefusal, skillBody, unmetGates, } from "@chopin-ai/core";
|
|
6
|
+
/** The versions a conversation runs with, fixed when it is made so its prompt does not change under it. */
|
|
7
|
+
const Pinned = defineDoc({
|
|
8
|
+
kind: "chopin.layer-versions",
|
|
9
|
+
version: 1,
|
|
10
|
+
scope: "conversation",
|
|
11
|
+
history: "latest",
|
|
12
|
+
fork: "current",
|
|
13
|
+
initial: () => ({ global: -1, project: -1 }),
|
|
14
|
+
checkpointWhen: () => false,
|
|
15
|
+
});
|
|
16
|
+
/** Pins the versions in use to a conversation made without them; a fork keeps the ones it was copied with. */
|
|
17
|
+
export function pinLayerVersions(source) {
|
|
18
|
+
return async (tx, conversation) => {
|
|
19
|
+
const pinned = await tx.doc(Pinned, conversation.id);
|
|
20
|
+
if (pinned.global !== -1)
|
|
21
|
+
return;
|
|
22
|
+
pinned.global = (await source.global?.current()) ?? 0;
|
|
23
|
+
pinned.project = (await source.project?.current()) ?? 0;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
6
26
|
/** Tools that have completed successfully in a conversation; a fork sees them as of its fork point. */
|
|
7
27
|
const Succeeded = defineDoc({
|
|
8
28
|
kind: "chopin.succeeded",
|
|
@@ -11,22 +31,57 @@ const Succeeded = defineDoc({
|
|
|
11
31
|
history: "rewindable",
|
|
12
32
|
fork: "asOf",
|
|
13
33
|
initial: () => ({ tools: [] }),
|
|
34
|
+
checkpointWhen: () => false,
|
|
14
35
|
});
|
|
15
36
|
/**
|
|
16
37
|
* The portable layer as an extension. Skills and instructions are served from here, outside the workspace, so the
|
|
17
|
-
* agent can read them but never edit them; only evaluation changes the layer. A
|
|
38
|
+
* agent can read them but never edit them; only evaluation changes the layer. A conversation sees the hand-written
|
|
39
|
+
* `layer` with the loop's items for its pinned versions and its model laid over it. A refused call names any required
|
|
18
40
|
* tool missing from `registered`, such as one whose MCP server did not answer.
|
|
19
41
|
*/
|
|
20
|
-
export function layerExtension(layer, registered) {
|
|
21
|
-
const
|
|
42
|
+
export function layerExtension(layer, registered, source = {}) {
|
|
43
|
+
const versioned = source.global !== undefined || source.project !== undefined;
|
|
44
|
+
const resolved = new Map();
|
|
45
|
+
// Versions never change once published, so what a conversation resolves to is kept by version and model.
|
|
46
|
+
const layerFor = async (read, conversation, model, context) => {
|
|
47
|
+
if (!versioned)
|
|
48
|
+
return layer;
|
|
49
|
+
const pinned = (await read.snapshot(Pinned, conversation, context)) ?? { global: 0, project: 0 };
|
|
50
|
+
const runner = {
|
|
51
|
+
model: model === undefined ? "" : `${model.provider}/${model.modelId}`,
|
|
52
|
+
harness: "pi",
|
|
53
|
+
// Without a model, as when a tool resolves a skill, every item counts; the index shown was already filtered.
|
|
54
|
+
anyModel: model === undefined || source.anyModel === true,
|
|
55
|
+
};
|
|
56
|
+
const key = `${pinned.global}/${pinned.project}/${runner.model}/${runner.anyModel === true}`;
|
|
57
|
+
let found = resolved.get(key);
|
|
58
|
+
if (found === undefined) {
|
|
59
|
+
found = (async () => {
|
|
60
|
+
let result = layer;
|
|
61
|
+
if (source.global !== undefined) {
|
|
62
|
+
result = await effectiveLayer(result, source.global, Math.max(0, pinned.global), runner);
|
|
63
|
+
}
|
|
64
|
+
if (source.project !== undefined) {
|
|
65
|
+
result = await effectiveLayer(result, source.project, Math.max(0, pinned.project), runner);
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
})();
|
|
69
|
+
found.catch(() => resolved.delete(key));
|
|
70
|
+
resolved.set(key, found);
|
|
71
|
+
}
|
|
72
|
+
return found;
|
|
73
|
+
};
|
|
22
74
|
const required = [...new Set(layer.gates.flatMap((rule) => rule.requires))];
|
|
23
75
|
return defineExtension({
|
|
24
76
|
name: "chopin-layer",
|
|
25
77
|
sections: [
|
|
26
|
-
section("guidance", () =>
|
|
27
|
-
section("skills", () =>
|
|
78
|
+
section("guidance", async (input, context) => (await layerFor(input.read, input.conversationId, input.agent.model, context)).instructions),
|
|
79
|
+
section("skills", async (input, context) => {
|
|
80
|
+
const { skills } = await layerFor(input.read, input.conversationId, input.agent.model, context);
|
|
81
|
+
return skills.length === 0 ? undefined : skillIndex(skills);
|
|
82
|
+
}),
|
|
28
83
|
],
|
|
29
|
-
tools: layer.skills.length === 0 ? [] : [skillTool(skills)],
|
|
84
|
+
tools: layer.skills.length === 0 && !versioned ? [] : [skillTool(async (name, api, context) => (await layerFor(api, api.conversationId, undefined, context)).skills.find((skill) => skill.name === name))],
|
|
30
85
|
hooks: layer.gates.length === 0 ? [] : [hook(ToolTask, {
|
|
31
86
|
beforeTool: async (call, api, context) => {
|
|
32
87
|
const succeeded = (await api.snapshot(Succeeded, api.conversationId, context))?.tools ?? [];
|
|
@@ -41,7 +96,7 @@ function skillIndex(skills) {
|
|
|
41
96
|
const lines = skills.map((skill) => `- ${skill.name}: ${skill.description}`);
|
|
42
97
|
return ["Skills; read one with the skill tool when its description applies:", ...lines].join("\n");
|
|
43
98
|
}
|
|
44
|
-
function skillTool(
|
|
99
|
+
function skillTool(find) {
|
|
45
100
|
return defineTool({
|
|
46
101
|
name: "skill",
|
|
47
102
|
description: "Read a skill's instructions, or a file the skill bundles.",
|
|
@@ -49,8 +104,8 @@ function skillTool(skills) {
|
|
|
49
104
|
name: Type.String({ description: "The skill's name" }),
|
|
50
105
|
file: Type.Optional(Type.String({ description: "A file inside the skill, relative to it; SKILL.md when omitted" })),
|
|
51
106
|
}),
|
|
52
|
-
execute: async ({ name, file }) => {
|
|
53
|
-
const skill =
|
|
107
|
+
execute: async ({ name, file }, api, context) => {
|
|
108
|
+
const skill = await find(name, api, context);
|
|
54
109
|
if (skill === undefined)
|
|
55
110
|
throw new Error(`no skill named ${name}`);
|
|
56
111
|
const path = resolve(skill.directory, file ?? "SKILL.md");
|
package/dist/layer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer.js","sourceRoot":"","sources":["../src/layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EACL,SAAS,EACT,eAAe,EACf,UAAU,EACV,IAAI,EACJ,OAAO,EACP,QAAQ,GAIT,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"layer.js","sourceRoot":"","sources":["../src/layer.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type Extension } from "@earendil-works/pi-durable";
|
|
2
2
|
import { type McpServer } from "@chopin-ai/core";
|
|
3
3
|
import type { Workspace } from "@chopin-ai/workspace";
|
|
4
|
+
/** The extension a server's tools come in. */
|
|
5
|
+
export declare function mcpExtensionName(server: string): string;
|
|
4
6
|
/**
|
|
5
7
|
* One owner's MCP servers. A command server runs inside the owner's workspace, never on the service host: the
|
|
6
8
|
* layer may change, and what it starts must stay as confined as the agent itself.
|
|
@@ -14,6 +16,18 @@ export declare class McpServers {
|
|
|
14
16
|
constructor(servers: Readonly<Record<string, McpServer>>, workspace: Workspace);
|
|
15
17
|
/** Connects every server and offers its tools, one extension per server; one that cannot be reached is left out. */
|
|
16
18
|
connect(report: (error: Error) => void): Promise<Extension[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Serves `server` under `name` from now on, in place of any by that name, and offers its tools; none while it
|
|
21
|
+
* cannot be reached, which a retry tries again. Its tools name the server, so a replaced one's names are reused.
|
|
22
|
+
*/
|
|
23
|
+
set(name: string, server: McpServer, report: (error: Error) => void): Promise<Extension[]>;
|
|
24
|
+
/** Stops serving `name`, answering with the names of the tools it offered. */
|
|
25
|
+
remove(name: string): string[];
|
|
26
|
+
/** How many tools `name` offers, or why it offers none while it cannot be reached. */
|
|
27
|
+
status(name: string): {
|
|
28
|
+
tools: number;
|
|
29
|
+
error?: string;
|
|
30
|
+
};
|
|
17
31
|
/**
|
|
18
32
|
* Tries the unavailable servers again and offers the tools of those that answer now; a server in the workspace is
|
|
19
33
|
* tried only while the workspace runs, so trying never wakes one stopped for being idle.
|
package/dist/mcp.js
CHANGED
|
@@ -10,6 +10,13 @@ function packageVersion() {
|
|
|
10
10
|
.then((text) => JSON.parse(text).version ?? "unknown", () => "unknown");
|
|
11
11
|
return version;
|
|
12
12
|
}
|
|
13
|
+
/** A command server the workspace will not run, as one that runs only its execution daemon will not. */
|
|
14
|
+
class Refused extends Error {
|
|
15
|
+
}
|
|
16
|
+
/** The extension a server's tools come in. */
|
|
17
|
+
export function mcpExtensionName(server) {
|
|
18
|
+
return `chopin-mcp-${server}`;
|
|
19
|
+
}
|
|
13
20
|
/**
|
|
14
21
|
* One owner's MCP servers. A command server runs inside the owner's workspace, never on the service host: the
|
|
15
22
|
* layer may change, and what it starts must stay as confined as the agent itself.
|
|
@@ -18,6 +25,10 @@ export class McpServers {
|
|
|
18
25
|
#servers;
|
|
19
26
|
#workspace;
|
|
20
27
|
#clients = new Map();
|
|
28
|
+
/** The tools each server offered when last reached. */
|
|
29
|
+
#tools = new Map();
|
|
30
|
+
/** Why each server that could not be reached last was not. */
|
|
31
|
+
#failures = new Map();
|
|
21
32
|
#closed = false;
|
|
22
33
|
/** Names of the offered tools that declare they change nothing. */
|
|
23
34
|
readOnly = new Set();
|
|
@@ -31,12 +42,49 @@ export class McpServers {
|
|
|
31
42
|
connect(report) {
|
|
32
43
|
return this.#offer(Object.keys(this.#servers), report);
|
|
33
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Serves `server` under `name` from now on, in place of any by that name, and offers its tools; none while it
|
|
47
|
+
* cannot be reached, which a retry tries again. Its tools name the server, so a replaced one's names are reused.
|
|
48
|
+
*/
|
|
49
|
+
set(name, server, report) {
|
|
50
|
+
this.#forget(name);
|
|
51
|
+
this.#servers = { ...this.#servers, [name]: server };
|
|
52
|
+
return this.#offer([name], report);
|
|
53
|
+
}
|
|
54
|
+
/** Stops serving `name`, answering with the names of the tools it offered. */
|
|
55
|
+
remove(name) {
|
|
56
|
+
const tools = this.#forget(name);
|
|
57
|
+
const { [name]: _gone, ...rest } = this.#servers;
|
|
58
|
+
this.#servers = rest;
|
|
59
|
+
return tools;
|
|
60
|
+
}
|
|
61
|
+
/** How many tools `name` offers, or why it offers none while it cannot be reached. */
|
|
62
|
+
status(name) {
|
|
63
|
+
const error = this.#failures.get(name);
|
|
64
|
+
return { tools: this.#tools.get(name)?.length ?? 0, ...(error !== undefined && { error }) };
|
|
65
|
+
}
|
|
66
|
+
/** Lets go of everything known of `name`: its client, its tools and why it failed; answers with those tools. */
|
|
67
|
+
#forget(name) {
|
|
68
|
+
const client = this.#clients.get(name);
|
|
69
|
+
if (client !== undefined)
|
|
70
|
+
this.#drop(name, client);
|
|
71
|
+
const tools = this.#tools.get(name) ?? [];
|
|
72
|
+
for (const tool of tools)
|
|
73
|
+
this.readOnly.delete(tool);
|
|
74
|
+
this.#tools.delete(name);
|
|
75
|
+
this.#failures.delete(name);
|
|
76
|
+
this.unavailable.delete(name);
|
|
77
|
+
return tools;
|
|
78
|
+
}
|
|
34
79
|
/**
|
|
35
80
|
* Tries the unavailable servers again and offers the tools of those that answer now; a server in the workspace is
|
|
36
81
|
* tried only while the workspace runs, so trying never wakes one stopped for being idle.
|
|
37
82
|
*/
|
|
38
83
|
async retry(report) {
|
|
39
|
-
const inWorkspace = (server) =>
|
|
84
|
+
const inWorkspace = (server) => {
|
|
85
|
+
const known = this.#servers[server];
|
|
86
|
+
return known !== undefined && "command" in known;
|
|
87
|
+
};
|
|
40
88
|
const unavailable = [...this.unavailable];
|
|
41
89
|
const running = unavailable.some(inWorkspace) && (await this.#workspace.state().catch(() => undefined)) === "running";
|
|
42
90
|
return this.#offer(unavailable.filter((server) => running || !inWorkspace(server)), report, false);
|
|
@@ -50,20 +98,38 @@ export class McpServers {
|
|
|
50
98
|
}
|
|
51
99
|
async #offer(servers, report, wake = true) {
|
|
52
100
|
const offered = await Promise.all(servers.map(async (server) => {
|
|
101
|
+
// A server replaced or taken away while it was being reached is not offered: its successor is, by whoever set it.
|
|
102
|
+
const serving = this.#servers[server];
|
|
103
|
+
if (serving === undefined)
|
|
104
|
+
return [];
|
|
53
105
|
const client = this.#client(server, wake);
|
|
106
|
+
const current = () => this.#servers[server] === serving;
|
|
54
107
|
try {
|
|
55
108
|
const listed = await (await client).listTools();
|
|
109
|
+
if (!current()) {
|
|
110
|
+
this.#drop(server, client);
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
56
113
|
const unique = [...new Map(listed.map((tool) => [tool.name, tool])).values()];
|
|
57
114
|
if (unique.length < listed.length)
|
|
58
115
|
report(new Error(`MCP server ${server} lists a tool name twice; one of each is offered`));
|
|
59
116
|
this.unavailable.delete(server);
|
|
60
|
-
|
|
117
|
+
this.#failures.delete(server);
|
|
118
|
+
const tools = unique.map((tool) => this.#tool(server, tool));
|
|
119
|
+
this.#tools.set(server, tools.map((tool) => tool.name));
|
|
120
|
+
return [defineExtension({ name: mcpExtensionName(server), tools })];
|
|
61
121
|
}
|
|
62
122
|
catch (error) {
|
|
63
123
|
// A client that connected but cannot list its tools is let go, so the next try starts afresh.
|
|
64
124
|
this.#drop(server, client);
|
|
65
|
-
if (this.#closed)
|
|
125
|
+
if (this.#closed || !current())
|
|
66
126
|
return [];
|
|
127
|
+
this.#failures.set(server, error.message);
|
|
128
|
+
// A workspace that cannot run the server never will, so it is told once and not tried again.
|
|
129
|
+
if (error instanceof Refused) {
|
|
130
|
+
report(new Error(`MCP server ${server} cannot run here: ${error.message}`));
|
|
131
|
+
return [];
|
|
132
|
+
}
|
|
67
133
|
if (!this.unavailable.has(server))
|
|
68
134
|
report(new Error(`MCP server ${server} is unavailable: ${error.message}`));
|
|
69
135
|
this.unavailable.add(server);
|
|
@@ -101,9 +167,16 @@ export class McpServers {
|
|
|
101
167
|
async #transport(server, wake) {
|
|
102
168
|
if (!("command" in server))
|
|
103
169
|
return new StreamableHttpTransport({ url: server.url, ...(server.headers && { headers: server.headers }) });
|
|
170
|
+
let launch;
|
|
171
|
+
try {
|
|
172
|
+
launch = this.#workspace.command([server.command, ...(server.args ?? [])], server.env);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
throw new Refused(error.message, { cause: error });
|
|
176
|
+
}
|
|
104
177
|
if (wake)
|
|
105
178
|
await this.#workspace.start();
|
|
106
|
-
const { argv: [command, ...args], env } =
|
|
179
|
+
const { argv: [command, ...args], env } = launch;
|
|
107
180
|
return new StdioTransport({ command: command, args, env });
|
|
108
181
|
}
|
|
109
182
|
#tool(server, tool) {
|
package/dist/mcp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAyC,MAAM,4BAA4B,CAAC;AACpG,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,uBAAuB,EAAE,YAAY,EAAqB,MAAM,wBAAwB,CAAC;AAC7H,OAAO,EAAE,WAAW,EAAkB,MAAM,iBAAiB,CAAC;AAK9D,IAAI,OAAoC,CAAC;AAEzC,iGAAiG;AACjG,SAAS,cAAc;IACrB,OAAO,KAAK,QAAQ,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;SACtE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAA0B,CAAC,OAAO,IAAI,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACpG,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,UAAU;
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
package/dist/mode.js
CHANGED
|
@@ -7,6 +7,7 @@ export const ModeDoc = defineDoc({
|
|
|
7
7
|
history: "latest",
|
|
8
8
|
fork: "current",
|
|
9
9
|
initial: () => ({ mode: "full" }),
|
|
10
|
+
checkpointWhen: () => false,
|
|
10
11
|
});
|
|
11
12
|
/** A conversation's name, as its owner gave it; empty until then. */
|
|
12
13
|
export const NameDoc = defineDoc({
|
|
@@ -16,6 +17,7 @@ export const NameDoc = defineDoc({
|
|
|
16
17
|
history: "latest",
|
|
17
18
|
fork: "current",
|
|
18
19
|
initial: () => ({ name: "" }),
|
|
20
|
+
checkpointWhen: () => false,
|
|
19
21
|
});
|
|
20
22
|
export function modeExtension(readOnly) {
|
|
21
23
|
return defineExtension({
|
package/dist/mode.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mode.js","sourceRoot":"","sources":["../src/mode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAkB,MAAM,4BAA4B,CAAC;AAGxG,oDAAoD;AACpD,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAiB;IAC/C,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,cAAc;IACrB,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"mode.js","sourceRoot":"","sources":["../src/mode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAkB,MAAM,4BAA4B,CAAC;AAGxG,oDAAoD;AACpD,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAiB;IAC/C,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,cAAc;IACrB,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACjC,cAAc,EAAE,GAAG,EAAE,CAAC,KAAK;CAC5B,CAAC,CAAC;AAEH,qEAAqE;AACrE,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAmB;IACjD,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,cAAc;IACrB,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IAC7B,cAAc,EAAE,GAAG,EAAE,CAAC,KAAK;CAC5B,CAAC,CAAC;AAEH,MAAM,UAAU,aAAa,CAAC,QAAmC;IAC/D,OAAO,eAAe,CAAC;QACrB,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE;gBACrB,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;oBACvC,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC;oBACxF,IAAI,IAAI,KAAK,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;wBAAE,OAAO,SAAS,CAAC;oBAC7D,OAAO,EAAE,KAAK,EAAE,yEAAyE,EAAE,CAAC;gBAC9F,CAAC;aACF,CAAC,CAAC;KACJ,CAAC,CAAC;AACL,CAAC"}
|