Use Effect fn for Ollama embeddings

This commit is contained in:
elpresidank 2026-06-04 07:21:30 -05:00
parent d939e6523c
commit 4032d15d96
2 changed files with 59 additions and 41 deletions

View file

@ -2143,6 +2143,27 @@ Notes:
- `cd ts && bun run lint`
- `git diff --check`
### 2026-06-04: Ollama Embeddings Effect.fn Helper Slice
- Status: migrated and package-verified.
- Completed:
- `ts/packages/flow/src/embeddings/ollama.ts` now defines the `embed`
service method as a named `Effect.fn` generator instead of returning a
nested `Effect.gen` from an `Effect.fn` callback.
- Empty embedding requests now return through the same generator path without
allocating a separate `Effect.succeed` helper.
- The public sync factory, effectful layer, `ManagedRuntime` facade, and
`NodeRuntime.runMain` entrypoint are unchanged.
- The focused scan for Ollama `return Effect.gen(...)` helper patterns is
clean.
- Verification:
- `cd ts/packages/flow && bunx --bun vitest run src/__tests__/ollama-embeddings.test.ts`
- `cd ts && bun run check:tsgo`
- `cd ts && bun run build`
- `cd ts && bun run test`
- `cd ts && bun run lint`
- `git diff --check`
## Subagent Findings To Preserve
- MCP/workbench:
@ -2301,9 +2322,8 @@ Notes:
- Fresh strict signal sweep after the 2026-06-04 helper and collection
slices found no production normal `Error`, raw `try`/`catch`, native
`switch`, or Effect-focused type assertions under `ts/packages`.
- Remaining real helper-normalization targets from the fresh sweep are
embeddings/ollama, base processor flow helpers, and one workbench atom
helper.
- Remaining real helper-normalization targets from the fresh sweep are base
processor flow helpers and one workbench atom helper.
- Remaining real long-lived native collection targets include base processor
registries, Librarian service / collection manager state, prompt template
cache, and a workbench module cache. Local traversal sets and test fakes

View file

@ -79,52 +79,50 @@ const makeOllamaEmbeddingsFromConfig = ({
ollamaHost,
fetchImpl,
}: ResolvedOllamaEmbeddingsConfig): EmbeddingsServiceShape => ({
embed: Effect.fn("OllamaEmbeddings.embed")((texts: ReadonlyArray<string>, model?: string) => {
embed: Effect.fn("OllamaEmbeddings.embed")(function* (texts: ReadonlyArray<string>, model?: string) {
if (texts.length === 0) {
return Effect.succeed([]);
return [];
}
const useModel = model ?? defaultModel;
const url = `${ollamaHost}/api/embed`;
return Effect.gen(function* () {
const body = yield* S.encodeUnknownEffect(S.UnknownFromJsonString)({
model: useModel,
input: Array.from(texts),
}).pipe(
Effect.mapError((error) => ollamaEmbeddingsError("ollama.encode-request", error))
);
const body = yield* S.encodeUnknownEffect(S.UnknownFromJsonString)({
model: useModel,
input: Array.from(texts),
}).pipe(
Effect.mapError((error) => ollamaEmbeddingsError("ollama.encode-request", error))
);
const response = yield* Effect.tryPromise({
try: () =>
fetchImpl(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body,
}),
catch: (error) => ollamaEmbeddingsError("ollama.fetch", error),
});
if (!response.ok) {
const errorBody = yield* Effect.tryPromise({
try: () => response.text(),
catch: (error) => ollamaEmbeddingsError("ollama.error-body", error),
});
return yield* ollamaEmbeddingsMessageError(
"ollama.embed",
`Ollama embeddings request failed (${response.status}): ${errorBody}`,
);
}
const data = yield* Effect.tryPromise({
try: () => responseJson(response),
catch: (error) => ollamaEmbeddingsError("ollama.response-json", error),
});
const decoded = yield* S.decodeUnknownEffect(OllamaEmbedResponse)(data).pipe(
Effect.mapError((error) => ollamaEmbeddingsError("ollama.decode-response", error))
);
return Array.from(decoded.embeddings, (vector) => Array.from(vector));
const response = yield* Effect.tryPromise({
try: () =>
fetchImpl(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body,
}),
catch: (error) => ollamaEmbeddingsError("ollama.fetch", error),
});
if (!response.ok) {
const errorBody = yield* Effect.tryPromise({
try: () => response.text(),
catch: (error) => ollamaEmbeddingsError("ollama.error-body", error),
});
return yield* ollamaEmbeddingsMessageError(
"ollama.embed",
`Ollama embeddings request failed (${response.status}): ${errorBody}`,
);
}
const data = yield* Effect.tryPromise({
try: () => responseJson(response),
catch: (error) => ollamaEmbeddingsError("ollama.response-json", error),
});
const decoded = yield* S.decodeUnknownEffect(OllamaEmbedResponse)(data).pipe(
Effect.mapError((error) => ollamaEmbeddingsError("ollama.decode-response", error))
);
return Array.from(decoded.embeddings, (vector) => Array.from(vector));
}),
});