@llm4ts/flow 0.6.3 → 0.7.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/Activity.d.ts +20 -0
- package/dist/Activity.d.ts.map +1 -0
- package/dist/Activity.js +110 -0
- package/dist/Activity.js.map +1 -0
- package/dist/Chat.d.ts.map +1 -1
- package/dist/Chat.js +3 -1
- package/dist/Chat.js.map +1 -1
- package/dist/Flow.d.ts.map +1 -1
- package/dist/Flow.js +2 -1
- package/dist/Flow.js.map +1 -1
- package/package.json +3 -2
- package/src/Activity.ts +124 -0
- package/src/Chat.ts +5 -3
- package/src/Flow.ts +2 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as Stream from "effect/Stream";
|
|
2
|
+
import type { LlmError } from "@llm4ts/core/Errors";
|
|
3
|
+
import type { LlmChunk } from "@llm4ts/core/Models";
|
|
4
|
+
import { ToolUse, type FlowEventsShape } from "./FlowEvents.ts";
|
|
5
|
+
/**
|
|
6
|
+
* The readable gist of a tool's arguments: the salient value on its own
|
|
7
|
+
* (`ls -R docs/modernization` rather than `{"command":"ls -R …"}`), a compact
|
|
8
|
+
* `key=value` list when no single field stands out, and the raw text when the
|
|
9
|
+
* input is not a JSON object. Always collapsed to one line and truncated.
|
|
10
|
+
*/
|
|
11
|
+
export declare const summariseToolArgs: (raw: string) => string;
|
|
12
|
+
/** The `ToolUse` event a chunk represents, or undefined when it is not a tool call. */
|
|
13
|
+
export declare const toolUseFrom: (chunk: LlmChunk) => ToolUse | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Republishes the stream unchanged, publishing a `ToolUse` event for every
|
|
16
|
+
* tool call it carries. Wrap a connector stream with this before `collect` so
|
|
17
|
+
* the run reports what the agent is doing while it is doing it.
|
|
18
|
+
*/
|
|
19
|
+
export declare const withToolActivity: <R>(events: FlowEventsShape, stream: Stream.Stream<LlmChunk, LlmError, R>) => Stream.Stream<LlmChunk, LlmError, R>;
|
|
20
|
+
//# sourceMappingURL=Activity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Activity.d.ts","sourceRoot":"","sources":["../src/Activity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAgD/D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,MAoC/C,CAAA;AAED,uFAAuF;AACvF,eAAO,MAAM,WAAW,GAAI,OAAO,QAAQ,KAAG,OAAO,GAAG,SAYvD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAChC,QAAQ,eAAe,EACvB,QAAQ,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,KAC3C,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAIlC,CAAA"}
|
package/dist/Activity.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Stream from "effect/Stream";
|
|
3
|
+
import { ToolUse } from "./FlowEvents.js";
|
|
4
|
+
/**
|
|
5
|
+
* Live agent activity.
|
|
6
|
+
*
|
|
7
|
+
* CLI connectors emit a zero-delta chunk per tool call, tagged
|
|
8
|
+
* `metadata.event = "tool_use"` with `tool_name` and `tool_input` (see
|
|
9
|
+
* `toolEventChunk` in `@llm4ts/core/providers/CliSupport`). `collect` folds a
|
|
10
|
+
* stream into its final response and drops those chunks, so a coding agent
|
|
11
|
+
* working for minutes rendered as a bare spinner with no sign of progress.
|
|
12
|
+
* Tapping the stream turns each of them into a `ToolUse` event the terminal
|
|
13
|
+
* already knows how to draw.
|
|
14
|
+
*/
|
|
15
|
+
const ArgsLimit = 120;
|
|
16
|
+
/** Keys worth showing alone, in the order a tool call is usually recognised by. */
|
|
17
|
+
const salientKeys = [
|
|
18
|
+
"command",
|
|
19
|
+
"file_path",
|
|
20
|
+
"filePath",
|
|
21
|
+
"path",
|
|
22
|
+
"pattern",
|
|
23
|
+
"query",
|
|
24
|
+
"url",
|
|
25
|
+
"topic",
|
|
26
|
+
"title",
|
|
27
|
+
"description",
|
|
28
|
+
"prompt"
|
|
29
|
+
];
|
|
30
|
+
const compact = (text) => {
|
|
31
|
+
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
32
|
+
return collapsed.length <= ArgsLimit ? collapsed : `${collapsed.slice(0, ArgsLimit - 1)}…`;
|
|
33
|
+
};
|
|
34
|
+
const scalar = (value) => {
|
|
35
|
+
switch (typeof value) {
|
|
36
|
+
case "string":
|
|
37
|
+
return value;
|
|
38
|
+
case "number":
|
|
39
|
+
case "boolean":
|
|
40
|
+
return String(value);
|
|
41
|
+
default:
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* The readable gist of a tool's arguments: the salient value on its own
|
|
47
|
+
* (`ls -R docs/modernization` rather than `{"command":"ls -R …"}`), a compact
|
|
48
|
+
* `key=value` list when no single field stands out, and the raw text when the
|
|
49
|
+
* input is not a JSON object. Always collapsed to one line and truncated.
|
|
50
|
+
*/
|
|
51
|
+
export const summariseToolArgs = (raw) => {
|
|
52
|
+
const trimmed = raw.trim();
|
|
53
|
+
if (trimmed.length === 0) {
|
|
54
|
+
return "";
|
|
55
|
+
}
|
|
56
|
+
let parsed;
|
|
57
|
+
try {
|
|
58
|
+
parsed = JSON.parse(trimmed);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return compact(trimmed);
|
|
62
|
+
}
|
|
63
|
+
const direct = scalar(parsed);
|
|
64
|
+
if (direct !== undefined) {
|
|
65
|
+
return compact(direct);
|
|
66
|
+
}
|
|
67
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
68
|
+
return compact(trimmed);
|
|
69
|
+
}
|
|
70
|
+
const entries = Object.entries(parsed);
|
|
71
|
+
if (entries.length === 0) {
|
|
72
|
+
return "";
|
|
73
|
+
}
|
|
74
|
+
for (const key of salientKeys) {
|
|
75
|
+
const found = entries.find(([name]) => name === key);
|
|
76
|
+
const value = found === undefined ? undefined : scalar(found[1]);
|
|
77
|
+
if (value !== undefined && value.trim().length > 0) {
|
|
78
|
+
return compact(value);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const single = entries.length === 1 ? scalar(entries[0]?.[1]) : undefined;
|
|
82
|
+
if (single !== undefined) {
|
|
83
|
+
return compact(single);
|
|
84
|
+
}
|
|
85
|
+
return compact(entries.map(([name, value]) => `${name}=${scalar(value) ?? JSON.stringify(value)}`).join(", "));
|
|
86
|
+
};
|
|
87
|
+
/** The `ToolUse` event a chunk represents, or undefined when it is not a tool call. */
|
|
88
|
+
export const toolUseFrom = (chunk) => {
|
|
89
|
+
if (chunk.metadata.event !== "tool_use") {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
const tool = (chunk.metadata.tool_name ?? chunk.metadata.toolName ?? "").trim();
|
|
93
|
+
if (tool.length === 0) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
return ToolUse.make({
|
|
97
|
+
tool,
|
|
98
|
+
args: summariseToolArgs(chunk.metadata.tool_input ?? chunk.metadata.toolInput ?? "")
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Republishes the stream unchanged, publishing a `ToolUse` event for every
|
|
103
|
+
* tool call it carries. Wrap a connector stream with this before `collect` so
|
|
104
|
+
* the run reports what the agent is doing while it is doing it.
|
|
105
|
+
*/
|
|
106
|
+
export const withToolActivity = (events, stream) => Stream.tap(stream, (chunk) => {
|
|
107
|
+
const event = toolUseFrom(chunk);
|
|
108
|
+
return event === undefined ? Effect.void : events.publish(event);
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=Activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Activity.js","sourceRoot":"","sources":["../src/Activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,EAAE,OAAO,EAAwB,MAAM,iBAAiB,CAAA;AAE/D;;;;;;;;;;GAUG;AAEH,MAAM,SAAS,GAAG,GAAG,CAAA;AAErB,mFAAmF;AACnF,MAAM,WAAW,GAA0B;IACzC,SAAS;IACT,WAAW;IACX,UAAU;IACV,MAAM;IACN,SAAS;IACT,OAAO;IACP,KAAK;IACL,OAAO;IACP,OAAO;IACP,aAAa;IACb,QAAQ;CACT,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IAClD,OAAO,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,CAAA;AAC5F,CAAC,CAAA;AAED,MAAM,MAAM,GAAG,CAAC,KAAc,EAAsB,EAAE;IACpD,QAAQ,OAAO,KAAK,EAAE,CAAC;QACrB,KAAK,QAAQ;YACX,OAAO,KAAK,CAAA;QACd,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;QACtB;YACE,OAAO,SAAS,CAAA;IACpB,CAAC;AACH,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAU,EAAE;IACvD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IAC1B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,CAAA;IACX,CAAC;IACD,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,OAAO,CAAC,CAAA;IACzB,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAC7B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAA;IACxB,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,OAAO,OAAO,CAAC,OAAO,CAAC,CAAA;IACzB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,CAAA;IACX,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,GAAG,CAAC,CAAA;QACpD,MAAM,KAAK,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QAChE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAA;QACvB,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACzE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAA;IACxB,CAAC;IACD,OAAO,OAAO,CACZ,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC/F,CAAA;AACH,CAAC,CAAA;AAED,uFAAuF;AACvF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAe,EAAuB,EAAE;IAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QACxC,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAC/E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC;QAClB,IAAI;QACJ,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC;KACrF,CAAC,CAAA;AACJ,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,MAAuB,EACvB,MAA4C,EACN,EAAE,CACxC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;IAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAA;IAChC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAClE,CAAC,CAAC,CAAA"}
|
package/dist/Chat.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../src/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAoB,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../src/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAoB,MAAM,qBAAqB,CAAA;AAG/D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAElE,eAAO,MAAM,uBAAuB,iHAC4E,CAAA;AAEhH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAA;IACjC,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAaD,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAA;CACzD;AAcD,eAAO,MAAM,QAAQ,oGA4BnB,CAAA"}
|
package/dist/Chat.js
CHANGED
|
@@ -3,6 +3,7 @@ import * as Ref from "effect/Ref";
|
|
|
3
3
|
import * as Semaphore from "effect/Semaphore";
|
|
4
4
|
import { Message } from "@llm4ts/core/Models";
|
|
5
5
|
import { collect } from "@llm4ts/core/Streaming";
|
|
6
|
+
import { withToolActivity } from "./Activity.js";
|
|
6
7
|
import { FlowLlmError } from "./FlowError.js";
|
|
7
8
|
import { TokensUsed } from "./FlowEvents.js";
|
|
8
9
|
export const gitOwnershipInstruction = "The flow runtime owns git operations. Do not create or switch branches, commit, push, or open pull requests.";
|
|
@@ -29,7 +30,8 @@ export const makeChat = Effect.fn("@llm4ts/flow/Chat.make")(function* (service,
|
|
|
29
30
|
const askRound = Effect.fn("@llm4ts/flow/Chat.ask")(function* (prompt) {
|
|
30
31
|
const userTurn = Message.make({ role: "User", content: prompt });
|
|
31
32
|
const messages = [...(yield* Ref.get(history)), userTurn];
|
|
32
|
-
const
|
|
33
|
+
const stream = service.executeStreamWithHistory(messages);
|
|
34
|
+
const response = yield* collect(options.events === undefined ? stream : withToolActivity(options.events, stream)).pipe(Effect.mapError(FlowLlmError.from));
|
|
33
35
|
yield* publishUsage(options, response);
|
|
34
36
|
yield* Ref.set(history, [
|
|
35
37
|
...messages,
|
package/dist/Chat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.js","sourceRoot":"","sources":["../src/Chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,GAAG,MAAM,YAAY,CAAA;AACjC,OAAO,KAAK,SAAS,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAE,OAAO,EAAoB,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAA;AAElE,MAAM,CAAC,MAAM,uBAAuB,GAClC,8GAA8G,CAAA;AAgBhH,MAAM,YAAY,GAAG,CAAC,OAAoB,EAAE,QAAqB,EAAuB,EAAE,CACxF,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS;IAC1D,CAAC,CAAC,MAAM,CAAC,IAAI;IACb,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CACpB,UAAU,CAAC,IAAI,CAAC;QACd,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM;QAC9B,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;KACrF,CAAC,CACH,CAAA;AAOP,MAAM,cAAc,GAAG,CAAC,OAAoB,EAA0B,EAAE;IACtE,MAAM,MAAM,GACV,OAAO,CAAC,SAAS,KAAK,IAAI;QACxB,CAAC,CAAC,OAAO,CAAC,MAAM;QAChB,CAAC,CAAC,CAAC,uBAAuB,EAAE,OAAO,CAAC,MAAM,CAAC;aACtC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;aACvD,IAAI,CAAC,MAAM,CAAC,CAAA;IACrB,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAChD,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;AACzD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,QAAQ,CAAC,EACnE,OAAwB,EACxB,UAAuB,EAAE;IAEzB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;IACxD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAErC,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,QAAQ,CAAC,EAC3D,MAAc;QAEd,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;QAChE,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;QACzD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"Chat.js","sourceRoot":"","sources":["../src/Chat.ts"],"names":[],"mappings":"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"}
|
package/dist/Flow.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Flow.d.ts","sourceRoot":"","sources":["../src/Flow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"Flow.d.ts","sourceRoot":"","sources":["../src/Flow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAI9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1E,OAAO,EAAsC,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC1F,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EAAsC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AACnF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAE/D,eAAO,MAAM,YAAY,GAAI,SAAS,gBAAgB,KAAG,eACd,CAAA;AAE3C,eAAO,MAAM,kBAAkB,mHAmB7B,CAAA;AAEF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,MAAM,CAAA;IAC3D,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;CACjD;AAOD,eAAO,MAAM,iBAAiB,2gBAoG5B,CAAA"}
|
package/dist/Flow.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as Effect from "effect/Effect";
|
|
2
2
|
import { collect } from "@llm4ts/core/Streaming";
|
|
3
|
+
import { withToolActivity } from "./Activity.js";
|
|
3
4
|
import { makeChat } from "./Chat.js";
|
|
4
5
|
import { FlowAborted, FlowLlmError } from "./FlowError.js";
|
|
5
6
|
import { AssistantMessage, Info, TokensUsed } from "./FlowEvents.js";
|
|
@@ -8,7 +9,7 @@ import { minimalReviewers, reviewAndFixLoop } from "./Review.js";
|
|
|
8
9
|
export { publishUsage, structuredAndPublish } from "./Usage.js";
|
|
9
10
|
export const flowReviewer = (context) => context.reviewers[0] ?? context.reasoning;
|
|
10
11
|
export const completeAndPublish = Effect.fn("@llm4ts/flow/Flow.completeAndPublish")(function* (service, events, prompt) {
|
|
11
|
-
const response = yield* collect(service.executeStream(prompt)).pipe(Effect.mapError(FlowLlmError.from));
|
|
12
|
+
const response = yield* collect(withToolActivity(events, service.executeStream(prompt))).pipe(Effect.mapError(FlowLlmError.from));
|
|
12
13
|
if (response.usage !== undefined) {
|
|
13
14
|
yield* events.publish(TokensUsed.make({
|
|
14
15
|
agent: "assistant",
|
package/dist/Flow.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Flow.js","sourceRoot":"","sources":["../src/Flow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAa,MAAM,WAAW,CAAA;AAE/C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAkB,MAAM,gBAAgB,CAAA;AAC1E,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAA;AAG1F,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAqB,MAAM,aAAa,CAAA;AAGnF,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAE/D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAyB,EAAmB,EAAE,CACzE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,SAAS,CAAA;AAE3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,EAAE,CAAC,sCAAsC,CAAC,CAAC,QAAQ,CAAC,EAC3F,OAAwB,EACxB,MAAuB,EACvB,MAAc;IAEd,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"Flow.js","sourceRoot":"","sources":["../src/Flow.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.7.0",
|
|
4
4
|
"description": "Effect-native LLM workflow, persistence, review, and repository automation",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"exports": {
|
|
16
16
|
"./package.json": "./package.json",
|
|
17
|
+
"./Activity": "./dist/Activity.js",
|
|
17
18
|
"./AzureDevOpsTool": "./dist/AzureDevOpsTool.js",
|
|
18
19
|
"./Bench": "./dist/Bench.js",
|
|
19
20
|
"./BenchReport": "./dist/BenchReport.js",
|
|
@@ -79,7 +80,7 @@
|
|
|
79
80
|
"typescript"
|
|
80
81
|
],
|
|
81
82
|
"dependencies": {
|
|
82
|
-
"@llm4ts/core": "0.
|
|
83
|
+
"@llm4ts/core": "0.7.0"
|
|
83
84
|
},
|
|
84
85
|
"peerDependencies": {
|
|
85
86
|
"effect": "^4.0.0-beta.102"
|
package/src/Activity.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect"
|
|
2
|
+
import * as Stream from "effect/Stream"
|
|
3
|
+
import type { LlmError } from "@llm4ts/core/Errors"
|
|
4
|
+
import type { LlmChunk } from "@llm4ts/core/Models"
|
|
5
|
+
import { ToolUse, type FlowEventsShape } from "./FlowEvents.ts"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Live agent activity.
|
|
9
|
+
*
|
|
10
|
+
* CLI connectors emit a zero-delta chunk per tool call, tagged
|
|
11
|
+
* `metadata.event = "tool_use"` with `tool_name` and `tool_input` (see
|
|
12
|
+
* `toolEventChunk` in `@llm4ts/core/providers/CliSupport`). `collect` folds a
|
|
13
|
+
* stream into its final response and drops those chunks, so a coding agent
|
|
14
|
+
* working for minutes rendered as a bare spinner with no sign of progress.
|
|
15
|
+
* Tapping the stream turns each of them into a `ToolUse` event the terminal
|
|
16
|
+
* already knows how to draw.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const ArgsLimit = 120
|
|
20
|
+
|
|
21
|
+
/** Keys worth showing alone, in the order a tool call is usually recognised by. */
|
|
22
|
+
const salientKeys: ReadonlyArray<string> = [
|
|
23
|
+
"command",
|
|
24
|
+
"file_path",
|
|
25
|
+
"filePath",
|
|
26
|
+
"path",
|
|
27
|
+
"pattern",
|
|
28
|
+
"query",
|
|
29
|
+
"url",
|
|
30
|
+
"topic",
|
|
31
|
+
"title",
|
|
32
|
+
"description",
|
|
33
|
+
"prompt"
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
const compact = (text: string): string => {
|
|
37
|
+
const collapsed = text.replace(/\s+/g, " ").trim()
|
|
38
|
+
return collapsed.length <= ArgsLimit ? collapsed : `${collapsed.slice(0, ArgsLimit - 1)}…`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const scalar = (value: unknown): string | undefined => {
|
|
42
|
+
switch (typeof value) {
|
|
43
|
+
case "string":
|
|
44
|
+
return value
|
|
45
|
+
case "number":
|
|
46
|
+
case "boolean":
|
|
47
|
+
return String(value)
|
|
48
|
+
default:
|
|
49
|
+
return undefined
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The readable gist of a tool's arguments: the salient value on its own
|
|
55
|
+
* (`ls -R docs/modernization` rather than `{"command":"ls -R …"}`), a compact
|
|
56
|
+
* `key=value` list when no single field stands out, and the raw text when the
|
|
57
|
+
* input is not a JSON object. Always collapsed to one line and truncated.
|
|
58
|
+
*/
|
|
59
|
+
export const summariseToolArgs = (raw: string): string => {
|
|
60
|
+
const trimmed = raw.trim()
|
|
61
|
+
if (trimmed.length === 0) {
|
|
62
|
+
return ""
|
|
63
|
+
}
|
|
64
|
+
let parsed: unknown
|
|
65
|
+
try {
|
|
66
|
+
parsed = JSON.parse(trimmed)
|
|
67
|
+
} catch {
|
|
68
|
+
return compact(trimmed)
|
|
69
|
+
}
|
|
70
|
+
const direct = scalar(parsed)
|
|
71
|
+
if (direct !== undefined) {
|
|
72
|
+
return compact(direct)
|
|
73
|
+
}
|
|
74
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
75
|
+
return compact(trimmed)
|
|
76
|
+
}
|
|
77
|
+
const entries = Object.entries(parsed)
|
|
78
|
+
if (entries.length === 0) {
|
|
79
|
+
return ""
|
|
80
|
+
}
|
|
81
|
+
for (const key of salientKeys) {
|
|
82
|
+
const found = entries.find(([name]) => name === key)
|
|
83
|
+
const value = found === undefined ? undefined : scalar(found[1])
|
|
84
|
+
if (value !== undefined && value.trim().length > 0) {
|
|
85
|
+
return compact(value)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const single = entries.length === 1 ? scalar(entries[0]?.[1]) : undefined
|
|
89
|
+
if (single !== undefined) {
|
|
90
|
+
return compact(single)
|
|
91
|
+
}
|
|
92
|
+
return compact(
|
|
93
|
+
entries.map(([name, value]) => `${name}=${scalar(value) ?? JSON.stringify(value)}`).join(", ")
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** The `ToolUse` event a chunk represents, or undefined when it is not a tool call. */
|
|
98
|
+
export const toolUseFrom = (chunk: LlmChunk): ToolUse | undefined => {
|
|
99
|
+
if (chunk.metadata.event !== "tool_use") {
|
|
100
|
+
return undefined
|
|
101
|
+
}
|
|
102
|
+
const tool = (chunk.metadata.tool_name ?? chunk.metadata.toolName ?? "").trim()
|
|
103
|
+
if (tool.length === 0) {
|
|
104
|
+
return undefined
|
|
105
|
+
}
|
|
106
|
+
return ToolUse.make({
|
|
107
|
+
tool,
|
|
108
|
+
args: summariseToolArgs(chunk.metadata.tool_input ?? chunk.metadata.toolInput ?? "")
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Republishes the stream unchanged, publishing a `ToolUse` event for every
|
|
114
|
+
* tool call it carries. Wrap a connector stream with this before `collect` so
|
|
115
|
+
* the run reports what the agent is doing while it is doing it.
|
|
116
|
+
*/
|
|
117
|
+
export const withToolActivity = <R>(
|
|
118
|
+
events: FlowEventsShape,
|
|
119
|
+
stream: Stream.Stream<LlmChunk, LlmError, R>
|
|
120
|
+
): Stream.Stream<LlmChunk, LlmError, R> =>
|
|
121
|
+
Stream.tap(stream, (chunk) => {
|
|
122
|
+
const event = toolUseFrom(chunk)
|
|
123
|
+
return event === undefined ? Effect.void : events.publish(event)
|
|
124
|
+
})
|
package/src/Chat.ts
CHANGED
|
@@ -4,6 +4,7 @@ import * as Semaphore from "effect/Semaphore"
|
|
|
4
4
|
import type { LlmServiceShape } from "@llm4ts/core/LlmService"
|
|
5
5
|
import { Message, type LlmResponse } from "@llm4ts/core/Models"
|
|
6
6
|
import { collect } from "@llm4ts/core/Streaming"
|
|
7
|
+
import { withToolActivity } from "./Activity.ts"
|
|
7
8
|
import { FlowLlmError } from "./FlowError.ts"
|
|
8
9
|
import { TokensUsed, type FlowEventsShape } from "./FlowEvents.ts"
|
|
9
10
|
|
|
@@ -64,9 +65,10 @@ export const makeChat = Effect.fn("@llm4ts/flow/Chat.make")(function* (
|
|
|
64
65
|
): Effect.fn.Return<string, FlowLlmError> {
|
|
65
66
|
const userTurn = Message.make({ role: "User", content: prompt })
|
|
66
67
|
const messages = [...(yield* Ref.get(history)), userTurn]
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
const stream = service.executeStreamWithHistory(messages)
|
|
69
|
+
const response = yield* collect(
|
|
70
|
+
options.events === undefined ? stream : withToolActivity(options.events, stream)
|
|
71
|
+
).pipe(Effect.mapError(FlowLlmError.from))
|
|
70
72
|
yield* publishUsage(options, response)
|
|
71
73
|
yield* Ref.set(history, [
|
|
72
74
|
...messages,
|
package/src/Flow.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as Effect from "effect/Effect"
|
|
2
2
|
import type { LlmServiceShape } from "@llm4ts/core/LlmService"
|
|
3
3
|
import { collect } from "@llm4ts/core/Streaming"
|
|
4
|
+
import { withToolActivity } from "./Activity.ts"
|
|
4
5
|
import { makeChat, type Chat } from "./Chat.ts"
|
|
5
6
|
import type { FlowContextShape } from "./FlowContext.ts"
|
|
6
7
|
import { FlowAborted, FlowLlmError, type FlowError } from "./FlowError.ts"
|
|
@@ -21,7 +22,7 @@ export const completeAndPublish = Effect.fn("@llm4ts/flow/Flow.completeAndPublis
|
|
|
21
22
|
events: FlowEventsShape,
|
|
22
23
|
prompt: string
|
|
23
24
|
): Effect.fn.Return<string, FlowLlmError> {
|
|
24
|
-
const response = yield* collect(service.executeStream(prompt)).pipe(
|
|
25
|
+
const response = yield* collect(withToolActivity(events, service.executeStream(prompt))).pipe(
|
|
25
26
|
Effect.mapError(FlowLlmError.from)
|
|
26
27
|
)
|
|
27
28
|
if (response.usage !== undefined) {
|