@llm4ts/flow 0.1.4 → 0.2.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/Chat.d.ts +10 -0
- package/dist/Chat.d.ts.map +1 -1
- package/dist/Chat.js +9 -0
- package/dist/Chat.js.map +1 -1
- package/dist/Flow.d.ts.map +1 -1
- package/dist/Flow.js +12 -1
- package/dist/Flow.js.map +1 -1
- package/package.json +2 -2
- package/src/Chat.ts +23 -1
- package/src/Flow.ts +14 -1
package/dist/Chat.d.ts
CHANGED
|
@@ -2,10 +2,20 @@ import * as Effect from "effect/Effect";
|
|
|
2
2
|
import type { LlmServiceShape } from "@llm4ts/core/LlmService";
|
|
3
3
|
import { Message } from "@llm4ts/core/Models";
|
|
4
4
|
import { FlowLlmError } from "./FlowError.ts";
|
|
5
|
+
import { type FlowEventsShape } from "./FlowEvents.ts";
|
|
5
6
|
export declare const gitOwnershipInstruction = "The flow runtime owns git operations. Do not create or switch branches, commit, push, or open pull requests.";
|
|
6
7
|
export interface ChatOptions {
|
|
7
8
|
readonly system?: string;
|
|
8
9
|
readonly manageGit?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* When set, every reply whose collected response carries token usage is
|
|
12
|
+
* published as a `TokensUsed` event, which is what `CostTracker` (and
|
|
13
|
+
* therefore cost summaries and budgets) consume. Without it, usage
|
|
14
|
+
* reported by the backend is silently discarded.
|
|
15
|
+
*/
|
|
16
|
+
readonly events?: FlowEventsShape;
|
|
17
|
+
/** Request label for published `TokensUsed` events. Default: "chat". */
|
|
18
|
+
readonly agent?: string;
|
|
9
19
|
}
|
|
10
20
|
export interface Chat {
|
|
11
21
|
readonly ask: (prompt: string) => Effect.Effect<string, FlowLlmError>;
|
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,
|
|
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;AAE/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,oGA2BnB,CAAA"}
|
package/dist/Chat.js
CHANGED
|
@@ -4,7 +4,15 @@ import * as Semaphore from "effect/Semaphore";
|
|
|
4
4
|
import { Message } from "@llm4ts/core/Models";
|
|
5
5
|
import { collect } from "@llm4ts/core/Streaming";
|
|
6
6
|
import { FlowLlmError } from "./FlowError.js";
|
|
7
|
+
import { TokensUsed } from "./FlowEvents.js";
|
|
7
8
|
export const gitOwnershipInstruction = "The flow runtime owns git operations. Do not create or switch branches, commit, push, or open pull requests.";
|
|
9
|
+
const publishUsage = (options, response) => options.events === undefined || response.usage === undefined
|
|
10
|
+
? Effect.void
|
|
11
|
+
: options.events.publish(TokensUsed.make({
|
|
12
|
+
agent: options.agent ?? "chat",
|
|
13
|
+
usage: response.usage,
|
|
14
|
+
...(response.metadata.model === undefined ? {} : { model: response.metadata.model })
|
|
15
|
+
}));
|
|
8
16
|
const initialHistory = (options) => {
|
|
9
17
|
const system = options.manageGit === true
|
|
10
18
|
? options.system
|
|
@@ -22,6 +30,7 @@ export const makeChat = Effect.fn("@llm4ts/flow/Chat.make")(function* (service,
|
|
|
22
30
|
const userTurn = Message.make({ role: "User", content: prompt });
|
|
23
31
|
const messages = [...(yield* Ref.get(history)), userTurn];
|
|
24
32
|
const response = yield* collect(service.executeStreamWithHistory(messages)).pipe(Effect.mapError(FlowLlmError.from));
|
|
33
|
+
yield* publishUsage(options, response);
|
|
25
34
|
yield* Ref.set(history, [
|
|
26
35
|
...messages,
|
|
27
36
|
Message.make({ role: "Assistant", content: response.content })
|
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,
|
|
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;AAG9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1E,OAAO,
|
|
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;AAG9D,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,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
|
@@ -2,12 +2,19 @@ import * as Effect from "effect/Effect";
|
|
|
2
2
|
import { collect } from "@llm4ts/core/Streaming";
|
|
3
3
|
import { makeChat } from "./Chat.js";
|
|
4
4
|
import { FlowAborted, FlowLlmError } from "./FlowError.js";
|
|
5
|
-
import { AssistantMessage, Info } from "./FlowEvents.js";
|
|
5
|
+
import { AssistantMessage, Info, TokensUsed } from "./FlowEvents.js";
|
|
6
6
|
import { implementTaskLoop, stage } from "./PlanExecution.js";
|
|
7
7
|
import { minimalReviewers, reviewAndFixLoop } from "./Review.js";
|
|
8
8
|
export const flowReviewer = (context) => context.reviewers[0] ?? context.reasoning;
|
|
9
9
|
export const completeAndPublish = Effect.fn("@llm4ts/flow/Flow.completeAndPublish")(function* (service, events, prompt) {
|
|
10
10
|
const response = yield* collect(service.executeStream(prompt)).pipe(Effect.mapError(FlowLlmError.from));
|
|
11
|
+
if (response.usage !== undefined) {
|
|
12
|
+
yield* events.publish(TokensUsed.make({
|
|
13
|
+
agent: "assistant",
|
|
14
|
+
usage: response.usage,
|
|
15
|
+
...(response.metadata.model === undefined ? {} : { model: response.metadata.model })
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
11
18
|
yield* events.publish(AssistantMessage.make({ text: response.content }));
|
|
12
19
|
return response.content;
|
|
13
20
|
});
|
|
@@ -21,6 +28,8 @@ export const implementPlanFlow = Effect.fn("@llm4ts/flow/Flow.implementPlan")(fu
|
|
|
21
28
|
let sharedCoder;
|
|
22
29
|
if (options.chatPerTask !== true) {
|
|
23
30
|
sharedCoder = yield* makeChat(context.coder, {
|
|
31
|
+
events: context.events,
|
|
32
|
+
agent: "coder",
|
|
24
33
|
...(options.system === undefined ? {} : { system: options.system })
|
|
25
34
|
});
|
|
26
35
|
}
|
|
@@ -34,6 +43,8 @@ export const implementPlanFlow = Effect.fn("@llm4ts/flow/Flow.implementPlan")(fu
|
|
|
34
43
|
}
|
|
35
44
|
else {
|
|
36
45
|
coder = yield* makeChat(context.coder, {
|
|
46
|
+
events: context.events,
|
|
47
|
+
agent: "coder",
|
|
37
48
|
system: composeSystem(options.system, planSoFar.render)
|
|
38
49
|
});
|
|
39
50
|
}
|
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,EAAwB,MAAM,iBAAiB,CAAA;
|
|
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.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Effect-native LLM workflow, persistence, review, and repository automation",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"typescript"
|
|
77
77
|
],
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@llm4ts/core": "0.1
|
|
79
|
+
"@llm4ts/core": "0.2.1"
|
|
80
80
|
},
|
|
81
81
|
"peerDependencies": {
|
|
82
82
|
"effect": "^4.0.0-beta.102"
|
package/src/Chat.ts
CHANGED
|
@@ -2,9 +2,10 @@ import * as Effect from "effect/Effect"
|
|
|
2
2
|
import * as Ref from "effect/Ref"
|
|
3
3
|
import * as Semaphore from "effect/Semaphore"
|
|
4
4
|
import type { LlmServiceShape } from "@llm4ts/core/LlmService"
|
|
5
|
-
import { Message } from "@llm4ts/core/Models"
|
|
5
|
+
import { Message, type LlmResponse } from "@llm4ts/core/Models"
|
|
6
6
|
import { collect } from "@llm4ts/core/Streaming"
|
|
7
7
|
import { FlowLlmError } from "./FlowError.ts"
|
|
8
|
+
import { TokensUsed, type FlowEventsShape } from "./FlowEvents.ts"
|
|
8
9
|
|
|
9
10
|
export const gitOwnershipInstruction =
|
|
10
11
|
"The flow runtime owns git operations. Do not create or switch branches, commit, push, or open pull requests."
|
|
@@ -12,8 +13,28 @@ export const gitOwnershipInstruction =
|
|
|
12
13
|
export interface ChatOptions {
|
|
13
14
|
readonly system?: string
|
|
14
15
|
readonly manageGit?: boolean
|
|
16
|
+
/**
|
|
17
|
+
* When set, every reply whose collected response carries token usage is
|
|
18
|
+
* published as a `TokensUsed` event, which is what `CostTracker` (and
|
|
19
|
+
* therefore cost summaries and budgets) consume. Without it, usage
|
|
20
|
+
* reported by the backend is silently discarded.
|
|
21
|
+
*/
|
|
22
|
+
readonly events?: FlowEventsShape
|
|
23
|
+
/** Request label for published `TokensUsed` events. Default: "chat". */
|
|
24
|
+
readonly agent?: string
|
|
15
25
|
}
|
|
16
26
|
|
|
27
|
+
const publishUsage = (options: ChatOptions, response: LlmResponse): Effect.Effect<void> =>
|
|
28
|
+
options.events === undefined || response.usage === undefined
|
|
29
|
+
? Effect.void
|
|
30
|
+
: options.events.publish(
|
|
31
|
+
TokensUsed.make({
|
|
32
|
+
agent: options.agent ?? "chat",
|
|
33
|
+
usage: response.usage,
|
|
34
|
+
...(response.metadata.model === undefined ? {} : { model: response.metadata.model })
|
|
35
|
+
})
|
|
36
|
+
)
|
|
37
|
+
|
|
17
38
|
export interface Chat {
|
|
18
39
|
readonly ask: (prompt: string) => Effect.Effect<string, FlowLlmError>
|
|
19
40
|
readonly messages: Effect.Effect<ReadonlyArray<Message>>
|
|
@@ -46,6 +67,7 @@ export const makeChat = Effect.fn("@llm4ts/flow/Chat.make")(function* (
|
|
|
46
67
|
const response = yield* collect(service.executeStreamWithHistory(messages)).pipe(
|
|
47
68
|
Effect.mapError(FlowLlmError.from)
|
|
48
69
|
)
|
|
70
|
+
yield* publishUsage(options, response)
|
|
49
71
|
yield* Ref.set(history, [
|
|
50
72
|
...messages,
|
|
51
73
|
Message.make({ role: "Assistant", content: response.content })
|
package/src/Flow.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { collect } from "@llm4ts/core/Streaming"
|
|
|
4
4
|
import { makeChat, type Chat } from "./Chat.ts"
|
|
5
5
|
import type { FlowContextShape } from "./FlowContext.ts"
|
|
6
6
|
import { FlowAborted, FlowLlmError, type FlowError } from "./FlowError.ts"
|
|
7
|
-
import { AssistantMessage, Info, type FlowEventsShape } from "./FlowEvents.ts"
|
|
7
|
+
import { AssistantMessage, Info, TokensUsed, type FlowEventsShape } from "./FlowEvents.ts"
|
|
8
8
|
import type { Plan, Task } from "./Plan.ts"
|
|
9
9
|
import type { PlanStoreShape } from "./Persistence.ts"
|
|
10
10
|
import { implementTaskLoop, stage } from "./PlanExecution.ts"
|
|
@@ -22,6 +22,15 @@ export const completeAndPublish = Effect.fn("@llm4ts/flow/Flow.completeAndPublis
|
|
|
22
22
|
const response = yield* collect(service.executeStream(prompt)).pipe(
|
|
23
23
|
Effect.mapError(FlowLlmError.from)
|
|
24
24
|
)
|
|
25
|
+
if (response.usage !== undefined) {
|
|
26
|
+
yield* events.publish(
|
|
27
|
+
TokensUsed.make({
|
|
28
|
+
agent: "assistant",
|
|
29
|
+
usage: response.usage,
|
|
30
|
+
...(response.metadata.model === undefined ? {} : { model: response.metadata.model })
|
|
31
|
+
})
|
|
32
|
+
)
|
|
33
|
+
}
|
|
25
34
|
yield* events.publish(AssistantMessage.make({ text: response.content }))
|
|
26
35
|
return response.content
|
|
27
36
|
})
|
|
@@ -62,6 +71,8 @@ export const implementPlanFlow = Effect.fn("@llm4ts/flow/Flow.implementPlan")(fu
|
|
|
62
71
|
let sharedCoder: Chat | undefined
|
|
63
72
|
if (options.chatPerTask !== true) {
|
|
64
73
|
sharedCoder = yield* makeChat(context.coder, {
|
|
74
|
+
events: context.events,
|
|
75
|
+
agent: "coder",
|
|
65
76
|
...(options.system === undefined ? {} : { system: options.system })
|
|
66
77
|
})
|
|
67
78
|
}
|
|
@@ -81,6 +92,8 @@ export const implementPlanFlow = Effect.fn("@llm4ts/flow/Flow.implementPlan")(fu
|
|
|
81
92
|
coder = sharedCoder
|
|
82
93
|
} else {
|
|
83
94
|
coder = yield* makeChat(context.coder, {
|
|
95
|
+
events: context.events,
|
|
96
|
+
agent: "coder",
|
|
84
97
|
system: composeSystem(options.system, planSoFar.render)
|
|
85
98
|
})
|
|
86
99
|
}
|