mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-09 00:13:55 +00:00
refactor(memory): localize host SDK internals (#101508)
This commit is contained in:
@@ -8,14 +8,14 @@ export const LOCAL_EMBEDDING_WORKER_ERROR_CODES = {
|
||||
} as const;
|
||||
|
||||
/** Error code union for local embedding worker failures. */
|
||||
export type LocalEmbeddingWorkerFailureCode =
|
||||
type LocalEmbeddingWorkerFailureCode =
|
||||
(typeof LOCAL_EMBEDDING_WORKER_ERROR_CODES)[keyof typeof LOCAL_EMBEDDING_WORKER_ERROR_CODES];
|
||||
|
||||
/** Cause category for local embedding worker failures. */
|
||||
type LocalEmbeddingWorkerFailureReason = "exit" | "signal" | "process-error" | "ipc";
|
||||
|
||||
/** Error shape used by callers that need retry/status decisions. */
|
||||
export type LocalEmbeddingWorkerFailureError = Error & {
|
||||
/** Error shape returned by the local embedding worker failure factory. */
|
||||
type LocalEmbeddingWorkerFailureError = Error & {
|
||||
code: LocalEmbeddingWorkerFailureCode;
|
||||
reason: LocalEmbeddingWorkerFailureReason;
|
||||
exitCode?: number | null;
|
||||
|
||||
@@ -8,7 +8,6 @@ export {
|
||||
assertNoSymlinkParents,
|
||||
readRegularFile,
|
||||
statRegularFile,
|
||||
type RegularFileStatResult,
|
||||
} from "@openclaw/fs-safe/advanced";
|
||||
export { walkDirectory, type WalkDirectoryEntry } from "@openclaw/fs-safe/walk";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Minimal node-llama-cpp type facade used by the local embedding provider.
|
||||
|
||||
/** Embedding vector returned by node-llama-cpp. */
|
||||
export type LlamaEmbedding = {
|
||||
type LlamaEmbedding = {
|
||||
vector: Float32Array | number[];
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ export type LlamaModel = {
|
||||
};
|
||||
|
||||
/** Options accepted by node-llama-cpp model file resolution. */
|
||||
export type ResolveModelFileOptions = {
|
||||
type ResolveModelFileOptions = {
|
||||
directory?: string;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
|
||||
@@ -1,37 +1,12 @@
|
||||
// Memory Host SDK tests cover retry utils behavior.
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { MAX_SAFE_TIMEOUT_DELAY_MS } from "../../../gateway-client/src/timeouts.js";
|
||||
import { resolveRetryConfig, retryAsync } from "./retry-utils.js";
|
||||
import { retryAsync } from "./retry-utils.js";
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("resolveRetryConfig", () => {
|
||||
const defaults = {
|
||||
attempts: 4,
|
||||
minDelayMs: 0,
|
||||
maxDelayMs: 0,
|
||||
jitter: 0,
|
||||
};
|
||||
|
||||
it("does not round malformed attempt counts", () => {
|
||||
expect(resolveRetryConfig(defaults, { attempts: 1.5 }).attempts).toBe(4);
|
||||
expect(resolveRetryConfig(defaults, { attempts: Number.POSITIVE_INFINITY }).attempts).toBe(4);
|
||||
expect(resolveRetryConfig(defaults, { attempts: Number.NaN }).attempts).toBe(4);
|
||||
});
|
||||
|
||||
it("caps oversized retry delays at the timer-safe ceiling", () => {
|
||||
const config = resolveRetryConfig(defaults, {
|
||||
minDelayMs: Number.MAX_SAFE_INTEGER,
|
||||
maxDelayMs: Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
|
||||
expect(config.minDelayMs).toBe(MAX_SAFE_TIMEOUT_DELAY_MS);
|
||||
expect(config.maxDelayMs).toBe(MAX_SAFE_TIMEOUT_DELAY_MS);
|
||||
});
|
||||
});
|
||||
|
||||
describe("retryAsync", () => {
|
||||
it("falls back to the default attempt count for malformed numeric counts", async () => {
|
||||
const run = vi.fn(async () => {
|
||||
@@ -43,6 +18,22 @@ describe("retryAsync", () => {
|
||||
expect(run).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it("falls back to the default attempt count for malformed option counts", async () => {
|
||||
const run = vi.fn(async () => {
|
||||
throw new Error("boom");
|
||||
});
|
||||
|
||||
await expect(
|
||||
retryAsync(run, {
|
||||
attempts: 1.5,
|
||||
minDelayMs: 0,
|
||||
maxDelayMs: 0,
|
||||
}),
|
||||
).rejects.toThrow("boom");
|
||||
|
||||
expect(run).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it("caps legacy numeric retry sleeps at the timer-safe ceiling", async () => {
|
||||
const run = vi
|
||||
.fn<() => Promise<string>>()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { resolveSafeTimeoutDelayMs } from "../../../gateway-client/src/timeouts.js";
|
||||
|
||||
/** Retry timing configuration with optional jitter. */
|
||||
export type RetryConfig = {
|
||||
type RetryConfig = {
|
||||
attempts?: number;
|
||||
minDelayMs?: number;
|
||||
maxDelayMs?: number;
|
||||
@@ -10,7 +10,7 @@ export type RetryConfig = {
|
||||
};
|
||||
|
||||
/** Retry callback payload. */
|
||||
export type RetryInfo = {
|
||||
type RetryInfo = {
|
||||
attempt: number;
|
||||
maxAttempts: number;
|
||||
delayMs: number;
|
||||
@@ -19,7 +19,7 @@ export type RetryInfo = {
|
||||
};
|
||||
|
||||
/** Retry options for retryAsync. */
|
||||
export type RetryOptions = RetryConfig & {
|
||||
type RetryOptions = RetryConfig & {
|
||||
label?: string;
|
||||
shouldRetry?: (err: unknown, attempt: number) => boolean;
|
||||
retryAfterMs?: (err: unknown) => number | undefined;
|
||||
@@ -64,7 +64,7 @@ function resolveAttempts(value: unknown, fallback: number): number {
|
||||
}
|
||||
|
||||
/** Resolve retry settings with clamped positive timeout values. */
|
||||
export function resolveRetryConfig(
|
||||
function resolveRetryConfig(
|
||||
defaults: Required<RetryConfig> = DEFAULT_RETRY_CONFIG,
|
||||
overrides?: RetryConfig,
|
||||
): Required<RetryConfig> {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Secret input parsing shared by memory provider config and gateway-resolved snapshots.
|
||||
|
||||
/** Supported secret reference backing stores. */
|
||||
export type SecretRefSource = "env" | "file" | "exec";
|
||||
type SecretRefSource = "env" | "file" | "exec";
|
||||
|
||||
/** Canonical secret reference shape used after gateway resolution. */
|
||||
export type SecretRef = {
|
||||
type SecretRef = {
|
||||
source: SecretRefSource;
|
||||
provider: string;
|
||||
id: string;
|
||||
|
||||
@@ -34,7 +34,6 @@ import type { MemorySessionSyncTarget } from "./types.js";
|
||||
|
||||
export {
|
||||
listSessionTranscriptCorpusEntriesForAgent,
|
||||
type SessionTranscriptCorpusArtifactKind,
|
||||
type SessionTranscriptCorpusEntry,
|
||||
} from "./session-transcript-corpus.js";
|
||||
|
||||
@@ -241,7 +240,7 @@ function isCanonicalSessionsDirForAgent(sessionsDir: string, agentId: string): b
|
||||
);
|
||||
}
|
||||
|
||||
export function loadSessionTranscriptClassificationForSessionsDir(
|
||||
function loadSessionTranscriptClassificationForSessionsDir(
|
||||
sessionsDir: string,
|
||||
): SessionTranscriptClassification {
|
||||
const agentId = extractAgentIdFromSessionsDir(sessionsDir);
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
type SessionEntry,
|
||||
} from "./openclaw-runtime-session.js";
|
||||
|
||||
export type SessionTranscriptCorpusArtifactKind =
|
||||
type SessionTranscriptCorpusArtifactKind =
|
||||
| "active-session"
|
||||
| "archive-artifact"
|
||||
| "orphan-file-artifact";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Small string normalization helpers kept local to memory-host-sdk for package
|
||||
// builds that should not depend on the full normalization package graph.
|
||||
/** Normalize a non-empty string or return null. */
|
||||
export function normalizeNullableString(value: unknown): string | null {
|
||||
function normalizeNullableString(value: unknown): string | null {
|
||||
if (typeof value !== "string") {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user