mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-06-30 17:09:38 +02:00
Use Match for Effect AI stream parts
This commit is contained in:
parent
3a256096f8
commit
664aef44a7
3 changed files with 33 additions and 18 deletions
|
|
@ -433,6 +433,22 @@ Notes:
|
|||
- `bun run --cwd ts/packages/flow test -- src/__tests__/gateway-dispatcher.test.ts`
|
||||
- `cd ts && bun run check:tsgo`
|
||||
|
||||
### 2026-06-04: Effect AI Stream Part Match Slice
|
||||
|
||||
- Status: migrated and package-verified.
|
||||
- Completed:
|
||||
- `ts/packages/flow/src/model/text-completion/common.ts` now maps
|
||||
`Response.StreamPart` values with `effect/Match` instead of a native
|
||||
`switch`.
|
||||
- The matcher handles `text-delta`, `finish`, and `error` explicitly, while
|
||||
preserving ignored behavior for other valid stream parts with
|
||||
`Match.orElse`.
|
||||
- Text-completion common tests now include an ignored `text-start` stream
|
||||
part before text deltas to prove the fallback path remains silent.
|
||||
- Verification:
|
||||
- `bun run --cwd ts/packages/flow test -- src/__tests__/text-completion-common.test.ts`
|
||||
- `cd ts && bun run check:tsgo`
|
||||
|
||||
### 2026-06-02: RAG And Agent Requestor Bridge Slice
|
||||
|
||||
- Status: migrated, root-verified, committed, and pushed.
|
||||
|
|
@ -1862,8 +1878,9 @@ Notes:
|
|||
installed client, so do not reopen it as an `acquireRelease` close slice
|
||||
without new SDK evidence.
|
||||
- Shared text-completion stream iteration and the Mistral content assertion are
|
||||
complete. The remaining provider-layer item is parity-backed Effect AI
|
||||
adapter work, not a direct SDK swap.
|
||||
complete, and the Effect AI stream-part adapter now uses `effect/Match`.
|
||||
The remaining provider-layer item is parity-backed Effect AI adapter work,
|
||||
not a direct SDK swap.
|
||||
- Scratch-note follow-ups:
|
||||
- `Term` / compact client term serialization is complete for base schema,
|
||||
gateway translation, and pure term helper switches. Future work should
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect, it } from "@effect/vitest";
|
||||
import type { LlmChunk } from "@trustgraph/base";
|
||||
import { Effect, Layer, ManagedRuntime, Stream } from "effect";
|
||||
import { AiError, LanguageModel } from "effect/unstable/ai";
|
||||
import { AiError, LanguageModel, Response } from "effect/unstable/ai";
|
||||
import {
|
||||
llmStreamPart,
|
||||
makeLanguageModelProvider,
|
||||
|
|
@ -157,6 +157,7 @@ describe("text completion common helpers", () => {
|
|||
]),
|
||||
streamText: () =>
|
||||
Stream.fromArray([
|
||||
Response.makePart("text-start", { id: "part-1" }),
|
||||
{ type: "text-delta", id: "part-1", delta: "hel" },
|
||||
{ type: "text-delta", id: "part-1", delta: "lo" },
|
||||
finishPart(13, 8),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
type LlmResult,
|
||||
type LlmProvider,
|
||||
} from "@trustgraph/base";
|
||||
import { Config, Effect, Layer, ManagedRuntime, Ref, Result, Stream } from "effect";
|
||||
import { Config, Effect, Layer, ManagedRuntime, Match, Ref, Result, Stream } from "effect";
|
||||
import * as O from "effect/Option";
|
||||
import * as Predicate from "effect/Predicate";
|
||||
import * as S from "effect/Schema";
|
||||
|
|
@ -258,29 +258,26 @@ const languageModelStreamChunk = (
|
|||
provider: string,
|
||||
model: string,
|
||||
part: Response.StreamPart<{}>,
|
||||
): Effect.Effect<Result.Result<LlmChunk, undefined>, TextCompletionRuntimeError> => {
|
||||
switch (part.type) {
|
||||
case "text-delta":
|
||||
return Effect.succeed(
|
||||
): Effect.Effect<Result.Result<LlmChunk, undefined>, TextCompletionRuntimeError> =>
|
||||
Match.value(part).pipe(
|
||||
Match.discriminators("type")({
|
||||
"text-delta": (part) => Effect.succeed(
|
||||
part.delta.length > 0
|
||||
? Result.succeed(textChunk(model, part.delta))
|
||||
: Result.fail(undefined),
|
||||
);
|
||||
case "finish":
|
||||
return Effect.succeed(
|
||||
),
|
||||
finish: (part) => Effect.succeed(
|
||||
Result.succeed(
|
||||
finalChunk(model, {
|
||||
inToken: usageInputTokens(part.usage),
|
||||
outToken: usageOutputTokens(part.usage),
|
||||
}),
|
||||
),
|
||||
);
|
||||
case "error":
|
||||
return Effect.fail(effectAiProviderError(provider, part.error));
|
||||
default:
|
||||
return Effect.succeed(Result.fail(undefined));
|
||||
}
|
||||
};
|
||||
),
|
||||
error: (part) => Effect.fail(effectAiProviderError(provider, part.error)),
|
||||
}),
|
||||
Match.orElse(() => Effect.succeed(Result.fail(undefined))),
|
||||
);
|
||||
|
||||
const runLanguageModelStream = <RuntimeRequirements, StreamRequirements extends RuntimeRequirements>(
|
||||
runtime: ManagedRuntime.ManagedRuntime<RuntimeRequirements, TextCompletionRuntimeError>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue