mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-06 20:02:11 +02:00
Use Effect fn for Ollama embeddings
This commit is contained in:
parent
d939e6523c
commit
4032d15d96
2 changed files with 59 additions and 41 deletions
|
|
@ -2143,6 +2143,27 @@ Notes:
|
||||||
- `cd ts && bun run lint`
|
- `cd ts && bun run lint`
|
||||||
- `git diff --check`
|
- `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
|
## Subagent Findings To Preserve
|
||||||
|
|
||||||
- MCP/workbench:
|
- MCP/workbench:
|
||||||
|
|
@ -2301,9 +2322,8 @@ Notes:
|
||||||
- Fresh strict signal sweep after the 2026-06-04 helper and collection
|
- Fresh strict signal sweep after the 2026-06-04 helper and collection
|
||||||
slices found no production normal `Error`, raw `try`/`catch`, native
|
slices found no production normal `Error`, raw `try`/`catch`, native
|
||||||
`switch`, or Effect-focused type assertions under `ts/packages`.
|
`switch`, or Effect-focused type assertions under `ts/packages`.
|
||||||
- Remaining real helper-normalization targets from the fresh sweep are
|
- Remaining real helper-normalization targets from the fresh sweep are base
|
||||||
embeddings/ollama, base processor flow helpers, and one workbench atom
|
processor flow helpers and one workbench atom helper.
|
||||||
helper.
|
|
||||||
- Remaining real long-lived native collection targets include base processor
|
- Remaining real long-lived native collection targets include base processor
|
||||||
registries, Librarian service / collection manager state, prompt template
|
registries, Librarian service / collection manager state, prompt template
|
||||||
cache, and a workbench module cache. Local traversal sets and test fakes
|
cache, and a workbench module cache. Local traversal sets and test fakes
|
||||||
|
|
|
||||||
|
|
@ -79,52 +79,50 @@ const makeOllamaEmbeddingsFromConfig = ({
|
||||||
ollamaHost,
|
ollamaHost,
|
||||||
fetchImpl,
|
fetchImpl,
|
||||||
}: ResolvedOllamaEmbeddingsConfig): EmbeddingsServiceShape => ({
|
}: 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) {
|
if (texts.length === 0) {
|
||||||
return Effect.succeed([]);
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const useModel = model ?? defaultModel;
|
const useModel = model ?? defaultModel;
|
||||||
const url = `${ollamaHost}/api/embed`;
|
const url = `${ollamaHost}/api/embed`;
|
||||||
|
|
||||||
return Effect.gen(function* () {
|
const body = yield* S.encodeUnknownEffect(S.UnknownFromJsonString)({
|
||||||
const body = yield* S.encodeUnknownEffect(S.UnknownFromJsonString)({
|
model: useModel,
|
||||||
model: useModel,
|
input: Array.from(texts),
|
||||||
input: Array.from(texts),
|
}).pipe(
|
||||||
}).pipe(
|
Effect.mapError((error) => ollamaEmbeddingsError("ollama.encode-request", error))
|
||||||
Effect.mapError((error) => ollamaEmbeddingsError("ollama.encode-request", error))
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const response = yield* Effect.tryPromise({
|
const response = yield* Effect.tryPromise({
|
||||||
try: () =>
|
try: () =>
|
||||||
fetchImpl(url, {
|
fetchImpl(url, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body,
|
body,
|
||||||
}),
|
}),
|
||||||
catch: (error) => ollamaEmbeddingsError("ollama.fetch", error),
|
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));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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));
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue