cloving 1.0.1 → 1.2.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/README.md +251 -20
- package/assets/watch-fonts/fira-code-OFL.md +93 -0
- package/assets/watch-fonts/fira-code-latin-400-normal.woff2 +0 -0
- package/assets/watch-fonts/fira-code-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-OFL.md +93 -0
- package/assets/watch-fonts/heebo-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-latin-700-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-latin-800-normal.woff2 +0 -0
- package/assets/watch-fonts/manifest.json +112 -0
- package/assets/watch-fonts/space-grotesk-OFL.md +93 -0
- package/assets/watch-fonts/space-grotesk-latin-400-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-600-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-700-normal.woff2 +0 -0
- package/dist/src/authority/commands.d.ts +1 -0
- package/dist/src/authority/commands.js +33 -4
- package/dist/src/authority/dispatch-decision.d.ts +1 -0
- package/dist/src/authority/dispatch-decision.js +7 -4
- package/dist/src/authority/events.js +2 -2
- package/dist/src/authority/handoff-chain.d.ts +24 -0
- package/dist/src/authority/handoff-chain.js +46 -0
- package/dist/src/authority/reconciliation.d.ts +3 -0
- package/dist/src/authority/reconciliation.js +21 -5
- package/dist/src/authority/transitions.d.ts +1 -1
- package/dist/src/authority/transitions.js +5 -0
- package/dist/src/broker/actor/authority-queries.d.ts +4 -0
- package/dist/src/broker/actor/authority-queries.js +51 -2
- package/dist/src/broker/actor/authority-session.d.ts +2 -0
- package/dist/src/broker/actor/authority-session.js +3 -4
- package/dist/src/broker/actor/delivery-intents.d.ts +1 -0
- package/dist/src/broker/actor/effect-delivery.js +9 -0
- package/dist/src/broker/authority-admission.js +13 -5
- package/dist/src/chats/analysis-batches.d.ts +42 -0
- package/dist/src/chats/analysis-batches.js +97 -0
- package/dist/src/chats/analysis-checkpoint.d.ts +29 -0
- package/dist/src/chats/analysis-checkpoint.js +31 -0
- package/dist/src/chats/analysis-contract.d.ts +80 -0
- package/dist/src/chats/analysis-contract.js +16 -0
- package/dist/src/chats/analysis-data.d.ts +3 -0
- package/dist/src/chats/analysis-data.js +85 -0
- package/dist/src/chats/analysis-input.d.ts +18 -0
- package/dist/src/chats/analysis-input.js +97 -0
- package/dist/src/chats/analysis-links.d.ts +2 -0
- package/dist/src/chats/analysis-links.js +25 -0
- package/dist/src/chats/analysis-merge.d.ts +16 -0
- package/dist/src/chats/analysis-merge.js +134 -0
- package/dist/src/chats/analysis-prompt.d.ts +18 -0
- package/dist/src/chats/analysis-prompt.js +42 -0
- package/dist/src/chats/analysis-proposal.d.ts +4 -0
- package/dist/src/chats/analysis-proposal.js +41 -0
- package/dist/src/chats/analysis-provenance.d.ts +4 -0
- package/dist/src/chats/analysis-provenance.js +99 -0
- package/dist/src/chats/analysis-shape.d.ts +4 -0
- package/dist/src/chats/analysis-shape.js +235 -0
- package/dist/src/chats/analysis.d.ts +3 -0
- package/dist/src/chats/analysis.js +42 -0
- package/dist/src/chats/corpus-input.d.ts +5 -0
- package/dist/src/chats/corpus-input.js +288 -0
- package/dist/src/chats/destination.js +3 -1
- package/dist/src/chats/import.d.ts +8 -6
- package/dist/src/chats/import.js +195 -23
- package/dist/src/chats/input-file.d.ts +3 -0
- package/dist/src/chats/input-file.js +32 -0
- package/dist/src/chats/normalize.d.ts +11 -2
- package/dist/src/chats/normalize.js +18 -2
- package/dist/src/chats/previous-import.d.ts +5 -0
- package/dist/src/chats/previous-import.js +34 -0
- package/dist/src/chats/reader.d.ts +7 -1
- package/dist/src/chats/reader.js +46 -15
- package/dist/src/chats/redact-import.d.ts +14 -0
- package/dist/src/chats/redact-import.js +141 -0
- package/dist/src/chats/redaction.d.ts +41 -0
- package/dist/src/chats/redaction.js +161 -0
- package/dist/src/chats/reference-mapping.d.ts +16 -0
- package/dist/src/chats/reference-mapping.js +153 -0
- package/dist/src/chats/revision-input.d.ts +3 -0
- package/dist/src/chats/revision-input.js +180 -0
- package/dist/src/chats/revision.d.ts +48 -0
- package/dist/src/chats/revision.js +94 -0
- package/dist/src/chats/selection.d.ts +25 -0
- package/dist/src/chats/selection.js +109 -0
- package/dist/src/chats/source.d.ts +23 -0
- package/dist/src/chats/source.js +135 -0
- package/dist/src/chats/structure.d.ts +57 -0
- package/dist/src/chats/structure.js +216 -0
- package/dist/src/chats/workflow-generation-projection.d.ts +8 -0
- package/dist/src/chats/workflow-generation-projection.js +75 -0
- package/dist/src/chats/workflow-generation-source.d.ts +25 -0
- package/dist/src/chats/workflow-generation-source.js +124 -0
- package/dist/src/chats/workflow-generation-text.d.ts +23 -0
- package/dist/src/chats/workflow-generation-text.js +74 -0
- package/dist/src/chats/workflow-generation.d.ts +69 -0
- package/dist/src/chats/workflow-generation.js +142 -0
- package/dist/src/cli/arguments.d.ts +8 -0
- package/dist/src/cli/arguments.js +94 -13
- package/dist/src/cli/client.d.ts +1 -0
- package/dist/src/cli/client.js +38 -1
- package/dist/src/cli/commands.d.ts +3 -0
- package/dist/src/cli/commands.js +29 -11
- package/dist/src/cli/main.d.ts +2 -1
- package/dist/src/cli/main.js +61 -14
- package/dist/src/cli/render.d.ts +3 -0
- package/dist/src/cli/render.js +122 -7
- package/dist/src/cli/usage-render.d.ts +3 -0
- package/dist/src/cli/usage-render.js +28 -0
- package/dist/src/cli/usage.d.ts +3 -2
- package/dist/src/cli/usage.js +42 -7
- package/dist/src/cli/watch-actions.d.ts +10 -0
- package/dist/src/cli/watch-actions.js +58 -0
- package/dist/src/cli/watch-board-view.d.ts +44 -1
- package/dist/src/cli/watch-board-view.js +137 -18
- package/dist/src/cli/watch-board.d.ts +7 -1
- package/dist/src/cli/watch-board.js +48 -11
- package/dist/src/cli/watch-card-client.d.ts +1 -0
- package/dist/src/cli/watch-card-client.js +44 -0
- package/dist/src/cli/watch-card-forms.d.ts +2 -0
- package/dist/src/cli/watch-card-forms.js +33 -0
- package/dist/src/cli/watch-card-reply.d.ts +5 -0
- package/dist/src/cli/watch-card-reply.js +34 -0
- package/dist/src/cli/watch-card-view.d.ts +40 -0
- package/dist/src/cli/watch-card-view.js +86 -0
- package/dist/src/cli/watch-client.d.ts +1 -0
- package/dist/src/cli/watch-client.js +122 -0
- package/dist/src/cli/watch-model.d.ts +10 -4
- package/dist/src/cli/watch-model.js +61 -67
- package/dist/src/cli/watch-page.d.ts +1 -1
- package/dist/src/cli/watch-page.js +89 -86
- package/dist/src/cli/watch-phases.js +3 -3
- package/dist/src/cli/watch-pr-board.d.ts +3 -0
- package/dist/src/cli/watch-pr-board.js +26 -0
- package/dist/src/cli/watch-pr-command.d.ts +18 -0
- package/dist/src/cli/watch-pr-command.js +74 -0
- package/dist/src/cli/watch-pr-identity.d.ts +32 -0
- package/dist/src/cli/watch-pr-identity.js +87 -0
- package/dist/src/cli/watch-pr-observer.d.ts +20 -0
- package/dist/src/cli/watch-pr-observer.js +150 -0
- package/dist/src/cli/watch-pr-settings.d.ts +8 -0
- package/dist/src/cli/watch-pr-settings.js +47 -0
- package/dist/src/cli/watch-pull-request.d.ts +10 -0
- package/dist/src/cli/watch-pull-request.js +130 -0
- package/dist/src/cli/watch-reads.d.ts +7 -1
- package/dist/src/cli/watch-reads.js +44 -18
- package/dist/src/cli/watch-render.d.ts +29 -2
- package/dist/src/cli/watch-render.js +11 -3
- package/dist/src/cli/watch-run-input.d.ts +14 -0
- package/dist/src/cli/watch-run-input.js +49 -0
- package/dist/src/cli/watch-server.d.ts +3 -0
- package/dist/src/cli/watch-server.js +77 -8
- package/dist/src/cli/watch-start-view.d.ts +18 -0
- package/dist/src/cli/watch-start-view.js +77 -0
- package/dist/src/cli/watch-turn.d.ts +1 -0
- package/dist/src/cli/watch-turn.js +8 -3
- package/dist/src/cli/watch-usage.d.ts +6 -0
- package/dist/src/cli/watch-usage.js +65 -0
- package/dist/src/cli/watch-view.d.ts +22 -0
- package/dist/src/cli/watch-view.js +111 -19
- package/dist/src/cli.js +48 -6
- package/dist/src/daemon/analysis-launch.d.ts +5 -0
- package/dist/src/daemon/analysis-launch.js +81 -0
- package/dist/src/daemon/analysis-token.d.ts +6 -0
- package/dist/src/daemon/analysis-token.js +88 -0
- package/dist/src/daemon/analysis-worker.d.ts +20 -0
- package/dist/src/daemon/analysis-worker.js +271 -0
- package/dist/src/daemon/chats-batch-binding.d.ts +23 -0
- package/dist/src/daemon/chats-batch-binding.js +99 -0
- package/dist/src/daemon/chats-capture.d.ts +18 -0
- package/dist/src/daemon/chats-capture.js +194 -0
- package/dist/src/daemon/chats-checkpoints.d.ts +41 -0
- package/dist/src/daemon/chats-checkpoints.js +186 -0
- package/dist/src/daemon/chats-files.d.ts +42 -0
- package/dist/src/daemon/chats-files.js +252 -0
- package/dist/src/daemon/chats-follow-up.d.ts +38 -0
- package/dist/src/daemon/chats-follow-up.js +180 -0
- package/dist/src/daemon/chats-question.d.ts +15 -0
- package/dist/src/daemon/chats-question.js +93 -0
- package/dist/src/daemon/chats-worker.d.ts +13 -0
- package/dist/src/daemon/chats-worker.js +201 -0
- package/dist/src/daemon/claude-turn.d.ts +11 -0
- package/dist/src/daemon/claude-turn.js +96 -15
- package/dist/src/daemon/claude-worker.d.ts +2 -1
- package/dist/src/daemon/claude-worker.js +92 -45
- package/dist/src/daemon/codex-stream.js +16 -0
- package/dist/src/daemon/daemon.d.ts +8 -1
- package/dist/src/daemon/daemon.js +51 -14
- package/dist/src/daemon/delivery-router.js +6 -0
- package/dist/src/daemon/github-calls.d.ts +4 -0
- package/dist/src/daemon/github-calls.js +16 -7
- package/dist/src/daemon/github-ci.d.ts +6 -0
- package/dist/src/daemon/github-ci.js +170 -0
- package/dist/src/daemon/github-merge-call.d.ts +14 -0
- package/dist/src/daemon/github-merge-call.js +73 -0
- package/dist/src/daemon/github-merge.d.ts +3 -5
- package/dist/src/daemon/github-merge.js +52 -95
- package/dist/src/daemon/github-methods.d.ts +28 -0
- package/dist/src/daemon/github-methods.js +84 -16
- package/dist/src/daemon/github-operation.d.ts +2 -0
- package/dist/src/daemon/github-retry.d.ts +6 -0
- package/dist/src/daemon/github-retry.js +49 -0
- package/dist/src/daemon/github-ticket-status.d.ts +3 -0
- package/dist/src/daemon/github-ticket-status.js +294 -0
- package/dist/src/daemon/github-worker.js +2 -1
- package/dist/src/daemon/handoff-worker.d.ts +10 -0
- package/dist/src/daemon/handoff-worker.js +232 -0
- package/dist/src/daemon/issue-queue.d.ts +2 -0
- package/dist/src/daemon/issue-queue.js +186 -43
- package/dist/src/daemon/notify-journal.d.ts +18 -0
- package/dist/src/daemon/notify-journal.js +108 -0
- package/dist/src/daemon/notify-message.js +2 -1
- package/dist/src/daemon/notify.js +176 -37
- package/dist/src/daemon/operation-journal.d.ts +1 -0
- package/dist/src/daemon/operation-journal.js +4 -2
- package/dist/src/daemon/retrying-turn.d.ts +12 -0
- package/dist/src/daemon/retrying-turn.js +231 -0
- package/dist/src/daemon/ticket-dependency-waits.d.ts +18 -0
- package/dist/src/daemon/ticket-dependency-waits.js +60 -0
- package/dist/src/daemon/ticket-registration.d.ts +8 -4
- package/dist/src/daemon/ticket-registration.js +76 -22
- package/dist/src/daemon/ticket-source.d.ts +4 -1
- package/dist/src/daemon/ticket-source.js +8 -2
- package/dist/src/decision-visibility.d.ts +2 -0
- package/dist/src/decision-visibility.js +10 -0
- package/dist/src/execution-pin.d.ts +4 -0
- package/dist/src/execution-pin.js +23 -2
- package/dist/src/host/start-delivery.d.ts +2 -1
- package/dist/src/host/start-delivery.js +1 -1
- package/dist/src/host/step-bridge-host.d.ts +1 -0
- package/dist/src/host/step-bridge-host.js +16 -0
- package/dist/src/host/world-reconciliation.d.ts +3 -0
- package/dist/src/host/world-reconciliation.js +9 -0
- package/dist/src/host/world-runs.js +14 -1
- package/dist/src/issue-identity.d.ts +6 -0
- package/dist/src/issue-identity.js +23 -0
- package/dist/src/service/queue-runs.d.ts +3 -0
- package/dist/src/service/queue-runs.js +39 -0
- package/dist/src/service/registry.d.ts +8 -2
- package/dist/src/service/registry.js +20 -8
- package/dist/src/service/replies.d.ts +2 -0
- package/dist/src/service/run-handlers.js +54 -30
- package/dist/src/service/service.d.ts +3 -0
- package/dist/src/service/service.js +3 -1
- package/dist/src/service/submission-handler.d.ts +1 -0
- package/dist/src/service/submission-handler.js +92 -13
- package/dist/src/service/worker-totals.d.ts +3 -0
- package/dist/src/service/worker-totals.js +52 -0
- package/dist/src/step-bridge.d.ts +9 -0
- package/dist/src/steps/handoff.d.ts +2 -0
- package/dist/src/steps/handoff.js +13 -0
- package/dist/src/ticket-dependencies.d.ts +1 -0
- package/dist/src/ticket-dependencies.js +15 -0
- package/dist/src/ticket-status.d.ts +8 -0
- package/dist/src/ticket-status.js +48 -0
- package/dist/src/token-prices.d.ts +21 -0
- package/dist/src/token-prices.js +108 -0
- package/dist/src/worker-usage.d.ts +31 -0
- package/dist/src/worker-usage.js +44 -0
- package/dist/src/workflow-admission.d.ts +1 -0
- package/dist/src/workflow-candidate.d.ts +29 -0
- package/dist/src/workflow-candidate.js +60 -0
- package/dist/src/workflow-contracts.d.ts +4 -0
- package/dist/src/workflow-contracts.js +32 -5
- package/dist/src/workflow-declaration.d.ts +12 -1
- package/dist/src/workflow-declaration.js +71 -13
- package/dist/src/workflow-discovery.d.ts +18 -0
- package/dist/src/workflow-discovery.js +33 -0
- package/dist/src/workflow-refusals.d.ts +6 -0
- package/dist/src/workflow-refusals.js +39 -0
- package/dist/src/workflows.d.ts +3 -1
- package/dist/src/workflows.js +2 -0
- package/dist/tools/admit-workflow.d.ts +13 -0
- package/dist/tools/admit-workflow.js +94 -0
- package/dist/tools/self-host-processes.js +7 -2
- package/dist/tools/self-host-project.d.ts +17 -0
- package/dist/tools/self-host-project.js +177 -0
- package/dist/tools/self-host-workflows.d.ts +1 -1
- package/dist/tools/self-host-workflows.js +2 -2
- package/dist/tools/self-host.js +30 -84
- package/dist/tools/self-update-host.d.ts +7 -0
- package/dist/tools/self-update-host.js +48 -1
- package/dist/tools/self-update.d.ts +1 -0
- package/dist/tools/self-update.js +85 -13
- package/dist/tools/workflow-bundle-dependencies.d.ts +5 -0
- package/dist/tools/workflow-bundle-dependencies.js +93 -0
- package/dist/tools/workflow-bundles.d.ts +20 -0
- package/dist/tools/workflow-bundles.js +173 -0
- package/dist/tools/workflow-candidate-counts.d.ts +8 -0
- package/dist/tools/workflow-candidate-counts.js +251 -0
- package/dist/tools/workflow-candidate-program.d.ts +11 -0
- package/dist/tools/workflow-candidate-program.js +78 -0
- package/dist/tools/workflow-candidate-source.d.ts +6 -0
- package/dist/tools/workflow-candidate-source.js +107 -0
- package/dist/tools/workflow-candidate-syntax.d.ts +15 -0
- package/dist/tools/workflow-candidate-syntax.js +219 -0
- package/dist/tools/workflow-folder-capture.d.ts +17 -0
- package/dist/tools/workflow-folder-capture.js +216 -0
- package/dist/tools/workflow-folders.d.ts +33 -0
- package/dist/tools/workflow-folders.js +150 -0
- package/dist/tools/workflow-source-effects.d.ts +10 -0
- package/dist/tools/workflow-source-effects.js +213 -0
- package/dist/workflows/analyze-chats.d.ts +15 -0
- package/dist/workflows/analyze-chats.declaration.json +22 -0
- package/dist/workflows/analyze-chats.js +250 -0
- package/dist/workflows/develop-prd.js +71 -3
- package/dist/workflows/develop-ticket.d.ts +1 -7
- package/dist/workflows/develop-ticket.js +47 -141
- package/dist/workflows/issue-labels.d.ts +3 -1
- package/dist/workflows/issue-labels.js +34 -0
- package/dist/workflows/ticket-prompts.d.ts +35 -0
- package/dist/workflows/ticket-prompts.js +143 -0
- package/package.json +25 -5
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { saveQuestion } from "./chats-question.js";
|
|
2
|
+
import { saveAcceptedAnalysis, saveFollowUp, } from "./chats-follow-up.js";
|
|
3
|
+
import { record } from "../protocol.js";
|
|
4
|
+
import { validateAnalysis } from "../chats/analysis.js";
|
|
5
|
+
import { analysisDocumentBytes, analysisEvidence, analysisSaveInput, validAnalysisImportId, } from "../chats/analysis-input.js";
|
|
6
|
+
import { analysisBatchData, prepareAnalysisBatch, } from "../chats/analysis-batches.js";
|
|
7
|
+
import { captureAnalysisSnapshot, readCapturedAnalysisSnapshot, findAnalysisCapture, } from "./chats-capture.js";
|
|
8
|
+
import { operationKey } from "./operation-journal.js";
|
|
9
|
+
import { analysisDirectory } from "./chats-files.js";
|
|
10
|
+
function completed(intent, result) {
|
|
11
|
+
return {
|
|
12
|
+
kind: "completed",
|
|
13
|
+
worker: "chats",
|
|
14
|
+
receipt: operationKey(intent.operationId),
|
|
15
|
+
result: JSON.stringify(result),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function refused(code, codes = [code]) {
|
|
19
|
+
return {
|
|
20
|
+
kind: "failed",
|
|
21
|
+
reason: code,
|
|
22
|
+
result: JSON.stringify({ kind: "blocked", codes }),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function bounded(text) {
|
|
26
|
+
if (Buffer.byteLength(text) > analysisDocumentBytes)
|
|
27
|
+
throw new Error("analysis-too-large");
|
|
28
|
+
}
|
|
29
|
+
function ownIntent(intent) {
|
|
30
|
+
return (intent.kind === "protected-effect" &&
|
|
31
|
+
intent.capability === "chats" &&
|
|
32
|
+
["read-analysis", "save-analysis"].includes(intent.method ?? "") &&
|
|
33
|
+
intent.payload !== undefined &&
|
|
34
|
+
intent.leaseGeneration !== undefined);
|
|
35
|
+
}
|
|
36
|
+
async function payloadOf(settings, intent) {
|
|
37
|
+
if (!ownIntent(intent) || intent.payload === undefined)
|
|
38
|
+
throw new Error("unsupported-effect");
|
|
39
|
+
if ((await settings.workflowId(intent.runId)) !== "analyze-chats")
|
|
40
|
+
throw new Error("workflow-not-allowed");
|
|
41
|
+
const text = await settings.document(intent.payload);
|
|
42
|
+
if (text === undefined)
|
|
43
|
+
throw new Error("payload-not-available");
|
|
44
|
+
bounded(text);
|
|
45
|
+
const payload = record(JSON.parse(text));
|
|
46
|
+
if (payload === undefined)
|
|
47
|
+
throw new Error("analysis-input-refused");
|
|
48
|
+
const importId = payload["importId"];
|
|
49
|
+
if (typeof importId !== "string" || importId === "")
|
|
50
|
+
throw new Error("analysis-input-refused");
|
|
51
|
+
if (!validAnalysisImportId(importId))
|
|
52
|
+
throw new Error("invalid-import-id");
|
|
53
|
+
if (intent.target !== importId)
|
|
54
|
+
throw new Error("analysis-input-refused");
|
|
55
|
+
return payload;
|
|
56
|
+
}
|
|
57
|
+
async function read(settings, call) {
|
|
58
|
+
const { importId } = call;
|
|
59
|
+
let directory;
|
|
60
|
+
try {
|
|
61
|
+
directory = await analysisDirectory(settings.runtimeDirectory, importId);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (Reflect.get(Object(error), "code") === "ENOENT")
|
|
65
|
+
throw new Error("redaction-required", { cause: error });
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
const capture = await captureAnalysisSnapshot(directory, {
|
|
69
|
+
importId,
|
|
70
|
+
runId: call.intent.runId,
|
|
71
|
+
});
|
|
72
|
+
const snapshot = await readCapturedAnalysisSnapshot(directory, capture);
|
|
73
|
+
const batch = prepareAnalysisBatch(snapshot, {
|
|
74
|
+
nextRecordIndex: 0,
|
|
75
|
+
completedBatchCount: 0,
|
|
76
|
+
previousResult: null,
|
|
77
|
+
});
|
|
78
|
+
if (batch.kind === "refused")
|
|
79
|
+
throw new Error(batch.code);
|
|
80
|
+
const result = analysisBatchData(batch, { digest: capture.digest, snapshot });
|
|
81
|
+
bounded(JSON.stringify(result));
|
|
82
|
+
return completed(call.intent, result);
|
|
83
|
+
}
|
|
84
|
+
async function saveInput(settings, call) {
|
|
85
|
+
if ("snapshot" in call.payload)
|
|
86
|
+
return analysisSaveInput(call.payload);
|
|
87
|
+
const importId = String(call.payload["importId"]);
|
|
88
|
+
const directory = await analysisDirectory(settings.runtimeDirectory, importId);
|
|
89
|
+
const capture = await findAnalysisCapture(directory, {
|
|
90
|
+
runId: call.intent.runId,
|
|
91
|
+
importId,
|
|
92
|
+
});
|
|
93
|
+
if (capture === undefined)
|
|
94
|
+
throw new Error("analysis-output-failed");
|
|
95
|
+
const snapshot = await readCapturedAnalysisSnapshot(directory, capture);
|
|
96
|
+
return analysisSaveInput({ ...call.payload, snapshot });
|
|
97
|
+
}
|
|
98
|
+
async function save(settings, call) {
|
|
99
|
+
const input = await saveInput(settings, call);
|
|
100
|
+
const { snapshot, candidate } = input;
|
|
101
|
+
if ("followUp" in call.payload)
|
|
102
|
+
return saveFollowUp(settings.runtimeDirectory, { ...call, input });
|
|
103
|
+
if ("batch" in call.payload &&
|
|
104
|
+
Object.hasOwn(record(candidate) ?? {}, "openQuestion"))
|
|
105
|
+
return saveQuestion(settings, { ...call, input });
|
|
106
|
+
const validation = "batch" in call.payload
|
|
107
|
+
? undefined
|
|
108
|
+
: validateAnalysis(candidate, analysisEvidence(snapshot));
|
|
109
|
+
if (validation === undefined)
|
|
110
|
+
return saveAcceptedAnalysis(settings.runtimeDirectory, { ...call, input });
|
|
111
|
+
if (!validation.accepted)
|
|
112
|
+
return refused(validation.codes[0] ?? "analysis-input-refused", validation.codes);
|
|
113
|
+
const question = validation.result.openQuestion;
|
|
114
|
+
if (question !== undefined)
|
|
115
|
+
return saveQuestion(settings, { ...call, input });
|
|
116
|
+
return saveAcceptedAnalysis(settings.runtimeDirectory, { ...call, input });
|
|
117
|
+
}
|
|
118
|
+
const reasons = new Set([
|
|
119
|
+
"analysis-too-large",
|
|
120
|
+
"redaction-required",
|
|
121
|
+
"invalid-import-id",
|
|
122
|
+
"analysis-invalid-json",
|
|
123
|
+
"analysis-follow-up-refused",
|
|
124
|
+
"analysis-input-refused",
|
|
125
|
+
"analysis-output-failed",
|
|
126
|
+
"analysis-batch-limit",
|
|
127
|
+
"unsupported-effect",
|
|
128
|
+
"workflow-not-allowed",
|
|
129
|
+
"payload-not-available",
|
|
130
|
+
]);
|
|
131
|
+
async function delivered(settings, call) {
|
|
132
|
+
const { intent, mode } = call;
|
|
133
|
+
try {
|
|
134
|
+
if (call.signal?.aborted)
|
|
135
|
+
return { kind: "stopped" };
|
|
136
|
+
const payload = await payloadOf(settings, intent);
|
|
137
|
+
if (call.signal?.aborted)
|
|
138
|
+
return { kind: "stopped" };
|
|
139
|
+
if (intent.method === "read-analysis" && mode === "reconcile")
|
|
140
|
+
return { kind: "absent" };
|
|
141
|
+
if (intent.method === "read-analysis")
|
|
142
|
+
return await read(settings, {
|
|
143
|
+
intent,
|
|
144
|
+
importId: String(payload["importId"]),
|
|
145
|
+
});
|
|
146
|
+
return await save(settings, { intent, payload, mode });
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
const message = String(Reflect.get(Object(error), "message"));
|
|
150
|
+
return refused(reasons.has(message) ? message : "analysis-input-refused");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
export function chatsWorker(settings) {
|
|
154
|
+
if (process.platform !== "darwin") {
|
|
155
|
+
const unsupported = () => Promise.resolve(refused("platform-unsupported"));
|
|
156
|
+
return {
|
|
157
|
+
deliver: unsupported,
|
|
158
|
+
reconcile: unsupported,
|
|
159
|
+
stop: unsupported,
|
|
160
|
+
close: () => Promise.resolve(),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
const active = new Map();
|
|
164
|
+
const lifecycle = { closed: false };
|
|
165
|
+
const deliver = (intent, signal) => {
|
|
166
|
+
if (lifecycle.closed || signal.aborted)
|
|
167
|
+
return Promise.resolve({ kind: "stopped" });
|
|
168
|
+
const key = operationKey(JSON.stringify([intent.runId, intent.operationId, intent.inputDigest]));
|
|
169
|
+
const known = active.get(key);
|
|
170
|
+
if (known !== undefined)
|
|
171
|
+
return known;
|
|
172
|
+
const pending = delivered(settings, {
|
|
173
|
+
intent,
|
|
174
|
+
mode: "deliver",
|
|
175
|
+
signal,
|
|
176
|
+
}).finally(() => active.delete(key));
|
|
177
|
+
active.set(key, pending);
|
|
178
|
+
return pending;
|
|
179
|
+
};
|
|
180
|
+
const stop = async (intent) => {
|
|
181
|
+
if (!ownIntent(intent))
|
|
182
|
+
return refused("unsupported-effect");
|
|
183
|
+
if ((await settings.workflowId(intent.runId)) !== "analyze-chats")
|
|
184
|
+
return refused("workflow-not-allowed");
|
|
185
|
+
const key = operationKey(JSON.stringify([intent.runId, intent.operationId, intent.inputDigest]));
|
|
186
|
+
const pending = active.get(key);
|
|
187
|
+
if (pending !== undefined)
|
|
188
|
+
return await pending;
|
|
189
|
+
const result = await delivered(settings, { intent, mode: "reconcile" });
|
|
190
|
+
return result.kind === "absent" ? { kind: "stopped" } : result;
|
|
191
|
+
};
|
|
192
|
+
return {
|
|
193
|
+
deliver,
|
|
194
|
+
reconcile: (intent) => delivered(settings, { intent, mode: "reconcile" }),
|
|
195
|
+
stop,
|
|
196
|
+
close: async () => {
|
|
197
|
+
lifecycle.closed = true;
|
|
198
|
+
await Promise.all(active.values());
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
@@ -1,22 +1,32 @@
|
|
|
1
|
+
import { type WorkerUsage, type WorkerAttemptUsage } from "../worker-usage.ts";
|
|
1
2
|
export type Worker = "claude" | "codex";
|
|
2
3
|
export interface StreamResult {
|
|
4
|
+
readonly attempts?: readonly WorkerAttemptUsage[];
|
|
5
|
+
readonly subtype?: string;
|
|
6
|
+
readonly errorType?: string;
|
|
7
|
+
readonly model: string | null;
|
|
3
8
|
readonly text: string;
|
|
4
9
|
readonly failed: boolean;
|
|
5
10
|
readonly costUsd: number | null;
|
|
11
|
+
readonly usage: WorkerUsage;
|
|
6
12
|
readonly sessionId: string | null;
|
|
7
13
|
readonly turns: number | null;
|
|
8
14
|
}
|
|
9
15
|
export interface TurnEnd {
|
|
16
|
+
readonly stopped?: boolean;
|
|
10
17
|
readonly exitCode: number | null;
|
|
11
18
|
readonly result: StreamResult | undefined;
|
|
12
19
|
}
|
|
13
20
|
export interface TurnStart {
|
|
21
|
+
readonly mode?: "analysis";
|
|
22
|
+
readonly analysisToken?: string;
|
|
14
23
|
readonly worker?: Worker;
|
|
15
24
|
readonly turnId?: string;
|
|
16
25
|
readonly environment?: Readonly<Record<string, string>>;
|
|
17
26
|
readonly command: readonly string[];
|
|
18
27
|
readonly directory: string;
|
|
19
28
|
readonly folder: string;
|
|
29
|
+
readonly activityFolder?: string;
|
|
20
30
|
readonly prompt: string;
|
|
21
31
|
}
|
|
22
32
|
export interface RunningTurn {
|
|
@@ -24,5 +34,6 @@ export interface RunningTurn {
|
|
|
24
34
|
readonly ended: Promise<TurnEnd>;
|
|
25
35
|
readonly stop: (graceMilliseconds: number) => void;
|
|
26
36
|
}
|
|
37
|
+
export declare function capacityRefusal(result: StreamResult | undefined): boolean;
|
|
27
38
|
export declare function streamResult(line: string): StreamResult | undefined;
|
|
28
39
|
export declare function startTurn(start: TurnStart): RunningTurn;
|
|
@@ -2,6 +2,9 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { createWriteStream, mkdtempSync, rmSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { codexStream } from "./codex-stream.js";
|
|
5
|
+
import { priceOf, usageOf, } from "../worker-usage.js";
|
|
6
|
+
import { commandModel } from "../token-prices.js";
|
|
7
|
+
import { analysisCommand, analysisEnvironment } from "./analysis-launch.js";
|
|
5
8
|
function parsed(line) {
|
|
6
9
|
try {
|
|
7
10
|
const value = JSON.parse(line);
|
|
@@ -17,6 +20,13 @@ function numberOf(value) {
|
|
|
17
20
|
function textOf(value) {
|
|
18
21
|
return typeof value === "string" ? value : null;
|
|
19
22
|
}
|
|
23
|
+
export function capacityRefusal(result) {
|
|
24
|
+
return (result?.failed === true &&
|
|
25
|
+
["success", "error_during_execution"].includes(result.subtype ?? "error_during_execution") &&
|
|
26
|
+
(result.text ===
|
|
27
|
+
"Selected model is at capacity. Please try a different model." ||
|
|
28
|
+
result.errorType === "overloaded"));
|
|
29
|
+
}
|
|
20
30
|
export function streamResult(line) {
|
|
21
31
|
if (!line.includes('"result"'))
|
|
22
32
|
return undefined;
|
|
@@ -25,9 +35,17 @@ export function streamResult(line) {
|
|
|
25
35
|
if (field("type") !== "result")
|
|
26
36
|
return undefined;
|
|
27
37
|
return {
|
|
38
|
+
...(typeof field("subtype") === "string"
|
|
39
|
+
? { subtype: String(field("subtype")) }
|
|
40
|
+
: {}),
|
|
41
|
+
...(typeof field("error") === "string"
|
|
42
|
+
? { errorType: String(field("error")) }
|
|
43
|
+
: {}),
|
|
28
44
|
text: textOf(field("result")) ?? "",
|
|
29
45
|
failed: field("is_error") === true,
|
|
30
|
-
costUsd:
|
|
46
|
+
costUsd: priceOf(field("total_cost_usd")),
|
|
47
|
+
usage: usageOf(field("usage")),
|
|
48
|
+
model: textOf(field("model")),
|
|
31
49
|
sessionId: textOf(field("session_id")),
|
|
32
50
|
turns: numberOf(field("num_turns")),
|
|
33
51
|
};
|
|
@@ -38,6 +56,11 @@ function ended(stream) {
|
|
|
38
56
|
});
|
|
39
57
|
}
|
|
40
58
|
function turnEnvironment(configuration, start) {
|
|
59
|
+
if (start.mode === "analysis")
|
|
60
|
+
return {
|
|
61
|
+
...analysisEnvironment(start.folder),
|
|
62
|
+
CLAUDE_CODE_OAUTH_TOKEN: start.analysisToken,
|
|
63
|
+
};
|
|
41
64
|
const excluded = new Set([
|
|
42
65
|
"GH_TOKEN",
|
|
43
66
|
"GITHUB_TOKEN",
|
|
@@ -56,7 +79,7 @@ function turnEnvironment(configuration, start) {
|
|
|
56
79
|
}
|
|
57
80
|
function spawnTurn(start) {
|
|
58
81
|
const configuration = mkdtempSync(join(start.folder, "gh-config-"));
|
|
59
|
-
const [executable = "", ...fixed] = start.command;
|
|
82
|
+
const [executable = "", ...fixed] = start.mode === "analysis" ? analysisCommand() : start.command;
|
|
60
83
|
try {
|
|
61
84
|
const child = spawn(executable, fixed, {
|
|
62
85
|
cwd: start.directory,
|
|
@@ -70,43 +93,101 @@ function spawnTurn(start) {
|
|
|
70
93
|
throw error;
|
|
71
94
|
}
|
|
72
95
|
}
|
|
96
|
+
function receivedLines(stream, lines) {
|
|
97
|
+
for (const line of lines) {
|
|
98
|
+
const event = parsed(line);
|
|
99
|
+
const field = (name) => Reflect.get(Object(event), name);
|
|
100
|
+
const type = field("type");
|
|
101
|
+
if (type === "assistant" && field("parent_tool_use_id") == null)
|
|
102
|
+
stream.errorType = textOf(field("error"));
|
|
103
|
+
if (type === "system" || type === "result")
|
|
104
|
+
stream.model = textOf(field("model")) ?? stream.model;
|
|
105
|
+
const result = streamResult(line);
|
|
106
|
+
if (result !== undefined) {
|
|
107
|
+
const errorType = result.errorType ?? stream.errorType;
|
|
108
|
+
stream.result = {
|
|
109
|
+
...result,
|
|
110
|
+
...(errorType === null ? {} : { errorType }),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function activityOutput(start) {
|
|
116
|
+
if (start.mode === "analysis")
|
|
117
|
+
return undefined;
|
|
118
|
+
const output = createWriteStream(join(start.activityFolder ?? start.folder, "turn.jsonl"), { flags: start.activityFolder === undefined ? "w" : "a" });
|
|
119
|
+
if (start.activityFolder !== undefined)
|
|
120
|
+
output.write("\n");
|
|
121
|
+
return output;
|
|
122
|
+
}
|
|
73
123
|
function turnOutput(start, stdout) {
|
|
74
|
-
const output =
|
|
124
|
+
const output = activityOutput(start);
|
|
75
125
|
const codex = start.worker === "codex" ? codexStream() : undefined;
|
|
76
|
-
const stream = {
|
|
126
|
+
const stream = {
|
|
127
|
+
pending: "",
|
|
128
|
+
result: undefined,
|
|
129
|
+
model: null,
|
|
130
|
+
errorType: null,
|
|
131
|
+
};
|
|
132
|
+
const received = (lines) => {
|
|
133
|
+
receivedLines(stream, lines);
|
|
134
|
+
};
|
|
77
135
|
const written = (lines) => {
|
|
78
136
|
for (const line of lines)
|
|
79
|
-
output
|
|
80
|
-
|
|
137
|
+
output?.write(`${line}\n`);
|
|
138
|
+
received(lines);
|
|
81
139
|
};
|
|
82
140
|
stdout.setEncoding("utf8");
|
|
83
141
|
stdout.on("data", (chunk) => {
|
|
84
142
|
if (codex === undefined)
|
|
85
|
-
output
|
|
143
|
+
output?.write(chunk);
|
|
86
144
|
const lines = `${stream.pending}${chunk}`.split("\n");
|
|
87
145
|
stream.pending = lines.pop() ?? "";
|
|
88
146
|
if (codex !== undefined) {
|
|
89
147
|
written(lines.flatMap(codex.line));
|
|
90
148
|
return;
|
|
91
149
|
}
|
|
92
|
-
|
|
150
|
+
received(lines);
|
|
93
151
|
});
|
|
94
152
|
return async (exitCode) => {
|
|
95
153
|
if (codex !== undefined) {
|
|
96
154
|
written(codex.line(stream.pending));
|
|
97
155
|
written([codex.result(exitCode)]);
|
|
98
156
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
157
|
+
if (output !== undefined)
|
|
158
|
+
await ended(output);
|
|
159
|
+
if (codex === undefined)
|
|
160
|
+
received([stream.pending]);
|
|
161
|
+
const result = stream.result;
|
|
162
|
+
return result === undefined
|
|
163
|
+
? undefined
|
|
164
|
+
: {
|
|
165
|
+
...result,
|
|
166
|
+
model: result.model ??
|
|
167
|
+
stream.model ??
|
|
168
|
+
commandModel(start.mode === "analysis" ? analysisCommand() : start.command),
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function withoutAnalysisToken(start, result) {
|
|
173
|
+
const token = start.mode === "analysis" ? start.analysisToken : undefined;
|
|
174
|
+
if (token === undefined || result === undefined)
|
|
175
|
+
return result;
|
|
176
|
+
const redact = (value) => value === null ? null : value.replaceAll(token, "[redacted]");
|
|
177
|
+
return {
|
|
178
|
+
...result,
|
|
179
|
+
text: redact(result.text) ?? "",
|
|
180
|
+
model: redact(result.model),
|
|
181
|
+
sessionId: redact(result.sessionId),
|
|
103
182
|
};
|
|
104
183
|
}
|
|
105
184
|
export function startTurn(start) {
|
|
106
185
|
const { child, configuration } = spawnTurn(start);
|
|
107
186
|
const output = turnOutput(start, child.stdout);
|
|
108
|
-
|
|
109
|
-
|
|
187
|
+
if (start.mode === "analysis")
|
|
188
|
+
child.stderr.resume();
|
|
189
|
+
else
|
|
190
|
+
child.stderr.pipe(createWriteStream(join(start.folder, "turn.stderr.log")));
|
|
110
191
|
child.stdin.on("error", () => undefined);
|
|
111
192
|
child.stdin.end(start.prompt);
|
|
112
193
|
const closed = new Promise((settle) => {
|
|
@@ -121,7 +202,7 @@ export function startTurn(start) {
|
|
|
121
202
|
timers.forEach(clearTimeout);
|
|
122
203
|
return {
|
|
123
204
|
exitCode,
|
|
124
|
-
result: await output(exitCode),
|
|
205
|
+
result: withoutAnalysisToken(start, await output(exitCode)),
|
|
125
206
|
};
|
|
126
207
|
})
|
|
127
208
|
.finally(() => {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type TurnProfiles } from "../turn-profile.ts";
|
|
2
2
|
import type { Delivery } from "../broker/actor/delivery-intents.ts";
|
|
3
3
|
import { type Worker } from "./claude-turn.ts";
|
|
4
|
+
import { type RetrySettings } from "./retrying-turn.ts";
|
|
4
5
|
import { type WorkerReport } from "./operation-journal.ts";
|
|
5
|
-
export interface ClaudeWorkerSettings {
|
|
6
|
+
export interface ClaudeWorkerSettings extends RetrySettings {
|
|
6
7
|
readonly worker?: Worker;
|
|
7
8
|
readonly profiles?: TurnProfiles;
|
|
8
9
|
readonly workflowId?: (runId: string) => Promise<string | undefined>;
|