@llm4ts/flow 0.14.0 → 0.15.1
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/GitTool.d.ts +7 -0
- package/dist/GitTool.d.ts.map +1 -1
- package/dist/GitTool.js +14 -3
- package/dist/GitTool.js.map +1 -1
- package/dist/TransientRetry.d.ts +18 -0
- package/dist/TransientRetry.d.ts.map +1 -1
- package/dist/TransientRetry.js +43 -4
- package/dist/TransientRetry.js.map +1 -1
- package/package.json +2 -2
- package/src/GitTool.ts +31 -3
- package/src/TransientRetry.ts +84 -8
package/dist/GitTool.d.ts
CHANGED
|
@@ -36,6 +36,13 @@ export interface GitToolShape {
|
|
|
36
36
|
readonly checkoutOrCreate: (name: string) => Effect.Effect<void, FlowError>;
|
|
37
37
|
readonly createBranch: (name: string) => Effect.Effect<CreateBranch, FlowError>;
|
|
38
38
|
readonly commitAll: (message: string) => Effect.Effect<CommitResult, FlowError>;
|
|
39
|
+
/**
|
|
40
|
+
* Stage ONLY `paths` (added, modified, or deleted) and commit them. The
|
|
41
|
+
* per-program commit primitive: when several programs are extracted at
|
|
42
|
+
* once, `commitAll` would sweep another program's half-written files into
|
|
43
|
+
* this program's commit. An empty `paths` is `NothingToCommit`.
|
|
44
|
+
*/
|
|
45
|
+
readonly commitPaths: (message: string, paths: ReadonlyArray<string>) => Effect.Effect<CommitResult, FlowError>;
|
|
39
46
|
readonly push: (remote: string, branch: string) => Effect.Effect<void, FlowError>;
|
|
40
47
|
readonly checkpoint: Effect.Effect<string, FlowError>;
|
|
41
48
|
readonly rollback: (checkpoint: string) => Effect.Effect<void, FlowError>;
|
package/dist/GitTool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GitTool.d.ts","sourceRoot":"","sources":["../src/GitTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,8BAA8B,CAAA;AACvF,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;;AAGtD,qBAAa,aAAc,SAAQ,kBAAkD;CAAG;;AACxF,qBAAa,mBAAoB,SAAQ,wBAGxC;CAAG;AACJ,eAAO,MAAM,YAAY,2EAAqD,CAAA;AAC9E,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;;AAEnD,qBAAa,SAAU,SAAQ,cAAgD;CAAG;;AAClF,qBAAa,eAAgB,SAAQ,oBAA4D;CAAG;AACpG,eAAO,MAAM,YAAY,mEAA6C,CAAA;AACtE,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAEnD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACjD,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IAC/E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACjD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACtD,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC3F,QAAQ,CAAC,gBAAgB,EAAE,CACzB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,EAC5B,QAAQ,CAAC,EAAE,OAAO,KACf,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACrC,QAAQ,CAAC,kBAAkB,EAAE,CAC3B,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,OAAO,KACf,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAA;IACpD,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACjF,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACnE,QAAQ,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IAC3E,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;IAC/E,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;IAC/E,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACjF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACrD,QAAQ,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACzE,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACtF,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;CAC1E;AAcD,eAAO,MAAM,WAAW,GACtB,SAAS,oBAAoB,EAC7B,SAAS,MAAM,EACf,QAAQ,eAAe,KACtB,
|
|
1
|
+
{"version":3,"file":"GitTool.d.ts","sourceRoot":"","sources":["../src/GitTool.ts"],"names":[],"mappings":"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"}
|
package/dist/GitTool.js
CHANGED
|
@@ -76,13 +76,16 @@ export const makeGitTool = (process, workDir, events) => {
|
|
|
76
76
|
}))));
|
|
77
77
|
const checkout = (name) => write("git checkout", runOrFail(["checkout", name]).pipe(Effect.asVoid));
|
|
78
78
|
const addAll = runOrFail(["add", "-A"]).pipe(Effect.asVoid);
|
|
79
|
-
const
|
|
80
|
-
yield* addAll;
|
|
79
|
+
const commitStaged = (message) => Effect.gen(function* () {
|
|
81
80
|
const result = yield* run(["commit", "-m", message]);
|
|
82
81
|
if (result.exitCode === 0) {
|
|
83
82
|
return new Committed();
|
|
84
83
|
}
|
|
85
|
-
|
|
84
|
+
// "nothing to commit, working tree clean" when the tree is clean;
|
|
85
|
+
// "nothing added to commit but untracked files present" when the only
|
|
86
|
+
// changes are files this commit was not asked to stage.
|
|
87
|
+
const detail = problem(result);
|
|
88
|
+
if (detail.includes("nothing to commit") || detail.includes("nothing added to commit")) {
|
|
86
89
|
return new NothingToCommit();
|
|
87
90
|
}
|
|
88
91
|
return yield* ProcessError.make({
|
|
@@ -90,6 +93,13 @@ export const makeGitTool = (process, workDir, events) => {
|
|
|
90
93
|
detail: problem(result)
|
|
91
94
|
});
|
|
92
95
|
});
|
|
96
|
+
const commitAllEffect = (message) => addAll.pipe(Effect.andThen(commitStaged(message)));
|
|
97
|
+
// `add -A -- <paths>` stages additions, modifications, AND deletions of
|
|
98
|
+
// exactly those paths; a plain `add` would refuse a deleted file. `--only`
|
|
99
|
+
// on commit would also work but ignores paths that were never tracked.
|
|
100
|
+
const commitPathsEffect = (message, paths) => paths.length === 0
|
|
101
|
+
? Effect.succeed(new NothingToCommit())
|
|
102
|
+
: runOrFail(["add", "-A", "--", ...paths]).pipe(Effect.andThen(commitStaged(message)));
|
|
93
103
|
return {
|
|
94
104
|
init: write("git init", runOrFail(["-c", "init.defaultBranch=main", "init"]).pipe(Effect.asVoid)),
|
|
95
105
|
initBare: write("git init --bare", runOrFail(["-c", "init.defaultBranch=main", "init", "--bare"]).pipe(Effect.asVoid)),
|
|
@@ -119,6 +129,7 @@ export const makeGitTool = (process, workDir, events) => {
|
|
|
119
129
|
createBranch,
|
|
120
130
|
checkoutOrCreate: (name) => Effect.flatMap(createBranch(name), (created) => created._tag === "Created" ? Effect.void : checkout(name)),
|
|
121
131
|
commitAll: (message) => write("git commitAll", commitAllEffect(message)),
|
|
132
|
+
commitPaths: (message, paths) => write("git commitPaths", commitPathsEffect(message, paths)),
|
|
122
133
|
push: (remote, branch) => gate(Capabilities.GitPush, "git push", runOrFail(["push", "-u", remote, branch]).pipe(Effect.asVoid)),
|
|
123
134
|
checkpoint: read("git checkpoint", runOrFail(["rev-parse", "HEAD"])),
|
|
124
135
|
rollback: (checkpoint) => write("git rollback", runOrFail(["reset", "--hard", checkpoint]).pipe(Effect.asVoid)),
|
package/dist/GitTool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GitTool.js","sourceRoot":"","sources":["../src/GitTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,YAAY,EAAmB,MAAM,yBAAyB,CAAA;AAEvE,OAAO,EAAE,YAAY,EAAkB,MAAM,gBAAgB,CAAA;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAE9C,MAAM,OAAO,aAAc,SAAQ,MAAM,CAAC,WAAW,EAAiB,CAAC,SAAS,EAAE,EAAE,CAAC;CAAG;AACxF,MAAM,OAAO,mBAAoB,SAAQ,MAAM,CAAC,WAAW,EAAuB,CAChF,eAAe,EACf,EAAE,CACH;CAAG;AACJ,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC,CAAA;AAG9E,MAAM,OAAO,SAAU,SAAQ,MAAM,CAAC,WAAW,EAAa,CAAC,WAAW,EAAE,EAAE,CAAC;CAAG;AAClF,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,WAAW,EAAmB,CAAC,iBAAiB,EAAE,EAAE,CAAC;CAAG;AACpG,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"GitTool.js","sourceRoot":"","sources":["../src/GitTool.ts"],"names":[],"mappings":"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"}
|
package/dist/TransientRetry.d.ts
CHANGED
|
@@ -13,6 +13,24 @@ export interface TransientRetryOptions {
|
|
|
13
13
|
readonly baseDelay?: Duration.Input;
|
|
14
14
|
readonly flakyRetries?: number;
|
|
15
15
|
readonly flakyDelay?: Duration.Input;
|
|
16
|
+
/**
|
|
17
|
+
* Re-asks a structured call whose response could not be parsed as the
|
|
18
|
+
* requested JSON, with the parse failure quoted back to the model. The
|
|
19
|
+
* model's output is not deterministic, so a malformed or off-schema reply
|
|
20
|
+
* is usually a one-off; but a schema the model cannot satisfy fails every
|
|
21
|
+
* time, so this budget is small (default 2) and independent of the others.
|
|
22
|
+
*/
|
|
23
|
+
readonly parseRetries?: number;
|
|
16
24
|
}
|
|
25
|
+
/** A structured call whose text came back but did not decode as the requested JSON. */
|
|
26
|
+
export declare const isStructuredParseFailure: (error: LlmError) => boolean;
|
|
27
|
+
/**
|
|
28
|
+
* The prompt for a structured re-ask: the original, plus what went wrong
|
|
29
|
+
* with the previous reply. Quoting the failure is what turns a blind retry
|
|
30
|
+
* into a repair — the common causes (prose around the JSON, a missing
|
|
31
|
+
* required field, a string where a number was asked for) are all things the
|
|
32
|
+
* model fixes on sight.
|
|
33
|
+
*/
|
|
34
|
+
export declare const repairPrompt: (prompt: string, error: LlmError) => string;
|
|
17
35
|
export declare const makeTransientRetry: (underlying: LlmServiceShape, retryOptions?: TransientRetryOptions | undefined) => Effect.Effect<LlmServiceShape, never, FlowEvents>;
|
|
18
36
|
//# sourceMappingURL=TransientRetry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransientRetry.d.ts","sourceRoot":"","sources":["../src/TransientRetry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"TransientRetry.d.ts","sourceRoot":"","sources":["../src/TransientRetry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAG1E,OAAO,EAAE,UAAU,EAAQ,MAAM,iBAAiB,CAAA;AAmElD,eAAO,MAAM,aAAa,GAAI,OAAO,QAAQ,KAAG,OAE6C,CAAA;AAK7F,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,KAAG,OACV,CAAA;AAKjD,eAAO,MAAM,iBAAiB,GAAI,OAAO,QAAQ,KAAG,OACuB,CAAA;AAE3E,eAAO,MAAM,WAAW,GAAI,OAAO,QAAQ,KAAG,OAc7C,CAAA;AAID,eAAO,MAAM,cAAc,GAAI,OAAO,QAAQ,EAAE,SAAS,QAAQ,CAAC,QAAQ,KAAG,QAAQ,CAAC,QAMrF,CAAA;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAA;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAA;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAkBD,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,GAAI,OAAO,QAAQ,KAAG,OAAsC,CAAA;AAIjG;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,EAAE,OAAO,QAAQ,KAAG,MAY9D,CAAA;AA4JD,eAAO,MAAM,kBAAkB,sIA8B7B,CAAA"}
|
package/dist/TransientRetry.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as Duration from "effect/Duration";
|
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
3
|
import * as Stream from "effect/Stream";
|
|
4
4
|
import { LlmService } from "@llm4ts/core/LlmService";
|
|
5
|
+
import { isLoopDetectedMessage } from "@llm4ts/core/providers/CliSupport";
|
|
5
6
|
import { FlowEvents, Info } from "./FlowEvents.js";
|
|
6
7
|
const transientSignals = [
|
|
7
8
|
"connection reset",
|
|
@@ -58,7 +59,13 @@ const includesSignal = (message, signals) => {
|
|
|
58
59
|
const normalized = message.toLowerCase();
|
|
59
60
|
return signals.some((signal) => normalized.includes(signal));
|
|
60
61
|
};
|
|
61
|
-
|
|
62
|
+
// A coding agent's own loop breaker (Gemini CLI: "A potential loop was
|
|
63
|
+
// detected … The request has been halted") is flaky in the same sense: the
|
|
64
|
+
// turn is lost, the quota is not, and a fresh process with the same prompt
|
|
65
|
+
// ordinarily completes — so it takes the fresh-retry budget, not the
|
|
66
|
+
// transient one, and is never treated as deterministic.
|
|
67
|
+
export const isFlakyStream = (error) => error._tag === "ProviderError" &&
|
|
68
|
+
(includesSignal(error.message, flakyStreamSignals) || isLoopDetectedMessage(error.message));
|
|
62
69
|
const isDeterministic4xx = (message) => includesSignal(message, deterministic4xxSignals);
|
|
63
70
|
export const isContextOverflowMessage = (message) => includesSignal(message, contextOverflowSignals);
|
|
64
71
|
// The prompt was larger than the model's input window. Deterministic: the same prompt
|
|
@@ -89,8 +96,31 @@ const resolveOptions = (options) => ({
|
|
|
89
96
|
maxRetries: options.maxRetries ?? 3,
|
|
90
97
|
baseDelay: Duration.fromInputUnsafe(options.baseDelay ?? "1 second"),
|
|
91
98
|
flakyRetries: options.flakyRetries ?? 6,
|
|
92
|
-
flakyDelay: Duration.fromInputUnsafe(options.flakyDelay ?? "1 second")
|
|
99
|
+
flakyDelay: Duration.fromInputUnsafe(options.flakyDelay ?? "1 second"),
|
|
100
|
+
parseRetries: options.parseRetries ?? 2
|
|
93
101
|
});
|
|
102
|
+
/** A structured call whose text came back but did not decode as the requested JSON. */
|
|
103
|
+
export const isStructuredParseFailure = (error) => error._tag === "ParseError";
|
|
104
|
+
const repairReasonLimit = 400;
|
|
105
|
+
/**
|
|
106
|
+
* The prompt for a structured re-ask: the original, plus what went wrong
|
|
107
|
+
* with the previous reply. Quoting the failure is what turns a blind retry
|
|
108
|
+
* into a repair — the common causes (prose around the JSON, a missing
|
|
109
|
+
* required field, a string where a number was asked for) are all things the
|
|
110
|
+
* model fixes on sight.
|
|
111
|
+
*/
|
|
112
|
+
export const repairPrompt = (prompt, error) => {
|
|
113
|
+
const reason = error.message.trim();
|
|
114
|
+
const shown = reason.length <= repairReasonLimit ? reason : `${reason.slice(0, repairReasonLimit - 3)}...`;
|
|
115
|
+
return [
|
|
116
|
+
prompt,
|
|
117
|
+
"",
|
|
118
|
+
"Your previous reply could not be parsed as the requested JSON:",
|
|
119
|
+
shown,
|
|
120
|
+
"Reply again with ONLY the JSON object — no prose before or after it, no markdown",
|
|
121
|
+
"fences, every required field present, and values of the requested types."
|
|
122
|
+
].join("\n");
|
|
123
|
+
};
|
|
94
124
|
const backoff = (baseDelay, attempt) => Duration.times(baseDelay, 2 ** attempt);
|
|
95
125
|
const retryNotice = (events, what, attempt, maximum, error) => events.publish(Info.make({
|
|
96
126
|
message: `⟳ ${what} — retry ${attempt + 1}/${maximum}: ${error.message}`
|
|
@@ -121,6 +151,15 @@ const retryStream = (stream, what, options, events) => {
|
|
|
121
151
|
});
|
|
122
152
|
return loop(0, 0);
|
|
123
153
|
};
|
|
154
|
+
/**
|
|
155
|
+
* A structured call under all three budgets: `run(prompt)` is retried for
|
|
156
|
+
* transient and flaky failures as any effect is, and a parse failure re-asks
|
|
157
|
+
* with `repairPrompt` up to `parseRetries` times before it is surfaced.
|
|
158
|
+
*/
|
|
159
|
+
const retryStructured = (prompt, run, options, events) => {
|
|
160
|
+
const loop = (current, parseAttempt) => retryEffect(run(current), "structured", options, events).pipe(Effect.catchIf((error) => isStructuredParseFailure(error) && parseAttempt < options.parseRetries, (error) => waitForRetry(events, "structured output (repair retry)", parseAttempt, options.parseRetries, error, options.flakyDelay).pipe(Effect.andThen(Effect.suspend(() => loop(repairPrompt(prompt, error), parseAttempt + 1))))));
|
|
161
|
+
return loop(prompt, 0);
|
|
162
|
+
};
|
|
124
163
|
export const makeTransientRetry = Effect.fn("@llm4ts/flow/TransientRetry.make")(function* (underlying, retryOptions = {}) {
|
|
125
164
|
const events = yield* FlowEvents;
|
|
126
165
|
const options = resolveOptions(retryOptions);
|
|
@@ -128,8 +167,8 @@ export const makeTransientRetry = Effect.fn("@llm4ts/flow/TransientRetry.make")(
|
|
|
128
167
|
executeStream: (prompt) => retryStream(underlying.executeStream(prompt), "stream", options, events),
|
|
129
168
|
executeStreamWithHistory: (messages) => retryStream(underlying.executeStreamWithHistory(messages), "stream", options, events),
|
|
130
169
|
executeWithTools: (prompt, tools) => retryEffect(underlying.executeWithTools(prompt, tools), "tools", options, events),
|
|
131
|
-
executeStructured: (prompt, schema, jsonSchema) =>
|
|
132
|
-
executeStructuredWithUsage: (prompt, schema, jsonSchema) =>
|
|
170
|
+
executeStructured: (prompt, schema, jsonSchema) => retryStructured(prompt, (current) => underlying.executeStructured(current, schema, jsonSchema), options, events),
|
|
171
|
+
executeStructuredWithUsage: (prompt, schema, jsonSchema) => retryStructured(prompt, (current) => underlying.executeStructuredWithUsage(current, schema, jsonSchema), options, events),
|
|
133
172
|
isAvailable: underlying.isAvailable
|
|
134
173
|
});
|
|
135
174
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransientRetry.js","sourceRoot":"","sources":["../src/TransientRetry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,UAAU,EAAwB,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"TransientRetry.js","sourceRoot":"","sources":["../src/TransientRetry.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llm4ts/flow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "Effect-native LLM workflow, persistence, review, and repository automation",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"typescript"
|
|
87
87
|
],
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@llm4ts/core": "0.
|
|
89
|
+
"@llm4ts/core": "0.15.1"
|
|
90
90
|
},
|
|
91
91
|
"peerDependencies": {
|
|
92
92
|
"effect": "4.0.0-beta.102"
|
package/src/GitTool.ts
CHANGED
|
@@ -43,6 +43,16 @@ export interface GitToolShape {
|
|
|
43
43
|
readonly checkoutOrCreate: (name: string) => Effect.Effect<void, FlowError>
|
|
44
44
|
readonly createBranch: (name: string) => Effect.Effect<CreateBranch, FlowError>
|
|
45
45
|
readonly commitAll: (message: string) => Effect.Effect<CommitResult, FlowError>
|
|
46
|
+
/**
|
|
47
|
+
* Stage ONLY `paths` (added, modified, or deleted) and commit them. The
|
|
48
|
+
* per-program commit primitive: when several programs are extracted at
|
|
49
|
+
* once, `commitAll` would sweep another program's half-written files into
|
|
50
|
+
* this program's commit. An empty `paths` is `NothingToCommit`.
|
|
51
|
+
*/
|
|
52
|
+
readonly commitPaths: (
|
|
53
|
+
message: string,
|
|
54
|
+
paths: ReadonlyArray<string>
|
|
55
|
+
) => Effect.Effect<CommitResult, FlowError>
|
|
46
56
|
readonly push: (remote: string, branch: string) => Effect.Effect<void, FlowError>
|
|
47
57
|
readonly checkpoint: Effect.Effect<string, FlowError>
|
|
48
58
|
readonly rollback: (checkpoint: string) => Effect.Effect<void, FlowError>
|
|
@@ -174,14 +184,17 @@ export const makeGitTool = (
|
|
|
174
184
|
|
|
175
185
|
const addAll = runOrFail(["add", "-A"]).pipe(Effect.asVoid)
|
|
176
186
|
|
|
177
|
-
const
|
|
187
|
+
const commitStaged = (message: string): Effect.Effect<CommitResult, FlowError> =>
|
|
178
188
|
Effect.gen(function* () {
|
|
179
|
-
yield* addAll
|
|
180
189
|
const result = yield* run(["commit", "-m", message])
|
|
181
190
|
if (result.exitCode === 0) {
|
|
182
191
|
return new Committed()
|
|
183
192
|
}
|
|
184
|
-
|
|
193
|
+
// "nothing to commit, working tree clean" when the tree is clean;
|
|
194
|
+
// "nothing added to commit but untracked files present" when the only
|
|
195
|
+
// changes are files this commit was not asked to stage.
|
|
196
|
+
const detail = problem(result)
|
|
197
|
+
if (detail.includes("nothing to commit") || detail.includes("nothing added to commit")) {
|
|
185
198
|
return new NothingToCommit()
|
|
186
199
|
}
|
|
187
200
|
return yield* ProcessError.make({
|
|
@@ -190,6 +203,20 @@ export const makeGitTool = (
|
|
|
190
203
|
})
|
|
191
204
|
})
|
|
192
205
|
|
|
206
|
+
const commitAllEffect = (message: string): Effect.Effect<CommitResult, FlowError> =>
|
|
207
|
+
addAll.pipe(Effect.andThen(commitStaged(message)))
|
|
208
|
+
|
|
209
|
+
// `add -A -- <paths>` stages additions, modifications, AND deletions of
|
|
210
|
+
// exactly those paths; a plain `add` would refuse a deleted file. `--only`
|
|
211
|
+
// on commit would also work but ignores paths that were never tracked.
|
|
212
|
+
const commitPathsEffect = (
|
|
213
|
+
message: string,
|
|
214
|
+
paths: ReadonlyArray<string>
|
|
215
|
+
): Effect.Effect<CommitResult, FlowError> =>
|
|
216
|
+
paths.length === 0
|
|
217
|
+
? Effect.succeed(new NothingToCommit())
|
|
218
|
+
: runOrFail(["add", "-A", "--", ...paths]).pipe(Effect.andThen(commitStaged(message)))
|
|
219
|
+
|
|
193
220
|
return {
|
|
194
221
|
init: write(
|
|
195
222
|
"git init",
|
|
@@ -248,6 +275,7 @@ export const makeGitTool = (
|
|
|
248
275
|
created._tag === "Created" ? Effect.void : checkout(name)
|
|
249
276
|
),
|
|
250
277
|
commitAll: (message) => write("git commitAll", commitAllEffect(message)),
|
|
278
|
+
commitPaths: (message, paths) => write("git commitPaths", commitPathsEffect(message, paths)),
|
|
251
279
|
push: (remote, branch) =>
|
|
252
280
|
gate(
|
|
253
281
|
Capabilities.GitPush,
|
package/src/TransientRetry.ts
CHANGED
|
@@ -3,6 +3,7 @@ import * as Effect from "effect/Effect"
|
|
|
3
3
|
import * as Stream from "effect/Stream"
|
|
4
4
|
import type { LlmError } from "@llm4ts/core/Errors"
|
|
5
5
|
import { LlmService, type LlmServiceShape } from "@llm4ts/core/LlmService"
|
|
6
|
+
import { isLoopDetectedMessage } from "@llm4ts/core/providers/CliSupport"
|
|
6
7
|
import type { LlmChunk } from "@llm4ts/core/Models"
|
|
7
8
|
import { FlowEvents, Info } from "./FlowEvents.ts"
|
|
8
9
|
|
|
@@ -66,8 +67,14 @@ const includesSignal = (message: string, signals: ReadonlyArray<string>): boolea
|
|
|
66
67
|
return signals.some((signal) => normalized.includes(signal))
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
// A coding agent's own loop breaker (Gemini CLI: "A potential loop was
|
|
71
|
+
// detected … The request has been halted") is flaky in the same sense: the
|
|
72
|
+
// turn is lost, the quota is not, and a fresh process with the same prompt
|
|
73
|
+
// ordinarily completes — so it takes the fresh-retry budget, not the
|
|
74
|
+
// transient one, and is never treated as deterministic.
|
|
69
75
|
export const isFlakyStream = (error: LlmError): boolean =>
|
|
70
|
-
error._tag === "ProviderError" &&
|
|
76
|
+
error._tag === "ProviderError" &&
|
|
77
|
+
(includesSignal(error.message, flakyStreamSignals) || isLoopDetectedMessage(error.message))
|
|
71
78
|
|
|
72
79
|
const isDeterministic4xx = (message: string): boolean =>
|
|
73
80
|
includesSignal(message, deterministic4xxSignals)
|
|
@@ -112,6 +119,14 @@ export interface TransientRetryOptions {
|
|
|
112
119
|
readonly baseDelay?: Duration.Input
|
|
113
120
|
readonly flakyRetries?: number
|
|
114
121
|
readonly flakyDelay?: Duration.Input
|
|
122
|
+
/**
|
|
123
|
+
* Re-asks a structured call whose response could not be parsed as the
|
|
124
|
+
* requested JSON, with the parse failure quoted back to the model. The
|
|
125
|
+
* model's output is not deterministic, so a malformed or off-schema reply
|
|
126
|
+
* is usually a one-off; but a schema the model cannot satisfy fails every
|
|
127
|
+
* time, so this budget is small (default 2) and independent of the others.
|
|
128
|
+
*/
|
|
129
|
+
readonly parseRetries?: number
|
|
115
130
|
}
|
|
116
131
|
|
|
117
132
|
interface ResolvedTransientRetryOptions {
|
|
@@ -119,15 +134,43 @@ interface ResolvedTransientRetryOptions {
|
|
|
119
134
|
readonly baseDelay: Duration.Duration
|
|
120
135
|
readonly flakyRetries: number
|
|
121
136
|
readonly flakyDelay: Duration.Duration
|
|
137
|
+
readonly parseRetries: number
|
|
122
138
|
}
|
|
123
139
|
|
|
124
140
|
const resolveOptions = (options: TransientRetryOptions): ResolvedTransientRetryOptions => ({
|
|
125
141
|
maxRetries: options.maxRetries ?? 3,
|
|
126
142
|
baseDelay: Duration.fromInputUnsafe(options.baseDelay ?? "1 second"),
|
|
127
143
|
flakyRetries: options.flakyRetries ?? 6,
|
|
128
|
-
flakyDelay: Duration.fromInputUnsafe(options.flakyDelay ?? "1 second")
|
|
144
|
+
flakyDelay: Duration.fromInputUnsafe(options.flakyDelay ?? "1 second"),
|
|
145
|
+
parseRetries: options.parseRetries ?? 2
|
|
129
146
|
})
|
|
130
147
|
|
|
148
|
+
/** A structured call whose text came back but did not decode as the requested JSON. */
|
|
149
|
+
export const isStructuredParseFailure = (error: LlmError): boolean => error._tag === "ParseError"
|
|
150
|
+
|
|
151
|
+
const repairReasonLimit = 400
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The prompt for a structured re-ask: the original, plus what went wrong
|
|
155
|
+
* with the previous reply. Quoting the failure is what turns a blind retry
|
|
156
|
+
* into a repair — the common causes (prose around the JSON, a missing
|
|
157
|
+
* required field, a string where a number was asked for) are all things the
|
|
158
|
+
* model fixes on sight.
|
|
159
|
+
*/
|
|
160
|
+
export const repairPrompt = (prompt: string, error: LlmError): string => {
|
|
161
|
+
const reason = error.message.trim()
|
|
162
|
+
const shown =
|
|
163
|
+
reason.length <= repairReasonLimit ? reason : `${reason.slice(0, repairReasonLimit - 3)}...`
|
|
164
|
+
return [
|
|
165
|
+
prompt,
|
|
166
|
+
"",
|
|
167
|
+
"Your previous reply could not be parsed as the requested JSON:",
|
|
168
|
+
shown,
|
|
169
|
+
"Reply again with ONLY the JSON object — no prose before or after it, no markdown",
|
|
170
|
+
"fences, every required field present, and values of the requested types."
|
|
171
|
+
].join("\n")
|
|
172
|
+
}
|
|
173
|
+
|
|
131
174
|
const backoff = (baseDelay: Duration.Duration, attempt: number): Duration.Duration =>
|
|
132
175
|
Duration.times(baseDelay, 2 ** attempt)
|
|
133
176
|
|
|
@@ -249,6 +292,39 @@ const retryStream = <R>(
|
|
|
249
292
|
return loop(0, 0)
|
|
250
293
|
}
|
|
251
294
|
|
|
295
|
+
/**
|
|
296
|
+
* A structured call under all three budgets: `run(prompt)` is retried for
|
|
297
|
+
* transient and flaky failures as any effect is, and a parse failure re-asks
|
|
298
|
+
* with `repairPrompt` up to `parseRetries` times before it is surfaced.
|
|
299
|
+
*/
|
|
300
|
+
const retryStructured = <A, R>(
|
|
301
|
+
prompt: string,
|
|
302
|
+
run: (prompt: string) => Effect.Effect<A, LlmError, R>,
|
|
303
|
+
options: ResolvedTransientRetryOptions,
|
|
304
|
+
events: FlowEvents["Service"]
|
|
305
|
+
): Effect.Effect<A, LlmError, R> => {
|
|
306
|
+
const loop = (current: string, parseAttempt: number): Effect.Effect<A, LlmError, R> =>
|
|
307
|
+
retryEffect(run(current), "structured", options, events).pipe(
|
|
308
|
+
Effect.catchIf(
|
|
309
|
+
(error) => isStructuredParseFailure(error) && parseAttempt < options.parseRetries,
|
|
310
|
+
(error) =>
|
|
311
|
+
waitForRetry(
|
|
312
|
+
events,
|
|
313
|
+
"structured output (repair retry)",
|
|
314
|
+
parseAttempt,
|
|
315
|
+
options.parseRetries,
|
|
316
|
+
error,
|
|
317
|
+
options.flakyDelay
|
|
318
|
+
).pipe(
|
|
319
|
+
Effect.andThen(
|
|
320
|
+
Effect.suspend(() => loop(repairPrompt(prompt, error), parseAttempt + 1))
|
|
321
|
+
)
|
|
322
|
+
)
|
|
323
|
+
)
|
|
324
|
+
)
|
|
325
|
+
return loop(prompt, 0)
|
|
326
|
+
}
|
|
327
|
+
|
|
252
328
|
export const makeTransientRetry = Effect.fn("@llm4ts/flow/TransientRetry.make")(function* (
|
|
253
329
|
underlying: LlmServiceShape,
|
|
254
330
|
retryOptions: TransientRetryOptions = {}
|
|
@@ -264,16 +340,16 @@ export const makeTransientRetry = Effect.fn("@llm4ts/flow/TransientRetry.make")(
|
|
|
264
340
|
executeWithTools: (prompt, tools) =>
|
|
265
341
|
retryEffect(underlying.executeWithTools(prompt, tools), "tools", options, events),
|
|
266
342
|
executeStructured: (prompt, schema, jsonSchema) =>
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
343
|
+
retryStructured(
|
|
344
|
+
prompt,
|
|
345
|
+
(current) => underlying.executeStructured(current, schema, jsonSchema),
|
|
270
346
|
options,
|
|
271
347
|
events
|
|
272
348
|
),
|
|
273
349
|
executeStructuredWithUsage: (prompt, schema, jsonSchema) =>
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
350
|
+
retryStructured(
|
|
351
|
+
prompt,
|
|
352
|
+
(current) => underlying.executeStructuredWithUsage(current, schema, jsonSchema),
|
|
277
353
|
options,
|
|
278
354
|
events
|
|
279
355
|
),
|